2 * Unit tests for service functions
4 * Copyright (c) 2007 Paul Vriens
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/test.h"
33 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
35 static void test_open_scm(void)
39 /* No access rights */
40 SetLastError(0xdeadbeef);
41 scm_handle = OpenSCManagerA(NULL, NULL, 0);
42 ok(scm_handle != NULL, "Expected success\n");
43 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
44 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
45 GetLastError() == ERROR_IO_PENDING /* W2K */,
46 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
47 CloseServiceHandle(scm_handle);
49 /* Unknown database name */
50 SetLastError(0xdeadbeef);
51 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
52 ok(!scm_handle, "Expected failure\n");
53 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
54 CloseServiceHandle(scm_handle); /* Just in case */
56 /* MSDN says only ServiceActive is allowed, or NULL */
57 SetLastError(0xdeadbeef);
58 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
59 ok(!scm_handle, "Expected failure\n");
60 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
61 CloseServiceHandle(scm_handle); /* Just in case */
63 /* Remote unknown host */
64 SetLastError(0xdeadbeef);
65 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
66 ok(!scm_handle, "Expected failure\n");
68 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
69 CloseServiceHandle(scm_handle); /* Just in case */
71 /* Proper call with an empty hostname */
72 SetLastError(0xdeadbeef);
73 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
74 ok(scm_handle != NULL, "Expected success\n");
75 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
76 GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
77 GetLastError() == 0xdeadbeef /* XP */ ||
78 GetLastError() == ERROR_IO_PENDING /* W2K */,
79 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
80 CloseServiceHandle(scm_handle);
82 /* Again a correct one */
83 SetLastError(0xdeadbeef);
84 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
85 ok(scm_handle != NULL, "Expected success\n");
86 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
87 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
88 GetLastError() == ERROR_IO_PENDING /* W2K */,
89 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
90 CloseServiceHandle(scm_handle);
93 static void test_open_svc(void)
95 SC_HANDLE scm_handle, svc_handle;
97 /* All NULL (invalid access rights) */
98 SetLastError(0xdeadbeef);
99 svc_handle = OpenServiceA(NULL, NULL, 0);
100 ok(!svc_handle, "Expected failure\n");
101 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
103 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
106 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
107 SetLastError(0xdeadbeef);
108 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
109 ok(!svc_handle, "Expected failure\n");
110 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
111 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
112 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
114 /* Nonexistent service */
115 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
116 SetLastError(0xdeadbeef);
117 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
118 ok(!svc_handle, "Expected failure\n");
119 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
120 CloseServiceHandle(scm_handle);
122 /* Proper SCM handle but different access rights */
123 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
124 SetLastError(0xdeadbeef);
125 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
126 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
127 skip("Not enough rights to get a handle to the service\n");
130 ok(svc_handle != NULL, "Expected success\n");
131 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
132 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
133 GetLastError() == 0xdeadbeef /* XP, NT4 */,
134 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
135 CloseServiceHandle(svc_handle);
137 CloseServiceHandle(scm_handle);
140 static void test_create_delete_svc(void)
142 SC_HANDLE scm_handle, svc_handle1;
143 CHAR username[UNLEN + 1], domain[MAX_PATH];
144 DWORD user_size = UNLEN + 1;
145 CHAR account[UNLEN + 3];
146 static const CHAR servicename [] = "Winetest";
147 static const CHAR pathname [] = "we_dont_care.exe";
148 static const CHAR empty [] = "";
149 static const CHAR password [] = "secret";
150 BOOL spooler_exists = FALSE;
153 DWORD display_size = sizeof(display);
155 /* Get the username and turn it into an account to be used in some tests */
156 GetUserNameA(username, &user_size);
157 /* Get the domainname to cater for that situation */
158 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
159 sprintf(account, "%s\\%s", domain, username);
161 sprintf(account, ".\\%s", username);
164 SetLastError(0xdeadbeef);
165 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
166 ok(!svc_handle1, "Expected failure\n");
167 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
169 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
171 /* Only a valid handle to the Service Control Manager */
172 SetLastError(0xdeadbeef);
173 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
174 ok(!svc_handle1, "Expected failure\n");
175 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
176 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
177 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
179 /* Now with a servicename */
180 SetLastError(0xdeadbeef);
181 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
182 ok(!svc_handle1, "Expected failure\n");
183 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
184 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
185 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
187 /* Or just a binary name */
188 SetLastError(0xdeadbeef);
189 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
190 ok(!svc_handle1, "Expected failure\n");
191 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
192 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
193 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
195 /* Both servicename and binary name (We only have connect rights) */
196 SetLastError(0xdeadbeef);
197 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
198 ok(!svc_handle1, "Expected failure\n");
199 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
201 /* They can even be empty at this stage of parameter checking */
202 SetLastError(0xdeadbeef);
203 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
204 ok(!svc_handle1, "Expected failure\n");
205 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
207 SetLastError(0xdeadbeef);
208 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
209 ok(!svc_handle1, "Expected failure\n");
210 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
212 /* Open the Service Control Manager with minimal rights for creation
213 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
215 CloseServiceHandle(scm_handle);
216 SetLastError(0xdeadbeef);
217 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
218 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
220 skip("Not enough rights to get a handle to the manager\n");
224 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
226 /* Empty strings for servicename and binary name are checked */
227 SetLastError(0xdeadbeef);
228 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
229 ok(!svc_handle1, "Expected failure\n");
230 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
232 SetLastError(0xdeadbeef);
233 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
234 ok(!svc_handle1, "Expected failure\n");
235 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
237 SetLastError(0xdeadbeef);
238 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
239 ok(!svc_handle1, "Expected failure\n");
240 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
242 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
243 * an ERROR_INVALID_PARAMETER)
245 SetLastError(0xdeadbeef);
246 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
247 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
248 ok(!svc_handle1, "Expected failure\n");
249 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
251 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
253 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
254 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
256 SetLastError(0xdeadbeef);
257 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
258 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
259 ok(!svc_handle1, "Expected failure\n");
260 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
262 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
263 SetLastError(0xdeadbeef);
264 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
265 SERVICE_DISABLED, 0, pathname, 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 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
270 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
272 SetLastError(0xdeadbeef);
273 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
274 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
275 ok(!svc_handle1, "Expected failure\n");
276 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
278 /* Illegal (start-type is not a mask and should only be one of the possibilities)
279 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
280 * it's most likely not the wanted start-type)
282 SetLastError(0xdeadbeef);
283 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
284 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
285 ok(!svc_handle1, "Expected failure\n");
286 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
288 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
289 SetLastError(0xdeadbeef);
290 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
291 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
292 ok(!svc_handle1, "Expected failure\n");
293 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
295 /* The service already exists (check first, just in case) */
296 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
299 spooler_exists = TRUE;
300 CloseServiceHandle(svc_handle1);
301 SetLastError(0xdeadbeef);
302 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
303 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
304 ok(!svc_handle1, "Expected failure\n");
305 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
308 skip("Spooler service doesn't exist\n");
310 /* To find an existing displayname we check the 'Spooler' service. Although the registry
311 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
312 * to the servicename and can't be used as well for a new displayname.
316 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
319 skip("Could not retrieve a displayname for the Spooler service\n");
322 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
323 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
324 ok(!svc_handle1, "Expected failure\n");
325 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
326 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
330 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
332 /* Windows doesn't care about the access rights for creation (which makes
333 * sense as there is no service yet) as long as there are sufficient
334 * rights to the manager.
336 SetLastError(0xdeadbeef);
337 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
338 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
339 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
340 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
341 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
342 GetLastError() == ERROR_IO_PENDING /* W2K */,
343 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
345 /* DeleteService however must have proper rights */
346 SetLastError(0xdeadbeef);
347 ret = DeleteService(svc_handle1);
348 ok(!ret, "Expected failure\n");
349 ok(GetLastError() == ERROR_ACCESS_DENIED,
350 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
352 /* Open the service with minimal rights for deletion.
353 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
355 CloseServiceHandle(svc_handle1);
356 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
358 /* Now that we have the proper rights, we should be able to delete */
359 SetLastError(0xdeadbeef);
360 ret = DeleteService(svc_handle1);
361 ok(ret, "Expected success\n");
362 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
363 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
364 GetLastError() == ERROR_IO_PENDING /* W2K */,
365 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
367 CloseServiceHandle(svc_handle1);
369 CloseServiceHandle(scm_handle);
371 /* Wait a while. One of the following tests also does a CreateService for the
372 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
373 * error if we do this to quick. Vista seems more picky then the others.
377 /* And a final NULL check */
378 SetLastError(0xdeadbeef);
379 ret = DeleteService(NULL);
380 ok(!ret, "Expected failure\n");
381 ok(GetLastError() == ERROR_INVALID_HANDLE,
382 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
385 static void test_get_displayname(void)
387 SC_HANDLE scm_handle, svc_handle;
389 CHAR displayname[4096];
390 WCHAR displaynameW[2048];
391 DWORD displaysize, tempsize, tempsizeW;
392 static const CHAR deadbeef[] = "Deadbeef";
393 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
394 static const CHAR servicename[] = "Winetest";
395 static const CHAR pathname[] = "we_dont_care.exe";
397 /* Having NULL for the size of the buffer will crash on W2K3 */
399 SetLastError(0xdeadbeef);
400 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
401 ok(!ret, "Expected failure\n");
402 ok(GetLastError() == ERROR_INVALID_HANDLE,
403 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
405 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
407 SetLastError(0xdeadbeef);
408 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
409 ok(!ret, "Expected failure\n");
410 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
411 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
412 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
414 SetLastError(0xdeadbeef);
415 displaysize = sizeof(displayname);
416 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
417 ok(!ret, "Expected failure\n");
418 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
419 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
420 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
422 /* Test for nonexistent service */
423 SetLastError(0xdeadbeef);
425 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
426 ok(!ret, "Expected failure\n");
427 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
428 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
430 /* Check if 'Spooler' exists */
431 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
434 skip("Spooler service doesn't exist\n");
435 CloseServiceHandle(scm_handle);
438 CloseServiceHandle(svc_handle);
440 /* Retrieve the needed size for the buffer */
441 SetLastError(0xdeadbeef);
443 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
444 ok(!ret, "Expected failure\n");
445 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
446 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
447 tempsize = displaysize;
450 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
451 ok(!ret, "Expected failure\n");
452 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
453 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
454 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
456 /* Buffer is too small */
457 SetLastError(0xdeadbeef);
458 displaysize = (tempsize / 2);
459 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
460 ok(!ret, "Expected failure\n");
461 ok(displaysize == tempsize, "Expected the needed buffersize\n");
462 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
463 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
465 /* First try with a buffer that should be big enough to hold
466 * the ANSI string (and terminating character). This succeeds on Windows
467 * although when asked (see above 2 tests) it will return twice the needed size.
469 SetLastError(0xdeadbeef);
470 displaysize = (tempsize / 2) + 1;
471 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
472 ok(ret, "Expected success\n");
473 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
474 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
475 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
476 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
477 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
479 /* Now with the original returned size */
480 SetLastError(0xdeadbeef);
481 displaysize = tempsize;
482 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
483 ok(ret, "Expected success\n");
484 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
485 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
486 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
487 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
488 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
490 /* And with a bigger than needed buffer */
491 SetLastError(0xdeadbeef);
492 displaysize = tempsize * 2;
493 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
494 ok(ret, "Expected success\n");
495 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
496 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
497 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
498 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
499 /* Test that shows that if the buffersize is enough, it's not changed */
500 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
501 ok(lstrlen(displayname) == tempsize/2,
502 "Expected the buffer to be twice the length of the string\n") ;
504 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
505 SetLastError(0xdeadbeef);
507 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
508 ok(!ret, "Expected failure\n");
509 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
510 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
512 /* Buffer is too small */
513 SetLastError(0xdeadbeef);
514 tempsizeW = displaysize;
515 displaysize = tempsizeW / 2;
516 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
517 ok(!ret, "Expected failure\n");
518 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
519 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
520 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
522 /* Now with the original returned size */
523 SetLastError(0xdeadbeef);
524 displaysize = tempsizeW;
525 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
526 ok(!ret, "Expected failure\n");
527 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
528 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
529 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
531 /* And with a bigger than needed buffer */
532 SetLastError(0xdeadbeef);
533 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
534 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
535 ok(ret, "Expected success\n");
536 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
537 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
538 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
539 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
540 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
541 ok(lstrlenW(displaynameW) == displaysize,
542 "Expected the buffer to be the length of the string\n") ;
543 ok(tempsize / 2 == tempsizeW,
544 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
546 CloseServiceHandle(scm_handle);
548 /* Test for a service without a displayname (which is valid). This should return
549 * the servicename itself.
551 SetLastError(0xdeadbeef);
552 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
553 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
555 skip("Not enough rights to get a handle to the manager\n");
559 SetLastError(0xdeadbeef);
560 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
561 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
562 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
563 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
566 CloseServiceHandle(scm_handle);
570 /* Retrieve the needed size for the buffer */
571 SetLastError(0xdeadbeef);
573 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
574 ok(!ret, "Expected failure\n");
575 ok(displaysize == lstrlen(servicename) * 2,
576 "Expected the displaysize to be twice the size of the servicename\n");
577 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
578 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
580 /* Buffer is too small */
581 SetLastError(0xdeadbeef);
582 tempsize = displaysize;
583 displaysize = (tempsize / 2);
584 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
585 ok(!ret, "Expected failure\n");
586 ok(displaysize == tempsize, "Expected the needed buffersize\n");
587 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
588 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
590 /* Get the displayname */
591 SetLastError(0xdeadbeef);
592 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
593 ok(ret, "Expected success\n");
594 ok(!lstrcmpi(displayname, servicename),
595 "Expected displayname to be %s, got %s\n", servicename, displayname);
596 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
597 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
598 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
599 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
601 /* Delete the service */
602 ret = DeleteService(svc_handle);
603 ok(ret, "Expected success\n");
605 CloseServiceHandle(svc_handle);
606 CloseServiceHandle(scm_handle);
608 /* Wait a while. Just in case one of the following tests does a CreateService again */
612 static void test_get_servicekeyname(void)
614 SC_HANDLE scm_handle, svc_handle;
615 CHAR servicename[4096];
616 CHAR displayname[4096];
617 DWORD servicesize, displaysize, tempsize;
619 static const CHAR deadbeef[] = "Deadbeef";
621 /* Having NULL for the size of the buffer will crash on W2K3 */
623 SetLastError(0xdeadbeef);
624 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
625 ok(!ret, "Expected failure\n");
627 ok(GetLastError() == ERROR_INVALID_HANDLE,
628 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
630 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
632 SetLastError(0xdeadbeef);
633 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
634 ok(!ret, "Expected failure\n");
636 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
637 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
638 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
640 /* Valid handle and buffer but no displayname */
641 SetLastError(0xdeadbeef);
642 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
643 ok(!ret, "Expected failure\n");
645 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
646 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
647 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
649 /* Test for nonexistent displayname */
650 SetLastError(0xdeadbeef);
651 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
652 ok(!ret, "Expected failure\n");
654 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
655 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
657 /* Check if 'Spooler' exists */
658 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
661 skip("Spooler service doesn't exist\n");
662 CloseServiceHandle(scm_handle);
665 CloseServiceHandle(svc_handle);
667 /* Get the displayname for the 'Spooler' service */
668 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
669 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
671 /* Retrieve the needed size for the buffer */
672 SetLastError(0xdeadbeef);
674 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
675 ok(!ret, "Expected failure\n");
677 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
678 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
680 /* Valid call with the correct buffersize */
681 SetLastError(0xdeadbeef);
682 tempsize = servicesize;
684 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
686 ok(ret, "Expected success\n");
687 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
688 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
689 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
690 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
693 ok(lstrlen(servicename) == tempsize/2,
694 "Expected the buffer to be twice the length of the string\n") ;
695 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
698 CloseServiceHandle(scm_handle);
701 static void test_close(void)
707 SetLastError(0xdeadbeef);
708 ret = CloseServiceHandle(NULL);
709 ok(!ret, "Expected failure\n");
710 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
712 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
715 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
716 SetLastError(0xdeadbeef);
717 ret = CloseServiceHandle(handle);
718 ok(ret, "Expected success\n");
719 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
720 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
721 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
722 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
725 static void test_sequence(void)
727 SC_HANDLE scm_handle, svc_handle;
729 QUERY_SERVICE_CONFIGA *config;
731 static const CHAR servicename [] = "Winetest";
732 static const CHAR displayname [] = "Winetest dummy service";
733 static const CHAR pathname [] = "we_dont_care.exe";
734 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
735 static const CHAR password [] = "";
736 static const CHAR empty [] = "";
737 static const CHAR localsystem [] = "LocalSystem";
739 SetLastError(0xdeadbeef);
740 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
742 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
744 skip("Not enough rights to get a handle to the manager\n");
748 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
750 if (!scm_handle) return;
752 /* Create a dummy service */
753 SetLastError(0xdeadbeef);
754 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
755 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
756 pathname, NULL, NULL, dependencies, NULL, password);
758 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
760 /* We try and open the service and do the rest of the tests. Some could
761 * fail if the tests were changed between these runs.
763 trace("Deletion probably didn't work last time\n");
764 SetLastError(0xdeadbeef);
765 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
766 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
768 skip("Not enough rights to open the service\n");
769 CloseServiceHandle(scm_handle);
772 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
774 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
776 skip("Not enough rights to create the service\n");
777 CloseServiceHandle(scm_handle);
781 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
783 if (!svc_handle) return;
786 * Before we do a QueryServiceConfig we should check the registry. This will make sure
787 * that the correct keys are used.
790 /* Request the size for the buffer */
791 SetLastError(0xdeadbeef);
792 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
793 ok(!ret, "Expected failure\n");
794 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
796 config = HeapAlloc(GetProcessHeap(), 0, needed);
798 SetLastError(0xdeadbeef);
799 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
800 ok(ret, "Expected success\n");
803 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
804 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
805 GetLastError() == ERROR_IO_PENDING /* W2K */,
806 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
807 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
809 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
810 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
811 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
812 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
813 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
814 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
815 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
816 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
817 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
818 /* TODO: Show the double 0 terminated string */
821 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
823 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
824 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
826 SetLastError(0xdeadbeef);
827 ret = DeleteService(svc_handle);
828 ok(ret, "Expected success\n");
829 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
830 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
831 GetLastError() == ERROR_IO_PENDING /* W2K */,
832 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
834 CloseServiceHandle(svc_handle);
836 /* Wait a while. The following test does a CreateService again */
839 CloseServiceHandle(scm_handle);
840 HeapFree(GetProcessHeap(), 0, config);
843 static void test_queryconfig2(void)
845 SC_HANDLE scm_handle, svc_handle;
847 DWORD expected, needed;
848 BYTE buffer[MAX_PATH];
849 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
850 static const CHAR servicename [] = "Winetest";
851 static const CHAR displayname [] = "Winetest dummy service";
852 static const CHAR pathname [] = "we_dont_care.exe";
853 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
854 static const CHAR password [] = "";
855 static const CHAR description [] = "Description";
856 HMODULE dllhandle = GetModuleHandleA("advapi32.dll");
857 BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID)
858 = (void*)GetProcAddress(dllhandle, "ChangeServiceConfig2A");
859 BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
860 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2A");
861 BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
862 = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2W");
863 if(!pQueryServiceConfig2A)
865 skip("function QueryServiceConfig2A not present\n");
869 SetLastError(0xdeadbeef);
870 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
874 if(GetLastError() == ERROR_ACCESS_DENIED)
875 skip("Not enough rights to get a handle to the manager\n");
877 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
881 /* Create a dummy service */
882 SetLastError(0xdeadbeef);
883 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
884 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
885 pathname, NULL, NULL, dependencies, NULL, password);
889 if(GetLastError() == ERROR_SERVICE_EXISTS)
891 /* We try and open the service and do the rest of the tests. Some could
892 * fail if the tests were changed between these runs.
894 trace("Deletion probably didn't work last time\n");
895 SetLastError(0xdeadbeef);
896 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
899 if(GetLastError() == ERROR_ACCESS_DENIED)
900 skip("Not enough rights to open the service\n");
902 ok(FALSE, "Could not open the service : %d\n", GetLastError());
903 CloseServiceHandle(scm_handle);
907 if (GetLastError() == ERROR_ACCESS_DENIED)
909 skip("Not enough rights to create the service\n");
910 CloseServiceHandle(scm_handle);
913 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
916 CloseServiceHandle(scm_handle);
920 SetLastError(0xdeadbeef);
921 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
922 ok(!ret, "expected QueryServiceConfig2A to fail\n");
923 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
925 SetLastError(0xdeadbeef);
926 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
927 ok(!ret, "expected QueryServiceConfig2A to fail\n");
928 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
930 SetLastError(0xdeadbeef);
931 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
932 ok(!ret, "expected QueryServiceConfig2A to fail\n");
933 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
935 SetLastError(0xdeadbeef);
936 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
937 ok(!ret, "expected QueryServiceConfig2A to fail\n");
938 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
939 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
941 SetLastError(0xdeadbeef);
942 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
943 ok(!ret, "expected QueryServiceConfig2A to fail\n");
944 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
947 SetLastError(0xdeadbeef);
948 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
949 ok(!ret, "expected QueryServiceConfig2A to fail\n");
950 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
951 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
954 pConfig->lpDescription = (LPSTR)0xdeadbeef;
955 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
956 ok(ret, "expected QueryServiceConfig2A to succeed\n");
957 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
958 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
960 SetLastError(0xdeadbeef);
962 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
963 ok(!ret, "expected QueryServiceConfig2A to fail\n");
964 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
965 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
967 if(!pChangeServiceConfig2A)
969 skip("function ChangeServiceConfig2A not present\n");
973 pConfig->lpDescription = (LPSTR) description;
974 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
975 ok(ret, "ChangeServiceConfig2A failed\n");
980 SetLastError(0xdeadbeef);
982 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
983 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
984 ok(!ret, "expected QueryServiceConfig2A to fail\n");
985 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
986 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
988 SetLastError(0xdeadbeef);
989 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
990 ok(!ret, "expected QueryServiceConfig2A to fail\n");
991 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
993 SetLastError(0xdeadbeef);
994 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
995 ok(ret, "expected QueryServiceConfig2A to succeed\n");
996 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
997 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
999 SetLastError(0xdeadbeef);
1000 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1001 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1002 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1003 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1005 if(!pQueryServiceConfig2W)
1007 skip("function QueryServiceConfig2W not present\n");
1010 SetLastError(0xdeadbeef);
1012 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1013 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1014 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1015 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1016 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1018 SetLastError(0xdeadbeef);
1019 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1020 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1023 DeleteService(svc_handle);
1025 CloseServiceHandle(svc_handle);
1027 /* Wait a while. The following test does a CreateService again */
1030 CloseServiceHandle(scm_handle);
1033 static void test_refcount(void)
1035 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1036 static const CHAR servicename [] = "Winetest";
1037 static const CHAR pathname [] = "we_dont_care.exe";
1040 /* Get a handle to the Service Control Manager */
1041 SetLastError(0xdeadbeef);
1042 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1043 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1045 skip("Not enough rights to get a handle to the manager\n");
1049 /* Create a service */
1050 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1051 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1052 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1053 ok(svc_handle1 != NULL, "Expected success\n");
1055 /* Get a handle to this new service */
1056 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1057 ok(svc_handle2 != NULL, "Expected success\n");
1059 /* Get another handle to this new service */
1060 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1061 ok(svc_handle3 != NULL, "Expected success\n");
1063 /* Check if we can close the handle to the Service Control Manager */
1064 ret = CloseServiceHandle(scm_handle);
1065 ok(ret, "Expected success\n");
1067 /* Get a new handle to the Service Control Manager */
1068 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1069 ok(scm_handle != NULL, "Expected success\n");
1071 /* Get a handle to this new service */
1072 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1073 ok(svc_handle4 != NULL, "Expected success\n");
1075 /* Delete the service */
1076 ret = DeleteService(svc_handle4);
1077 ok(ret, "Expected success\n");
1079 /* We cannot create the same service again as it's still marked as 'being deleted'.
1080 * The reason is that we still have 4 open handles to this service even though we
1081 * closed the handle to the Service Control Manager in between.
1083 SetLastError(0xdeadbeef);
1084 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1085 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1086 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1089 ok(!svc_handle5, "Expected failure\n");
1090 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1091 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1094 /* FIXME: Remove this when Wine is fixed */
1097 DeleteService(svc_handle5);
1098 CloseServiceHandle(svc_handle5);
1101 /* Close all the handles to the service and try again */
1102 ret = CloseServiceHandle(svc_handle4);
1103 ok(ret, "Expected success\n");
1104 ret = CloseServiceHandle(svc_handle3);
1105 ok(ret, "Expected success\n");
1106 ret = CloseServiceHandle(svc_handle2);
1107 ok(ret, "Expected success\n");
1108 ret = CloseServiceHandle(svc_handle1);
1109 ok(ret, "Expected success\n");
1111 /* Wait a while. Doing a CreateService too soon will result again
1112 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1116 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1117 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1118 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1119 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1120 ok(svc_handle5 != NULL, "Expected success\n");
1122 /* Delete the service */
1123 ret = DeleteService(svc_handle5);
1124 ok(ret, "Expected success\n");
1126 /* Wait a while. Just in case one of the following tests does a CreateService again */
1129 CloseServiceHandle(svc_handle5);
1130 CloseServiceHandle(scm_handle);
1135 SC_HANDLE scm_handle;
1137 /* Bail out if we are on win98 */
1138 SetLastError(0xdeadbeef);
1139 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1141 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1143 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1146 CloseServiceHandle(scm_handle);
1148 /* First some parameter checking */
1151 test_create_delete_svc();
1152 test_get_displayname();
1153 test_get_servicekeyname();
1155 /* Test the creation, querying and deletion of a service */
1157 test_queryconfig2();
1158 /* The main reason for this test is to check if any refcounting is used
1159 * and what the rules are