ReactOS 0.4.16-dev-1946-g52006dd
fpEnumPrinters.c File Reference
#include <apitest.h>
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winreg.h>
#include <winspool.h>
#include <winsplp.h>
#include <pseh/pseh2.h>
#include "../localspl_apitest.h"
#include <spoolss.h>
Include dependency graph for fpEnumPrinters.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 
#define STATUS_ACCESS_VIOLATION   ((DWORD)0xC0000005)
 

Functions

BOOL GetLocalsplFuncs (LPPRINTPROVIDOR pp)
 
 START_TEST (fpEnumPrinters)
 

Macro Definition Documentation

◆ STATUS_ACCESS_VIOLATION

#define STATUS_ACCESS_VIOLATION   ((DWORD)0xC0000005)

Definition at line 23 of file fpEnumPrinters.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 10 of file fpEnumPrinters.c.

Function Documentation

◆ GetLocalsplFuncs()

BOOL GetLocalsplFuncs ( LPPRINTPROVIDOR  pp)

Definition at line 108 of file main.c.

109{
110 HMODULE hLocalspl;
111 PInitializePrintProvidor pfnInitializePrintProvidor;
112
113 // Get us a handle to the loaded localspl.dll.
114 hLocalspl = GetModuleHandleW(L"localspl");
115 if (!hLocalspl)
116 {
117 skip("GetModuleHandleW failed with error %u!\n", GetLastError());
118 return FALSE;
119 }
120
121 // Get a pointer to its InitializePrintProvidor function.
122 pfnInitializePrintProvidor = (PInitializePrintProvidor)GetProcAddress(hLocalspl, "InitializePrintProvidor");
123 if (!pfnInitializePrintProvidor)
124 {
125 skip("GetProcAddress failed with error %u!\n", GetLastError());
126 return FALSE;
127 }
128
129 // Get localspl's function pointers.
130 if (!pfnInitializePrintProvidor(pp, sizeof(PRINTPROVIDOR), NULL))
131 {
132 skip("pfnInitializePrintProvidor failed with error %u!\n", GetLastError());
133 return FALSE;
134 }
135
136 return TRUE;
137}
#define skip(...)
Definition: atltest.h:64
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define L(x)
Definition: resources.c:13
BOOL(WINAPI * PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR)
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( fpEnumPrinters  )

Definition at line 26 of file fpEnumPrinters.c.

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