2 * PROJECT: ReactOS Local Spooler API Tests Injected DLL
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
4 * PURPOSE: Tests for fpGetPrintProcessorDirectory
5 * COPYRIGHT: Copyright 2016-2017 Colin Finck <colin@reactos.org>
10 #define WIN32_NO_STATUS
18 #include "../localspl_apitest.h"
21 typedef BOOL (WINAPI
*PGetPrintProcessorDirectoryW
)(LPWSTR
, LPWSTR
, DWORD
, LPBYTE
, DWORD
, LPDWORD
);
22 extern BOOL
GetLocalsplFuncs(LPPRINTPROVIDOR pp
);
23 extern PVOID
GetSpoolssFunc(const char* FunctionName
);
25 START_TEST(fpGetPrintProcessorDirectory
)
30 PGetPrintProcessorDirectoryW pGetPrintProcessorDirectoryW
;
34 if (!GetLocalsplFuncs(&pp
))
37 pGetPrintProcessorDirectoryW
= GetSpoolssFunc("GetPrintProcessorDirectoryW");
38 if (!pGetPrintProcessorDirectoryW
)
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());
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());
51 // This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
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.
59 pp
.fpGetPrintProcessorDirectory(NULL
, L
"wIndows nt x86", 0, NULL
, 0, NULL
);
61 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
63 dwReturned
= _SEH2_GetExceptionCode();
67 ok(dwReturned
== EXCEPTION_ACCESS_VIOLATION
, "dwReturned is %lu!\n", dwReturned
);
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);
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
);
78 // This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
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.
85 pp
.fpGetPrintProcessorDirectory(NULL
, L
"wIndows nt x86", 1, NULL
, cbNeeded
, &cbTemp
);
87 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
89 dwReturned
= _SEH2_GetExceptionCode();
93 ok(dwReturned
== EXCEPTION_ACCESS_VIOLATION
, "dwReturned is %lu!\n", dwReturned
);
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);
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
);
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
);