From: Colin Finck Date: Sun, 10 Dec 2017 11:28:08 +0000 (+0100) Subject: [PRINTING] Fix GetPrinterW, add tests for it and GetDefaultPrinterA/W, and add a... X-Git-Tag: 0.4.9-dev~694 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=3a69fd4e966feb867fd730442a971041ade3965a [PRINTING] Fix GetPrinterW, add tests for it and GetDefaultPrinterA/W, and add a proper stub for GetPrinterDriverDirectoryA. * Pass the correct handle to _RpcGetPrinter in GetPrinterW. * Pass an empty string instead of a NULL pointer as wszComputerName to the GetPrinterLevel* functions, because this variable is later used as source for StringCbCopyExW. * Don't check for GetLastError() == ERROR_SUCCESS in tests. Windows apparently only sets the last error in case of failure. The Printing code should probably be changed similarly in a future commit. Should fix CORE-14072 --- diff --git a/modules/rostests/apitests/winspool/CMakeLists.txt b/modules/rostests/apitests/winspool/CMakeLists.txt index 803d3d0c896..3a5bd52db5c 100644 --- a/modules/rostests/apitests/winspool/CMakeLists.txt +++ b/modules/rostests/apitests/winspool/CMakeLists.txt @@ -4,6 +4,7 @@ list(APPEND SOURCE EnumPrinters.c EnumPrintProcessorDatatypes.c GetDefaultPrinter.c + GetPrinter.c GetPrinterData.c GetPrintProcessorDirectory.c IsValidDevmode.c diff --git a/modules/rostests/apitests/winspool/GetDefaultPrinter.c b/modules/rostests/apitests/winspool/GetDefaultPrinter.c index 728f10c24e3..b40e74f5f0d 100644 --- a/modules/rostests/apitests/winspool/GetDefaultPrinter.c +++ b/modules/rostests/apitests/winspool/GetDefaultPrinter.c @@ -13,7 +13,44 @@ #include #include -START_TEST(GetDefaultPrinter) +START_TEST(GetDefaultPrinterA) +{ + DWORD cchDefaultPrinter; + PSTR pszDefaultPrinter; + + // Don't supply any parameters, this has to fail with ERROR_INVALID_PARAMETER. + SetLastError(0xDEADBEEF); + ok(!GetDefaultPrinterA(NULL, NULL), "GetDefaultPrinterA returns TRUE!\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetDefaultPrinterA returns error %lu!\n", GetLastError()); + + // Determine the size of the required buffer. This has to bail out with ERROR_INSUFFICIENT_BUFFER. + cchDefaultPrinter = 0; + SetLastError(0xDEADBEEF); + ok(!GetDefaultPrinterA(NULL, &cchDefaultPrinter), "GetDefaultPrinterA returns TRUE!\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetDefaultPrinterA returns error %lu!\n", GetLastError()); + + // Try with a buffer large enough. + pszDefaultPrinter = HeapAlloc(GetProcessHeap(), 0, cchDefaultPrinter); + SetLastError(0xDEADBEEF); + ok(GetDefaultPrinterA(pszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterA returns FALSE!\n"); + + // SetDefaultPrinterA with NULL needs to succeed and leave the default printer unchanged. + SetLastError(0xDEADBEEF); + ok(SetDefaultPrinterA(NULL), "SetDefaultPrinterA returns FALSE!\n"); + + // SetDefaultPrinterA with the previous default printer also needs to succeed. + SetLastError(0xDEADBEEF); + ok(SetDefaultPrinterA(pszDefaultPrinter), "SetDefaultPrinterA returns FALSE!\n"); + + // SetDefaultPrinterA with an invalid printer name needs to fail with ERROR_INVALID_PRINTER_NAME. + SetLastError(0xDEADBEEF); + ok(!SetDefaultPrinterA("INVALID PRINTER NAME!!!"), "SetDefaultPrinterA returns TRUE!\n"); + ok(GetLastError() == ERROR_INVALID_PRINTER_NAME, "SetDefaultPrinterA returns error %lu!\n", GetLastError()); + + HeapFree(GetProcessHeap(), 0, pszDefaultPrinter); +} + +START_TEST(GetDefaultPrinterW) { DWORD cchDefaultPrinter; PWSTR pwszDefaultPrinter; @@ -33,17 +70,14 @@ START_TEST(GetDefaultPrinter) pwszDefaultPrinter = HeapAlloc(GetProcessHeap(), 0, cchDefaultPrinter * sizeof(WCHAR)); SetLastError(0xDEADBEEF); ok(GetDefaultPrinterW(pwszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterW returns FALSE!\n"); - ok(GetLastError() == ERROR_SUCCESS, "GetDefaultPrinterW returns error %lu!\n", GetLastError()); // SetDefaultPrinterW with NULL needs to succeed and leave the default printer unchanged. SetLastError(0xDEADBEEF); ok(SetDefaultPrinterW(NULL), "SetDefaultPrinterW returns FALSE!\n"); - ok(GetLastError() == ERROR_SUCCESS, "SetDefaultPrinterW returns error %lu!\n", GetLastError()); // SetDefaultPrinterW with the previous default printer also needs to succeed. SetLastError(0xDEADBEEF); ok(SetDefaultPrinterW(pwszDefaultPrinter), "SetDefaultPrinterW returns FALSE!\n"); - ok(GetLastError() == ERROR_SUCCESS, "SetDefaultPrinterW returns error %lu!\n", GetLastError()); // SetDefaultPrinterW with an invalid printer name needs to fail with ERROR_INVALID_PRINTER_NAME. SetLastError(0xDEADBEEF); diff --git a/modules/rostests/apitests/winspool/GetPrinter.c b/modules/rostests/apitests/winspool/GetPrinter.c new file mode 100644 index 00000000000..608f8f5a51a --- /dev/null +++ b/modules/rostests/apitests/winspool/GetPrinter.c @@ -0,0 +1,65 @@ +/* + * PROJECT: ReactOS Print Spooler DLL API Tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Tests for GetPrinterA/GetPrinterW + * COPYRIGHT: Copyright 2017 Colin Finck (colin@reactos.org) + */ + +#include + +#define WIN32_NO_STATUS +#include +#include +#include +#include + +/* From printing/include/spoolss.h */ +#define MAX_PRINTER_NAME 220 + +START_TEST(GetPrinter) +{ + DWORD cbNeeded; + DWORD cbTemp; + DWORD cchDefaultPrinter; + DWORD Level; + HANDLE hPrinter; + PVOID pMem; + WCHAR wszDefaultPrinter[MAX_PRINTER_NAME + 1]; + + // Open a handle to the default printer. + cchDefaultPrinter = _countof(wszDefaultPrinter); + ok(GetDefaultPrinterW(wszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterW returns FALSE and requires %lu characters!\n", cchDefaultPrinter); + if (!OpenPrinterW(wszDefaultPrinter, &hPrinter, NULL)) + { + skip("Could not retrieve a handle to the default printer!\n"); + return; + } + + // Try for all levels. Level 0 is valid here and returns the PRINTER_INFO_STRESS structure (documented in MS-RPRN). + for (Level = 0; Level <= 9; Level++) + { + // Try with no valid arguments at all. + SetLastError(0xDEADBEEF); + ok(!GetPrinterW(NULL, Level, NULL, 0, NULL), "GetPrinterW returns TRUE for Level %lu!\n", Level); + ok(GetLastError() == ERROR_INVALID_HANDLE, "GetPrinterW returns error %lu for Level %lu!\n", GetLastError(), Level); + + // Now supply at least a handle. + SetLastError(0xDEADBEEF); + ok(!GetPrinterW(hPrinter, Level, NULL, 0, NULL), "GetPrinterW returns TRUE for Level %lu!\n", Level); + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "GetPrinterW returns error %lu for Level %lu!\n", GetLastError(), Level); + + // Now get the buffer size. + SetLastError(0xDEADBEEF); + ok(!GetPrinterW(hPrinter, Level, NULL, 0, &cbNeeded), "GetPrinterW returns TRUE for Level %lu!\n", Level); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetPrinterW returns error %lu for Level %lu!\n", GetLastError(), Level); + + // Finally use the function as intended and aim for success! + pMem = HeapAlloc(GetProcessHeap(), 0, cbNeeded); + SetLastError(0xDEADBEEF); + ok(GetPrinterW(hPrinter, Level, pMem, cbNeeded, &cbTemp), "GetPrinterW returns FALSE for Level %lu!\n", Level); + ok(cbNeeded == cbTemp, "cbNeeded is %lu, reference size is %lu for Level %lu!\n", cbNeeded, cbTemp, Level); + HeapFree(GetProcessHeap(), 0, pMem); + } + + ClosePrinter(hPrinter); +} diff --git a/modules/rostests/apitests/winspool/testlist.c b/modules/rostests/apitests/winspool/testlist.c index e08bffdd324..445de7a6e1c 100644 --- a/modules/rostests/apitests/winspool/testlist.c +++ b/modules/rostests/apitests/winspool/testlist.c @@ -13,7 +13,9 @@ extern void func_ClosePrinter(void); extern void func_EnumPrinters(void); extern void func_EnumPrintProcessorDatatypes(void); -extern void func_GetDefaultPrinter(void); +extern void func_GetDefaultPrinterA(void); +extern void func_GetDefaultPrinterW(void); +extern void func_GetPrinter(void); extern void func_GetPrinterData(void); extern void func_GetPrintProcessorDirectoryA(void); extern void func_GetPrintProcessorDirectoryW(void); @@ -27,7 +29,9 @@ const struct test winetest_testlist[] = { "ClosePrinter", func_ClosePrinter }, { "EnumPrinters", func_EnumPrinters }, { "EnumPrintProcessorDatatypes", func_EnumPrintProcessorDatatypes }, - { "GetDefaultPrinter", func_GetDefaultPrinter }, + { "GetDefaultPrinterA", func_GetDefaultPrinterA }, + { "GetDefaultPrinterW", func_GetDefaultPrinterW }, + { "GetPrinter", func_GetPrinter }, { "GetPrinterData", func_GetPrinterData }, { "GetPrintProcessorDirectoryA", func_GetPrintProcessorDirectoryA }, { "GetPrintProcessorDirectoryW", func_GetPrintProcessorDirectoryW }, diff --git a/win32ss/printing/base/winspool/printerdrivers.c b/win32ss/printing/base/winspool/printerdrivers.c index de877810856..07ba18c1311 100644 --- a/win32ss/printing/base/winspool/printerdrivers.c +++ b/win32ss/printing/base/winspool/printerdrivers.c @@ -87,6 +87,14 @@ EnumPrinterDriversW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverI return FALSE; } +BOOL WINAPI +GetPrinterDriverDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded) +{ + TRACE("GetPrinterDriverDirectoryA(%s, %s, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded); + UNIMPLEMENTED; + return FALSE; +} + BOOL WINAPI GetPrinterDriverDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded) { diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index ffe18230897..471db1339e1 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -630,9 +630,17 @@ BOOL WINAPI GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) { DWORD dwErrorCode; + PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; TRACE("GetPrinterW(%p, %lu, %p, %lu, %p)\n", hPrinter, Level, pPrinter, cbBuf, pcbNeeded); + // Sanity checks. + if (!pHandle) + { + dwErrorCode = ERROR_INVALID_HANDLE; + goto Cleanup; + } + // Dismiss invalid levels already at this point. if (Level > 9) { @@ -646,7 +654,7 @@ GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD // Do the RPC call RpcTryExcept { - dwErrorCode = _RpcGetPrinter(hPrinter, Level, pPrinter, cbBuf, pcbNeeded); + dwErrorCode = _RpcGetPrinter(pHandle->hPrinter, Level, pPrinter, cbBuf, pcbNeeded); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { diff --git a/win32ss/printing/base/winspool/winspool.spec b/win32ss/printing/base/winspool/winspool.spec index 5d8fed463e5..7c2888b236b 100644 --- a/win32ss/printing/base/winspool/winspool.spec +++ b/win32ss/printing/base/winspool/winspool.spec @@ -152,7 +152,7 @@ 251 stdcall GetPrinterDataExW(ptr wstr wstr ptr ptr long ptr) 252 stdcall GetPrinterDataW(ptr wstr ptr ptr long ptr) 253 stdcall GetPrinterDriverA(ptr str long ptr long ptr) -254 stdcall -stub GetPrinterDriverDirectoryA(str str long ptr long ptr) +254 stdcall GetPrinterDriverDirectoryA(str str long ptr long ptr) 255 stdcall GetPrinterDriverDirectoryW(wstr wstr long ptr long ptr) 256 stdcall GetPrinterDriverW(ptr wstr long ptr long ptr) 257 stdcall GetPrinterW(ptr long ptr long ptr) diff --git a/win32ss/printing/providers/localspl/printers.c b/win32ss/printing/providers/localspl/printers.c index 022fd39a3e0..7c9c2dd3b53 100644 --- a/win32ss/printing/providers/localspl/printers.c +++ b/win32ss/printing/providers/localspl/printers.c @@ -11,19 +11,19 @@ SKIPLIST PrinterList; // Forward Declarations -static void _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); -static void _LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); +static void _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); +static void _LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); // Local Constants -typedef void (*PLocalGetPrinterLevelFunc)(PLOCAL_PRINTER, PVOID, PBYTE*, PDWORD, DWORD, PWSTR); +typedef void (*PLocalGetPrinterLevelFunc)(PLOCAL_PRINTER, PVOID, PBYTE*, PDWORD, DWORD, PCWSTR); static const PLocalGetPrinterLevelFunc pfnGetPrinterLevels[] = { (PLocalGetPrinterLevelFunc)&_LocalGetPrinterLevel0, @@ -488,7 +488,7 @@ _DumpLevel1PrintProviderInformation(PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbN } static void -_LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { size_t cbName; PWSTR p; @@ -535,7 +535,7 @@ _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterI } static void -_LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { const WCHAR wszComma[] = L","; @@ -590,7 +590,7 @@ _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, } static void -_LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { WCHAR wszEmpty[] = L""; @@ -682,7 +682,7 @@ _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, } static void -_LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { SECURITY_DESCRIPTOR SecurityDescriptor = { 0 }; @@ -704,7 +704,7 @@ _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, } static void -_LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { size_t cbPrinterName; PWSTR p; @@ -738,7 +738,7 @@ _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, } static void -_LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { size_t cbPrinterName; size_t cbPortName; @@ -779,7 +779,7 @@ _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, } static void -_LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { if (!ppPrinterInfo) { @@ -795,7 +795,7 @@ _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, } static void -_LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { if (!ppPrinterInfo) { @@ -814,7 +814,7 @@ _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, } static void -_LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { DWORD cbDevMode; @@ -837,7 +837,7 @@ _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, } static void -_LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) +_LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) { DWORD cbDevMode; @@ -965,6 +965,10 @@ Cleanup: BOOL WINAPI LocalGetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) { + // We never prepend a Computer Name to the output, but need to provide an empty string, + // because this variable is passed to StringCbCopyExW. + const WCHAR wszDummyComputerName[] = L""; + DWORD dwErrorCode; PBYTE pPrinterEnd; PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter; @@ -997,7 +1001,7 @@ LocalGetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDW // Count the required buffer size. *pcbNeeded = 0; - pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, NULL, NULL, pcbNeeded, 0, NULL); + pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, NULL, NULL, pcbNeeded, 0, wszDummyComputerName); // Check if the supplied buffer is large enough. if (cbBuf < *pcbNeeded) @@ -1008,7 +1012,7 @@ LocalGetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDW // Copy over the Printer information. pPrinterEnd = &pPrinter[*pcbNeeded]; - pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, &pPrinter, &pPrinterEnd, NULL, 0, NULL); + pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, &pPrinter, &pPrinterEnd, NULL, 0, wszDummyComputerName); dwErrorCode = ERROR_SUCCESS; Cleanup: