ReactOS  0.4.14-dev-358-gbef841c
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 "../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 TRUE
Definition: types.h:120
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define pp
Definition: hlsl.yy.c:1208
smooth NULL
Definition: ftsmooth.c:416
BOOL(WINAPI * PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR)
static const WCHAR L[]
Definition: oid.c:1250
#define skip(...)
Definition: atltest.h:64
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
#define GetProcAddress(x, y)
Definition: compat.h:418

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( fpEnumPrinters  )

Definition at line 23 of file fpEnumPrinters.c.

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
#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:403
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:417
static const WCHAR L[]
Definition: oid.c:1250
unsigned char BYTE
Definition: mem.h:68
_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
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10