ReactOS  0.4.14-dev-358-gbef841c
fpGetPrintProcessorDirectory.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 fpGetPrintProcessorDirectory.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 

Typedefs

typedef BOOL(WINAPIPGetPrintProcessorDirectoryW) (LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
 

Functions

BOOL GetLocalsplFuncs (LPPRINTPROVIDOR pp)
 
PVOID GetSpoolssFunc (const char *FunctionName)
 
 START_TEST (fpGetPrintProcessorDirectory)
 

Macro Definition Documentation

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 10 of file fpGetPrintProcessorDirectory.c.

Typedef Documentation

◆ PGetPrintProcessorDirectoryW

typedef BOOL(WINAPI * PGetPrintProcessorDirectoryW) (LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)

Definition at line 21 of file fpGetPrintProcessorDirectory.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().

◆ GetSpoolssFunc()

PVOID GetSpoolssFunc ( const char FunctionName)

Definition at line 142 of file main.c.

143 {
144  HMODULE hSpoolss;
145 
146  // Get us a handle to the loaded spoolss.dll.
147  hSpoolss = GetModuleHandleW(L"spoolss");
148  if (!hSpoolss)
149  {
150  skip("GetModuleHandleW failed with error %u!\n", GetLastError());
151  return FALSE;
152  }
153 
154  return GetProcAddress(hSpoolss, FunctionName);
155 }
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static const WCHAR L[]
Definition: oid.c:1250
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char * FunctionName
Definition: acpixf.h:1270
#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 ( fpGetPrintProcessorDirectory  )

Definition at line 25 of file fpGetPrintProcessorDirectory.c.

26 {
27  DWORD cbNeeded;
28  DWORD cbTemp;
29  //DWORD dwReturned;
30  PGetPrintProcessorDirectoryW pGetPrintProcessorDirectoryW;
32  PWSTR pwszBuffer;
33 
34  if (!GetLocalsplFuncs(&pp))
35  return;
36 
37  pGetPrintProcessorDirectoryW = GetSpoolssFunc("GetPrintProcessorDirectoryW");
38  if (!pGetPrintProcessorDirectoryW)
39  return;
40 
41  // In contrast to GetPrintProcessorDirectoryW, fpGetPrintProcessorDirectory needs an environment and doesn't just accept NULL.
42  SetLastError(0xDEADBEEF);
43  ok(!pp.fpGetPrintProcessorDirectory(NULL, NULL, 0, NULL, 0, NULL), "fpGetPrintProcessorDirectory returns TRUE!\n");
44  ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
45 
46  // Try with an invalid environment as well.
47  SetLastError(0xDEADBEEF);
48  ok(!pp.fpGetPrintProcessorDirectory(NULL, L"invalid", 0, NULL, 0, NULL), "fpGetPrintProcessorDirectory returns TRUE!\n");
49  ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
50 
51  // This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
52 #if 0
53  // Now provide a valid environment and prove that it is checked case-insensitively.
54  // In contrast to GetPrintProcessorDirectoryW, the level isn't the next thing checked here, but fpGetPrintProcessorDirectory
55  // already tries to access the non-supplied pcbNeeded variable.
56  _SEH2_TRY
57  {
58  dwReturned = 0;
59  pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 0, NULL, 0, NULL);
60  }
62  {
63  dwReturned = _SEH2_GetExceptionCode();
64  }
65  _SEH2_END;
66 
67  ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu!\n", dwReturned);
68 #endif
69 
70  // fpGetPrintProcessorDirectory doesn't care about the supplied level at all. Prove this here.
71  // With no buffer given, this needs to fail with ERROR_INSUFFICIENT_BUFFER.
72  SetLastError(0xDEADBEEF);
73  cbNeeded = 0;
74  ok(!pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1337, NULL, 0, &cbNeeded), "fpGetPrintProcessorDirectory returns TRUE!\n");
75  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
76  ok(cbNeeded > 0, "cbNeeded is %lu!\n", cbNeeded);
77 
78  // This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
79 #if 0
80  // Now provide the demanded size, but no buffer.
81  // Unlike GetPrintProcessorDirectoryW, fpGetPrintProcessorDirectory doesn't check for this case and tries to access the buffer.
82  _SEH2_TRY
83  {
84  dwReturned = 0;
85  pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1, NULL, cbNeeded, &cbTemp);
86  }
88  {
89  dwReturned = _SEH2_GetExceptionCode();
90  }
91  _SEH2_END;
92 
93  ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu!\n", dwReturned);
94 #endif
95 
96  // Prove that this check is implemented in spoolss' GetPrintProcessorDirectoryW instead.
97  // In contrast to winspool's GetPrintProcessorDirectoryW, cbTemp is left untouched though. This comes from the fact that RPC isn't involved here.
98  SetLastError(0xDEADBEEF);
99  cbTemp = 0xDEADBEEF;
100  ok(!pGetPrintProcessorDirectoryW(NULL, L"wIndows nt x86", 1, NULL, cbNeeded, &cbTemp), "pGetPrintProcessorDirectoryW returns TRUE!\n");
101  ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "pGetPrintProcessorDirectoryW returns error %lu!\n", GetLastError());
102  ok(cbTemp == 0xDEADBEEF, "cbTemp is %lu!\n", cbTemp);
103 
104  // Finally use the function as intended and aim for success!
105  // We only check success by the boolean return value though. GetLastError doesn't return anything meaningful here.
106  pwszBuffer = DllAllocSplMem(cbNeeded);
107  SetLastError(0xDEADBEEF);
108  ok(pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1, (PBYTE)pwszBuffer, cbNeeded, &cbTemp), "fpGetPrintProcessorDirectory returns FALSE!\n");
109  ok(wcslen(pwszBuffer) == cbNeeded / sizeof(WCHAR) - 1, "fpGetPrintProcessorDirectory string is %Iu characters long, but %lu characters expected!\n", wcslen(pwszBuffer), cbNeeded / sizeof(WCHAR) - 1);
110  DllFreeSplMem(pwszBuffer);
111 }
uint16_t * PWSTR
Definition: typedefs.h:54
#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
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define pp
Definition: hlsl.yy.c:1208
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
BOOL GetLocalsplFuncs(LPPRINTPROVIDOR pp)
Definition: main.c:110
PVOID GetSpoolssFunc(const char *FunctionName)
Definition: main.c:142
BOOL(WINAPI * PGetPrintProcessorDirectoryW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
static const WCHAR L[]
Definition: oid.c:1250
_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
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10