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