mirror of
https://github.com/reactos/reactos.git
synced 2024-09-17 08:09:26 +00:00
4536560a1d
Disable fpGetPrintProcessorDirectory tests that use PSEH. For some reason, they can only be run once and corrupt something inside spoolsv, so that spoolsv needs to be restarted afterwards. svn path=/trunk/; revision=73539
112 lines
5 KiB
C
112 lines
5 KiB
C
/*
|
|
* PROJECT: ReactOS Local Spooler API Tests Injected DLL
|
|
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
|
* PURPOSE: Tests for fpGetPrintProcessorDirectory
|
|
* COPYRIGHT: Copyright 2016-2017 Colin Finck <colin@reactos.org>
|
|
*/
|
|
|
|
#include <apitest.h>
|
|
|
|
#define WIN32_NO_STATUS
|
|
#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>
|
|
|
|
typedef BOOL (WINAPI *PGetPrintProcessorDirectoryW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
|
|
extern BOOL GetLocalsplFuncs(LPPRINTPROVIDOR pp);
|
|
extern PVOID GetSpoolssFunc(const char* FunctionName);
|
|
|
|
START_TEST(fpGetPrintProcessorDirectory)
|
|
{
|
|
DWORD cbNeeded;
|
|
DWORD cbTemp;
|
|
//DWORD dwReturned;
|
|
PGetPrintProcessorDirectoryW pGetPrintProcessorDirectoryW;
|
|
PRINTPROVIDOR pp;
|
|
PWSTR pwszBuffer;
|
|
|
|
if (!GetLocalsplFuncs(&pp))
|
|
return;
|
|
|
|
pGetPrintProcessorDirectoryW = GetSpoolssFunc("GetPrintProcessorDirectoryW");
|
|
if (!pGetPrintProcessorDirectoryW)
|
|
return;
|
|
|
|
// In contrast to GetPrintProcessorDirectoryW, fpGetPrintProcessorDirectory needs an environment and doesn't just accept NULL.
|
|
SetLastError(0xDEADBEEF);
|
|
ok(!pp.fpGetPrintProcessorDirectory(NULL, NULL, 0, NULL, 0, NULL), "fpGetPrintProcessorDirectory returns TRUE!\n");
|
|
ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
|
|
|
|
// Try with an invalid environment as well.
|
|
SetLastError(0xDEADBEEF);
|
|
ok(!pp.fpGetPrintProcessorDirectory(NULL, L"invalid", 0, NULL, 0, NULL), "fpGetPrintProcessorDirectory returns TRUE!\n");
|
|
ok(GetLastError() == ERROR_INVALID_ENVIRONMENT, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
|
|
|
|
// This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
|
|
#if 0
|
|
// Now provide a valid environment and prove that it is checked case-insensitively.
|
|
// In contrast to GetPrintProcessorDirectoryW, the level isn't the next thing checked here, but fpGetPrintProcessorDirectory
|
|
// already tries to access the non-supplied pcbNeeded variable.
|
|
_SEH2_TRY
|
|
{
|
|
dwReturned = 0;
|
|
pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 0, NULL, 0, NULL);
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
dwReturned = _SEH2_GetExceptionCode();
|
|
}
|
|
_SEH2_END;
|
|
|
|
ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu!\n", dwReturned);
|
|
#endif
|
|
|
|
// fpGetPrintProcessorDirectory doesn't care about the supplied level at all. Prove this here.
|
|
// With no buffer given, this needs to fail with ERROR_INSUFFICIENT_BUFFER.
|
|
SetLastError(0xDEADBEEF);
|
|
cbNeeded = 0;
|
|
ok(!pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1337, NULL, 0, &cbNeeded), "fpGetPrintProcessorDirectory returns TRUE!\n");
|
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "fpGetPrintProcessorDirectory returns error %lu!\n", GetLastError());
|
|
ok(cbNeeded > 0, "cbNeeded is %lu!\n", cbNeeded);
|
|
|
|
// This test corrupts something inside spoolsv so that it's only runnable once without restarting spoolsv. Therefore it's disabled.
|
|
#if 0
|
|
// Now provide the demanded size, but no buffer.
|
|
// Unlike GetPrintProcessorDirectoryW, fpGetPrintProcessorDirectory doesn't check for this case and tries to access the buffer.
|
|
_SEH2_TRY
|
|
{
|
|
dwReturned = 0;
|
|
pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1, NULL, cbNeeded, &cbTemp);
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
dwReturned = _SEH2_GetExceptionCode();
|
|
}
|
|
_SEH2_END;
|
|
|
|
ok(dwReturned == EXCEPTION_ACCESS_VIOLATION, "dwReturned is %lu!\n", dwReturned);
|
|
#endif
|
|
|
|
// Prove that this check is implemented in spoolss' GetPrintProcessorDirectoryW instead.
|
|
// In contrast to winspool's GetPrintProcessorDirectoryW, cbTemp is left untouched though. This comes from the fact that RPC isn't involved here.
|
|
SetLastError(0xDEADBEEF);
|
|
cbTemp = 0xDEADBEEF;
|
|
ok(!pGetPrintProcessorDirectoryW(NULL, L"wIndows nt x86", 1, NULL, cbNeeded, &cbTemp), "pGetPrintProcessorDirectoryW returns TRUE!\n");
|
|
ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "pGetPrintProcessorDirectoryW returns error %lu!\n", GetLastError());
|
|
ok(cbTemp == 0xDEADBEEF, "cbTemp is %lu!\n", cbTemp);
|
|
|
|
// Finally use the function as intended and aim for success!
|
|
// We only check success by the boolean return value though. GetLastError doesn't return anything meaningful here.
|
|
pwszBuffer = DllAllocSplMem(cbNeeded);
|
|
SetLastError(0xDEADBEEF);
|
|
ok(pp.fpGetPrintProcessorDirectory(NULL, L"wIndows nt x86", 1, (PBYTE)pwszBuffer, cbNeeded, &cbTemp), "fpGetPrintProcessorDirectory returns FALSE!\n");
|
|
ok(wcslen(pwszBuffer) == cbNeeded / sizeof(WCHAR) - 1, "fpGetPrintProcessorDirectory string is %Iu characters long, but %lu characters expected!\n", wcslen(pwszBuffer), cbNeeded / sizeof(WCHAR) - 1);
|
|
DllFreeSplMem(pwszBuffer);
|
|
}
|