Release 0.9.61.
[wine/gsoc-2012-control.git] / dlls / advapi32 / tests / service.c
blobd299d2d7a1288a9b56d553ba2023330409bae6e9
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 void test_open_scm(void)
38 SC_HANDLE scm_handle;
40 /* No access rights */
41 SetLastError(0xdeadbeef);
42 scm_handle = OpenSCManagerA(NULL, NULL, 0);
43 ok(scm_handle != NULL, "Expected success\n");
44 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
45 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
46 GetLastError() == ERROR_IO_PENDING /* W2K */,
47 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
48 CloseServiceHandle(scm_handle);
50 /* Unknown database name */
51 SetLastError(0xdeadbeef);
52 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
53 ok(!scm_handle, "Expected failure\n");
54 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
55 CloseServiceHandle(scm_handle); /* Just in case */
57 /* MSDN says only ServiceActive is allowed, or NULL */
58 SetLastError(0xdeadbeef);
59 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
60 ok(!scm_handle, "Expected failure\n");
61 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
62 CloseServiceHandle(scm_handle); /* Just in case */
64 /* Remote unknown host */
65 SetLastError(0xdeadbeef);
66 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
67 ok(!scm_handle, "Expected failure\n");
68 todo_wine
69 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
70 CloseServiceHandle(scm_handle); /* Just in case */
72 /* Proper call with an empty hostname */
73 SetLastError(0xdeadbeef);
74 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
75 ok(scm_handle != NULL, "Expected success\n");
76 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
77 GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
78 GetLastError() == 0xdeadbeef /* XP */ ||
79 GetLastError() == ERROR_IO_PENDING /* W2K */,
80 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
81 CloseServiceHandle(scm_handle);
83 /* Again a correct one */
84 SetLastError(0xdeadbeef);
85 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
86 ok(scm_handle != NULL, "Expected success\n");
87 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
88 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
89 GetLastError() == ERROR_IO_PENDING /* W2K */,
90 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
91 CloseServiceHandle(scm_handle);
94 static void test_open_svc(void)
96 SC_HANDLE scm_handle, svc_handle;
98 /* All NULL (invalid access rights) */
99 SetLastError(0xdeadbeef);
100 svc_handle = OpenServiceA(NULL, NULL, 0);
101 ok(!svc_handle, "Expected failure\n");
102 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
104 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
106 /* NULL service */
107 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
108 SetLastError(0xdeadbeef);
109 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
110 ok(!svc_handle, "Expected failure\n");
111 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
112 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
113 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
115 /* Nonexistent service */
116 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
117 SetLastError(0xdeadbeef);
118 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
119 ok(!svc_handle, "Expected failure\n");
120 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
121 CloseServiceHandle(scm_handle);
123 /* Proper SCM handle but different access rights */
124 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
125 SetLastError(0xdeadbeef);
126 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
127 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
128 skip("Not enough rights to get a handle to the service\n");
129 else
131 ok(svc_handle != NULL, "Expected success\n");
132 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
133 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
134 GetLastError() == 0xdeadbeef /* XP, NT4 */,
135 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
136 CloseServiceHandle(svc_handle);
138 CloseServiceHandle(scm_handle);
141 static void test_create_delete_svc(void)
143 SC_HANDLE scm_handle, svc_handle1;
144 CHAR username[UNLEN + 1], domain[MAX_PATH];
145 DWORD user_size = UNLEN + 1;
146 CHAR account[UNLEN + 3];
147 static const CHAR servicename [] = "Winetest";
148 static const CHAR pathname [] = "we_dont_care.exe";
149 static const CHAR empty [] = "";
150 static const CHAR password [] = "secret";
151 BOOL spooler_exists = FALSE;
152 BOOL ret;
153 CHAR display[4096];
154 DWORD display_size = sizeof(display);
156 /* Get the username and turn it into an account to be used in some tests */
157 GetUserNameA(username, &user_size);
158 /* Get the domainname to cater for that situation */
159 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
160 sprintf(account, "%s\\%s", domain, username);
161 else
162 sprintf(account, ".\\%s", username);
164 /* All NULL */
165 SetLastError(0xdeadbeef);
166 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
167 ok(!svc_handle1, "Expected failure\n");
168 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
170 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
172 /* Only a valid handle to the Service Control Manager */
173 SetLastError(0xdeadbeef);
174 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
175 ok(!svc_handle1, "Expected failure\n");
176 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
177 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
178 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
180 /* Now with a servicename */
181 SetLastError(0xdeadbeef);
182 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
183 ok(!svc_handle1, "Expected failure\n");
184 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
185 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
186 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
188 /* Or just a binary name */
189 SetLastError(0xdeadbeef);
190 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
191 ok(!svc_handle1, "Expected failure\n");
192 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
193 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
194 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
196 /* Both servicename and binary name (We only have connect rights) */
197 SetLastError(0xdeadbeef);
198 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
199 ok(!svc_handle1, "Expected failure\n");
200 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
202 /* They can even be empty at this stage of parameter checking */
203 SetLastError(0xdeadbeef);
204 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
205 ok(!svc_handle1, "Expected failure\n");
206 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
208 SetLastError(0xdeadbeef);
209 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
210 ok(!svc_handle1, "Expected failure\n");
211 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
213 /* Open the Service Control Manager with minimal rights for creation
214 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
216 CloseServiceHandle(scm_handle);
217 SetLastError(0xdeadbeef);
218 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
219 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
221 skip("Not enough rights to get a handle to the manager\n");
222 return;
225 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
227 /* Empty strings for servicename and binary name are checked */
228 SetLastError(0xdeadbeef);
229 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
230 ok(!svc_handle1, "Expected failure\n");
231 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
233 SetLastError(0xdeadbeef);
234 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
235 ok(!svc_handle1, "Expected failure\n");
236 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
238 SetLastError(0xdeadbeef);
239 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
240 ok(!svc_handle1, "Expected failure\n");
241 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
243 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
244 * an ERROR_INVALID_PARAMETER)
246 SetLastError(0xdeadbeef);
247 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
248 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
249 ok(!svc_handle1, "Expected failure\n");
250 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
252 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
254 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
255 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
257 SetLastError(0xdeadbeef);
258 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
259 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
260 ok(!svc_handle1, "Expected failure\n");
261 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
263 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
264 SetLastError(0xdeadbeef);
265 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
266 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
267 ok(!svc_handle1, "Expected failure\n");
268 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
270 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
271 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
273 SetLastError(0xdeadbeef);
274 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
275 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
276 ok(!svc_handle1, "Expected failure\n");
277 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
279 /* Illegal (start-type is not a mask and should only be one of the possibilities)
280 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
281 * it's most likely not the wanted start-type)
283 SetLastError(0xdeadbeef);
284 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
285 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
286 ok(!svc_handle1, "Expected failure\n");
287 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
289 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
290 SetLastError(0xdeadbeef);
291 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
292 SERVICE_BOOT_START, 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 /* The service already exists (check first, just in case) */
297 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
298 if (svc_handle1)
300 spooler_exists = TRUE;
301 CloseServiceHandle(svc_handle1);
302 SetLastError(0xdeadbeef);
303 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
304 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
305 ok(!svc_handle1, "Expected failure\n");
306 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
308 else
309 skip("Spooler service doesn't exist\n");
311 /* To find an existing displayname we check the 'Spooler' service. Although the registry
312 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
313 * to the servicename and can't be used as well for a new displayname.
315 if (spooler_exists)
317 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
319 if (!ret)
320 skip("Could not retrieve a displayname for the Spooler service\n");
321 else
323 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
324 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
325 ok(!svc_handle1, "Expected failure\n");
326 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
327 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
330 else
331 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
333 /* Windows doesn't care about the access rights for creation (which makes
334 * sense as there is no service yet) as long as there are sufficient
335 * rights to the manager.
337 SetLastError(0xdeadbeef);
338 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
339 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
340 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
341 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
342 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
343 GetLastError() == ERROR_IO_PENDING /* W2K */,
344 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
346 /* DeleteService however must have proper rights */
347 SetLastError(0xdeadbeef);
348 ret = DeleteService(svc_handle1);
349 ok(!ret, "Expected failure\n");
350 ok(GetLastError() == ERROR_ACCESS_DENIED,
351 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
353 /* Open the service with minimal rights for deletion.
354 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
356 CloseServiceHandle(svc_handle1);
357 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
359 /* Now that we have the proper rights, we should be able to delete */
360 SetLastError(0xdeadbeef);
361 ret = DeleteService(svc_handle1);
362 ok(ret, "Expected success\n");
363 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
364 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
365 GetLastError() == ERROR_IO_PENDING /* W2K */,
366 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
368 CloseServiceHandle(svc_handle1);
370 CloseServiceHandle(scm_handle);
372 /* Wait a while. One of the following tests also does a CreateService for the
373 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
374 * error if we do this to quick. Vista seems more picky then the others.
376 Sleep(1000);
378 /* And a final NULL check */
379 SetLastError(0xdeadbeef);
380 ret = DeleteService(NULL);
381 ok(!ret, "Expected failure\n");
382 ok(GetLastError() == ERROR_INVALID_HANDLE,
383 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
386 static void test_get_displayname(void)
388 SC_HANDLE scm_handle, svc_handle;
389 BOOL ret;
390 CHAR displayname[4096];
391 WCHAR displaynameW[2048];
392 DWORD displaysize, tempsize, tempsizeW;
393 static const CHAR deadbeef[] = "Deadbeef";
394 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
395 static const CHAR servicename[] = "Winetest";
396 static const CHAR pathname[] = "we_dont_care.exe";
398 /* Having NULL for the size of the buffer will crash on W2K3 */
400 SetLastError(0xdeadbeef);
401 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
402 ok(!ret, "Expected failure\n");
403 ok(GetLastError() == ERROR_INVALID_HANDLE,
404 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
406 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
408 SetLastError(0xdeadbeef);
409 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
410 ok(!ret, "Expected failure\n");
411 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
412 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
413 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
415 SetLastError(0xdeadbeef);
416 displaysize = sizeof(displayname);
417 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
418 ok(!ret, "Expected failure\n");
419 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
420 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
421 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
423 /* Test for nonexistent service */
424 SetLastError(0xdeadbeef);
425 displaysize = -1;
426 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
427 ok(!ret, "Expected failure\n");
428 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
429 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
431 /* Check if 'Spooler' exists */
432 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
433 if (!svc_handle)
435 skip("Spooler service doesn't exist\n");
436 CloseServiceHandle(scm_handle);
437 return;
439 CloseServiceHandle(svc_handle);
441 /* Retrieve the needed size for the buffer */
442 SetLastError(0xdeadbeef);
443 displaysize = -1;
444 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
445 ok(!ret, "Expected failure\n");
446 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
447 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
448 tempsize = displaysize;
450 displaysize = 0;
451 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
452 ok(!ret, "Expected failure\n");
453 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
454 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
455 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
457 /* Buffer is too small */
458 SetLastError(0xdeadbeef);
459 displaysize = (tempsize / 2);
460 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
461 ok(!ret, "Expected failure\n");
462 ok(displaysize == tempsize, "Expected the needed buffersize\n");
463 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
464 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
466 /* First try with a buffer that should be big enough to hold
467 * the ANSI string (and terminating character). This succeeds on Windows
468 * although when asked (see above 2 tests) it will return twice the needed size.
470 SetLastError(0xdeadbeef);
471 displaysize = (tempsize / 2) + 1;
472 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
473 ok(ret, "Expected success\n");
474 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
475 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
476 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
477 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
478 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
480 /* Now with the original returned size */
481 SetLastError(0xdeadbeef);
482 displaysize = tempsize;
483 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
484 ok(ret, "Expected success\n");
485 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
486 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
487 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
488 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
489 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
491 /* And with a bigger than needed buffer */
492 SetLastError(0xdeadbeef);
493 displaysize = tempsize * 2;
494 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
495 ok(ret, "Expected success\n");
496 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
497 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
498 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
499 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
500 /* Test that shows that if the buffersize is enough, it's not changed */
501 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
502 ok(lstrlen(displayname) == tempsize/2,
503 "Expected the buffer to be twice the length of the string\n") ;
505 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
506 SetLastError(0xdeadbeef);
507 displaysize = -1;
508 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
509 ok(!ret, "Expected failure\n");
510 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
511 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
513 /* Buffer is too small */
514 SetLastError(0xdeadbeef);
515 tempsizeW = displaysize;
516 displaysize = tempsizeW / 2;
517 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
518 ok(!ret, "Expected failure\n");
519 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
520 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
521 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
523 /* Now with the original returned size */
524 SetLastError(0xdeadbeef);
525 displaysize = tempsizeW;
526 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
527 ok(!ret, "Expected failure\n");
528 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
529 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
530 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
532 /* And with a bigger than needed buffer */
533 SetLastError(0xdeadbeef);
534 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
535 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
536 ok(ret, "Expected success\n");
537 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
538 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
539 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
540 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
541 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
542 ok(lstrlenW(displaynameW) == displaysize,
543 "Expected the buffer to be the length of the string\n") ;
544 ok(tempsize / 2 == tempsizeW,
545 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
547 CloseServiceHandle(scm_handle);
549 /* Test for a service without a displayname (which is valid). This should return
550 * the servicename itself.
552 SetLastError(0xdeadbeef);
553 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
554 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
556 skip("Not enough rights to get a handle to the manager\n");
557 return;
560 SetLastError(0xdeadbeef);
561 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
562 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
563 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
564 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
565 if (!svc_handle)
567 CloseServiceHandle(scm_handle);
568 return;
571 /* Retrieve the needed size for the buffer */
572 SetLastError(0xdeadbeef);
573 displaysize = -1;
574 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
575 ok(!ret, "Expected failure\n");
576 ok(displaysize == lstrlen(servicename) * 2,
577 "Expected the displaysize to be twice the size of the servicename\n");
578 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
579 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
581 /* Buffer is too small */
582 SetLastError(0xdeadbeef);
583 tempsize = displaysize;
584 displaysize = (tempsize / 2);
585 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
586 ok(!ret, "Expected failure\n");
587 ok(displaysize == tempsize, "Expected the needed buffersize\n");
588 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
589 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
591 /* Get the displayname */
592 SetLastError(0xdeadbeef);
593 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
594 ok(ret, "Expected success\n");
595 ok(!lstrcmpi(displayname, servicename),
596 "Expected displayname to be %s, got %s\n", servicename, displayname);
597 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
598 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
599 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
600 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
602 /* Delete the service */
603 ret = DeleteService(svc_handle);
604 ok(ret, "Expected success\n");
606 CloseServiceHandle(svc_handle);
607 CloseServiceHandle(scm_handle);
609 /* Wait a while. Just in case one of the following tests does a CreateService again */
610 Sleep(1000);
613 static void test_get_servicekeyname(void)
615 SC_HANDLE scm_handle, svc_handle;
616 CHAR servicename[4096];
617 CHAR displayname[4096];
618 WCHAR servicenameW[4096];
619 WCHAR displaynameW[4096];
620 DWORD servicesize, displaysize, tempsize;
621 BOOL ret;
622 static const CHAR deadbeef[] = "Deadbeef";
623 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
625 /* Having NULL for the size of the buffer will crash on W2K3 */
627 SetLastError(0xdeadbeef);
628 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
629 ok(!ret, "Expected failure\n");
630 ok(GetLastError() == ERROR_INVALID_HANDLE,
631 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
633 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
635 servicesize = 200;
636 SetLastError(0xdeadbeef);
637 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
638 ok(!ret, "Expected failure\n");
639 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
640 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
641 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
642 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
644 /* Valid handle and buffer but no displayname */
645 servicesize = 200;
646 SetLastError(0xdeadbeef);
647 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
648 ok(!ret, "Expected failure\n");
649 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
650 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
651 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
652 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
654 /* Test for nonexistent displayname */
655 SetLastError(0xdeadbeef);
656 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
657 ok(!ret, "Expected failure\n");
658 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
659 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
660 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
662 servicesize = 15;
663 strcpy(servicename, "ABC");
664 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
665 ok(!ret, "Expected failure\n");
666 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
667 ok(servicename[0] == 0, "Service name not empty\n");
669 servicesize = 15;
670 servicenameW[0] = 'A';
671 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
672 ok(!ret, "Expected failure\n");
673 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
674 ok(servicenameW[0] == 0, "Service name not empty\n");
676 servicesize = 0;
677 strcpy(servicename, "ABC");
678 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
679 ok(!ret, "Expected failure\n");
680 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
681 ok(servicename[0] == 'A', "Service name changed\n");
683 servicesize = 0;
684 servicenameW[0] = 'A';
685 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
686 ok(!ret, "Expected failure\n");
687 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
688 ok(servicenameW[0] == 'A', "Service name changed\n");
690 /* Check if 'Spooler' exists */
691 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
692 if (!svc_handle)
694 skip("Spooler service doesn't exist\n");
695 CloseServiceHandle(scm_handle);
696 return;
698 CloseServiceHandle(svc_handle);
700 /* Get the displayname for the 'Spooler' service */
701 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
702 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
704 /* Retrieve the needed size for the buffer */
705 SetLastError(0xdeadbeef);
706 servicesize = 0;
707 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
708 ok(!ret, "Expected failure\n");
709 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
710 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
712 /* Valid call with the correct buffersize */
713 SetLastError(0xdeadbeef);
714 tempsize = servicesize;
715 servicesize *= 2;
716 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
717 ok(ret, "Expected success\n");
718 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
719 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
720 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
721 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
722 if (ret)
724 ok(lstrlen(servicename) == tempsize/2,
725 "Expected the buffer to be twice the length of the string\n") ;
726 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
727 ok(servicesize == (tempsize * 2),
728 "Expected servicesize not to change if buffer not insufficient\n") ;
731 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
732 SetLastError(0xdeadbeef);
733 servicesize *= 2;
734 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
735 ok(ret, "Expected success\n");
736 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
737 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
738 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
739 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
740 if (ret)
742 ok(lstrlen(servicename) == tempsize/2,
743 "Expected the buffer to be twice the length of the string\n") ;
744 ok(servicesize == lstrlenW(servicenameW),
745 "Expected servicesize not to change if buffer not insufficient\n") ;
748 SetLastError(0xdeadbeef);
749 servicesize = 3;
750 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
751 ok(!ret, "Expected failure\n");
752 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
753 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
754 ok(servicenameW[0] == 0, "Buffer not empty\n");
756 CloseServiceHandle(scm_handle);
759 static void test_close(void)
761 SC_HANDLE handle;
762 BOOL ret;
764 /* NULL handle */
765 SetLastError(0xdeadbeef);
766 ret = CloseServiceHandle(NULL);
767 ok(!ret, "Expected failure\n");
768 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
770 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
772 /* Proper call */
773 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
774 SetLastError(0xdeadbeef);
775 ret = CloseServiceHandle(handle);
776 ok(ret, "Expected success\n");
777 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
778 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
779 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
780 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
783 static void test_sequence(void)
785 SC_HANDLE scm_handle, svc_handle;
786 BOOL ret;
787 QUERY_SERVICE_CONFIGA *config;
788 DWORD given, needed;
789 static const CHAR servicename [] = "Winetest";
790 static const CHAR displayname [] = "Winetest dummy service";
791 static const CHAR displayname2[] = "Winetest dummy service (2)";
792 static const CHAR pathname [] = "we_dont_care.exe";
793 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
794 static const CHAR password [] = "";
795 static const CHAR empty [] = "";
796 static const CHAR localsystem [] = "LocalSystem";
798 SetLastError(0xdeadbeef);
799 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
801 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
803 skip("Not enough rights to get a handle to the manager\n");
804 return;
806 else
807 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
809 if (!scm_handle) return;
811 /* Create a dummy service */
812 SetLastError(0xdeadbeef);
813 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
814 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
815 pathname, NULL, NULL, dependencies, NULL, password);
817 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
819 /* We try and open the service and do the rest of the tests. Some could
820 * fail if the tests were changed between these runs.
822 trace("Deletion probably didn't work last time\n");
823 SetLastError(0xdeadbeef);
824 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
825 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
827 skip("Not enough rights to open the service\n");
828 CloseServiceHandle(scm_handle);
829 return;
831 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
833 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
835 skip("Not enough rights to create the service\n");
836 CloseServiceHandle(scm_handle);
837 return;
839 else
840 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
842 if (!svc_handle) return;
844 /* TODO:
845 * Before we do a QueryServiceConfig we should check the registry. This will make sure
846 * that the correct keys are used.
849 /* Request the size for the buffer */
850 SetLastError(0xdeadbeef);
851 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
852 ok(!ret, "Expected failure\n");
853 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
855 config = HeapAlloc(GetProcessHeap(), 0, needed);
856 given = needed;
857 SetLastError(0xdeadbeef);
858 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
859 ok(ret, "Expected success\n");
860 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
861 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
862 GetLastError() == ERROR_IO_PENDING /* W2K */,
863 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
864 todo_wine
866 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
868 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
869 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
870 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
871 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
872 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
873 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
874 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
875 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
876 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
877 /* TODO: Show the double 0 terminated string */
878 todo_wine
880 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
882 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
883 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
885 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
886 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
888 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
889 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
890 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
891 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
892 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
893 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
894 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
895 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
896 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
897 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
898 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
899 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
900 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
901 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
903 SetLastError(0xdeadbeef);
904 ret = DeleteService(svc_handle);
905 ok(ret, "Expected success\n");
906 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
907 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
908 GetLastError() == ERROR_IO_PENDING /* W2K */,
909 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
911 CloseServiceHandle(svc_handle);
913 /* Wait a while. The following test does a CreateService again */
914 Sleep(1000);
916 CloseServiceHandle(scm_handle);
917 HeapFree(GetProcessHeap(), 0, config);
920 static void test_queryconfig2(void)
922 SC_HANDLE scm_handle, svc_handle;
923 BOOL ret;
924 DWORD expected, needed;
925 BYTE buffer[MAX_PATH];
926 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
927 static const CHAR servicename [] = "Winetest";
928 static const CHAR displayname [] = "Winetest dummy service";
929 static const CHAR pathname [] = "we_dont_care.exe";
930 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
931 static const CHAR password [] = "";
932 static const CHAR description [] = "Description";
933 HMODULE dllhandle = GetModuleHandleA("advapi32.dll");
934 BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID)
935 = (void*)GetProcAddress(dllhandle, "ChangeServiceConfig2A");
936 BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
937 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2A");
938 BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
939 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2W");
940 if(!pQueryServiceConfig2A)
942 skip("function QueryServiceConfig2A not present\n");
943 return;
946 SetLastError(0xdeadbeef);
947 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
949 if (!scm_handle)
951 if(GetLastError() == ERROR_ACCESS_DENIED)
952 skip("Not enough rights to get a handle to the manager\n");
953 else
954 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
955 return;
958 /* Create a dummy service */
959 SetLastError(0xdeadbeef);
960 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
961 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
962 pathname, NULL, NULL, dependencies, NULL, password);
964 if (!svc_handle)
966 if(GetLastError() == ERROR_SERVICE_EXISTS)
968 /* We try and open the service and do the rest of the tests. Some could
969 * fail if the tests were changed between these runs.
971 trace("Deletion probably didn't work last time\n");
972 SetLastError(0xdeadbeef);
973 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
974 if (!svc_handle)
976 if(GetLastError() == ERROR_ACCESS_DENIED)
977 skip("Not enough rights to open the service\n");
978 else
979 ok(FALSE, "Could not open the service : %d\n", GetLastError());
980 CloseServiceHandle(scm_handle);
981 return;
984 if (GetLastError() == ERROR_ACCESS_DENIED)
986 skip("Not enough rights to create the service\n");
987 CloseServiceHandle(scm_handle);
988 return;
990 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
991 if (!svc_handle)
993 CloseServiceHandle(scm_handle);
994 return;
997 SetLastError(0xdeadbeef);
998 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
999 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1000 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1002 SetLastError(0xdeadbeef);
1003 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1004 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1005 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1007 SetLastError(0xdeadbeef);
1008 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1009 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1010 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1012 SetLastError(0xdeadbeef);
1013 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1014 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1015 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1016 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1018 SetLastError(0xdeadbeef);
1019 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1020 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1021 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1023 needed = 0;
1024 SetLastError(0xdeadbeef);
1025 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1026 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1027 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1028 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1030 needed = 0;
1031 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1032 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1033 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1034 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1035 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1037 SetLastError(0xdeadbeef);
1038 needed = 0;
1039 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1040 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1041 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1042 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1044 if(!pChangeServiceConfig2A)
1046 skip("function ChangeServiceConfig2A not present\n");
1047 goto cleanup;
1050 pConfig->lpDescription = (LPSTR) description;
1051 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1052 ok(ret, "ChangeServiceConfig2A failed\n");
1053 if (!ret) {
1054 goto cleanup;
1057 SetLastError(0xdeadbeef);
1058 needed = 0;
1059 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1060 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1061 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1062 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1063 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1065 SetLastError(0xdeadbeef);
1066 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1067 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1068 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1070 SetLastError(0xdeadbeef);
1071 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1072 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1073 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1074 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1076 SetLastError(0xdeadbeef);
1077 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1078 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1079 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1080 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1082 if(!pQueryServiceConfig2W)
1084 skip("function QueryServiceConfig2W not present\n");
1085 goto cleanup;
1087 SetLastError(0xdeadbeef);
1088 needed = 0;
1089 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1090 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1091 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1092 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1093 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1095 SetLastError(0xdeadbeef);
1096 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1097 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1099 cleanup:
1100 DeleteService(svc_handle);
1102 CloseServiceHandle(svc_handle);
1104 /* Wait a while. The following test does a CreateService again */
1105 Sleep(1000);
1107 CloseServiceHandle(scm_handle);
1110 static void test_refcount(void)
1112 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1113 static const CHAR servicename [] = "Winetest";
1114 static const CHAR pathname [] = "we_dont_care.exe";
1115 BOOL ret;
1117 /* Get a handle to the Service Control Manager */
1118 SetLastError(0xdeadbeef);
1119 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1120 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1122 skip("Not enough rights to get a handle to the manager\n");
1123 return;
1126 /* Create a service */
1127 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1128 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1129 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1130 ok(svc_handle1 != NULL, "Expected success\n");
1132 /* Get a handle to this new service */
1133 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1134 ok(svc_handle2 != NULL, "Expected success\n");
1136 /* Get another handle to this new service */
1137 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1138 ok(svc_handle3 != NULL, "Expected success\n");
1140 /* Check if we can close the handle to the Service Control Manager */
1141 ret = CloseServiceHandle(scm_handle);
1142 ok(ret, "Expected success\n");
1144 /* Get a new handle to the Service Control Manager */
1145 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1146 ok(scm_handle != NULL, "Expected success\n");
1148 /* Get a handle to this new service */
1149 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1150 ok(svc_handle4 != NULL, "Expected success\n");
1152 /* Delete the service */
1153 ret = DeleteService(svc_handle4);
1154 ok(ret, "Expected success\n");
1156 /* We cannot create the same service again as it's still marked as 'being deleted'.
1157 * The reason is that we still have 4 open handles to this service even though we
1158 * closed the handle to the Service Control Manager in between.
1160 SetLastError(0xdeadbeef);
1161 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1162 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1163 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1164 todo_wine
1166 ok(!svc_handle5, "Expected failure\n");
1167 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1168 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1171 /* FIXME: Remove this when Wine is fixed */
1172 if (svc_handle5)
1174 DeleteService(svc_handle5);
1175 CloseServiceHandle(svc_handle5);
1178 /* Close all the handles to the service and try again */
1179 ret = CloseServiceHandle(svc_handle4);
1180 ok(ret, "Expected success\n");
1181 ret = CloseServiceHandle(svc_handle3);
1182 ok(ret, "Expected success\n");
1183 ret = CloseServiceHandle(svc_handle2);
1184 ok(ret, "Expected success\n");
1185 ret = CloseServiceHandle(svc_handle1);
1186 ok(ret, "Expected success\n");
1188 /* Wait a while. Doing a CreateService too soon will result again
1189 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1191 Sleep(1000);
1193 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1194 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1195 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1196 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1197 ok(svc_handle5 != NULL, "Expected success\n");
1199 /* Delete the service */
1200 ret = DeleteService(svc_handle5);
1201 ok(ret, "Expected success\n");
1203 /* Wait a while. Just in case one of the following tests does a CreateService again */
1204 Sleep(1000);
1206 CloseServiceHandle(svc_handle5);
1207 CloseServiceHandle(scm_handle);
1210 START_TEST(service)
1212 SC_HANDLE scm_handle;
1214 /* Bail out if we are on win98 */
1215 SetLastError(0xdeadbeef);
1216 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1218 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1220 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1221 return;
1223 CloseServiceHandle(scm_handle);
1225 /* First some parameter checking */
1226 test_open_scm();
1227 test_open_svc();
1228 test_create_delete_svc();
1229 test_get_displayname();
1230 test_get_servicekeyname();
1231 test_close();
1232 /* Test the creation, querying and deletion of a service */
1233 test_sequence();
1234 test_queryconfig2();
1235 /* The main reason for this test is to check if any refcounting is used
1236 * and what the rules are
1238 test_refcount();