ReactOS  0.4.15-dev-345-g5d88487
fpEnumPrinters.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Local Spooler API Tests Injected DLL
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Tests for fpEnumPrinters
5  * COPYRIGHT: Copyright 2015-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 <winreg.h>
15 #include <winspool.h>
16 #include <winsplp.h>
17 
18 #include "../localspl_apitest.h"
19 #include <spoolss.h>
20 
22 
23 START_TEST(fpEnumPrinters)
24 {
25  BYTE TempBuffer[50];
26  BYTE ZeroBuffer[50];
27  DWORD cbNeeded;
28  DWORD cbTemp;
29  DWORD dwReturned;
30  DWORD i;
32  PPRINTER_INFO_1W pPrinterInfo1;
33  PVOID pMem;
34 
35  if (!GetLocalsplFuncs(&pp))
36  return;
37 
38  // Verify that fpEnumPrinters returns success and zeros cbNeeded and dwReturned (but not TempBuffer!) if no flag has been specified.
39  memset(TempBuffer, 0xDE, sizeof(TempBuffer));
40  memset(ZeroBuffer, 0, sizeof(ZeroBuffer));
41  cbNeeded = 0xDEADBEEF;
42  dwReturned = 0xDEADBEEF;
43  SetLastError(0xDEADBEEF);
44  ok(pp.fpEnumPrinters(0, NULL, 1, TempBuffer, sizeof(TempBuffer), &cbNeeded, &dwReturned), "fpEnumPrinters returns FALSE\n");
45  ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu!\n", GetLastError());
46  ok(memcmp(TempBuffer, ZeroBuffer, sizeof(TempBuffer)) != 0, "TempBuffer has been zeroed!\n");
47  ok(cbNeeded == 0, "cbNeeded is %lu!\n", cbNeeded);
48  ok(dwReturned == 0, "dwReturned is %lu!\n", dwReturned);
49 
50  // Verify that localspl only returns information about a single print provider (namely itself).
51  cbNeeded = 0xDEADBEEF;
52  dwReturned = 0xDEADBEEF;
53  SetLastError(0xDEADBEEF);
54  ok(!pp.fpEnumPrinters(PRINTER_ENUM_NAME, NULL, 1, NULL, 0, &cbNeeded, &dwReturned), "fpEnumPrinters returns TRUE\n");
55  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpEnumPrinters returns error %lu!\n", GetLastError());
56  ok(cbNeeded > 0, "cbNeeded is 0!\n");
57  ok(dwReturned == 0, "dwReturned is %lu!\n", dwReturned);
58 
59  SetLastError(0xDEADBEEF);
60  pPrinterInfo1 = HeapAlloc(GetProcessHeap(), 0, cbNeeded);
61  ok(pp.fpEnumPrinters(PRINTER_ENUM_NAME, NULL, 1, (PBYTE)pPrinterInfo1, cbNeeded, &cbNeeded, &dwReturned), "fpEnumPrinters returns FALSE\n");
62  ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu!\n", GetLastError());
63  ok(cbNeeded > 0, "cbNeeded is 0!\n");
64  ok(dwReturned == 1, "dwReturned is %lu!\n", dwReturned);
65 
66  // Verify the actual strings returned.
67  ok(wcscmp(pPrinterInfo1->pName, L"Windows NT Local Print Providor") == 0, "pPrinterInfo1->pName is \"%S\"!\n", pPrinterInfo1->pName);
68  ok(wcscmp(pPrinterInfo1->pDescription, L"Windows NT Local Printers") == 0, "pPrinterInfo1->pDescription is \"%S\"!\n", pPrinterInfo1->pDescription);
69  ok(wcscmp(pPrinterInfo1->pComment, L"Locally connected Printers") == 0, "pPrinterInfo1->pComment is \"%S\"!\n", pPrinterInfo1->pComment);
70 
71  // Level 7 is the highest supported for localspl under Windows Server 2003.
72  // Higher levels need to fail, but they don't set an error code, just cbNeeded to 0.
73  cbNeeded = 0xDEADBEEF;
74  dwReturned = 0xDEADBEEF;
75  SetLastError(0xDEADBEEF);
76  ok(!pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, 8, NULL, 0, &cbNeeded, &dwReturned), "fpEnumPrinters returns TRUE!\n");
77  ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu!\n", GetLastError());
78  ok(cbNeeded == 0, "cbNeeded is %lu!\n", cbNeeded);
79  ok(dwReturned == 0, "dwReturned is %lu!\n", dwReturned);
80 
81  // Verify that all valid levels work.
82  // In contrast to EnumPrintersW, which only accepts levels 0, 1, 2, 4 and 5, localspl returns information for level 0 to 7.
83  for (i = 0; i <= 7; i++)
84  {
85  // Try with no valid arguments at all.
86  // This scenario is usually caugt by RPC, so it just raises an exception here.
87  _SEH2_TRY
88  {
89  dwReturned = 0;
90  pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, NULL, 0, NULL, NULL);
91  }
93  {
94  dwReturned = _SEH2_GetExceptionCode();
95  }
96  _SEH2_END;
97 
98  ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu for Level %lu!\n", dwReturned, i);
99 
100  // Now get the required buffer size.
101  cbNeeded = 0xDEADBEEF;
102  dwReturned = 0xDEADBEEF;
103  SetLastError(0xDEADBEEF);
104  ok(!pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, NULL, 0, &cbNeeded, &dwReturned), "fpEnumPrinters returns TRUE for Level %lu!\n", i);
105  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpEnumPrinters returns error %lu for Level %lu!\n", GetLastError(), i);
106  ok(cbNeeded > 0, "cbNeeded is 0 for Level %lu!\n", i);
107  ok(dwReturned == 0, "dwReturned is %lu for Level %lu!\n", dwReturned, i);
108 
109  // This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
110 #if 0
111  // Now provide the demanded size, but no buffer. This also mustn't touch cbNeeded.
112  // This scenario is also caught by RPC and we just have an exception here.
113  _SEH2_TRY
114  {
115  dwReturned = 0;
116  pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, NULL, cbNeeded, &cbTemp, &dwReturned);
117  }
119  {
120  dwReturned = _SEH2_GetExceptionCode();
121  }
122  _SEH2_END;
123 
124  ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu for Level %lu!\n", dwReturned, i);
125  ok(cbNeeded == cbTemp, "cbNeeded is %lu, cbTemp is %lu for Level %lu!\n", cbNeeded, cbTemp, i);
126 #endif
127 
128  // Finally use the function as intended and aim for success!
129  pMem = DllAllocSplMem(cbNeeded);
130  SetLastError(0xDEADBEEF);
131  ok(pp.fpEnumPrinters(PRINTER_ENUM_LOCAL, NULL, i, pMem, cbNeeded, &cbTemp, &dwReturned), "fpEnumPrinters returns FALSE for Level %lu!\n", i);
132 
133  // This is crazy. For level 3, fpEnumPrinters always returns ERROR_INSUFFICIENT_BUFFER even if we supply a buffer large enough.
134  if (i == 3)
135  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpEnumPrinters returns error %lu for Level %lu!\n", GetLastError(), i);
136  else
137  ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu for Level %lu!\n", GetLastError(), i);
138 
139  DllFreeSplMem(pMem);
140  }
141 
142  // fpEnumPrinters has to succeed independent of the level (valid or not) if we query no information.
143  for (i = 0; i < 10; i++)
144  {
145  SetLastError(0xDEADBEEF);
146  ok(pp.fpEnumPrinters(0, NULL, i, NULL, 0, &cbNeeded, &dwReturned), "fpEnumPrinters returns FALSE for Level %lu!\n", i);
147  ok(GetLastError() == ERROR_SUCCESS, "fpEnumPrinters returns error %lu for Level %lu!\n", GetLastError(), i);
148  ok(cbNeeded == 0, "cbNeeded is %lu for Level %lu!\n", cbNeeded, i);
149  ok(dwReturned == 0, "dwReturned is %lu for Level %lu!\n", dwReturned, i);
150  }
151 }
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL GetLocalsplFuncs(LPPRINTPROVIDOR pp)
Definition: main.c:110
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:308
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
_SEH2_TRY
Definition: create.c:4250
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
#define pp
Definition: hlsl.yy.c:1208
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define PRINTER_ENUM_NAME
Definition: winspool.h:806
#define PRINTER_ENUM_LOCAL
Definition: winspool.h:803
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:418
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: xxhash.c:193
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_SEH2_END
Definition: create.c:4424
#define ok(value,...)
Definition: atltest.h:57
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define memset(x, y, z)
Definition: compat.h:39
BYTE * PBYTE
Definition: pedump.c:66
START_TEST(fpEnumPrinters)
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10