ReactOS  0.4.15-dev-492-ga1108f6
tests.c File Reference
#include <apitest.h>
#include <stdio.h>
#include <stdlib.h>
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winreg.h>
#include <winsvc.h>
#include <winspool.h>
#include <winsplp.h>
#include "localspl_apitest.h"
Include dependency graph for tests.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 

Functions

static void _RunRemoteTest (const char *szTestName)
 
 START_TEST (fpEnumPrinters)
 
 START_TEST (fpGetPrintProcessorDirectory)
 
 START_TEST (fpSetJob)
 

Macro Definition Documentation

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 26 of file tests.c.

Function Documentation

◆ _RunRemoteTest()

static void _RunRemoteTest ( const char szTestName)
static

Definition at line 41 of file tests.c.

42 {
43  BOOL bSuccessful = FALSE;
44  char szBuffer[1024];
45  DWORD cbRead;
46  DWORD cbWritten;
47  HANDLE hCommandPipe = INVALID_HANDLE_VALUE;
49  HANDLE hOutputPipe = INVALID_HANDLE_VALUE;
50  PWSTR p;
51  SC_HANDLE hSC = NULL;
52  SC_HANDLE hService = NULL;
54  WCHAR wszFilePath[MAX_PATH + 20];
56 
57  // Do a dummy EnumPrintersW call.
58  // This guarantees that the Spooler Service has actually loaded localspl.dll, which is a requirement for our injected DLL to work properly.
59  EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_NAME, NULL, 1, NULL, 0, &cbRead, &cbWritten);
60 
61  // Get the full path to our EXE file.
62  if (!GetModuleFileNameW(NULL, wszFilePath, MAX_PATH))
63  {
64  skip("GetModuleFileNameW failed with error %lu!\n", GetLastError());
65  goto Cleanup;
66  }
67 
68  // Replace the extension.
69  p = wcsrchr(wszFilePath, L'.');
70  if (!p)
71  {
72  skip("File path has no file extension: %S\n", wszFilePath);
73  goto Cleanup;
74  }
75 
76  wcscpy(p, L".dll");
77 
78  // Check if the corresponding DLL file exists.
79  hFind = FindFirstFileW(wszFilePath, &fd);
80  if (hFind == INVALID_HANDLE_VALUE)
81  {
82  skip("My DLL file \"%S\" does not exist!\n", wszFilePath);
83  goto Cleanup;
84  }
85 
86  // Change the extension back to .exe and add the parameters.
87  wcscpy(p, L".exe service dummy");
88 
89  // Open a handle to the service manager.
91  if (!hSC)
92  {
93  skip("OpenSCManagerW failed with error %lu!\n", GetLastError());
94  goto Cleanup;
95  }
96 
97  // Ensure that the spooler service is running.
98  hService = OpenServiceW(hSC, L"spooler", SERVICE_QUERY_STATUS);
99  if (!hService)
100  {
101  skip("OpenServiceW failed for the spooler service with error %lu!\n", GetLastError());
102  goto Cleanup;
103  }
104 
105  if (!QueryServiceStatus(hService, &ServiceStatus))
106  {
107  skip("QueryServiceStatus failed for the spooler service with error %lu!\n", GetLastError());
108  goto Cleanup;
109  }
110 
112  {
113  skip("Spooler Service is not running!\n");
114  goto Cleanup;
115  }
116 
117  CloseServiceHandle(hService);
118 
119  // Try to open the service if we've created it in a previous run.
120  hService = OpenServiceW(hSC, SERVICE_NAME, SERVICE_ALL_ACCESS);
121  if (!hService)
122  {
124  {
125  // Create the service.
127  if (!hService)
128  {
129  skip("CreateServiceW failed with error %lu!\n", GetLastError());
130  goto Cleanup;
131  }
132  }
133  else
134  {
135  skip("OpenServiceW failed with error %lu!\n", GetLastError());
136  goto Cleanup;
137  }
138  }
139 
140  // Create pipes for the communication with the injected DLL.
142  if (hCommandPipe == INVALID_HANDLE_VALUE)
143  {
144  skip("CreateNamedPipeW failed for the command pipe with error %lu!\n", GetLastError());
145  goto Cleanup;
146  }
147 
149  if (hOutputPipe == INVALID_HANDLE_VALUE)
150  {
151  skip("CreateNamedPipeW failed for the output pipe with error %lu!\n", GetLastError());
152  goto Cleanup;
153  }
154 
155  // Start the service with "service" and a dummy parameter (to distinguish it from a call by rosautotest to localspl_apitest:service)
156  if (!StartServiceW(hService, 0, NULL))
157  {
158  skip("StartServiceW failed with error %lu!\n", GetLastError());
159  goto Cleanup;
160  }
161 
162  // Wait till it has injected the DLL and the DLL expects its test name.
163  if (!ConnectNamedPipe(hCommandPipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
164  {
165  skip("ConnectNamedPipe failed for the command pipe with error %lu!\n", GetLastError());
166  goto Cleanup;
167  }
168 
169  // Send the test name.
170  if (!WriteFile(hCommandPipe, szTestName, lstrlenA(szTestName) + sizeof(char), &cbWritten, NULL))
171  {
172  skip("WriteFile failed with error %lu!\n", GetLastError());
173  goto Cleanup;
174  }
175 
176  // Now wait for the DLL to connect to the output pipe.
177  if (!ConnectNamedPipe(hOutputPipe, NULL))
178  {
179  skip("ConnectNamedPipe failed for the output pipe with error %lu!\n", GetLastError());
180  goto Cleanup;
181  }
182 
183  // Get all testing messages from the pipe and output them on stdout.
184  while (ReadFile(hOutputPipe, szBuffer, sizeof(szBuffer), &cbRead, NULL) && cbRead)
185  fwrite(szBuffer, sizeof(char), cbRead, stdout);
186 
187  bSuccessful = TRUE;
188 
189 Cleanup:
190  if (hCommandPipe != INVALID_HANDLE_VALUE)
191  CloseHandle(hCommandPipe);
192 
193  if (hOutputPipe != INVALID_HANDLE_VALUE)
194  CloseHandle(hOutputPipe);
195 
196  if (hFind != INVALID_HANDLE_VALUE)
197  FindClose(hFind);
198 
199  if (hService)
200  CloseServiceHandle(hService);
201 
202  if (hSC)
203  CloseServiceHandle(hSC);
204 
205  // If we successfully received test output through the named pipe, we have also output a summary line already.
206  // Prevent the testing framework from outputting another "0 tests executed" line in this case.
207  if (bSuccessful)
208  ExitProcess(0);
209 }
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:407
DWORD dwCurrentState
Definition: winsvc.h:100
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:168
SC_HANDLE WINAPI CreateServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword)
Definition: scm.c:808
uint16_t * PWSTR
Definition: typedefs.h:55
#define PIPE_WAIT
Definition: winbase.h:171
#define OUTPUT_PIPE_NAME
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static int fd
Definition: io.c:51
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
FILE * stdout
unsigned int BOOL
Definition: ntddk_ex.h:94
#define SERVICE_RUNNING
Definition: winsvc.h:24
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2103
#define PIPE_TYPE_BYTE
Definition: winbase.h:167
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
BOOL WINAPI StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:2923
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define PRINTER_ENUM_NAME
Definition: winspool.h:895
static SERVICE_STATUS ServiceStatus
Definition: browser.c:22
#define MAX_PATH
Definition: compat.h:26
#define PRINTER_ENUM_LOCAL
Definition: winspool.h:892
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2788
WINBOOL WINAPI EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
#define PIPE_ACCESS_OUTBOUND
Definition: winbase.h:166
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:352
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2011
static const WCHAR Cleanup[]
Definition: register.c:80
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define SERVICE_NAME
Definition: wlansvc.c:18
#define PIPE_ACCESS_INBOUND
Definition: winbase.h:165
#define SC_MANAGER_ALL_ACCESS
Definition: winsvc.h:13
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
#define skip(...)
Definition: atltest.h:64
#define COMMAND_PIPE_NAME
GLfloat GLfloat p
Definition: glext.h:8902
HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:246
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
#define PIPE_READMODE_BYTE
Definition: winbase.h:169
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Referenced by START_TEST().

◆ START_TEST() [1/3]

START_TEST ( fpEnumPrinters  )

Definition at line 211 of file tests.c.

212 {
213  _RunRemoteTest("fpEnumPrinters");
214 }
static void _RunRemoteTest(const char *szTestName)
Definition: tests.c:41

◆ START_TEST() [2/3]

START_TEST ( fpGetPrintProcessorDirectory  )

Definition at line 216 of file tests.c.

217 {
218  _RunRemoteTest("fpGetPrintProcessorDirectory");
219 }
static void _RunRemoteTest(const char *szTestName)
Definition: tests.c:41

◆ START_TEST() [3/3]

START_TEST ( fpSetJob  )

Definition at line 221 of file tests.c.

222 {
223  _RunRemoteTest("fpSetJob");
224 }
static void _RunRemoteTest(const char *szTestName)
Definition: tests.c:41