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
32 #include "wine/test.h"
34 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
36 static void test_open_scm(void)
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");
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];
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 */
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");
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 */
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 */
149 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
150 ok(!svc_handle, "Expected failure\n");
151 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
153 CloseServiceHandle(svc_handle);
155 CloseServiceHandle(scm_handle);
158 static void test_create_delete_svc(void)
160 SC_HANDLE scm_handle, svc_handle1;
161 CHAR username[UNLEN + 1], domain[MAX_PATH];
162 DWORD user_size = UNLEN + 1;
163 CHAR account[UNLEN + 3];
164 static const CHAR servicename [] = "Winetest";
165 static const CHAR pathname [] = "we_dont_care.exe";
166 static const CHAR empty [] = "";
167 static const CHAR password [] = "secret";
168 BOOL spooler_exists = FALSE;
171 DWORD display_size = sizeof(display);
173 /* Get the username and turn it into an account to be used in some tests */
174 GetUserNameA(username, &user_size);
175 /* Get the domainname to cater for that situation */
176 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
177 sprintf(account, "%s\\%s", domain, username);
179 sprintf(account, ".\\%s", username);
182 SetLastError(0xdeadbeef);
183 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
184 ok(!svc_handle1, "Expected failure\n");
185 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
187 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
189 /* Only a valid handle to the Service Control Manager */
190 SetLastError(0xdeadbeef);
191 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
192 ok(!svc_handle1, "Expected failure\n");
193 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
194 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
195 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
197 /* Now with a servicename */
198 SetLastError(0xdeadbeef);
199 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
200 ok(!svc_handle1, "Expected failure\n");
201 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
202 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
203 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
205 /* Or just a binary name */
206 SetLastError(0xdeadbeef);
207 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
208 ok(!svc_handle1, "Expected failure\n");
209 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
210 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
211 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
213 /* Both servicename and binary name (We only have connect rights) */
214 SetLastError(0xdeadbeef);
215 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
216 ok(!svc_handle1, "Expected failure\n");
217 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
219 /* They can even be empty at this stage of parameter checking */
220 SetLastError(0xdeadbeef);
221 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
222 ok(!svc_handle1, "Expected failure\n");
223 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
225 SetLastError(0xdeadbeef);
226 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, 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 /* Open the Service Control Manager with minimal rights for creation
231 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
233 CloseServiceHandle(scm_handle);
234 SetLastError(0xdeadbeef);
235 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
236 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
238 skip("Not enough rights to get a handle to the manager\n");
242 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
244 /* Empty strings for servicename and binary name are checked */
245 SetLastError(0xdeadbeef);
246 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
247 ok(!svc_handle1, "Expected failure\n");
248 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
250 SetLastError(0xdeadbeef);
251 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
252 ok(!svc_handle1, "Expected failure\n");
253 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
255 SetLastError(0xdeadbeef);
256 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, 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 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
261 * an ERROR_INVALID_PARAMETER)
263 SetLastError(0xdeadbeef);
264 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
265 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
266 ok(!svc_handle1, "Expected failure\n");
267 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
269 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
271 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
272 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
274 SetLastError(0xdeadbeef);
275 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
276 SERVICE_DISABLED, 0, pathname, 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 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
281 SetLastError(0xdeadbeef);
282 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
283 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
284 ok(!svc_handle1, "Expected failure\n");
285 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
287 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
288 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
290 SetLastError(0xdeadbeef);
291 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
292 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
293 ok(!svc_handle1, "Expected failure\n");
294 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
296 /* Illegal (start-type is not a mask and should only be one of the possibilities)
297 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
298 * it's most likely not the wanted start-type)
300 SetLastError(0xdeadbeef);
301 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
302 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
303 ok(!svc_handle1, "Expected failure\n");
304 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
306 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
307 SetLastError(0xdeadbeef);
308 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
309 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
310 ok(!svc_handle1, "Expected failure\n");
311 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
313 /* The service already exists (check first, just in case) */
314 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
317 spooler_exists = TRUE;
318 CloseServiceHandle(svc_handle1);
319 SetLastError(0xdeadbeef);
320 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
321 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
322 ok(!svc_handle1, "Expected failure\n");
323 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
326 skip("Spooler service doesn't exist\n");
328 /* To find an existing displayname we check the 'Spooler' service. Although the registry
329 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
330 * to the servicename and can't be used as well for a new displayname.
334 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
337 skip("Could not retrieve a displayname for the Spooler service\n");
340 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
341 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
342 ok(!svc_handle1, "Expected failure\n");
343 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
344 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
348 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
350 /* Windows doesn't care about the access rights for creation (which makes
351 * sense as there is no service yet) as long as there are sufficient
352 * rights to the manager.
354 SetLastError(0xdeadbeef);
355 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
356 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
357 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
358 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
359 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
360 GetLastError() == ERROR_IO_PENDING /* W2K */,
361 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
363 /* DeleteService however must have proper rights */
364 SetLastError(0xdeadbeef);
365 ret = DeleteService(svc_handle1);
366 ok(!ret, "Expected failure\n");
367 ok(GetLastError() == ERROR_ACCESS_DENIED,
368 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
370 /* Open the service with minimal rights for deletion.
371 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
373 CloseServiceHandle(svc_handle1);
374 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
376 /* Now that we have the proper rights, we should be able to delete */
377 SetLastError(0xdeadbeef);
378 ret = DeleteService(svc_handle1);
379 ok(ret, "Expected success\n");
380 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
381 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
382 GetLastError() == ERROR_IO_PENDING /* W2K */,
383 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
385 CloseServiceHandle(svc_handle1);
387 CloseServiceHandle(scm_handle);
389 /* Wait a while. One of the following tests also does a CreateService for the
390 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
391 * error if we do this to quick. Vista seems more picky then the others.
395 /* And a final NULL check */
396 SetLastError(0xdeadbeef);
397 ret = DeleteService(NULL);
398 ok(!ret, "Expected failure\n");
399 ok(GetLastError() == ERROR_INVALID_HANDLE,
400 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
403 static void test_get_displayname(void)
405 SC_HANDLE scm_handle, svc_handle;
407 CHAR displayname[4096];
408 WCHAR displaynameW[2048];
409 DWORD displaysize, tempsize, tempsizeW;
410 static const CHAR deadbeef[] = "Deadbeef";
411 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
412 static const CHAR servicename[] = "Winetest";
413 static const CHAR pathname[] = "we_dont_care.exe";
415 /* Having NULL for the size of the buffer will crash on W2K3 */
417 SetLastError(0xdeadbeef);
418 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
419 ok(!ret, "Expected failure\n");
420 ok(GetLastError() == ERROR_INVALID_HANDLE,
421 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
423 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
425 SetLastError(0xdeadbeef);
426 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
427 ok(!ret, "Expected failure\n");
428 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
429 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
430 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
432 SetLastError(0xdeadbeef);
433 displaysize = sizeof(displayname);
434 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
435 ok(!ret, "Expected failure\n");
436 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
437 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
438 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
440 /* Test for nonexistent service */
441 SetLastError(0xdeadbeef);
443 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
444 ok(!ret, "Expected failure\n");
445 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
446 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
448 /* Check if 'Spooler' exists */
449 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
452 skip("Spooler service doesn't exist\n");
453 CloseServiceHandle(scm_handle);
456 CloseServiceHandle(svc_handle);
458 /* Retrieve the needed size for the buffer */
459 SetLastError(0xdeadbeef);
461 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
462 ok(!ret, "Expected failure\n");
463 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
464 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
465 tempsize = displaysize;
468 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
469 ok(!ret, "Expected failure\n");
470 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
471 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
472 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
474 /* Buffer is too small */
475 SetLastError(0xdeadbeef);
476 displaysize = (tempsize / 2);
477 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
478 ok(!ret, "Expected failure\n");
479 ok(displaysize == tempsize, "Expected the needed buffersize\n");
480 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
481 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
483 /* First try with a buffer that should be big enough to hold
484 * the ANSI string (and terminating character). This succeeds on Windows
485 * although when asked (see above 2 tests) it will return twice the needed size.
487 SetLastError(0xdeadbeef);
488 displaysize = (tempsize / 2) + 1;
489 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
490 ok(ret, "Expected success\n");
491 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
492 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
493 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
494 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
495 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
497 /* Now with the original returned size */
498 SetLastError(0xdeadbeef);
499 displaysize = tempsize;
500 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
501 ok(ret, "Expected success\n");
502 ok(displaysize == tempsize, "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 /* And with a bigger than needed buffer */
509 SetLastError(0xdeadbeef);
510 displaysize = tempsize * 2;
511 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
512 ok(ret, "Expected success\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());
517 /* Test that shows that if the buffersize is enough, it's not changed */
518 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
519 ok(lstrlen(displayname) == tempsize/2,
520 "Expected the buffer to be twice the length of the string\n") ;
522 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
523 SetLastError(0xdeadbeef);
525 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
526 ok(!ret, "Expected failure\n");
527 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
528 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
530 /* Buffer is too small */
531 SetLastError(0xdeadbeef);
532 tempsizeW = displaysize;
533 displaysize = tempsizeW / 2;
534 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
535 ok(!ret, "Expected failure\n");
536 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
537 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
538 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
540 /* Now with the original returned size */
541 SetLastError(0xdeadbeef);
542 displaysize = tempsizeW;
543 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
544 ok(!ret, "Expected failure\n");
545 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
546 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
547 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
549 /* And with a bigger than needed buffer */
550 SetLastError(0xdeadbeef);
551 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
552 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
553 ok(ret, "Expected success\n");
554 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
555 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
556 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
557 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
558 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
559 ok(lstrlenW(displaynameW) == displaysize,
560 "Expected the buffer to be the length of the string\n") ;
561 ok(tempsize / 2 == tempsizeW,
562 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
564 CloseServiceHandle(scm_handle);
566 /* Test for a service without a displayname (which is valid). This should return
567 * the servicename itself.
569 SetLastError(0xdeadbeef);
570 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
571 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
573 skip("Not enough rights to get a handle to the manager\n");
577 SetLastError(0xdeadbeef);
578 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
579 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
580 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
581 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
584 CloseServiceHandle(scm_handle);
588 /* Retrieve the needed size for the buffer */
589 SetLastError(0xdeadbeef);
591 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
592 ok(!ret, "Expected failure\n");
593 ok(displaysize == lstrlen(servicename) * 2,
594 "Expected the displaysize to be twice the size of the servicename\n");
595 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
596 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
598 /* Buffer is too small */
599 SetLastError(0xdeadbeef);
600 tempsize = displaysize;
601 displaysize = (tempsize / 2);
602 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
603 ok(!ret, "Expected failure\n");
604 ok(displaysize == tempsize, "Expected the needed buffersize\n");
605 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
606 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
608 /* Get the displayname */
609 SetLastError(0xdeadbeef);
610 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
611 ok(ret, "Expected success\n");
612 ok(!lstrcmpi(displayname, servicename),
613 "Expected displayname to be %s, got %s\n", servicename, displayname);
614 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
615 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
616 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
617 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
619 /* Delete the service */
620 ret = DeleteService(svc_handle);
621 ok(ret, "Expected success\n");
623 CloseServiceHandle(svc_handle);
624 CloseServiceHandle(scm_handle);
626 /* Wait a while. Just in case one of the following tests does a CreateService again */
630 static void test_get_servicekeyname(void)
632 SC_HANDLE scm_handle, svc_handle;
633 CHAR servicename[4096];
634 CHAR displayname[4096];
635 WCHAR servicenameW[4096];
636 WCHAR displaynameW[4096];
637 DWORD servicesize, displaysize, tempsize;
639 static const CHAR deadbeef[] = "Deadbeef";
640 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
642 /* Having NULL for the size of the buffer will crash on W2K3 */
644 SetLastError(0xdeadbeef);
645 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
646 ok(!ret, "Expected failure\n");
647 ok(GetLastError() == ERROR_INVALID_HANDLE,
648 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
650 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
653 SetLastError(0xdeadbeef);
654 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
655 ok(!ret, "Expected failure\n");
656 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
657 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
658 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
659 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
661 /* Valid handle and buffer but no displayname */
663 SetLastError(0xdeadbeef);
664 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &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 == 200, "Service size expected 1, got %d\n", servicesize);
671 /* Test for nonexistent displayname */
672 SetLastError(0xdeadbeef);
673 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
674 ok(!ret, "Expected failure\n");
675 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
676 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
677 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
680 strcpy(servicename, "ABC");
681 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
682 ok(!ret, "Expected failure\n");
683 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
684 ok(servicename[0] == 0, "Service name not empty\n");
687 servicenameW[0] = 'A';
688 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
689 ok(!ret, "Expected failure\n");
690 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
691 ok(servicenameW[0] == 0, "Service name not empty\n");
694 strcpy(servicename, "ABC");
695 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
696 ok(!ret, "Expected failure\n");
697 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
698 ok(servicename[0] == 'A', "Service name changed\n");
701 servicenameW[0] = 'A';
702 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
703 ok(!ret, "Expected failure\n");
704 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
705 ok(servicenameW[0] == 'A', "Service name changed\n");
707 /* Check if 'Spooler' exists */
708 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
711 skip("Spooler service doesn't exist\n");
712 CloseServiceHandle(scm_handle);
715 CloseServiceHandle(svc_handle);
717 /* Get the displayname for the 'Spooler' service */
718 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
719 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
721 /* Retrieve the needed size for the buffer */
722 SetLastError(0xdeadbeef);
724 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
725 ok(!ret, "Expected failure\n");
726 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
727 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
729 /* Valid call with the correct buffersize */
730 SetLastError(0xdeadbeef);
731 tempsize = servicesize;
733 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
734 ok(ret, "Expected success\n");
735 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
736 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
737 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
738 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
741 ok(lstrlen(servicename) == tempsize/2,
742 "Expected the buffer to be twice the length of the string\n") ;
743 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
744 ok(servicesize == (tempsize * 2),
745 "Expected servicesize not to change if buffer not insufficient\n") ;
748 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
749 SetLastError(0xdeadbeef);
751 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
752 ok(ret, "Expected success\n");
753 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
754 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
755 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
756 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
759 ok(lstrlen(servicename) == tempsize/2,
760 "Expected the buffer to be twice the length of the string\n") ;
761 ok(servicesize == lstrlenW(servicenameW),
762 "Expected servicesize not to change if buffer not insufficient\n") ;
765 SetLastError(0xdeadbeef);
767 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
768 ok(!ret, "Expected failure\n");
769 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
770 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
771 ok(servicenameW[0] == 0, "Buffer not empty\n");
773 CloseServiceHandle(scm_handle);
776 static void test_close(void)
782 SetLastError(0xdeadbeef);
783 ret = CloseServiceHandle(NULL);
784 ok(!ret, "Expected failure\n");
785 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
787 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
790 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
791 SetLastError(0xdeadbeef);
792 ret = CloseServiceHandle(handle);
793 ok(ret, "Expected success\n");
794 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
795 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
796 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
797 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
800 static void test_sequence(void)
802 SC_HANDLE scm_handle, svc_handle;
804 QUERY_SERVICE_CONFIGA *config;
806 static const CHAR servicename [] = "Winetest";
807 static const CHAR displayname [] = "Winetest dummy service";
808 static const CHAR displayname2[] = "Winetest dummy service (2)";
809 static const CHAR pathname [] = "we_dont_care.exe";
810 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
811 static const CHAR password [] = "";
812 static const CHAR empty [] = "";
813 static const CHAR localsystem [] = "LocalSystem";
815 SetLastError(0xdeadbeef);
816 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
818 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
820 skip("Not enough rights to get a handle to the manager\n");
824 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
826 if (!scm_handle) return;
828 /* Create a dummy service */
829 SetLastError(0xdeadbeef);
830 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
831 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
832 pathname, NULL, NULL, dependencies, NULL, password);
834 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
836 /* We try and open the service and do the rest of the tests. Some could
837 * fail if the tests were changed between these runs.
839 trace("Deletion probably didn't work last time\n");
840 SetLastError(0xdeadbeef);
841 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
842 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
844 skip("Not enough rights to open the service\n");
845 CloseServiceHandle(scm_handle);
848 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
850 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
852 skip("Not enough rights to create the service\n");
853 CloseServiceHandle(scm_handle);
857 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
859 if (!svc_handle) return;
862 * Before we do a QueryServiceConfig we should check the registry. This will make sure
863 * that the correct keys are used.
866 /* Request the size for the buffer */
867 SetLastError(0xdeadbeef);
868 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
869 ok(!ret, "Expected failure\n");
870 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
872 config = HeapAlloc(GetProcessHeap(), 0, needed);
874 SetLastError(0xdeadbeef);
875 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
876 ok(ret, "Expected success\n");
877 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
878 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
879 GetLastError() == ERROR_IO_PENDING /* W2K */,
880 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
883 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
885 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
886 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
887 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
888 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
889 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
890 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
891 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
892 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
893 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
894 /* TODO: Show the double 0 terminated string */
897 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
899 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
900 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
902 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
903 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
905 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
906 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
907 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
908 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
909 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
910 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
911 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
912 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
913 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
914 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
915 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
916 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
917 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
918 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
920 SetLastError(0xdeadbeef);
921 ret = DeleteService(svc_handle);
922 ok(ret, "Expected success\n");
923 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
924 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
925 GetLastError() == ERROR_IO_PENDING /* W2K */,
926 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
928 CloseServiceHandle(svc_handle);
930 /* Wait a while. The following test does a CreateService again */
933 CloseServiceHandle(scm_handle);
934 HeapFree(GetProcessHeap(), 0, config);
937 static void test_queryconfig2(void)
939 SC_HANDLE scm_handle, svc_handle;
941 DWORD expected, needed;
942 BYTE buffer[MAX_PATH];
943 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
944 static const CHAR servicename [] = "Winetest";
945 static const CHAR displayname [] = "Winetest dummy service";
946 static const CHAR pathname [] = "we_dont_care.exe";
947 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
948 static const CHAR password [] = "";
949 static const CHAR description [] = "Description";
950 HMODULE dllhandle = GetModuleHandleA("advapi32.dll");
951 BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID)
952 = (void*)GetProcAddress(dllhandle, "ChangeServiceConfig2A");
953 BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
954 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2A");
955 BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
956 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2W");
957 if(!pQueryServiceConfig2A)
959 skip("function QueryServiceConfig2A not present\n");
963 SetLastError(0xdeadbeef);
964 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
968 if(GetLastError() == ERROR_ACCESS_DENIED)
969 skip("Not enough rights to get a handle to the manager\n");
971 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
975 /* Create a dummy service */
976 SetLastError(0xdeadbeef);
977 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
978 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
979 pathname, NULL, NULL, dependencies, NULL, password);
983 if(GetLastError() == ERROR_SERVICE_EXISTS)
985 /* We try and open the service and do the rest of the tests. Some could
986 * fail if the tests were changed between these runs.
988 trace("Deletion probably didn't work last time\n");
989 SetLastError(0xdeadbeef);
990 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
993 if(GetLastError() == ERROR_ACCESS_DENIED)
994 skip("Not enough rights to open the service\n");
996 ok(FALSE, "Could not open the service : %d\n", GetLastError());
997 CloseServiceHandle(scm_handle);
1001 if (GetLastError() == ERROR_ACCESS_DENIED)
1003 skip("Not enough rights to create the service\n");
1004 CloseServiceHandle(scm_handle);
1007 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1010 CloseServiceHandle(scm_handle);
1014 SetLastError(0xdeadbeef);
1015 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1016 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1017 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1019 SetLastError(0xdeadbeef);
1020 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1021 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1022 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1024 SetLastError(0xdeadbeef);
1025 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1026 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1027 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1029 SetLastError(0xdeadbeef);
1030 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1031 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1032 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1033 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1035 SetLastError(0xdeadbeef);
1036 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,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());
1041 SetLastError(0xdeadbeef);
1042 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1043 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1044 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1045 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1048 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1049 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1050 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1051 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1052 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1054 SetLastError(0xdeadbeef);
1056 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1057 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1058 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1059 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1061 if(!pChangeServiceConfig2A)
1063 skip("function ChangeServiceConfig2A not present\n");
1067 pConfig->lpDescription = (LPSTR) description;
1068 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1069 ok(ret, "ChangeServiceConfig2A failed\n");
1074 SetLastError(0xdeadbeef);
1076 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1077 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1078 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1079 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1080 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1082 SetLastError(0xdeadbeef);
1083 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1084 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1085 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1087 SetLastError(0xdeadbeef);
1088 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1089 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1090 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1091 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1093 SetLastError(0xdeadbeef);
1094 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1095 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1096 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1097 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1099 if(!pQueryServiceConfig2W)
1101 skip("function QueryServiceConfig2W not present\n");
1104 SetLastError(0xdeadbeef);
1106 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1107 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1108 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1109 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1110 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1112 SetLastError(0xdeadbeef);
1113 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1114 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1117 DeleteService(svc_handle);
1119 CloseServiceHandle(svc_handle);
1121 /* Wait a while. The following test does a CreateService again */
1124 CloseServiceHandle(scm_handle);
1127 static void test_refcount(void)
1129 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1130 static const CHAR servicename [] = "Winetest";
1131 static const CHAR pathname [] = "we_dont_care.exe";
1134 /* Get a handle to the Service Control Manager */
1135 SetLastError(0xdeadbeef);
1136 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1137 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1139 skip("Not enough rights to get a handle to the manager\n");
1143 /* Create a service */
1144 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1145 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1146 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1147 ok(svc_handle1 != NULL, "Expected success\n");
1149 /* Get a handle to this new service */
1150 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1151 ok(svc_handle2 != NULL, "Expected success\n");
1153 /* Get another handle to this new service */
1154 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1155 ok(svc_handle3 != NULL, "Expected success\n");
1157 /* Check if we can close the handle to the Service Control Manager */
1158 ret = CloseServiceHandle(scm_handle);
1159 ok(ret, "Expected success\n");
1161 /* Get a new handle to the Service Control Manager */
1162 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1163 ok(scm_handle != NULL, "Expected success\n");
1165 /* Get a handle to this new service */
1166 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1167 ok(svc_handle4 != NULL, "Expected success\n");
1169 /* Delete the service */
1170 ret = DeleteService(svc_handle4);
1171 ok(ret, "Expected success\n");
1173 /* We cannot create the same service again as it's still marked as 'being deleted'.
1174 * The reason is that we still have 4 open handles to this service even though we
1175 * closed the handle to the Service Control Manager in between.
1177 SetLastError(0xdeadbeef);
1178 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1179 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1180 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1183 ok(!svc_handle5, "Expected failure\n");
1184 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1185 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1188 /* FIXME: Remove this when Wine is fixed */
1191 DeleteService(svc_handle5);
1192 CloseServiceHandle(svc_handle5);
1195 /* Close all the handles to the service and try again */
1196 ret = CloseServiceHandle(svc_handle4);
1197 ok(ret, "Expected success\n");
1198 ret = CloseServiceHandle(svc_handle3);
1199 ok(ret, "Expected success\n");
1200 ret = CloseServiceHandle(svc_handle2);
1201 ok(ret, "Expected success\n");
1202 ret = CloseServiceHandle(svc_handle1);
1203 ok(ret, "Expected success\n");
1205 /* Wait a while. Doing a CreateService too soon will result again
1206 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1210 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1211 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1212 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1213 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1214 ok(svc_handle5 != NULL, "Expected success\n");
1216 /* Delete the service */
1217 ret = DeleteService(svc_handle5);
1218 ok(ret, "Expected success\n");
1220 /* Wait a while. Just in case one of the following tests does a CreateService again */
1223 CloseServiceHandle(svc_handle5);
1224 CloseServiceHandle(scm_handle);
1229 SC_HANDLE scm_handle;
1231 /* Bail out if we are on win98 */
1232 SetLastError(0xdeadbeef);
1233 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1235 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1237 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1240 CloseServiceHandle(scm_handle);
1242 /* First some parameter checking */
1245 test_create_delete_svc();
1246 test_get_displayname();
1247 test_get_servicekeyname();
1249 /* Test the creation, querying and deletion of a service */
1251 test_queryconfig2();
1252 /* The main reason for this test is to check if any refcounting is used
1253 * and what the rules are