Assorted spelling fixes.
[wine/gsoc_dplay.git] / dlls / advapi32 / tests / service.c
blobcd6d82c26b9793b6dfdef2724b56f77b3c6e4d75
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;
97 CHAR displayname[4096];
98 DWORD displaysize;
100 /* All NULL (invalid access rights) */
101 SetLastError(0xdeadbeef);
102 svc_handle = OpenServiceA(NULL, NULL, 0);
103 ok(!svc_handle, "Expected failure\n");
104 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
106 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
108 /* NULL service */
109 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
110 SetLastError(0xdeadbeef);
111 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
112 ok(!svc_handle, "Expected failure\n");
113 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
114 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
115 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
117 /* Nonexistent service */
118 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
119 SetLastError(0xdeadbeef);
120 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
121 ok(!svc_handle, "Expected failure\n");
122 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
123 CloseServiceHandle(scm_handle);
125 /* Proper SCM handle but different access rights */
126 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
127 SetLastError(0xdeadbeef);
128 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
129 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
130 skip("Not enough rights to get a handle to the service\n");
131 else
133 ok(svc_handle != NULL, "Expected success\n");
134 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
135 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
136 GetLastError() == 0xdeadbeef /* XP, NT4 */,
137 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
138 CloseServiceHandle(svc_handle);
141 /* Test to show we can't open a service with the displayname */
143 /* Retrieve the needed size for the buffer */
144 displaysize = 0;
145 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
146 /* Get the displayname */
147 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
148 /* Try to open the service with this displayname, unless the displayname equals
149 * the servicename as that would defeat the purpose of this test.
151 if (!lstrcmpi(spooler, displayname))
153 skip("displayname equals servicename\n");
154 CloseServiceHandle(scm_handle);
155 return;
158 SetLastError(0xdeadbeef);
159 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
160 ok(!svc_handle, "Expected failure\n");
161 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
162 /* Just in case */
163 CloseServiceHandle(svc_handle);
165 CloseServiceHandle(scm_handle);
168 static void test_create_delete_svc(void)
170 SC_HANDLE scm_handle, svc_handle1;
171 CHAR username[UNLEN + 1], domain[MAX_PATH];
172 DWORD user_size = UNLEN + 1;
173 CHAR account[UNLEN + 3];
174 static const CHAR servicename [] = "Winetest";
175 static const CHAR pathname [] = "we_dont_care.exe";
176 static const CHAR empty [] = "";
177 static const CHAR password [] = "secret";
178 BOOL spooler_exists = FALSE;
179 BOOL ret;
180 CHAR display[4096];
181 DWORD display_size = sizeof(display);
183 /* Get the username and turn it into an account to be used in some tests */
184 GetUserNameA(username, &user_size);
185 /* Get the domainname to cater for that situation */
186 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
187 sprintf(account, "%s\\%s", domain, username);
188 else
189 sprintf(account, ".\\%s", username);
191 /* All NULL */
192 SetLastError(0xdeadbeef);
193 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
194 ok(!svc_handle1, "Expected failure\n");
195 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
197 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
199 /* Only a valid handle to the Service Control Manager */
200 SetLastError(0xdeadbeef);
201 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
202 ok(!svc_handle1, "Expected failure\n");
203 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
204 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
205 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
207 /* Now with a servicename */
208 SetLastError(0xdeadbeef);
209 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
210 ok(!svc_handle1, "Expected failure\n");
211 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
212 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
213 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
215 /* Or just a binary name */
216 SetLastError(0xdeadbeef);
217 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
218 ok(!svc_handle1, "Expected failure\n");
219 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
220 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
221 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
223 /* Both servicename and binary name (We only have connect rights) */
224 SetLastError(0xdeadbeef);
225 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
226 ok(!svc_handle1, "Expected failure\n");
227 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
229 /* They can even be empty at this stage of parameter checking */
230 SetLastError(0xdeadbeef);
231 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
232 ok(!svc_handle1, "Expected failure\n");
233 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
235 SetLastError(0xdeadbeef);
236 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
237 ok(!svc_handle1, "Expected failure\n");
238 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
240 /* Open the Service Control Manager with minimal rights for creation
241 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
243 CloseServiceHandle(scm_handle);
244 SetLastError(0xdeadbeef);
245 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
246 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
248 skip("Not enough rights to get a handle to the manager\n");
249 return;
252 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
254 /* Empty strings for servicename and binary name are checked */
255 SetLastError(0xdeadbeef);
256 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
257 ok(!svc_handle1, "Expected failure\n");
258 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
260 SetLastError(0xdeadbeef);
261 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
262 ok(!svc_handle1, "Expected failure\n");
263 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
265 SetLastError(0xdeadbeef);
266 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
267 ok(!svc_handle1, "Expected failure\n");
268 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
270 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
271 * an ERROR_INVALID_PARAMETER)
273 SetLastError(0xdeadbeef);
274 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
275 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
276 ok(!svc_handle1, "Expected failure\n");
277 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
279 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
281 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
282 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
284 SetLastError(0xdeadbeef);
285 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
286 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
287 ok(!svc_handle1, "Expected failure\n");
288 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
290 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
291 SetLastError(0xdeadbeef);
292 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
293 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
294 ok(!svc_handle1, "Expected failure\n");
295 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
297 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
298 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
300 SetLastError(0xdeadbeef);
301 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
302 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
303 ok(!svc_handle1, "Expected failure\n");
304 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
306 /* Illegal (start-type is not a mask and should only be one of the possibilities)
307 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
308 * it's most likely not the wanted start-type)
310 SetLastError(0xdeadbeef);
311 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
312 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
313 ok(!svc_handle1, "Expected failure\n");
314 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
316 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
317 SetLastError(0xdeadbeef);
318 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
319 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
320 ok(!svc_handle1, "Expected failure\n");
321 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
323 /* The service already exists (check first, just in case) */
324 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
325 if (svc_handle1)
327 spooler_exists = TRUE;
328 CloseServiceHandle(svc_handle1);
329 SetLastError(0xdeadbeef);
330 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
331 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
332 ok(!svc_handle1, "Expected failure\n");
333 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
335 else
336 skip("Spooler service doesn't exist\n");
338 /* To find an existing displayname we check the 'Spooler' service. Although the registry
339 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
340 * to the servicename and can't be used as well for a new displayname.
342 if (spooler_exists)
344 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
346 if (!ret)
347 skip("Could not retrieve a displayname for the Spooler service\n");
348 else
350 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
351 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
352 ok(!svc_handle1, "Expected failure\n");
353 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
354 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
357 else
358 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
360 /* Windows doesn't care about the access rights for creation (which makes
361 * sense as there is no service yet) as long as there are sufficient
362 * rights to the manager.
364 SetLastError(0xdeadbeef);
365 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
366 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
367 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
368 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
369 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
370 GetLastError() == ERROR_IO_PENDING /* W2K */,
371 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
373 /* DeleteService however must have proper rights */
374 SetLastError(0xdeadbeef);
375 ret = DeleteService(svc_handle1);
376 ok(!ret, "Expected failure\n");
377 ok(GetLastError() == ERROR_ACCESS_DENIED,
378 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
380 /* Open the service with minimal rights for deletion.
381 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
383 CloseServiceHandle(svc_handle1);
384 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
386 /* Now that we have the proper rights, we should be able to delete */
387 SetLastError(0xdeadbeef);
388 ret = DeleteService(svc_handle1);
389 ok(ret, "Expected success\n");
390 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
391 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
392 GetLastError() == ERROR_IO_PENDING /* W2K */,
393 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
395 CloseServiceHandle(svc_handle1);
397 CloseServiceHandle(scm_handle);
399 /* Wait a while. One of the following tests also does a CreateService for the
400 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
401 * error if we do this to quick. Vista seems more picky then the others.
403 Sleep(1000);
405 /* And a final NULL check */
406 SetLastError(0xdeadbeef);
407 ret = DeleteService(NULL);
408 ok(!ret, "Expected failure\n");
409 ok(GetLastError() == ERROR_INVALID_HANDLE,
410 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
413 static void test_get_displayname(void)
415 SC_HANDLE scm_handle, svc_handle;
416 BOOL ret;
417 CHAR displayname[4096];
418 WCHAR displaynameW[2048];
419 DWORD displaysize, tempsize, tempsizeW;
420 static const CHAR deadbeef[] = "Deadbeef";
421 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
422 static const CHAR servicename[] = "Winetest";
423 static const CHAR pathname[] = "we_dont_care.exe";
425 /* Having NULL for the size of the buffer will crash on W2K3 */
427 SetLastError(0xdeadbeef);
428 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
429 ok(!ret, "Expected failure\n");
430 ok(GetLastError() == ERROR_INVALID_HANDLE,
431 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
433 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
435 SetLastError(0xdeadbeef);
436 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
437 ok(!ret, "Expected failure\n");
438 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
439 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
440 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
442 SetLastError(0xdeadbeef);
443 displaysize = sizeof(displayname);
444 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
445 ok(!ret, "Expected failure\n");
446 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
447 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
448 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
450 /* Test for nonexistent service */
451 SetLastError(0xdeadbeef);
452 displaysize = -1;
453 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
454 ok(!ret, "Expected failure\n");
455 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
456 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
458 /* Check if 'Spooler' exists */
459 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
460 if (!svc_handle)
462 skip("Spooler service doesn't exist\n");
463 CloseServiceHandle(scm_handle);
464 return;
466 CloseServiceHandle(svc_handle);
468 /* Retrieve the needed size for the buffer */
469 SetLastError(0xdeadbeef);
470 displaysize = -1;
471 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
472 ok(!ret, "Expected failure\n");
473 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
474 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
475 tempsize = displaysize;
477 displaysize = 0;
478 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
479 ok(!ret, "Expected failure\n");
480 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
481 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
482 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
484 /* Buffer is too small */
485 SetLastError(0xdeadbeef);
486 displaysize = (tempsize / 2);
487 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
488 ok(!ret, "Expected failure\n");
489 ok(displaysize == tempsize, "Expected the needed buffersize\n");
490 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
491 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
493 /* First try with a buffer that should be big enough to hold
494 * the ANSI string (and terminating character). This succeeds on Windows
495 * although when asked (see above 2 tests) it will return twice the needed size.
497 SetLastError(0xdeadbeef);
498 displaysize = (tempsize / 2) + 1;
499 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
500 ok(ret, "Expected success\n");
501 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
502 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
503 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
504 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
505 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
507 /* Now with the original returned size */
508 SetLastError(0xdeadbeef);
509 displaysize = tempsize;
510 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
511 ok(ret, "Expected success\n");
512 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
513 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
514 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
515 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
516 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
518 /* And with a bigger than needed buffer */
519 SetLastError(0xdeadbeef);
520 displaysize = tempsize * 2;
521 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
522 ok(ret, "Expected success\n");
523 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
524 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
525 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
526 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
527 /* Test that shows that if the buffersize is enough, it's not changed */
528 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
529 ok(lstrlen(displayname) == tempsize/2,
530 "Expected the buffer to be twice the length of the string\n") ;
532 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
533 SetLastError(0xdeadbeef);
534 displaysize = -1;
535 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
536 ok(!ret, "Expected failure\n");
537 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
538 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
540 /* Buffer is too small */
541 SetLastError(0xdeadbeef);
542 tempsizeW = displaysize;
543 displaysize = tempsizeW / 2;
544 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
545 ok(!ret, "Expected failure\n");
546 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
547 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
548 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
550 /* Now with the original returned size */
551 SetLastError(0xdeadbeef);
552 displaysize = tempsizeW;
553 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
554 ok(!ret, "Expected failure\n");
555 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
556 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
557 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
559 /* And with a bigger than needed buffer */
560 SetLastError(0xdeadbeef);
561 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
562 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
563 ok(ret, "Expected success\n");
564 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
565 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
566 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
567 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
568 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
569 ok(lstrlenW(displaynameW) == displaysize,
570 "Expected the buffer to be the length of the string\n") ;
571 ok(tempsize / 2 == tempsizeW,
572 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
574 CloseServiceHandle(scm_handle);
576 /* Test for a service without a displayname (which is valid). This should return
577 * the servicename itself.
579 SetLastError(0xdeadbeef);
580 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
581 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
583 skip("Not enough rights to get a handle to the manager\n");
584 return;
587 SetLastError(0xdeadbeef);
588 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
589 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
590 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
591 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
592 if (!svc_handle)
594 CloseServiceHandle(scm_handle);
595 return;
598 /* Retrieve the needed size for the buffer */
599 SetLastError(0xdeadbeef);
600 displaysize = -1;
601 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
602 ok(!ret, "Expected failure\n");
603 ok(displaysize == lstrlen(servicename) * 2,
604 "Expected the displaysize to be twice the size of the servicename\n");
605 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
606 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
608 /* Buffer is too small */
609 SetLastError(0xdeadbeef);
610 tempsize = displaysize;
611 displaysize = (tempsize / 2);
612 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
613 ok(!ret, "Expected failure\n");
614 ok(displaysize == tempsize, "Expected the needed buffersize\n");
615 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
616 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
618 /* Get the displayname */
619 SetLastError(0xdeadbeef);
620 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
621 ok(ret, "Expected success\n");
622 ok(!lstrcmpi(displayname, servicename),
623 "Expected displayname to be %s, got %s\n", servicename, displayname);
624 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
625 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
626 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
627 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
629 /* Delete the service */
630 ret = DeleteService(svc_handle);
631 ok(ret, "Expected success\n");
633 CloseServiceHandle(svc_handle);
634 CloseServiceHandle(scm_handle);
636 /* Wait a while. Just in case one of the following tests does a CreateService again */
637 Sleep(1000);
640 static void test_get_servicekeyname(void)
642 SC_HANDLE scm_handle, svc_handle;
643 CHAR servicename[4096];
644 CHAR displayname[4096];
645 WCHAR servicenameW[4096];
646 WCHAR displaynameW[4096];
647 DWORD servicesize, displaysize, tempsize;
648 BOOL ret;
649 static const CHAR deadbeef[] = "Deadbeef";
650 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
652 /* Having NULL for the size of the buffer will crash on W2K3 */
654 SetLastError(0xdeadbeef);
655 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
656 ok(!ret, "Expected failure\n");
657 ok(GetLastError() == ERROR_INVALID_HANDLE,
658 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
660 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
662 servicesize = 200;
663 SetLastError(0xdeadbeef);
664 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
665 ok(!ret, "Expected failure\n");
666 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
667 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
668 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
669 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
671 /* Valid handle and buffer but no displayname */
672 servicesize = 200;
673 SetLastError(0xdeadbeef);
674 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
675 ok(!ret, "Expected failure\n");
676 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
677 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
678 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
679 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
681 /* Test for nonexistent displayname */
682 SetLastError(0xdeadbeef);
683 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
684 ok(!ret, "Expected failure\n");
685 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
686 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
687 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
689 servicesize = 15;
690 strcpy(servicename, "ABC");
691 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
692 ok(!ret, "Expected failure\n");
693 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
694 ok(servicename[0] == 0, "Service name not empty\n");
696 servicesize = 15;
697 servicenameW[0] = 'A';
698 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
699 ok(!ret, "Expected failure\n");
700 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
701 ok(servicenameW[0] == 0, "Service name not empty\n");
703 servicesize = 0;
704 strcpy(servicename, "ABC");
705 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
706 ok(!ret, "Expected failure\n");
707 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
708 ok(servicename[0] == 'A', "Service name changed\n");
710 servicesize = 0;
711 servicenameW[0] = 'A';
712 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
713 ok(!ret, "Expected failure\n");
714 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
715 ok(servicenameW[0] == 'A', "Service name changed\n");
717 /* Check if 'Spooler' exists */
718 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
719 if (!svc_handle)
721 skip("Spooler service doesn't exist\n");
722 CloseServiceHandle(scm_handle);
723 return;
725 CloseServiceHandle(svc_handle);
727 /* Get the displayname for the 'Spooler' service */
728 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
729 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
731 /* Retrieve the needed size for the buffer */
732 SetLastError(0xdeadbeef);
733 servicesize = 0;
734 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
735 ok(!ret, "Expected failure\n");
736 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
737 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
739 /* Valid call with the correct buffersize */
740 SetLastError(0xdeadbeef);
741 tempsize = servicesize;
742 servicesize *= 2;
743 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
744 ok(ret, "Expected success\n");
745 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
746 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
747 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
748 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
749 if (ret)
751 ok(lstrlen(servicename) == tempsize/2,
752 "Expected the buffer to be twice the length of the string\n") ;
753 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
754 ok(servicesize == (tempsize * 2),
755 "Expected servicesize not to change if buffer not insufficient\n") ;
758 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
759 SetLastError(0xdeadbeef);
760 servicesize *= 2;
761 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
762 ok(ret, "Expected success\n");
763 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
764 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
765 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
766 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
767 if (ret)
769 ok(lstrlen(servicename) == tempsize/2,
770 "Expected the buffer to be twice the length of the string\n") ;
771 ok(servicesize == lstrlenW(servicenameW),
772 "Expected servicesize not to change if buffer not insufficient\n") ;
775 SetLastError(0xdeadbeef);
776 servicesize = 3;
777 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
778 ok(!ret, "Expected failure\n");
779 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
780 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
781 ok(servicenameW[0] == 0, "Buffer not empty\n");
783 CloseServiceHandle(scm_handle);
786 static void test_close(void)
788 SC_HANDLE handle;
789 BOOL ret;
791 /* NULL handle */
792 SetLastError(0xdeadbeef);
793 ret = CloseServiceHandle(NULL);
794 ok(!ret, "Expected failure\n");
795 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
797 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
799 /* Proper call */
800 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
801 SetLastError(0xdeadbeef);
802 ret = CloseServiceHandle(handle);
803 ok(ret, "Expected success\n");
804 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
805 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
806 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
807 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
810 static void test_sequence(void)
812 SC_HANDLE scm_handle, svc_handle;
813 BOOL ret;
814 QUERY_SERVICE_CONFIGA *config;
815 DWORD given, needed;
816 static const CHAR servicename [] = "Winetest";
817 static const CHAR displayname [] = "Winetest dummy service";
818 static const CHAR displayname2[] = "Winetest dummy service (2)";
819 static const CHAR pathname [] = "we_dont_care.exe";
820 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
821 static const CHAR password [] = "";
822 static const CHAR empty [] = "";
823 static const CHAR localsystem [] = "LocalSystem";
825 SetLastError(0xdeadbeef);
826 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
828 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
830 skip("Not enough rights to get a handle to the manager\n");
831 return;
833 else
834 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
836 if (!scm_handle) return;
838 /* Create a dummy service */
839 SetLastError(0xdeadbeef);
840 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
841 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
842 pathname, NULL, NULL, dependencies, NULL, password);
844 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
846 /* We try and open the service and do the rest of the tests. Some could
847 * fail if the tests were changed between these runs.
849 trace("Deletion probably didn't work last time\n");
850 SetLastError(0xdeadbeef);
851 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
852 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
854 skip("Not enough rights to open the service\n");
855 CloseServiceHandle(scm_handle);
856 return;
858 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
860 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
862 skip("Not enough rights to create the service\n");
863 CloseServiceHandle(scm_handle);
864 return;
866 else
867 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
869 if (!svc_handle) return;
871 /* TODO:
872 * Before we do a QueryServiceConfig we should check the registry. This will make sure
873 * that the correct keys are used.
876 /* Request the size for the buffer */
877 SetLastError(0xdeadbeef);
878 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
879 ok(!ret, "Expected failure\n");
880 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
882 config = HeapAlloc(GetProcessHeap(), 0, needed);
883 given = needed;
884 SetLastError(0xdeadbeef);
885 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
886 ok(ret, "Expected success\n");
887 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
888 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
889 GetLastError() == ERROR_IO_PENDING /* W2K */,
890 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
891 todo_wine
893 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
895 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
896 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
897 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
898 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
899 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
900 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
901 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
902 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
903 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
904 /* TODO: Show the double 0 terminated string */
905 todo_wine
907 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
909 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
910 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
912 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
913 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
915 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
916 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
917 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
918 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
919 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
920 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
921 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
922 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
923 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
924 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
925 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
926 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
927 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
928 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
930 SetLastError(0xdeadbeef);
931 ret = DeleteService(svc_handle);
932 ok(ret, "Expected success\n");
933 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
934 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
935 GetLastError() == ERROR_IO_PENDING /* W2K */,
936 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
938 CloseServiceHandle(svc_handle);
940 /* Wait a while. The following test does a CreateService again */
941 Sleep(1000);
943 CloseServiceHandle(scm_handle);
944 HeapFree(GetProcessHeap(), 0, config);
947 static void test_queryconfig2(void)
949 SC_HANDLE scm_handle, svc_handle;
950 BOOL ret;
951 DWORD expected, needed;
952 BYTE buffer[MAX_PATH];
953 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
954 static const CHAR servicename [] = "Winetest";
955 static const CHAR displayname [] = "Winetest dummy service";
956 static const CHAR pathname [] = "we_dont_care.exe";
957 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
958 static const CHAR password [] = "";
959 static const CHAR description [] = "Description";
960 HMODULE dllhandle = GetModuleHandleA("advapi32.dll");
961 BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID)
962 = (void*)GetProcAddress(dllhandle, "ChangeServiceConfig2A");
963 BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
964 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2A");
965 BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
966 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2W");
967 if(!pQueryServiceConfig2A)
969 skip("function QueryServiceConfig2A not present\n");
970 return;
973 SetLastError(0xdeadbeef);
974 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
976 if (!scm_handle)
978 if(GetLastError() == ERROR_ACCESS_DENIED)
979 skip("Not enough rights to get a handle to the manager\n");
980 else
981 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
982 return;
985 /* Create a dummy service */
986 SetLastError(0xdeadbeef);
987 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
988 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
989 pathname, NULL, NULL, dependencies, NULL, password);
991 if (!svc_handle)
993 if(GetLastError() == ERROR_SERVICE_EXISTS)
995 /* We try and open the service and do the rest of the tests. Some could
996 * fail if the tests were changed between these runs.
998 trace("Deletion probably didn't work last time\n");
999 SetLastError(0xdeadbeef);
1000 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1001 if (!svc_handle)
1003 if(GetLastError() == ERROR_ACCESS_DENIED)
1004 skip("Not enough rights to open the service\n");
1005 else
1006 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1007 CloseServiceHandle(scm_handle);
1008 return;
1011 if (GetLastError() == ERROR_ACCESS_DENIED)
1013 skip("Not enough rights to create the service\n");
1014 CloseServiceHandle(scm_handle);
1015 return;
1017 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1018 if (!svc_handle)
1020 CloseServiceHandle(scm_handle);
1021 return;
1024 SetLastError(0xdeadbeef);
1025 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1026 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1027 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1029 SetLastError(0xdeadbeef);
1030 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1031 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1032 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1034 SetLastError(0xdeadbeef);
1035 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1036 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1037 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1039 SetLastError(0xdeadbeef);
1040 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1041 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1042 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1043 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1045 SetLastError(0xdeadbeef);
1046 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1047 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1048 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1050 needed = 0;
1051 SetLastError(0xdeadbeef);
1052 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1053 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1054 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1055 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1057 needed = 0;
1058 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1059 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1060 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1061 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1062 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1064 SetLastError(0xdeadbeef);
1065 needed = 0;
1066 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1067 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1068 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1069 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1071 if(!pChangeServiceConfig2A)
1073 skip("function ChangeServiceConfig2A not present\n");
1074 goto cleanup;
1077 pConfig->lpDescription = (LPSTR) description;
1078 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1079 ok(ret, "ChangeServiceConfig2A failed\n");
1080 if (!ret) {
1081 goto cleanup;
1084 SetLastError(0xdeadbeef);
1085 needed = 0;
1086 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1087 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1088 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1089 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1090 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1092 SetLastError(0xdeadbeef);
1093 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1094 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1095 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1097 SetLastError(0xdeadbeef);
1098 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1099 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1100 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1101 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1103 SetLastError(0xdeadbeef);
1104 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1105 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1106 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1107 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1109 if(!pQueryServiceConfig2W)
1111 skip("function QueryServiceConfig2W not present\n");
1112 goto cleanup;
1114 SetLastError(0xdeadbeef);
1115 needed = 0;
1116 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1117 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1118 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1119 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1120 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1122 SetLastError(0xdeadbeef);
1123 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1124 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1126 cleanup:
1127 DeleteService(svc_handle);
1129 CloseServiceHandle(svc_handle);
1131 /* Wait a while. The following test does a CreateService again */
1132 Sleep(1000);
1134 CloseServiceHandle(scm_handle);
1137 static void test_refcount(void)
1139 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1140 static const CHAR servicename [] = "Winetest";
1141 static const CHAR pathname [] = "we_dont_care.exe";
1142 BOOL ret;
1144 /* Get a handle to the Service Control Manager */
1145 SetLastError(0xdeadbeef);
1146 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1147 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1149 skip("Not enough rights to get a handle to the manager\n");
1150 return;
1153 /* Create a service */
1154 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1155 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1156 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1157 ok(svc_handle1 != NULL, "Expected success\n");
1159 /* Get a handle to this new service */
1160 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1161 ok(svc_handle2 != NULL, "Expected success\n");
1163 /* Get another handle to this new service */
1164 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1165 ok(svc_handle3 != NULL, "Expected success\n");
1167 /* Check if we can close the handle to the Service Control Manager */
1168 ret = CloseServiceHandle(scm_handle);
1169 ok(ret, "Expected success\n");
1171 /* Get a new handle to the Service Control Manager */
1172 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1173 ok(scm_handle != NULL, "Expected success\n");
1175 /* Get a handle to this new service */
1176 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1177 ok(svc_handle4 != NULL, "Expected success\n");
1179 /* Delete the service */
1180 ret = DeleteService(svc_handle4);
1181 ok(ret, "Expected success\n");
1183 /* We cannot create the same service again as it's still marked as 'being deleted'.
1184 * The reason is that we still have 4 open handles to this service even though we
1185 * closed the handle to the Service Control Manager in between.
1187 SetLastError(0xdeadbeef);
1188 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1189 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1190 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1191 todo_wine
1193 ok(!svc_handle5, "Expected failure\n");
1194 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1195 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1198 /* FIXME: Remove this when Wine is fixed */
1199 if (svc_handle5)
1201 DeleteService(svc_handle5);
1202 CloseServiceHandle(svc_handle5);
1205 /* Close all the handles to the service and try again */
1206 ret = CloseServiceHandle(svc_handle4);
1207 ok(ret, "Expected success\n");
1208 ret = CloseServiceHandle(svc_handle3);
1209 ok(ret, "Expected success\n");
1210 ret = CloseServiceHandle(svc_handle2);
1211 ok(ret, "Expected success\n");
1212 ret = CloseServiceHandle(svc_handle1);
1213 ok(ret, "Expected success\n");
1215 /* Wait a while. Doing a CreateService too soon will result again
1216 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1218 Sleep(1000);
1220 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1221 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1222 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1223 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1224 ok(svc_handle5 != NULL, "Expected success\n");
1226 /* Delete the service */
1227 ret = DeleteService(svc_handle5);
1228 ok(ret, "Expected success\n");
1230 /* Wait a while. Just in case one of the following tests does a CreateService again */
1231 Sleep(1000);
1233 CloseServiceHandle(svc_handle5);
1234 CloseServiceHandle(scm_handle);
1237 START_TEST(service)
1239 SC_HANDLE scm_handle;
1241 /* Bail out if we are on win98 */
1242 SetLastError(0xdeadbeef);
1243 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1245 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1247 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1248 return;
1250 CloseServiceHandle(scm_handle);
1252 /* First some parameter checking */
1253 test_open_scm();
1254 test_open_svc();
1255 test_create_delete_svc();
1256 test_get_displayname();
1257 test_get_servicekeyname();
1258 test_close();
1259 /* Test the creation, querying and deletion of a service */
1260 test_sequence();
1261 test_queryconfig2();
1262 /* The main reason for this test is to check if any refcounting is used
1263 * and what the rules are
1265 test_refcount();