push 535a8035db5d709ef8f05977281c2f1a0c4cce0a
[wine/hacks.git] / dlls / advapi32 / tests / service.c
blob829cfe7bf94a227e14e0d3cedc5b9eea1441c8d2
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 || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
70 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
71 CloseServiceHandle(scm_handle); /* Just in case */
73 /* Proper call with an empty hostname */
74 SetLastError(0xdeadbeef);
75 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
76 ok(scm_handle != NULL, "Expected success\n");
77 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
78 GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
79 GetLastError() == 0xdeadbeef /* XP */ ||
80 GetLastError() == ERROR_IO_PENDING /* W2K */,
81 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
82 CloseServiceHandle(scm_handle);
84 /* Again a correct one */
85 SetLastError(0xdeadbeef);
86 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
87 ok(scm_handle != NULL, "Expected success\n");
88 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
89 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
90 GetLastError() == ERROR_IO_PENDING /* W2K */,
91 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
92 CloseServiceHandle(scm_handle);
95 static void test_open_svc(void)
97 SC_HANDLE scm_handle, svc_handle;
98 CHAR displayname[4096];
99 DWORD displaysize;
101 /* All NULL (invalid access rights) */
102 SetLastError(0xdeadbeef);
103 svc_handle = OpenServiceA(NULL, NULL, 0);
104 ok(!svc_handle, "Expected failure\n");
105 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
107 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
109 /* NULL service */
110 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
111 SetLastError(0xdeadbeef);
112 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
113 ok(!svc_handle, "Expected failure\n");
114 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
115 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
116 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
118 /* Nonexistent service */
119 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
120 SetLastError(0xdeadbeef);
121 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
122 ok(!svc_handle, "Expected failure\n");
123 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
124 CloseServiceHandle(scm_handle);
126 /* Proper SCM handle but different access rights */
127 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
128 SetLastError(0xdeadbeef);
129 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
130 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
131 skip("Not enough rights to get a handle to the service\n");
132 else
134 ok(svc_handle != NULL, "Expected success\n");
135 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
136 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
137 GetLastError() == 0xdeadbeef /* XP, NT4 */,
138 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
139 CloseServiceHandle(svc_handle);
142 /* Test to show we can't open a service with the displayname */
144 /* Retrieve the needed size for the buffer */
145 displaysize = 0;
146 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
147 /* Get the displayname */
148 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
149 /* Try to open the service with this displayname, unless the displayname equals
150 * the servicename as that would defeat the purpose of this test.
152 if (!lstrcmpi(spooler, displayname))
154 skip("displayname equals servicename\n");
155 CloseServiceHandle(scm_handle);
156 return;
159 SetLastError(0xdeadbeef);
160 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
161 ok(!svc_handle, "Expected failure\n");
162 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
163 /* Just in case */
164 CloseServiceHandle(svc_handle);
166 CloseServiceHandle(scm_handle);
169 static void test_create_delete_svc(void)
171 SC_HANDLE scm_handle, svc_handle1;
172 CHAR username[UNLEN + 1], domain[MAX_PATH];
173 DWORD user_size = UNLEN + 1;
174 CHAR account[UNLEN + 3];
175 static const CHAR servicename [] = "Winetest";
176 static const CHAR pathname [] = "we_dont_care.exe";
177 static const CHAR empty [] = "";
178 static const CHAR password [] = "secret";
179 BOOL spooler_exists = FALSE;
180 BOOL ret;
181 CHAR display[4096];
182 DWORD display_size = sizeof(display);
184 /* Get the username and turn it into an account to be used in some tests */
185 GetUserNameA(username, &user_size);
186 /* Get the domainname to cater for that situation */
187 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
188 sprintf(account, "%s\\%s", domain, username);
189 else
190 sprintf(account, ".\\%s", username);
192 /* All NULL */
193 SetLastError(0xdeadbeef);
194 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
195 ok(!svc_handle1, "Expected failure\n");
196 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
198 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
200 /* Only a valid handle to the Service Control Manager */
201 SetLastError(0xdeadbeef);
202 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
203 ok(!svc_handle1, "Expected failure\n");
204 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
205 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
206 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
208 /* Now with a servicename */
209 SetLastError(0xdeadbeef);
210 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
211 ok(!svc_handle1, "Expected failure\n");
212 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
213 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
214 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
216 /* Or just a binary name */
217 SetLastError(0xdeadbeef);
218 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
219 ok(!svc_handle1, "Expected failure\n");
220 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
221 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
222 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
224 /* Both servicename and binary name (We only have connect rights) */
225 SetLastError(0xdeadbeef);
226 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
227 ok(!svc_handle1, "Expected failure\n");
228 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
230 /* They can even be empty at this stage of parameter checking */
231 SetLastError(0xdeadbeef);
232 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
233 ok(!svc_handle1, "Expected failure\n");
234 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
236 SetLastError(0xdeadbeef);
237 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
238 ok(!svc_handle1, "Expected failure\n");
239 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
241 /* Open the Service Control Manager with minimal rights for creation
242 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
244 CloseServiceHandle(scm_handle);
245 SetLastError(0xdeadbeef);
246 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
247 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
249 skip("Not enough rights to get a handle to the manager\n");
250 return;
253 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
255 /* Empty strings for servicename and binary name are checked */
256 SetLastError(0xdeadbeef);
257 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
258 ok(!svc_handle1, "Expected failure\n");
259 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
261 SetLastError(0xdeadbeef);
262 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
263 ok(!svc_handle1, "Expected failure\n");
264 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
266 SetLastError(0xdeadbeef);
267 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
268 ok(!svc_handle1, "Expected failure\n");
269 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
271 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
272 * an ERROR_INVALID_PARAMETER)
274 SetLastError(0xdeadbeef);
275 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
276 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
277 ok(!svc_handle1, "Expected failure\n");
278 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
280 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
282 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
283 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
285 SetLastError(0xdeadbeef);
286 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
287 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
288 ok(!svc_handle1, "Expected failure\n");
289 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
291 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
292 SetLastError(0xdeadbeef);
293 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
294 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
295 ok(!svc_handle1, "Expected failure\n");
296 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
298 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
299 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
301 SetLastError(0xdeadbeef);
302 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
303 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
304 ok(!svc_handle1, "Expected failure\n");
305 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
307 /* Illegal (start-type is not a mask and should only be one of the possibilities)
308 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
309 * it's most likely not the wanted start-type)
311 SetLastError(0xdeadbeef);
312 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
313 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
314 ok(!svc_handle1, "Expected failure\n");
315 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
317 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
318 SetLastError(0xdeadbeef);
319 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
320 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
321 ok(!svc_handle1, "Expected failure\n");
322 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
324 /* The service already exists (check first, just in case) */
325 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
326 if (svc_handle1)
328 spooler_exists = TRUE;
329 CloseServiceHandle(svc_handle1);
330 SetLastError(0xdeadbeef);
331 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
332 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
333 ok(!svc_handle1, "Expected failure\n");
334 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
336 else
337 skip("Spooler service doesn't exist\n");
339 /* To find an existing displayname we check the 'Spooler' service. Although the registry
340 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
341 * to the servicename and can't be used as well for a new displayname.
343 if (spooler_exists)
345 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
347 if (!ret)
348 skip("Could not retrieve a displayname for the Spooler service\n");
349 else
351 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
352 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
353 ok(!svc_handle1, "Expected failure\n");
354 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
355 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
358 else
359 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
361 /* Windows doesn't care about the access rights for creation (which makes
362 * sense as there is no service yet) as long as there are sufficient
363 * rights to the manager.
365 SetLastError(0xdeadbeef);
366 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
367 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
368 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
369 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
370 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
371 GetLastError() == ERROR_IO_PENDING /* W2K */,
372 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
374 /* DeleteService however must have proper rights */
375 SetLastError(0xdeadbeef);
376 ret = DeleteService(svc_handle1);
377 ok(!ret, "Expected failure\n");
378 ok(GetLastError() == ERROR_ACCESS_DENIED,
379 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
381 /* Open the service with minimal rights for deletion.
382 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
384 CloseServiceHandle(svc_handle1);
385 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
387 /* Now that we have the proper rights, we should be able to delete */
388 SetLastError(0xdeadbeef);
389 ret = DeleteService(svc_handle1);
390 ok(ret, "Expected success\n");
391 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
392 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
393 GetLastError() == ERROR_IO_PENDING /* W2K */,
394 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
396 CloseServiceHandle(svc_handle1);
398 CloseServiceHandle(scm_handle);
400 /* Wait a while. One of the following tests also does a CreateService for the
401 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
402 * error if we do this to quick. Vista seems more picky then the others.
404 Sleep(1000);
406 /* And a final NULL check */
407 SetLastError(0xdeadbeef);
408 ret = DeleteService(NULL);
409 ok(!ret, "Expected failure\n");
410 ok(GetLastError() == ERROR_INVALID_HANDLE,
411 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
414 static void test_get_displayname(void)
416 SC_HANDLE scm_handle, svc_handle;
417 BOOL ret;
418 CHAR displayname[4096];
419 WCHAR displaynameW[2048];
420 DWORD displaysize, tempsize, tempsizeW;
421 static const CHAR deadbeef[] = "Deadbeef";
422 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
423 static const CHAR servicename[] = "Winetest";
424 static const CHAR pathname[] = "we_dont_care.exe";
426 /* Having NULL for the size of the buffer will crash on W2K3 */
428 SetLastError(0xdeadbeef);
429 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
430 ok(!ret, "Expected failure\n");
431 ok(GetLastError() == ERROR_INVALID_HANDLE,
432 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
434 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
436 SetLastError(0xdeadbeef);
437 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
438 ok(!ret, "Expected failure\n");
439 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
440 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
441 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
443 SetLastError(0xdeadbeef);
444 displaysize = sizeof(displayname);
445 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
446 ok(!ret, "Expected failure\n");
447 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
448 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
449 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
451 /* Test for nonexistent service */
452 SetLastError(0xdeadbeef);
453 displaysize = -1;
454 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
455 ok(!ret, "Expected failure\n");
456 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
457 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
459 /* Check if 'Spooler' exists */
460 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
461 if (!svc_handle)
463 skip("Spooler service doesn't exist\n");
464 CloseServiceHandle(scm_handle);
465 return;
467 CloseServiceHandle(svc_handle);
469 /* Retrieve the needed size for the buffer */
470 SetLastError(0xdeadbeef);
471 displaysize = -1;
472 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
473 ok(!ret, "Expected failure\n");
474 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
475 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
476 tempsize = displaysize;
478 displaysize = 0;
479 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
480 ok(!ret, "Expected failure\n");
481 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
482 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
483 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
485 /* Buffer is too small */
486 SetLastError(0xdeadbeef);
487 displaysize = (tempsize / 2);
488 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
489 ok(!ret, "Expected failure\n");
490 ok(displaysize == tempsize, "Expected the needed buffersize\n");
491 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
492 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
494 /* First try with a buffer that should be big enough to hold
495 * the ANSI string (and terminating character). This succeeds on Windows
496 * although when asked (see above 2 tests) it will return twice the needed size.
498 SetLastError(0xdeadbeef);
499 displaysize = (tempsize / 2) + 1;
500 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
501 ok(ret, "Expected success\n");
502 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
503 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
504 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
505 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
506 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
508 /* Now with the original returned size */
509 SetLastError(0xdeadbeef);
510 displaysize = tempsize;
511 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
512 ok(ret, "Expected success\n");
513 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
514 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
515 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
516 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
517 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
519 /* And with a bigger than needed buffer */
520 SetLastError(0xdeadbeef);
521 displaysize = tempsize * 2;
522 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
523 ok(ret, "Expected success\n");
524 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
525 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
526 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
527 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
528 /* Test that shows that if the buffersize is enough, it's not changed */
529 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
530 ok(lstrlen(displayname) == tempsize/2,
531 "Expected the buffer to be twice the length of the string\n") ;
533 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
534 SetLastError(0xdeadbeef);
535 displaysize = -1;
536 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
537 ok(!ret, "Expected failure\n");
538 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
539 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
541 /* Buffer is too small */
542 SetLastError(0xdeadbeef);
543 tempsizeW = displaysize;
544 displaysize = tempsizeW / 2;
545 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
546 ok(!ret, "Expected failure\n");
547 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
548 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
549 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
551 /* Now with the original returned size */
552 SetLastError(0xdeadbeef);
553 displaysize = tempsizeW;
554 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
555 ok(!ret, "Expected failure\n");
556 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
557 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
558 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
560 /* And with a bigger than needed buffer */
561 SetLastError(0xdeadbeef);
562 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
563 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
564 ok(ret, "Expected success\n");
565 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
566 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
567 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
568 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
569 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
570 ok(lstrlenW(displaynameW) == displaysize,
571 "Expected the buffer to be the length of the string\n") ;
572 ok(tempsize / 2 == tempsizeW,
573 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
575 CloseServiceHandle(scm_handle);
577 /* Test for a service without a displayname (which is valid). This should return
578 * the servicename itself.
580 SetLastError(0xdeadbeef);
581 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
582 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
584 skip("Not enough rights to get a handle to the manager\n");
585 return;
588 SetLastError(0xdeadbeef);
589 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
590 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
591 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
592 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
593 if (!svc_handle)
595 CloseServiceHandle(scm_handle);
596 return;
599 /* Retrieve the needed size for the buffer */
600 SetLastError(0xdeadbeef);
601 displaysize = -1;
602 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
603 ok(!ret, "Expected failure\n");
604 ok(displaysize == lstrlen(servicename) * 2,
605 "Expected the displaysize to be twice the size of the servicename\n");
606 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
607 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
609 /* Buffer is too small */
610 SetLastError(0xdeadbeef);
611 tempsize = displaysize;
612 displaysize = (tempsize / 2);
613 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
614 ok(!ret, "Expected failure\n");
615 ok(displaysize == tempsize, "Expected the needed buffersize\n");
616 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
617 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
619 /* Get the displayname */
620 SetLastError(0xdeadbeef);
621 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
622 ok(ret, "Expected success\n");
623 ok(!lstrcmpi(displayname, servicename),
624 "Expected displayname to be %s, got %s\n", servicename, displayname);
625 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
626 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
627 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
628 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
630 /* Delete the service */
631 ret = DeleteService(svc_handle);
632 ok(ret, "Expected success\n");
634 CloseServiceHandle(svc_handle);
635 CloseServiceHandle(scm_handle);
637 /* Wait a while. Just in case one of the following tests does a CreateService again */
638 Sleep(1000);
641 static void test_get_servicekeyname(void)
643 SC_HANDLE scm_handle, svc_handle;
644 CHAR servicename[4096];
645 CHAR displayname[4096];
646 WCHAR servicenameW[4096];
647 WCHAR displaynameW[4096];
648 DWORD servicesize, displaysize, tempsize;
649 BOOL ret;
650 static const CHAR deadbeef[] = "Deadbeef";
651 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
653 /* Having NULL for the size of the buffer will crash on W2K3 */
655 SetLastError(0xdeadbeef);
656 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
657 ok(!ret, "Expected failure\n");
658 ok(GetLastError() == ERROR_INVALID_HANDLE,
659 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
661 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
663 servicesize = 200;
664 SetLastError(0xdeadbeef);
665 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
666 ok(!ret, "Expected failure\n");
667 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
668 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
669 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
670 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
672 /* Valid handle and buffer but no displayname */
673 servicesize = 200;
674 SetLastError(0xdeadbeef);
675 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
676 ok(!ret, "Expected failure\n");
677 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
678 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
679 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
680 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
682 /* Test for nonexistent displayname */
683 SetLastError(0xdeadbeef);
684 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
685 ok(!ret, "Expected failure\n");
686 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
687 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
688 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
690 servicesize = 15;
691 strcpy(servicename, "ABC");
692 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
693 ok(!ret, "Expected failure\n");
694 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
695 ok(servicename[0] == 0, "Service name not empty\n");
697 servicesize = 15;
698 servicenameW[0] = 'A';
699 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
700 ok(!ret, "Expected failure\n");
701 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
702 ok(servicenameW[0] == 0, "Service name not empty\n");
704 servicesize = 0;
705 strcpy(servicename, "ABC");
706 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
707 ok(!ret, "Expected failure\n");
708 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
709 ok(servicename[0] == 'A', "Service name changed\n");
711 servicesize = 0;
712 servicenameW[0] = 'A';
713 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
714 ok(!ret, "Expected failure\n");
715 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
716 ok(servicenameW[0] == 'A', "Service name changed\n");
718 /* Check if 'Spooler' exists */
719 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
720 if (!svc_handle)
722 skip("Spooler service doesn't exist\n");
723 CloseServiceHandle(scm_handle);
724 return;
726 CloseServiceHandle(svc_handle);
728 /* Get the displayname for the 'Spooler' service */
729 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
730 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
732 /* Retrieve the needed size for the buffer */
733 SetLastError(0xdeadbeef);
734 servicesize = 0;
735 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
736 ok(!ret, "Expected failure\n");
737 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
738 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
740 /* Valid call with the correct buffersize */
741 SetLastError(0xdeadbeef);
742 tempsize = servicesize;
743 servicesize *= 2;
744 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
745 ok(ret, "Expected success\n");
746 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
747 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
748 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
749 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
750 if (ret)
752 ok(lstrlen(servicename) == tempsize/2,
753 "Expected the buffer to be twice the length of the string\n") ;
754 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
755 ok(servicesize == (tempsize * 2),
756 "Expected servicesize not to change if buffer not insufficient\n") ;
759 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
760 SetLastError(0xdeadbeef);
761 servicesize *= 2;
762 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
763 ok(ret, "Expected success\n");
764 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
765 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
766 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
767 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
768 if (ret)
770 ok(lstrlen(servicename) == tempsize/2,
771 "Expected the buffer to be twice the length of the string\n") ;
772 ok(servicesize == lstrlenW(servicenameW),
773 "Expected servicesize not to change if buffer not insufficient\n") ;
776 SetLastError(0xdeadbeef);
777 servicesize = 3;
778 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
779 ok(!ret, "Expected failure\n");
780 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
781 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
782 ok(servicenameW[0] == 0, "Buffer not empty\n");
784 CloseServiceHandle(scm_handle);
787 static void test_close(void)
789 SC_HANDLE handle;
790 BOOL ret;
792 /* NULL handle */
793 SetLastError(0xdeadbeef);
794 ret = CloseServiceHandle(NULL);
795 ok(!ret, "Expected failure\n");
796 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
798 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
800 /* Proper call */
801 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
802 SetLastError(0xdeadbeef);
803 ret = CloseServiceHandle(handle);
804 ok(ret, "Expected success\n");
805 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
806 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
807 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
808 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
811 static void test_sequence(void)
813 SC_HANDLE scm_handle, svc_handle;
814 BOOL ret;
815 QUERY_SERVICE_CONFIGA *config;
816 DWORD given, needed;
817 static const CHAR servicename [] = "Winetest";
818 static const CHAR displayname [] = "Winetest dummy service";
819 static const CHAR displayname2[] = "Winetest dummy service (2)";
820 static const CHAR pathname [] = "we_dont_care.exe";
821 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
822 static const CHAR password [] = "";
823 static const CHAR empty [] = "";
824 static const CHAR localsystem [] = "LocalSystem";
826 SetLastError(0xdeadbeef);
827 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
829 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
831 skip("Not enough rights to get a handle to the manager\n");
832 return;
834 else
835 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
837 if (!scm_handle) return;
839 /* Create a dummy service */
840 SetLastError(0xdeadbeef);
841 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
842 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
843 pathname, NULL, NULL, dependencies, NULL, password);
845 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
847 /* We try and open the service and do the rest of the tests. Some could
848 * fail if the tests were changed between these runs.
850 trace("Deletion probably didn't work last time\n");
851 SetLastError(0xdeadbeef);
852 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
853 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
855 skip("Not enough rights to open the service\n");
856 CloseServiceHandle(scm_handle);
857 return;
859 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
861 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
863 skip("Not enough rights to create the service\n");
864 CloseServiceHandle(scm_handle);
865 return;
867 else
868 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
870 if (!svc_handle) return;
872 /* TODO:
873 * Before we do a QueryServiceConfig we should check the registry. This will make sure
874 * that the correct keys are used.
877 /* Request the size for the buffer */
878 SetLastError(0xdeadbeef);
879 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
880 ok(!ret, "Expected failure\n");
881 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
883 config = HeapAlloc(GetProcessHeap(), 0, needed);
884 given = needed;
885 SetLastError(0xdeadbeef);
886 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
887 ok(ret, "Expected success\n");
888 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
889 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
890 GetLastError() == ERROR_IO_PENDING /* W2K */,
891 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
892 todo_wine
894 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
896 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
897 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
898 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
899 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
900 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
901 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
902 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
903 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
904 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
905 /* TODO: Show the double 0 terminated string */
906 todo_wine
908 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
910 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
911 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
913 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
914 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
916 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
917 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
918 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
919 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
920 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
921 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
922 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
923 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
924 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
925 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
926 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
927 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
928 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
929 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
931 SetLastError(0xdeadbeef);
932 ret = DeleteService(svc_handle);
933 ok(ret, "Expected success\n");
934 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
935 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
936 GetLastError() == ERROR_IO_PENDING /* W2K */,
937 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
939 CloseServiceHandle(svc_handle);
941 /* Wait a while. The following test does a CreateService again */
942 Sleep(1000);
944 CloseServiceHandle(scm_handle);
945 HeapFree(GetProcessHeap(), 0, config);
948 static void test_queryconfig2(void)
950 SC_HANDLE scm_handle, svc_handle;
951 BOOL ret;
952 DWORD expected, needed;
953 BYTE buffer[MAX_PATH];
954 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
955 static const CHAR servicename [] = "Winetest";
956 static const CHAR displayname [] = "Winetest dummy service";
957 static const CHAR pathname [] = "we_dont_care.exe";
958 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
959 static const CHAR password [] = "";
960 static const CHAR description [] = "Description";
961 HMODULE dllhandle = GetModuleHandleA("advapi32.dll");
962 BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID)
963 = (void*)GetProcAddress(dllhandle, "ChangeServiceConfig2A");
964 BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
965 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2A");
966 BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
967 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2W");
968 if(!pQueryServiceConfig2A)
970 skip("function QueryServiceConfig2A not present\n");
971 return;
974 SetLastError(0xdeadbeef);
975 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
977 if (!scm_handle)
979 if(GetLastError() == ERROR_ACCESS_DENIED)
980 skip("Not enough rights to get a handle to the manager\n");
981 else
982 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
983 return;
986 /* Create a dummy service */
987 SetLastError(0xdeadbeef);
988 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
989 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
990 pathname, NULL, NULL, dependencies, NULL, password);
992 if (!svc_handle)
994 if(GetLastError() == ERROR_SERVICE_EXISTS)
996 /* We try and open the service and do the rest of the tests. Some could
997 * fail if the tests were changed between these runs.
999 trace("Deletion probably didn't work last time\n");
1000 SetLastError(0xdeadbeef);
1001 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1002 if (!svc_handle)
1004 if(GetLastError() == ERROR_ACCESS_DENIED)
1005 skip("Not enough rights to open the service\n");
1006 else
1007 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1008 CloseServiceHandle(scm_handle);
1009 return;
1012 if (GetLastError() == ERROR_ACCESS_DENIED)
1014 skip("Not enough rights to create the service\n");
1015 CloseServiceHandle(scm_handle);
1016 return;
1018 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1019 if (!svc_handle)
1021 CloseServiceHandle(scm_handle);
1022 return;
1025 SetLastError(0xdeadbeef);
1026 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1027 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1028 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1030 SetLastError(0xdeadbeef);
1031 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1032 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1033 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1035 SetLastError(0xdeadbeef);
1036 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1037 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1038 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1040 SetLastError(0xdeadbeef);
1041 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1042 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1043 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1044 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1046 SetLastError(0xdeadbeef);
1047 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1048 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1049 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1051 needed = 0;
1052 SetLastError(0xdeadbeef);
1053 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1054 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1055 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1056 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1058 needed = 0;
1059 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1060 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1061 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1062 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1063 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1065 SetLastError(0xdeadbeef);
1066 needed = 0;
1067 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1068 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1069 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1070 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1072 if(!pChangeServiceConfig2A)
1074 skip("function ChangeServiceConfig2A not present\n");
1075 goto cleanup;
1078 pConfig->lpDescription = (LPSTR) description;
1079 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1080 ok(ret, "ChangeServiceConfig2A failed\n");
1081 if (!ret) {
1082 goto cleanup;
1085 SetLastError(0xdeadbeef);
1086 needed = 0;
1087 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1088 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1089 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1090 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1091 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1093 SetLastError(0xdeadbeef);
1094 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1095 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1096 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1098 SetLastError(0xdeadbeef);
1099 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1100 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1101 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1102 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1104 SetLastError(0xdeadbeef);
1105 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1106 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1107 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1108 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1110 if(!pQueryServiceConfig2W)
1112 skip("function QueryServiceConfig2W not present\n");
1113 goto cleanup;
1115 SetLastError(0xdeadbeef);
1116 needed = 0;
1117 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1118 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1119 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1120 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1121 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1123 SetLastError(0xdeadbeef);
1124 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1125 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1127 cleanup:
1128 DeleteService(svc_handle);
1130 CloseServiceHandle(svc_handle);
1132 /* Wait a while. The following test does a CreateService again */
1133 Sleep(1000);
1135 CloseServiceHandle(scm_handle);
1138 static void test_refcount(void)
1140 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1141 static const CHAR servicename [] = "Winetest";
1142 static const CHAR pathname [] = "we_dont_care.exe";
1143 BOOL ret;
1145 /* Get a handle to the Service Control Manager */
1146 SetLastError(0xdeadbeef);
1147 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1148 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1150 skip("Not enough rights to get a handle to the manager\n");
1151 return;
1154 /* Create a service */
1155 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1156 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1157 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1158 ok(svc_handle1 != NULL, "Expected success\n");
1160 /* Get a handle to this new service */
1161 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1162 ok(svc_handle2 != NULL, "Expected success\n");
1164 /* Get another handle to this new service */
1165 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1166 ok(svc_handle3 != NULL, "Expected success\n");
1168 /* Check if we can close the handle to the Service Control Manager */
1169 ret = CloseServiceHandle(scm_handle);
1170 ok(ret, "Expected success\n");
1172 /* Get a new handle to the Service Control Manager */
1173 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1174 ok(scm_handle != NULL, "Expected success\n");
1176 /* Get a handle to this new service */
1177 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1178 ok(svc_handle4 != NULL, "Expected success\n");
1180 /* Delete the service */
1181 ret = DeleteService(svc_handle4);
1182 ok(ret, "Expected success\n");
1184 /* We cannot create the same service again as it's still marked as 'being deleted'.
1185 * The reason is that we still have 4 open handles to this service even though we
1186 * closed the handle to the Service Control Manager in between.
1188 SetLastError(0xdeadbeef);
1189 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1190 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1191 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1192 todo_wine
1194 ok(!svc_handle5, "Expected failure\n");
1195 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1196 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1199 /* FIXME: Remove this when Wine is fixed */
1200 if (svc_handle5)
1202 DeleteService(svc_handle5);
1203 CloseServiceHandle(svc_handle5);
1206 /* Close all the handles to the service and try again */
1207 ret = CloseServiceHandle(svc_handle4);
1208 ok(ret, "Expected success\n");
1209 ret = CloseServiceHandle(svc_handle3);
1210 ok(ret, "Expected success\n");
1211 ret = CloseServiceHandle(svc_handle2);
1212 ok(ret, "Expected success\n");
1213 ret = CloseServiceHandle(svc_handle1);
1214 ok(ret, "Expected success\n");
1216 /* Wait a while. Doing a CreateService too soon will result again
1217 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1219 Sleep(1000);
1221 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1222 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1223 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1224 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1225 ok(svc_handle5 != NULL, "Expected success\n");
1227 /* Delete the service */
1228 ret = DeleteService(svc_handle5);
1229 ok(ret, "Expected success\n");
1231 /* Wait a while. Just in case one of the following tests does a CreateService again */
1232 Sleep(1000);
1234 CloseServiceHandle(svc_handle5);
1235 CloseServiceHandle(scm_handle);
1238 START_TEST(service)
1240 SC_HANDLE scm_handle;
1242 /* Bail out if we are on win98 */
1243 SetLastError(0xdeadbeef);
1244 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1246 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1248 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1249 return;
1251 CloseServiceHandle(scm_handle);
1253 /* First some parameter checking */
1254 test_open_scm();
1255 test_open_svc();
1256 test_create_delete_svc();
1257 test_get_displayname();
1258 test_get_servicekeyname();
1259 test_close();
1260 /* Test the creation, querying and deletion of a service */
1261 test_sequence();
1262 test_queryconfig2();
1263 /* The main reason for this test is to check if any refcounting is used
1264 * and what the rules are
1266 test_refcount();