mirror of
https://github.com/reactos/reactos.git
synced 2024-09-10 04:42:00 +00:00
![Colin Finck](/assets/img/avatar_default.png)
Tests show that the Print Provider functions are less forgiving and expect winspool.drv and spoolss.dll to perform the necessary sanity checks. Also they don't default to the current environment if none was supplied as pEnvironment. Change our functions accordingly to pass the tests. [LOCALSPL_APITEST] Add a test to prove that spoolss.dll isn't just a forwarder, but also performs some sanity checks even though winspool.drv and localspl.dll also do. This rather belongs to spoolss_apitest. But it needs to be tested inside the Spooler Server Process and it's not worth it to copy all the DLL injection code to spoolss_apitest just for a single test. [SPOOLSS] Check for an invalid buffer in GetPrintProcessorDirectoryW. [WINSPOOL] * Check the level before the RPC call in GetPrintProcessorDirectoryW. * Supply our current environment if the caller didn't give any in EnumPrintProcessorsW and GetPrintProcessorDirectoryW. * Implement GetPrintProcessorDirectoryA. [WINSPOOL_APITEST] Prove that pcbNeeded isn't touched when calling GetPrintProcessorDirectoryW with an invalid level. ReactOS now passes all API tests for GetPrintProcessorDirectoryA and GetPrintProcessorDirectoryW. These tests also cover all known behaviors of both functions. CORE-12399 svn path=/trunk/; revision=73373
138 lines
3.6 KiB
C
138 lines
3.6 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: Main functions
|
|
* COPYRIGHT: Copyright 2015-2016 Colin Finck <colin@reactos.org>
|
|
*/
|
|
|
|
#define __ROS_LONG64__
|
|
|
|
#define STANDALONE
|
|
#include <apitest.h>
|
|
|
|
#define WIN32_NO_STATUS
|
|
#include <io.h>
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <wingdi.h>
|
|
#include <winreg.h>
|
|
#include <winspool.h>
|
|
#include <winsplp.h>
|
|
|
|
#include "../localspl_apitest.h"
|
|
|
|
//#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
// Test list
|
|
extern void func_fpEnumPrinters(void);
|
|
extern void func_fpGetPrintProcessorDirectory(void);
|
|
|
|
const struct test winetest_testlist[] =
|
|
{
|
|
{ "fpEnumPrinters", func_fpEnumPrinters },
|
|
{ "fpGetPrintProcessorDirectory", func_fpGetPrintProcessorDirectory },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
BOOL
|
|
GetLocalsplFuncs(LPPRINTPROVIDOR pp)
|
|
{
|
|
HMODULE hLocalspl;
|
|
PInitializePrintProvidor pfnInitializePrintProvidor;
|
|
|
|
// Get us a handle to the loaded localspl.dll.
|
|
hLocalspl = GetModuleHandleW(L"localspl");
|
|
if (!hLocalspl)
|
|
{
|
|
skip("GetModuleHandleW failed with error %u!\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
// Get a pointer to its InitializePrintProvidor function.
|
|
pfnInitializePrintProvidor = (PInitializePrintProvidor)GetProcAddress(hLocalspl, "InitializePrintProvidor");
|
|
if (!pfnInitializePrintProvidor)
|
|
{
|
|
skip("GetProcAddress failed with error %u!\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
// Get localspl's function pointers.
|
|
if (!pfnInitializePrintProvidor(pp, sizeof(PRINTPROVIDOR), NULL))
|
|
{
|
|
skip("pfnInitializePrintProvidor failed with error %u!\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
PVOID
|
|
GetSpoolssFunc(const char* FunctionName)
|
|
{
|
|
HMODULE hSpoolss;
|
|
|
|
// Get us a handle to the loaded spoolss.dll.
|
|
hSpoolss = GetModuleHandleW(L"spoolss");
|
|
if (!hSpoolss)
|
|
{
|
|
skip("GetModuleHandleW failed with error %u!\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
return GetProcAddress(hSpoolss, FunctionName);
|
|
}
|
|
|
|
// Running the tests from the injected DLL and redirecting their output to the pipe.
|
|
BOOL WINAPI
|
|
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|
{
|
|
char szTestName[150];
|
|
DWORD cbRead;
|
|
FILE* fpStdout;
|
|
HANDLE hCommandPipe;
|
|
int iOldStdout;
|
|
|
|
// We only want to run our test once when the DLL is injected to the process.
|
|
if (fdwReason != DLL_PROCESS_ATTACH)
|
|
return TRUE;
|
|
|
|
// Read the test to run from the command pipe.
|
|
hCommandPipe = CreateFileW(COMMAND_PIPE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
if (hCommandPipe == INVALID_HANDLE_VALUE)
|
|
{
|
|
DPRINT("DLL: CreateFileW failed for the command pipe with error %lu!\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
if (!ReadFile(hCommandPipe, szTestName, sizeof(szTestName), &cbRead, NULL))
|
|
{
|
|
DPRINT("DLL: ReadFile failed for the command pipe with error %lu!\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
CloseHandle(hCommandPipe);
|
|
|
|
// Check if the test name is valid.
|
|
if (!find_test(szTestName))
|
|
{
|
|
DPRINT("DLL: Got invalid test name \"%s\"!\n", szTestName);
|
|
return FALSE;
|
|
}
|
|
|
|
// Backup our current stdout and set it to the output pipe.
|
|
iOldStdout = _dup(_fileno(stdout));
|
|
fpStdout = _wfreopen(OUTPUT_PIPE_NAME, L"w", stdout);
|
|
setbuf(stdout, NULL);
|
|
|
|
// Run the test.
|
|
run_test(szTestName);
|
|
|
|
// Restore stdout to the previous value.
|
|
fclose(fpStdout);
|
|
_dup2(iOldStdout, _fileno(stdout));
|
|
|
|
// Return FALSE so that our DLL is immediately unloaded.
|
|
return FALSE;
|
|
}
|