Reactos

[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

+155 -31
+1
modules/rostests/apitests/winspool/CMakeLists.txt
··· 4 4 EnumPrinters.c 5 5 EnumPrintProcessorDatatypes.c 6 6 GetDefaultPrinter.c 7 + GetPrinter.c 7 8 GetPrinterData.c 8 9 GetPrintProcessorDirectory.c 9 10 IsValidDevmode.c
+38 -4
modules/rostests/apitests/winspool/GetDefaultPrinter.c
··· 13 13 #include <wingdi.h> 14 14 #include <winspool.h> 15 15 16 - START_TEST(GetDefaultPrinter) 16 + START_TEST(GetDefaultPrinterA) 17 + { 18 + DWORD cchDefaultPrinter; 19 + PSTR pszDefaultPrinter; 20 + 21 + // Don't supply any parameters, this has to fail with ERROR_INVALID_PARAMETER. 22 + SetLastError(0xDEADBEEF); 23 + ok(!GetDefaultPrinterA(NULL, NULL), "GetDefaultPrinterA returns TRUE!\n"); 24 + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetDefaultPrinterA returns error %lu!\n", GetLastError()); 25 + 26 + // Determine the size of the required buffer. This has to bail out with ERROR_INSUFFICIENT_BUFFER. 27 + cchDefaultPrinter = 0; 28 + SetLastError(0xDEADBEEF); 29 + ok(!GetDefaultPrinterA(NULL, &cchDefaultPrinter), "GetDefaultPrinterA returns TRUE!\n"); 30 + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetDefaultPrinterA returns error %lu!\n", GetLastError()); 31 + 32 + // Try with a buffer large enough. 33 + pszDefaultPrinter = HeapAlloc(GetProcessHeap(), 0, cchDefaultPrinter); 34 + SetLastError(0xDEADBEEF); 35 + ok(GetDefaultPrinterA(pszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterA returns FALSE!\n"); 36 + 37 + // SetDefaultPrinterA with NULL needs to succeed and leave the default printer unchanged. 38 + SetLastError(0xDEADBEEF); 39 + ok(SetDefaultPrinterA(NULL), "SetDefaultPrinterA returns FALSE!\n"); 40 + 41 + // SetDefaultPrinterA with the previous default printer also needs to succeed. 42 + SetLastError(0xDEADBEEF); 43 + ok(SetDefaultPrinterA(pszDefaultPrinter), "SetDefaultPrinterA returns FALSE!\n"); 44 + 45 + // SetDefaultPrinterA with an invalid printer name needs to fail with ERROR_INVALID_PRINTER_NAME. 46 + SetLastError(0xDEADBEEF); 47 + ok(!SetDefaultPrinterA("INVALID PRINTER NAME!!!"), "SetDefaultPrinterA returns TRUE!\n"); 48 + ok(GetLastError() == ERROR_INVALID_PRINTER_NAME, "SetDefaultPrinterA returns error %lu!\n", GetLastError()); 49 + 50 + HeapFree(GetProcessHeap(), 0, pszDefaultPrinter); 51 + } 52 + 53 + START_TEST(GetDefaultPrinterW) 17 54 { 18 55 DWORD cchDefaultPrinter; 19 56 PWSTR pwszDefaultPrinter; ··· 33 70 pwszDefaultPrinter = HeapAlloc(GetProcessHeap(), 0, cchDefaultPrinter * sizeof(WCHAR)); 34 71 SetLastError(0xDEADBEEF); 35 72 ok(GetDefaultPrinterW(pwszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterW returns FALSE!\n"); 36 - ok(GetLastError() == ERROR_SUCCESS, "GetDefaultPrinterW returns error %lu!\n", GetLastError()); 37 73 38 74 // SetDefaultPrinterW with NULL needs to succeed and leave the default printer unchanged. 39 75 SetLastError(0xDEADBEEF); 40 76 ok(SetDefaultPrinterW(NULL), "SetDefaultPrinterW returns FALSE!\n"); 41 - ok(GetLastError() == ERROR_SUCCESS, "SetDefaultPrinterW returns error %lu!\n", GetLastError()); 42 77 43 78 // SetDefaultPrinterW with the previous default printer also needs to succeed. 44 79 SetLastError(0xDEADBEEF); 45 80 ok(SetDefaultPrinterW(pwszDefaultPrinter), "SetDefaultPrinterW returns FALSE!\n"); 46 - ok(GetLastError() == ERROR_SUCCESS, "SetDefaultPrinterW returns error %lu!\n", GetLastError()); 47 81 48 82 // SetDefaultPrinterW with an invalid printer name needs to fail with ERROR_INVALID_PRINTER_NAME. 49 83 SetLastError(0xDEADBEEF);
+65
modules/rostests/apitests/winspool/GetPrinter.c
··· 1 + /* 2 + * PROJECT: ReactOS Print Spooler DLL API Tests 3 + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 + * PURPOSE: Tests for GetPrinterA/GetPrinterW 5 + * COPYRIGHT: Copyright 2017 Colin Finck (colin@reactos.org) 6 + */ 7 + 8 + #include <apitest.h> 9 + 10 + #define WIN32_NO_STATUS 11 + #include <windef.h> 12 + #include <winbase.h> 13 + #include <wingdi.h> 14 + #include <winspool.h> 15 + 16 + /* From printing/include/spoolss.h */ 17 + #define MAX_PRINTER_NAME 220 18 + 19 + START_TEST(GetPrinter) 20 + { 21 + DWORD cbNeeded; 22 + DWORD cbTemp; 23 + DWORD cchDefaultPrinter; 24 + DWORD Level; 25 + HANDLE hPrinter; 26 + PVOID pMem; 27 + WCHAR wszDefaultPrinter[MAX_PRINTER_NAME + 1]; 28 + 29 + // Open a handle to the default printer. 30 + cchDefaultPrinter = _countof(wszDefaultPrinter); 31 + ok(GetDefaultPrinterW(wszDefaultPrinter, &cchDefaultPrinter), "GetDefaultPrinterW returns FALSE and requires %lu characters!\n", cchDefaultPrinter); 32 + if (!OpenPrinterW(wszDefaultPrinter, &hPrinter, NULL)) 33 + { 34 + skip("Could not retrieve a handle to the default printer!\n"); 35 + return; 36 + } 37 + 38 + // Try for all levels. Level 0 is valid here and returns the PRINTER_INFO_STRESS structure (documented in MS-RPRN). 39 + for (Level = 0; Level <= 9; Level++) 40 + { 41 + // Try with no valid arguments at all. 42 + SetLastError(0xDEADBEEF); 43 + ok(!GetPrinterW(NULL, Level, NULL, 0, NULL), "GetPrinterW returns TRUE for Level %lu!\n", Level); 44 + ok(GetLastError() == ERROR_INVALID_HANDLE, "GetPrinterW returns error %lu for Level %lu!\n", GetLastError(), Level); 45 + 46 + // Now supply at least a handle. 47 + SetLastError(0xDEADBEEF); 48 + ok(!GetPrinterW(hPrinter, Level, NULL, 0, NULL), "GetPrinterW returns TRUE for Level %lu!\n", Level); 49 + ok(GetLastError() == RPC_X_NULL_REF_POINTER, "GetPrinterW returns error %lu for Level %lu!\n", GetLastError(), Level); 50 + 51 + // Now get the buffer size. 52 + SetLastError(0xDEADBEEF); 53 + ok(!GetPrinterW(hPrinter, Level, NULL, 0, &cbNeeded), "GetPrinterW returns TRUE for Level %lu!\n", Level); 54 + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetPrinterW returns error %lu for Level %lu!\n", GetLastError(), Level); 55 + 56 + // Finally use the function as intended and aim for success! 57 + pMem = HeapAlloc(GetProcessHeap(), 0, cbNeeded); 58 + SetLastError(0xDEADBEEF); 59 + ok(GetPrinterW(hPrinter, Level, pMem, cbNeeded, &cbTemp), "GetPrinterW returns FALSE for Level %lu!\n", Level); 60 + ok(cbNeeded == cbTemp, "cbNeeded is %lu, reference size is %lu for Level %lu!\n", cbNeeded, cbTemp, Level); 61 + HeapFree(GetProcessHeap(), 0, pMem); 62 + } 63 + 64 + ClosePrinter(hPrinter); 65 + }
+6 -2
modules/rostests/apitests/winspool/testlist.c
··· 13 13 extern void func_ClosePrinter(void); 14 14 extern void func_EnumPrinters(void); 15 15 extern void func_EnumPrintProcessorDatatypes(void); 16 - extern void func_GetDefaultPrinter(void); 16 + extern void func_GetDefaultPrinterA(void); 17 + extern void func_GetDefaultPrinterW(void); 18 + extern void func_GetPrinter(void); 17 19 extern void func_GetPrinterData(void); 18 20 extern void func_GetPrintProcessorDirectoryA(void); 19 21 extern void func_GetPrintProcessorDirectoryW(void); ··· 27 29 { "ClosePrinter", func_ClosePrinter }, 28 30 { "EnumPrinters", func_EnumPrinters }, 29 31 { "EnumPrintProcessorDatatypes", func_EnumPrintProcessorDatatypes }, 30 - { "GetDefaultPrinter", func_GetDefaultPrinter }, 32 + { "GetDefaultPrinterA", func_GetDefaultPrinterA }, 33 + { "GetDefaultPrinterW", func_GetDefaultPrinterW }, 34 + { "GetPrinter", func_GetPrinter }, 31 35 { "GetPrinterData", func_GetPrinterData }, 32 36 { "GetPrintProcessorDirectoryA", func_GetPrintProcessorDirectoryA }, 33 37 { "GetPrintProcessorDirectoryW", func_GetPrintProcessorDirectoryW },
+8
win32ss/printing/base/winspool/printerdrivers.c
··· 88 88 } 89 89 90 90 BOOL WINAPI 91 + GetPrinterDriverDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded) 92 + { 93 + TRACE("GetPrinterDriverDirectoryA(%s, %s, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded); 94 + UNIMPLEMENTED; 95 + return FALSE; 96 + } 97 + 98 + BOOL WINAPI 91 99 GetPrinterDriverDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded) 92 100 { 93 101 TRACE("GetPrinterDriverDirectoryW(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded);
+9 -1
win32ss/printing/base/winspool/printers.c
··· 630 630 GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) 631 631 { 632 632 DWORD dwErrorCode; 633 + PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; 633 634 634 635 TRACE("GetPrinterW(%p, %lu, %p, %lu, %p)\n", hPrinter, Level, pPrinter, cbBuf, pcbNeeded); 636 + 637 + // Sanity checks. 638 + if (!pHandle) 639 + { 640 + dwErrorCode = ERROR_INVALID_HANDLE; 641 + goto Cleanup; 642 + } 635 643 636 644 // Dismiss invalid levels already at this point. 637 645 if (Level > 9) ··· 646 654 // Do the RPC call 647 655 RpcTryExcept 648 656 { 649 - dwErrorCode = _RpcGetPrinter(hPrinter, Level, pPrinter, cbBuf, pcbNeeded); 657 + dwErrorCode = _RpcGetPrinter(pHandle->hPrinter, Level, pPrinter, cbBuf, pcbNeeded); 650 658 } 651 659 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 652 660 {
+1 -1
win32ss/printing/base/winspool/winspool.spec
··· 152 152 251 stdcall GetPrinterDataExW(ptr wstr wstr ptr ptr long ptr) 153 153 252 stdcall GetPrinterDataW(ptr wstr ptr ptr long ptr) 154 154 253 stdcall GetPrinterDriverA(ptr str long ptr long ptr) 155 - 254 stdcall -stub GetPrinterDriverDirectoryA(str str long ptr long ptr) 155 + 254 stdcall GetPrinterDriverDirectoryA(str str long ptr long ptr) 156 156 255 stdcall GetPrinterDriverDirectoryW(wstr wstr long ptr long ptr) 157 157 256 stdcall GetPrinterDriverW(ptr wstr long ptr long ptr) 158 158 257 stdcall GetPrinterW(ptr long ptr long ptr)
+27 -23
win32ss/printing/providers/localspl/printers.c
··· 11 11 SKIPLIST PrinterList; 12 12 13 13 // Forward Declarations 14 - static void _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 15 - static void _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 16 - static void _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 17 - static void _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 18 - static void _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 19 - static void _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 20 - static void _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 21 - static void _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 22 - static void _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 23 - static void _LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName); 14 + static void _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 15 + static void _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 16 + static void _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 17 + static void _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 18 + static void _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 19 + static void _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 20 + static void _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 21 + static void _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 22 + static void _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 23 + static void _LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName); 24 24 25 25 // Local Constants 26 - typedef void (*PLocalGetPrinterLevelFunc)(PLOCAL_PRINTER, PVOID, PBYTE*, PDWORD, DWORD, PWSTR); 26 + typedef void (*PLocalGetPrinterLevelFunc)(PLOCAL_PRINTER, PVOID, PBYTE*, PDWORD, DWORD, PCWSTR); 27 27 28 28 static const PLocalGetPrinterLevelFunc pfnGetPrinterLevels[] = { 29 29 (PLocalGetPrinterLevelFunc)&_LocalGetPrinterLevel0, ··· 488 488 } 489 489 490 490 static void 491 - _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 491 + _LocalGetPrinterLevel0(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_STRESS* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 492 492 { 493 493 size_t cbName; 494 494 PWSTR p; ··· 535 535 } 536 536 537 537 static void 538 - _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 538 + _LocalGetPrinterLevel1(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_1W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 539 539 { 540 540 const WCHAR wszComma[] = L","; 541 541 ··· 590 590 } 591 591 592 592 static void 593 - _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 593 + _LocalGetPrinterLevel2(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_2W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 594 594 { 595 595 WCHAR wszEmpty[] = L""; 596 596 ··· 682 682 } 683 683 684 684 static void 685 - _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 685 + _LocalGetPrinterLevel3(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_3* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 686 686 { 687 687 SECURITY_DESCRIPTOR SecurityDescriptor = { 0 }; 688 688 ··· 704 704 } 705 705 706 706 static void 707 - _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 707 + _LocalGetPrinterLevel4(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_4W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 708 708 { 709 709 size_t cbPrinterName; 710 710 PWSTR p; ··· 738 738 } 739 739 740 740 static void 741 - _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 741 + _LocalGetPrinterLevel5(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_5W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 742 742 { 743 743 size_t cbPrinterName; 744 744 size_t cbPortName; ··· 779 779 } 780 780 781 781 static void 782 - _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 782 + _LocalGetPrinterLevel6(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_6* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 783 783 { 784 784 if (!ppPrinterInfo) 785 785 { ··· 795 795 } 796 796 797 797 static void 798 - _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 798 + _LocalGetPrinterLevel7(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_7W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 799 799 { 800 800 if (!ppPrinterInfo) 801 801 { ··· 814 814 } 815 815 816 816 static void 817 - _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 817 + _LocalGetPrinterLevel8(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_8W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 818 818 { 819 819 DWORD cbDevMode; 820 820 ··· 837 837 } 838 838 839 839 static void 840 - _LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PWSTR wszComputerName) 840 + _LocalGetPrinterLevel9(PLOCAL_PRINTER pPrinter, PPRINTER_INFO_9W* ppPrinterInfo, PBYTE* ppPrinterInfoEnd, PDWORD pcbNeeded, DWORD cchComputerName, PCWSTR wszComputerName) 841 841 { 842 842 DWORD cbDevMode; 843 843 ··· 965 965 BOOL WINAPI 966 966 LocalGetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) 967 967 { 968 + // We never prepend a Computer Name to the output, but need to provide an empty string, 969 + // because this variable is passed to StringCbCopyExW. 970 + const WCHAR wszDummyComputerName[] = L""; 971 + 968 972 DWORD dwErrorCode; 969 973 PBYTE pPrinterEnd; 970 974 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter; ··· 997 1001 998 1002 // Count the required buffer size. 999 1003 *pcbNeeded = 0; 1000 - pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, NULL, NULL, pcbNeeded, 0, NULL); 1004 + pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, NULL, NULL, pcbNeeded, 0, wszDummyComputerName); 1001 1005 1002 1006 // Check if the supplied buffer is large enough. 1003 1007 if (cbBuf < *pcbNeeded) ··· 1008 1012 1009 1013 // Copy over the Printer information. 1010 1014 pPrinterEnd = &pPrinter[*pcbNeeded]; 1011 - pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, &pPrinter, &pPrinterEnd, NULL, 0, NULL); 1015 + pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, &pPrinter, &pPrinterEnd, NULL, 0, wszDummyComputerName); 1012 1016 dwErrorCode = ERROR_SUCCESS; 1013 1017 1014 1018 Cleanup: