ReactOS  0.4.15-dev-3017-g1d9542d
ServiceEnv.c File Reference
#include "precomp.h"
#include "svchlp.h"
Include dependency graph for ServiceEnv.c:

Go to the source code of this file.

Functions

static void report_service_status (DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
 
static VOID WINAPI service_handler (DWORD ctrl)
 
static void WINAPI service_main (DWORD dwArgc, LPWSTR *lpszArgv)
 
static BOOL start_service (PCSTR service_nameA, PCWSTR service_nameW)
 
static void my_test_server (PCSTR service_nameA, PCWSTR service_nameW, void *param)
 
 START_TEST (ServiceEnv)
 

Variables

static SERVICE_STATUS_HANDLE status_handle
 

Function Documentation

◆ my_test_server()

static void my_test_server ( PCSTR  service_nameA,
PCWSTR  service_nameW,
void param 
)
static

Definition at line 168 of file ServiceEnv.c.

171 {
172  BOOL res;
173  SC_HANDLE hSC = NULL;
174  SC_HANDLE hService = NULL;
176 
177  /* Open the SCM */
179  if (!hSC)
180  {
181  skip("OpenSCManagerW failed with error %lu!\n", GetLastError());
182  return;
183  }
184 
185  /* First create ourselves as a service running in the default LocalSystem account */
186  hService = register_service_exW(hSC, L"ServiceEnv", service_nameW, NULL,
191  NULL, NULL, NULL,
192  NULL, NULL);
193  if (!hService)
194  {
195  skip("CreateServiceW failed with error %lu!\n", GetLastError());
196  goto Cleanup;
197  }
198 
199  /* Start it */
200  if (!StartServiceW(hService, 0, NULL))
201  {
202  skip("StartServiceW failed with error %lu!\n", GetLastError());
203  goto Cleanup;
204  }
205 
206  /* Wait for the service to stop by itself */
207  do
208  {
209  Sleep(100);
211  res = QueryServiceStatus(hService, &ServiceStatus);
213  ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
214  ok(ServiceStatus.dwCurrentState == SERVICE_STOPPED, "ServiceStatus.dwCurrentState = %lx\n", ServiceStatus.dwCurrentState);
215 
216  /* Be sure the service is really stopped */
221  {
222  skip("ControlService failed with error %lu!\n", GetLastError());
223  goto Cleanup;
224  }
225 
226 #if 0
227  trace("Service stopped. Going to restart it...\n");
228 
229  /* Now change the service configuration to make it start under the NetworkService account */
230  if (!ChangeServiceConfigW(hService,
234  NULL, NULL, NULL, NULL,
235  L"NT AUTHORITY\\NetworkService", L"",
236  NULL))
237  {
238  skip("ChangeServiceConfigW failed with error %lu!\n", GetLastError());
239  goto Cleanup;
240  }
241 
242  /* Start it */
243  if (!StartServiceW(hService, 0, NULL))
244  {
245  skip("StartServiceW failed with error %lu!\n", GetLastError());
246  goto Cleanup;
247  }
248 
249  /* Wait for the service to stop by itself */
250  do
251  {
252  Sleep(100);
254  res = QueryServiceStatus(hService, &ServiceStatus);
256  ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
257  ok(ServiceStatus.dwCurrentState == SERVICE_STOPPED, "ServiceStatus.dwCurrentState = %lx\n", ServiceStatus.dwCurrentState);
258 
259  /* Be sure the service is really stopped */
264  {
265  skip("ControlService failed with error %lu!\n", GetLastError());
266  goto Cleanup;
267  }
268 #endif
269 
270 Cleanup:
271  if (hService)
272  {
273  res = DeleteService(hService);
274  ok(res, "DeleteService failed: %lu\n", GetLastError());
275  CloseServiceHandle(hService);
276  }
277 
278  if (hSC)
279  CloseServiceHandle(hSC);
280 }
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
DWORD dwCurrentState
Definition: winsvc.h:100
#define SERVICE_INTERACTIVE_PROCESS
Definition: cmtypes.h:967
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1664
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
#define ERROR_SERVICE_NOT_ACTIVE
Definition: winerror.h:613
#define SERVICE_NO_CHANGE
Definition: winsvc.h:20
#define SERVICE_STOPPED
Definition: winsvc.h:21
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI ChangeServiceConfigW(SC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName)
Definition: scm.c:482
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
BOOL WINAPI StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:2928
#define trace
Definition: atltest.h:70
static SERVICE_STATUS ServiceStatus
Definition: browser.c:22
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2793
static const WCHAR L[]
Definition: oid.c:1250
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2016
static const WCHAR Cleanup[]
Definition: register.c:80
#define ok(value,...)
Definition: atltest.h:57
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:622
#define NULL
Definition: types.h:112
#define SC_MANAGER_ALL_ACCESS
Definition: winsvc.h:13
#define skip(...)
Definition: atltest.h:64
static WCHAR service_nameW[100]
Definition: ServiceArgs.c:16
GLuint res
Definition: glext.h:9613
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
SC_HANDLE register_service_exW(SC_HANDLE scm_handle, PCWSTR test_name, PCWSTR service_name, PCWSTR extra_args OPTIONAL, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpLoadOrderGroup OPTIONAL, LPDWORD lpdwTagId OPTIONAL, LPCWSTR lpDependencies OPTIONAL, LPCWSTR lpServiceStartName OPTIONAL, LPCWSTR lpPassword OPTIONAL)
Definition: svchlp.c:142

Referenced by START_TEST().

◆ report_service_status()

static void report_service_status ( DWORD  dwCurrentState,
DWORD  dwWin32ExitCode,
DWORD  dwWaitHint 
)
static

Definition at line 18 of file ServiceEnv.c.

21 {
22  BOOL res;
24 
25  status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
26  status.dwCurrentState = dwCurrentState;
27  status.dwWin32ExitCode = dwWin32ExitCode;
28  status.dwWaitHint = dwWaitHint;
29 
30  status.dwServiceSpecificExitCode = 0;
31  status.dwCheckPoint = 0;
32 
33  if ( (dwCurrentState == SERVICE_START_PENDING) ||
34  (dwCurrentState == SERVICE_STOP_PENDING) ||
35  (dwCurrentState == SERVICE_STOPPED) )
36  {
37  status.dwControlsAccepted = 0;
38  }
39  else
40  {
41  status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
42  }
43 
44 #if 0
45  if ( (dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED) )
46  status.dwCheckPoint = 0;
47  else
48  status.dwCheckPoint = dwCheckPoint++;
49 #endif
50 
52  service_ok(res, "SetServiceStatus(%d) failed: %lu\n", dwCurrentState, GetLastError());
53 }
static SERVICE_STATUS_HANDLE status_handle
Definition: ServiceEnv.c:15
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define SERVICE_START_PENDING
Definition: winsvc.h:22
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:997
#define SERVICE_STOPPED
Definition: winsvc.h:21
unsigned int BOOL
Definition: ntddk_ex.h:94
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
static void service_ok(int cnd, const char *msg,...)
Definition: ServiceArgs.c:46
GLuint res
Definition: glext.h:9613
static SERVICE_STATUS status
Definition: service.c:31
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
Definition: ps.c:97

Referenced by service_handler(), and service_main().

◆ service_handler()

static VOID WINAPI service_handler ( DWORD  ctrl)
static

Definition at line 55 of file ServiceEnv.c.

56 {
57  switch(ctrl)
58  {
62  default:
64  }
65 }
static void report_service_status(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
Definition: ServiceEnv.c:18
#define NO_ERROR
Definition: dderror.h:5
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define ctrl
Definition: input.c:1757
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40

Referenced by service_main().

◆ service_main()

static void WINAPI service_main ( DWORD  dwArgc,
LPWSTR lpszArgv 
)
static

Definition at line 68 of file ServiceEnv.c.

69 {
70  // SERVICE_STATUS_HANDLE status_handle;
71  LPWSTR lpEnvironment, lpEnvStr;
72  DWORD dwSize;
73  PTEB Teb;
74 
75  UNREFERENCED_PARAMETER(dwArgc);
76  UNREFERENCED_PARAMETER(lpszArgv);
77 
78  /* Register our service for control (lpszArgv[0] holds the service name) */
80  service_ok(status_handle != NULL, "RegisterServiceCtrlHandler failed: %lu\n", GetLastError());
81  if (!status_handle)
82  return;
83 
84  /* Report SERVICE_RUNNING status */
86 
87  /* Display our current environment for informative purposes */
88  lpEnvironment = GetEnvironmentStringsW();
89  lpEnvStr = lpEnvironment;
90  while (*lpEnvStr)
91  {
92  service_trace("%S\n", lpEnvStr);
93  lpEnvStr += wcslen(lpEnvStr) + 1;
94  }
95  FreeEnvironmentStringsW(lpEnvironment);
96 
97  /* Check the presence of the user-related environment variables */
98  dwSize = GetEnvironmentVariableW(L"ALLUSERSPROFILE", NULL, 0);
99  service_ok(dwSize != 0, "ALLUSERSPROFILE envvar not found, or GetEnvironmentVariableW failed: %lu\n", GetLastError());
100  dwSize = GetEnvironmentVariableW(L"USERPROFILE", NULL, 0);
101  service_ok(dwSize != 0, "USERPROFILE envvar not found, or GetEnvironmentVariableW failed: %lu\n", GetLastError());
102 #if 0 // May not always exist
103  dwSize = GetEnvironmentVariableW(L"USERNAME", NULL, 0);
104  service_ok(dwSize != 0, "USERNAME envvar not found, or GetEnvironmentVariableW failed: %lu\n", GetLastError());
105 #endif
106 
107  Teb = NtCurrentTeb();
108  service_ok(Teb->SubProcessTag != 0, "SubProcessTag is not defined!\n");
109  if (Teb->SubProcessTag != 0)
110  {
111  ULONG (NTAPI *_I_QueryTagInformation)(PVOID, DWORD, PVOID) = (PVOID)GetProcAddress(GetModuleHandle("advapi32.dll"), "I_QueryTagInformation");
112  if (_I_QueryTagInformation != NULL)
113  {
114  /* IN/OUT parameter structure for I_QueryTagInformation() function
115  * See: https://wj32.org/wp/2010/03/30/howto-use-i_querytaginformation/
116  * See: https://github.com/processhacker/processhacker/blob/master/phnt/include/subprocesstag.h
117  */
118  struct
119  {
122  ULONG TagType;
123  PWSTR Buffer;
124  } ServiceQuery;
125 
126  /* Set our input parameters */
127  ServiceQuery.ProcessId = GetCurrentProcessId();
128  ServiceQuery.ServiceTag = Teb->SubProcessTag;
129  ServiceQuery.TagType = 0;
130  ServiceQuery.Buffer = NULL;
131  /* Call ADVAPI32 to query the correctness of our tag */
132  _I_QueryTagInformation(NULL, 1, &ServiceQuery);
133 
134  /* If buffer is not NULL, call succeed */
135  if (ServiceQuery.Buffer != NULL)
136  {
137  /* It should match our service name */
138  service_ok(wcscmp(lpszArgv[0], ServiceQuery.Buffer) == 0, "Mismatching info: %S - %S\n", lpszArgv[0], ServiceQuery.Buffer);
139  service_ok(ServiceQuery.TagType == 1, "Invalid tag type: %x\n", ServiceQuery.TagType);
140  LocalFree(ServiceQuery.Buffer);
141  }
142  }
143  }
144 
145  /* Work is done */
147 }
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
static SERVICE_STATUS_HANDLE status_handle
Definition: ServiceEnv.c:15
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
uint16_t * PWSTR
Definition: typedefs.h:56
static void report_service_status(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
Definition: ServiceEnv.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION lpHandlerProc)
Definition: sctrl.c:742
#define NO_ERROR
Definition: dderror.h:5
#define DWORD
Definition: nt_native.h:44
#define SERVICE_STOPPED
Definition: winsvc.h:21
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define SERVICE_RUNNING
Definition: winsvc.h:24
void * PVOID
Definition: retypes.h:9
void service_trace(const char *msg,...)
Definition: svchlp.c:36
static void service_ok(int cnd, const char *msg,...)
Definition: ServiceArgs.c:46
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR L[]
Definition: oid.c:1250
static VOID WINAPI service_handler(DWORD ctrl)
Definition: ServiceEnv.c:55
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
Definition: compat.h:694
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define GetModuleHandle
Definition: winbase.h:3683
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
LPWSTR WINAPI GetEnvironmentStringsW(VOID)
Definition: environ.c:344
unsigned int ULONG
Definition: retypes.h:1
#define GetProcAddress(x, y)
Definition: compat.h:612
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:614
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
static DWORD ServiceTag
Definition: database.c:34

Referenced by start_service().

◆ start_service()

static BOOL start_service ( PCSTR  service_nameA,
PCWSTR  service_nameW 
)
static

Definition at line 149 of file ServiceEnv.c.

150 {
151  BOOL res;
152 
153  SERVICE_TABLE_ENTRYW servtbl[] =
154  {
156  { NULL, NULL }
157  };
158 
159  res = StartServiceCtrlDispatcherW(servtbl);
160  service_ok(res, "StartServiceCtrlDispatcherW failed: %lu\n", GetLastError());
161  return res;
162 }
uint16_t * PWSTR
Definition: typedefs.h:56
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
BOOL WINAPI StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
Definition: sctrl.c:1134
unsigned int BOOL
Definition: ntddk_ex.h:94
static void service_ok(int cnd, const char *msg,...)
Definition: ServiceArgs.c:46
#define NULL
Definition: types.h:112
static WCHAR service_nameW[100]
Definition: ServiceArgs.c:16
GLuint res
Definition: glext.h:9613
static void WINAPI service_main(DWORD dwArgc, LPWSTR *lpszArgv)
Definition: ServiceEnv.c:68

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( ServiceEnv  )

Definition at line 282 of file ServiceEnv.c.

283 {
284  int argc;
285  char** argv;
286  PTEB Teb;
287 
288  /* Check whether this test is started as a separated service process */
290  if (argc >= 3)
291  {
293  return;
294  }
295 
296  Teb = NtCurrentTeb();
297  ok(Teb->SubProcessTag == 0, "SubProcessTag is defined: %p\n", Teb->SubProcessTag);
298 
299  /* We are started as the real test */
301  // trace("Returned from test_runner\n");
302 }
static void test_runner(BOOLEAN unicode, PCWSTR extra_args, int service_argc, void *service_argv)
Definition: ServiceArgs.c:334
static int argc
Definition: ServiceArgs.c:12
static void service_process(BOOLEAN unicode)
Definition: ServiceArgs.c:188
static void my_test_server(PCSTR service_nameA, PCWSTR service_nameW, void *param)
Definition: ServiceEnv.c:168
#define argv
Definition: mplay32.c:18
static BOOL start_service(PCSTR service_nameA, PCWSTR service_nameW)
Definition: ServiceEnv.c:149
int winetest_get_mainargs(char ***pargv)
Definition: compat.h:694
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112

Variable Documentation

◆ status_handle

SERVICE_STATUS_HANDLE status_handle
static

Definition at line 15 of file ServiceEnv.c.

Referenced by report_service_status(), and service_main().