ReactOS 0.4.15-dev-7958-gcd0bb1a
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
 

Functions

BOOL GetLocalsplFuncs (LPPRINTPROVIDOR pp)
 
 START_TEST (fpEnumPrinters)
 

Macro Definition Documentation

◆ 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 110 of file main.c.

111{
112 HMODULE hLocalspl;
113 PInitializePrintProvidor pfnInitializePrintProvidor;
114
115 // Get us a handle to the loaded localspl.dll.
116 hLocalspl = GetModuleHandleW(L"localspl");
117 if (!hLocalspl)
118 {
119 skip("GetModuleHandleW failed with error %u!\n", GetLastError());
120 return FALSE;
121 }
122
123 // Get a pointer to its InitializePrintProvidor function.
124 pfnInitializePrintProvidor = (PInitializePrintProvidor)GetProcAddress(hLocalspl, "InitializePrintProvidor");
125 if (!pfnInitializePrintProvidor)
126 {
127 skip("GetProcAddress failed with error %u!\n", GetLastError());
128 return FALSE;
129 }
130
131 // Get localspl's function pointers.
132 if (!pfnInitializePrintProvidor(pp, sizeof(PRINTPROVIDOR), NULL))
133 {
134 skip("pfnInitializePrintProvidor failed with error %u!\n", GetLastError());
135 return FALSE;
136 }
137
138 return TRUE;
139}
#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
BOOL(WINAPI * PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR)
#define L(x)
Definition: ntvdm.h:50
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( fpEnumPrinters  )

Definition at line 25 of file fpEnumPrinters.c.

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 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
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
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
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
#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