ReactOS  0.4.14-dev-98-gb0d4763
main.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Local Spooler API Tests Injected DLL
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Main functions
5  * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
6  */
7 
8 #define __ROS_LONG64__
9 
10 #define STANDALONE
11 #include <apitest.h>
12 
13 #define WIN32_NO_STATUS
14 #include <io.h>
15 #include <windef.h>
16 #include <winbase.h>
17 #include <wingdi.h>
18 #include <winreg.h>
19 #include <winspool.h>
20 #include <winsplp.h>
21 
22 #include "../localspl_apitest.h"
23 
24 //#define NDEBUG
25 #include <debug.h>
26 
27 // Test list
28 extern void func_fpEnumPrinters(void);
29 extern void func_fpGetPrintProcessorDirectory(void);
30 extern void func_fpSetJob(void);
31 
32 const struct test winetest_testlist[] =
33 {
34  { "fpEnumPrinters", func_fpEnumPrinters },
35  { "fpGetPrintProcessorDirectory", func_fpGetPrintProcessorDirectory },
36  { "fpSetJob", func_fpSetJob },
37  { 0, 0 }
38 };
39 
44 PWSTR
46 {
47  static const WCHAR wszWindowsKey[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
48  static const WCHAR wszDeviceValue[] = L"Device";
49 
50  DWORD cbNeeded;
51  DWORD dwErrorCode;
52  HKEY hWindowsKey = NULL;
53  PWSTR pwszDevice;
54  PWSTR pwszComma;
55  PWSTR pwszReturnValue = NULL;
56 
57  // Open the registry key where the default printer for the current user is stored.
58  dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_CURRENT_USER, wszWindowsKey, 0, KEY_READ, &hWindowsKey);
59  if (dwErrorCode != ERROR_SUCCESS)
60  {
61  skip("RegOpenKeyExW failed with status %u!\n", dwErrorCode);
62  goto Cleanup;
63  }
64 
65  // Determine the size of the required buffer.
66  dwErrorCode = (DWORD)RegQueryValueExW(hWindowsKey, wszDeviceValue, NULL, NULL, NULL, &cbNeeded);
67  if (dwErrorCode != ERROR_SUCCESS)
68  {
69  skip("RegQueryValueExW failed with status %u!\n", dwErrorCode);
70  goto Cleanup;
71  }
72 
73  // Allocate it.
74  pwszDevice = HeapAlloc(GetProcessHeap(), 0, cbNeeded);
75  if (!pwszDevice)
76  {
77  skip("HeapAlloc failed!\n");
78  goto Cleanup;
79  }
80 
81  // Now get the actual value.
82  dwErrorCode = RegQueryValueExW(hWindowsKey, wszDeviceValue, NULL, NULL, (PBYTE)pwszDevice, &cbNeeded);
83  if (dwErrorCode != ERROR_SUCCESS)
84  {
85  skip("RegQueryValueExW failed with status %u!\n", dwErrorCode);
86  goto Cleanup;
87  }
88 
89  // We get a string "<Printer Name>,winspool,<Port>:".
90  // Extract the printer name from it.
91  pwszComma = wcschr(pwszDevice, L',');
92  if (!pwszComma)
93  {
94  skip("Found no or invalid default printer: %S!\n", pwszDevice);
95  goto Cleanup;
96  }
97 
98  // Return the default printer.
99  *pwszComma = 0;
100  pwszReturnValue = pwszDevice;
101 
102 Cleanup:
103  if (hWindowsKey)
104  RegCloseKey(hWindowsKey);
105 
106  return pwszReturnValue;
107 }
108 
109 BOOL
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 }
140 
141 PVOID
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 }
156 
157 // Running the tests from the injected DLL and redirecting their output to the pipe.
158 BOOL WINAPI
159 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
160 {
161  char szTestName[150];
162  DWORD cbRead;
163  FILE* fpStdout;
164  HANDLE hCommandPipe;
165  int iOldStdout;
166 
167  // We only want to run our test once when the DLL is injected to the process.
168  if (fdwReason != DLL_PROCESS_ATTACH)
169  return TRUE;
170 
171  // Read the test to run from the command pipe.
173  if (hCommandPipe == INVALID_HANDLE_VALUE)
174  {
175  DPRINT("DLL: CreateFileW failed for the command pipe with error %lu!\n", GetLastError());
176  return FALSE;
177  }
178 
179  if (!ReadFile(hCommandPipe, szTestName, sizeof(szTestName), &cbRead, NULL))
180  {
181  DPRINT("DLL: ReadFile failed for the command pipe with error %lu!\n", GetLastError());
182  return FALSE;
183  }
184 
185  CloseHandle(hCommandPipe);
186 
187  // Check if the test name is valid.
188  if (!find_test(szTestName))
189  {
190  DPRINT("DLL: Got invalid test name \"%s\"!\n", szTestName);
191  return FALSE;
192  }
193 
194  // Backup our current stdout and set it to the output pipe.
195  iOldStdout = _dup(_fileno(stdout));
196  fpStdout = _wfreopen(OUTPUT_PIPE_NAME, L"w", stdout);
197  setbuf(stdout, NULL);
198 
199  // Run the test.
200  run_test(szTestName);
201 
202  // Restore stdout to the previous value.
203  fclose(fpStdout);
204  _dup2(iOldStdout, _fileno(stdout));
205 
206  // Return FALSE so that our DLL is immediately unloaded.
207  return FALSE;
208 }
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
_Check_return_ _CRTIMP int __cdecl _dup2(_In_ int _FileHandleSrc, _In_ int _FileHandleDst)
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
uint16_t * PWSTR
Definition: typedefs.h:54
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define OUTPUT_PIPE_NAME
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
#define test
Definition: rosglue.h:37
#define DWORD
Definition: nt_native.h:44
PVOID GetSpoolssFunc(const char *FunctionName)
Definition: main.c:142
static IN DWORD IN LPVOID lpvReserved
FILE * stdout
void func_fpEnumPrinters(void)
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned int BOOL
Definition: ntddk_ex.h:94
void func_fpGetPrintProcessorDirectory(void)
BOOL GetLocalsplFuncs(LPPRINTPROVIDOR pp)
Definition: main.c:110
#define pp
Definition: hlsl.yy.c:978
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define OPEN_EXISTING
Definition: compat.h:426
BOOL(WINAPI * PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR)
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR wszWindowsKey[]
Definition: printers.c:16
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
static const WCHAR Cleanup[]
Definition: register.c:80
static void run_test(struct wine_test *test, const char *subtest, const char *tempdir)
Definition: main.c:448
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:1264
#define CreateFileW
Definition: compat.h:400
#define skip(...)
Definition: atltest.h:64
static const WCHAR wszDeviceValue[]
Definition: printers.c:17
void func_fpSetJob(void)
#define COMMAND_PIPE_NAME
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:847
_CRTIMP void __cdecl setbuf(_Inout_ FILE *_File, _Inout_updates_opt_(BUFSIZ) _Post_readable_size_(0) char *_Buffer)
#define GetProcAddress(x, y)
Definition: compat.h:410
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
BYTE * PBYTE
Definition: pedump.c:66
_Check_return_ _CRTIMP FILE *__cdecl _wfreopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode, _Inout_ FILE *_OldFile)
const struct test winetest_testlist[]
Definition: main.c:32
PWSTR GetDefaultPrinterFromRegistry(VOID)
Definition: main.c:45
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Definition: main.c:26
_Check_return_ _CRTIMP int __cdecl _dup(_In_ int _FileHandle)