ReactOS  0.4.12-dev-375-g61fed54
ServiceArgs.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE: Test for service arguments
5  * PROGRAMMER: Jacek Caban for CodeWeavers
6  * Thomas Faber <thomas.faber@reactos.org>
7  */
8 
9 #include "precomp.h"
10 
11 static char **argv;
12 static int argc;
13 
15 static char service_nameA[100];
16 static WCHAR service_nameW[100];
17 static WCHAR named_pipe_name[100];
18 
19 /* Test process global variables */
20 static SC_HANDLE scm_handle;
22 
23 static void send_msg(const char *type, const char *msg)
24 {
25  DWORD written = 0;
26  char buf[512];
27 
28  StringCbPrintfA(buf, sizeof(buf), "%s:%s", type, msg);
29  WriteFile(pipe_handle, buf, strlen(buf)+1, &written, NULL);
30 }
31 
32 #if 0
33 static inline void service_trace(const char *msg, ...)
34 {
36  char buf[512];
37 
39  StringCbVPrintfA(buf, sizeof(buf), msg, valist);
40  va_end(valist);
41 
42  send_msg("TRACE", buf);
43 }
44 #endif
45 
46 static void service_ok(int cnd, const char *msg, ...)
47 {
49  char buf[512];
50 
52  StringCbVPrintfA(buf, sizeof(buf), msg, valist);
53  va_end(valist);
54 
55  send_msg(cnd ? "OK" : "FAIL", buf);
56 }
57 
59 {
61 
62  status.dwServiceType = SERVICE_WIN32;
63  status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
64  status.dwWin32ExitCode = 0;
65  status.dwServiceSpecificExitCode = 0;
66  status.dwCheckPoint = 0;
67  status.dwWaitHint = 0;
68 
69  switch(ctrl)
70  {
72  status.dwCurrentState = SERVICE_STOP_PENDING;
73  status.dwControlsAccepted = 0;
75  default:
76  status.dwCurrentState = SERVICE_RUNNING;
78  }
79 }
80 
81 static void service_main_common(void)
82 {
84  BOOL res;
85 
87  service_ok(service_handle != NULL, "RegisterServiceCtrlHandler failed: %lu\n", GetLastError());
88  if (!service_handle)
89  return;
90 
91  status.dwServiceType = SERVICE_WIN32;
92  status.dwCurrentState = SERVICE_RUNNING;
93  status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
94  status.dwWin32ExitCode = 0;
95  status.dwServiceSpecificExitCode = 0;
96  status.dwCheckPoint = 0;
97  status.dwWaitHint = 10000;
99  service_ok(res, "SetServiceStatus(SERVICE_RUNNING) failed: %lu", GetLastError());
100 
101  Sleep(100);
102 
103  status.dwCurrentState = SERVICE_STOPPED;
104  status.dwControlsAccepted = 0;
106  service_ok(res, "SetServiceStatus(SERVICE_STOPPED) failed: %lu", GetLastError());
107 }
108 
109 /*
110  * A/W argument layout XP/2003:
111  * [argv array of pointers][parameter 1][parameter 2]...[service name]
112  *
113  * A/W argument layout Vista:
114  * [argv array of pointers][align to 8 bytes][parameter 1][parameter 2]...[service name]
115  *
116  * A/W argument layout Win7/8:
117  * [argv array of pointers][service name]
118  * [parameter 1][align to 4 bytes][parameter 2][align to 4 bytes]...
119  *
120  * Space for parameters and service name is always enough to store
121  * the WCHAR version including null terminator.
122  */
123 
124 static void WINAPI service_mainA(DWORD service_argc, char **service_argv)
125 {
126  int i;
127  char *next_arg;
128  char *next_arg_aligned;
129 
130  service_ok(service_argc == argc - 3, "service_argc = %d, expected %d", service_argc, argc - 3);
131  if (service_argc == argc - 3)
132  {
133  service_ok(!strcmp(service_argv[0], service_nameA), "service_argv[0] = %s, expected %s", service_argv[0], service_nameA);
134  service_ok(service_argv[0] == (char *)&service_argv[service_argc] ||
135  service_argv[1] == (char *)&service_argv[service_argc] ||
136  service_argv[1] == (char *)(((ULONG_PTR)&service_argv[service_argc] + 7) & ~7), "service_argv[0] = %p, [1] = %p, expected one of them to be %p", service_argv[0], service_argv[1], &service_argv[service_argc]);
137  //service_trace("service_argv[0] = %p", service_argv[0]);
138  next_arg_aligned = next_arg = NULL;
139  for (i = 1; i < service_argc; i++)
140  {
141  //service_trace("service_argv[%d] = %p", i, service_argv[i]);
142  service_ok(!strcmp(service_argv[i], argv[i + 3]), "service_argv[%d] = %s, expected %s", i, service_argv[i], argv[i + 3]);
143  service_ok(next_arg == NULL ||
144  service_argv[i] == next_arg ||
145  service_argv[i] == next_arg_aligned, "service_argv[%d] = %p, expected %p or %p", i, service_argv[i], next_arg, next_arg_aligned);
146  next_arg = service_argv[i];
147  next_arg += 2 * (strlen(next_arg) + 1);
148  next_arg_aligned = (char *)(((ULONG_PTR)next_arg + 3) & ~3);
149  }
150  }
151 
153 }
154 
155 static void WINAPI service_mainW(DWORD service_argc, WCHAR **service_argv)
156 {
157  int i;
158  WCHAR argW[32];
159  WCHAR *next_arg;
160  WCHAR *next_arg_aligned;
161 
162  service_ok(service_argc == argc - 3, "service_argc = %d, expected %d", service_argc, argc - 3);
163  if (service_argc == argc - 3)
164  {
165  service_ok(!wcscmp(service_argv[0], service_nameW), "service_argv[0] = %ls, expected %ls", service_argv[0], service_nameW);
166  service_ok(service_argv[0] == (WCHAR *)&service_argv[service_argc] ||
167  service_argv[1] == (WCHAR *)&service_argv[service_argc] ||
168  service_argv[1] == (WCHAR *)(((ULONG_PTR)&service_argv[service_argc] + 7) & ~7), "service_argv[0] = %p, [1] = %p, expected one of them to be %p", service_argv[0], service_argv[1], &service_argv[service_argc]);
169  //service_trace("service_argv[0] = %p", service_argv[0]);
170  next_arg_aligned = next_arg = NULL;
171  for (i = 1; i < service_argc; i++)
172  {
173  //service_trace("service_argv[%d] = %p", i, service_argv[i]);
174  MultiByteToWideChar(CP_ACP, 0, argv[i + 3], -1, argW, _countof(argW));
175  service_ok(!wcscmp(service_argv[i], argW), "service_argv[%d] = %ls, expected %ls", i, service_argv[i], argW);
176  service_ok(next_arg == NULL ||
177  service_argv[i] == next_arg ||
178  service_argv[i] == next_arg_aligned, "service_argv[%d] = %p, expected %p or %p", i, service_argv[i], next_arg, next_arg_aligned);
179  next_arg = service_argv[i];
180  next_arg += wcslen(next_arg) + 1;
181  next_arg_aligned = (WCHAR *)(((ULONG_PTR)next_arg + 3) & ~3);
182  }
183  }
184 
186 }
187 
188 static void service_process(BOOLEAN unicode)
189 {
190  BOOL res;
191 
192  SERVICE_TABLE_ENTRYA servtblA[] =
193  {
195  { NULL, NULL }
196  };
197  SERVICE_TABLE_ENTRYW servtblW[] =
198  {
200  { NULL, NULL }
201  };
202 
204  if (!res)
205  return;
206 
209  return;
210 
211  //service_trace("Starting...");
212  if (unicode)
213  {
214  res = StartServiceCtrlDispatcherW(servtblW);
215  service_ok(res, "StartServiceCtrlDispatcherW failed: %lu\n", GetLastError());
216  }
217  else
218  {
219  res = StartServiceCtrlDispatcherA(servtblA);
220  service_ok(res, "StartServiceCtrlDispatcherA failed: %lu\n", GetLastError());
221  }
222 
224 }
225 
226 static SC_HANDLE register_service(PCWSTR extra_args)
227 {
228  WCHAR service_cmd[MAX_PATH+150];
229  SC_HANDLE service;
230 
231  GetModuleFileNameW(NULL, service_cmd, MAX_PATH);
232 
233  StringCbCatW(service_cmd, sizeof(service_cmd), L" ServiceArgs ");
234  StringCbCatW(service_cmd, sizeof(service_cmd), service_nameW);
235  StringCbCatW(service_cmd, sizeof(service_cmd), extra_args);
236 
237  trace("service_cmd \"%ls\"\n", service_cmd);
238 
241  service_cmd, NULL, NULL, NULL, NULL, NULL);
242  if (!service && GetLastError() == ERROR_ACCESS_DENIED)
243  {
244  skip("Not enough access right to create service\n");
245  return NULL;
246  }
247 
248  ok(service != NULL, "CreateService failed: %lu\n", GetLastError());
249  return service;
250 }
251 
253 {
254  char buf[512];
255  DWORD read;
256  BOOL res;
257 
259  ok(res || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe failed: %lu\n", GetLastError());
260 
261  while (1)
262  {
263  res = ReadFile(pipe_handle, buf, sizeof(buf), &read, NULL);
264  if (!res)
265  {
267  "ReadFile failed: %lu\n", GetLastError());
268  break;
269  }
270 
271  if (!strncmp(buf, "TRACE:", 6))
272  {
273  trace("service trace: %s\n", buf+6);
274  }
275  else if (!strncmp(buf, "OK:", 3))
276  {
277  ok(1, "service: %s\n", buf+3);
278  }
279  else if (!strncmp(buf, "FAIL:", 5))
280  {
281  ok(0, "service: %s\n", buf+5);
282  }
283  else
284  {
285  ok(0, "malformed service message: %s\n", buf);
286  }
287  }
288 
290  //trace("pipe disconnected\n");
291  return 0;
292 }
293 
294 static void test_startA(SC_HANDLE service_handle, int service_argc, const char **service_argv)
295 {
297  BOOL res;
298 
299  res = StartServiceA(service_handle, service_argc, service_argv);
300  ok(res, "StartService failed: %lu\n", GetLastError());
301  if (!res)
302  return;
303 
304  do
305  {
306  Sleep(100);
307  ZeroMemory(&status, sizeof(status));
309  } while (res && status.dwCurrentState != SERVICE_STOPPED);
310  ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
311  ok(status.dwCurrentState == SERVICE_STOPPED, "status.dwCurrentState = %lx\n", status.dwCurrentState);
312 }
313 
314 static void test_startW(SC_HANDLE service_handle, int service_argc, const WCHAR **service_argv)
315 {
317  BOOL res;
318 
319  res = StartServiceW(service_handle, service_argc, service_argv);
320  ok(res, "StartService failed: %lu\n", GetLastError());
321  if (!res)
322  return;
323 
324  do
325  {
326  Sleep(100);
327  ZeroMemory(&status, sizeof(status));
329  } while (res && status.dwCurrentState != SERVICE_STOPPED);
330  ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
331  ok(status.dwCurrentState == SERVICE_STOPPED, "status.dwCurrentState = %lx\n", status.dwCurrentState);
332 }
333 
334 static void test_runner(BOOLEAN unicode, PCWSTR extra_args, int service_argc, void *service_argv)
335 {
336  HANDLE thread;
337  SC_HANDLE service_handle;
338  BOOL res;
339 
340  StringCbPrintfW(service_nameW, sizeof(service_nameW), L"WineTestService%lu", GetTickCount());
342  //trace("service_name: %ls\n", service_nameW);
343  StringCbPrintfW(named_pipe_name, sizeof(named_pipe_name), L"\\\\.\\pipe\\%ls_pipe", service_nameW);
344 
346  PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, 10, 2048, 2048, 10000, NULL);
347  ok(pipe_handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError());
349  return;
350 
352  ok(thread != NULL, "CreateThread failed: %lu\n", GetLastError());
353  if (!thread)
354  goto Quit;
355 
356  service_handle = register_service(extra_args);
357  if (!service_handle)
358  goto Quit;
359 
360  //trace("starting...\n");
361 
362  if (unicode)
363  test_startW(service_handle, service_argc, service_argv);
364  else
365  test_startA(service_handle, service_argc, service_argv);
366 
368  ok(res, "DeleteService failed: %lu\n", GetLastError());
369 
371 
372  ok(WaitForSingleObject(thread, 10000) == WAIT_OBJECT_0, "Timeout waiting for thread\n");
373 
374 Quit:
375  if (thread)
377 
380 }
381 
382 START_TEST(ServiceArgs)
383 {
385 
387  ok(scm_handle != NULL, "OpenSCManager failed: %lu\n", GetLastError());
388  if (!scm_handle)
389  {
390  skip("Failed to open service control manager. Skipping test\n");
391  return;
392  }
393 
394  if (argc < 3)
395  {
396  char *service_argvA[10];
397  WCHAR *service_argvW[10];
398 
399  test_runner(FALSE, L" A", 0, NULL);
400  test_runner(FALSE, L" W", 0, NULL);
401  test_runner(TRUE, L" A", 0, NULL);
402  test_runner(TRUE, L" W", 0, NULL);
403 
404  service_argvA[0] = "x";
405  service_argvW[0] = L"x";
406  test_runner(FALSE, L" A x", 1, service_argvA);
407  test_runner(FALSE, L" W x", 1, service_argvA);
408  test_runner(TRUE, L" A x", 1, service_argvW);
409  test_runner(TRUE, L" W x", 1, service_argvW);
410 
411  service_argvA[1] = "y";
412  service_argvW[1] = L"y";
413  test_runner(FALSE, L" A x y", 2, service_argvA);
414  test_runner(FALSE, L" W x y", 2, service_argvA);
415  test_runner(TRUE, L" A x y", 2, service_argvW);
416  test_runner(TRUE, L" W x y", 2, service_argvW);
417 
418  service_argvA[0] = "ab";
419  service_argvW[0] = L"ab";
420  test_runner(FALSE, L" A ab y", 2, service_argvA);
421  test_runner(FALSE, L" W ab y", 2, service_argvA);
422  test_runner(TRUE, L" A ab y", 2, service_argvW);
423  test_runner(TRUE, L" W ab y", 2, service_argvW);
424 
425  service_argvA[0] = "abc";
426  service_argvW[0] = L"abc";
427  test_runner(FALSE, L" A abc y", 2, service_argvA);
428  test_runner(FALSE, L" W abc y", 2, service_argvA);
429  test_runner(TRUE, L" A abc y", 2, service_argvW);
430  test_runner(TRUE, L" W abc y", 2, service_argvW);
431 
432  service_argvA[0] = "abcd";
433  service_argvW[0] = L"abcd";
434  test_runner(FALSE, L" A abcd y", 2, service_argvA);
435  test_runner(FALSE, L" W abcd y", 2, service_argvA);
436  test_runner(TRUE, L" A abcd y", 2, service_argvW);
437  test_runner(TRUE, L" W abcd y", 2, service_argvW);
438 
439  service_argvA[0] = "abcde";
440  service_argvW[0] = L"abcde";
441  test_runner(FALSE, L" A abcde y", 2, service_argvA);
442  test_runner(FALSE, L" W abcde y", 2, service_argvA);
443  test_runner(TRUE, L" A abcde y", 2, service_argvW);
444  test_runner(TRUE, L" W abcde y", 2, service_argvW);
445 
446  service_argvA[0] = "abcdef";
447  service_argvW[0] = L"abcdef";
448  test_runner(FALSE, L" A abcdef y", 2, service_argvA);
449  test_runner(FALSE, L" W abcdef y", 2, service_argvA);
450  test_runner(TRUE, L" A abcdef y", 2, service_argvW);
451  test_runner(TRUE, L" W abcdef y", 2, service_argvW);
452 
453  service_argvA[0] = "abcdefg";
454  service_argvW[0] = L"abcdefg";
455  test_runner(FALSE, L" A abcdefg y", 2, service_argvA);
456  test_runner(FALSE, L" W abcdefg y", 2, service_argvA);
457  test_runner(TRUE, L" A abcdefg y", 2, service_argvW);
458  test_runner(TRUE, L" W abcdefg y", 2, service_argvW);
459 
460  service_argvA[0] = "";
461  service_argvW[0] = L"";
462  test_runner(FALSE, L" A \"\" y", 2, service_argvA);
463  test_runner(FALSE, L" W \"\" y", 2, service_argvA);
464  test_runner(TRUE, L" A \"\" y", 2, service_argvW);
465  test_runner(TRUE, L" W \"\" y", 2, service_argvW);
466  }
467  else
468  {
471  StringCbPrintfW(named_pipe_name, sizeof(named_pipe_name), L"\\\\.\\pipe\\%ls_pipe", service_nameW);
472  if (!strcmp(argv[3], "A"))
474  else
476  }
477 
479 }
static void test_runner(BOOLEAN unicode, PCWSTR extra_args, int service_argc, void *service_argv)
Definition: ServiceArgs.c:334
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:607
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static int argc
Definition: ServiceArgs.c:12
#define trace(...)
Definition: kmt_test.h:217
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:979
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
#define WideCharToMultiByte
Definition: compat.h:101
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:168
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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
static SC_HANDLE scm_handle
Definition: ServiceArgs.c:20
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CP_ACP
Definition: compat.h:99
#define _countof(array)
Definition: fontsub.cpp:30
static void service_main_common(void)
Definition: ServiceArgs.c:81
BOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
Definition: npipe.c:458
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
static void service_process(BOOLEAN unicode)
Definition: ServiceArgs.c:188
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
static DWORD WINAPI pipe_thread(void *arg)
Definition: ServiceArgs.c:252
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define PIPE_WAIT
Definition: winbase.h:171
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:732
#define NMPWAIT_USE_DEFAULT_WAIT
Definition: winbase.h:134
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:916
BOOL WINAPI StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
Definition: sctrl.c:1123
BOOL WINAPI StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
Definition: sctrl.c:1024
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
static char ** argv
Definition: ServiceArgs.c:11
uint32_t ULONG_PTR
Definition: typedefs.h:63
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:986
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static void test_startW(SC_HANDLE service_handle, int service_argc, const WCHAR **service_argv)
Definition: ServiceArgs.c:314
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define va_end(ap)
Definition: acmsvcex.h:90
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define GENERIC_WRITE
Definition: nt_native.h:90
#define SERVICE_RUNNING
Definition: winsvc.h:24
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
unsigned char BOOLEAN
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:112
UINT msg
Definition: msvc.h:92
static void test_startA(SC_HANDLE service_handle, int service_argc, const char **service_argv)
Definition: ServiceArgs.c:294
smooth NULL
Definition: ftsmooth.c:416
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
char * va_list
Definition: acmsvcex.h:78
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
void service_trace(const char *msg,...)
Definition: svchlp.c:36
#define OPEN_EXISTING
Definition: compat.h:426
#define ctrl
Definition: input.c:1669
#define ok(value,...)
Definition: CComObject.cpp:34
BOOL WINAPI StartServiceA(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCSTR *lpServiceArgVectors)
Definition: scm.c:2885
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
BOOL WINAPI StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:2923
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WAIT_OBJECT_0
Definition: winbase.h:387
STRSAFEAPI StringCbPrintfA(STRSAFE_LPSTR pszDest, size_t cbDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:547
static void service_ok(int cnd, const char *msg,...)
Definition: ServiceArgs.c:46
#define MAX_PATH
Definition: compat.h:26
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_BROKEN_PIPE
Definition: winerror.h:183
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2788
int winetest_get_mainargs(char ***pargv)
char * next_arg(char *src, char needle)
Definition: rdesktop.c:1174
STRSAFEAPI StringCbVPrintfA(STRSAFE_LPSTR pszDest, size_t cbDest, STRSAFE_LPCSTR pszFormat, va_list argList)
Definition: strsafe.h:502
static HANDLE thread
Definition: service.c:33
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static void WINAPI service_mainW(DWORD service_argc, WCHAR **service_argv)
Definition: ServiceArgs.c:155
static const WCHAR L[]
Definition: oid.c:1087
static WCHAR named_pipe_name[100]
Definition: ServiceArgs.c:17
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:352
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2011
BOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe)
Definition: npipe.c:961
static VOID WINAPI service_handler(DWORD ctrl)
Definition: ServiceArgs.c:58
#define WINAPI
Definition: msvc.h:20
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
START_TEST(ServiceArgs)
Definition: ServiceArgs.c:382
static HANDLE pipe_handle
Definition: ServiceArgs.c:14
#define skip(...)
Definition: CString.cpp:57
#define SERVICE_WIN32
Definition: cmtypes.h:962
#define PIPE_ACCESS_INBOUND
Definition: winbase.h:165
#define va_start(ap, A)
Definition: acmsvcex.h:91
static char service_nameA[100]
Definition: ServiceArgs.c:15
static void WINAPI service_mainA(DWORD service_argc, char **service_argv)
Definition: ServiceArgs.c:124
#define SC_MANAGER_ALL_ACCESS
Definition: winsvc.h:13
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:400
static WCHAR service_nameW[100]
Definition: ServiceArgs.c:16
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
static __ms_va_list valist
Definition: printf.c:59
const uint16_t * PCWSTR
Definition: typedefs.h:55
HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:246
static void send_msg(const char *type, const char *msg)
Definition: ServiceArgs.c:23
#define SERVICE_DEMAND_START
Definition: cmtypes.h:976
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
static SERVICE_STATUS status
Definition: service.c:31
static SERVICE_STATUS_HANDLE service_handle
Definition: ServiceArgs.c:21
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
static SC_HANDLE register_service(PCWSTR extra_args)
Definition: ServiceArgs.c:226
Definition: ps.c:97