1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:     ReactOS Spooler API
3c2c66affSColin Finck  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4c2c66affSColin Finck  * PURPOSE:     Functions related to Printer Configuration Data
5c2c66affSColin Finck  * COPYRIGHT:   Copyright 2015-2017 Colin Finck (colin@reactos.org)
6c2c66affSColin Finck  */
7c2c66affSColin Finck 
8c2c66affSColin Finck #include "precomp.h"
9c2c66affSColin Finck 
10c2c66affSColin Finck LONG WINAPI
AdvancedSetupDialog(HWND hWnd,INT Unknown,PDEVMODEA pDevModeInput,PDEVMODEA pDevModeOutput)117bffb703SJames Tabor AdvancedSetupDialog(HWND hWnd, INT Unknown, PDEVMODEA pDevModeInput, PDEVMODEA pDevModeOutput)
127bffb703SJames Tabor {
137bffb703SJames Tabor    HANDLE hPrinter;
147bffb703SJames Tabor    LONG Ret = -1;
157bffb703SJames Tabor 
167bffb703SJames Tabor     TRACE("AdvancedSetupDialog(%p, %d, %p, %p)\n", hWnd, Unknown, pDevModeOutput, pDevModeInput);
177bffb703SJames Tabor 
187bffb703SJames Tabor     if ( OpenPrinterA( (LPSTR)pDevModeInput->dmDeviceName, &hPrinter, NULL ) )
197bffb703SJames Tabor     {
207bffb703SJames Tabor         Ret = AdvancedDocumentPropertiesA( hWnd, hPrinter, (PSTR)pDevModeInput->dmDeviceName, pDevModeOutput, pDevModeInput );
217bffb703SJames Tabor         ClosePrinter(hPrinter);
227bffb703SJames Tabor     }
237bffb703SJames Tabor     return Ret;
247bffb703SJames Tabor }
257bffb703SJames Tabor 
267bffb703SJames Tabor LONG WINAPI
AdvancedDocumentPropertiesA(HWND hWnd,HANDLE hPrinter,PSTR pDeviceName,PDEVMODEA pDevModeOutput,PDEVMODEA pDevModeInput)2746b91659SColin Finck AdvancedDocumentPropertiesA(HWND hWnd, HANDLE hPrinter, PSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput)
2846b91659SColin Finck {
2946b91659SColin Finck     TRACE("AdvancedDocumentPropertiesA(%p, %p, %s, %p, %p)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput);
3046b91659SColin Finck     UNIMPLEMENTED;
3146b91659SColin Finck     return 0;
3246b91659SColin Finck }
3346b91659SColin Finck 
3446b91659SColin Finck LONG WINAPI
AdvancedDocumentPropertiesW(HWND hWnd,HANDLE hPrinter,PWSTR pDeviceName,PDEVMODEW pDevModeOutput,PDEVMODEW pDevModeInput)35c2c66affSColin Finck AdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, PWSTR pDeviceName, PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput)
36c2c66affSColin Finck {
371f6f08ecSColin Finck     TRACE("AdvancedDocumentPropertiesW(%p, %p, %S, %p, %p)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput);
38c2c66affSColin Finck     UNIMPLEMENTED;
3946b91659SColin Finck     return 0;
4046b91659SColin Finck }
4146b91659SColin Finck 
4246b91659SColin Finck DWORD WINAPI
DeletePrinterDataA(HANDLE hPrinter,PSTR pValueName)4346b91659SColin Finck DeletePrinterDataA(HANDLE hPrinter, PSTR pValueName)
4446b91659SColin Finck {
457bffb703SJames Tabor     LPWSTR  valuenameW = NULL;
467bffb703SJames Tabor     INT     len;
477bffb703SJames Tabor     DWORD   res;
487bffb703SJames Tabor 
4946b91659SColin Finck     TRACE("DeletePrinterDataA(%p, %s)\n", hPrinter, pValueName);
507bffb703SJames Tabor 
517bffb703SJames Tabor     if (pValueName)
527bffb703SJames Tabor     {
537bffb703SJames Tabor         len = MultiByteToWideChar(CP_ACP, 0, pValueName, -1, NULL, 0);
547bffb703SJames Tabor         valuenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
557bffb703SJames Tabor         MultiByteToWideChar(CP_ACP, 0, pValueName, -1, valuenameW, len);
567bffb703SJames Tabor     }
577bffb703SJames Tabor 
587bffb703SJames Tabor     res = DeletePrinterDataW( hPrinter, valuenameW );
597bffb703SJames Tabor 
6062c4b828SJames Tabor     if (valuenameW) HeapFree(GetProcessHeap(), 0, valuenameW);
617bffb703SJames Tabor 
627bffb703SJames Tabor     return res;
637bffb703SJames Tabor 
6446b91659SColin Finck }
6546b91659SColin Finck 
6646b91659SColin Finck DWORD WINAPI
DeletePrinterDataExA(HANDLE hPrinter,PCSTR pKeyName,PCSTR pValueName)6746b91659SColin Finck DeletePrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PCSTR pValueName)
6846b91659SColin Finck {
697bffb703SJames Tabor     LPWSTR  keynameW = NULL;
707bffb703SJames Tabor     LPWSTR  valuenameW = NULL;
717bffb703SJames Tabor     INT     len;
727bffb703SJames Tabor     DWORD   res;
737bffb703SJames Tabor 
7446b91659SColin Finck     TRACE("DeletePrinterDataExA(%p, %s, %s)\n", hPrinter, pKeyName, pValueName);
757bffb703SJames Tabor 
767bffb703SJames Tabor     if (pKeyName)
777bffb703SJames Tabor     {
787bffb703SJames Tabor         len = MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, NULL, 0);
797bffb703SJames Tabor         keynameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
807bffb703SJames Tabor         MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, keynameW, len);
817bffb703SJames Tabor     }
827bffb703SJames Tabor 
837bffb703SJames Tabor     if (pValueName)
847bffb703SJames Tabor     {
857bffb703SJames Tabor         len = MultiByteToWideChar(CP_ACP, 0, pValueName, -1, NULL, 0);
867bffb703SJames Tabor         valuenameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
877bffb703SJames Tabor         MultiByteToWideChar(CP_ACP, 0, pValueName, -1, valuenameW, len);
887bffb703SJames Tabor     }
897bffb703SJames Tabor 
907bffb703SJames Tabor     res = DeletePrinterDataExW( hPrinter, keynameW, valuenameW );
917bffb703SJames Tabor 
9262c4b828SJames Tabor     if (keynameW) HeapFree(GetProcessHeap(), 0, keynameW);
9362c4b828SJames Tabor     if (valuenameW) HeapFree(GetProcessHeap(), 0, valuenameW);
947bffb703SJames Tabor 
957bffb703SJames Tabor     return res;
9646b91659SColin Finck }
9746b91659SColin Finck 
9846b91659SColin Finck DWORD WINAPI
DeletePrinterDataExW(HANDLE hPrinter,PCWSTR pKeyName,PCWSTR pValueName)9946b91659SColin Finck DeletePrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName)
10046b91659SColin Finck {
10146b91659SColin Finck     TRACE("DeletePrinterDataExW(%p, %S, %S)\n", hPrinter, pKeyName, pValueName);
10246b91659SColin Finck     UNIMPLEMENTED;
10346b91659SColin Finck     return ERROR_NOT_SUPPORTED;
10446b91659SColin Finck }
10546b91659SColin Finck 
10646b91659SColin Finck DWORD WINAPI
DeletePrinterDataW(HANDLE hPrinter,PWSTR pValueName)10746b91659SColin Finck DeletePrinterDataW(HANDLE hPrinter, PWSTR pValueName)
10846b91659SColin Finck {
10946b91659SColin Finck     TRACE("DeletePrinterDataW(%p, %S)\n", hPrinter, pValueName);
11046b91659SColin Finck     UNIMPLEMENTED;
11146b91659SColin Finck     return ERROR_NOT_SUPPORTED;
11246b91659SColin Finck }
11346b91659SColin Finck 
11446b91659SColin Finck DWORD WINAPI
DeletePrinterKeyA(HANDLE hPrinter,PCSTR pKeyName)11546b91659SColin Finck DeletePrinterKeyA(HANDLE hPrinter, PCSTR pKeyName)
11646b91659SColin Finck {
1177bffb703SJames Tabor     LPWSTR  keynameW = NULL;
1187bffb703SJames Tabor     INT     len;
1197bffb703SJames Tabor     DWORD   res;
1207bffb703SJames Tabor 
12146b91659SColin Finck     TRACE("DeletePrinterKeyA(%p, %s)\n", hPrinter, pKeyName);
1227bffb703SJames Tabor 
1237bffb703SJames Tabor     if (pKeyName)
1247bffb703SJames Tabor     {
1257bffb703SJames Tabor         len = MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, NULL, 0);
1267bffb703SJames Tabor         keynameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1277bffb703SJames Tabor         MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, keynameW, len);
1287bffb703SJames Tabor     }
1297bffb703SJames Tabor 
1307bffb703SJames Tabor     res = DeletePrinterKeyW( hPrinter, keynameW );
1317bffb703SJames Tabor 
13262c4b828SJames Tabor     if (keynameW) HeapFree(GetProcessHeap(), 0, keynameW);
1337bffb703SJames Tabor 
1347bffb703SJames Tabor     return res;
13546b91659SColin Finck }
13646b91659SColin Finck 
13746b91659SColin Finck DWORD WINAPI
DeletePrinterKeyW(HANDLE hPrinter,PCWSTR pKeyName)13846b91659SColin Finck DeletePrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName)
13946b91659SColin Finck {
14046b91659SColin Finck     TRACE("DeletePrinterKeyW(%p, %S)\n", hPrinter, pKeyName);
14146b91659SColin Finck     UNIMPLEMENTED;
14246b91659SColin Finck     return ERROR_NOT_SUPPORTED;
14346b91659SColin Finck }
14446b91659SColin Finck 
14546b91659SColin Finck DWORD WINAPI
EnumPrinterDataA(HANDLE hPrinter,DWORD dwIndex,PSTR pValueName,DWORD cbValueName,PDWORD pcbValueName,PDWORD pType,PBYTE pData,DWORD cbData,PDWORD pcbData)14646b91659SColin Finck EnumPrinterDataA(HANDLE hPrinter, DWORD dwIndex, PSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData)
14746b91659SColin Finck {
14846b91659SColin Finck     TRACE("EnumPrinterDataA(%p, %lu, %s, %lu, %p, %p, %p, %lu, %p)\n", hPrinter, dwIndex, pValueName, cbValueName, pcbValueName, pType, pData, cbData, pcbData);
14946b91659SColin Finck     UNIMPLEMENTED;
15046b91659SColin Finck     return ERROR_NOT_SUPPORTED;
15146b91659SColin Finck }
15246b91659SColin Finck 
15346b91659SColin Finck DWORD WINAPI
EnumPrinterDataExA(HANDLE hPrinter,PCSTR pKeyName,PBYTE pEnumValues,DWORD cbEnumValues,PDWORD pcbEnumValues,PDWORD pnEnumValues)15446b91659SColin Finck EnumPrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
15546b91659SColin Finck {
1567bffb703SJames Tabor     INT	    len;
1577bffb703SJames Tabor     LPWSTR  pKeyNameW;
1587bffb703SJames Tabor     DWORD   ret, dwIndex, dwBufSize;
1597bffb703SJames Tabor     HANDLE  hHeap;
1607bffb703SJames Tabor     LPSTR   pBuffer;
1617bffb703SJames Tabor 
16246b91659SColin Finck     TRACE("EnumPrinterDataExA(%p, %s, %p, %lu, %p, %p)\n", hPrinter, pKeyName, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues);
1637bffb703SJames Tabor 
1647bffb703SJames Tabor     if (pKeyName == NULL || *pKeyName == 0)
1657bffb703SJames Tabor 	return ERROR_INVALID_PARAMETER;
1667bffb703SJames Tabor 
1677bffb703SJames Tabor     len = MultiByteToWideChar (CP_ACP, 0, pKeyName, -1, NULL, 0);
1687bffb703SJames Tabor     if (len == 0)
1697bffb703SJames Tabor     {
1707bffb703SJames Tabor 	ret = GetLastError ();
1717bffb703SJames Tabor 	ERR ("MultiByteToWideChar failed with code %i\n", ret);
1727bffb703SJames Tabor 	return ret;
1737bffb703SJames Tabor     }
1747bffb703SJames Tabor 
1757bffb703SJames Tabor     hHeap = GetProcessHeap ();
1767bffb703SJames Tabor     if (hHeap == NULL)
1777bffb703SJames Tabor     {
1787bffb703SJames Tabor 	ERR ("GetProcessHeap failed\n");
1797bffb703SJames Tabor 	return ERROR_OUTOFMEMORY;
1807bffb703SJames Tabor     }
1817bffb703SJames Tabor 
1827bffb703SJames Tabor     pKeyNameW = HeapAlloc (hHeap, 0, len * sizeof (WCHAR));
1837bffb703SJames Tabor     if (pKeyNameW == NULL)
1847bffb703SJames Tabor     {
1857bffb703SJames Tabor 	ERR ("Failed to allocate %i bytes from process heap\n",
1867bffb703SJames Tabor              (LONG)(len * sizeof (WCHAR)));
1877bffb703SJames Tabor 	return ERROR_OUTOFMEMORY;
1887bffb703SJames Tabor     }
1897bffb703SJames Tabor 
1907bffb703SJames Tabor     if (MultiByteToWideChar (CP_ACP, 0, pKeyName, -1, pKeyNameW, len) == 0)
1917bffb703SJames Tabor     {
1927bffb703SJames Tabor 	ret = GetLastError ();
1937bffb703SJames Tabor 	ERR ("MultiByteToWideChar failed with code %i\n", ret);
1947bffb703SJames Tabor 	if (HeapFree (hHeap, 0, pKeyNameW) == 0)
1957bffb703SJames Tabor 	    WARN ("HeapFree failed with code %i\n", GetLastError ());
1967bffb703SJames Tabor 	return ret;
1977bffb703SJames Tabor     }
1987bffb703SJames Tabor 
1997bffb703SJames Tabor     ret = EnumPrinterDataExW (hPrinter, pKeyNameW, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues);
2007bffb703SJames Tabor 
2017bffb703SJames Tabor     if (ret != ERROR_SUCCESS)
2027bffb703SJames Tabor     {
2037bffb703SJames Tabor 	if (HeapFree (hHeap, 0, pKeyNameW) == 0)
2047bffb703SJames Tabor 	    WARN ("HeapFree failed with code %i\n", GetLastError ());
2057bffb703SJames Tabor 	TRACE ("EnumPrinterDataExW returned %i\n", ret);
2067bffb703SJames Tabor 	return ret;
2077bffb703SJames Tabor     }
2087bffb703SJames Tabor 
2097bffb703SJames Tabor     if (HeapFree (hHeap, 0, pKeyNameW) == 0)
2107bffb703SJames Tabor     {
2117bffb703SJames Tabor 	ret = GetLastError ();
2127bffb703SJames Tabor 	ERR ("HeapFree failed with code %i\n", ret);
2137bffb703SJames Tabor 	return ret;
2147bffb703SJames Tabor     }
2157bffb703SJames Tabor 
2167bffb703SJames Tabor     if (*pnEnumValues == 0)	/* empty key */
2177bffb703SJames Tabor 	return ERROR_SUCCESS;
2187bffb703SJames Tabor 
2197bffb703SJames Tabor     dwBufSize = 0;
2207bffb703SJames Tabor     for (dwIndex = 0; dwIndex < *pnEnumValues; ++dwIndex)
2217bffb703SJames Tabor     {
22262c4b828SJames Tabor 	PPRINTER_ENUM_VALUESW ppev = &((PPRINTER_ENUM_VALUESW) pEnumValues)[dwIndex];
2237bffb703SJames Tabor 
2247bffb703SJames Tabor 	if (dwBufSize < ppev->cbValueName)
2257bffb703SJames Tabor 	    dwBufSize = ppev->cbValueName;
2267bffb703SJames Tabor 
22762c4b828SJames Tabor 	if ( dwBufSize < ppev->cbData &&
22862c4b828SJames Tabor 	    (ppev->dwType == REG_SZ || ppev->dwType == REG_EXPAND_SZ || ppev->dwType == REG_MULTI_SZ))
2297bffb703SJames Tabor 	    dwBufSize = ppev->cbData;
2307bffb703SJames Tabor     }
2317bffb703SJames Tabor 
23262c4b828SJames Tabor     FIXME ("Largest Unicode name or value is %i bytes\n", dwBufSize);
2337bffb703SJames Tabor 
2347bffb703SJames Tabor     pBuffer = HeapAlloc (hHeap, 0, dwBufSize);
2357bffb703SJames Tabor     if (pBuffer == NULL)
2367bffb703SJames Tabor     {
2377bffb703SJames Tabor 	ERR ("Failed to allocate %i bytes from process heap\n", dwBufSize);
2387bffb703SJames Tabor 	return ERROR_OUTOFMEMORY;
2397bffb703SJames Tabor     }
2407bffb703SJames Tabor 
2417bffb703SJames Tabor     for (dwIndex = 0; dwIndex < *pnEnumValues; ++dwIndex)
2427bffb703SJames Tabor     {
2437bffb703SJames Tabor 	PPRINTER_ENUM_VALUESW ppev =
2447bffb703SJames Tabor 		&((PPRINTER_ENUM_VALUESW) pEnumValues)[dwIndex];
2457bffb703SJames Tabor 
2467bffb703SJames Tabor 	len = WideCharToMultiByte (CP_ACP, 0, ppev->pValueName,
2477bffb703SJames Tabor 		ppev->cbValueName / sizeof (WCHAR), pBuffer, dwBufSize, NULL,
2487bffb703SJames Tabor 		NULL);
2497bffb703SJames Tabor 	if (len == 0)
2507bffb703SJames Tabor 	{
2517bffb703SJames Tabor 	    ret = GetLastError ();
2527bffb703SJames Tabor 	    ERR ("WideCharToMultiByte failed with code %i\n", ret);
2537bffb703SJames Tabor 	    if (HeapFree (hHeap, 0, pBuffer) == 0)
2547bffb703SJames Tabor 		WARN ("HeapFree failed with code %i\n", GetLastError ());
2557bffb703SJames Tabor 	    return ret;
2567bffb703SJames Tabor 	}
2577bffb703SJames Tabor 
2587bffb703SJames Tabor 	memcpy (ppev->pValueName, pBuffer, len);
2597bffb703SJames Tabor 
2607bffb703SJames Tabor 	TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer);
2617bffb703SJames Tabor 
2627bffb703SJames Tabor 	if (ppev->dwType != REG_SZ && ppev->dwType != REG_EXPAND_SZ &&
2637bffb703SJames Tabor 		ppev->dwType != REG_MULTI_SZ)
2647bffb703SJames Tabor 	    continue;
2657bffb703SJames Tabor 
2667bffb703SJames Tabor 	len = WideCharToMultiByte (CP_ACP, 0, (LPWSTR) ppev->pData,
2677bffb703SJames Tabor 		ppev->cbData / sizeof (WCHAR), pBuffer, dwBufSize, NULL, NULL);
2687bffb703SJames Tabor 	if (len == 0)
2697bffb703SJames Tabor 	{
2707bffb703SJames Tabor 	    ret = GetLastError ();
2717bffb703SJames Tabor 	    ERR ("WideCharToMultiByte failed with code %i\n", ret);
2727bffb703SJames Tabor 	    if (HeapFree (hHeap, 0, pBuffer) == 0)
2737bffb703SJames Tabor 		WARN ("HeapFree failed with code %i\n", GetLastError ());
2747bffb703SJames Tabor 	    return ret;
2757bffb703SJames Tabor 	}
2767bffb703SJames Tabor 
2777bffb703SJames Tabor 	memcpy (ppev->pData, pBuffer, len);
2787bffb703SJames Tabor 
2797bffb703SJames Tabor 	TRACE ("Converted '%s' from Unicode to ASCII\n", pBuffer);
2807bffb703SJames Tabor 	TRACE ("  (only first string of REG_MULTI_SZ printed)\n");
2817bffb703SJames Tabor     }
2827bffb703SJames Tabor 
2837bffb703SJames Tabor     if (HeapFree (hHeap, 0, pBuffer) == 0)
2847bffb703SJames Tabor     {
2857bffb703SJames Tabor 	ret = GetLastError ();
2867bffb703SJames Tabor 	ERR ("HeapFree failed with code %i\n", ret);
2877bffb703SJames Tabor 	return ret;
2887bffb703SJames Tabor     }
2897bffb703SJames Tabor 
2907bffb703SJames Tabor     return ERROR_SUCCESS;
29146b91659SColin Finck }
29246b91659SColin Finck 
29346b91659SColin Finck DWORD WINAPI
EnumPrinterDataExW(HANDLE hPrinter,PCWSTR pKeyName,PBYTE pEnumValues,DWORD cbEnumValues,PDWORD pcbEnumValues,PDWORD pnEnumValues)29446b91659SColin Finck EnumPrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues)
29546b91659SColin Finck {
29646b91659SColin Finck     TRACE("EnumPrinterDataExW(%p, %S, %p, %lu, %p, %p)\n", hPrinter, pKeyName, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues);
29746b91659SColin Finck     UNIMPLEMENTED;
29846b91659SColin Finck     return ERROR_NOT_SUPPORTED;
29946b91659SColin Finck }
30046b91659SColin Finck 
30146b91659SColin Finck DWORD WINAPI
EnumPrinterDataW(HANDLE hPrinter,DWORD dwIndex,PWSTR pValueName,DWORD cbValueName,PDWORD pcbValueName,PDWORD pType,PBYTE pData,DWORD cbData,PDWORD pcbData)30246b91659SColin Finck EnumPrinterDataW(HANDLE hPrinter, DWORD dwIndex, PWSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData)
30346b91659SColin Finck {
30446b91659SColin Finck     TRACE("EnumPrinterDataW(%p, %lu, %S, %lu, %p, %p, %p, %lu, %p)\n", hPrinter, dwIndex, pValueName, cbValueName, pcbValueName, pType, pData, cbData, pcbData);
30546b91659SColin Finck     UNIMPLEMENTED;
30646b91659SColin Finck     return ERROR_NOT_SUPPORTED;
30746b91659SColin Finck }
30846b91659SColin Finck 
30946b91659SColin Finck DWORD WINAPI
EnumPrinterKeyA(HANDLE hPrinter,PCSTR pKeyName,PSTR pSubkey,DWORD cbSubkey,PDWORD pcbSubkey)31046b91659SColin Finck EnumPrinterKeyA(HANDLE hPrinter, PCSTR pKeyName, PSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
31146b91659SColin Finck {
31246b91659SColin Finck     TRACE("EnumPrinterKeyA(%p, %s, %s, %lu, %p)\n", hPrinter, pKeyName, pSubkey, cbSubkey, pcbSubkey);
31346b91659SColin Finck     UNIMPLEMENTED;
31446b91659SColin Finck     return ERROR_NOT_SUPPORTED;
31546b91659SColin Finck }
31646b91659SColin Finck 
31746b91659SColin Finck DWORD WINAPI
EnumPrinterKeyW(HANDLE hPrinter,PCWSTR pKeyName,PWSTR pSubkey,DWORD cbSubkey,PDWORD pcbSubkey)31846b91659SColin Finck EnumPrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName, PWSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey)
31946b91659SColin Finck {
32046b91659SColin Finck     TRACE("EnumPrinterKeyW(%p, %S, %S, %lu, %p)\n", hPrinter, pKeyName, pSubkey, cbSubkey, pcbSubkey);
32146b91659SColin Finck     UNIMPLEMENTED;
32246b91659SColin Finck     return ERROR_NOT_SUPPORTED;
323c2c66affSColin Finck }
324c2c66affSColin Finck 
325c2c66affSColin Finck DWORD WINAPI
GetPrinterDataA(HANDLE hPrinter,LPSTR pValueName,LPDWORD pType,LPBYTE pData,DWORD nSize,LPDWORD pcbNeeded)326c2c66affSColin Finck GetPrinterDataA(HANDLE hPrinter, LPSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
327c2c66affSColin Finck {
3281f6f08ecSColin Finck     TRACE("GetPrinterDataA(%p, %s, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded);
329c2c66affSColin Finck     return GetPrinterDataExA(hPrinter, "PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded);
330c2c66affSColin Finck }
331c2c66affSColin Finck 
332c2c66affSColin Finck DWORD WINAPI
GetPrinterDataExA(HANDLE hPrinter,LPCSTR pKeyName,LPCSTR pValueName,LPDWORD pType,LPBYTE pData,DWORD nSize,LPDWORD pcbNeeded)333c2c66affSColin Finck GetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
334c2c66affSColin Finck {
335c2c66affSColin Finck     DWORD cbUnicodeData;
336c2c66affSColin Finck     DWORD cch;
337c2c66affSColin Finck     DWORD dwReturnValue;
338c2c66affSColin Finck     DWORD dwType;
339c2c66affSColin Finck     POSVERSIONINFOEXA pInfoA;
340c2c66affSColin Finck     POSVERSIONINFOEXW pInfoW;
341c2c66affSColin Finck     PVOID pUnicodeData = NULL;
342c2c66affSColin Finck     PWSTR pwszKeyName = NULL;
343c2c66affSColin Finck     PWSTR pwszValueName = NULL;
344c2c66affSColin Finck 
3451f6f08ecSColin Finck     TRACE("GetPrinterDataExA(%p, %s, %s, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
3461f6f08ecSColin Finck 
347c2c66affSColin Finck     if (pKeyName)
348c2c66affSColin Finck     {
349c2c66affSColin Finck         // Convert pKeyName to a Unicode string pwszKeyName
350c2c66affSColin Finck         cch = strlen(pKeyName);
351c2c66affSColin Finck 
352c2c66affSColin Finck         pwszKeyName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
353c2c66affSColin Finck         if (!pwszKeyName)
354c2c66affSColin Finck         {
355c2c66affSColin Finck             dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
356c2c66affSColin Finck             ERR("HeapAlloc failed!\n");
357c2c66affSColin Finck             goto Cleanup;
358c2c66affSColin Finck         }
359c2c66affSColin Finck 
360c2c66affSColin Finck         MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, pwszKeyName, cch + 1);
361c2c66affSColin Finck     }
362c2c66affSColin Finck 
363c2c66affSColin Finck     if (pValueName)
364c2c66affSColin Finck     {
365c2c66affSColin Finck         // Convert pValueName to a Unicode string pwszValueName
366c2c66affSColin Finck         cch = strlen(pValueName);
367c2c66affSColin Finck 
368c2c66affSColin Finck         pwszValueName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
369c2c66affSColin Finck         if (!pwszValueName)
370c2c66affSColin Finck         {
371c2c66affSColin Finck             dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
372c2c66affSColin Finck             ERR("HeapAlloc failed!\n");
373c2c66affSColin Finck             goto Cleanup;
374c2c66affSColin Finck         }
375c2c66affSColin Finck 
376c2c66affSColin Finck         MultiByteToWideChar(CP_ACP, 0, pValueName, -1, pwszValueName, cch + 1);
377c2c66affSColin Finck     }
378c2c66affSColin Finck 
379c2c66affSColin Finck     // We need the data type information, even if no pData was passed.
380c2c66affSColin Finck     if (!pType)
381c2c66affSColin Finck         pType = &dwType;
382c2c66affSColin Finck 
383c2c66affSColin Finck     // Call GetPrinterDataExW for the first time.
384c2c66affSColin Finck     // If we're lucky, the supplied buffer is already large enough and we don't need to do the expensive RPC call a second time.
385c2c66affSColin Finck     dwReturnValue = GetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, pType, pData, nSize, pcbNeeded);
386c2c66affSColin Finck 
387c2c66affSColin Finck     // If a critical error occurred, just return it. We cannot do anything else in this case.
388c2c66affSColin Finck     if (dwReturnValue != ERROR_SUCCESS && dwReturnValue != ERROR_MORE_DATA)
389c2c66affSColin Finck         goto Cleanup;
390c2c66affSColin Finck 
391c2c66affSColin Finck     // Save the needed buffer size for the Unicode data. We may alter *pcbNeeded for an ANSI buffer size.
392c2c66affSColin Finck     cbUnicodeData = *pcbNeeded;
393c2c66affSColin Finck 
394c2c66affSColin Finck     if (*pType == REG_SZ || *pType == REG_MULTI_SZ || *pType == REG_EXPAND_SZ)
395c2c66affSColin Finck     {
396c2c66affSColin Finck         // This is a string that needs to be converted from Unicode to ANSI.
397c2c66affSColin Finck         // Output the required buffer size for the ANSI string.
398c2c66affSColin Finck         *pcbNeeded /= sizeof(WCHAR);
399c2c66affSColin Finck     }
400c2c66affSColin Finck     else if (*pType == REG_NONE)
401c2c66affSColin Finck     {
402*e4930be4STimo Kreuzer         if (cbUnicodeData == sizeof(OSVERSIONINFOW) && _wcsicmp(pwszValueName, SPLREG_OS_VERSION) == 0)
403c2c66affSColin Finck         {
404c2c66affSColin Finck             // This is a Unicode OSVERSIONINFOW structure that needs to be converted to an ANSI OSVERSIONINFOA.
405c2c66affSColin Finck             *pcbNeeded = sizeof(OSVERSIONINFOA);
406c2c66affSColin Finck         }
407*e4930be4STimo Kreuzer         else if (cbUnicodeData == sizeof(OSVERSIONINFOEXW) && _wcsicmp(pwszValueName, SPLREG_OS_VERSIONEX) == 0)
408c2c66affSColin Finck         {
409c2c66affSColin Finck             // This is a Unicode OSVERSIONINFOEXW structure that needs to be converted to an ANSI OSVERSIONINFOEXA.
410c2c66affSColin Finck             *pcbNeeded = sizeof(OSVERSIONINFOEXA);
411c2c66affSColin Finck         }
412c2c66affSColin Finck         else
413c2c66affSColin Finck         {
414c2c66affSColin Finck             // Other REG_NONE value, nothing to do.
415c2c66affSColin Finck             goto Cleanup;
416c2c66affSColin Finck         }
417c2c66affSColin Finck     }
418c2c66affSColin Finck 
419c2c66affSColin Finck     // Check if the supplied buffer is large enough for the ANSI data.
420c2c66affSColin Finck     if (nSize < *pcbNeeded)
421c2c66affSColin Finck     {
422c2c66affSColin Finck         dwReturnValue = ERROR_MORE_DATA;
423c2c66affSColin Finck         goto Cleanup;
424c2c66affSColin Finck     }
425c2c66affSColin Finck 
426c2c66affSColin Finck     // Allocate a temporary buffer for the Unicode data.
427c2c66affSColin Finck     pUnicodeData = HeapAlloc(hProcessHeap, 0, cbUnicodeData);
428c2c66affSColin Finck     if (!pUnicodeData)
429c2c66affSColin Finck     {
430c2c66affSColin Finck         dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
431c2c66affSColin Finck         ERR("HeapAlloc failed!\n");
432c2c66affSColin Finck         goto Cleanup;
433c2c66affSColin Finck     }
434c2c66affSColin Finck 
435c2c66affSColin Finck     if (dwReturnValue == ERROR_SUCCESS)
436c2c66affSColin Finck     {
437c2c66affSColin Finck         // ERROR_SUCCESS: The buffer is large enough for the ANSI and the Unicode string,
438c2c66affSColin Finck         // so the Unicode string has been copied into pData. Copy it to pUnicodeData.
439c2c66affSColin Finck         CopyMemory(pUnicodeData, pData, cbUnicodeData);
440c2c66affSColin Finck     }
441c2c66affSColin Finck     else
442c2c66affSColin Finck     {
443c2c66affSColin Finck         // ERROR_MORE_DATA: The buffer is large enough for the ANSI string, but not for the Unicode string.
444c2c66affSColin Finck         // We have to call GetPrinterDataExW again with the temporary buffer.
445c2c66affSColin Finck         dwReturnValue = GetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, NULL, (PBYTE)pUnicodeData, cbUnicodeData, &cbUnicodeData);
446c2c66affSColin Finck         if (dwReturnValue != ERROR_SUCCESS)
447c2c66affSColin Finck             goto Cleanup;
448c2c66affSColin Finck     }
449c2c66affSColin Finck 
450c2c66affSColin Finck     if (*pType == REG_SZ || *pType == REG_MULTI_SZ || *pType == REG_EXPAND_SZ)
451c2c66affSColin Finck     {
452c2c66affSColin Finck         // Convert the Unicode string to ANSI.
453c2c66affSColin Finck         WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeData, -1, (PSTR)pData, *pcbNeeded, NULL, NULL);
454c2c66affSColin Finck     }
455c2c66affSColin Finck     else
456c2c66affSColin Finck     {
457c2c66affSColin Finck         // This is a REG_NONE with either OSVERSIONINFOW or OSVERSIONINFOEXW.
458c2c66affSColin Finck         // Copy the fields and convert the Unicode CSD Version string to ANSI.
459c2c66affSColin Finck         pInfoW = (POSVERSIONINFOEXW)pUnicodeData;
460c2c66affSColin Finck         pInfoA = (POSVERSIONINFOEXA)pData;
461c2c66affSColin Finck         pInfoA->dwMajorVersion = pInfoW->dwMajorVersion;
462c2c66affSColin Finck         pInfoA->dwMinorVersion = pInfoW->dwMinorVersion;
463c2c66affSColin Finck         pInfoA->dwBuildNumber = pInfoW->dwBuildNumber;
464c2c66affSColin Finck         pInfoA->dwPlatformId = pInfoW->dwPlatformId;
465c2c66affSColin Finck         WideCharToMultiByte(CP_ACP, 0, pInfoW->szCSDVersion, -1, pInfoA->szCSDVersion, sizeof(pInfoA->szCSDVersion), NULL, NULL);
466c2c66affSColin Finck 
467c2c66affSColin Finck         if (cbUnicodeData == sizeof(OSVERSIONINFOW))
468c2c66affSColin Finck         {
469c2c66affSColin Finck             pInfoA->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
470c2c66affSColin Finck         }
471c2c66affSColin Finck         else
472c2c66affSColin Finck         {
473c2c66affSColin Finck             pInfoA->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
474c2c66affSColin Finck             pInfoA->wServicePackMajor = pInfoW->wServicePackMajor;
475c2c66affSColin Finck             pInfoA->wServicePackMinor = pInfoW->wServicePackMinor;
476c2c66affSColin Finck             pInfoA->wSuiteMask = pInfoW->wSuiteMask;
477c2c66affSColin Finck             pInfoA->wProductType = pInfoW->wProductType;
478c2c66affSColin Finck             pInfoA->wReserved = pInfoW->wReserved;
479c2c66affSColin Finck         }
480c2c66affSColin Finck     }
481c2c66affSColin Finck 
482c2c66affSColin Finck Cleanup:
483c2c66affSColin Finck     if (pwszKeyName)
484c2c66affSColin Finck         HeapFree(hProcessHeap, 0, pwszKeyName);
485c2c66affSColin Finck 
486c2c66affSColin Finck     if (pwszValueName)
487c2c66affSColin Finck         HeapFree(hProcessHeap, 0, pwszValueName);
488c2c66affSColin Finck 
489c2c66affSColin Finck     if (pUnicodeData)
490c2c66affSColin Finck         HeapFree(hProcessHeap, 0, pUnicodeData);
491c2c66affSColin Finck 
492c2c66affSColin Finck     return dwReturnValue;
493c2c66affSColin Finck }
494c2c66affSColin Finck 
495c2c66affSColin Finck DWORD WINAPI
GetPrinterDataExW(HANDLE hPrinter,LPCWSTR pKeyName,LPCWSTR pValueName,LPDWORD pType,LPBYTE pData,DWORD nSize,LPDWORD pcbNeeded)496c2c66affSColin Finck GetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
497c2c66affSColin Finck {
498c2c66affSColin Finck     const WCHAR wszEmptyString[] = L"";
499c2c66affSColin Finck 
500c2c66affSColin Finck     BYTE DummyData;
501c2c66affSColin Finck     DWORD dwErrorCode;
502c2c66affSColin Finck     DWORD dwType = REG_NONE;
503c2c66affSColin Finck     PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
504c2c66affSColin Finck 
5051f6f08ecSColin Finck     TRACE("GetPrinterDataExW(%p, %S, %S, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
5061f6f08ecSColin Finck 
507c2c66affSColin Finck     // Sanity checks
508c2c66affSColin Finck     if (!pHandle)
509c2c66affSColin Finck         return ERROR_INVALID_HANDLE;
510c2c66affSColin Finck 
511c2c66affSColin Finck     // Yes, instead of declaring these pointers unique in the IDL file (and perfectly accepting NULL pointers this way),
512c2c66affSColin Finck     // Windows does it differently for GetPrinterDataExW and points them to empty variables.
513c2c66affSColin Finck     if (!pKeyName)
514c2c66affSColin Finck         pKeyName = wszEmptyString;
515c2c66affSColin Finck 
516c2c66affSColin Finck     if (!pType)
517c2c66affSColin Finck         pType = &dwType;
518c2c66affSColin Finck 
519c2c66affSColin Finck     if (!pData && !nSize)
520c2c66affSColin Finck         pData = &DummyData;
521c2c66affSColin Finck 
522c2c66affSColin Finck     // Do the RPC call
523c2c66affSColin Finck     RpcTryExcept
524c2c66affSColin Finck     {
525c2c66affSColin Finck         dwErrorCode = _RpcGetPrinterDataEx(pHandle->hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
526c2c66affSColin Finck     }
527c2c66affSColin Finck     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
528c2c66affSColin Finck     {
529c2c66affSColin Finck         dwErrorCode = RpcExceptionCode();
530c2c66affSColin Finck     }
531c2c66affSColin Finck     RpcEndExcept;
532c2c66affSColin Finck 
533c2c66affSColin Finck     return dwErrorCode;
534c2c66affSColin Finck }
535c2c66affSColin Finck 
536c2c66affSColin Finck DWORD WINAPI
GetPrinterDataW(HANDLE hPrinter,LPWSTR pValueName,LPDWORD pType,LPBYTE pData,DWORD nSize,LPDWORD pcbNeeded)537c2c66affSColin Finck GetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded)
538c2c66affSColin Finck {
5391f6f08ecSColin Finck     TRACE("GetPrinterDataW(%p, %S, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded);
540c2c66affSColin Finck     return GetPrinterDataExW(hPrinter, L"PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded);
541c2c66affSColin Finck }
542c2c66affSColin Finck 
543c2c66affSColin Finck DWORD WINAPI
SetPrinterDataA(HANDLE hPrinter,PSTR pValueName,DWORD Type,PBYTE pData,DWORD cbData)544c2c66affSColin Finck SetPrinterDataA(HANDLE hPrinter, PSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
545c2c66affSColin Finck {
5461f6f08ecSColin Finck     TRACE("SetPrinterDataA(%p, %s, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData);
547c2c66affSColin Finck     return SetPrinterDataExA(hPrinter, "PrinterDriverData", pValueName, Type, pData, cbData);
548c2c66affSColin Finck }
549c2c66affSColin Finck 
550c2c66affSColin Finck DWORD WINAPI
SetPrinterDataExA(HANDLE hPrinter,LPCSTR pKeyName,LPCSTR pValueName,DWORD Type,LPBYTE pData,DWORD cbData)551c2c66affSColin Finck SetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
552c2c66affSColin Finck {
553c2c66affSColin Finck     DWORD cch;
554c2c66affSColin Finck     DWORD dwReturnValue;
555c2c66affSColin Finck     PWSTR pwszKeyName = NULL;
556c2c66affSColin Finck     PWSTR pwszValueName = NULL;
557c2c66affSColin Finck     PWSTR pUnicodeData = NULL;
558c2c66affSColin Finck 
5591f6f08ecSColin Finck     TRACE("SetPrinterDataExA(%p, %s, %s, %lu, %p, %lu)\n", hPrinter, pKeyName, pValueName, Type, pData, cbData);
5601f6f08ecSColin Finck 
561c2c66affSColin Finck     if (pKeyName)
562c2c66affSColin Finck     {
563c2c66affSColin Finck         // Convert pKeyName to a Unicode string pwszKeyName
564c2c66affSColin Finck         cch = strlen(pKeyName);
565c2c66affSColin Finck 
566c2c66affSColin Finck         pwszKeyName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
567c2c66affSColin Finck         if (!pwszKeyName)
568c2c66affSColin Finck         {
569c2c66affSColin Finck             dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
570c2c66affSColin Finck             ERR("HeapAlloc failed!\n");
571c2c66affSColin Finck             goto Cleanup;
572c2c66affSColin Finck         }
573c2c66affSColin Finck 
574c2c66affSColin Finck         MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, pwszKeyName, cch + 1);
575c2c66affSColin Finck     }
576c2c66affSColin Finck 
577c2c66affSColin Finck     if (pValueName)
578c2c66affSColin Finck     {
579c2c66affSColin Finck         // Convert pValueName to a Unicode string pwszValueName
580c2c66affSColin Finck         cch = strlen(pValueName);
581c2c66affSColin Finck 
582c2c66affSColin Finck         pwszValueName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR));
583c2c66affSColin Finck         if (!pwszValueName)
584c2c66affSColin Finck         {
585c2c66affSColin Finck             dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
586c2c66affSColin Finck             ERR("HeapAlloc failed!\n");
587c2c66affSColin Finck             goto Cleanup;
588c2c66affSColin Finck         }
589c2c66affSColin Finck 
590c2c66affSColin Finck         MultiByteToWideChar(CP_ACP, 0, pValueName, -1, pwszValueName, cch + 1);
591c2c66affSColin Finck     }
592c2c66affSColin Finck 
593c2c66affSColin Finck     if (Type == REG_SZ || Type == REG_MULTI_SZ || Type == REG_EXPAND_SZ)
594c2c66affSColin Finck     {
595c2c66affSColin Finck         // Convert pData to a Unicode string pUnicodeData.
596c2c66affSColin Finck         pUnicodeData = HeapAlloc(hProcessHeap, 0, cbData * sizeof(WCHAR));
597c2c66affSColin Finck         if (!pUnicodeData)
598c2c66affSColin Finck         {
599c2c66affSColin Finck             dwReturnValue = ERROR_NOT_ENOUGH_MEMORY;
600c2c66affSColin Finck             ERR("HeapAlloc failed!\n");
601c2c66affSColin Finck             goto Cleanup;
602c2c66affSColin Finck         }
603c2c66affSColin Finck 
604c2c66affSColin Finck         MultiByteToWideChar(CP_ACP, 0, (PCSTR)pData, -1, pUnicodeData, cbData);
605c2c66affSColin Finck 
606c2c66affSColin Finck         pData = (PBYTE)pUnicodeData;
607c2c66affSColin Finck         cbData *= sizeof(WCHAR);
608c2c66affSColin Finck     }
609c2c66affSColin Finck 
610c2c66affSColin Finck     dwReturnValue = SetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, Type, pData, cbData);
611c2c66affSColin Finck 
612c2c66affSColin Finck Cleanup:
613c2c66affSColin Finck     if (pwszKeyName)
614c2c66affSColin Finck         HeapFree(hProcessHeap, 0, pwszKeyName);
615c2c66affSColin Finck 
616c2c66affSColin Finck     if (pwszValueName)
617c2c66affSColin Finck         HeapFree(hProcessHeap, 0, pwszValueName);
618c2c66affSColin Finck 
619c2c66affSColin Finck     if (pUnicodeData)
620c2c66affSColin Finck         HeapFree(hProcessHeap, 0, pUnicodeData);
621c2c66affSColin Finck 
622c2c66affSColin Finck     return dwReturnValue;
623c2c66affSColin Finck }
624c2c66affSColin Finck 
625c2c66affSColin Finck DWORD WINAPI
SetPrinterDataExW(HANDLE hPrinter,LPCWSTR pKeyName,LPCWSTR pValueName,DWORD Type,LPBYTE pData,DWORD cbData)626c2c66affSColin Finck SetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
627c2c66affSColin Finck {
628c2c66affSColin Finck     const WCHAR wszEmptyString[] = L"";
629c2c66affSColin Finck 
630c2c66affSColin Finck     DWORD dwErrorCode;
631c2c66affSColin Finck     PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter;
632c2c66affSColin Finck 
6331f6f08ecSColin Finck     TRACE("SetPrinterDataExW(%p, %S, %S, %lu, %p, %lu)\n", hPrinter, pKeyName, pValueName, Type, pData, cbData);
6341f6f08ecSColin Finck 
635c2c66affSColin Finck     // Sanity checks
636c2c66affSColin Finck     if (!pHandle)
637c2c66affSColin Finck         return ERROR_INVALID_HANDLE;
638c2c66affSColin Finck 
639c2c66affSColin Finck     if (!pKeyName)
640c2c66affSColin Finck         pKeyName = wszEmptyString;
641c2c66affSColin Finck 
642c2c66affSColin Finck     // Do the RPC call
643c2c66affSColin Finck     RpcTryExcept
644c2c66affSColin Finck     {
645c2c66affSColin Finck         dwErrorCode = _RpcSetPrinterDataEx(pHandle->hPrinter, pKeyName, pValueName, Type, pData, cbData);
646c2c66affSColin Finck     }
647c2c66affSColin Finck     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
648c2c66affSColin Finck     {
649c2c66affSColin Finck         dwErrorCode = RpcExceptionCode();
650c2c66affSColin Finck     }
651c2c66affSColin Finck     RpcEndExcept;
652c2c66affSColin Finck 
653c2c66affSColin Finck     return dwErrorCode;
654c2c66affSColin Finck }
655c2c66affSColin Finck 
656c2c66affSColin Finck DWORD WINAPI
SetPrinterDataW(HANDLE hPrinter,PWSTR pValueName,DWORD Type,PBYTE pData,DWORD cbData)657c2c66affSColin Finck SetPrinterDataW(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
658c2c66affSColin Finck {
6591f6f08ecSColin Finck     TRACE("SetPrinterDataW(%p, %S, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData);
660c2c66affSColin Finck     return SetPrinterDataExW(hPrinter, L"PrinterDriverData", pValueName, Type, pData, cbData);
661c2c66affSColin Finck }
662