[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
This commit is contained in:
Colin Finck 2017-12-10 12:28:08 +01:00
parent 3449296f7b
commit 3a69fd4e96
8 changed files with 155 additions and 31 deletions

View file

@ -4,6 +4,7 @@ list(APPEND SOURCE
EnumPrinters.c
EnumPrintProcessorDatatypes.c
GetDefaultPrinter.c
GetPrinter.c
GetPrinterData.c
GetPrintProcessorDirectory.c
IsValidDevmode.c

View file

@ -13,7 +13,44 @@
#include <wingdi.h>
#include <winspool.h>
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);

View file

@ -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 <apitest.h>
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winspool.h>
/* 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);
}

View file

@ -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 },