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
31 #include "wine/test.h"
33 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
35 static void test_open_scm(void)
39 /* No access rights */
40 SetLastError(0xdeadbeef);
41 scm_handle = OpenSCManagerA(NULL, NULL, 0);
42 ok(scm_handle != NULL, "Expected success\n");
43 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
44 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
45 GetLastError() == ERROR_IO_PENDING /* W2K */,
46 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
47 CloseServiceHandle(scm_handle);
49 /* Unknown database name */
50 SetLastError(0xdeadbeef);
51 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
52 ok(!scm_handle, "Expected failure\n");
53 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
54 CloseServiceHandle(scm_handle); /* Just in case */
56 /* MSDN says only ServiceActive is allowed, or NULL */
57 SetLastError(0xdeadbeef);
58 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
59 ok(!scm_handle, "Expected failure\n");
60 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
61 CloseServiceHandle(scm_handle); /* Just in case */
63 /* Remote unknown host */
64 SetLastError(0xdeadbeef);
65 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
66 ok(!scm_handle, "Expected failure\n");
68 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
69 CloseServiceHandle(scm_handle); /* Just in case */
71 /* Proper call with an empty hostname */
72 SetLastError(0xdeadbeef);
73 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
74 ok(scm_handle != NULL, "Expected success\n");
75 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
76 GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
77 GetLastError() == 0xdeadbeef /* XP */ ||
78 GetLastError() == ERROR_IO_PENDING /* W2K */,
79 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
80 CloseServiceHandle(scm_handle);
82 /* Again a correct one */
83 SetLastError(0xdeadbeef);
84 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
85 ok(scm_handle != NULL, "Expected success\n");
86 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
87 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
88 GetLastError() == ERROR_IO_PENDING /* W2K */,
89 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
90 CloseServiceHandle(scm_handle);
93 static void test_open_svc(void)
95 SC_HANDLE scm_handle, svc_handle;
97 /* All NULL (invalid access rights) */
98 SetLastError(0xdeadbeef);
99 svc_handle = OpenServiceA(NULL, NULL, 0);
100 ok(!svc_handle, "Expected failure\n");
101 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
103 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
106 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
107 SetLastError(0xdeadbeef);
108 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
109 ok(!svc_handle, "Expected failure\n");
110 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
111 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
112 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
114 /* Nonexistent service */
115 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
116 SetLastError(0xdeadbeef);
117 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
118 ok(!svc_handle, "Expected failure\n");
119 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
120 CloseServiceHandle(scm_handle);
122 /* Proper SCM handle but different access rights */
123 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
124 SetLastError(0xdeadbeef);
125 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
126 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
127 skip("Not enough rights to get a handle to the service\n");
130 ok(svc_handle != NULL, "Expected success\n");
131 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
132 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
133 GetLastError() == 0xdeadbeef /* XP, NT4 */,
134 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
135 CloseServiceHandle(svc_handle);
137 CloseServiceHandle(scm_handle);
140 static void test_create_delete_svc(void)
142 SC_HANDLE scm_handle, svc_handle1;
143 CHAR username[UNLEN + 1], *domain;
144 DWORD user_size = UNLEN + 1, domain_size = 0;
145 CHAR account[UNLEN + 3];
146 static const CHAR servicename [] = "Winetest";
147 static const CHAR pathname [] = "we_dont_care.exe";
148 static const CHAR empty [] = "";
149 static const CHAR password [] = "secret";
150 BOOL spooler_exists = FALSE;
153 DWORD display_size = sizeof(display);
155 /* Get the username and turn it into an account to be used in some tests */
156 GetUserNameA(username, &user_size);
157 /* Get the domainname to cater for that situation */
158 GetComputerNameEx(ComputerNameDnsDomain, NULL, &domain_size);
159 domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
160 GetComputerNameEx(ComputerNameDnsDomain, domain, &domain_size);
162 sprintf(account, "%s\\%s", domain, username);
164 sprintf(account, ".\\%s", username);
165 HeapFree(GetProcessHeap(), 0, domain);
168 SetLastError(0xdeadbeef);
169 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
170 ok(!svc_handle1, "Expected failure\n");
171 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
173 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
175 /* Only a valid handle to the Service Control Manager */
176 SetLastError(0xdeadbeef);
177 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
178 ok(!svc_handle1, "Expected failure\n");
179 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
180 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
181 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
183 /* Now with a servicename */
184 SetLastError(0xdeadbeef);
185 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
186 ok(!svc_handle1, "Expected failure\n");
187 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
188 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
189 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
191 /* Or just a binary name */
192 SetLastError(0xdeadbeef);
193 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
194 ok(!svc_handle1, "Expected failure\n");
195 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
196 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
197 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
199 /* Both servicename and binary name (We only have connect rights) */
200 SetLastError(0xdeadbeef);
201 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
202 ok(!svc_handle1, "Expected failure\n");
203 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
205 /* They can even be empty at this stage of parameter checking */
206 SetLastError(0xdeadbeef);
207 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
208 ok(!svc_handle1, "Expected failure\n");
209 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
211 SetLastError(0xdeadbeef);
212 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
213 ok(!svc_handle1, "Expected failure\n");
214 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
216 /* Open the Service Control Manager with minimal rights for creation
217 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
219 CloseServiceHandle(scm_handle);
220 SetLastError(0xdeadbeef);
221 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
222 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
224 skip("Not enough rights to get a handle to the manager\n");
228 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
230 /* Empty strings for servicename and binary name are checked */
231 SetLastError(0xdeadbeef);
232 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
233 ok(!svc_handle1, "Expected failure\n");
234 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
236 SetLastError(0xdeadbeef);
237 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
238 ok(!svc_handle1, "Expected failure\n");
239 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
241 SetLastError(0xdeadbeef);
242 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
243 ok(!svc_handle1, "Expected failure\n");
244 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
246 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
247 * an ERROR_INVALID_PARAMETER)
249 SetLastError(0xdeadbeef);
250 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
251 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
252 ok(!svc_handle1, "Expected failure\n");
253 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
255 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
257 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
258 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
260 SetLastError(0xdeadbeef);
261 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
262 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
263 ok(!svc_handle1, "Expected failure\n");
264 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
266 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
267 SetLastError(0xdeadbeef);
268 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
269 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
270 ok(!svc_handle1, "Expected failure\n");
271 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
273 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
274 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
276 SetLastError(0xdeadbeef);
277 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
278 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
279 ok(!svc_handle1, "Expected failure\n");
280 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
282 /* Illegal (start-type is not a mask and should only be one of the possibilities)
283 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
284 * it's most likely not the wanted start-type)
286 SetLastError(0xdeadbeef);
287 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
288 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
289 ok(!svc_handle1, "Expected failure\n");
290 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
292 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
293 SetLastError(0xdeadbeef);
294 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
295 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
296 ok(!svc_handle1, "Expected failure\n");
297 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
299 /* The service already exists (check first, just in case) */
300 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
303 spooler_exists = TRUE;
304 CloseServiceHandle(svc_handle1);
305 SetLastError(0xdeadbeef);
306 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
307 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
308 ok(!svc_handle1, "Expected failure\n");
309 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
312 skip("Spooler service doesn't exist\n");
314 /* To find an existing displayname we check the 'Spooler' service. Although the registry
315 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
316 * to the servicename and can't be used as well for a new displayname.
320 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
323 skip("Could not retrieve a displayname for the Spooler service\n");
326 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
327 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
328 ok(!svc_handle1, "Expected failure\n");
329 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
330 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
334 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
336 /* Windows doesn't care about the access rights for creation (which makes
337 * sense as there is no service yet) as long as there are sufficient
338 * rights to the manager.
340 SetLastError(0xdeadbeef);
341 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
342 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
343 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
344 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
345 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
346 GetLastError() == ERROR_IO_PENDING /* W2K */,
347 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
349 /* DeleteService however must have proper rights */
350 SetLastError(0xdeadbeef);
351 ret = DeleteService(svc_handle1);
352 ok(!ret, "Expected failure\n");
353 ok(GetLastError() == ERROR_ACCESS_DENIED,
354 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
356 /* Open the service with minimal rights for deletion.
357 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
359 CloseServiceHandle(svc_handle1);
360 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
362 /* Now that we have the proper rights, we should be able to delete */
363 SetLastError(0xdeadbeef);
364 ret = DeleteService(svc_handle1);
365 ok(ret, "Expected success\n");
366 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
367 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
368 GetLastError() == ERROR_IO_PENDING /* W2K */,
369 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
371 CloseServiceHandle(svc_handle1);
373 CloseServiceHandle(scm_handle);
375 /* Wait a while. One of the following tests also does a CreateService for the
376 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
377 * error if we do this to quick. Vista seems more picky then the others.
381 /* And a final NULL check */
382 SetLastError(0xdeadbeef);
383 ret = DeleteService(NULL);
384 ok(!ret, "Expected failure\n");
385 ok(GetLastError() == ERROR_INVALID_HANDLE,
386 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
389 static void test_get_displayname(void)
391 SC_HANDLE scm_handle, svc_handle;
393 CHAR displayname[4096];
394 WCHAR displaynameW[2048];
395 DWORD displaysize, tempsize, tempsizeW;
396 static const CHAR deadbeef[] = "Deadbeef";
397 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
398 static const CHAR servicename[] = "Winetest";
399 static const CHAR pathname[] = "we_dont_care.exe";
401 /* Having NULL for the size of the buffer will crash on W2K3 */
403 SetLastError(0xdeadbeef);
404 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
405 ok(!ret, "Expected failure\n");
406 ok(GetLastError() == ERROR_INVALID_HANDLE,
407 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
409 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
411 SetLastError(0xdeadbeef);
412 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
413 ok(!ret, "Expected failure\n");
414 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
415 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
416 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
418 SetLastError(0xdeadbeef);
419 displaysize = sizeof(displayname);
420 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
421 ok(!ret, "Expected failure\n");
422 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
423 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
424 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
426 /* Test for nonexistent service */
427 SetLastError(0xdeadbeef);
429 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
430 ok(!ret, "Expected failure\n");
431 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
432 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
434 /* Check if 'Spooler' exists */
435 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
438 skip("Spooler service doesn't exist\n");
439 CloseServiceHandle(scm_handle);
442 CloseServiceHandle(svc_handle);
444 /* Retrieve the needed size for the buffer */
445 SetLastError(0xdeadbeef);
447 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
448 ok(!ret, "Expected failure\n");
449 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
450 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
452 /* Buffer is too small */
453 SetLastError(0xdeadbeef);
454 tempsize = displaysize;
455 displaysize = (tempsize / 2);
456 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
457 ok(!ret, "Expected failure\n");
458 ok(displaysize == tempsize, "Expected the needed buffersize\n");
459 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
460 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
462 /* First try with a buffer that should be big enough to hold
463 * the ANSI string (and terminating character). This succeeds on Windows
464 * although when asked (see above 2 tests) it will return twice the needed size.
466 SetLastError(0xdeadbeef);
467 displaysize = (tempsize / 2) + 1;
468 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
469 ok(ret, "Expected success\n");
470 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
471 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
472 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
473 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
474 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
476 /* Now with the original returned size */
477 SetLastError(0xdeadbeef);
478 displaysize = tempsize;
479 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
480 ok(ret, "Expected success\n");
481 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
482 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
483 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
484 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
485 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
487 /* And with a bigger than needed buffer */
488 SetLastError(0xdeadbeef);
489 displaysize = tempsize * 2;
490 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
491 ok(ret, "Expected success\n");
492 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
493 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
494 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
495 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
496 /* Test that shows that if the buffersize is enough, it's not changed */
497 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
498 ok(lstrlen(displayname) == tempsize/2,
499 "Expected the buffer to be twice the length of the string\n") ;
501 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
502 SetLastError(0xdeadbeef);
504 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
505 ok(!ret, "Expected failure\n");
506 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
507 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
509 /* Buffer is too small */
510 SetLastError(0xdeadbeef);
511 tempsizeW = displaysize;
512 displaysize = tempsizeW / 2;
513 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
514 ok(!ret, "Expected failure\n");
515 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
516 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
517 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
519 /* Now with the original returned size */
520 SetLastError(0xdeadbeef);
521 displaysize = tempsizeW;
522 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
523 ok(!ret, "Expected failure\n");
524 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
525 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
526 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
528 /* And with a bigger than needed buffer */
529 SetLastError(0xdeadbeef);
530 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
531 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
532 ok(ret, "Expected success\n");
533 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
534 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
535 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
536 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
537 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
538 ok(lstrlenW(displaynameW) == displaysize,
539 "Expected the buffer to be the length of the string\n") ;
540 ok(tempsize / 2 == tempsizeW,
541 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
543 CloseServiceHandle(scm_handle);
545 /* Test for a service without a displayname (which is valid). This should return
546 * the servicename itself.
548 SetLastError(0xdeadbeef);
549 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
550 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
552 skip("Not enough rights to get a handle to the manager\n");
556 SetLastError(0xdeadbeef);
557 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
558 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
559 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
560 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
563 CloseServiceHandle(scm_handle);
567 /* Retrieve the needed size for the buffer */
568 SetLastError(0xdeadbeef);
570 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
571 ok(!ret, "Expected failure\n");
572 ok(displaysize == lstrlen(servicename) * 2,
573 "Expected the displaysize to be twice the size of the servicename\n");
574 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
575 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
577 /* Buffer is too small */
578 SetLastError(0xdeadbeef);
579 tempsize = displaysize;
580 displaysize = (tempsize / 2);
581 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
582 ok(!ret, "Expected failure\n");
583 ok(displaysize == tempsize, "Expected the needed buffersize\n");
584 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
585 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
587 /* Get the displayname */
588 SetLastError(0xdeadbeef);
589 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
590 ok(ret, "Expected success\n");
591 ok(!lstrcmpi(displayname, servicename),
592 "Expected displayname to be %s, got %s\n", servicename, displayname);
593 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
594 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
595 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
596 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
598 /* Delete the service */
599 ret = DeleteService(svc_handle);
600 ok(ret, "Expected success\n");
602 CloseServiceHandle(svc_handle);
603 CloseServiceHandle(scm_handle);
605 /* Wait a while. Just in case one of the following tests does a CreateService again */
609 static void test_get_servicekeyname(void)
611 SC_HANDLE scm_handle, svc_handle;
612 CHAR servicename[4096];
613 CHAR displayname[4096];
614 DWORD servicesize, displaysize, tempsize;
616 static const CHAR deadbeef[] = "Deadbeef";
618 /* Having NULL for the size of the buffer will crash on W2K3 */
620 SetLastError(0xdeadbeef);
621 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
622 ok(!ret, "Expected failure\n");
624 ok(GetLastError() == ERROR_INVALID_HANDLE,
625 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
627 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
629 SetLastError(0xdeadbeef);
630 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
631 ok(!ret, "Expected failure\n");
633 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
634 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
635 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
637 /* Valid handle and buffer but no displayname */
638 SetLastError(0xdeadbeef);
639 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
640 ok(!ret, "Expected failure\n");
642 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
643 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
644 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
646 /* Test for nonexistent displayname */
647 SetLastError(0xdeadbeef);
648 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
649 ok(!ret, "Expected failure\n");
651 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
652 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
654 /* Check if 'Spooler' exists */
655 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
658 skip("Spooler service doesn't exist\n");
659 CloseServiceHandle(scm_handle);
662 CloseServiceHandle(svc_handle);
664 /* Get the displayname for the 'Spooler' service */
665 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
666 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
668 /* Retrieve the needed size for the buffer */
669 SetLastError(0xdeadbeef);
671 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
672 ok(!ret, "Expected failure\n");
674 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
675 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
677 /* Valid call with the correct buffersize */
678 SetLastError(0xdeadbeef);
679 tempsize = servicesize;
681 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
683 ok(ret, "Expected success\n");
684 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
685 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
686 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
687 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
690 ok(lstrlen(servicename) == tempsize/2,
691 "Expected the buffer to be twice the length of the string\n") ;
692 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
695 CloseServiceHandle(scm_handle);
698 static void test_close(void)
704 SetLastError(0xdeadbeef);
705 ret = CloseServiceHandle(NULL);
708 ok(!ret, "Expected failure\n");
709 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
712 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
715 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
716 SetLastError(0xdeadbeef);
717 ret = CloseServiceHandle(handle);
718 ok(ret, "Expected success\n");
719 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
720 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
721 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
722 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
725 static void test_sequence(void)
727 SC_HANDLE scm_handle, svc_handle;
729 QUERY_SERVICE_CONFIGA *config;
731 static const CHAR servicename [] = "Winetest";
732 static const CHAR displayname [] = "Winetest dummy service";
733 static const CHAR pathname [] = "we_dont_care.exe";
734 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0\0";
735 static const CHAR password [] = "";
736 static const CHAR empty [] = "";
737 static const CHAR localsystem [] = "LocalSystem";
739 SetLastError(0xdeadbeef);
740 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
742 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
744 skip("Not enough rights to get a handle to the manager\n");
748 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
750 if (!scm_handle) return;
752 /* Create a dummy service */
753 SetLastError(0xdeadbeef);
754 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
755 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
756 pathname, NULL, NULL, dependencies, NULL, password);
758 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
760 /* We try and open the service and do the rest of the tests. Some could
761 * fail if the tests were changed between these runs.
763 trace("Deletion probably didn't work last time\n");
764 SetLastError(0xdeadbeef);
765 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
766 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
768 skip("Not enough rights to open the service\n");
769 CloseServiceHandle(scm_handle);
772 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
774 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
776 skip("Not enough rights to create the service\n");
777 CloseServiceHandle(scm_handle);
781 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
783 if (!svc_handle) return;
786 * Before we do a QueryServiceConfig we should check the registry. This will make sure
787 * that the correct keys are used.
790 /* Request the size for the buffer */
791 SetLastError(0xdeadbeef);
792 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
793 ok(!ret, "Expected failure\n");
794 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
796 config = HeapAlloc(GetProcessHeap(), 0, needed);
798 SetLastError(0xdeadbeef);
799 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
800 ok(ret, "Expected success\n");
803 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
804 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
805 GetLastError() == ERROR_IO_PENDING /* W2K */,
806 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
807 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
809 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
810 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
811 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
812 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
813 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
814 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
815 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
816 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
817 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
818 /* TODO: Show the double 0 terminated string */
821 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
822 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
824 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
826 SetLastError(0xdeadbeef);
827 ret = DeleteService(svc_handle);
828 ok(ret, "Expected success\n");
829 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
830 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
831 GetLastError() == ERROR_IO_PENDING /* W2K */,
832 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
834 CloseServiceHandle(svc_handle);
836 /* Wait a while. The following test does a CreateService again */
839 CloseServiceHandle(scm_handle);
842 static void test_refcount(void)
844 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
845 static const CHAR servicename [] = "Winetest";
846 static const CHAR pathname [] = "we_dont_care.exe";
849 /* Get a handle to the Service Control Manager */
850 SetLastError(0xdeadbeef);
851 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
852 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
854 skip("Not enough rights to get a handle to the manager\n");
858 /* Create a service */
859 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
860 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
861 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
862 ok(svc_handle1 != NULL, "Expected success\n");
864 /* Get a handle to this new service */
865 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
866 ok(svc_handle2 != NULL, "Expected success\n");
868 /* Get another handle to this new service */
869 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
870 ok(svc_handle3 != NULL, "Expected success\n");
872 /* Check if we can close the handle to the Service Control Manager */
873 ret = CloseServiceHandle(scm_handle);
874 ok(ret, "Expected success\n");
876 /* Get a new handle to the Service Control Manager */
877 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
878 ok(scm_handle != NULL, "Expected success\n");
880 /* Get a handle to this new service */
881 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
882 ok(svc_handle4 != NULL, "Expected success\n");
884 /* Delete the service */
885 ret = DeleteService(svc_handle4);
886 ok(ret, "Expected success\n");
888 /* We cannot create the same service again as it's still marked as 'being deleted'.
889 * The reason is that we still have 4 open handles to this service even though we
890 * closed the handle to the Service Control Manager in between.
892 SetLastError(0xdeadbeef);
893 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
894 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
895 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
898 ok(!svc_handle5, "Expected failure\n");
899 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
900 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
903 /* FIXME: Remove this when Wine is fixed */
906 DeleteService(svc_handle5);
907 CloseServiceHandle(svc_handle5);
910 /* Close all the handles to the service and try again */
911 ret = CloseServiceHandle(svc_handle4);
912 ok(ret, "Expected success\n");
913 ret = CloseServiceHandle(svc_handle3);
914 ok(ret, "Expected success\n");
915 ret = CloseServiceHandle(svc_handle2);
916 ok(ret, "Expected success\n");
917 ret = CloseServiceHandle(svc_handle1);
918 ok(ret, "Expected success\n");
920 /* Wait a while. Doing a CreateService too soon will result again
921 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
925 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
926 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
927 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
928 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
929 ok(svc_handle5 != NULL, "Expected success\n");
931 /* Delete the service */
932 ret = DeleteService(svc_handle5);
933 ok(ret, "Expected success\n");
935 /* Wait a while. Just in case one of the following tests does a CreateService again */
938 CloseServiceHandle(svc_handle5);
939 CloseServiceHandle(scm_handle);
944 SC_HANDLE scm_handle;
946 /* Bail out if we are on win98 */
947 SetLastError(0xdeadbeef);
948 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
950 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
952 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
955 CloseServiceHandle(scm_handle);
957 /* First some parameter checking */
960 test_create_delete_svc();
961 test_get_displayname();
962 test_get_servicekeyname();
964 /* Test the creation, querying and deletion of a service */
966 /* The main reason for this test is to check if any refcounting is used
967 * and what the rules are