ReactOS  0.4.13-dev-257-gfabbd7c
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
const uint16_t * PCWSTR
Definition: typedefs.h:55
#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
#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
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define va_end(ap)
Definition: acmsvcex.h:90
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GENERIC_WRITE
Definition: nt_native.h:90
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define ok(value,...)
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:111
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
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
#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
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
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:1250
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 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 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
#define skip(...)
#define msg(x)
Definition: auth_time.c:54
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
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