603e5085e60ac37a9b9acf7e00e43a84458933d8
[reactos.git] / rostests / winetests / advapi32 / service.c
1 /*
2 * Unit tests for service functions
3 *
4 * Copyright (c) 2007 Paul Vriens
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define WIN32_NO_STATUS
22 #define WIN32_LEAN_AND_MEAN
23
24 #include <stdarg.h>
25 #include <stdio.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsvc.h"
32 #include "winnls.h"
33 #include "lmcons.h"
34 #include "aclapi.h"
35
36 #include "wine/test.h"
37
38 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
39 static CHAR selfname[MAX_PATH];
40
41 static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
42 static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
43 DWORD, LPBYTE, DWORD, LPDWORD,
44 LPDWORD, LPDWORD, LPCSTR);
45 static BOOL (WINAPI *pEnumServicesStatusExW)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
46 DWORD, LPBYTE, DWORD, LPDWORD,
47 LPDWORD, LPDWORD, LPCWSTR);
48 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
49 PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
50 static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
51 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
52 static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
53 DWORD, LPDWORD);
54 static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
55 PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
56
57 static void init_function_pointers(void)
58 {
59 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
60
61 pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A");
62 pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA");
63 pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW");
64 pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo");
65 pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
66 pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
67 pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
68 pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity");
69 }
70
71 static void test_open_scm(void)
72 {
73 SC_HANDLE scm_handle;
74
75 /* No access rights */
76 SetLastError(0xdeadbeef);
77 scm_handle = OpenSCManagerA(NULL, NULL, 0);
78 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
79 CloseServiceHandle(scm_handle);
80
81 /* Unknown database name */
82 SetLastError(0xdeadbeef);
83 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
84 ok(!scm_handle, "Expected failure\n");
85 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
86 CloseServiceHandle(scm_handle); /* Just in case */
87
88 /* MSDN says only ServiceActive is allowed, or NULL */
89 SetLastError(0xdeadbeef);
90 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
91 ok(!scm_handle, "Expected failure\n");
92 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
93 CloseServiceHandle(scm_handle); /* Just in case */
94
95 /* Remote unknown host */
96 SetLastError(0xdeadbeef);
97 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
98 todo_wine
99 {
100 ok(!scm_handle, "Expected failure\n");
101 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
102 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
103 }
104 CloseServiceHandle(scm_handle); /* Just in case */
105
106 /* Proper call with an empty hostname */
107 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
108 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
109 CloseServiceHandle(scm_handle);
110
111 /* Again a correct one */
112 SetLastError(0xdeadbeef);
113 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
114 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_IO_PENDING) /* win2k */,
115 "Expected ERROR_SUCCESS, got %u\n", GetLastError());
116 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
117 CloseServiceHandle(scm_handle);
118 }
119
120 static void test_open_svc(void)
121 {
122 SC_HANDLE scm_handle, svc_handle;
123 CHAR displayname[4096];
124 DWORD displaysize;
125
126 /* All NULL (invalid access rights) */
127 SetLastError(0xdeadbeef);
128 svc_handle = OpenServiceA(NULL, NULL, 0);
129 ok(!svc_handle, "Expected failure\n");
130 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
131
132 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
133
134 /* NULL service */
135 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
136 SetLastError(0xdeadbeef);
137 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
138 ok(!svc_handle, "Expected failure\n");
139 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
140 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
141 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
142
143 /* Nonexistent service */
144 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
145 SetLastError(0xdeadbeef);
146 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
147 ok(!svc_handle, "Expected failure\n");
148 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
149 CloseServiceHandle(scm_handle);
150
151 /* Proper SCM handle but different access rights */
152 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
153 SetLastError(0xdeadbeef);
154 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_WRITE);
155 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
156 skip("Not enough rights to get a handle to the service\n");
157 else
158 {
159 ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError());
160 CloseServiceHandle(svc_handle);
161 }
162
163 /* Test to show we can't open a service with the displayname */
164
165 /* Retrieve the needed size for the buffer */
166 displaysize = 0;
167 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
168 /* Get the displayname */
169 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
170 /* Try to open the service with this displayname, unless the displayname equals
171 * the servicename as that would defeat the purpose of this test.
172 */
173 if (!lstrcmpiA(spooler, displayname))
174 {
175 skip("displayname equals servicename\n");
176 CloseServiceHandle(scm_handle);
177 return;
178 }
179
180 SetLastError(0xdeadbeef);
181 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
182 ok(!svc_handle, "Expected failure\n");
183 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
184 /* Just in case */
185 CloseServiceHandle(svc_handle);
186
187 CloseServiceHandle(scm_handle);
188 }
189
190 static void test_create_delete_svc(void)
191 {
192 SC_HANDLE scm_handle, svc_handle1;
193 CHAR username[UNLEN + 1], domain[MAX_PATH];
194 DWORD user_size = UNLEN + 1;
195 CHAR account[UNLEN + 3];
196 static const CHAR servicename [] = "Winetest";
197 static const CHAR pathname [] = "we_dont_care.exe";
198 static const CHAR empty [] = "";
199 static const CHAR password [] = "secret";
200 BOOL spooler_exists = FALSE;
201 BOOL ret;
202 CHAR display[4096];
203 DWORD display_size = sizeof(display);
204
205 /* Get the username and turn it into an account to be used in some tests */
206 GetUserNameA(username, &user_size);
207 /* Get the domainname to cater for that situation */
208 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
209 sprintf(account, "%s\\%s", domain, username);
210 else
211 sprintf(account, ".\\%s", username);
212
213 /* All NULL */
214 SetLastError(0xdeadbeef);
215 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
216 ok(!svc_handle1, "Expected failure\n");
217 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
218
219 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
220
221 /* Only a valid handle to the Service Control Manager */
222 SetLastError(0xdeadbeef);
223 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
224 ok(!svc_handle1, "Expected failure\n");
225 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
226 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
227 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
228
229 /* Now with a servicename */
230 SetLastError(0xdeadbeef);
231 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
232 ok(!svc_handle1, "Expected failure\n");
233 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
234 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
235 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
236
237 /* Or just a binary name */
238 SetLastError(0xdeadbeef);
239 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
240 ok(!svc_handle1, "Expected failure\n");
241 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
242 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
243 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
244
245 /* Both servicename and binary name (We only have connect rights) */
246 SetLastError(0xdeadbeef);
247 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
248 ok(!svc_handle1, "Expected failure\n");
249 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
250
251 /* They can even be empty at this stage of parameter checking */
252 SetLastError(0xdeadbeef);
253 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
254 ok(!svc_handle1, "Expected failure\n");
255 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
256
257 SetLastError(0xdeadbeef);
258 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
259 ok(!svc_handle1, "Expected failure\n");
260 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
261
262 /* Open the Service Control Manager with minimal rights for creation
263 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
264 */
265 CloseServiceHandle(scm_handle);
266 SetLastError(0xdeadbeef);
267 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
268 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
269 {
270 skip("Not enough rights to get a handle to the manager\n");
271 return;
272 }
273
274 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
275
276 /* Empty strings for servicename and binary name are checked */
277 SetLastError(0xdeadbeef);
278 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
279 ok(!svc_handle1, "Expected failure\n");
280 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
281
282 SetLastError(0xdeadbeef);
283 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
284 ok(!svc_handle1, "Expected failure\n");
285 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
286
287 SetLastError(0xdeadbeef);
288 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
289 ok(!svc_handle1, "Expected failure\n");
290 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
291
292 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
293 * an ERROR_INVALID_PARAMETER)
294 */
295 SetLastError(0xdeadbeef);
296 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
297 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
298 ok(!svc_handle1, "Expected failure\n");
299 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
300
301 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
302
303 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
304 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
305 */
306 SetLastError(0xdeadbeef);
307 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
308 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
309 ok(!svc_handle1, "Expected failure\n");
310 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
311
312 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
313 SetLastError(0xdeadbeef);
314 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
315 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
316 ok(!svc_handle1, "Expected failure\n");
317 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
318
319 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
320 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
321 */
322 SetLastError(0xdeadbeef);
323 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
324 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
325 ok(!svc_handle1, "Expected failure\n");
326 ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT,
327 "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError());
328
329 /* Illegal (start-type is not a mask and should only be one of the possibilities)
330 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
331 * it's most likely not the wanted start-type)
332 */
333 SetLastError(0xdeadbeef);
334 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
335 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
336 ok(!svc_handle1, "Expected failure\n");
337 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
338
339 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
340 SetLastError(0xdeadbeef);
341 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
342 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
343 ok(!svc_handle1, "Expected failure\n");
344 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
345
346 /* Test if ServiceType can be a combined one for drivers */
347 SetLastError(0xdeadbeef);
348 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER,
349 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
350 ok(!svc_handle1, "Expected failure\n");
351 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
352
353 /* The service already exists (check first, just in case) */
354 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
355 if (svc_handle1)
356 {
357 spooler_exists = TRUE;
358 CloseServiceHandle(svc_handle1);
359 SetLastError(0xdeadbeef);
360 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
361 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
362 ok(!svc_handle1, "Expected failure\n");
363 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
364 }
365 else
366 skip("Spooler service doesn't exist\n");
367
368 /* To find an existing displayname we check the 'Spooler' service. Although the registry
369 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
370 * to the servicename and can't be used as well for a new displayname.
371 */
372 if (spooler_exists)
373 {
374 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
375
376 if (!ret)
377 skip("Could not retrieve a displayname for the Spooler service\n");
378 else
379 {
380 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
381 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
382 ok(!svc_handle1, "Expected failure\n");
383 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
384 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
385 }
386 }
387 else
388 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
389
390 /* Windows doesn't care about the access rights for creation (which makes
391 * sense as there is no service yet) as long as there are sufficient
392 * rights to the manager.
393 */
394 SetLastError(0xdeadbeef);
395 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
396 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
397 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
398
399 /* DeleteService however must have proper rights */
400 SetLastError(0xdeadbeef);
401 ret = DeleteService(svc_handle1);
402 ok(!ret, "Expected failure\n");
403 ok(GetLastError() == ERROR_ACCESS_DENIED,
404 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
405
406 /* Open the service with minimal rights for deletion.
407 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
408 */
409 CloseServiceHandle(svc_handle1);
410 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
411
412 /* Now that we have the proper rights, we should be able to delete */
413 SetLastError(0xdeadbeef);
414 ret = DeleteService(svc_handle1);
415 ok(ret, "Expected success, got error %u\n", GetLastError());
416
417 CloseServiceHandle(svc_handle1);
418 CloseServiceHandle(scm_handle);
419
420 /* Wait a while. One of the following tests also does a CreateService for the
421 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
422 * error if we do this too quickly. Vista seems more picky than the others.
423 */
424 Sleep(1000);
425
426 /* And a final NULL check */
427 SetLastError(0xdeadbeef);
428 ret = DeleteService(NULL);
429 ok(!ret, "Expected failure\n");
430 ok(GetLastError() == ERROR_INVALID_HANDLE,
431 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
432 }
433
434 static void test_get_displayname(void)
435 {
436 SC_HANDLE scm_handle, svc_handle;
437 BOOL ret;
438 CHAR displayname[4096];
439 WCHAR displaynameW[2048];
440 DWORD displaysize, tempsize, tempsizeW;
441 static const CHAR deadbeef[] = "Deadbeef";
442 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
443 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
444 static const WCHAR abcW[] = {'A','B','C',0};
445 static const CHAR servicename[] = "Winetest";
446 static const CHAR pathname[] = "we_dont_care.exe";
447
448 /* Having NULL for the size of the buffer will crash on W2K3 */
449
450 SetLastError(0xdeadbeef);
451 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
452 ok(!ret, "Expected failure\n");
453 ok(GetLastError() == ERROR_INVALID_HANDLE,
454 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
455
456 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
457
458 SetLastError(0xdeadbeef);
459 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
460 ok(!ret, "Expected failure\n");
461 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
462 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
463 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
464
465 SetLastError(0xdeadbeef);
466 displaysize = sizeof(displayname);
467 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
468 ok(!ret, "Expected failure\n");
469 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
470 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
471 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
472
473 /* Test for nonexistent service */
474 SetLastError(0xdeadbeef);
475 displaysize = -1;
476 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
477 ok(!ret, "Expected failure\n");
478 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
479 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
480
481 SetLastError(0xdeadbeef);
482 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
483 ok(!ret, "Expected failure\n");
484 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
485 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
486 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
487
488 displaysize = 15;
489 strcpy(displayname, "ABC");
490 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
491 ok(!ret, "Expected failure\n");
492 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
493 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
494 todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
495 ok(displayname[0] == 0, "Service name not empty\n");
496
497 displaysize = 15;
498 lstrcpyW( displaynameW, abcW );
499 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
500 ok(!ret, "Expected failure\n");
501 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
502 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
503 ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
504 ok(displaynameW[0] == 0, "Service name not empty\n");
505
506 displaysize = 0;
507 strcpy(displayname, "ABC");
508 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
509 ok(!ret, "Expected failure\n");
510 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
511 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
512 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
513 ok(displayname[0] == 'A', "Service name changed\n");
514
515 displaysize = 0;
516 lstrcpyW( displaynameW, abcW );
517 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
518 ok(!ret, "Expected failure\n");
519 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
520 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
521 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
522 ok(displaynameW[0] == 'A', "Service name changed\n");
523
524 displaysize = 1;
525 strcpy(displayname, "ABC");
526 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
527 ok(!ret, "Expected failure\n");
528 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
529 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
530 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
531 ok(displayname[0] == 0, "Service name not empty\n");
532
533 displaysize = 1;
534 lstrcpyW( displaynameW, abcW );
535 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
536 ok(!ret, "Expected failure\n");
537 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
538 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
539 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
540 ok(displaynameW[0] == 'A', "Service name changed\n");
541
542 displaysize = 2;
543 strcpy(displayname, "ABC");
544 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
545 ok(!ret, "Expected failure\n");
546 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
547 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
548 todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
549 ok(displayname[0] == 0, "Service name not empty\n");
550
551 displaysize = 2;
552 lstrcpyW( displaynameW, abcW );
553 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
554 ok(!ret, "Expected failure\n");
555 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
556 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
557 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
558 ok(displaynameW[0] == 0, "Service name not empty\n");
559
560 /* Check if 'Spooler' exists */
561 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
562 if (!svc_handle)
563 {
564 skip("Spooler service doesn't exist\n");
565 CloseServiceHandle(scm_handle);
566 return;
567 }
568 CloseServiceHandle(svc_handle);
569
570 /* Retrieve the needed size for the buffer */
571 SetLastError(0xdeadbeef);
572 displaysize = -1;
573 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
574 ok(!ret, "Expected failure\n");
575 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
576 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
577 tempsize = displaysize;
578
579 displaysize = 0;
580 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
581 ok(!ret, "Expected failure\n");
582 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
583 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
584 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
585
586 /* Buffer is too small */
587 SetLastError(0xdeadbeef);
588 displaysize = (tempsize / 2);
589 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
590 ok(!ret, "Expected failure\n");
591 ok(displaysize == tempsize, "Expected the needed buffersize\n");
592 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
593 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
594
595 /* First try with a buffer that should be big enough to hold
596 * the ANSI string (and terminating character). This succeeds on Windows
597 * although when asked (see above 2 tests) it will return twice the needed size.
598 */
599 SetLastError(0xdeadbeef);
600 displaysize = (tempsize / 2) + 1;
601 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
602 ok(ret, "Expected success, got error %u\n", GetLastError());
603 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
604
605 /* Now with the original returned size */
606 SetLastError(0xdeadbeef);
607 displaysize = tempsize;
608 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
609 ok(ret, "Expected success, got error %u\n", GetLastError());
610 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
611
612 /* And with a bigger than needed buffer */
613 SetLastError(0xdeadbeef);
614 displaysize = tempsize * 2;
615 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
616 ok(ret, "Expected success, got error %u\n", GetLastError());
617 /* Test that shows that if the buffersize is enough, it's not changed */
618 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
619 ok(strlen(displayname) == tempsize/2,
620 "Expected the buffer to be twice the length of the string\n") ;
621
622 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
623 SetLastError(0xdeadbeef);
624 displaysize = -1;
625 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
626 ok(!ret, "Expected failure\n");
627 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
628 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
629
630 /* Buffer is too small */
631 SetLastError(0xdeadbeef);
632 tempsizeW = displaysize;
633 displaysize = tempsizeW / 2;
634 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
635 ok(!ret, "Expected failure\n");
636 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
637 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
638 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
639
640 /* Now with the original returned size */
641 SetLastError(0xdeadbeef);
642 displaysize = tempsizeW;
643 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
644 ok(!ret, "Expected failure\n");
645 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
646 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
647 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
648
649 /* And with a bigger than needed buffer */
650 SetLastError(0xdeadbeef);
651 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
652 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
653 ok(ret, "Expected success, got error %u\n", GetLastError());
654 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
655 ok(lstrlenW(displaynameW) == displaysize,
656 "Expected the buffer to be the length of the string\n") ;
657 ok(tempsize / 2 == tempsizeW,
658 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
659
660 CloseServiceHandle(scm_handle);
661
662 /* Test for a service without a displayname (which is valid). This should return
663 * the servicename itself.
664 */
665 SetLastError(0xdeadbeef);
666 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
667 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
668 {
669 skip("Not enough rights to get a handle to the manager\n");
670 return;
671 }
672
673 SetLastError(0xdeadbeef);
674 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
675 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
676 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
677 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
678 if (!svc_handle)
679 {
680 CloseServiceHandle(scm_handle);
681 return;
682 }
683
684 /* Retrieve the needed size for the buffer */
685 SetLastError(0xdeadbeef);
686 displaysize = -1;
687 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
688 ok(!ret, "Expected failure\n");
689 ok(displaysize == strlen(servicename) * 2,
690 "Expected the displaysize to be twice the size of the servicename\n");
691 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
692 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
693
694 /* Buffer is too small */
695 SetLastError(0xdeadbeef);
696 tempsize = displaysize;
697 displaysize = (tempsize / 2);
698 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
699 ok(!ret, "Expected failure\n");
700 ok(displaysize == tempsize, "Expected the needed buffersize\n");
701 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
702 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
703
704 /* Get the displayname */
705 SetLastError(0xdeadbeef);
706 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
707 ok(ret, "Expected success, got error %u\n", GetLastError());
708 ok(!lstrcmpiA(displayname, servicename),
709 "Expected displayname to be %s, got %s\n", servicename, displayname);
710
711 /* Delete the service */
712 ret = DeleteService(svc_handle);
713 ok(ret, "Expected success (err=%d)\n", GetLastError());
714
715 CloseServiceHandle(svc_handle);
716 CloseServiceHandle(scm_handle);
717
718 /* Wait a while. Just in case one of the following tests does a CreateService again */
719 Sleep(1000);
720 }
721
722 static void test_get_servicekeyname(void)
723 {
724 SC_HANDLE scm_handle, svc_handle;
725 CHAR servicename[4096];
726 CHAR displayname[4096];
727 WCHAR servicenameW[4096];
728 WCHAR displaynameW[4096];
729 DWORD servicesize, displaysize, tempsize;
730 BOOL ret;
731 static const CHAR deadbeef[] = "Deadbeef";
732 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
733 static const WCHAR abcW[] = {'A','B','C',0};
734
735 /* Having NULL for the size of the buffer will crash on W2K3 */
736
737 SetLastError(0xdeadbeef);
738 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
739 ok(!ret, "Expected failure\n");
740 ok(GetLastError() == ERROR_INVALID_HANDLE,
741 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
742
743 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
744
745 servicesize = 200;
746 SetLastError(0xdeadbeef);
747 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
748 ok(!ret, "Expected failure\n");
749 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
750 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
751 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
752 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
753
754 /* Valid handle and buffer but no displayname */
755 servicesize = 200;
756 SetLastError(0xdeadbeef);
757 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
758 ok(!ret, "Expected failure\n");
759 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
760 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
761 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
762 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
763
764 /* Test for nonexistent displayname */
765 SetLastError(0xdeadbeef);
766 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
767 ok(!ret, "Expected failure\n");
768 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
769 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
770 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
771
772 servicesize = 15;
773 strcpy(servicename, "ABC");
774 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
775 ok(!ret, "Expected failure\n");
776 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
777 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
778 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
779 ok(servicename[0] == 0, "Service name not empty\n");
780
781 servicesize = 15;
782 lstrcpyW( servicenameW, abcW );
783 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
784 ok(!ret, "Expected failure\n");
785 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
786 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
787 ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
788 ok(servicenameW[0] == 0, "Service name not empty\n");
789
790 servicesize = 0;
791 strcpy(servicename, "ABC");
792 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
793 ok(!ret, "Expected failure\n");
794 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
795 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
796 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
797 ok(servicename[0] == 'A', "Service name changed\n");
798
799 servicesize = 0;
800 lstrcpyW( servicenameW, abcW );
801 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
802 ok(!ret, "Expected failure\n");
803 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
804 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
805 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
806 ok(servicenameW[0] == 'A', "Service name changed\n");
807
808 servicesize = 1;
809 strcpy(servicename, "ABC");
810 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
811 ok(!ret, "Expected failure\n");
812 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
813 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
814 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
815 ok(servicename[0] == 0, "Service name not empty\n");
816
817 servicesize = 1;
818 lstrcpyW( servicenameW, abcW );
819 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
820 ok(!ret, "Expected failure\n");
821 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
822 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
823 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
824 ok(servicenameW[0] == 'A', "Service name changed\n");
825
826 servicesize = 2;
827 strcpy(servicename, "ABC");
828 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
829 ok(!ret, "Expected failure\n");
830 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
831 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
832 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
833 ok(servicename[0] == 0, "Service name not empty\n");
834
835 servicesize = 2;
836 lstrcpyW( servicenameW, abcW );
837 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
838 ok(!ret, "Expected failure\n");
839 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
840 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
841 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
842 ok(servicenameW[0] == 0, "Service name not empty\n");
843
844 /* Check if 'Spooler' exists */
845 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
846 if (!svc_handle)
847 {
848 skip("Spooler service doesn't exist\n");
849 CloseServiceHandle(scm_handle);
850 return;
851 }
852 CloseServiceHandle(svc_handle);
853
854 /* Get the displayname for the 'Spooler' service */
855 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
856 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
857
858 /* Retrieve the needed size for the buffer */
859 SetLastError(0xdeadbeef);
860 servicesize = 0;
861 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
862 ok(!ret, "Expected failure\n");
863 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
864 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
865
866 /* Valid call with the correct buffersize */
867 SetLastError(0xdeadbeef);
868 tempsize = servicesize;
869 servicesize *= 2;
870 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
871 ok(ret, "Expected success, got error %u\n", GetLastError());
872 if (ret)
873 {
874 ok(strlen(servicename) == tempsize/2,
875 "Expected the buffer to be twice the length of the string\n") ;
876 ok(!lstrcmpiA(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
877 ok(servicesize == (tempsize * 2),
878 "Expected servicesize not to change if buffer not insufficient\n") ;
879 }
880
881 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
882 SetLastError(0xdeadbeef);
883 servicesize *= 2;
884 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
885 ok(ret, "Expected success, got error %u\n", GetLastError());
886 if (ret)
887 {
888 ok(strlen(servicename) == tempsize/2,
889 "Expected the buffer to be twice the length of the string\n") ;
890 ok(servicesize == lstrlenW(servicenameW),
891 "Expected servicesize not to change if buffer not insufficient\n") ;
892 }
893
894 SetLastError(0xdeadbeef);
895 servicesize = 3;
896 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
897 ok(!ret, "Expected failure\n");
898 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
899 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
900 ok(servicenameW[0] == 0, "Buffer not empty\n");
901
902 CloseServiceHandle(scm_handle);
903 }
904
905 static void test_query_svc(void)
906 {
907 SC_HANDLE scm_handle, svc_handle;
908 BOOL ret;
909 SERVICE_STATUS status;
910 SERVICE_STATUS_PROCESS *statusproc;
911 DWORD bufsize, needed;
912
913 /* All NULL or wrong */
914 SetLastError(0xdeadbeef);
915 ret = QueryServiceStatus(NULL, NULL);
916 ok(!ret, "Expected failure\n");
917 ok(GetLastError() == ERROR_INVALID_HANDLE,
918 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
919
920 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
921
922 /* Check if 'Spooler' exists.
923 * Open with not enough rights to query the status.
924 */
925 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
926 if (!svc_handle)
927 {
928 skip("Spooler service doesn't exist\n");
929 CloseServiceHandle(scm_handle);
930 return;
931 }
932
933 SetLastError(0xdeadbeef);
934 ret = QueryServiceStatus(svc_handle, NULL);
935 ok(!ret, "Expected failure\n");
936 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
937 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
938 "Unexpected last error %d\n", GetLastError());
939
940 SetLastError(0xdeadbeef);
941 ret = QueryServiceStatus(svc_handle, &status);
942 ok(!ret, "Expected failure\n");
943 ok(GetLastError() == ERROR_ACCESS_DENIED,
944 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
945
946 /* Open the service with just enough rights.
947 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
948 */
949 CloseServiceHandle(svc_handle);
950 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
951
952 SetLastError(0xdeadbeef);
953 ret = QueryServiceStatus(svc_handle, &status);
954 ok(ret, "Expected success, got error %u\n", GetLastError());
955
956 CloseServiceHandle(svc_handle);
957
958 /* More or less the same tests for QueryServiceStatusEx */
959 if (!pQueryServiceStatusEx)
960 {
961 win_skip( "QueryServiceStatusEx not available\n" );
962 CloseServiceHandle(scm_handle);
963 return;
964 }
965
966 /* Open service with not enough rights to query the status */
967 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
968
969 /* All NULL or wrong, this proves that info level is checked first */
970 SetLastError(0xdeadbeef);
971 ret = pQueryServiceStatusEx(NULL, 1, NULL, 0, NULL);
972 ok(!ret, "Expected failure\n");
973 ok(GetLastError() == ERROR_INVALID_LEVEL,
974 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
975
976 /* Passing a NULL parameter for the needed buffer size
977 * will crash on anything but NT4.
978 */
979
980 /* Only info level is correct. It looks like the buffer/size is checked second */
981 SetLastError(0xdeadbeef);
982 ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, NULL, 0, &needed);
983 /* NT4 checks the handle first */
984 if (GetLastError() != ERROR_INVALID_HANDLE)
985 {
986 ok(!ret, "Expected failure\n");
987 ok(needed == sizeof(SERVICE_STATUS_PROCESS),
988 "Needed buffersize is wrong : %d\n", needed);
989 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
990 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
991 }
992
993 /* Pass a correct buffer and buffersize but a NULL handle */
994 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
995 bufsize = needed;
996 SetLastError(0xdeadbeef);
997 ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
998 ok(!ret, "Expected failure\n");
999 ok(GetLastError() == ERROR_INVALID_HANDLE,
1000 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1001 HeapFree(GetProcessHeap(), 0, statusproc);
1002
1003 /* Correct handle and info level */
1004 SetLastError(0xdeadbeef);
1005 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, NULL, 0, &needed);
1006 /* NT4 doesn't return the needed size */
1007 if (GetLastError() != ERROR_INVALID_PARAMETER)
1008 {
1009 ok(!ret, "Expected failure\n");
1010 ok(needed == sizeof(SERVICE_STATUS_PROCESS),
1011 "Needed buffersize is wrong : %d\n", needed);
1012 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1013 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1014 }
1015
1016 /* All parameters are OK but we don't have enough rights */
1017 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1018 bufsize = sizeof(SERVICE_STATUS_PROCESS);
1019 SetLastError(0xdeadbeef);
1020 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
1021 ok(!ret, "Expected failure\n");
1022 ok(GetLastError() == ERROR_ACCESS_DENIED,
1023 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1024 HeapFree(GetProcessHeap(), 0, statusproc);
1025
1026 /* Open the service with just enough rights. */
1027 CloseServiceHandle(svc_handle);
1028 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
1029
1030 /* Everything should be fine now. */
1031 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1032 bufsize = sizeof(SERVICE_STATUS_PROCESS);
1033 SetLastError(0xdeadbeef);
1034 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
1035 ok(ret, "Expected success, got error %u\n", GetLastError());
1036 if (statusproc->dwCurrentState == SERVICE_RUNNING)
1037 ok(statusproc->dwProcessId != 0,
1038 "Expect a process id for this running service\n");
1039 else
1040 ok(statusproc->dwProcessId == 0,
1041 "Expect no process id for this stopped service\n");
1042
1043 /* same call with null needed pointer */
1044 SetLastError(0xdeadbeef);
1045 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, NULL);
1046 ok(!ret, "Expected failure\n");
1047 ok(broken(GetLastError() == ERROR_INVALID_PARAMETER) /* NT4 */ ||
1048 GetLastError() == ERROR_INVALID_ADDRESS, "got %d\n", GetLastError());
1049
1050 HeapFree(GetProcessHeap(), 0, statusproc);
1051
1052 CloseServiceHandle(svc_handle);
1053 CloseServiceHandle(scm_handle);
1054 }
1055
1056 static void test_enum_svc(void)
1057 {
1058 SC_HANDLE scm_handle;
1059 BOOL ret;
1060 DWORD bufsize, needed, returned, resume;
1061 DWORD neededW, returnedW;
1062 DWORD tempneeded, tempreturned, missing;
1063 DWORD servicecountactive, servicecountinactive;
1064 ENUM_SERVICE_STATUSA *services;
1065 ENUM_SERVICE_STATUSW *servicesW;
1066 ENUM_SERVICE_STATUS_PROCESSA *exservices;
1067 UINT i;
1068
1069 /* All NULL or wrong */
1070 SetLastError(0xdeadbeef);
1071 ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1072 ok(!ret, "Expected failure\n");
1073 ok(GetLastError() == ERROR_INVALID_HANDLE,
1074 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1075
1076 SetLastError(0xdeadbeef);
1077 ret = EnumServicesStatusW(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1078 ok(!ret, "Expected failure\n");
1079 ok(GetLastError() == ERROR_INVALID_HANDLE,
1080 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1081
1082 /* Open the service control manager with not enough rights at first */
1083 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1084
1085 /* Valid handle but rest is still NULL or wrong */
1086 SetLastError(0xdeadbeef);
1087 ret = EnumServicesStatusA(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1088 ok(!ret, "Expected failure\n");
1089 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1090 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1091 "Unexpected last error %d\n", GetLastError());
1092
1093 SetLastError(0xdeadbeef);
1094 ret = EnumServicesStatusW(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1095 ok(!ret, "Expected failure\n");
1096 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1097 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1098 "Unexpected last error %d\n", GetLastError());
1099
1100 /* Don't specify the two required pointers */
1101 returned = 0xdeadbeef;
1102 SetLastError(0xdeadbeef);
1103 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1104 ok(!ret, "Expected failure\n");
1105 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1106 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1107 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1108 "Unexpected last error %d\n", GetLastError());
1109
1110 returned = 0xdeadbeef;
1111 SetLastError(0xdeadbeef);
1112 ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1113 ok(!ret, "Expected failure\n");
1114 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1115 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1116 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1117 "Unexpected last error %d\n", GetLastError());
1118
1119 /* Don't specify the two required pointers */
1120 needed = 0xdeadbeef;
1121 SetLastError(0xdeadbeef);
1122 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1123 ok(!ret, "Expected failure\n");
1124 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1125 "Expected no change to the needed buffer variable\n");
1126 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1127 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1128 "Unexpected last error %d\n", GetLastError());
1129
1130 needed = 0xdeadbeef;
1131 SetLastError(0xdeadbeef);
1132 ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1133 ok(!ret, "Expected failure\n");
1134 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1135 "Expected no change to the needed buffer variable\n");
1136 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1137 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1138 "Unexpected last error %d\n", GetLastError());
1139
1140 /* No valid servicetype and servicestate */
1141 needed = 0xdeadbeef;
1142 returned = 0xdeadbeef;
1143 SetLastError(0xdeadbeef);
1144 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1145 ok(!ret, "Expected failure\n");
1146 ok(needed == 0 || broken(needed != 0), /* nt4 */
1147 "Expected needed buffer size to be set to 0, got %d\n", needed);
1148 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1149 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1150 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1151
1152 needed = 0xdeadbeef;
1153 returned = 0xdeadbeef;
1154 SetLastError(0xdeadbeef);
1155 ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1156 ok(!ret, "Expected failure\n");
1157 ok(needed == 0 || broken(needed != 0), /* nt4 */
1158 "Expected needed buffer size to be set to 0, got %d\n", needed);
1159 ok(returned == 0 || broken(returned != 0), /* nt4 */
1160 "Expected number of services to be set to 0, got %d\n", returned);
1161 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1162 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1163
1164 /* No valid servicestate */
1165 needed = 0xdeadbeef;
1166 returned = 0xdeadbeef;
1167 SetLastError(0xdeadbeef);
1168 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1169 ok(!ret, "Expected failure\n");
1170 ok(needed == 0 || broken(needed != 0), /* nt4 */
1171 "Expected needed buffer size to be set to 0, got %d\n", needed);
1172 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1173 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1174 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1175
1176 needed = 0xdeadbeef;
1177 returned = 0xdeadbeef;
1178 SetLastError(0xdeadbeef);
1179 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1180 ok(!ret, "Expected failure\n");
1181 ok(needed == 0 || broken(needed != 0), /* nt4 */
1182 "Expected needed buffer size to be set to 0, got %d\n", needed);
1183 ok(returned == 0 || broken(returned != 0), /* nt4 */
1184 "Expected number of services to be set to 0, got %d\n", returned);
1185 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1186 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1187
1188 /* No valid servicetype */
1189 needed = 0xdeadbeef;
1190 returned = 0xdeadbeef;
1191 SetLastError(0xdeadbeef);
1192 ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1193 ok(!ret, "Expected failure\n");
1194 ok(needed == 0 || broken(needed != 0), /* nt4 */
1195 "Expected needed buffer size to be set to 0, got %d\n", needed);
1196 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1197 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1198 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1199
1200 needed = 0xdeadbeef;
1201 returned = 0xdeadbeef;
1202 SetLastError(0xdeadbeef);
1203 ret = EnumServicesStatusW(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1204 ok(!ret, "Expected failure\n");
1205 ok(needed == 0 || broken(needed != 0), /* nt4 */
1206 "Expected needed buffer size to be set to 0, got %d\n", needed);
1207 ok(returned == 0 || broken(returned != 0), /* nt4 */
1208 "Expected number of services to be set to 0, got %d\n", returned);
1209 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1210 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1211
1212 /* All parameters are correct but our access rights are wrong */
1213 needed = 0xdeadbeef;
1214 returned = 0xdeadbeef;
1215 SetLastError(0xdeadbeef);
1216 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1217 ok(!ret, "Expected failure\n");
1218 ok(needed == 0 || broken(needed != 0), /* nt4 */
1219 "Expected needed buffer size to be set to 0, got %d\n", needed);
1220 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1221 ok(GetLastError() == ERROR_ACCESS_DENIED,
1222 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1223
1224 needed = 0xdeadbeef;
1225 returned = 0xdeadbeef;
1226 SetLastError(0xdeadbeef);
1227 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1228 ok(!ret, "Expected failure\n");
1229 ok(needed == 0 || broken(needed != 0), /* nt4 */
1230 "Expected needed buffer size to be set to 0, got %d\n", needed);
1231 ok(returned == 0 || broken(returned != 0), /* nt4 */
1232 "Expected number of services to be set to 0, got %d\n", returned);
1233 ok(GetLastError() == ERROR_ACCESS_DENIED,
1234 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1235
1236 /* Open the service control manager with the needed rights */
1237 CloseServiceHandle(scm_handle);
1238 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1239
1240 /* All parameters are correct. Request the needed buffer size */
1241 needed = 0xdeadbeef;
1242 returned = 0xdeadbeef;
1243 SetLastError(0xdeadbeef);
1244 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1245 ok(!ret, "Expected failure\n");
1246 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1247 ok(returned == 0, "Expected no service returned, got %d\n", returned);
1248 ok(GetLastError() == ERROR_MORE_DATA,
1249 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1250
1251 /* Test to show we get the same needed buffer size for the W-call */
1252 neededW = 0xdeadbeef;
1253 returnedW = 0xdeadbeef;
1254 SetLastError(0xdeadbeef);
1255 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &neededW, &returnedW, NULL);
1256 ok(!ret, "Expected failure\n");
1257 ok(neededW != 0xdeadbeef && neededW > 0, "Expected the needed buffer size for this one service\n");
1258 ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n");
1259 ok(returnedW == 0, "Expected no service returned, got %d\n", returnedW);
1260 ok(GetLastError() == ERROR_MORE_DATA,
1261 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1262
1263 /* Store the needed bytes */
1264 tempneeded = needed;
1265
1266 /* Allocate the correct needed bytes */
1267 services = HeapAlloc(GetProcessHeap(), 0, needed);
1268 bufsize = needed;
1269 needed = 0xdeadbeef;
1270 returned = 0xdeadbeef;
1271 SetLastError(0xdeadbeef);
1272 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1273 services, bufsize, &needed, &returned, NULL);
1274 ok(ret, "Expected success, got error %u\n", GetLastError());
1275 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1276 ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n");
1277 HeapFree(GetProcessHeap(), 0, services);
1278
1279 /* Store the number of returned services */
1280 tempreturned = returned;
1281
1282 servicesW = HeapAlloc(GetProcessHeap(), 0, neededW);
1283 bufsize = neededW;
1284 neededW = 0xdeadbeef;
1285 returnedW = 0xdeadbeef;
1286 SetLastError(0xdeadbeef);
1287 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1288 servicesW, bufsize, &neededW, &returnedW, NULL);
1289 ok(ret, "Expected success, got error %u\n", GetLastError());
1290 ok(neededW == 0, "Expected needed buffer to be 0 as we are done\n");
1291 ok(returnedW != 0xdeadbeef && returnedW > 0, "Expected some returned services\n");
1292 HeapFree(GetProcessHeap(), 0, servicesW);
1293
1294 /* Allocate less than the needed bytes and don't specify a resume handle */
1295 services = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1296 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA);
1297 needed = 0xdeadbeef;
1298 returned = 0xdeadbeef;
1299 SetLastError(0xdeadbeef);
1300 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1301 services, bufsize, &needed, &returned, NULL);
1302 ok(!ret, "Expected failure\n");
1303 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1304 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1305 ok(GetLastError() == ERROR_MORE_DATA,
1306 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1307
1308 /* Allocate less than the needed bytes, this time with a correct resume handle */
1309 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA);
1310 needed = 0xdeadbeef;
1311 returned = 0xdeadbeef;
1312 resume = 0;
1313 SetLastError(0xdeadbeef);
1314 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1315 services, bufsize, &needed, &returned, &resume);
1316 ok(!ret, "Expected failure\n");
1317 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1318 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1319 todo_wine ok(resume, "Expected a resume handle\n");
1320 ok(GetLastError() == ERROR_MORE_DATA,
1321 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1322
1323 /* Fetch the missing services but pass a bigger buffer size */
1324 missing = tempreturned - returned;
1325 bufsize = tempneeded;
1326 needed = 0xdeadbeef;
1327 returned = 0xdeadbeef;
1328 SetLastError(0xdeadbeef);
1329 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1330 services, bufsize, &needed, &returned, &resume);
1331 ok(ret, "Expected success, got error %u\n", GetLastError());
1332 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1333 ok(returned == missing, "Expected %u services to be returned\n", missing);
1334 ok(resume == 0, "Expected the resume handle to be 0\n");
1335 HeapFree(GetProcessHeap(), 0, services);
1336
1337 /* See if things add up */
1338
1339 /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1340 * and doesn't count the others as inactive. This means that Vista could
1341 * show a total that is greater than the sum of active and inactive
1342 * drivers.
1343 * The number of active and inactive drivers is greatly influenced by the
1344 * time when tests are run, immediately after boot or later for example.
1345 *
1346 * Both reasons make calculations for drivers not so useful
1347 */
1348
1349 /* Get the number of active win32 services */
1350 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0,
1351 &needed, &returned, NULL);
1352 services = HeapAlloc(GetProcessHeap(), 0, needed);
1353 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services,
1354 needed, &needed, &returned, NULL);
1355 HeapFree(GetProcessHeap(), 0, services);
1356
1357 servicecountactive = returned;
1358
1359 /* Get the number of inactive win32 services */
1360 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0,
1361 &needed, &returned, NULL);
1362 services = HeapAlloc(GetProcessHeap(), 0, needed);
1363 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services,
1364 needed, &needed, &returned, NULL);
1365 HeapFree(GetProcessHeap(), 0, services);
1366
1367 servicecountinactive = returned;
1368
1369 /* Get the number of win32 services */
1370 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1371 &needed, &returned, NULL);
1372 services = HeapAlloc(GetProcessHeap(), 0, needed);
1373 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services,
1374 needed, &needed, &returned, NULL);
1375 HeapFree(GetProcessHeap(), 0, services);
1376
1377 /* Check if total is the same as active and inactive win32 services */
1378 ok(returned == (servicecountactive + servicecountinactive),
1379 "Something wrong in the calculation\n");
1380
1381 /* Get all drivers and services
1382 *
1383 * Fetch the status of the last call as failing could make the following tests crash
1384 * on Wine (we don't return anything yet).
1385 */
1386 EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1387 NULL, 0, &needed, &returned, NULL);
1388 services = HeapAlloc(GetProcessHeap(), 0, needed);
1389 ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1390 services, needed, &needed, &returned, NULL);
1391
1392 /* Loop through all those returned drivers and services */
1393 for (i = 0; ret && i < returned; i++)
1394 {
1395 SERVICE_STATUS status = services[i].ServiceStatus;
1396
1397 /* lpServiceName and lpDisplayName should always be filled */
1398 ok(lstrlenA(services[i].lpServiceName) > 0, "Expected a service name\n");
1399 ok(lstrlenA(services[i].lpDisplayName) > 0, "Expected a display name\n");
1400
1401 /* Decrement the counters to see if the functions calls return the same
1402 * numbers as the contents of these structures.
1403 */
1404 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1405 {
1406 if (status.dwCurrentState == SERVICE_STOPPED)
1407 servicecountinactive--;
1408 else
1409 servicecountactive--;
1410 }
1411 }
1412 HeapFree(GetProcessHeap(), 0, services);
1413
1414 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1415 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1416
1417 CloseServiceHandle(scm_handle);
1418
1419 /* More or less the same for EnumServicesStatusExA */
1420 if (!pEnumServicesStatusExA)
1421 {
1422 win_skip( "EnumServicesStatusExA not available\n" );
1423 return;
1424 }
1425
1426 /* All NULL or wrong */
1427 SetLastError(0xdeadbeef);
1428 ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1429 ok(!ret, "Expected failure\n");
1430 ok(GetLastError() == ERROR_INVALID_LEVEL,
1431 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1432
1433 /* All NULL or wrong, just the info level is correct */
1434 SetLastError(0xdeadbeef);
1435 ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1436 ok(!ret, "Expected failure\n");
1437 ok(GetLastError() == ERROR_INVALID_HANDLE,
1438 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1439
1440 /* Open the service control manager with not enough rights at first */
1441 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1442
1443 /* Valid handle and info level but rest is still NULL or wrong */
1444 SetLastError(0xdeadbeef);
1445 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1446 ok(!ret, "Expected failure\n");
1447 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1448 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1449 "Unexpected last error %d\n", GetLastError());
1450
1451 /* Don't specify the two required pointers */
1452 needed = 0xdeadbeef;
1453 SetLastError(0xdeadbeef);
1454 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL);
1455 ok(!ret, "Expected failure\n");
1456 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1457 "Expected no change to the needed buffer variable\n");
1458 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1459 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1460 "Unexpected last error %d\n", GetLastError());
1461
1462 /* Don't specify the two required pointers */
1463 returned = 0xdeadbeef;
1464 SetLastError(0xdeadbeef);
1465 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL);
1466 ok(!ret, "Expected failure\n");
1467 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1468 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1469 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1470 "Unexpected last error %d\n", GetLastError());
1471
1472 /* No valid servicetype and servicestate */
1473 needed = 0xdeadbeef;
1474 returned = 0xdeadbeef;
1475 SetLastError(0xdeadbeef);
1476 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL);
1477 ok(!ret, "Expected failure\n");
1478 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1479 ok(needed == 0 || broken(needed != 0), /* nt4 */
1480 "Expected needed buffer size to be set to 0, got %d\n", needed);
1481 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1482 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1483
1484 /* No valid servicestate */
1485 needed = 0xdeadbeef;
1486 returned = 0xdeadbeef;
1487 SetLastError(0xdeadbeef);
1488 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0,
1489 &needed, &returned, NULL, NULL);
1490 ok(!ret, "Expected failure\n");
1491 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1492 ok(needed == 0 || broken(needed != 0), /* nt4 */
1493 "Expected needed buffer size to be set to 0, got %d\n", needed);
1494 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1495 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1496
1497 /* No valid servicetype */
1498 needed = 0xdeadbeef;
1499 returned = 0xdeadbeef;
1500 SetLastError(0xdeadbeef);
1501 ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0,
1502 &needed, &returned, NULL, NULL);
1503 ok(!ret, "Expected failure\n");
1504 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1505 ok(needed == 0 || broken(needed != 0), /* nt4 */
1506 "Expected needed buffer size to be set to 0, got %d\n", needed);
1507 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1508 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1509
1510 /* No valid servicetype and servicestate and unknown service group */
1511 needed = 0xdeadbeef;
1512 returned = 0xdeadbeef;
1513 SetLastError(0xdeadbeef);
1514 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed,
1515 &returned, NULL, "deadbeef_group");
1516 ok(!ret, "Expected failure\n");
1517 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1518 ok(needed == 0 || broken(needed != 0), /* nt4 */
1519 "Expected needed buffer size to be set to 0, got %d\n", needed);
1520 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1521 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1522
1523 /* All parameters are correct but our access rights are wrong */
1524 needed = 0xdeadbeef;
1525 returned = 0xdeadbeef;
1526 SetLastError(0xdeadbeef);
1527 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1528 NULL, 0, &needed, &returned, NULL, NULL);
1529 ok(!ret, "Expected failure\n");
1530 ok(needed == 0 || broken(needed != 0), /* nt4 */
1531 "Expected needed buffer size to be set to 0, got %d\n", needed);
1532 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1533 ok(GetLastError() == ERROR_ACCESS_DENIED,
1534 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1535
1536 /* All parameters are correct, access rights are wrong but the
1537 * group name won't be checked yet.
1538 */
1539 needed = 0xdeadbeef;
1540 returned = 0xdeadbeef;
1541 SetLastError(0xdeadbeef);
1542 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1543 NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1544 ok(!ret, "Expected failure\n");
1545 ok(needed == 0 || broken(needed != 0), /* nt4 */
1546 "Expected needed buffer size to be set to 0, got %d\n", needed);
1547 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1548 ok(GetLastError() == ERROR_ACCESS_DENIED,
1549 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1550
1551 /* Open the service control manager with the needed rights */
1552 CloseServiceHandle(scm_handle);
1553 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1554
1555 /* All parameters are correct and the group will be checked */
1556 needed = 0xdeadbeef;
1557 returned = 0xdeadbeef;
1558 SetLastError(0xdeadbeef);
1559 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1560 NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1561 ok(!ret, "Expected failure\n");
1562 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1563 ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
1564 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
1565 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1566
1567 /* TODO: Create a test that makes sure we enumerate all services that don't
1568 * belong to a group. (specifying "").
1569 */
1570
1571 /* All parameters are correct. Request the needed buffer size */
1572 needed = 0xdeadbeef;
1573 returned = 0xdeadbeef;
1574 SetLastError(0xdeadbeef);
1575 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1576 NULL, 0, &needed, &returned, NULL, NULL);
1577 ok(!ret, "Expected failure\n");
1578 ok(returned == 0, "Expected no service returned, got %d\n", returned);
1579 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1580 ok(GetLastError() == ERROR_MORE_DATA,
1581 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1582
1583 /* Test to show we get the same needed buffer size for the W-call */
1584 neededW = 0xdeadbeef;
1585 ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1586 NULL, 0, &neededW, &returnedW, NULL, NULL);
1587 ok(!ret, "Expected failure\n");
1588 ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n");
1589
1590 /* Store the needed bytes */
1591 tempneeded = needed;
1592
1593 /* Allocate the correct needed bytes */
1594 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1595 bufsize = needed;
1596 needed = 0xdeadbeef;
1597 returned = 0xdeadbeef;
1598 SetLastError(0xdeadbeef);
1599 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1600 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1601 ok(ret, "Expected success, got error %u\n", GetLastError());
1602 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1603 ok(returned == tempreturned, "Expected the same number of service from this function\n");
1604 HeapFree(GetProcessHeap(), 0, exservices);
1605
1606 /* Store the number of returned services */
1607 tempreturned = returned;
1608
1609 /* Allocate less than the needed bytes and don't specify a resume handle */
1610 exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1611 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA);
1612 needed = 0xdeadbeef;
1613 returned = 0xdeadbeef;
1614 SetLastError(0xdeadbeef);
1615 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1616 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1617 ok(!ret, "Expected failure\n");
1618 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1619 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1620 ok(GetLastError() == ERROR_MORE_DATA,
1621 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1622
1623 /* Allocate less than the needed bytes, this time with a correct resume handle */
1624 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA);
1625 needed = 0xdeadbeef;
1626 returned = 0xdeadbeef;
1627 resume = 0;
1628 SetLastError(0xdeadbeef);
1629 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1630 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1631 ok(!ret, "Expected failure\n");
1632 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1633 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1634 todo_wine ok(resume, "Expected a resume handle\n");
1635 ok(GetLastError() == ERROR_MORE_DATA,
1636 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1637
1638 /* Fetch that last service but pass a bigger buffer size */
1639 missing = tempreturned - returned;
1640 bufsize = tempneeded;
1641 needed = 0xdeadbeef;
1642 returned = 0xdeadbeef;
1643 SetLastError(0xdeadbeef);
1644 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1645 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1646 ok(ret, "Expected success, got error %u\n", GetLastError());
1647 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1648 ok(returned == missing, "Expected %u services to be returned\n", missing);
1649 ok(resume == 0, "Expected the resume handle to be 0\n");
1650 HeapFree(GetProcessHeap(), 0, exservices);
1651
1652 /* See if things add up */
1653
1654 /* Get the number of active win32 services */
1655 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1656 NULL, 0, &needed, &returned, NULL, NULL);
1657 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1658 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1659 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1660 HeapFree(GetProcessHeap(), 0, exservices);
1661
1662 servicecountactive = returned;
1663
1664 /* Get the number of inactive win32 services */
1665 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1666 NULL, 0, &needed, &returned, NULL, NULL);
1667 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1668 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1669 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1670 HeapFree(GetProcessHeap(), 0, exservices);
1671
1672 servicecountinactive = returned;
1673
1674 /* Get the number of win32 services */
1675 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1676 NULL, 0, &needed, &returned, NULL, NULL);
1677 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1678 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1679 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1680 HeapFree(GetProcessHeap(), 0, exservices);
1681
1682 /* Check if total is the same as active and inactive win32 services */
1683 ok(returned == (servicecountactive + servicecountinactive),
1684 "Something wrong in the calculation\n");
1685
1686 /* Get all drivers and services */
1687 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1688 SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
1689 ok(!ret, "Expected failure\n");
1690 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1691 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1692 SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1693 ok(ret, "Expected success %u\n", GetLastError());
1694
1695 /* Loop through all those returned drivers and services */
1696 for (i = 0; i < returned; i++)
1697 {
1698 SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
1699
1700 /* lpServiceName and lpDisplayName should always be filled */
1701 ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n");
1702 ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n");
1703
1704 /* Decrement the counters to see if the functions calls return the
1705 * same numbers as the contents of these structures.
1706 * Check some process id specifics.
1707 */
1708 if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
1709 {
1710 /* We shouldn't have a process id for drivers */
1711 ok(status.dwProcessId == 0,
1712 "This driver shouldn't have an associated process id\n");
1713 }
1714
1715 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1716 {
1717 if (status.dwCurrentState != SERVICE_STOPPED)
1718 {
1719 /* We expect a process id for every running service */
1720 ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n",
1721 exservices[i].lpServiceName);
1722
1723 servicecountactive--;
1724 }
1725 else
1726 {
1727 /* We shouldn't have a process id for inactive services */
1728 ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n",
1729 exservices[i].lpServiceName, status.dwCurrentState);
1730
1731 servicecountinactive--;
1732 }
1733 }
1734 }
1735 HeapFree(GetProcessHeap(), 0, exservices);
1736
1737 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1738 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1739
1740 CloseServiceHandle(scm_handle);
1741 }
1742
1743 static void test_close(void)
1744 {
1745 SC_HANDLE handle;
1746 BOOL ret;
1747
1748 /* NULL handle */
1749 SetLastError(0xdeadbeef);
1750 ret = CloseServiceHandle(NULL);
1751 ok(!ret, "Expected failure\n");
1752 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1753
1754 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1755
1756 /* Proper call */
1757 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1758 SetLastError(0xdeadbeef);
1759 ret = CloseServiceHandle(handle);
1760 ok(ret, "Expected success got error %u\n", GetLastError());
1761 }
1762
1763 static void test_sequence(void)
1764 {
1765 SC_HANDLE scm_handle, svc_handle;
1766 BOOL ret, is_nt4;
1767 QUERY_SERVICE_CONFIGA *config;
1768 DWORD given, needed;
1769 static const CHAR servicename [] = "Winetest";
1770 static const CHAR displayname [] = "Winetest dummy service";
1771 static const CHAR displayname2[] = "Winetest dummy service (2)";
1772 static const CHAR pathname [] = "we_dont_care.exe";
1773 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1774 static const CHAR password [] = "";
1775 static const CHAR empty [] = "";
1776 static const CHAR localsystem [] = "LocalSystem";
1777
1778 SetLastError(0xdeadbeef);
1779 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1780
1781 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1782 {
1783 skip("Not enough rights to get a handle to the manager\n");
1784 return;
1785 }
1786 else
1787 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
1788
1789 if (!scm_handle) return;
1790 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
1791 is_nt4=(svc_handle == NULL && GetLastError() == ERROR_INVALID_PARAMETER);
1792 CloseServiceHandle(svc_handle);
1793
1794 /* Create a dummy service */
1795 SetLastError(0xdeadbeef);
1796 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1797 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1798 pathname, NULL, NULL, dependencies, NULL, password);
1799
1800 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
1801 {
1802 /* We try and open the service and do the rest of the tests. Some could
1803 * fail if the tests were changed between these runs.
1804 */
1805 trace("Deletion probably didn't work last time\n");
1806 SetLastError(0xdeadbeef);
1807 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1808 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1809 {
1810 skip("Not enough rights to open the service\n");
1811 CloseServiceHandle(scm_handle);
1812 return;
1813 }
1814 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
1815 }
1816 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1817 {
1818 skip("Not enough rights to create the service\n");
1819 CloseServiceHandle(scm_handle);
1820 return;
1821 }
1822 else
1823 {
1824 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1825 if ((svc_handle != NULL) && (pGetSecurityInfo != NULL))
1826 {
1827 PSID sidOwner, sidGroup;
1828 PACL dacl, sacl;
1829 PSECURITY_DESCRIPTOR pSD;
1830 DWORD error, n1, n2;
1831 HRESULT retval;
1832 BOOL bret;
1833
1834 /* Test using GetSecurityInfo to obtain security information */
1835 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, &sidOwner,
1836 &sidGroup, &dacl, &sacl, &pSD);
1837 LocalFree(pSD);
1838 ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
1839 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
1840 NULL, NULL, NULL, &pSD);
1841 LocalFree(pSD);
1842 ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
1843 if (!is_nt4)
1844 {
1845 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
1846 NULL, &dacl, NULL, NULL);
1847 ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
1848 SetLastError(0xdeadbeef);
1849 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
1850 NULL, NULL, NULL, NULL);
1851 error = GetLastError();
1852 ok(retval == ERROR_INVALID_PARAMETER, "Expected GetSecurityInfo to fail: result %d\n", retval);
1853 ok(error == 0xdeadbeef, "Unexpected last error %d\n", error);
1854 }
1855 else
1856 win_skip("A NULL security descriptor in GetSecurityInfo results in an exception on NT4.\n");
1857
1858 /* Test using QueryServiceObjectSecurity to obtain security information */
1859 SetLastError(0xdeadbeef);
1860 bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, NULL, 0, &n1);
1861 error = GetLastError();
1862 ok(!bret, "Expected QueryServiceObjectSecurity to fail: result %d\n", bret);
1863 ok(error == ERROR_INSUFFICIENT_BUFFER ||
1864 broken(error == ERROR_INVALID_ADDRESS) || broken(error == ERROR_INVALID_PARAMETER),
1865 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", error);
1866 if (error != ERROR_INSUFFICIENT_BUFFER) n1 = 1024;
1867 pSD = LocalAlloc(0, n1);
1868 bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, pSD, n1, &n2);
1869 ok(bret, "Expected QueryServiceObjectSecurity to succeed: result %d\n", bret);
1870 LocalFree(pSD);
1871 }
1872 }
1873
1874 if (!svc_handle) {
1875 CloseServiceHandle(scm_handle);
1876 return;
1877 }
1878
1879 /* TODO:
1880 * Before we do a QueryServiceConfig we should check the registry. This will make sure
1881 * that the correct keys are used.
1882 */
1883
1884 /* Request the size for the buffer */
1885 SetLastError(0xdeadbeef);
1886 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1887 ok(!ret, "Expected failure\n");
1888 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1889
1890 config = HeapAlloc(GetProcessHeap(), 0, needed);
1891 given = needed;
1892 SetLastError(0xdeadbeef);
1893 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
1894 ok(ret, "Expected success, got error %u\n", GetLastError());
1895
1896 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1897 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1898 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1899 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1900 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1901 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
1902 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1903 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
1904 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1905 /* TODO: Show the double 0 terminated string */
1906 todo_wine
1907 {
1908 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
1909 }
1910 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1911 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
1912
1913 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2",
1914 NULL, NULL, NULL, NULL, displayname2);
1915 ok(ret, "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1916
1917 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1918 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
1919 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
1920 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1921 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1922 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1923 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1924 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1925 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
1926 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1927 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
1928 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1929 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1930 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
1931
1932 SetLastError(0xdeadbeef);
1933 ret = DeleteService(svc_handle);
1934 ok(ret, "Expected success, got error %u\n", GetLastError());
1935 CloseServiceHandle(svc_handle);
1936
1937 /* Wait a while. The following test does a CreateService again */
1938 Sleep(1000);
1939
1940 CloseServiceHandle(scm_handle);
1941 HeapFree(GetProcessHeap(), 0, config);
1942 }
1943
1944 static void test_queryconfig2(void)
1945 {
1946 SC_HANDLE scm_handle, svc_handle;
1947 BOOL ret;
1948 DWORD expected, needed;
1949 BYTE buffer[MAX_PATH];
1950 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
1951 SERVICE_PRESHUTDOWN_INFO preshutdown_info;
1952 static const CHAR servicename [] = "Winetest";
1953 static const CHAR displayname [] = "Winetest dummy service";
1954 static const CHAR pathname [] = "we_dont_care.exe";
1955 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1956 static const CHAR password [] = "";
1957 static const CHAR description [] = "Description";
1958
1959 if(!pQueryServiceConfig2A)
1960 {
1961 win_skip("function QueryServiceConfig2A not present\n");
1962 return;
1963 }
1964
1965 SetLastError(0xdeadbeef);
1966 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1967
1968 if (!scm_handle)
1969 {
1970 if(GetLastError() == ERROR_ACCESS_DENIED)
1971 skip("Not enough rights to get a handle to the manager\n");
1972 else
1973 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
1974 return;
1975 }
1976
1977 /* Create a dummy service */
1978 SetLastError(0xdeadbeef);
1979 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1980 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1981 pathname, NULL, NULL, dependencies, NULL, password);
1982
1983 if (!svc_handle)
1984 {
1985 if(GetLastError() == ERROR_SERVICE_EXISTS)
1986 {
1987 /* We try and open the service and do the rest of the tests. Some could
1988 * fail if the tests were changed between these runs.
1989 */
1990 trace("Deletion probably didn't work last time\n");
1991 SetLastError(0xdeadbeef);
1992 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1993 if (!svc_handle)
1994 {
1995 if(GetLastError() == ERROR_ACCESS_DENIED)
1996 skip("Not enough rights to open the service\n");
1997 else
1998 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1999 CloseServiceHandle(scm_handle);
2000 return;
2001 }
2002 }
2003 if (GetLastError() == ERROR_ACCESS_DENIED)
2004 {
2005 skip("Not enough rights to create the service\n");
2006 CloseServiceHandle(scm_handle);
2007 return;
2008 }
2009 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
2010 if (!svc_handle)
2011 {
2012 CloseServiceHandle(scm_handle);
2013 return;
2014 }
2015 }
2016 SetLastError(0xdeadbeef);
2017 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
2018 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2019 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
2020
2021 SetLastError(0xdeadbeef);
2022 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
2023 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2024 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
2025
2026 SetLastError(0xdeadbeef);
2027 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
2028 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2029 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
2030
2031 SetLastError(0xdeadbeef);
2032 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
2033 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2034 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
2035 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2036
2037 SetLastError(0xdeadbeef);
2038 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
2039 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2040 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
2041
2042 needed = 0;
2043 SetLastError(0xdeadbeef);
2044 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
2045 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2046 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2047 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
2048
2049 needed = 0;
2050 pConfig->lpDescription = (LPSTR)0xdeadbeef;
2051 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
2052 ok(ret, "expected QueryServiceConfig2A to succeed\n");
2053 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
2054 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
2055
2056 SetLastError(0xdeadbeef);
2057 needed = 0;
2058 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
2059 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2060 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2061 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
2062
2063 if(!pChangeServiceConfig2A)
2064 {
2065 win_skip("function ChangeServiceConfig2A not present\n");
2066 goto cleanup;
2067 }
2068
2069 pConfig->lpDescription = (LPSTR) description;
2070 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
2071 ok(ret, "ChangeServiceConfig2A failed\n");
2072 if (!ret) {
2073 goto cleanup;
2074 }
2075
2076 SetLastError(0xdeadbeef);
2077 needed = 0;
2078 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
2079 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
2080 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2081 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2082 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
2083
2084 SetLastError(0xdeadbeef);
2085 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
2086 ok(!ret, "expected QueryServiceConfig2A to fail\n");
2087 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2088
2089 SetLastError(0xdeadbeef);
2090 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
2091 ok(ret, "expected QueryServiceConfig2A to succeed\n");
2092 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
2093 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
2094
2095 SetLastError(0xdeadbeef);
2096 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
2097 ok(ret, "expected QueryServiceConfig2A to succeed\n");
2098 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
2099 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
2100
2101 if(!pQueryServiceConfig2W)
2102 {
2103 win_skip("function QueryServiceConfig2W not present\n");
2104 goto cleanup;
2105 }
2106 SetLastError(0xdeadbeef);
2107 needed = 0;
2108 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
2109 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
2110 ok(!ret, "expected QueryServiceConfig2W to fail\n");
2111 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2112 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
2113
2114 SetLastError(0xdeadbeef);
2115 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
2116 ok(ret, "expected QueryServiceConfig2W to succeed\n");
2117
2118 SetLastError(0xdeadbeef);
2119 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
2120 (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed);
2121 if(!ret && GetLastError()==ERROR_INVALID_LEVEL)
2122 {
2123 /* Win2k3 and older */
2124 win_skip("SERVICE_CONFIG_PRESHUTDOWN_INFO not supported\n");
2125 goto cleanup;
2126 }
2127 ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError());
2128 ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed);
2129 ok(preshutdown_info.dwPreshutdownTimeout == 180000, "Default PreshutdownTimeout = %d\n",
2130 preshutdown_info.dwPreshutdownTimeout);
2131
2132 SetLastError(0xdeadbeef);
2133 preshutdown_info.dwPreshutdownTimeout = -1;
2134 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
2135 (LPVOID)&preshutdown_info);
2136 ok(ret, "expected ChangeServiceConfig2A to succeed (%d)\n", GetLastError());
2137
2138 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
2139 (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed);
2140 ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError());
2141 ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed);
2142 ok(preshutdown_info.dwPreshutdownTimeout == -1, "New PreshutdownTimeout = %d\n",
2143 preshutdown_info.dwPreshutdownTimeout);
2144
2145 cleanup:
2146 DeleteService(svc_handle);
2147
2148 CloseServiceHandle(svc_handle);
2149
2150 /* Wait a while. The following test does a CreateService again */
2151 Sleep(1000);
2152
2153 CloseServiceHandle(scm_handle);
2154 }
2155
2156 static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, DWORD is_nt4)
2157 {
2158 BOOL ret;
2159 DWORD le1, le2;
2160 SERVICE_STATUS status;
2161
2162 ret = StartServiceA(svc_handle, 0, NULL);
2163 le1 = GetLastError();
2164 ok(!ret, "%s: StartServiceA() should have failed\n", name);
2165
2166 if (pQueryServiceStatusEx)
2167 {
2168 DWORD needed;
2169 SERVICE_STATUS_PROCESS statusproc;
2170
2171 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)&statusproc, sizeof(statusproc), &needed);
2172 ok(ret, "%s: QueryServiceStatusEx() failed le=%u\n", name, GetLastError());
2173 ok(statusproc.dwCurrentState == SERVICE_STOPPED, "%s: should be stopped state=%x\n", name, statusproc.dwCurrentState);
2174 ok(statusproc.dwProcessId == 0, "%s: ProcessId should be 0 instead of %x\n", name, statusproc.dwProcessId);
2175 }
2176
2177 ret = StartServiceA(svc_handle, 0, NULL);
2178 le2 = GetLastError();
2179 ok(!ret, "%s: StartServiceA() should have failed\n", name);
2180 ok(le2 == le1, "%s: the second try should yield the same error: %u != %u\n", name, le1, le2);
2181
2182 status.dwCurrentState = 0xdeadbeef;
2183 ret = ControlService(svc_handle, SERVICE_CONTROL_STOP, &status);
2184 le2 = GetLastError();
2185 ok(!ret, "%s: ControlService() should have failed\n", name);
2186 ok(le2 == ERROR_SERVICE_NOT_ACTIVE, "%s: %d != ERROR_SERVICE_NOT_ACTIVE\n", name, le2);
2187 ok(status.dwCurrentState == SERVICE_STOPPED ||
2188 broken(is_nt4), /* NT4 returns a random value */
2189 "%s: should be stopped state=%x\n", name, status.dwCurrentState);
2190
2191 return le1;
2192 }
2193
2194 static void test_start_stop(void)
2195 {
2196 BOOL ret;
2197 SC_HANDLE scm_handle, svc_handle;
2198 DWORD le, is_nt4;
2199 static const char servicename[] = "Winetest";
2200 char cmd[MAX_PATH+20];
2201 const char* displayname;
2202
2203 SetLastError(0xdeadbeef);
2204 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2205 if (!scm_handle)
2206 {
2207 if(GetLastError() == ERROR_ACCESS_DENIED)
2208 skip("Not enough rights to get a handle to the manager\n");
2209 else
2210 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
2211 return;
2212 }
2213
2214 /* Detect NT4 */
2215 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
2216 is_nt4=(svc_handle == NULL && GetLastError() == ERROR_INVALID_PARAMETER);
2217
2218 /* Do some cleanup in case a previous run crashed */
2219 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
2220 if (svc_handle)
2221 {
2222 DeleteService(svc_handle);
2223 CloseServiceHandle(svc_handle);
2224 }
2225
2226 /* Create a dummy disabled service */
2227 sprintf(cmd, "\"%s\" service exit", selfname);
2228 displayname = "Winetest Disabled Service";
2229 svc_handle = CreateServiceA(scm_handle, servicename, displayname,
2230 GENERIC_ALL, SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS,
2231 SERVICE_DISABLED, SERVICE_ERROR_IGNORE, cmd, NULL,
2232 NULL, NULL, NULL, NULL);
2233 if (!svc_handle)
2234 {
2235 if(GetLastError() == ERROR_ACCESS_DENIED)
2236 skip("Not enough rights to create the service\n");
2237 else
2238 ok(FALSE, "Could not create the service: %d\n", GetLastError());
2239 goto cleanup;
2240 }
2241 le = try_start_stop(svc_handle, displayname, is_nt4);
2242 ok(le == ERROR_SERVICE_DISABLED, "%d != ERROR_SERVICE_DISABLED\n", le);
2243
2244 /* Then one with a bad path */
2245 displayname = "Winetest Bad Path";
2246 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, "c:\\no_such_file.exe", NULL, NULL, NULL, NULL, NULL, displayname);
2247 ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError());
2248 try_start_stop(svc_handle, displayname, is_nt4);
2249
2250 if (is_nt4)
2251 {
2252 /* NT4 does not detect when a service fails to start and uses an
2253 * insanely long timeout: 120s. So skip the rest of the tests.
2254 */
2255 win_skip("Skip some service start/stop tests on NT4\n");
2256 goto cleanup;
2257 }
2258
2259 if (!winetest_interactive)
2260 {
2261 skip("ROSTESTS-56: Skipping service start timeout tests!\n");
2262 goto cleanup;
2263 }
2264
2265 /* Again with a process that exits right away */
2266 displayname = "Winetest Exit Service";
2267 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname);
2268 ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError());
2269 le = try_start_stop(svc_handle, displayname, is_nt4);
2270 ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
2271
2272 /* And finally with a service that plays dead, forcing a timeout.
2273 * This time we will put no quotes. That should work too, even if there are
2274 * spaces in the path.
2275 */
2276 sprintf(cmd, "%s service sleep", selfname);
2277 displayname = "Winetest Sleep Service";
2278 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname);
2279 ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError());
2280
2281 le = try_start_stop(svc_handle, displayname, is_nt4);
2282 ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
2283
2284 cleanup:
2285 if (svc_handle)
2286 {
2287 DeleteService(svc_handle);
2288 CloseServiceHandle(svc_handle);
2289 }
2290
2291 /* Wait a while. The following test does a CreateService again */
2292 Sleep(1000);
2293
2294 CloseServiceHandle(scm_handle);
2295 }
2296
2297 static void test_refcount(void)
2298 {
2299 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
2300 static const CHAR servicename [] = "Winetest";
2301 static const CHAR pathname [] = "we_dont_care.exe";
2302 BOOL ret;
2303
2304 /* Get a handle to the Service Control Manager */
2305 SetLastError(0xdeadbeef);
2306 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2307 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
2308 {
2309 skip("Not enough rights to get a handle to the manager\n");
2310 return;
2311 }
2312
2313 /* Create a service */
2314 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2315 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2316 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2317 ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError());
2318
2319 /* Get a handle to this new service */
2320 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2321 ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError());
2322
2323 /* Get another handle to this new service */
2324 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2325 ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError());
2326
2327 /* Check if we can close the handle to the Service Control Manager */
2328 ret = CloseServiceHandle(scm_handle);
2329 ok(ret, "Expected success (err=%d)\n", GetLastError());
2330
2331 /* Get a new handle to the Service Control Manager */
2332 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2333 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
2334
2335 /* Get a handle to this new service */
2336 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
2337 ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError());
2338
2339 /* Delete the service */
2340 ret = DeleteService(svc_handle4);
2341 ok(ret, "Expected success (err=%d)\n", GetLastError());
2342
2343 /* We cannot create the same service again as it's still marked as 'being deleted'.
2344 * The reason is that we still have 4 open handles to this service even though we
2345 * closed the handle to the Service Control Manager in between.
2346 */
2347 SetLastError(0xdeadbeef);
2348 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2349 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2350 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2351 todo_wine
2352 {
2353 ok(!svc_handle5, "Expected failure\n");
2354 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
2355 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2356 }
2357
2358 /* FIXME: Remove this when Wine is fixed */
2359 if (svc_handle5)
2360 {
2361 DeleteService(svc_handle5);
2362 CloseServiceHandle(svc_handle5);
2363 }
2364
2365 /* Close all the handles to the service and try again */
2366 ret = CloseServiceHandle(svc_handle4);
2367 ok(ret, "Expected success (err=%d)\n", GetLastError());
2368 ret = CloseServiceHandle(svc_handle3);
2369 ok(ret, "Expected success (err=%d)\n", GetLastError());
2370 ret = CloseServiceHandle(svc_handle2);
2371 ok(ret, "Expected success (err=%d)\n", GetLastError());
2372 ret = CloseServiceHandle(svc_handle1);
2373 ok(ret, "Expected success (err=%d)\n", GetLastError());
2374
2375 /* Wait a while. Doing a CreateService too soon will result again
2376 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2377 */
2378 Sleep(1000);
2379
2380 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2381 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2382 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2383 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2384 ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError());
2385
2386 /* Delete the service */
2387 ret = DeleteService(svc_handle5);
2388 ok(ret, "Expected success (err=%d)\n", GetLastError());
2389
2390 /* Wait a while. Just in case one of the following tests does a CreateService again */
2391 Sleep(1000);
2392
2393 CloseServiceHandle(svc_handle5);
2394 CloseServiceHandle(scm_handle);
2395 }
2396
2397 START_TEST(service)
2398 {
2399 SC_HANDLE scm_handle;
2400 int myARGC;
2401 char** myARGV;
2402
2403 myARGC = winetest_get_mainargs(&myARGV);
2404 GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL);
2405 if (myARGC >= 3)
2406 {
2407 if (strcmp(myARGV[2], "sleep") == 0)
2408 /* Cause a service startup timeout */
2409 Sleep(90000);
2410 /* then, or if myARGV[2] == "exit", just exit */
2411 return;
2412 }
2413
2414 /* Bail out if we are on win98 */
2415 SetLastError(0xdeadbeef);
2416 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2417
2418 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2419 {
2420 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2421 return;
2422 }
2423 CloseServiceHandle(scm_handle);
2424
2425 init_function_pointers();
2426
2427 /* First some parameter checking */
2428 test_open_scm();
2429 test_open_svc();
2430 test_create_delete_svc();
2431 test_get_displayname();
2432 test_get_servicekeyname();
2433 test_query_svc();
2434 test_enum_svc();
2435 test_close();
2436 /* Test the creation, querying and deletion of a service */
2437 test_sequence();
2438 test_queryconfig2();
2439 test_start_stop();
2440 /* The main reason for this test is to check if any refcounting is used
2441 * and what the rules are
2442 */
2443 test_refcount();
2444 }