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 11*46b91659SColin Finck AdvancedDocumentPropertiesA(HWND hWnd, HANDLE hPrinter, PSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput) 12*46b91659SColin Finck { 13*46b91659SColin Finck TRACE("AdvancedDocumentPropertiesA(%p, %p, %s, %p, %p)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput); 14*46b91659SColin Finck UNIMPLEMENTED; 15*46b91659SColin Finck return 0; 16*46b91659SColin Finck } 17*46b91659SColin Finck 18*46b91659SColin Finck LONG WINAPI 19c2c66affSColin Finck AdvancedDocumentPropertiesW(HWND hWnd, HANDLE hPrinter, PWSTR pDeviceName, PDEVMODEW pDevModeOutput, PDEVMODEW pDevModeInput) 20c2c66affSColin Finck { 211f6f08ecSColin Finck TRACE("AdvancedDocumentPropertiesW(%p, %p, %S, %p, %p)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput); 22c2c66affSColin Finck UNIMPLEMENTED; 23*46b91659SColin Finck return 0; 24*46b91659SColin Finck } 25*46b91659SColin Finck 26*46b91659SColin Finck DWORD WINAPI 27*46b91659SColin Finck DeletePrinterDataA(HANDLE hPrinter, PSTR pValueName) 28*46b91659SColin Finck { 29*46b91659SColin Finck TRACE("DeletePrinterDataA(%p, %s)\n", hPrinter, pValueName); 30*46b91659SColin Finck UNIMPLEMENTED; 31*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 32*46b91659SColin Finck } 33*46b91659SColin Finck 34*46b91659SColin Finck DWORD WINAPI 35*46b91659SColin Finck DeletePrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PCSTR pValueName) 36*46b91659SColin Finck { 37*46b91659SColin Finck TRACE("DeletePrinterDataExA(%p, %s, %s)\n", hPrinter, pKeyName, pValueName); 38*46b91659SColin Finck UNIMPLEMENTED; 39*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 40*46b91659SColin Finck } 41*46b91659SColin Finck 42*46b91659SColin Finck DWORD WINAPI 43*46b91659SColin Finck DeletePrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName) 44*46b91659SColin Finck { 45*46b91659SColin Finck TRACE("DeletePrinterDataExW(%p, %S, %S)\n", hPrinter, pKeyName, pValueName); 46*46b91659SColin Finck UNIMPLEMENTED; 47*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 48*46b91659SColin Finck } 49*46b91659SColin Finck 50*46b91659SColin Finck DWORD WINAPI 51*46b91659SColin Finck DeletePrinterDataW(HANDLE hPrinter, PWSTR pValueName) 52*46b91659SColin Finck { 53*46b91659SColin Finck TRACE("DeletePrinterDataW(%p, %S)\n", hPrinter, pValueName); 54*46b91659SColin Finck UNIMPLEMENTED; 55*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 56*46b91659SColin Finck } 57*46b91659SColin Finck 58*46b91659SColin Finck DWORD WINAPI 59*46b91659SColin Finck DeletePrinterKeyA(HANDLE hPrinter, PCSTR pKeyName) 60*46b91659SColin Finck { 61*46b91659SColin Finck TRACE("DeletePrinterKeyA(%p, %s)\n", hPrinter, pKeyName); 62*46b91659SColin Finck UNIMPLEMENTED; 63*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 64*46b91659SColin Finck } 65*46b91659SColin Finck 66*46b91659SColin Finck DWORD WINAPI 67*46b91659SColin Finck DeletePrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName) 68*46b91659SColin Finck { 69*46b91659SColin Finck TRACE("DeletePrinterKeyW(%p, %S)\n", hPrinter, pKeyName); 70*46b91659SColin Finck UNIMPLEMENTED; 71*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 72*46b91659SColin Finck } 73*46b91659SColin Finck 74*46b91659SColin Finck DWORD WINAPI 75*46b91659SColin Finck EnumPrinterDataA(HANDLE hPrinter, DWORD dwIndex, PSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData) 76*46b91659SColin Finck { 77*46b91659SColin Finck TRACE("EnumPrinterDataA(%p, %lu, %s, %lu, %p, %p, %p, %lu, %p)\n", hPrinter, dwIndex, pValueName, cbValueName, pcbValueName, pType, pData, cbData, pcbData); 78*46b91659SColin Finck UNIMPLEMENTED; 79*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 80*46b91659SColin Finck } 81*46b91659SColin Finck 82*46b91659SColin Finck DWORD WINAPI 83*46b91659SColin Finck EnumPrinterDataExA(HANDLE hPrinter, PCSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues) 84*46b91659SColin Finck { 85*46b91659SColin Finck TRACE("EnumPrinterDataExA(%p, %s, %p, %lu, %p, %p)\n", hPrinter, pKeyName, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues); 86*46b91659SColin Finck UNIMPLEMENTED; 87*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 88*46b91659SColin Finck } 89*46b91659SColin Finck 90*46b91659SColin Finck DWORD WINAPI 91*46b91659SColin Finck EnumPrinterDataExW(HANDLE hPrinter, PCWSTR pKeyName, PBYTE pEnumValues, DWORD cbEnumValues, PDWORD pcbEnumValues, PDWORD pnEnumValues) 92*46b91659SColin Finck { 93*46b91659SColin Finck TRACE("EnumPrinterDataExW(%p, %S, %p, %lu, %p, %p)\n", hPrinter, pKeyName, pEnumValues, cbEnumValues, pcbEnumValues, pnEnumValues); 94*46b91659SColin Finck UNIMPLEMENTED; 95*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 96*46b91659SColin Finck } 97*46b91659SColin Finck 98*46b91659SColin Finck DWORD WINAPI 99*46b91659SColin Finck EnumPrinterDataW(HANDLE hPrinter, DWORD dwIndex, PWSTR pValueName, DWORD cbValueName, PDWORD pcbValueName, PDWORD pType, PBYTE pData, DWORD cbData, PDWORD pcbData) 100*46b91659SColin Finck { 101*46b91659SColin Finck TRACE("EnumPrinterDataW(%p, %lu, %S, %lu, %p, %p, %p, %lu, %p)\n", hPrinter, dwIndex, pValueName, cbValueName, pcbValueName, pType, pData, cbData, pcbData); 102*46b91659SColin Finck UNIMPLEMENTED; 103*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 104*46b91659SColin Finck } 105*46b91659SColin Finck 106*46b91659SColin Finck DWORD WINAPI 107*46b91659SColin Finck EnumPrinterKeyA(HANDLE hPrinter, PCSTR pKeyName, PSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey) 108*46b91659SColin Finck { 109*46b91659SColin Finck TRACE("EnumPrinterKeyA(%p, %s, %s, %lu, %p)\n", hPrinter, pKeyName, pSubkey, cbSubkey, pcbSubkey); 110*46b91659SColin Finck UNIMPLEMENTED; 111*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 112*46b91659SColin Finck } 113*46b91659SColin Finck 114*46b91659SColin Finck DWORD WINAPI 115*46b91659SColin Finck EnumPrinterKeyW(HANDLE hPrinter, PCWSTR pKeyName, PWSTR pSubkey, DWORD cbSubkey, PDWORD pcbSubkey) 116*46b91659SColin Finck { 117*46b91659SColin Finck TRACE("EnumPrinterKeyW(%p, %S, %S, %lu, %p)\n", hPrinter, pKeyName, pSubkey, cbSubkey, pcbSubkey); 118*46b91659SColin Finck UNIMPLEMENTED; 119*46b91659SColin Finck return ERROR_NOT_SUPPORTED; 120c2c66affSColin Finck } 121c2c66affSColin Finck 122c2c66affSColin Finck DWORD WINAPI 123c2c66affSColin Finck GetPrinterDataA(HANDLE hPrinter, LPSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded) 124c2c66affSColin Finck { 1251f6f08ecSColin Finck TRACE("GetPrinterDataA(%p, %s, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded); 126c2c66affSColin Finck return GetPrinterDataExA(hPrinter, "PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded); 127c2c66affSColin Finck } 128c2c66affSColin Finck 129c2c66affSColin Finck DWORD WINAPI 130c2c66affSColin Finck GetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded) 131c2c66affSColin Finck { 132c2c66affSColin Finck DWORD cbUnicodeData; 133c2c66affSColin Finck DWORD cch; 134c2c66affSColin Finck DWORD dwReturnValue; 135c2c66affSColin Finck DWORD dwType; 136c2c66affSColin Finck POSVERSIONINFOEXA pInfoA; 137c2c66affSColin Finck POSVERSIONINFOEXW pInfoW; 138c2c66affSColin Finck PVOID pUnicodeData = NULL; 139c2c66affSColin Finck PWSTR pwszKeyName = NULL; 140c2c66affSColin Finck PWSTR pwszValueName = NULL; 141c2c66affSColin Finck 1421f6f08ecSColin Finck TRACE("GetPrinterDataExA(%p, %s, %s, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded); 1431f6f08ecSColin Finck 144c2c66affSColin Finck if (pKeyName) 145c2c66affSColin Finck { 146c2c66affSColin Finck // Convert pKeyName to a Unicode string pwszKeyName 147c2c66affSColin Finck cch = strlen(pKeyName); 148c2c66affSColin Finck 149c2c66affSColin Finck pwszKeyName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 150c2c66affSColin Finck if (!pwszKeyName) 151c2c66affSColin Finck { 152c2c66affSColin Finck dwReturnValue = ERROR_NOT_ENOUGH_MEMORY; 153c2c66affSColin Finck ERR("HeapAlloc failed!\n"); 154c2c66affSColin Finck goto Cleanup; 155c2c66affSColin Finck } 156c2c66affSColin Finck 157c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, pwszKeyName, cch + 1); 158c2c66affSColin Finck } 159c2c66affSColin Finck 160c2c66affSColin Finck if (pValueName) 161c2c66affSColin Finck { 162c2c66affSColin Finck // Convert pValueName to a Unicode string pwszValueName 163c2c66affSColin Finck cch = strlen(pValueName); 164c2c66affSColin Finck 165c2c66affSColin Finck pwszValueName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 166c2c66affSColin Finck if (!pwszValueName) 167c2c66affSColin Finck { 168c2c66affSColin Finck dwReturnValue = ERROR_NOT_ENOUGH_MEMORY; 169c2c66affSColin Finck ERR("HeapAlloc failed!\n"); 170c2c66affSColin Finck goto Cleanup; 171c2c66affSColin Finck } 172c2c66affSColin Finck 173c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, pValueName, -1, pwszValueName, cch + 1); 174c2c66affSColin Finck } 175c2c66affSColin Finck 176c2c66affSColin Finck // We need the data type information, even if no pData was passed. 177c2c66affSColin Finck if (!pType) 178c2c66affSColin Finck pType = &dwType; 179c2c66affSColin Finck 180c2c66affSColin Finck // Call GetPrinterDataExW for the first time. 181c2c66affSColin 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. 182c2c66affSColin Finck dwReturnValue = GetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, pType, pData, nSize, pcbNeeded); 183c2c66affSColin Finck 184c2c66affSColin Finck // If a critical error occurred, just return it. We cannot do anything else in this case. 185c2c66affSColin Finck if (dwReturnValue != ERROR_SUCCESS && dwReturnValue != ERROR_MORE_DATA) 186c2c66affSColin Finck goto Cleanup; 187c2c66affSColin Finck 188c2c66affSColin Finck // Save the needed buffer size for the Unicode data. We may alter *pcbNeeded for an ANSI buffer size. 189c2c66affSColin Finck cbUnicodeData = *pcbNeeded; 190c2c66affSColin Finck 191c2c66affSColin Finck if (*pType == REG_SZ || *pType == REG_MULTI_SZ || *pType == REG_EXPAND_SZ) 192c2c66affSColin Finck { 193c2c66affSColin Finck // This is a string that needs to be converted from Unicode to ANSI. 194c2c66affSColin Finck // Output the required buffer size for the ANSI string. 195c2c66affSColin Finck *pcbNeeded /= sizeof(WCHAR); 196c2c66affSColin Finck } 197c2c66affSColin Finck else if (*pType == REG_NONE) 198c2c66affSColin Finck { 199c2c66affSColin Finck if (cbUnicodeData == sizeof(OSVERSIONINFOW) && wcsicmp(pwszValueName, SPLREG_OS_VERSION) == 0) 200c2c66affSColin Finck { 201c2c66affSColin Finck // This is a Unicode OSVERSIONINFOW structure that needs to be converted to an ANSI OSVERSIONINFOA. 202c2c66affSColin Finck *pcbNeeded = sizeof(OSVERSIONINFOA); 203c2c66affSColin Finck } 204c2c66affSColin Finck else if (cbUnicodeData == sizeof(OSVERSIONINFOEXW) && wcsicmp(pwszValueName, SPLREG_OS_VERSIONEX) == 0) 205c2c66affSColin Finck { 206c2c66affSColin Finck // This is a Unicode OSVERSIONINFOEXW structure that needs to be converted to an ANSI OSVERSIONINFOEXA. 207c2c66affSColin Finck *pcbNeeded = sizeof(OSVERSIONINFOEXA); 208c2c66affSColin Finck } 209c2c66affSColin Finck else 210c2c66affSColin Finck { 211c2c66affSColin Finck // Other REG_NONE value, nothing to do. 212c2c66affSColin Finck goto Cleanup; 213c2c66affSColin Finck } 214c2c66affSColin Finck } 215c2c66affSColin Finck 216c2c66affSColin Finck // Check if the supplied buffer is large enough for the ANSI data. 217c2c66affSColin Finck if (nSize < *pcbNeeded) 218c2c66affSColin Finck { 219c2c66affSColin Finck dwReturnValue = ERROR_MORE_DATA; 220c2c66affSColin Finck goto Cleanup; 221c2c66affSColin Finck } 222c2c66affSColin Finck 223c2c66affSColin Finck // Allocate a temporary buffer for the Unicode data. 224c2c66affSColin Finck pUnicodeData = HeapAlloc(hProcessHeap, 0, cbUnicodeData); 225c2c66affSColin Finck if (!pUnicodeData) 226c2c66affSColin Finck { 227c2c66affSColin Finck dwReturnValue = ERROR_NOT_ENOUGH_MEMORY; 228c2c66affSColin Finck ERR("HeapAlloc failed!\n"); 229c2c66affSColin Finck goto Cleanup; 230c2c66affSColin Finck } 231c2c66affSColin Finck 232c2c66affSColin Finck if (dwReturnValue == ERROR_SUCCESS) 233c2c66affSColin Finck { 234c2c66affSColin Finck // ERROR_SUCCESS: The buffer is large enough for the ANSI and the Unicode string, 235c2c66affSColin Finck // so the Unicode string has been copied into pData. Copy it to pUnicodeData. 236c2c66affSColin Finck CopyMemory(pUnicodeData, pData, cbUnicodeData); 237c2c66affSColin Finck } 238c2c66affSColin Finck else 239c2c66affSColin Finck { 240c2c66affSColin Finck // ERROR_MORE_DATA: The buffer is large enough for the ANSI string, but not for the Unicode string. 241c2c66affSColin Finck // We have to call GetPrinterDataExW again with the temporary buffer. 242c2c66affSColin Finck dwReturnValue = GetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, NULL, (PBYTE)pUnicodeData, cbUnicodeData, &cbUnicodeData); 243c2c66affSColin Finck if (dwReturnValue != ERROR_SUCCESS) 244c2c66affSColin Finck goto Cleanup; 245c2c66affSColin Finck } 246c2c66affSColin Finck 247c2c66affSColin Finck if (*pType == REG_SZ || *pType == REG_MULTI_SZ || *pType == REG_EXPAND_SZ) 248c2c66affSColin Finck { 249c2c66affSColin Finck // Convert the Unicode string to ANSI. 250c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 0, (PWSTR)pUnicodeData, -1, (PSTR)pData, *pcbNeeded, NULL, NULL); 251c2c66affSColin Finck } 252c2c66affSColin Finck else 253c2c66affSColin Finck { 254c2c66affSColin Finck // This is a REG_NONE with either OSVERSIONINFOW or OSVERSIONINFOEXW. 255c2c66affSColin Finck // Copy the fields and convert the Unicode CSD Version string to ANSI. 256c2c66affSColin Finck pInfoW = (POSVERSIONINFOEXW)pUnicodeData; 257c2c66affSColin Finck pInfoA = (POSVERSIONINFOEXA)pData; 258c2c66affSColin Finck pInfoA->dwMajorVersion = pInfoW->dwMajorVersion; 259c2c66affSColin Finck pInfoA->dwMinorVersion = pInfoW->dwMinorVersion; 260c2c66affSColin Finck pInfoA->dwBuildNumber = pInfoW->dwBuildNumber; 261c2c66affSColin Finck pInfoA->dwPlatformId = pInfoW->dwPlatformId; 262c2c66affSColin Finck WideCharToMultiByte(CP_ACP, 0, pInfoW->szCSDVersion, -1, pInfoA->szCSDVersion, sizeof(pInfoA->szCSDVersion), NULL, NULL); 263c2c66affSColin Finck 264c2c66affSColin Finck if (cbUnicodeData == sizeof(OSVERSIONINFOW)) 265c2c66affSColin Finck { 266c2c66affSColin Finck pInfoA->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); 267c2c66affSColin Finck } 268c2c66affSColin Finck else 269c2c66affSColin Finck { 270c2c66affSColin Finck pInfoA->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); 271c2c66affSColin Finck pInfoA->wServicePackMajor = pInfoW->wServicePackMajor; 272c2c66affSColin Finck pInfoA->wServicePackMinor = pInfoW->wServicePackMinor; 273c2c66affSColin Finck pInfoA->wSuiteMask = pInfoW->wSuiteMask; 274c2c66affSColin Finck pInfoA->wProductType = pInfoW->wProductType; 275c2c66affSColin Finck pInfoA->wReserved = pInfoW->wReserved; 276c2c66affSColin Finck } 277c2c66affSColin Finck } 278c2c66affSColin Finck 279c2c66affSColin Finck Cleanup: 280c2c66affSColin Finck if (pwszKeyName) 281c2c66affSColin Finck HeapFree(hProcessHeap, 0, pwszKeyName); 282c2c66affSColin Finck 283c2c66affSColin Finck if (pwszValueName) 284c2c66affSColin Finck HeapFree(hProcessHeap, 0, pwszValueName); 285c2c66affSColin Finck 286c2c66affSColin Finck if (pUnicodeData) 287c2c66affSColin Finck HeapFree(hProcessHeap, 0, pUnicodeData); 288c2c66affSColin Finck 289c2c66affSColin Finck return dwReturnValue; 290c2c66affSColin Finck } 291c2c66affSColin Finck 292c2c66affSColin Finck DWORD WINAPI 293c2c66affSColin Finck GetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded) 294c2c66affSColin Finck { 295c2c66affSColin Finck const WCHAR wszEmptyString[] = L""; 296c2c66affSColin Finck 297c2c66affSColin Finck BYTE DummyData; 298c2c66affSColin Finck DWORD dwErrorCode; 299c2c66affSColin Finck DWORD dwType = REG_NONE; 300c2c66affSColin Finck PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; 301c2c66affSColin Finck 3021f6f08ecSColin Finck TRACE("GetPrinterDataExW(%p, %S, %S, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded); 3031f6f08ecSColin Finck 304c2c66affSColin Finck // Sanity checks 305c2c66affSColin Finck if (!pHandle) 306c2c66affSColin Finck return ERROR_INVALID_HANDLE; 307c2c66affSColin Finck 308c2c66affSColin Finck // Yes, instead of declaring these pointers unique in the IDL file (and perfectly accepting NULL pointers this way), 309c2c66affSColin Finck // Windows does it differently for GetPrinterDataExW and points them to empty variables. 310c2c66affSColin Finck if (!pKeyName) 311c2c66affSColin Finck pKeyName = wszEmptyString; 312c2c66affSColin Finck 313c2c66affSColin Finck if (!pType) 314c2c66affSColin Finck pType = &dwType; 315c2c66affSColin Finck 316c2c66affSColin Finck if (!pData && !nSize) 317c2c66affSColin Finck pData = &DummyData; 318c2c66affSColin Finck 319c2c66affSColin Finck // Do the RPC call 320c2c66affSColin Finck RpcTryExcept 321c2c66affSColin Finck { 322c2c66affSColin Finck dwErrorCode = _RpcGetPrinterDataEx(pHandle->hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded); 323c2c66affSColin Finck } 324c2c66affSColin Finck RpcExcept(EXCEPTION_EXECUTE_HANDLER) 325c2c66affSColin Finck { 326c2c66affSColin Finck dwErrorCode = RpcExceptionCode(); 327c2c66affSColin Finck } 328c2c66affSColin Finck RpcEndExcept; 329c2c66affSColin Finck 330c2c66affSColin Finck return dwErrorCode; 331c2c66affSColin Finck } 332c2c66affSColin Finck 333c2c66affSColin Finck DWORD WINAPI 334c2c66affSColin Finck GetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, DWORD nSize, LPDWORD pcbNeeded) 335c2c66affSColin Finck { 3361f6f08ecSColin Finck TRACE("GetPrinterDataW(%p, %S, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded); 337c2c66affSColin Finck return GetPrinterDataExW(hPrinter, L"PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded); 338c2c66affSColin Finck } 339c2c66affSColin Finck 340c2c66affSColin Finck DWORD WINAPI 341c2c66affSColin Finck SetPrinterDataA(HANDLE hPrinter, PSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData) 342c2c66affSColin Finck { 3431f6f08ecSColin Finck TRACE("SetPrinterDataA(%p, %s, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData); 344c2c66affSColin Finck return SetPrinterDataExA(hPrinter, "PrinterDriverData", pValueName, Type, pData, cbData); 345c2c66affSColin Finck } 346c2c66affSColin Finck 347c2c66affSColin Finck DWORD WINAPI 348c2c66affSColin Finck SetPrinterDataExA(HANDLE hPrinter, LPCSTR pKeyName, LPCSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData) 349c2c66affSColin Finck { 350c2c66affSColin Finck DWORD cch; 351c2c66affSColin Finck DWORD dwReturnValue; 352c2c66affSColin Finck PWSTR pwszKeyName = NULL; 353c2c66affSColin Finck PWSTR pwszValueName = NULL; 354c2c66affSColin Finck PWSTR pUnicodeData = NULL; 355c2c66affSColin Finck 3561f6f08ecSColin Finck TRACE("SetPrinterDataExA(%p, %s, %s, %lu, %p, %lu)\n", hPrinter, pKeyName, pValueName, Type, pData, cbData); 3571f6f08ecSColin Finck 358c2c66affSColin Finck if (pKeyName) 359c2c66affSColin Finck { 360c2c66affSColin Finck // Convert pKeyName to a Unicode string pwszKeyName 361c2c66affSColin Finck cch = strlen(pKeyName); 362c2c66affSColin Finck 363c2c66affSColin Finck pwszKeyName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 364c2c66affSColin Finck if (!pwszKeyName) 365c2c66affSColin Finck { 366c2c66affSColin Finck dwReturnValue = ERROR_NOT_ENOUGH_MEMORY; 367c2c66affSColin Finck ERR("HeapAlloc failed!\n"); 368c2c66affSColin Finck goto Cleanup; 369c2c66affSColin Finck } 370c2c66affSColin Finck 371c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, pKeyName, -1, pwszKeyName, cch + 1); 372c2c66affSColin Finck } 373c2c66affSColin Finck 374c2c66affSColin Finck if (pValueName) 375c2c66affSColin Finck { 376c2c66affSColin Finck // Convert pValueName to a Unicode string pwszValueName 377c2c66affSColin Finck cch = strlen(pValueName); 378c2c66affSColin Finck 379c2c66affSColin Finck pwszValueName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 380c2c66affSColin Finck if (!pwszValueName) 381c2c66affSColin Finck { 382c2c66affSColin Finck dwReturnValue = ERROR_NOT_ENOUGH_MEMORY; 383c2c66affSColin Finck ERR("HeapAlloc failed!\n"); 384c2c66affSColin Finck goto Cleanup; 385c2c66affSColin Finck } 386c2c66affSColin Finck 387c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, pValueName, -1, pwszValueName, cch + 1); 388c2c66affSColin Finck } 389c2c66affSColin Finck 390c2c66affSColin Finck if (Type == REG_SZ || Type == REG_MULTI_SZ || Type == REG_EXPAND_SZ) 391c2c66affSColin Finck { 392c2c66affSColin Finck // Convert pData to a Unicode string pUnicodeData. 393c2c66affSColin Finck pUnicodeData = HeapAlloc(hProcessHeap, 0, cbData * sizeof(WCHAR)); 394c2c66affSColin Finck if (!pUnicodeData) 395c2c66affSColin Finck { 396c2c66affSColin Finck dwReturnValue = ERROR_NOT_ENOUGH_MEMORY; 397c2c66affSColin Finck ERR("HeapAlloc failed!\n"); 398c2c66affSColin Finck goto Cleanup; 399c2c66affSColin Finck } 400c2c66affSColin Finck 401c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, (PCSTR)pData, -1, pUnicodeData, cbData); 402c2c66affSColin Finck 403c2c66affSColin Finck pData = (PBYTE)pUnicodeData; 404c2c66affSColin Finck cbData *= sizeof(WCHAR); 405c2c66affSColin Finck } 406c2c66affSColin Finck 407c2c66affSColin Finck dwReturnValue = SetPrinterDataExW(hPrinter, pwszKeyName, pwszValueName, Type, pData, cbData); 408c2c66affSColin Finck 409c2c66affSColin Finck Cleanup: 410c2c66affSColin Finck if (pwszKeyName) 411c2c66affSColin Finck HeapFree(hProcessHeap, 0, pwszKeyName); 412c2c66affSColin Finck 413c2c66affSColin Finck if (pwszValueName) 414c2c66affSColin Finck HeapFree(hProcessHeap, 0, pwszValueName); 415c2c66affSColin Finck 416c2c66affSColin Finck if (pUnicodeData) 417c2c66affSColin Finck HeapFree(hProcessHeap, 0, pUnicodeData); 418c2c66affSColin Finck 419c2c66affSColin Finck return dwReturnValue; 420c2c66affSColin Finck } 421c2c66affSColin Finck 422c2c66affSColin Finck DWORD WINAPI 423c2c66affSColin Finck SetPrinterDataExW(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData) 424c2c66affSColin Finck { 425c2c66affSColin Finck const WCHAR wszEmptyString[] = L""; 426c2c66affSColin Finck 427c2c66affSColin Finck DWORD dwErrorCode; 428c2c66affSColin Finck PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; 429c2c66affSColin Finck 4301f6f08ecSColin Finck TRACE("SetPrinterDataExW(%p, %S, %S, %lu, %p, %lu)\n", hPrinter, pKeyName, pValueName, Type, pData, cbData); 4311f6f08ecSColin Finck 432c2c66affSColin Finck // Sanity checks 433c2c66affSColin Finck if (!pHandle) 434c2c66affSColin Finck return ERROR_INVALID_HANDLE; 435c2c66affSColin Finck 436c2c66affSColin Finck if (!pKeyName) 437c2c66affSColin Finck pKeyName = wszEmptyString; 438c2c66affSColin Finck 439c2c66affSColin Finck // Do the RPC call 440c2c66affSColin Finck RpcTryExcept 441c2c66affSColin Finck { 442c2c66affSColin Finck dwErrorCode = _RpcSetPrinterDataEx(pHandle->hPrinter, pKeyName, pValueName, Type, pData, cbData); 443c2c66affSColin Finck } 444c2c66affSColin Finck RpcExcept(EXCEPTION_EXECUTE_HANDLER) 445c2c66affSColin Finck { 446c2c66affSColin Finck dwErrorCode = RpcExceptionCode(); 447c2c66affSColin Finck } 448c2c66affSColin Finck RpcEndExcept; 449c2c66affSColin Finck 450c2c66affSColin Finck return dwErrorCode; 451c2c66affSColin Finck } 452c2c66affSColin Finck 453c2c66affSColin Finck DWORD WINAPI 454c2c66affSColin Finck SetPrinterDataW(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData) 455c2c66affSColin Finck { 4561f6f08ecSColin Finck TRACE("SetPrinterDataW(%p, %S, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData); 457c2c66affSColin Finck return SetPrinterDataExW(hPrinter, L"PrinterDriverData", pValueName, Type, pData, cbData); 458c2c66affSColin Finck } 459