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