[SHELL32_APITEST] -Add some tests for SHParseDisplayName for CORE-12882.
[reactos.git] / rostests / apitests / advapi32 / ServiceEnv.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for service process environment block
5 * PROGRAMMER: Hermes Belusca-Maito
6 */
7
8 #include <apitest.h>
9 #include <winsvc.h>
10 #include "svchlp.h"
11
12
13 /*** Service part of the test ***/
14
15 static SERVICE_STATUS_HANDLE status_handle;
16
17 static void
18 report_service_status(DWORD dwCurrentState,
19 DWORD dwWin32ExitCode,
20 DWORD dwWaitHint)
21 {
22 BOOL res;
23 SERVICE_STATUS status;
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
51 res = SetServiceStatus(status_handle, &status);
52 service_ok(res, "SetServiceStatus(%d) failed: %lu\n", dwCurrentState, GetLastError());
53 }
54
55 static VOID WINAPI service_handler(DWORD ctrl)
56 {
57 switch(ctrl)
58 {
59 case SERVICE_CONTROL_STOP:
60 case SERVICE_CONTROL_SHUTDOWN:
61 report_service_status(SERVICE_STOP_PENDING, NO_ERROR, 0);
62 default:
63 report_service_status(SERVICE_RUNNING, NO_ERROR, 0);
64 }
65 }
66
67 static void WINAPI
68 service_main(DWORD dwArgc, LPWSTR* lpszArgv)
69 {
70 // SERVICE_STATUS_HANDLE status_handle;
71 LPWSTR lpEnvironment, lpEnvStr;
72 DWORD dwSize;
73
74 UNREFERENCED_PARAMETER(dwArgc);
75 UNREFERENCED_PARAMETER(lpszArgv);
76
77 /* Register our service for control (lpszArgv[0] holds the service name) */
78 status_handle = RegisterServiceCtrlHandlerW(lpszArgv[0], service_handler);
79 service_ok(status_handle != NULL, "RegisterServiceCtrlHandler failed: %lu\n", GetLastError());
80 if (!status_handle)
81 return;
82
83 /* Report SERVICE_RUNNING status */
84 report_service_status(SERVICE_RUNNING, NO_ERROR, 4000);
85
86 /* Display our current environment for informative purposes */
87 lpEnvironment = GetEnvironmentStringsW();
88 lpEnvStr = lpEnvironment;
89 while (*lpEnvStr)
90 {
91 service_trace("%S\n", lpEnvStr);
92 lpEnvStr += wcslen(lpEnvStr) + 1;
93 }
94 FreeEnvironmentStringsW(lpEnvironment);
95
96 /* Check the presence of the user-related environment variables */
97 dwSize = GetEnvironmentVariableW(L"ALLUSERSPROFILE", NULL, 0);
98 service_ok(dwSize != 0, "ALLUSERSPROFILE envvar not found, or GetEnvironmentVariableW failed: %lu\n", GetLastError());
99 dwSize = GetEnvironmentVariableW(L"USERPROFILE", NULL, 0);
100 service_ok(dwSize != 0, "USERPROFILE envvar not found, or GetEnvironmentVariableW failed: %lu\n", GetLastError());
101 #if 0 // May not always exist
102 dwSize = GetEnvironmentVariableW(L"USERNAME", NULL, 0);
103 service_ok(dwSize != 0, "USERNAME envvar not found, or GetEnvironmentVariableW failed: %lu\n", GetLastError());
104 #endif
105
106 /* Work is done */
107 report_service_status(SERVICE_STOPPED, NO_ERROR, 0);
108 }
109
110 static BOOL start_service(PCSTR service_nameA, PCWSTR service_nameW)
111 {
112 BOOL res;
113
114 SERVICE_TABLE_ENTRYW servtbl[] =
115 {
116 { (PWSTR)service_nameW, service_main },
117 { NULL, NULL }
118 };
119
120 res = StartServiceCtrlDispatcherW(servtbl);
121 service_ok(res, "StartServiceCtrlDispatcherW failed: %lu\n", GetLastError());
122 return res;
123 }
124
125
126 /*** Tester part of the test ***/
127
128 static void
129 my_test_server(PCSTR service_nameA,
130 PCWSTR service_nameW,
131 void *param)
132 {
133 BOOL res;
134 SC_HANDLE hSC = NULL;
135 SC_HANDLE hService = NULL;
136 SERVICE_STATUS ServiceStatus;
137
138 /* Open the SCM */
139 hSC = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
140 if (!hSC)
141 {
142 skip("OpenSCManagerW failed with error %lu!\n", GetLastError());
143 return;
144 }
145
146 /* First create ourselves as a service running in the default LocalSystem account */
147 hService = register_service_exW(hSC, L"ServiceEnv", service_nameW, NULL,
148 SERVICE_ALL_ACCESS,
149 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
150 SERVICE_DEMAND_START,
151 SERVICE_ERROR_IGNORE,
152 NULL, NULL, NULL,
153 NULL, NULL);
154 if (!hService)
155 {
156 skip("CreateServiceW failed with error %lu!\n", GetLastError());
157 goto Cleanup;
158 }
159
160 /* Start it */
161 if (!StartServiceW(hService, 0, NULL))
162 {
163 skip("StartServiceW failed with error %lu!\n", GetLastError());
164 goto Cleanup;
165 }
166
167 /* Wait for the service to stop by itself */
168 do
169 {
170 Sleep(100);
171 ZeroMemory(&ServiceStatus, sizeof(ServiceStatus));
172 res = QueryServiceStatus(hService, &ServiceStatus);
173 } while (res && ServiceStatus.dwCurrentState != SERVICE_STOPPED);
174 ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
175 ok(ServiceStatus.dwCurrentState == SERVICE_STOPPED, "ServiceStatus.dwCurrentState = %lx\n", ServiceStatus.dwCurrentState);
176
177 /* Be sure the service is really stopped */
178 res = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
179 if (!res && ServiceStatus.dwCurrentState != SERVICE_STOPPED &&
180 ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING &&
181 GetLastError() != ERROR_SERVICE_NOT_ACTIVE)
182 {
183 skip("ControlService failed with error %lu!\n", GetLastError());
184 goto Cleanup;
185 }
186
187 #if 0
188 trace("Service stopped. Going to restart it...\n");
189
190 /* Now change the service configuration to make it start under the NetworkService account */
191 if (!ChangeServiceConfigW(hService,
192 SERVICE_NO_CHANGE,
193 SERVICE_NO_CHANGE,
194 SERVICE_NO_CHANGE,
195 NULL, NULL, NULL, NULL,
196 L"NT AUTHORITY\\NetworkService", L"",
197 NULL))
198 {
199 skip("ChangeServiceConfigW failed with error %lu!\n", GetLastError());
200 goto Cleanup;
201 }
202
203 /* Start it */
204 if (!StartServiceW(hService, 0, NULL))
205 {
206 skip("StartServiceW failed with error %lu!\n", GetLastError());
207 goto Cleanup;
208 }
209
210 /* Wait for the service to stop by itself */
211 do
212 {
213 Sleep(100);
214 ZeroMemory(&ServiceStatus, sizeof(ServiceStatus));
215 res = QueryServiceStatus(hService, &ServiceStatus);
216 } while (res && ServiceStatus.dwCurrentState != SERVICE_STOPPED);
217 ok(res, "QueryServiceStatus failed: %lu\n", GetLastError());
218 ok(ServiceStatus.dwCurrentState == SERVICE_STOPPED, "ServiceStatus.dwCurrentState = %lx\n", ServiceStatus.dwCurrentState);
219
220 /* Be sure the service is really stopped */
221 res = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
222 if (!res && ServiceStatus.dwCurrentState != SERVICE_STOPPED &&
223 ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING &&
224 GetLastError() != ERROR_SERVICE_NOT_ACTIVE)
225 {
226 skip("ControlService failed with error %lu!\n", GetLastError());
227 goto Cleanup;
228 }
229 #endif
230
231 Cleanup:
232 if (hService)
233 {
234 res = DeleteService(hService);
235 ok(res, "DeleteService failed: %lu\n", GetLastError());
236 CloseServiceHandle(hService);
237 }
238
239 if (hSC)
240 CloseServiceHandle(hSC);
241 }
242
243 START_TEST(ServiceEnv)
244 {
245 int argc;
246 char** argv;
247
248 /* Check whether this test is started as a separated service process */
249 argc = winetest_get_mainargs(&argv);
250 if (argc >= 3)
251 {
252 service_process(start_service, argc, argv);
253 return;
254 }
255
256 /* We are started as the real test */
257 test_runner(my_test_server, NULL);
258 // trace("Returned from test_runner\n");
259 }