push 6377a023768d7480eb1b17e57456824888936b43
[wine/hacks.git] / dlls / advapi32 / tests / service.c
blob0851384b70b2d1d4084a84cee1a1ac2fb003e8c4
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 */
37 static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
38 static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
39 DWORD, LPBYTE, DWORD, LPDWORD,
40 LPDWORD, LPDWORD, LPCSTR);
41 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
42 PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
43 static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
44 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
45 static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
46 DWORD, LPDWORD);
48 static void init_function_pointers(void)
50 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
52 pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A");
53 pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA");
54 pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo");
55 pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
56 pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
57 pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
60 static void test_open_scm(void)
62 SC_HANDLE scm_handle;
64 /* No access rights */
65 SetLastError(0xdeadbeef);
66 scm_handle = OpenSCManagerA(NULL, NULL, 0);
67 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
68 CloseServiceHandle(scm_handle);
70 /* Unknown database name */
71 SetLastError(0xdeadbeef);
72 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
73 ok(!scm_handle, "Expected failure\n");
74 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
75 CloseServiceHandle(scm_handle); /* Just in case */
77 /* MSDN says only ServiceActive is allowed, or NULL */
78 SetLastError(0xdeadbeef);
79 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
80 ok(!scm_handle, "Expected failure\n");
81 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
82 CloseServiceHandle(scm_handle); /* Just in case */
84 /* Remote unknown host */
85 SetLastError(0xdeadbeef);
86 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
87 todo_wine
89 ok(!scm_handle, "Expected failure\n");
90 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
91 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
93 CloseServiceHandle(scm_handle); /* Just in case */
95 /* Proper call with an empty hostname */
96 SetLastError(0xdeadbeef);
97 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
98 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
99 CloseServiceHandle(scm_handle);
101 /* Again a correct one */
102 SetLastError(0xdeadbeef);
103 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
104 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
105 CloseServiceHandle(scm_handle);
108 static void test_open_svc(void)
110 SC_HANDLE scm_handle, svc_handle;
111 CHAR displayname[4096];
112 DWORD displaysize;
114 /* All NULL (invalid access rights) */
115 SetLastError(0xdeadbeef);
116 svc_handle = OpenServiceA(NULL, NULL, 0);
117 ok(!svc_handle, "Expected failure\n");
118 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
120 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
122 /* NULL service */
123 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
124 SetLastError(0xdeadbeef);
125 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
126 ok(!svc_handle, "Expected failure\n");
127 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
128 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
129 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
131 /* Nonexistent service */
132 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
133 SetLastError(0xdeadbeef);
134 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
135 ok(!svc_handle, "Expected failure\n");
136 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
137 CloseServiceHandle(scm_handle);
139 /* Proper SCM handle but different access rights */
140 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
141 SetLastError(0xdeadbeef);
142 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
143 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
144 skip("Not enough rights to get a handle to the service\n");
145 else
147 ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError());
148 CloseServiceHandle(svc_handle);
151 /* Test to show we can't open a service with the displayname */
153 /* Retrieve the needed size for the buffer */
154 displaysize = 0;
155 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
156 /* Get the displayname */
157 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
158 /* Try to open the service with this displayname, unless the displayname equals
159 * the servicename as that would defeat the purpose of this test.
161 if (!lstrcmpi(spooler, displayname))
163 skip("displayname equals servicename\n");
164 CloseServiceHandle(scm_handle);
165 return;
168 SetLastError(0xdeadbeef);
169 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
170 ok(!svc_handle, "Expected failure\n");
171 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
172 /* Just in case */
173 CloseServiceHandle(svc_handle);
175 CloseServiceHandle(scm_handle);
178 static void test_create_delete_svc(void)
180 SC_HANDLE scm_handle, svc_handle1;
181 CHAR username[UNLEN + 1], domain[MAX_PATH];
182 DWORD user_size = UNLEN + 1;
183 CHAR account[UNLEN + 3];
184 static const CHAR servicename [] = "Winetest";
185 static const CHAR pathname [] = "we_dont_care.exe";
186 static const CHAR empty [] = "";
187 static const CHAR password [] = "secret";
188 BOOL spooler_exists = FALSE;
189 BOOL ret;
190 CHAR display[4096];
191 DWORD display_size = sizeof(display);
193 /* Get the username and turn it into an account to be used in some tests */
194 GetUserNameA(username, &user_size);
195 /* Get the domainname to cater for that situation */
196 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
197 sprintf(account, "%s\\%s", domain, username);
198 else
199 sprintf(account, ".\\%s", username);
201 /* All NULL */
202 SetLastError(0xdeadbeef);
203 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
204 ok(!svc_handle1, "Expected failure\n");
205 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
207 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
209 /* Only a valid handle to the Service Control Manager */
210 SetLastError(0xdeadbeef);
211 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
212 ok(!svc_handle1, "Expected failure\n");
213 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
214 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
215 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
217 /* Now with a servicename */
218 SetLastError(0xdeadbeef);
219 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
220 ok(!svc_handle1, "Expected failure\n");
221 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
222 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
223 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
225 /* Or just a binary name */
226 SetLastError(0xdeadbeef);
227 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
228 ok(!svc_handle1, "Expected failure\n");
229 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
230 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
231 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
233 /* Both servicename and binary name (We only have connect rights) */
234 SetLastError(0xdeadbeef);
235 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
236 ok(!svc_handle1, "Expected failure\n");
237 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
239 /* They can even be empty at this stage of parameter checking */
240 SetLastError(0xdeadbeef);
241 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
242 ok(!svc_handle1, "Expected failure\n");
243 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
245 SetLastError(0xdeadbeef);
246 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
247 ok(!svc_handle1, "Expected failure\n");
248 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
250 /* Open the Service Control Manager with minimal rights for creation
251 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
253 CloseServiceHandle(scm_handle);
254 SetLastError(0xdeadbeef);
255 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
256 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
258 skip("Not enough rights to get a handle to the manager\n");
259 return;
262 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
264 /* Empty strings for servicename and binary name are checked */
265 SetLastError(0xdeadbeef);
266 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
267 ok(!svc_handle1, "Expected failure\n");
268 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
270 SetLastError(0xdeadbeef);
271 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
272 ok(!svc_handle1, "Expected failure\n");
273 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
275 SetLastError(0xdeadbeef);
276 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, 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 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
281 * an ERROR_INVALID_PARAMETER)
283 SetLastError(0xdeadbeef);
284 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
285 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
286 ok(!svc_handle1, "Expected failure\n");
287 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
289 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
291 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
292 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
294 SetLastError(0xdeadbeef);
295 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
296 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
297 ok(!svc_handle1, "Expected failure\n");
298 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
300 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
301 SetLastError(0xdeadbeef);
302 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
303 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
304 ok(!svc_handle1, "Expected failure\n");
305 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
307 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
308 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
310 SetLastError(0xdeadbeef);
311 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
312 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
313 ok(!svc_handle1, "Expected failure\n");
314 ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT,
315 "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError());
317 /* Illegal (start-type is not a mask and should only be one of the possibilities)
318 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
319 * it's most likely not the wanted start-type)
321 SetLastError(0xdeadbeef);
322 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
323 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
324 ok(!svc_handle1, "Expected failure\n");
325 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
327 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
328 SetLastError(0xdeadbeef);
329 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
330 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
331 ok(!svc_handle1, "Expected failure\n");
332 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
334 /* The service already exists (check first, just in case) */
335 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
336 if (svc_handle1)
338 spooler_exists = TRUE;
339 CloseServiceHandle(svc_handle1);
340 SetLastError(0xdeadbeef);
341 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
342 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
343 ok(!svc_handle1, "Expected failure\n");
344 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
346 else
347 skip("Spooler service doesn't exist\n");
349 /* To find an existing displayname we check the 'Spooler' service. Although the registry
350 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
351 * to the servicename and can't be used as well for a new displayname.
353 if (spooler_exists)
355 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
357 if (!ret)
358 skip("Could not retrieve a displayname for the Spooler service\n");
359 else
361 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
362 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
363 ok(!svc_handle1, "Expected failure\n");
364 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
365 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
368 else
369 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
371 /* Windows doesn't care about the access rights for creation (which makes
372 * sense as there is no service yet) as long as there are sufficient
373 * rights to the manager.
375 SetLastError(0xdeadbeef);
376 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
377 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
378 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
380 /* DeleteService however must have proper rights */
381 SetLastError(0xdeadbeef);
382 ret = DeleteService(svc_handle1);
383 ok(!ret, "Expected failure\n");
384 ok(GetLastError() == ERROR_ACCESS_DENIED,
385 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
387 /* Open the service with minimal rights for deletion.
388 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
390 CloseServiceHandle(svc_handle1);
391 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
393 /* Now that we have the proper rights, we should be able to delete */
394 SetLastError(0xdeadbeef);
395 ret = DeleteService(svc_handle1);
396 ok(ret, "Expected success, got error %u\n", GetLastError());
398 CloseServiceHandle(svc_handle1);
399 CloseServiceHandle(scm_handle);
401 /* Wait a while. One of the following tests also does a CreateService for the
402 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
403 * error if we do this to quick. Vista seems more picky then the others.
405 Sleep(1000);
407 /* And a final NULL check */
408 SetLastError(0xdeadbeef);
409 ret = DeleteService(NULL);
410 ok(!ret, "Expected failure\n");
411 ok(GetLastError() == ERROR_INVALID_HANDLE,
412 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
415 static void test_get_displayname(void)
417 SC_HANDLE scm_handle, svc_handle;
418 BOOL ret;
419 CHAR displayname[4096];
420 WCHAR displaynameW[2048];
421 DWORD displaysize, tempsize, tempsizeW;
422 static const CHAR deadbeef[] = "Deadbeef";
423 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
424 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
425 static const WCHAR abcW[] = {'A','B','C',0};
426 static const CHAR servicename[] = "Winetest";
427 static const CHAR pathname[] = "we_dont_care.exe";
429 /* Having NULL for the size of the buffer will crash on W2K3 */
431 SetLastError(0xdeadbeef);
432 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
433 ok(!ret, "Expected failure\n");
434 ok(GetLastError() == ERROR_INVALID_HANDLE,
435 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
437 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
439 SetLastError(0xdeadbeef);
440 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
441 ok(!ret, "Expected failure\n");
442 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
443 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
444 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
446 SetLastError(0xdeadbeef);
447 displaysize = sizeof(displayname);
448 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
449 ok(!ret, "Expected failure\n");
450 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
451 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
452 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
454 /* Test for nonexistent service */
455 SetLastError(0xdeadbeef);
456 displaysize = -1;
457 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
458 ok(!ret, "Expected failure\n");
459 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
460 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
462 SetLastError(0xdeadbeef);
463 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
464 ok(!ret, "Expected failure\n");
465 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
466 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
467 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
469 displaysize = 15;
470 strcpy(displayname, "ABC");
471 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
472 ok(!ret, "Expected failure\n");
473 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
474 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
475 todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
476 ok(displayname[0] == 0, "Service name not empty\n");
478 displaysize = 15;
479 lstrcpyW( displaynameW, abcW );
480 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &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 ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
485 ok(displaynameW[0] == 0, "Service name not empty\n");
487 displaysize = 0;
488 strcpy(displayname, "ABC");
489 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
490 ok(!ret, "Expected failure\n");
491 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
492 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
493 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
494 ok(displayname[0] == 'A', "Service name changed\n");
496 displaysize = 0;
497 lstrcpyW( displaynameW, abcW );
498 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
499 ok(!ret, "Expected failure\n");
500 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
501 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
502 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
503 ok(displaynameW[0] == 'A', "Service name changed\n");
505 displaysize = 1;
506 strcpy(displayname, "ABC");
507 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
508 ok(!ret, "Expected failure\n");
509 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
510 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
511 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
512 ok(displayname[0] == 0, "Service name not empty\n");
514 displaysize = 1;
515 lstrcpyW( displaynameW, abcW );
516 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
517 ok(!ret, "Expected failure\n");
518 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
519 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
520 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
521 ok(displaynameW[0] == 'A', "Service name changed\n");
523 displaysize = 2;
524 strcpy(displayname, "ABC");
525 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
526 ok(!ret, "Expected failure\n");
527 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
528 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
529 todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
530 ok(displayname[0] == 0, "Service name not empty\n");
532 displaysize = 2;
533 lstrcpyW( displaynameW, abcW );
534 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
535 ok(!ret, "Expected failure\n");
536 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
537 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
538 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
539 ok(displaynameW[0] == 0, "Service name not empty\n");
541 /* Check if 'Spooler' exists */
542 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
543 if (!svc_handle)
545 skip("Spooler service doesn't exist\n");
546 CloseServiceHandle(scm_handle);
547 return;
549 CloseServiceHandle(svc_handle);
551 /* Retrieve the needed size for the buffer */
552 SetLastError(0xdeadbeef);
553 displaysize = -1;
554 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
555 ok(!ret, "Expected failure\n");
556 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
557 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
558 tempsize = displaysize;
560 displaysize = 0;
561 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
562 ok(!ret, "Expected failure\n");
563 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
564 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
565 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
567 /* Buffer is too small */
568 SetLastError(0xdeadbeef);
569 displaysize = (tempsize / 2);
570 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
571 ok(!ret, "Expected failure\n");
572 ok(displaysize == tempsize, "Expected the needed buffersize\n");
573 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
574 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
576 /* First try with a buffer that should be big enough to hold
577 * the ANSI string (and terminating character). This succeeds on Windows
578 * although when asked (see above 2 tests) it will return twice the needed size.
580 SetLastError(0xdeadbeef);
581 displaysize = (tempsize / 2) + 1;
582 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
583 ok(ret, "Expected success, got error %u\n", GetLastError());
584 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
586 /* Now with the original returned size */
587 SetLastError(0xdeadbeef);
588 displaysize = tempsize;
589 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
590 ok(ret, "Expected success, got error %u\n", GetLastError());
591 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
593 /* And with a bigger than needed buffer */
594 SetLastError(0xdeadbeef);
595 displaysize = tempsize * 2;
596 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
597 ok(ret, "Expected success, got error %u\n", GetLastError());
598 /* Test that shows that if the buffersize is enough, it's not changed */
599 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
600 ok(lstrlen(displayname) == tempsize/2,
601 "Expected the buffer to be twice the length of the string\n") ;
603 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
604 SetLastError(0xdeadbeef);
605 displaysize = -1;
606 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
607 ok(!ret, "Expected failure\n");
608 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
609 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
611 /* Buffer is too small */
612 SetLastError(0xdeadbeef);
613 tempsizeW = displaysize;
614 displaysize = tempsizeW / 2;
615 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
616 ok(!ret, "Expected failure\n");
617 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
618 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
619 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
621 /* Now with the original returned size */
622 SetLastError(0xdeadbeef);
623 displaysize = tempsizeW;
624 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
625 ok(!ret, "Expected failure\n");
626 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
627 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
628 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
630 /* And with a bigger than needed buffer */
631 SetLastError(0xdeadbeef);
632 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
633 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
634 ok(ret, "Expected success, got error %u\n", GetLastError());
635 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
636 ok(lstrlenW(displaynameW) == displaysize,
637 "Expected the buffer to be the length of the string\n") ;
638 ok(tempsize / 2 == tempsizeW,
639 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
641 CloseServiceHandle(scm_handle);
643 /* Test for a service without a displayname (which is valid). This should return
644 * the servicename itself.
646 SetLastError(0xdeadbeef);
647 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
648 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
650 skip("Not enough rights to get a handle to the manager\n");
651 return;
654 SetLastError(0xdeadbeef);
655 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
656 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
657 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
658 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
659 if (!svc_handle)
661 CloseServiceHandle(scm_handle);
662 return;
665 /* Retrieve the needed size for the buffer */
666 SetLastError(0xdeadbeef);
667 displaysize = -1;
668 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
669 ok(!ret, "Expected failure\n");
670 ok(displaysize == lstrlen(servicename) * 2,
671 "Expected the displaysize to be twice the size of the servicename\n");
672 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
673 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
675 /* Buffer is too small */
676 SetLastError(0xdeadbeef);
677 tempsize = displaysize;
678 displaysize = (tempsize / 2);
679 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
680 ok(!ret, "Expected failure\n");
681 ok(displaysize == tempsize, "Expected the needed buffersize\n");
682 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
683 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
685 /* Get the displayname */
686 SetLastError(0xdeadbeef);
687 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
688 ok(ret, "Expected success, got error %u\n", GetLastError());
689 ok(!lstrcmpi(displayname, servicename),
690 "Expected displayname to be %s, got %s\n", servicename, displayname);
692 /* Delete the service */
693 ret = DeleteService(svc_handle);
694 ok(ret, "Expected success (err=%d)\n", GetLastError());
696 CloseServiceHandle(svc_handle);
697 CloseServiceHandle(scm_handle);
699 /* Wait a while. Just in case one of the following tests does a CreateService again */
700 Sleep(1000);
703 static void test_get_servicekeyname(void)
705 SC_HANDLE scm_handle, svc_handle;
706 CHAR servicename[4096];
707 CHAR displayname[4096];
708 WCHAR servicenameW[4096];
709 WCHAR displaynameW[4096];
710 DWORD servicesize, displaysize, tempsize;
711 BOOL ret;
712 static const CHAR deadbeef[] = "Deadbeef";
713 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
714 static const WCHAR abcW[] = {'A','B','C',0};
716 /* Having NULL for the size of the buffer will crash on W2K3 */
718 SetLastError(0xdeadbeef);
719 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
720 ok(!ret, "Expected failure\n");
721 ok(GetLastError() == ERROR_INVALID_HANDLE,
722 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
724 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
726 servicesize = 200;
727 SetLastError(0xdeadbeef);
728 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
729 ok(!ret, "Expected failure\n");
730 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
731 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
732 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
733 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
735 /* Valid handle and buffer but no displayname */
736 servicesize = 200;
737 SetLastError(0xdeadbeef);
738 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
739 ok(!ret, "Expected failure\n");
740 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
741 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
742 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
743 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
745 /* Test for nonexistent displayname */
746 SetLastError(0xdeadbeef);
747 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
748 ok(!ret, "Expected failure\n");
749 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
750 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
751 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
753 servicesize = 15;
754 strcpy(servicename, "ABC");
755 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
756 ok(!ret, "Expected failure\n");
757 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
758 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
759 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
760 ok(servicename[0] == 0, "Service name not empty\n");
762 servicesize = 15;
763 lstrcpyW( servicenameW, abcW );
764 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &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 ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
769 ok(servicenameW[0] == 0, "Service name not empty\n");
771 servicesize = 0;
772 strcpy(servicename, "ABC");
773 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
774 ok(!ret, "Expected failure\n");
775 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
776 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
777 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
778 ok(servicename[0] == 'A', "Service name changed\n");
780 servicesize = 0;
781 lstrcpyW( servicenameW, abcW );
782 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
783 ok(!ret, "Expected failure\n");
784 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
785 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
786 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
787 ok(servicenameW[0] == 'A', "Service name changed\n");
789 servicesize = 1;
790 strcpy(servicename, "ABC");
791 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
792 ok(!ret, "Expected failure\n");
793 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
794 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
795 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
796 ok(servicename[0] == 0, "Service name not empty\n");
798 servicesize = 1;
799 lstrcpyW( servicenameW, abcW );
800 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
801 ok(!ret, "Expected failure\n");
802 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
803 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
804 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
805 ok(servicenameW[0] == 'A', "Service name changed\n");
807 servicesize = 2;
808 strcpy(servicename, "ABC");
809 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
810 ok(!ret, "Expected failure\n");
811 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
812 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
813 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
814 ok(servicename[0] == 0, "Service name not empty\n");
816 servicesize = 2;
817 lstrcpyW( servicenameW, abcW );
818 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
819 ok(!ret, "Expected failure\n");
820 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
821 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
822 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
823 ok(servicenameW[0] == 0, "Service name not empty\n");
825 /* Check if 'Spooler' exists */
826 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
827 if (!svc_handle)
829 skip("Spooler service doesn't exist\n");
830 CloseServiceHandle(scm_handle);
831 return;
833 CloseServiceHandle(svc_handle);
835 /* Get the displayname for the 'Spooler' service */
836 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
837 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
839 /* Retrieve the needed size for the buffer */
840 SetLastError(0xdeadbeef);
841 servicesize = 0;
842 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
843 ok(!ret, "Expected failure\n");
844 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
845 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
847 /* Valid call with the correct buffersize */
848 SetLastError(0xdeadbeef);
849 tempsize = servicesize;
850 servicesize *= 2;
851 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
852 ok(ret, "Expected success, got error %u\n", GetLastError());
853 if (ret)
855 ok(lstrlen(servicename) == tempsize/2,
856 "Expected the buffer to be twice the length of the string\n") ;
857 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
858 ok(servicesize == (tempsize * 2),
859 "Expected servicesize not to change if buffer not insufficient\n") ;
862 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
863 SetLastError(0xdeadbeef);
864 servicesize *= 2;
865 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
866 ok(ret, "Expected success, got error %u\n", GetLastError());
867 if (ret)
869 ok(lstrlen(servicename) == tempsize/2,
870 "Expected the buffer to be twice the length of the string\n") ;
871 ok(servicesize == lstrlenW(servicenameW),
872 "Expected servicesize not to change if buffer not insufficient\n") ;
875 SetLastError(0xdeadbeef);
876 servicesize = 3;
877 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
878 ok(!ret, "Expected failure\n");
879 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
880 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
881 ok(servicenameW[0] == 0, "Buffer not empty\n");
883 CloseServiceHandle(scm_handle);
886 static void test_query_svc(void)
888 SC_HANDLE scm_handle, svc_handle;
889 BOOL ret;
890 SERVICE_STATUS status;
891 SERVICE_STATUS_PROCESS *statusproc;
892 DWORD bufsize, needed;
894 /* All NULL or wrong */
895 SetLastError(0xdeadbeef);
896 ret = QueryServiceStatus(NULL, NULL);
897 ok(!ret, "Expected failure\n");
898 ok(GetLastError() == ERROR_INVALID_HANDLE,
899 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
901 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
903 /* Check if 'Spooler' exists.
904 * Open with not enough rights to query the status.
906 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
907 if (!svc_handle)
909 skip("Spooler service doesn't exist\n");
910 CloseServiceHandle(scm_handle);
911 return;
914 SetLastError(0xdeadbeef);
915 ret = QueryServiceStatus(svc_handle, NULL);
916 ok(!ret, "Expected failure\n");
917 todo_wine
918 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
919 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
920 "Unexpected last error %d\n", GetLastError());
922 SetLastError(0xdeadbeef);
923 ret = QueryServiceStatus(svc_handle, &status);
924 ok(!ret, "Expected failure\n");
925 ok(GetLastError() == ERROR_ACCESS_DENIED,
926 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
928 /* Open the service with just enough rights.
929 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
931 CloseServiceHandle(svc_handle);
932 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
934 SetLastError(0xdeadbeef);
935 ret = QueryServiceStatus(svc_handle, &status);
936 ok(ret, "Expected success, got error %u\n", GetLastError());
938 CloseServiceHandle(svc_handle);
940 /* More or less the same tests for QueryServiceStatusEx */
942 /* Open service with not enough rights to query the status */
943 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
945 /* All NULL or wrong, this proves that info level is checked first */
946 SetLastError(0xdeadbeef);
947 ret = pQueryServiceStatusEx(NULL, 1, NULL, 0, NULL);
948 ok(!ret, "Expected failure\n");
949 todo_wine
950 ok(GetLastError() == ERROR_INVALID_LEVEL,
951 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
953 /* Passing a NULL parameter for the needed buffer size
954 * will crash on anything but NT4.
957 /* Only info level is correct. It looks like the buffer/size is checked second */
958 SetLastError(0xdeadbeef);
959 ret = pQueryServiceStatusEx(NULL, 0, NULL, 0, &needed);
960 /* NT4 and Wine check the handle first */
961 if (GetLastError() != ERROR_INVALID_HANDLE)
963 ok(!ret, "Expected failure\n");
964 ok(needed == sizeof(SERVICE_STATUS_PROCESS),
965 "Needed buffersize is wrong : %d\n", needed);
966 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
967 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
970 /* Pass a correct buffer and buffersize but a NULL handle */
971 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
972 bufsize = needed;
973 SetLastError(0xdeadbeef);
974 ret = pQueryServiceStatusEx(NULL, 0, (BYTE*)statusproc, bufsize, &needed);
975 ok(!ret, "Expected failure\n");
976 ok(GetLastError() == ERROR_INVALID_HANDLE,
977 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
978 HeapFree(GetProcessHeap(), 0, statusproc);
980 /* Correct handle and info level */
981 SetLastError(0xdeadbeef);
982 ret = pQueryServiceStatusEx(svc_handle, 0, NULL, 0, &needed);
983 /* NT4 doesn't return the needed size */
984 if (GetLastError() != ERROR_INVALID_PARAMETER)
986 ok(!ret, "Expected failure\n");
987 todo_wine
989 ok(needed == sizeof(SERVICE_STATUS_PROCESS),
990 "Needed buffersize is wrong : %d\n", needed);
991 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
992 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
996 /* All parameters are OK but we don't have enough rights */
997 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
998 bufsize = sizeof(SERVICE_STATUS_PROCESS);
999 SetLastError(0xdeadbeef);
1000 ret = pQueryServiceStatusEx(svc_handle, 0, (BYTE*)statusproc, bufsize, &needed);
1001 ok(!ret, "Expected failure\n");
1002 ok(GetLastError() == ERROR_ACCESS_DENIED,
1003 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1004 HeapFree(GetProcessHeap(), 0, statusproc);
1006 /* Open the service with just enough rights. */
1007 CloseServiceHandle(svc_handle);
1008 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
1010 /* Everything should be fine now. */
1011 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1012 bufsize = sizeof(SERVICE_STATUS_PROCESS);
1013 SetLastError(0xdeadbeef);
1014 ret = pQueryServiceStatusEx(svc_handle, 0, (BYTE*)statusproc, bufsize, &needed);
1015 ok(ret, "Expected success, got error %u\n", GetLastError());
1016 if (statusproc->dwCurrentState == SERVICE_RUNNING)
1017 ok(statusproc->dwProcessId != 0,
1018 "Expect a process id for this running service\n");
1019 else
1020 ok(statusproc->dwProcessId == 0,
1021 "Expect no process id for this stopped service\n");
1022 HeapFree(GetProcessHeap(), 0, statusproc);
1024 CloseServiceHandle(svc_handle);
1025 CloseServiceHandle(scm_handle);
1028 static void test_enum_svc(void)
1030 SC_HANDLE scm_handle;
1031 BOOL ret;
1032 DWORD bufsize, needed, returned, resume;
1033 DWORD tempneeded, tempreturned, missing;
1034 DWORD servicecountactive, servicecountinactive;
1035 ENUM_SERVICE_STATUS *services;
1036 ENUM_SERVICE_STATUS_PROCESS *exservices;
1037 INT i;
1039 /* All NULL or wrong */
1040 SetLastError(0xdeadbeef);
1041 ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1042 ok(!ret, "Expected failure\n");
1043 todo_wine
1044 ok(GetLastError() == ERROR_INVALID_HANDLE,
1045 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1047 /* Open the service control manager with not enough rights at first */
1048 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1050 /* Valid handle but rest is still NULL or wrong */
1051 SetLastError(0xdeadbeef);
1052 ret = EnumServicesStatusA(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1053 ok(!ret, "Expected failure\n");
1054 todo_wine
1055 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1056 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1057 "Unexpected last error %d\n", GetLastError());
1059 /* Don't specify the two required pointers */
1060 returned = 0xdeadbeef;
1061 SetLastError(0xdeadbeef);
1062 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1063 ok(!ret, "Expected failure\n");
1064 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1065 todo_wine
1066 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1067 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1068 "Unexpected last error %d\n", GetLastError());
1070 /* Don't specify the two required pointers */
1071 needed = 0xdeadbeef;
1072 SetLastError(0xdeadbeef);
1073 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1074 ok(!ret, "Expected failure\n");
1075 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1076 "Expected no change to the needed buffer variable\n");
1077 todo_wine
1078 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1079 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1080 "Unexpected last error %d\n", GetLastError());
1082 /* No valid servicetype and servicestate */
1083 needed = 0xdeadbeef;
1084 returned = 0xdeadbeef;
1085 SetLastError(0xdeadbeef);
1086 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1087 ok(!ret, "Expected failure\n");
1088 todo_wine
1090 ok(needed == 0 || broken(needed != 0), /* nt4 */
1091 "Expected needed buffer size to be set to 0, got %d\n", needed);
1092 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1093 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1094 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1097 /* No valid servicetype and servicestate */
1098 needed = 0xdeadbeef;
1099 returned = 0xdeadbeef;
1100 SetLastError(0xdeadbeef);
1101 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1102 ok(!ret, "Expected failure\n");
1103 todo_wine
1105 ok(needed == 0 || broken(needed != 0), /* nt4 */
1106 "Expected needed buffer size to be set to 0, got %d\n", needed);
1107 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1108 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1109 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1112 /* No valid servicetype and servicestate */
1113 needed = 0xdeadbeef;
1114 returned = 0xdeadbeef;
1115 SetLastError(0xdeadbeef);
1116 ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0,
1117 &needed, &returned, NULL);
1118 ok(!ret, "Expected failure\n");
1119 todo_wine
1121 ok(needed == 0 || broken(needed != 0), /* nt4 */
1122 "Expected needed buffer size to be set to 0, got %d\n", needed);
1123 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1124 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1125 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1128 /* All parameters are correct but our access rights are wrong */
1129 needed = 0xdeadbeef;
1130 returned = 0xdeadbeef;
1131 SetLastError(0xdeadbeef);
1132 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1133 &needed, &returned, NULL);
1134 ok(!ret, "Expected failure\n");
1135 todo_wine
1137 ok(needed == 0 || broken(needed != 0), /* nt4 */
1138 "Expected needed buffer size to be set to 0, got %d\n", needed);
1139 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1141 ok(GetLastError() == ERROR_ACCESS_DENIED,
1142 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1144 /* Open the service control manager with the needed rights */
1145 CloseServiceHandle(scm_handle);
1146 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1148 /* All parameters are correct. Request the needed buffer size */
1149 needed = 0xdeadbeef;
1150 returned = 0xdeadbeef;
1151 SetLastError(0xdeadbeef);
1152 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1153 &needed, &returned, NULL);
1154 ok(!ret, "Expected failure\n");
1155 todo_wine
1157 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1158 ok(returned == 0, "Expected no service returned, got %d\n", returned);
1159 ok(GetLastError() == ERROR_MORE_DATA,
1160 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1163 /* Store the needed bytes */
1164 tempneeded = needed;
1166 /* Allocate the correct needed bytes */
1167 services = HeapAlloc(GetProcessHeap(), 0, needed);
1168 bufsize = needed;
1169 needed = 0xdeadbeef;
1170 returned = 0xdeadbeef;
1171 SetLastError(0xdeadbeef);
1172 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1173 services, bufsize, &needed, &returned, NULL);
1174 todo_wine
1176 ok(ret, "Expected success, got error %u\n", GetLastError());
1177 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1178 ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n");
1180 HeapFree(GetProcessHeap(), 0, services);
1182 /* Store the number of returned services */
1183 tempreturned = returned;
1185 /* Allocate less than the needed bytes and don't specify a resume handle */
1186 services = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1187 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1188 needed = 0xdeadbeef;
1189 returned = 0xdeadbeef;
1190 SetLastError(0xdeadbeef);
1191 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1192 services, bufsize, &needed, &returned, NULL);
1193 ok(!ret, "Expected failure\n");
1194 todo_wine
1196 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1197 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1198 ok(GetLastError() == ERROR_MORE_DATA,
1199 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1202 /* Allocate less than the needed bytes, this time with a correct resume handle */
1203 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1204 needed = 0xdeadbeef;
1205 returned = 0xdeadbeef;
1206 resume = 0;
1207 SetLastError(0xdeadbeef);
1208 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1209 services, bufsize, &needed, &returned, &resume);
1210 ok(!ret, "Expected failure\n");
1211 todo_wine
1213 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1214 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1215 ok(resume, "Expected a resume handle\n");
1216 ok(GetLastError() == ERROR_MORE_DATA,
1217 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1220 /* Fetch the missing services but pass a bigger buffer size */
1221 missing = tempreturned - returned;
1222 bufsize = tempneeded;
1223 needed = 0xdeadbeef;
1224 returned = 0xdeadbeef;
1225 SetLastError(0xdeadbeef);
1226 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1227 services, bufsize, &needed, &returned, &resume);
1228 todo_wine
1230 ok(ret, "Expected success, got error %u\n", GetLastError());
1231 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1232 ok(returned == missing, "Expected %u services to be returned\n", missing);
1234 ok(resume == 0, "Expected the resume handle to be 0\n");
1235 HeapFree(GetProcessHeap(), 0, services);
1237 /* See if things add up */
1239 /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1240 * and doesn't count the others as inactive. This means that Vista could
1241 * show a total that is greater than the sum of active and inactive
1242 * drivers.
1243 * The number of active and inactive drivers is greatly influenced by the
1244 * time when tests are run, immediately after boot or later for example.
1246 * Both reasons make calculations for drivers not so useful
1249 /* Get the number of active win32 services */
1250 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0,
1251 &needed, &returned, NULL);
1252 services = HeapAlloc(GetProcessHeap(), 0, needed);
1253 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services,
1254 needed, &needed, &returned, NULL);
1255 HeapFree(GetProcessHeap(), 0, services);
1257 servicecountactive = returned;
1259 /* Get the number of inactive win32 services */
1260 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0,
1261 &needed, &returned, NULL);
1262 services = HeapAlloc(GetProcessHeap(), 0, needed);
1263 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services,
1264 needed, &needed, &returned, NULL);
1265 HeapFree(GetProcessHeap(), 0, services);
1267 servicecountinactive = returned;
1269 /* Get the number of win32 services */
1270 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1271 &needed, &returned, NULL);
1272 services = HeapAlloc(GetProcessHeap(), 0, needed);
1273 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services,
1274 needed, &needed, &returned, NULL);
1275 HeapFree(GetProcessHeap(), 0, services);
1277 /* Check if total is the same as active and inactive win32 services */
1278 todo_wine
1279 ok(returned == (servicecountactive + servicecountinactive),
1280 "Something wrong in the calculation\n");
1282 /* Get all drivers and services
1284 * Fetch the status of the last call as failing could make the following tests crash
1285 * on Wine (we don't return anything yet).
1287 EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1288 NULL, 0, &needed, &returned, NULL);
1289 services = HeapAlloc(GetProcessHeap(), 0, needed);
1290 ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1291 services, needed, &needed, &returned, NULL);
1293 /* Loop through all those returned drivers and services */
1294 for (i = 0; ret && i < returned; i++)
1296 SERVICE_STATUS status = services[i].ServiceStatus;
1298 /* lpServiceName and lpDisplayName should always be filled */
1299 ok(lstrlenA(services[i].lpServiceName) > 0, "Expected a service name\n");
1300 ok(lstrlenA(services[i].lpDisplayName) > 0, "Expected a display name\n");
1302 /* Decrement the counters to see if the functions calls return the same
1303 * numbers as the contents of these structures.
1305 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1307 if (status.dwCurrentState == SERVICE_RUNNING)
1308 servicecountactive--;
1309 else
1310 servicecountinactive--;
1313 HeapFree(GetProcessHeap(), 0, services);
1315 todo_wine
1317 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1318 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1321 CloseServiceHandle(scm_handle);
1323 /* More or less the same for EnumServicesStatusExA */
1325 /* All NULL or wrong */
1326 SetLastError(0xdeadbeef);
1327 ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1328 ok(!ret, "Expected failure\n");
1329 todo_wine
1330 ok(GetLastError() == ERROR_INVALID_LEVEL,
1331 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1333 /* All NULL or wrong, just the info level is correct */
1334 SetLastError(0xdeadbeef);
1335 ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1336 ok(!ret, "Expected failure\n");
1337 todo_wine
1338 ok(GetLastError() == ERROR_INVALID_HANDLE,
1339 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1341 /* Open the service control manager with not enough rights at first */
1342 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1344 /* Valid handle and info level but rest is still NULL or wrong */
1345 SetLastError(0xdeadbeef);
1346 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1347 ok(!ret, "Expected failure\n");
1348 todo_wine
1349 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1350 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1351 "Unexpected last error %d\n", GetLastError());
1353 /* Don't specify the two required pointers */
1354 needed = 0xdeadbeef;
1355 SetLastError(0xdeadbeef);
1356 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL);
1357 ok(!ret, "Expected failure\n");
1358 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1359 "Expected no change to the needed buffer variable\n");
1360 todo_wine
1361 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1362 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1363 "Unexpected last error %d\n", GetLastError());
1365 /* Don't specify the two required pointers */
1366 returned = 0xdeadbeef;
1367 SetLastError(0xdeadbeef);
1368 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL);
1369 ok(!ret, "Expected failure\n");
1370 todo_wine
1372 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1373 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1374 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1375 "Unexpected last error %d\n", GetLastError());
1378 /* No valid servicetype and servicestate */
1379 needed = 0xdeadbeef;
1380 returned = 0xdeadbeef;
1381 SetLastError(0xdeadbeef);
1382 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL);
1383 ok(!ret, "Expected failure\n");
1384 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1385 todo_wine
1387 ok(needed == 0 || broken(needed != 0), /* nt4 */
1388 "Expected needed buffer size to be set to 0, got %d\n", needed);
1389 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1390 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1393 /* No valid servicestate */
1394 needed = 0xdeadbeef;
1395 returned = 0xdeadbeef;
1396 SetLastError(0xdeadbeef);
1397 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0,
1398 &needed, &returned, NULL, NULL);
1399 ok(!ret, "Expected failure\n");
1400 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1401 todo_wine
1403 ok(needed == 0 || broken(needed != 0), /* nt4 */
1404 "Expected needed buffer size to be set to 0, got %d\n", needed);
1405 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1406 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1409 /* No valid servicetype */
1410 needed = 0xdeadbeef;
1411 returned = 0xdeadbeef;
1412 SetLastError(0xdeadbeef);
1413 ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0,
1414 &needed, &returned, NULL, NULL);
1415 ok(!ret, "Expected failure\n");
1416 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1417 todo_wine
1419 ok(needed == 0 || broken(needed != 0), /* nt4 */
1420 "Expected needed buffer size to be set to 0, got %d\n", needed);
1421 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1422 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1425 /* No valid servicetype and servicestate and unknown service group */
1426 needed = 0xdeadbeef;
1427 returned = 0xdeadbeef;
1428 SetLastError(0xdeadbeef);
1429 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed,
1430 &returned, NULL, "deadbeef_group");
1431 ok(!ret, "Expected failure\n");
1432 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1433 todo_wine
1435 ok(needed == 0 || broken(needed != 0), /* nt4 */
1436 "Expected needed buffer size to be set to 0, got %d\n", needed);
1437 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1438 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1441 /* All parameters are correct but our access rights are wrong */
1442 needed = 0xdeadbeef;
1443 returned = 0xdeadbeef;
1444 SetLastError(0xdeadbeef);
1445 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1446 NULL, 0, &needed, &returned, NULL, NULL);
1447 ok(!ret, "Expected failure\n");
1448 todo_wine
1449 ok(needed == 0 || broken(needed != 0), /* nt4 */
1450 "Expected needed buffer size to be set to 0, got %d\n", needed);
1451 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1452 ok(GetLastError() == ERROR_ACCESS_DENIED,
1453 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1455 /* All parameters are correct, access rights are wrong but the
1456 * group name won't be checked yet.
1458 needed = 0xdeadbeef;
1459 returned = 0xdeadbeef;
1460 SetLastError(0xdeadbeef);
1461 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1462 NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1463 ok(!ret, "Expected failure\n");
1464 todo_wine
1465 ok(needed == 0 || broken(needed != 0), /* nt4 */
1466 "Expected needed buffer size to be set to 0, got %d\n", needed);
1467 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1468 ok(GetLastError() == ERROR_ACCESS_DENIED,
1469 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1471 /* Open the service control manager with the needed rights */
1472 CloseServiceHandle(scm_handle);
1473 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1475 /* All parameters are correct and the group will be checked */
1476 needed = 0xdeadbeef;
1477 returned = 0xdeadbeef;
1478 SetLastError(0xdeadbeef);
1479 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1480 NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1481 ok(!ret, "Expected failure\n");
1482 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1483 todo_wine
1485 ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
1486 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
1487 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1490 /* TODO: Create a test that makes sure we enumerate all services that don't
1491 * belong to a group. (specifying "").
1494 /* All parameters are correct. Request the needed buffer size */
1495 needed = 0xdeadbeef;
1496 returned = 0xdeadbeef;
1497 SetLastError(0xdeadbeef);
1498 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1499 NULL, 0, &needed, &returned, NULL, NULL);
1500 ok(!ret, "Expected failure\n");
1501 ok(returned == 0, "Expected no service returned, got %d\n", returned);
1502 todo_wine
1504 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1505 ok(GetLastError() == ERROR_MORE_DATA,
1506 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1509 /* Store the needed bytes */
1510 tempneeded = needed;
1512 /* Allocate the correct needed bytes */
1513 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1514 bufsize = needed;
1515 needed = 0xdeadbeef;
1516 returned = 0xdeadbeef;
1517 SetLastError(0xdeadbeef);
1518 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1519 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1520 todo_wine
1522 ok(ret, "Expected success, got error %u\n", GetLastError());
1523 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1524 ok(returned == tempreturned, "Expected the same number of service from this function\n");
1526 HeapFree(GetProcessHeap(), 0, exservices);
1528 /* Store the number of returned services */
1529 tempreturned = returned;
1531 /* Allocate less than the needed bytes and don't specify a resume handle */
1532 exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1533 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1534 needed = 0xdeadbeef;
1535 returned = 0xdeadbeef;
1536 SetLastError(0xdeadbeef);
1537 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1538 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1539 ok(!ret, "Expected failure\n");
1540 todo_wine
1542 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1543 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1544 ok(GetLastError() == ERROR_MORE_DATA,
1545 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1548 /* Allocate less than the needed bytes, this time with a correct resume handle */
1549 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1550 needed = 0xdeadbeef;
1551 returned = 0xdeadbeef;
1552 resume = 0;
1553 SetLastError(0xdeadbeef);
1554 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1555 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1556 ok(!ret, "Expected failure\n");
1557 todo_wine
1559 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1560 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1561 ok(resume, "Expected a resume handle\n");
1562 ok(GetLastError() == ERROR_MORE_DATA,
1563 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1566 /* Fetch that last service but pass a bigger buffer size */
1567 missing = tempreturned - returned;
1568 bufsize = tempneeded;
1569 needed = 0xdeadbeef;
1570 returned = 0xdeadbeef;
1571 SetLastError(0xdeadbeef);
1572 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1573 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1574 todo_wine
1576 ok(ret, "Expected success, got error %u\n", GetLastError());
1577 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1579 ok(returned == missing, "Expected %u services to be returned\n", missing);
1580 ok(resume == 0, "Expected the resume handle to be 0\n");
1581 HeapFree(GetProcessHeap(), 0, exservices);
1583 /* See if things add up */
1585 /* Get the number of active win32 services */
1586 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1587 NULL, 0, &needed, &returned, NULL, NULL);
1588 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1589 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1590 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1591 HeapFree(GetProcessHeap(), 0, exservices);
1593 servicecountactive = returned;
1595 /* Get the number of inactive win32 services */
1596 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1597 NULL, 0, &needed, &returned, NULL, NULL);
1598 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1599 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1600 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1601 HeapFree(GetProcessHeap(), 0, exservices);
1603 servicecountinactive = returned;
1605 /* Get the number of win32 services */
1606 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1607 NULL, 0, &needed, &returned, NULL, NULL);
1608 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1609 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1610 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1611 HeapFree(GetProcessHeap(), 0, exservices);
1613 /* Check if total is the same as active and inactive win32 services */
1614 ok(returned == (servicecountactive + servicecountinactive),
1615 "Something wrong in the calculation\n");
1617 /* Get all drivers and services */
1618 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1619 SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
1620 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1621 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1622 SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1624 /* Loop through all those returned drivers and services */
1625 for (i = 0; i < returned; i++)
1627 SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
1630 /* lpServiceName and lpDisplayName should always be filled */
1631 ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n");
1632 ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n");
1634 /* Decrement the counters to see if the functions calls return the
1635 * same numbers as the contents of these structures.
1636 * Check some process id specifics.
1638 if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
1640 /* We shouldn't have a process id for drivers */
1641 ok(status.dwProcessId == 0,
1642 "This driver shouldn't have an associated process id\n");
1645 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1647 if (status.dwCurrentState == SERVICE_RUNNING)
1649 /* We expect a process id for every running service */
1650 ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n",
1651 exservices[i].lpServiceName);
1653 servicecountactive--;
1655 else
1657 /* We shouldn't have a process id for inactive services */
1658 ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n",
1659 exservices[i].lpServiceName, status.dwCurrentState);
1661 servicecountinactive--;
1665 HeapFree(GetProcessHeap(), 0, exservices);
1667 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1668 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1670 CloseServiceHandle(scm_handle);
1673 static void test_close(void)
1675 SC_HANDLE handle;
1676 BOOL ret;
1678 /* NULL handle */
1679 SetLastError(0xdeadbeef);
1680 ret = CloseServiceHandle(NULL);
1681 ok(!ret, "Expected failure\n");
1682 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1684 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1686 /* Proper call */
1687 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1688 SetLastError(0xdeadbeef);
1689 ret = CloseServiceHandle(handle);
1690 ok(ret, "Expected success got error %u\n", GetLastError());
1693 static void test_sequence(void)
1695 SC_HANDLE scm_handle, svc_handle;
1696 BOOL ret;
1697 QUERY_SERVICE_CONFIGA *config;
1698 DWORD given, needed;
1699 static const CHAR servicename [] = "Winetest";
1700 static const CHAR displayname [] = "Winetest dummy service";
1701 static const CHAR displayname2[] = "Winetest dummy service (2)";
1702 static const CHAR pathname [] = "we_dont_care.exe";
1703 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1704 static const CHAR password [] = "";
1705 static const CHAR empty [] = "";
1706 static const CHAR localsystem [] = "LocalSystem";
1708 SetLastError(0xdeadbeef);
1709 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1711 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1713 skip("Not enough rights to get a handle to the manager\n");
1714 return;
1716 else
1717 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
1719 if (!scm_handle) return;
1721 /* Create a dummy service */
1722 SetLastError(0xdeadbeef);
1723 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1724 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1725 pathname, NULL, NULL, dependencies, NULL, password);
1727 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
1729 /* We try and open the service and do the rest of the tests. Some could
1730 * fail if the tests were changed between these runs.
1732 trace("Deletion probably didn't work last time\n");
1733 SetLastError(0xdeadbeef);
1734 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1735 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1737 skip("Not enough rights to open the service\n");
1738 CloseServiceHandle(scm_handle);
1739 return;
1741 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
1743 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1745 skip("Not enough rights to create the service\n");
1746 CloseServiceHandle(scm_handle);
1747 return;
1749 else
1751 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1752 if ((svc_handle != NULL) && (pGetSecurityInfo != NULL))
1754 PSID sidOwner, sidGroup;
1755 PACL dacl, sacl;
1756 PSECURITY_DESCRIPTOR pSD;
1757 HRESULT retval = pGetSecurityInfo(svc_handle,SE_SERVICE,DACL_SECURITY_INFORMATION,&sidOwner,&sidGroup,&dacl,&sacl,&pSD);
1758 todo_wine ok(ERROR_SUCCESS == retval, "Expected GetSecurityInfo to succeed: result %d\n",retval);
1762 if (!svc_handle) return;
1764 /* TODO:
1765 * Before we do a QueryServiceConfig we should check the registry. This will make sure
1766 * that the correct keys are used.
1769 /* Request the size for the buffer */
1770 SetLastError(0xdeadbeef);
1771 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1772 ok(!ret, "Expected failure\n");
1773 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1775 config = HeapAlloc(GetProcessHeap(), 0, needed);
1776 given = needed;
1777 SetLastError(0xdeadbeef);
1778 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
1779 ok(ret, "Expected success, got error %u\n", GetLastError());
1781 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1782 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1783 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1784 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1785 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1786 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
1787 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1788 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
1789 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1790 /* TODO: Show the double 0 terminated string */
1791 todo_wine
1793 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
1795 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1796 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
1798 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
1799 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1801 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1802 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
1803 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
1804 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1805 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1806 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1807 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1808 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1809 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
1810 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1811 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
1812 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1813 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1814 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
1816 SetLastError(0xdeadbeef);
1817 ret = DeleteService(svc_handle);
1818 ok(ret, "Expected success, got error %u\n", GetLastError());
1819 CloseServiceHandle(svc_handle);
1821 /* Wait a while. The following test does a CreateService again */
1822 Sleep(1000);
1824 CloseServiceHandle(scm_handle);
1825 HeapFree(GetProcessHeap(), 0, config);
1828 static void test_queryconfig2(void)
1830 SC_HANDLE scm_handle, svc_handle;
1831 BOOL ret;
1832 DWORD expected, needed;
1833 BYTE buffer[MAX_PATH];
1834 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
1835 static const CHAR servicename [] = "Winetest";
1836 static const CHAR displayname [] = "Winetest dummy service";
1837 static const CHAR pathname [] = "we_dont_care.exe";
1838 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1839 static const CHAR password [] = "";
1840 static const CHAR description [] = "Description";
1842 if(!pQueryServiceConfig2A)
1844 win_skip("function QueryServiceConfig2A not present\n");
1845 return;
1848 SetLastError(0xdeadbeef);
1849 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1851 if (!scm_handle)
1853 if(GetLastError() == ERROR_ACCESS_DENIED)
1854 skip("Not enough rights to get a handle to the manager\n");
1855 else
1856 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
1857 return;
1860 /* Create a dummy service */
1861 SetLastError(0xdeadbeef);
1862 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1863 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1864 pathname, NULL, NULL, dependencies, NULL, password);
1866 if (!svc_handle)
1868 if(GetLastError() == ERROR_SERVICE_EXISTS)
1870 /* We try and open the service and do the rest of the tests. Some could
1871 * fail if the tests were changed between these runs.
1873 trace("Deletion probably didn't work last time\n");
1874 SetLastError(0xdeadbeef);
1875 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1876 if (!svc_handle)
1878 if(GetLastError() == ERROR_ACCESS_DENIED)
1879 skip("Not enough rights to open the service\n");
1880 else
1881 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1882 CloseServiceHandle(scm_handle);
1883 return;
1886 if (GetLastError() == ERROR_ACCESS_DENIED)
1888 skip("Not enough rights to create the service\n");
1889 CloseServiceHandle(scm_handle);
1890 return;
1892 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1893 if (!svc_handle)
1895 CloseServiceHandle(scm_handle);
1896 return;
1899 SetLastError(0xdeadbeef);
1900 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1901 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1902 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1904 SetLastError(0xdeadbeef);
1905 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1906 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1907 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1909 SetLastError(0xdeadbeef);
1910 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1911 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1912 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1914 SetLastError(0xdeadbeef);
1915 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1916 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1917 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1918 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1920 SetLastError(0xdeadbeef);
1921 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1922 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1923 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1925 needed = 0;
1926 SetLastError(0xdeadbeef);
1927 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1928 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1929 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1930 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1932 needed = 0;
1933 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1934 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1935 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1936 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1937 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1939 SetLastError(0xdeadbeef);
1940 needed = 0;
1941 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1942 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1943 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1944 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1946 if(!pChangeServiceConfig2A)
1948 win_skip("function ChangeServiceConfig2A not present\n");
1949 goto cleanup;
1952 pConfig->lpDescription = (LPSTR) description;
1953 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1954 ok(ret, "ChangeServiceConfig2A failed\n");
1955 if (!ret) {
1956 goto cleanup;
1959 SetLastError(0xdeadbeef);
1960 needed = 0;
1961 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1962 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1963 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1964 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1965 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1967 SetLastError(0xdeadbeef);
1968 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1969 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1970 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1972 SetLastError(0xdeadbeef);
1973 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1974 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1975 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1976 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1978 SetLastError(0xdeadbeef);
1979 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1980 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1981 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1982 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1984 if(!pQueryServiceConfig2W)
1986 win_skip("function QueryServiceConfig2W not present\n");
1987 goto cleanup;
1989 SetLastError(0xdeadbeef);
1990 needed = 0;
1991 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1992 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1993 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1994 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1995 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1997 SetLastError(0xdeadbeef);
1998 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1999 ok(ret, "expected QueryServiceConfig2W to succeed\n");
2001 cleanup:
2002 DeleteService(svc_handle);
2004 CloseServiceHandle(svc_handle);
2006 /* Wait a while. The following test does a CreateService again */
2007 Sleep(1000);
2009 CloseServiceHandle(scm_handle);
2012 static void test_refcount(void)
2014 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
2015 static const CHAR servicename [] = "Winetest";
2016 static const CHAR pathname [] = "we_dont_care.exe";
2017 BOOL ret;
2019 /* Get a handle to the Service Control Manager */
2020 SetLastError(0xdeadbeef);
2021 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2022 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
2024 skip("Not enough rights to get a handle to the manager\n");
2025 return;
2028 /* Create a service */
2029 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2030 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2031 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2032 ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError());
2034 /* Get a handle to this new service */
2035 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2036 ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError());
2038 /* Get another handle to this new service */
2039 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2040 ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError());
2042 /* Check if we can close the handle to the Service Control Manager */
2043 ret = CloseServiceHandle(scm_handle);
2044 ok(ret, "Expected success (err=%d)\n", GetLastError());
2046 /* Get a new handle to the Service Control Manager */
2047 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2048 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
2050 /* Get a handle to this new service */
2051 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
2052 ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError());
2054 /* Delete the service */
2055 ret = DeleteService(svc_handle4);
2056 ok(ret, "Expected success (err=%d)\n", GetLastError());
2058 /* We cannot create the same service again as it's still marked as 'being deleted'.
2059 * The reason is that we still have 4 open handles to this service even though we
2060 * closed the handle to the Service Control Manager in between.
2062 SetLastError(0xdeadbeef);
2063 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2064 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2065 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2066 todo_wine
2068 ok(!svc_handle5, "Expected failure\n");
2069 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
2070 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2073 /* FIXME: Remove this when Wine is fixed */
2074 if (svc_handle5)
2076 DeleteService(svc_handle5);
2077 CloseServiceHandle(svc_handle5);
2080 /* Close all the handles to the service and try again */
2081 ret = CloseServiceHandle(svc_handle4);
2082 ok(ret, "Expected success (err=%d)\n", GetLastError());
2083 ret = CloseServiceHandle(svc_handle3);
2084 ok(ret, "Expected success (err=%d)\n", GetLastError());
2085 ret = CloseServiceHandle(svc_handle2);
2086 ok(ret, "Expected success (err=%d)\n", GetLastError());
2087 ret = CloseServiceHandle(svc_handle1);
2088 ok(ret, "Expected success (err=%d)\n", GetLastError());
2090 /* Wait a while. Doing a CreateService too soon will result again
2091 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2093 Sleep(1000);
2095 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2096 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2097 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2098 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2099 ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError());
2101 /* Delete the service */
2102 ret = DeleteService(svc_handle5);
2103 ok(ret, "Expected success (err=%d)\n", GetLastError());
2105 /* Wait a while. Just in case one of the following tests does a CreateService again */
2106 Sleep(1000);
2108 CloseServiceHandle(svc_handle5);
2109 CloseServiceHandle(scm_handle);
2112 START_TEST(service)
2114 SC_HANDLE scm_handle;
2116 /* Bail out if we are on win98 */
2117 SetLastError(0xdeadbeef);
2118 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2120 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2122 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2123 return;
2125 CloseServiceHandle(scm_handle);
2127 init_function_pointers();
2129 /* First some parameter checking */
2130 test_open_scm();
2131 test_open_svc();
2132 test_create_delete_svc();
2133 test_get_displayname();
2134 test_get_servicekeyname();
2135 test_query_svc();
2136 test_enum_svc();
2137 test_close();
2138 /* Test the creation, querying and deletion of a service */
2139 test_sequence();
2140 test_queryconfig2();
2141 /* The main reason for this test is to check if any refcounting is used
2142 * and what the rules are
2144 test_refcount();