push e1d8a1293d44015bb0894687d02c5c53339996f7
[wine/hacks.git] / dlls / advapi32 / tests / service.c
blobb924c69d3d4c97baf30d752c46da99957b686405
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"
32 #include "wine/test.h"
34 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
36 static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
37 static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
38 DWORD, LPBYTE, DWORD, LPDWORD,
39 LPDWORD, LPDWORD, LPCSTR);
40 static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
41 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
42 static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
43 DWORD, LPDWORD);
45 static void init_function_pointers(void)
47 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
49 pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A");
50 pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA");
51 pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
52 pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
53 pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
56 static void test_open_scm(void)
58 SC_HANDLE scm_handle;
60 /* No access rights */
61 SetLastError(0xdeadbeef);
62 scm_handle = OpenSCManagerA(NULL, NULL, 0);
63 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
64 CloseServiceHandle(scm_handle);
66 /* Unknown database name */
67 SetLastError(0xdeadbeef);
68 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
69 ok(!scm_handle, "Expected failure\n");
70 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
71 CloseServiceHandle(scm_handle); /* Just in case */
73 /* MSDN says only ServiceActive is allowed, or NULL */
74 SetLastError(0xdeadbeef);
75 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
76 ok(!scm_handle, "Expected failure\n");
77 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
78 CloseServiceHandle(scm_handle); /* Just in case */
80 /* Remote unknown host */
81 SetLastError(0xdeadbeef);
82 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
83 todo_wine
85 ok(!scm_handle, "Expected failure\n");
86 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
87 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
89 CloseServiceHandle(scm_handle); /* Just in case */
91 /* Proper call with an empty hostname */
92 SetLastError(0xdeadbeef);
93 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
94 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
95 CloseServiceHandle(scm_handle);
97 /* Again a correct one */
98 SetLastError(0xdeadbeef);
99 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
100 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
101 CloseServiceHandle(scm_handle);
104 static void test_open_svc(void)
106 SC_HANDLE scm_handle, svc_handle;
107 CHAR displayname[4096];
108 DWORD displaysize;
110 /* All NULL (invalid access rights) */
111 SetLastError(0xdeadbeef);
112 svc_handle = OpenServiceA(NULL, NULL, 0);
113 ok(!svc_handle, "Expected failure\n");
114 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
116 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
118 /* NULL service */
119 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
120 SetLastError(0xdeadbeef);
121 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
122 ok(!svc_handle, "Expected failure\n");
123 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
124 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
125 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
127 /* Nonexistent service */
128 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
129 SetLastError(0xdeadbeef);
130 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
131 ok(!svc_handle, "Expected failure\n");
132 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
133 CloseServiceHandle(scm_handle);
135 /* Proper SCM handle but different access rights */
136 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
137 SetLastError(0xdeadbeef);
138 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
139 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
140 skip("Not enough rights to get a handle to the service\n");
141 else
143 ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError());
144 CloseServiceHandle(svc_handle);
147 /* Test to show we can't open a service with the displayname */
149 /* Retrieve the needed size for the buffer */
150 displaysize = 0;
151 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
152 /* Get the displayname */
153 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
154 /* Try to open the service with this displayname, unless the displayname equals
155 * the servicename as that would defeat the purpose of this test.
157 if (!lstrcmpi(spooler, displayname))
159 skip("displayname equals servicename\n");
160 CloseServiceHandle(scm_handle);
161 return;
164 SetLastError(0xdeadbeef);
165 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
166 ok(!svc_handle, "Expected failure\n");
167 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
168 /* Just in case */
169 CloseServiceHandle(svc_handle);
171 CloseServiceHandle(scm_handle);
174 static void test_create_delete_svc(void)
176 SC_HANDLE scm_handle, svc_handle1;
177 CHAR username[UNLEN + 1], domain[MAX_PATH];
178 DWORD user_size = UNLEN + 1;
179 CHAR account[UNLEN + 3];
180 static const CHAR servicename [] = "Winetest";
181 static const CHAR pathname [] = "we_dont_care.exe";
182 static const CHAR empty [] = "";
183 static const CHAR password [] = "secret";
184 BOOL spooler_exists = FALSE;
185 BOOL ret;
186 CHAR display[4096];
187 DWORD display_size = sizeof(display);
189 /* Get the username and turn it into an account to be used in some tests */
190 GetUserNameA(username, &user_size);
191 /* Get the domainname to cater for that situation */
192 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
193 sprintf(account, "%s\\%s", domain, username);
194 else
195 sprintf(account, ".\\%s", username);
197 /* All NULL */
198 SetLastError(0xdeadbeef);
199 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
200 ok(!svc_handle1, "Expected failure\n");
201 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
203 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
205 /* Only a valid handle to the Service Control Manager */
206 SetLastError(0xdeadbeef);
207 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
208 ok(!svc_handle1, "Expected failure\n");
209 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
210 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
211 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
213 /* Now with a servicename */
214 SetLastError(0xdeadbeef);
215 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
216 ok(!svc_handle1, "Expected failure\n");
217 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
218 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
219 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
221 /* Or just a binary name */
222 SetLastError(0xdeadbeef);
223 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
224 ok(!svc_handle1, "Expected failure\n");
225 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
226 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
227 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
229 /* Both servicename and binary name (We only have connect rights) */
230 SetLastError(0xdeadbeef);
231 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
232 ok(!svc_handle1, "Expected failure\n");
233 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
235 /* They can even be empty at this stage of parameter checking */
236 SetLastError(0xdeadbeef);
237 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
238 ok(!svc_handle1, "Expected failure\n");
239 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
241 SetLastError(0xdeadbeef);
242 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
243 ok(!svc_handle1, "Expected failure\n");
244 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
246 /* Open the Service Control Manager with minimal rights for creation
247 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
249 CloseServiceHandle(scm_handle);
250 SetLastError(0xdeadbeef);
251 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
252 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
254 skip("Not enough rights to get a handle to the manager\n");
255 return;
258 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
260 /* Empty strings for servicename and binary name are checked */
261 SetLastError(0xdeadbeef);
262 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
263 ok(!svc_handle1, "Expected failure\n");
264 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
266 SetLastError(0xdeadbeef);
267 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
268 ok(!svc_handle1, "Expected failure\n");
269 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
271 SetLastError(0xdeadbeef);
272 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
273 ok(!svc_handle1, "Expected failure\n");
274 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
276 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
277 * an ERROR_INVALID_PARAMETER)
279 SetLastError(0xdeadbeef);
280 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
281 SERVICE_DISABLED, 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 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
287 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
288 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
290 SetLastError(0xdeadbeef);
291 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
292 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
293 ok(!svc_handle1, "Expected failure\n");
294 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
296 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
297 SetLastError(0xdeadbeef);
298 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
299 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
300 ok(!svc_handle1, "Expected failure\n");
301 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
303 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
304 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
306 SetLastError(0xdeadbeef);
307 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
308 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
309 ok(!svc_handle1, "Expected failure\n");
310 ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT,
311 "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError());
313 /* Illegal (start-type is not a mask and should only be one of the possibilities)
314 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
315 * it's most likely not the wanted start-type)
317 SetLastError(0xdeadbeef);
318 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
319 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
320 ok(!svc_handle1, "Expected failure\n");
321 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
323 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
324 SetLastError(0xdeadbeef);
325 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
326 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
327 ok(!svc_handle1, "Expected failure\n");
328 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
330 /* The service already exists (check first, just in case) */
331 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
332 if (svc_handle1)
334 spooler_exists = TRUE;
335 CloseServiceHandle(svc_handle1);
336 SetLastError(0xdeadbeef);
337 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
338 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
339 ok(!svc_handle1, "Expected failure\n");
340 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
342 else
343 skip("Spooler service doesn't exist\n");
345 /* To find an existing displayname we check the 'Spooler' service. Although the registry
346 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
347 * to the servicename and can't be used as well for a new displayname.
349 if (spooler_exists)
351 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
353 if (!ret)
354 skip("Could not retrieve a displayname for the Spooler service\n");
355 else
357 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
358 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
359 ok(!svc_handle1, "Expected failure\n");
360 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
361 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
364 else
365 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
367 /* Windows doesn't care about the access rights for creation (which makes
368 * sense as there is no service yet) as long as there are sufficient
369 * rights to the manager.
371 SetLastError(0xdeadbeef);
372 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
373 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
374 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
376 /* DeleteService however must have proper rights */
377 SetLastError(0xdeadbeef);
378 ret = DeleteService(svc_handle1);
379 ok(!ret, "Expected failure\n");
380 ok(GetLastError() == ERROR_ACCESS_DENIED,
381 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
383 /* Open the service with minimal rights for deletion.
384 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
386 CloseServiceHandle(svc_handle1);
387 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
389 /* Now that we have the proper rights, we should be able to delete */
390 SetLastError(0xdeadbeef);
391 ret = DeleteService(svc_handle1);
392 ok(ret, "Expected success, got error %u\n", GetLastError());
394 CloseServiceHandle(svc_handle1);
395 CloseServiceHandle(scm_handle);
397 /* Wait a while. One of the following tests also does a CreateService for the
398 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
399 * error if we do this to quick. Vista seems more picky then the others.
401 Sleep(1000);
403 /* And a final NULL check */
404 SetLastError(0xdeadbeef);
405 ret = DeleteService(NULL);
406 ok(!ret, "Expected failure\n");
407 ok(GetLastError() == ERROR_INVALID_HANDLE,
408 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
411 static void test_get_displayname(void)
413 SC_HANDLE scm_handle, svc_handle;
414 BOOL ret;
415 CHAR displayname[4096];
416 WCHAR displaynameW[2048];
417 DWORD displaysize, tempsize, tempsizeW;
418 static const CHAR deadbeef[] = "Deadbeef";
419 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
420 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
421 static const WCHAR abcW[] = {'A','B','C',0};
422 static const CHAR servicename[] = "Winetest";
423 static const CHAR pathname[] = "we_dont_care.exe";
425 /* Having NULL for the size of the buffer will crash on W2K3 */
427 SetLastError(0xdeadbeef);
428 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
429 ok(!ret, "Expected failure\n");
430 ok(GetLastError() == ERROR_INVALID_HANDLE,
431 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
433 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
435 SetLastError(0xdeadbeef);
436 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
437 ok(!ret, "Expected failure\n");
438 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
439 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
440 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
442 SetLastError(0xdeadbeef);
443 displaysize = sizeof(displayname);
444 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
445 ok(!ret, "Expected failure\n");
446 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
447 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
448 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
450 /* Test for nonexistent service */
451 SetLastError(0xdeadbeef);
452 displaysize = -1;
453 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
454 ok(!ret, "Expected failure\n");
455 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
456 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
458 SetLastError(0xdeadbeef);
459 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
460 ok(!ret, "Expected failure\n");
461 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
462 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
463 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
465 displaysize = 15;
466 strcpy(displayname, "ABC");
467 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
468 ok(!ret, "Expected failure\n");
469 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
470 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
471 todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
472 ok(displayname[0] == 0, "Service name not empty\n");
474 displaysize = 15;
475 lstrcpyW( displaynameW, abcW );
476 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
477 ok(!ret, "Expected failure\n");
478 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
479 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
480 ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
481 ok(displaynameW[0] == 0, "Service name not empty\n");
483 displaysize = 0;
484 strcpy(displayname, "ABC");
485 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
486 ok(!ret, "Expected failure\n");
487 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
488 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
489 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
490 ok(displayname[0] == 'A', "Service name changed\n");
492 displaysize = 0;
493 lstrcpyW( displaynameW, abcW );
494 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
495 ok(!ret, "Expected failure\n");
496 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
497 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
498 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
499 ok(displaynameW[0] == 'A', "Service name changed\n");
501 displaysize = 1;
502 strcpy(displayname, "ABC");
503 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
504 ok(!ret, "Expected failure\n");
505 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
506 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
507 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
508 ok(displayname[0] == 0, "Service name not empty\n");
510 displaysize = 1;
511 lstrcpyW( displaynameW, abcW );
512 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
513 ok(!ret, "Expected failure\n");
514 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
515 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
516 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
517 ok(displaynameW[0] == 'A', "Service name changed\n");
519 displaysize = 2;
520 strcpy(displayname, "ABC");
521 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
522 ok(!ret, "Expected failure\n");
523 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
524 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
525 todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
526 ok(displayname[0] == 0, "Service name not empty\n");
528 displaysize = 2;
529 lstrcpyW( displaynameW, abcW );
530 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
531 ok(!ret, "Expected failure\n");
532 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
533 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
534 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
535 ok(displaynameW[0] == 0, "Service name not empty\n");
537 /* Check if 'Spooler' exists */
538 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
539 if (!svc_handle)
541 skip("Spooler service doesn't exist\n");
542 CloseServiceHandle(scm_handle);
543 return;
545 CloseServiceHandle(svc_handle);
547 /* Retrieve the needed size for the buffer */
548 SetLastError(0xdeadbeef);
549 displaysize = -1;
550 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
551 ok(!ret, "Expected failure\n");
552 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
553 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
554 tempsize = displaysize;
556 displaysize = 0;
557 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
558 ok(!ret, "Expected failure\n");
559 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
560 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
561 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
563 /* Buffer is too small */
564 SetLastError(0xdeadbeef);
565 displaysize = (tempsize / 2);
566 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
567 ok(!ret, "Expected failure\n");
568 ok(displaysize == tempsize, "Expected the needed buffersize\n");
569 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
570 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
572 /* First try with a buffer that should be big enough to hold
573 * the ANSI string (and terminating character). This succeeds on Windows
574 * although when asked (see above 2 tests) it will return twice the needed size.
576 SetLastError(0xdeadbeef);
577 displaysize = (tempsize / 2) + 1;
578 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
579 ok(ret, "Expected success, got error %u\n", GetLastError());
580 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
582 /* Now with the original returned size */
583 SetLastError(0xdeadbeef);
584 displaysize = tempsize;
585 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
586 ok(ret, "Expected success, got error %u\n", GetLastError());
587 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
589 /* And with a bigger than needed buffer */
590 SetLastError(0xdeadbeef);
591 displaysize = tempsize * 2;
592 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
593 ok(ret, "Expected success, got error %u\n", GetLastError());
594 /* Test that shows that if the buffersize is enough, it's not changed */
595 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
596 ok(lstrlen(displayname) == tempsize/2,
597 "Expected the buffer to be twice the length of the string\n") ;
599 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
600 SetLastError(0xdeadbeef);
601 displaysize = -1;
602 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
603 ok(!ret, "Expected failure\n");
604 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
605 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
607 /* Buffer is too small */
608 SetLastError(0xdeadbeef);
609 tempsizeW = displaysize;
610 displaysize = tempsizeW / 2;
611 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
612 ok(!ret, "Expected failure\n");
613 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
614 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
615 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
617 /* Now with the original returned size */
618 SetLastError(0xdeadbeef);
619 displaysize = tempsizeW;
620 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
621 ok(!ret, "Expected failure\n");
622 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
623 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
624 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
626 /* And with a bigger than needed buffer */
627 SetLastError(0xdeadbeef);
628 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
629 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
630 ok(ret, "Expected success, got error %u\n", GetLastError());
631 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
632 ok(lstrlenW(displaynameW) == displaysize,
633 "Expected the buffer to be the length of the string\n") ;
634 ok(tempsize / 2 == tempsizeW,
635 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
637 CloseServiceHandle(scm_handle);
639 /* Test for a service without a displayname (which is valid). This should return
640 * the servicename itself.
642 SetLastError(0xdeadbeef);
643 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
644 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
646 skip("Not enough rights to get a handle to the manager\n");
647 return;
650 SetLastError(0xdeadbeef);
651 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
652 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
653 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
654 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
655 if (!svc_handle)
657 CloseServiceHandle(scm_handle);
658 return;
661 /* Retrieve the needed size for the buffer */
662 SetLastError(0xdeadbeef);
663 displaysize = -1;
664 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
665 ok(!ret, "Expected failure\n");
666 ok(displaysize == lstrlen(servicename) * 2,
667 "Expected the displaysize to be twice the size of the servicename\n");
668 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
669 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
671 /* Buffer is too small */
672 SetLastError(0xdeadbeef);
673 tempsize = displaysize;
674 displaysize = (tempsize / 2);
675 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
676 ok(!ret, "Expected failure\n");
677 ok(displaysize == tempsize, "Expected the needed buffersize\n");
678 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
679 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
681 /* Get the displayname */
682 SetLastError(0xdeadbeef);
683 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
684 ok(ret, "Expected success, got error %u\n", GetLastError());
685 ok(!lstrcmpi(displayname, servicename),
686 "Expected displayname to be %s, got %s\n", servicename, displayname);
688 /* Delete the service */
689 ret = DeleteService(svc_handle);
690 ok(ret, "Expected success (err=%d)\n", GetLastError());
692 CloseServiceHandle(svc_handle);
693 CloseServiceHandle(scm_handle);
695 /* Wait a while. Just in case one of the following tests does a CreateService again */
696 Sleep(1000);
699 static void test_get_servicekeyname(void)
701 SC_HANDLE scm_handle, svc_handle;
702 CHAR servicename[4096];
703 CHAR displayname[4096];
704 WCHAR servicenameW[4096];
705 WCHAR displaynameW[4096];
706 DWORD servicesize, displaysize, tempsize;
707 BOOL ret;
708 static const CHAR deadbeef[] = "Deadbeef";
709 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
710 static const WCHAR abcW[] = {'A','B','C',0};
712 /* Having NULL for the size of the buffer will crash on W2K3 */
714 SetLastError(0xdeadbeef);
715 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
716 ok(!ret, "Expected failure\n");
717 ok(GetLastError() == ERROR_INVALID_HANDLE,
718 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
720 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
722 servicesize = 200;
723 SetLastError(0xdeadbeef);
724 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
725 ok(!ret, "Expected failure\n");
726 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
727 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
728 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
729 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
731 /* Valid handle and buffer but no displayname */
732 servicesize = 200;
733 SetLastError(0xdeadbeef);
734 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
735 ok(!ret, "Expected failure\n");
736 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
737 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
738 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
739 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
741 /* Test for nonexistent displayname */
742 SetLastError(0xdeadbeef);
743 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
744 ok(!ret, "Expected failure\n");
745 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
746 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
747 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
749 servicesize = 15;
750 strcpy(servicename, "ABC");
751 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
752 ok(!ret, "Expected failure\n");
753 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
754 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
755 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
756 ok(servicename[0] == 0, "Service name not empty\n");
758 servicesize = 15;
759 lstrcpyW( servicenameW, abcW );
760 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
761 ok(!ret, "Expected failure\n");
762 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
763 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
764 ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
765 ok(servicenameW[0] == 0, "Service name not empty\n");
767 servicesize = 0;
768 strcpy(servicename, "ABC");
769 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
770 ok(!ret, "Expected failure\n");
771 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
772 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
773 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
774 ok(servicename[0] == 'A', "Service name changed\n");
776 servicesize = 0;
777 lstrcpyW( servicenameW, abcW );
778 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
779 ok(!ret, "Expected failure\n");
780 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
781 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
782 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
783 ok(servicenameW[0] == 'A', "Service name changed\n");
785 servicesize = 1;
786 strcpy(servicename, "ABC");
787 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
788 ok(!ret, "Expected failure\n");
789 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
790 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
791 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
792 ok(servicename[0] == 0, "Service name not empty\n");
794 servicesize = 1;
795 lstrcpyW( servicenameW, abcW );
796 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
797 ok(!ret, "Expected failure\n");
798 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
799 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
800 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
801 ok(servicenameW[0] == 'A', "Service name changed\n");
803 servicesize = 2;
804 strcpy(servicename, "ABC");
805 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
806 ok(!ret, "Expected failure\n");
807 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
808 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
809 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
810 ok(servicename[0] == 0, "Service name not empty\n");
812 servicesize = 2;
813 lstrcpyW( servicenameW, abcW );
814 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
815 ok(!ret, "Expected failure\n");
816 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
817 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
818 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
819 ok(servicenameW[0] == 0, "Service name not empty\n");
821 /* Check if 'Spooler' exists */
822 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
823 if (!svc_handle)
825 skip("Spooler service doesn't exist\n");
826 CloseServiceHandle(scm_handle);
827 return;
829 CloseServiceHandle(svc_handle);
831 /* Get the displayname for the 'Spooler' service */
832 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
833 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
835 /* Retrieve the needed size for the buffer */
836 SetLastError(0xdeadbeef);
837 servicesize = 0;
838 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
839 ok(!ret, "Expected failure\n");
840 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
841 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
843 /* Valid call with the correct buffersize */
844 SetLastError(0xdeadbeef);
845 tempsize = servicesize;
846 servicesize *= 2;
847 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
848 ok(ret, "Expected success, got error %u\n", GetLastError());
849 if (ret)
851 ok(lstrlen(servicename) == tempsize/2,
852 "Expected the buffer to be twice the length of the string\n") ;
853 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
854 ok(servicesize == (tempsize * 2),
855 "Expected servicesize not to change if buffer not insufficient\n") ;
858 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
859 SetLastError(0xdeadbeef);
860 servicesize *= 2;
861 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
862 ok(ret, "Expected success, got error %u\n", GetLastError());
863 if (ret)
865 ok(lstrlen(servicename) == tempsize/2,
866 "Expected the buffer to be twice the length of the string\n") ;
867 ok(servicesize == lstrlenW(servicenameW),
868 "Expected servicesize not to change if buffer not insufficient\n") ;
871 SetLastError(0xdeadbeef);
872 servicesize = 3;
873 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
874 ok(!ret, "Expected failure\n");
875 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
876 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
877 ok(servicenameW[0] == 0, "Buffer not empty\n");
879 CloseServiceHandle(scm_handle);
882 static void test_query_svc(void)
884 SC_HANDLE scm_handle, svc_handle;
885 BOOL ret;
886 SERVICE_STATUS status;
887 SERVICE_STATUS_PROCESS *statusproc;
888 DWORD bufsize, needed;
890 /* All NULL or wrong */
891 SetLastError(0xdeadbeef);
892 ret = QueryServiceStatus(NULL, NULL);
893 ok(!ret, "Expected failure\n");
894 ok(GetLastError() == ERROR_INVALID_HANDLE,
895 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
897 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
899 /* Check if 'Spooler' exists.
900 * Open with not enough rights to query the status.
902 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
903 if (!svc_handle)
905 skip("Spooler service doesn't exist\n");
906 CloseServiceHandle(scm_handle);
907 return;
910 SetLastError(0xdeadbeef);
911 ret = QueryServiceStatus(svc_handle, NULL);
912 ok(!ret, "Expected failure\n");
913 todo_wine
914 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
915 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
916 "Unexpected last error %d\n", GetLastError());
918 SetLastError(0xdeadbeef);
919 ret = QueryServiceStatus(svc_handle, &status);
920 ok(!ret, "Expected failure\n");
921 ok(GetLastError() == ERROR_ACCESS_DENIED,
922 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
924 /* Open the service with just enough rights.
925 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
927 CloseServiceHandle(svc_handle);
928 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
930 SetLastError(0xdeadbeef);
931 ret = QueryServiceStatus(svc_handle, &status);
932 ok(ret, "Expected success, got error %u\n", GetLastError());
934 CloseServiceHandle(svc_handle);
936 /* More or less the same tests for QueryServiceStatusEx */
938 /* Open service with not enough rights to query the status */
939 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
941 /* All NULL or wrong, this proves that info level is checked first */
942 SetLastError(0xdeadbeef);
943 ret = pQueryServiceStatusEx(NULL, 1, NULL, 0, NULL);
944 ok(!ret, "Expected failure\n");
945 todo_wine
946 ok(GetLastError() == ERROR_INVALID_LEVEL,
947 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
949 /* Passing a NULL parameter for the needed buffer size
950 * will crash on anything but NT4.
953 /* Only info level is correct. It looks like the buffer/size is checked second */
954 SetLastError(0xdeadbeef);
955 ret = pQueryServiceStatusEx(NULL, 0, NULL, 0, &needed);
956 /* NT4 and Wine check the handle first */
957 if (GetLastError() != ERROR_INVALID_HANDLE)
959 ok(!ret, "Expected failure\n");
960 ok(needed == sizeof(SERVICE_STATUS_PROCESS),
961 "Needed buffersize is wrong : %d\n", needed);
962 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
963 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
966 /* Pass a correct buffer and buffersize but a NULL handle */
967 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
968 bufsize = needed;
969 SetLastError(0xdeadbeef);
970 ret = pQueryServiceStatusEx(NULL, 0, (BYTE*)statusproc, bufsize, &needed);
971 ok(!ret, "Expected failure\n");
972 ok(GetLastError() == ERROR_INVALID_HANDLE,
973 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
974 HeapFree(GetProcessHeap(), 0, statusproc);
976 /* Correct handle and info level */
977 SetLastError(0xdeadbeef);
978 ret = pQueryServiceStatusEx(svc_handle, 0, NULL, 0, &needed);
979 /* NT4 doesn't return the needed size */
980 if (GetLastError() != ERROR_INVALID_PARAMETER)
982 ok(!ret, "Expected failure\n");
983 todo_wine
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());
992 /* All parameters are OK but we don't have enough rights */
993 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
994 bufsize = sizeof(SERVICE_STATUS_PROCESS);
995 SetLastError(0xdeadbeef);
996 ret = pQueryServiceStatusEx(svc_handle, 0, (BYTE*)statusproc, bufsize, &needed);
997 ok(!ret, "Expected failure\n");
998 ok(GetLastError() == ERROR_ACCESS_DENIED,
999 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1000 HeapFree(GetProcessHeap(), 0, statusproc);
1002 /* Open the service with just enough rights. */
1003 CloseServiceHandle(svc_handle);
1004 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
1006 /* Everything should be fine now. */
1007 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1008 bufsize = sizeof(SERVICE_STATUS_PROCESS);
1009 SetLastError(0xdeadbeef);
1010 ret = pQueryServiceStatusEx(svc_handle, 0, (BYTE*)statusproc, bufsize, &needed);
1011 ok(ret, "Expected success, got error %u\n", GetLastError());
1012 if (statusproc->dwCurrentState == SERVICE_RUNNING)
1013 ok(statusproc->dwProcessId != 0,
1014 "Expect a process id for this running service\n");
1015 else
1016 ok(statusproc->dwProcessId == 0,
1017 "Expect no process id for this stopped service\n");
1018 HeapFree(GetProcessHeap(), 0, statusproc);
1020 CloseServiceHandle(svc_handle);
1021 CloseServiceHandle(scm_handle);
1024 static void test_enum_svc(void)
1026 SC_HANDLE scm_handle;
1027 BOOL ret;
1028 DWORD bufsize, needed, returned, resume;
1029 DWORD tempneeded, tempreturned, missing;
1030 DWORD servicecountactive, servicecountinactive;
1031 ENUM_SERVICE_STATUS *services;
1032 ENUM_SERVICE_STATUS_PROCESS *exservices;
1033 INT i;
1035 /* All NULL or wrong */
1036 SetLastError(0xdeadbeef);
1037 ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1038 ok(!ret, "Expected failure\n");
1039 todo_wine
1040 ok(GetLastError() == ERROR_INVALID_HANDLE,
1041 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1043 /* Open the service control manager with not enough rights at first */
1044 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1046 /* Valid handle but rest is still NULL or wrong */
1047 SetLastError(0xdeadbeef);
1048 ret = EnumServicesStatusA(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1049 ok(!ret, "Expected failure\n");
1050 todo_wine
1051 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1052 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1053 "Unexpected last error %d\n", GetLastError());
1055 /* Don't specify the two required pointers */
1056 returned = 0xdeadbeef;
1057 SetLastError(0xdeadbeef);
1058 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1059 ok(!ret, "Expected failure\n");
1060 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1061 todo_wine
1062 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1063 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1064 "Unexpected last error %d\n", GetLastError());
1066 /* Don't specify the two required pointers */
1067 needed = 0xdeadbeef;
1068 SetLastError(0xdeadbeef);
1069 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1070 ok(!ret, "Expected failure\n");
1071 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1072 "Expected no change to the needed buffer variable\n");
1073 todo_wine
1074 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1075 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1076 "Unexpected last error %d\n", GetLastError());
1078 /* No valid servicetype and servicestate */
1079 needed = 0xdeadbeef;
1080 returned = 0xdeadbeef;
1081 SetLastError(0xdeadbeef);
1082 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1083 ok(!ret, "Expected failure\n");
1084 todo_wine
1086 ok(needed == 0 || broken(needed != 0), /* nt4 */
1087 "Expected needed buffer size to be set to 0, got %d\n", needed);
1088 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1089 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1090 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1093 /* No valid servicetype and servicestate */
1094 needed = 0xdeadbeef;
1095 returned = 0xdeadbeef;
1096 SetLastError(0xdeadbeef);
1097 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1098 ok(!ret, "Expected failure\n");
1099 todo_wine
1101 ok(needed == 0 || broken(needed != 0), /* nt4 */
1102 "Expected needed buffer size to be set to 0, got %d\n", needed);
1103 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1104 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1105 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1108 /* No valid servicetype and servicestate */
1109 needed = 0xdeadbeef;
1110 returned = 0xdeadbeef;
1111 SetLastError(0xdeadbeef);
1112 ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0,
1113 &needed, &returned, NULL);
1114 ok(!ret, "Expected failure\n");
1115 todo_wine
1117 ok(needed == 0 || broken(needed != 0), /* nt4 */
1118 "Expected needed buffer size to be set to 0, got %d\n", needed);
1119 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1120 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1121 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1124 /* All parameters are correct but our access rights are wrong */
1125 needed = 0xdeadbeef;
1126 returned = 0xdeadbeef;
1127 SetLastError(0xdeadbeef);
1128 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1129 &needed, &returned, NULL);
1130 ok(!ret, "Expected failure\n");
1131 todo_wine
1133 ok(needed == 0 || broken(needed != 0), /* nt4 */
1134 "Expected needed buffer size to be set to 0, got %d\n", needed);
1135 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1137 ok(GetLastError() == ERROR_ACCESS_DENIED,
1138 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1140 /* Open the service control manager with the needed rights */
1141 CloseServiceHandle(scm_handle);
1142 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1144 /* All parameters are correct. Request the needed buffer size */
1145 needed = 0xdeadbeef;
1146 returned = 0xdeadbeef;
1147 SetLastError(0xdeadbeef);
1148 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1149 &needed, &returned, NULL);
1150 ok(!ret, "Expected failure\n");
1151 todo_wine
1153 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1154 ok(returned == 0, "Expected no service returned, got %d\n", returned);
1155 ok(GetLastError() == ERROR_MORE_DATA,
1156 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1159 /* Store the needed bytes */
1160 tempneeded = needed;
1162 /* Allocate the correct needed bytes */
1163 services = HeapAlloc(GetProcessHeap(), 0, needed);
1164 bufsize = needed;
1165 needed = 0xdeadbeef;
1166 returned = 0xdeadbeef;
1167 SetLastError(0xdeadbeef);
1168 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1169 services, bufsize, &needed, &returned, NULL);
1170 todo_wine
1172 ok(ret, "Expected success, got error %u\n", GetLastError());
1173 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1174 ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n");
1176 HeapFree(GetProcessHeap(), 0, services);
1178 /* Store the number of returned services */
1179 tempreturned = returned;
1181 /* Allocate less than the needed bytes and don't specify a resume handle */
1182 services = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1183 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1184 needed = 0xdeadbeef;
1185 returned = 0xdeadbeef;
1186 SetLastError(0xdeadbeef);
1187 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1188 services, bufsize, &needed, &returned, NULL);
1189 ok(!ret, "Expected failure\n");
1190 todo_wine
1192 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1193 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1194 ok(GetLastError() == ERROR_MORE_DATA,
1195 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1198 /* Allocate less than the needed bytes, this time with a correct resume handle */
1199 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1200 needed = 0xdeadbeef;
1201 returned = 0xdeadbeef;
1202 resume = 0;
1203 SetLastError(0xdeadbeef);
1204 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1205 services, bufsize, &needed, &returned, &resume);
1206 ok(!ret, "Expected failure\n");
1207 todo_wine
1209 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1210 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1211 ok(resume, "Expected a resume handle\n");
1212 ok(GetLastError() == ERROR_MORE_DATA,
1213 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1216 /* Fetch the missing services but pass a bigger buffer size */
1217 missing = tempreturned - returned;
1218 bufsize = tempneeded;
1219 needed = 0xdeadbeef;
1220 returned = 0xdeadbeef;
1221 SetLastError(0xdeadbeef);
1222 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1223 services, bufsize, &needed, &returned, &resume);
1224 todo_wine
1226 ok(ret, "Expected success, got error %u\n", GetLastError());
1227 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1228 ok(returned == missing, "Expected %u services to be returned\n", missing);
1230 ok(resume == 0, "Expected the resume handle to be 0\n");
1231 HeapFree(GetProcessHeap(), 0, services);
1233 /* See if things add up */
1235 /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1236 * and doesn't count the others as inactive. This means that Vista could
1237 * show a total that is greater than the sum of active and inactive
1238 * drivers.
1239 * The number of active and inactive drivers is greatly influenced by the
1240 * time when tests are run, immediately after boot or later for example.
1242 * Both reasons make calculations for drivers not so useful
1245 /* Get the number of active win32 services */
1246 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0,
1247 &needed, &returned, NULL);
1248 services = HeapAlloc(GetProcessHeap(), 0, needed);
1249 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services,
1250 needed, &needed, &returned, NULL);
1251 HeapFree(GetProcessHeap(), 0, services);
1253 servicecountactive = returned;
1255 /* Get the number of inactive win32 services */
1256 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0,
1257 &needed, &returned, NULL);
1258 services = HeapAlloc(GetProcessHeap(), 0, needed);
1259 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services,
1260 needed, &needed, &returned, NULL);
1261 HeapFree(GetProcessHeap(), 0, services);
1263 servicecountinactive = returned;
1265 /* Get the number of win32 services */
1266 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1267 &needed, &returned, NULL);
1268 services = HeapAlloc(GetProcessHeap(), 0, needed);
1269 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services,
1270 needed, &needed, &returned, NULL);
1271 HeapFree(GetProcessHeap(), 0, services);
1273 /* Check if total is the same as active and inactive win32 services */
1274 todo_wine
1275 ok(returned == (servicecountactive + servicecountinactive),
1276 "Something wrong in the calculation\n");
1278 /* Get all drivers and services
1280 * Fetch the status of the last call as failing could make the following tests crash
1281 * on Wine (we don't return anything yet).
1283 EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1284 NULL, 0, &needed, &returned, NULL);
1285 services = HeapAlloc(GetProcessHeap(), 0, needed);
1286 ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1287 services, needed, &needed, &returned, NULL);
1289 /* Loop through all those returned drivers and services */
1290 for (i = 0; ret && i < returned; i++)
1292 SERVICE_STATUS status = services[i].ServiceStatus;
1294 /* lpServiceName and lpDisplayName should always be filled */
1295 ok(lstrlenA(services[i].lpServiceName) > 0, "Expected a service name\n");
1296 ok(lstrlenA(services[i].lpDisplayName) > 0, "Expected a display name\n");
1298 /* Decrement the counters to see if the functions calls return the same
1299 * numbers as the contents of these structures.
1301 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1303 if (status.dwCurrentState == SERVICE_RUNNING)
1304 servicecountactive--;
1305 else
1306 servicecountinactive--;
1309 HeapFree(GetProcessHeap(), 0, services);
1311 todo_wine
1313 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1314 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1317 CloseServiceHandle(scm_handle);
1319 /* More or less the same for EnumServicesStatusExA */
1321 /* All NULL or wrong */
1322 SetLastError(0xdeadbeef);
1323 ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1324 ok(!ret, "Expected failure\n");
1325 todo_wine
1326 ok(GetLastError() == ERROR_INVALID_LEVEL,
1327 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1329 /* All NULL or wrong, just the info level is correct */
1330 SetLastError(0xdeadbeef);
1331 ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1332 ok(!ret, "Expected failure\n");
1333 todo_wine
1334 ok(GetLastError() == ERROR_INVALID_HANDLE,
1335 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1337 /* Open the service control manager with not enough rights at first */
1338 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1340 /* Valid handle and info level but rest is still NULL or wrong */
1341 SetLastError(0xdeadbeef);
1342 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1343 ok(!ret, "Expected failure\n");
1344 todo_wine
1345 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1346 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1347 "Unexpected last error %d\n", GetLastError());
1349 /* Don't specify the two required pointers */
1350 needed = 0xdeadbeef;
1351 SetLastError(0xdeadbeef);
1352 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL);
1353 ok(!ret, "Expected failure\n");
1354 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1355 "Expected no change to the needed buffer variable\n");
1356 todo_wine
1357 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1358 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1359 "Unexpected last error %d\n", GetLastError());
1361 /* Don't specify the two required pointers */
1362 returned = 0xdeadbeef;
1363 SetLastError(0xdeadbeef);
1364 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL);
1365 ok(!ret, "Expected failure\n");
1366 todo_wine
1368 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1369 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1370 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1371 "Unexpected last error %d\n", GetLastError());
1374 /* No valid servicetype and servicestate */
1375 needed = 0xdeadbeef;
1376 returned = 0xdeadbeef;
1377 SetLastError(0xdeadbeef);
1378 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL);
1379 ok(!ret, "Expected failure\n");
1380 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1381 todo_wine
1383 ok(needed == 0 || broken(needed != 0), /* nt4 */
1384 "Expected needed buffer size to be set to 0, got %d\n", needed);
1385 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1386 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1389 /* No valid servicestate */
1390 needed = 0xdeadbeef;
1391 returned = 0xdeadbeef;
1392 SetLastError(0xdeadbeef);
1393 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0,
1394 &needed, &returned, NULL, NULL);
1395 ok(!ret, "Expected failure\n");
1396 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1397 todo_wine
1399 ok(needed == 0 || broken(needed != 0), /* nt4 */
1400 "Expected needed buffer size to be set to 0, got %d\n", needed);
1401 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1402 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1405 /* No valid servicetype */
1406 needed = 0xdeadbeef;
1407 returned = 0xdeadbeef;
1408 SetLastError(0xdeadbeef);
1409 ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0,
1410 &needed, &returned, NULL, NULL);
1411 ok(!ret, "Expected failure\n");
1412 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1413 todo_wine
1415 ok(needed == 0 || broken(needed != 0), /* nt4 */
1416 "Expected needed buffer size to be set to 0, got %d\n", needed);
1417 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1418 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1421 /* No valid servicetype and servicestate and unknown service group */
1422 needed = 0xdeadbeef;
1423 returned = 0xdeadbeef;
1424 SetLastError(0xdeadbeef);
1425 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed,
1426 &returned, NULL, "deadbeef_group");
1427 ok(!ret, "Expected failure\n");
1428 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1429 todo_wine
1431 ok(needed == 0 || broken(needed != 0), /* nt4 */
1432 "Expected needed buffer size to be set to 0, got %d\n", needed);
1433 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1434 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1437 /* All parameters are correct but our access rights are wrong */
1438 needed = 0xdeadbeef;
1439 returned = 0xdeadbeef;
1440 SetLastError(0xdeadbeef);
1441 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1442 NULL, 0, &needed, &returned, NULL, NULL);
1443 ok(!ret, "Expected failure\n");
1444 todo_wine
1445 ok(needed == 0 || broken(needed != 0), /* nt4 */
1446 "Expected needed buffer size to be set to 0, got %d\n", needed);
1447 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1448 ok(GetLastError() == ERROR_ACCESS_DENIED,
1449 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1451 /* All parameters are correct, access rights are wrong but the
1452 * group name won't be checked yet.
1454 needed = 0xdeadbeef;
1455 returned = 0xdeadbeef;
1456 SetLastError(0xdeadbeef);
1457 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1458 NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1459 ok(!ret, "Expected failure\n");
1460 todo_wine
1461 ok(needed == 0 || broken(needed != 0), /* nt4 */
1462 "Expected needed buffer size to be set to 0, got %d\n", needed);
1463 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1464 ok(GetLastError() == ERROR_ACCESS_DENIED,
1465 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1467 /* Open the service control manager with the needed rights */
1468 CloseServiceHandle(scm_handle);
1469 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1471 /* All parameters are correct and the group will be checked */
1472 needed = 0xdeadbeef;
1473 returned = 0xdeadbeef;
1474 SetLastError(0xdeadbeef);
1475 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1476 NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1477 ok(!ret, "Expected failure\n");
1478 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1479 todo_wine
1481 ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
1482 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
1483 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1486 /* TODO: Create a test that makes sure we enumerate all services that don't
1487 * belong to a group. (specifying "").
1490 /* All parameters are correct. Request the needed buffer size */
1491 needed = 0xdeadbeef;
1492 returned = 0xdeadbeef;
1493 SetLastError(0xdeadbeef);
1494 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1495 NULL, 0, &needed, &returned, NULL, NULL);
1496 ok(!ret, "Expected failure\n");
1497 ok(returned == 0, "Expected no service returned, got %d\n", returned);
1498 todo_wine
1500 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1501 ok(GetLastError() == ERROR_MORE_DATA,
1502 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1505 /* Store the needed bytes */
1506 tempneeded = needed;
1508 /* Allocate the correct needed bytes */
1509 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1510 bufsize = needed;
1511 needed = 0xdeadbeef;
1512 returned = 0xdeadbeef;
1513 SetLastError(0xdeadbeef);
1514 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1515 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1516 todo_wine
1518 ok(ret, "Expected success, got error %u\n", GetLastError());
1519 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1520 ok(returned == tempreturned, "Expected the same number of service from this function\n");
1522 HeapFree(GetProcessHeap(), 0, exservices);
1524 /* Store the number of returned services */
1525 tempreturned = returned;
1527 /* Allocate less than the needed bytes and don't specify a resume handle */
1528 exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1529 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1530 needed = 0xdeadbeef;
1531 returned = 0xdeadbeef;
1532 SetLastError(0xdeadbeef);
1533 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1534 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1535 ok(!ret, "Expected failure\n");
1536 todo_wine
1538 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1539 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1540 ok(GetLastError() == ERROR_MORE_DATA,
1541 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1544 /* Allocate less than the needed bytes, this time with a correct resume handle */
1545 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1546 needed = 0xdeadbeef;
1547 returned = 0xdeadbeef;
1548 resume = 0;
1549 SetLastError(0xdeadbeef);
1550 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1551 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1552 ok(!ret, "Expected failure\n");
1553 todo_wine
1555 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1556 ok(returned < tempreturned, "Expected fewer services to be returned\n");
1557 ok(resume, "Expected a resume handle\n");
1558 ok(GetLastError() == ERROR_MORE_DATA,
1559 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1562 /* Fetch that last service but pass a bigger buffer size */
1563 missing = tempreturned - returned;
1564 bufsize = tempneeded;
1565 needed = 0xdeadbeef;
1566 returned = 0xdeadbeef;
1567 SetLastError(0xdeadbeef);
1568 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1569 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1570 todo_wine
1572 ok(ret, "Expected success, got error %u\n", GetLastError());
1573 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1575 ok(returned == missing, "Expected %u services to be returned\n", missing);
1576 ok(resume == 0, "Expected the resume handle to be 0\n");
1577 HeapFree(GetProcessHeap(), 0, exservices);
1579 /* See if things add up */
1581 /* Get the number of active win32 services */
1582 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1583 NULL, 0, &needed, &returned, NULL, NULL);
1584 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1585 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1586 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1587 HeapFree(GetProcessHeap(), 0, exservices);
1589 servicecountactive = returned;
1591 /* Get the number of inactive win32 services */
1592 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1593 NULL, 0, &needed, &returned, NULL, NULL);
1594 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1595 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1596 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1597 HeapFree(GetProcessHeap(), 0, exservices);
1599 servicecountinactive = returned;
1601 /* Get the number of win32 services */
1602 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1603 NULL, 0, &needed, &returned, NULL, NULL);
1604 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1605 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1606 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1607 HeapFree(GetProcessHeap(), 0, exservices);
1609 /* Check if total is the same as active and inactive win32 services */
1610 ok(returned == (servicecountactive + servicecountinactive),
1611 "Something wrong in the calculation\n");
1613 /* Get all drivers and services */
1614 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1615 SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
1616 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1617 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1618 SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1620 /* Loop through all those returned drivers and services */
1621 for (i = 0; i < returned; i++)
1623 SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
1626 /* lpServiceName and lpDisplayName should always be filled */
1627 ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n");
1628 ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n");
1630 /* Decrement the counters to see if the functions calls return the
1631 * same numbers as the contents of these structures.
1632 * Check some process id specifics.
1634 if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
1636 /* We shouldn't have a process id for drivers */
1637 ok(status.dwProcessId == 0,
1638 "This driver shouldn't have an associated process id\n");
1641 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1643 if (status.dwCurrentState == SERVICE_RUNNING)
1645 /* We expect a process id for every running service */
1646 ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n",
1647 exservices[i].lpServiceName);
1649 servicecountactive--;
1651 else
1653 /* We shouldn't have a process id for inactive services */
1654 ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n",
1655 exservices[i].lpServiceName, status.dwCurrentState);
1657 servicecountinactive--;
1661 HeapFree(GetProcessHeap(), 0, exservices);
1663 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1664 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1666 CloseServiceHandle(scm_handle);
1669 static void test_close(void)
1671 SC_HANDLE handle;
1672 BOOL ret;
1674 /* NULL handle */
1675 SetLastError(0xdeadbeef);
1676 ret = CloseServiceHandle(NULL);
1677 ok(!ret, "Expected failure\n");
1678 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1680 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1682 /* Proper call */
1683 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1684 SetLastError(0xdeadbeef);
1685 ret = CloseServiceHandle(handle);
1686 ok(ret, "Expected success got error %u\n", GetLastError());
1689 static void test_sequence(void)
1691 SC_HANDLE scm_handle, svc_handle;
1692 BOOL ret;
1693 QUERY_SERVICE_CONFIGA *config;
1694 DWORD given, needed;
1695 static const CHAR servicename [] = "Winetest";
1696 static const CHAR displayname [] = "Winetest dummy service";
1697 static const CHAR displayname2[] = "Winetest dummy service (2)";
1698 static const CHAR pathname [] = "we_dont_care.exe";
1699 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1700 static const CHAR password [] = "";
1701 static const CHAR empty [] = "";
1702 static const CHAR localsystem [] = "LocalSystem";
1704 SetLastError(0xdeadbeef);
1705 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1707 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1709 skip("Not enough rights to get a handle to the manager\n");
1710 return;
1712 else
1713 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
1715 if (!scm_handle) return;
1717 /* Create a dummy service */
1718 SetLastError(0xdeadbeef);
1719 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1720 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1721 pathname, NULL, NULL, dependencies, NULL, password);
1723 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
1725 /* We try and open the service and do the rest of the tests. Some could
1726 * fail if the tests were changed between these runs.
1728 trace("Deletion probably didn't work last time\n");
1729 SetLastError(0xdeadbeef);
1730 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1731 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1733 skip("Not enough rights to open the service\n");
1734 CloseServiceHandle(scm_handle);
1735 return;
1737 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
1739 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1741 skip("Not enough rights to create the service\n");
1742 CloseServiceHandle(scm_handle);
1743 return;
1745 else
1746 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1748 if (!svc_handle) return;
1750 /* TODO:
1751 * Before we do a QueryServiceConfig we should check the registry. This will make sure
1752 * that the correct keys are used.
1755 /* Request the size for the buffer */
1756 SetLastError(0xdeadbeef);
1757 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1758 ok(!ret, "Expected failure\n");
1759 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1761 config = HeapAlloc(GetProcessHeap(), 0, needed);
1762 given = needed;
1763 SetLastError(0xdeadbeef);
1764 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
1765 ok(ret, "Expected success, got error %u\n", GetLastError());
1767 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1768 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1769 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1770 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1771 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1772 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
1773 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1774 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
1775 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1776 /* TODO: Show the double 0 terminated string */
1777 todo_wine
1779 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
1781 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1782 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
1784 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
1785 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1787 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1788 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
1789 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
1790 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1791 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1792 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1793 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1794 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1795 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
1796 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1797 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
1798 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1799 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1800 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
1802 SetLastError(0xdeadbeef);
1803 ret = DeleteService(svc_handle);
1804 ok(ret, "Expected success, got error %u\n", GetLastError());
1805 CloseServiceHandle(svc_handle);
1807 /* Wait a while. The following test does a CreateService again */
1808 Sleep(1000);
1810 CloseServiceHandle(scm_handle);
1811 HeapFree(GetProcessHeap(), 0, config);
1814 static void test_queryconfig2(void)
1816 SC_HANDLE scm_handle, svc_handle;
1817 BOOL ret;
1818 DWORD expected, needed;
1819 BYTE buffer[MAX_PATH];
1820 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
1821 static const CHAR servicename [] = "Winetest";
1822 static const CHAR displayname [] = "Winetest dummy service";
1823 static const CHAR pathname [] = "we_dont_care.exe";
1824 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1825 static const CHAR password [] = "";
1826 static const CHAR description [] = "Description";
1828 if(!pQueryServiceConfig2A)
1830 win_skip("function QueryServiceConfig2A not present\n");
1831 return;
1834 SetLastError(0xdeadbeef);
1835 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1837 if (!scm_handle)
1839 if(GetLastError() == ERROR_ACCESS_DENIED)
1840 skip("Not enough rights to get a handle to the manager\n");
1841 else
1842 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
1843 return;
1846 /* Create a dummy service */
1847 SetLastError(0xdeadbeef);
1848 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1849 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1850 pathname, NULL, NULL, dependencies, NULL, password);
1852 if (!svc_handle)
1854 if(GetLastError() == ERROR_SERVICE_EXISTS)
1856 /* We try and open the service and do the rest of the tests. Some could
1857 * fail if the tests were changed between these runs.
1859 trace("Deletion probably didn't work last time\n");
1860 SetLastError(0xdeadbeef);
1861 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1862 if (!svc_handle)
1864 if(GetLastError() == ERROR_ACCESS_DENIED)
1865 skip("Not enough rights to open the service\n");
1866 else
1867 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1868 CloseServiceHandle(scm_handle);
1869 return;
1872 if (GetLastError() == ERROR_ACCESS_DENIED)
1874 skip("Not enough rights to create the service\n");
1875 CloseServiceHandle(scm_handle);
1876 return;
1878 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1879 if (!svc_handle)
1881 CloseServiceHandle(scm_handle);
1882 return;
1885 SetLastError(0xdeadbeef);
1886 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1887 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1888 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1890 SetLastError(0xdeadbeef);
1891 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1892 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1893 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1895 SetLastError(0xdeadbeef);
1896 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1897 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1898 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1900 SetLastError(0xdeadbeef);
1901 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1902 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1903 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1904 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1906 SetLastError(0xdeadbeef);
1907 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1908 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1909 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1911 needed = 0;
1912 SetLastError(0xdeadbeef);
1913 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1914 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1915 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1916 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1918 needed = 0;
1919 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1920 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1921 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1922 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1923 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1925 SetLastError(0xdeadbeef);
1926 needed = 0;
1927 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&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 if(!pChangeServiceConfig2A)
1934 win_skip("function ChangeServiceConfig2A not present\n");
1935 goto cleanup;
1938 pConfig->lpDescription = (LPSTR) description;
1939 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1940 ok(ret, "ChangeServiceConfig2A failed\n");
1941 if (!ret) {
1942 goto cleanup;
1945 SetLastError(0xdeadbeef);
1946 needed = 0;
1947 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1948 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1949 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1950 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1951 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1953 SetLastError(0xdeadbeef);
1954 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1955 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1956 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1958 SetLastError(0xdeadbeef);
1959 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1960 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1961 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1962 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1964 SetLastError(0xdeadbeef);
1965 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1966 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1967 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1968 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1970 if(!pQueryServiceConfig2W)
1972 win_skip("function QueryServiceConfig2W not present\n");
1973 goto cleanup;
1975 SetLastError(0xdeadbeef);
1976 needed = 0;
1977 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1978 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1979 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1980 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1981 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1983 SetLastError(0xdeadbeef);
1984 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1985 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1987 cleanup:
1988 DeleteService(svc_handle);
1990 CloseServiceHandle(svc_handle);
1992 /* Wait a while. The following test does a CreateService again */
1993 Sleep(1000);
1995 CloseServiceHandle(scm_handle);
1998 static void test_refcount(void)
2000 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
2001 static const CHAR servicename [] = "Winetest";
2002 static const CHAR pathname [] = "we_dont_care.exe";
2003 BOOL ret;
2005 /* Get a handle to the Service Control Manager */
2006 SetLastError(0xdeadbeef);
2007 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2008 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
2010 skip("Not enough rights to get a handle to the manager\n");
2011 return;
2014 /* Create a service */
2015 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2016 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2017 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2018 ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError());
2020 /* Get a handle to this new service */
2021 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2022 ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError());
2024 /* Get another handle to this new service */
2025 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2026 ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError());
2028 /* Check if we can close the handle to the Service Control Manager */
2029 ret = CloseServiceHandle(scm_handle);
2030 ok(ret, "Expected success (err=%d)\n", GetLastError());
2032 /* Get a new handle to the Service Control Manager */
2033 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2034 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
2036 /* Get a handle to this new service */
2037 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
2038 ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError());
2040 /* Delete the service */
2041 ret = DeleteService(svc_handle4);
2042 ok(ret, "Expected success (err=%d)\n", GetLastError());
2044 /* We cannot create the same service again as it's still marked as 'being deleted'.
2045 * The reason is that we still have 4 open handles to this service even though we
2046 * closed the handle to the Service Control Manager in between.
2048 SetLastError(0xdeadbeef);
2049 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2050 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2051 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2052 todo_wine
2054 ok(!svc_handle5, "Expected failure\n");
2055 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
2056 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2059 /* FIXME: Remove this when Wine is fixed */
2060 if (svc_handle5)
2062 DeleteService(svc_handle5);
2063 CloseServiceHandle(svc_handle5);
2066 /* Close all the handles to the service and try again */
2067 ret = CloseServiceHandle(svc_handle4);
2068 ok(ret, "Expected success (err=%d)\n", GetLastError());
2069 ret = CloseServiceHandle(svc_handle3);
2070 ok(ret, "Expected success (err=%d)\n", GetLastError());
2071 ret = CloseServiceHandle(svc_handle2);
2072 ok(ret, "Expected success (err=%d)\n", GetLastError());
2073 ret = CloseServiceHandle(svc_handle1);
2074 ok(ret, "Expected success (err=%d)\n", GetLastError());
2076 /* Wait a while. Doing a CreateService too soon will result again
2077 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2079 Sleep(1000);
2081 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2082 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2083 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2084 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2085 ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError());
2087 /* Delete the service */
2088 ret = DeleteService(svc_handle5);
2089 ok(ret, "Expected success (err=%d)\n", GetLastError());
2091 /* Wait a while. Just in case one of the following tests does a CreateService again */
2092 Sleep(1000);
2094 CloseServiceHandle(svc_handle5);
2095 CloseServiceHandle(scm_handle);
2098 START_TEST(service)
2100 SC_HANDLE scm_handle;
2102 /* Bail out if we are on win98 */
2103 SetLastError(0xdeadbeef);
2104 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2106 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2108 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2109 return;
2111 CloseServiceHandle(scm_handle);
2113 init_function_pointers();
2115 /* First some parameter checking */
2116 test_open_scm();
2117 test_open_svc();
2118 test_create_delete_svc();
2119 test_get_displayname();
2120 test_get_servicekeyname();
2121 test_query_svc();
2122 test_enum_svc();
2123 test_close();
2124 /* Test the creation, querying and deletion of a service */
2125 test_sequence();
2126 test_queryconfig2();
2127 /* The main reason for this test is to check if any refcounting is used
2128 * and what the rules are
2130 test_refcount();