advapi32/tests: Add helper function to get function pointers.
[wine/multimedia.git] / dlls / advapi32 / tests / service.c
blob306f0007a972af538eddc32bd2d7b444e50aba95
1 /*
2 * Unit tests for service functions
4 * Copyright (c) 2007 Paul Vriens
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
28 #include "winsvc.h"
29 #include "winnls.h"
30 #include "lmcons.h"
32 #include "wine/test.h"
34 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
36 static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
37 static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
38 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
40 static void init_function_pointers(void)
42 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
44 pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A");
45 pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
46 pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
49 static void test_open_scm(void)
51 SC_HANDLE scm_handle;
53 /* No access rights */
54 SetLastError(0xdeadbeef);
55 scm_handle = OpenSCManagerA(NULL, NULL, 0);
56 ok(scm_handle != NULL, "Expected success\n");
57 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
58 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
59 GetLastError() == ERROR_IO_PENDING /* W2K */,
60 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
61 CloseServiceHandle(scm_handle);
63 /* Unknown database name */
64 SetLastError(0xdeadbeef);
65 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
66 ok(!scm_handle, "Expected failure\n");
67 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
68 CloseServiceHandle(scm_handle); /* Just in case */
70 /* MSDN says only ServiceActive is allowed, or NULL */
71 SetLastError(0xdeadbeef);
72 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
73 ok(!scm_handle, "Expected failure\n");
74 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
75 CloseServiceHandle(scm_handle); /* Just in case */
77 /* Remote unknown host */
78 SetLastError(0xdeadbeef);
79 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
80 ok(!scm_handle, "Expected failure\n");
81 todo_wine
82 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
83 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
84 CloseServiceHandle(scm_handle); /* Just in case */
86 /* Proper call with an empty hostname */
87 SetLastError(0xdeadbeef);
88 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
89 ok(scm_handle != NULL, "Expected success\n");
90 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
91 GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
92 GetLastError() == 0xdeadbeef /* XP */ ||
93 GetLastError() == ERROR_IO_PENDING /* W2K */,
94 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
95 CloseServiceHandle(scm_handle);
97 /* Again a correct one */
98 SetLastError(0xdeadbeef);
99 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
100 ok(scm_handle != NULL, "Expected success\n");
101 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
102 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
103 GetLastError() == ERROR_IO_PENDING /* W2K */,
104 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
105 CloseServiceHandle(scm_handle);
108 static void test_open_svc(void)
110 SC_HANDLE scm_handle, svc_handle;
111 CHAR displayname[4096];
112 DWORD displaysize;
114 /* All NULL (invalid access rights) */
115 SetLastError(0xdeadbeef);
116 svc_handle = OpenServiceA(NULL, NULL, 0);
117 ok(!svc_handle, "Expected failure\n");
118 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
120 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
122 /* NULL service */
123 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
124 SetLastError(0xdeadbeef);
125 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
126 ok(!svc_handle, "Expected failure\n");
127 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
128 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
129 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
131 /* Nonexistent service */
132 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
133 SetLastError(0xdeadbeef);
134 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
135 ok(!svc_handle, "Expected failure\n");
136 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
137 CloseServiceHandle(scm_handle);
139 /* Proper SCM handle but different access rights */
140 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
141 SetLastError(0xdeadbeef);
142 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
143 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
144 skip("Not enough rights to get a handle to the service\n");
145 else
147 ok(svc_handle != NULL, "Expected success\n");
148 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
149 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
150 GetLastError() == 0xdeadbeef /* XP, NT4 */,
151 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
152 CloseServiceHandle(svc_handle);
155 /* Test to show we can't open a service with the displayname */
157 /* Retrieve the needed size for the buffer */
158 displaysize = 0;
159 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
160 /* Get the displayname */
161 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
162 /* Try to open the service with this displayname, unless the displayname equals
163 * the servicename as that would defeat the purpose of this test.
165 if (!lstrcmpi(spooler, displayname))
167 skip("displayname equals servicename\n");
168 CloseServiceHandle(scm_handle);
169 return;
172 SetLastError(0xdeadbeef);
173 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
174 ok(!svc_handle, "Expected failure\n");
175 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
176 /* Just in case */
177 CloseServiceHandle(svc_handle);
179 CloseServiceHandle(scm_handle);
182 static void test_create_delete_svc(void)
184 SC_HANDLE scm_handle, svc_handle1;
185 CHAR username[UNLEN + 1], domain[MAX_PATH];
186 DWORD user_size = UNLEN + 1;
187 CHAR account[UNLEN + 3];
188 static const CHAR servicename [] = "Winetest";
189 static const CHAR pathname [] = "we_dont_care.exe";
190 static const CHAR empty [] = "";
191 static const CHAR password [] = "secret";
192 BOOL spooler_exists = FALSE;
193 BOOL ret;
194 CHAR display[4096];
195 DWORD display_size = sizeof(display);
197 /* Get the username and turn it into an account to be used in some tests */
198 GetUserNameA(username, &user_size);
199 /* Get the domainname to cater for that situation */
200 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
201 sprintf(account, "%s\\%s", domain, username);
202 else
203 sprintf(account, ".\\%s", username);
205 /* All NULL */
206 SetLastError(0xdeadbeef);
207 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
208 ok(!svc_handle1, "Expected failure\n");
209 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
211 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
213 /* Only a valid handle to the Service Control Manager */
214 SetLastError(0xdeadbeef);
215 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
216 ok(!svc_handle1, "Expected failure\n");
217 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
218 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
219 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
221 /* Now with a servicename */
222 SetLastError(0xdeadbeef);
223 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
224 ok(!svc_handle1, "Expected failure\n");
225 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
226 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
227 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
229 /* Or just a binary name */
230 SetLastError(0xdeadbeef);
231 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
232 ok(!svc_handle1, "Expected failure\n");
233 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
234 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
235 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
237 /* Both servicename and binary name (We only have connect rights) */
238 SetLastError(0xdeadbeef);
239 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
240 ok(!svc_handle1, "Expected failure\n");
241 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
243 /* They can even be empty at this stage of parameter checking */
244 SetLastError(0xdeadbeef);
245 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
246 ok(!svc_handle1, "Expected failure\n");
247 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
249 SetLastError(0xdeadbeef);
250 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
251 ok(!svc_handle1, "Expected failure\n");
252 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
254 /* Open the Service Control Manager with minimal rights for creation
255 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
257 CloseServiceHandle(scm_handle);
258 SetLastError(0xdeadbeef);
259 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
260 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
262 skip("Not enough rights to get a handle to the manager\n");
263 return;
266 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
268 /* Empty strings for servicename and binary name are checked */
269 SetLastError(0xdeadbeef);
270 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
271 ok(!svc_handle1, "Expected failure\n");
272 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
274 SetLastError(0xdeadbeef);
275 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
276 ok(!svc_handle1, "Expected failure\n");
277 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
279 SetLastError(0xdeadbeef);
280 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
281 ok(!svc_handle1, "Expected failure\n");
282 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
284 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
285 * an ERROR_INVALID_PARAMETER)
287 SetLastError(0xdeadbeef);
288 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
289 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
290 ok(!svc_handle1, "Expected failure\n");
291 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
293 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
295 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
296 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
298 SetLastError(0xdeadbeef);
299 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
300 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
301 ok(!svc_handle1, "Expected failure\n");
302 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
304 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
305 SetLastError(0xdeadbeef);
306 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
307 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
308 ok(!svc_handle1, "Expected failure\n");
309 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
311 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
312 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
314 SetLastError(0xdeadbeef);
315 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
316 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
317 ok(!svc_handle1, "Expected failure\n");
318 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
320 /* Illegal (start-type is not a mask and should only be one of the possibilities)
321 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
322 * it's most likely not the wanted start-type)
324 SetLastError(0xdeadbeef);
325 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
326 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
327 ok(!svc_handle1, "Expected failure\n");
328 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
330 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
331 SetLastError(0xdeadbeef);
332 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
333 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
334 ok(!svc_handle1, "Expected failure\n");
335 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
337 /* The service already exists (check first, just in case) */
338 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
339 if (svc_handle1)
341 spooler_exists = TRUE;
342 CloseServiceHandle(svc_handle1);
343 SetLastError(0xdeadbeef);
344 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
345 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
346 ok(!svc_handle1, "Expected failure\n");
347 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
349 else
350 skip("Spooler service doesn't exist\n");
352 /* To find an existing displayname we check the 'Spooler' service. Although the registry
353 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
354 * to the servicename and can't be used as well for a new displayname.
356 if (spooler_exists)
358 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
360 if (!ret)
361 skip("Could not retrieve a displayname for the Spooler service\n");
362 else
364 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
365 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
366 ok(!svc_handle1, "Expected failure\n");
367 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
368 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
371 else
372 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
374 /* Windows doesn't care about the access rights for creation (which makes
375 * sense as there is no service yet) as long as there are sufficient
376 * rights to the manager.
378 SetLastError(0xdeadbeef);
379 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
380 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
381 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
382 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
383 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
384 GetLastError() == ERROR_IO_PENDING /* W2K */,
385 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
387 /* DeleteService however must have proper rights */
388 SetLastError(0xdeadbeef);
389 ret = DeleteService(svc_handle1);
390 ok(!ret, "Expected failure\n");
391 ok(GetLastError() == ERROR_ACCESS_DENIED,
392 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
394 /* Open the service with minimal rights for deletion.
395 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
397 CloseServiceHandle(svc_handle1);
398 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
400 /* Now that we have the proper rights, we should be able to delete */
401 SetLastError(0xdeadbeef);
402 ret = DeleteService(svc_handle1);
403 ok(ret, "Expected success\n");
404 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
405 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
406 GetLastError() == ERROR_IO_PENDING /* W2K */,
407 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
409 CloseServiceHandle(svc_handle1);
411 CloseServiceHandle(scm_handle);
413 /* Wait a while. One of the following tests also does a CreateService for the
414 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
415 * error if we do this to quick. Vista seems more picky then the others.
417 Sleep(1000);
419 /* And a final NULL check */
420 SetLastError(0xdeadbeef);
421 ret = DeleteService(NULL);
422 ok(!ret, "Expected failure\n");
423 ok(GetLastError() == ERROR_INVALID_HANDLE,
424 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
427 static void test_get_displayname(void)
429 SC_HANDLE scm_handle, svc_handle;
430 BOOL ret;
431 CHAR displayname[4096];
432 WCHAR displaynameW[2048];
433 DWORD displaysize, tempsize, tempsizeW;
434 static const CHAR deadbeef[] = "Deadbeef";
435 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
436 static const CHAR servicename[] = "Winetest";
437 static const CHAR pathname[] = "we_dont_care.exe";
439 /* Having NULL for the size of the buffer will crash on W2K3 */
441 SetLastError(0xdeadbeef);
442 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
443 ok(!ret, "Expected failure\n");
444 ok(GetLastError() == ERROR_INVALID_HANDLE,
445 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
447 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
449 SetLastError(0xdeadbeef);
450 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
451 ok(!ret, "Expected failure\n");
452 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
453 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
454 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
456 SetLastError(0xdeadbeef);
457 displaysize = sizeof(displayname);
458 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
459 ok(!ret, "Expected failure\n");
460 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
461 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
462 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
464 /* Test for nonexistent service */
465 SetLastError(0xdeadbeef);
466 displaysize = -1;
467 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
468 ok(!ret, "Expected failure\n");
469 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
470 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
472 /* Check if 'Spooler' exists */
473 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
474 if (!svc_handle)
476 skip("Spooler service doesn't exist\n");
477 CloseServiceHandle(scm_handle);
478 return;
480 CloseServiceHandle(svc_handle);
482 /* Retrieve the needed size for the buffer */
483 SetLastError(0xdeadbeef);
484 displaysize = -1;
485 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
486 ok(!ret, "Expected failure\n");
487 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
488 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
489 tempsize = displaysize;
491 displaysize = 0;
492 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
493 ok(!ret, "Expected failure\n");
494 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
495 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
496 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
498 /* Buffer is too small */
499 SetLastError(0xdeadbeef);
500 displaysize = (tempsize / 2);
501 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
502 ok(!ret, "Expected failure\n");
503 ok(displaysize == tempsize, "Expected the needed buffersize\n");
504 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
505 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
507 /* First try with a buffer that should be big enough to hold
508 * the ANSI string (and terminating character). This succeeds on Windows
509 * although when asked (see above 2 tests) it will return twice the needed size.
511 SetLastError(0xdeadbeef);
512 displaysize = (tempsize / 2) + 1;
513 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
514 ok(ret, "Expected success\n");
515 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
516 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
517 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
518 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
519 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
521 /* Now with the original returned size */
522 SetLastError(0xdeadbeef);
523 displaysize = tempsize;
524 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
525 ok(ret, "Expected success\n");
526 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
527 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
528 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
529 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
530 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
532 /* And with a bigger than needed buffer */
533 SetLastError(0xdeadbeef);
534 displaysize = tempsize * 2;
535 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
536 ok(ret, "Expected success\n");
537 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
538 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
539 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
540 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
541 /* Test that shows that if the buffersize is enough, it's not changed */
542 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
543 ok(lstrlen(displayname) == tempsize/2,
544 "Expected the buffer to be twice the length of the string\n") ;
546 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
547 SetLastError(0xdeadbeef);
548 displaysize = -1;
549 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
550 ok(!ret, "Expected failure\n");
551 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
552 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
554 /* Buffer is too small */
555 SetLastError(0xdeadbeef);
556 tempsizeW = displaysize;
557 displaysize = tempsizeW / 2;
558 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
559 ok(!ret, "Expected failure\n");
560 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
561 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
562 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
564 /* Now with the original returned size */
565 SetLastError(0xdeadbeef);
566 displaysize = tempsizeW;
567 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
568 ok(!ret, "Expected failure\n");
569 ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
570 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
571 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
573 /* And with a bigger than needed buffer */
574 SetLastError(0xdeadbeef);
575 displaysize = tempsizeW + 1; /* This caters for the null terminating character */
576 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
577 ok(ret, "Expected success\n");
578 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
579 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
580 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
581 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
582 ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
583 ok(lstrlenW(displaynameW) == displaysize,
584 "Expected the buffer to be the length of the string\n") ;
585 ok(tempsize / 2 == tempsizeW,
586 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
588 CloseServiceHandle(scm_handle);
590 /* Test for a service without a displayname (which is valid). This should return
591 * the servicename itself.
593 SetLastError(0xdeadbeef);
594 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
595 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
597 skip("Not enough rights to get a handle to the manager\n");
598 return;
601 SetLastError(0xdeadbeef);
602 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
603 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
604 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
605 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
606 if (!svc_handle)
608 CloseServiceHandle(scm_handle);
609 return;
612 /* Retrieve the needed size for the buffer */
613 SetLastError(0xdeadbeef);
614 displaysize = -1;
615 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
616 ok(!ret, "Expected failure\n");
617 ok(displaysize == lstrlen(servicename) * 2,
618 "Expected the displaysize to be twice the size of the servicename\n");
619 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
620 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
622 /* Buffer is too small */
623 SetLastError(0xdeadbeef);
624 tempsize = displaysize;
625 displaysize = (tempsize / 2);
626 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
627 ok(!ret, "Expected failure\n");
628 ok(displaysize == tempsize, "Expected the needed buffersize\n");
629 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
630 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
632 /* Get the displayname */
633 SetLastError(0xdeadbeef);
634 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
635 ok(ret, "Expected success\n");
636 ok(!lstrcmpi(displayname, servicename),
637 "Expected displayname to be %s, got %s\n", servicename, displayname);
638 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
639 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
640 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
641 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
643 /* Delete the service */
644 ret = DeleteService(svc_handle);
645 ok(ret, "Expected success\n");
647 CloseServiceHandle(svc_handle);
648 CloseServiceHandle(scm_handle);
650 /* Wait a while. Just in case one of the following tests does a CreateService again */
651 Sleep(1000);
654 static void test_get_servicekeyname(void)
656 SC_HANDLE scm_handle, svc_handle;
657 CHAR servicename[4096];
658 CHAR displayname[4096];
659 WCHAR servicenameW[4096];
660 WCHAR displaynameW[4096];
661 DWORD servicesize, displaysize, tempsize;
662 BOOL ret;
663 static const CHAR deadbeef[] = "Deadbeef";
664 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
666 /* Having NULL for the size of the buffer will crash on W2K3 */
668 SetLastError(0xdeadbeef);
669 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
670 ok(!ret, "Expected failure\n");
671 ok(GetLastError() == ERROR_INVALID_HANDLE,
672 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
674 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
676 servicesize = 200;
677 SetLastError(0xdeadbeef);
678 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
679 ok(!ret, "Expected failure\n");
680 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
681 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
682 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
683 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
685 /* Valid handle and buffer but no displayname */
686 servicesize = 200;
687 SetLastError(0xdeadbeef);
688 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
689 ok(!ret, "Expected failure\n");
690 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
691 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
692 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
693 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
695 /* Test for nonexistent displayname */
696 SetLastError(0xdeadbeef);
697 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
698 ok(!ret, "Expected failure\n");
699 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
700 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
701 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
703 servicesize = 15;
704 strcpy(servicename, "ABC");
705 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
706 ok(!ret, "Expected failure\n");
707 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
708 ok(servicename[0] == 0, "Service name not empty\n");
710 servicesize = 15;
711 servicenameW[0] = 'A';
712 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
713 ok(!ret, "Expected failure\n");
714 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
715 ok(servicenameW[0] == 0, "Service name not empty\n");
717 servicesize = 0;
718 strcpy(servicename, "ABC");
719 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
720 ok(!ret, "Expected failure\n");
721 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
722 ok(servicename[0] == 'A', "Service name changed\n");
724 servicesize = 0;
725 servicenameW[0] = 'A';
726 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
727 ok(!ret, "Expected failure\n");
728 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
729 ok(servicenameW[0] == 'A', "Service name changed\n");
731 /* Check if 'Spooler' exists */
732 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
733 if (!svc_handle)
735 skip("Spooler service doesn't exist\n");
736 CloseServiceHandle(scm_handle);
737 return;
739 CloseServiceHandle(svc_handle);
741 /* Get the displayname for the 'Spooler' service */
742 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
743 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
745 /* Retrieve the needed size for the buffer */
746 SetLastError(0xdeadbeef);
747 servicesize = 0;
748 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
749 ok(!ret, "Expected failure\n");
750 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
751 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
753 /* Valid call with the correct buffersize */
754 SetLastError(0xdeadbeef);
755 tempsize = servicesize;
756 servicesize *= 2;
757 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
758 ok(ret, "Expected success\n");
759 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
760 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
761 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
762 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
763 if (ret)
765 ok(lstrlen(servicename) == tempsize/2,
766 "Expected the buffer to be twice the length of the string\n") ;
767 ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
768 ok(servicesize == (tempsize * 2),
769 "Expected servicesize not to change if buffer not insufficient\n") ;
772 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
773 SetLastError(0xdeadbeef);
774 servicesize *= 2;
775 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
776 ok(ret, "Expected success\n");
777 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
778 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
779 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
780 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
781 if (ret)
783 ok(lstrlen(servicename) == tempsize/2,
784 "Expected the buffer to be twice the length of the string\n") ;
785 ok(servicesize == lstrlenW(servicenameW),
786 "Expected servicesize not to change if buffer not insufficient\n") ;
789 SetLastError(0xdeadbeef);
790 servicesize = 3;
791 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
792 ok(!ret, "Expected failure\n");
793 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
794 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
795 ok(servicenameW[0] == 0, "Buffer not empty\n");
797 CloseServiceHandle(scm_handle);
800 static void test_close(void)
802 SC_HANDLE handle;
803 BOOL ret;
805 /* NULL handle */
806 SetLastError(0xdeadbeef);
807 ret = CloseServiceHandle(NULL);
808 ok(!ret, "Expected failure\n");
809 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
811 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
813 /* Proper call */
814 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
815 SetLastError(0xdeadbeef);
816 ret = CloseServiceHandle(handle);
817 ok(ret, "Expected success\n");
818 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
819 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
820 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
821 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
824 static void test_sequence(void)
826 SC_HANDLE scm_handle, svc_handle;
827 BOOL ret;
828 QUERY_SERVICE_CONFIGA *config;
829 DWORD given, needed;
830 static const CHAR servicename [] = "Winetest";
831 static const CHAR displayname [] = "Winetest dummy service";
832 static const CHAR displayname2[] = "Winetest dummy service (2)";
833 static const CHAR pathname [] = "we_dont_care.exe";
834 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
835 static const CHAR password [] = "";
836 static const CHAR empty [] = "";
837 static const CHAR localsystem [] = "LocalSystem";
839 SetLastError(0xdeadbeef);
840 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
842 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
844 skip("Not enough rights to get a handle to the manager\n");
845 return;
847 else
848 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
850 if (!scm_handle) return;
852 /* Create a dummy service */
853 SetLastError(0xdeadbeef);
854 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
855 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
856 pathname, NULL, NULL, dependencies, NULL, password);
858 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
860 /* We try and open the service and do the rest of the tests. Some could
861 * fail if the tests were changed between these runs.
863 trace("Deletion probably didn't work last time\n");
864 SetLastError(0xdeadbeef);
865 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
866 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
868 skip("Not enough rights to open the service\n");
869 CloseServiceHandle(scm_handle);
870 return;
872 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
874 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
876 skip("Not enough rights to create the service\n");
877 CloseServiceHandle(scm_handle);
878 return;
880 else
881 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
883 if (!svc_handle) return;
885 /* TODO:
886 * Before we do a QueryServiceConfig we should check the registry. This will make sure
887 * that the correct keys are used.
890 /* Request the size for the buffer */
891 SetLastError(0xdeadbeef);
892 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
893 ok(!ret, "Expected failure\n");
894 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
896 config = HeapAlloc(GetProcessHeap(), 0, needed);
897 given = needed;
898 SetLastError(0xdeadbeef);
899 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
900 ok(ret, "Expected success\n");
901 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
902 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
903 GetLastError() == ERROR_IO_PENDING /* W2K */,
904 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
905 todo_wine
907 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
909 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
910 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
911 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
912 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
913 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
914 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
915 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
916 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
917 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
918 /* TODO: Show the double 0 terminated string */
919 todo_wine
921 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
923 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
924 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
926 ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
927 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
929 QueryServiceConfigA(svc_handle, NULL, 0, &needed);
930 config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
931 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
932 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
933 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
934 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
935 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
936 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
937 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
938 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
939 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
940 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
941 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
942 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
944 SetLastError(0xdeadbeef);
945 ret = DeleteService(svc_handle);
946 ok(ret, "Expected success\n");
947 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
948 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
949 GetLastError() == ERROR_IO_PENDING /* W2K */,
950 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
952 CloseServiceHandle(svc_handle);
954 /* Wait a while. The following test does a CreateService again */
955 Sleep(1000);
957 CloseServiceHandle(scm_handle);
958 HeapFree(GetProcessHeap(), 0, config);
961 static void test_queryconfig2(void)
963 SC_HANDLE scm_handle, svc_handle;
964 BOOL ret;
965 DWORD expected, needed;
966 BYTE buffer[MAX_PATH];
967 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
968 static const CHAR servicename [] = "Winetest";
969 static const CHAR displayname [] = "Winetest dummy service";
970 static const CHAR pathname [] = "we_dont_care.exe";
971 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
972 static const CHAR password [] = "";
973 static const CHAR description [] = "Description";
975 if(!pQueryServiceConfig2A)
977 skip("function QueryServiceConfig2A not present\n");
978 return;
981 SetLastError(0xdeadbeef);
982 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
984 if (!scm_handle)
986 if(GetLastError() == ERROR_ACCESS_DENIED)
987 skip("Not enough rights to get a handle to the manager\n");
988 else
989 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
990 return;
993 /* Create a dummy service */
994 SetLastError(0xdeadbeef);
995 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
996 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
997 pathname, NULL, NULL, dependencies, NULL, password);
999 if (!svc_handle)
1001 if(GetLastError() == ERROR_SERVICE_EXISTS)
1003 /* We try and open the service and do the rest of the tests. Some could
1004 * fail if the tests were changed between these runs.
1006 trace("Deletion probably didn't work last time\n");
1007 SetLastError(0xdeadbeef);
1008 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1009 if (!svc_handle)
1011 if(GetLastError() == ERROR_ACCESS_DENIED)
1012 skip("Not enough rights to open the service\n");
1013 else
1014 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1015 CloseServiceHandle(scm_handle);
1016 return;
1019 if (GetLastError() == ERROR_ACCESS_DENIED)
1021 skip("Not enough rights to create the service\n");
1022 CloseServiceHandle(scm_handle);
1023 return;
1025 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1026 if (!svc_handle)
1028 CloseServiceHandle(scm_handle);
1029 return;
1032 SetLastError(0xdeadbeef);
1033 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1034 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1035 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1037 SetLastError(0xdeadbeef);
1038 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1039 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1040 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1042 SetLastError(0xdeadbeef);
1043 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1044 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1045 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1047 SetLastError(0xdeadbeef);
1048 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1049 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1050 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1051 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1053 SetLastError(0xdeadbeef);
1054 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1055 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1056 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1058 needed = 0;
1059 SetLastError(0xdeadbeef);
1060 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1061 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1062 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1063 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1065 needed = 0;
1066 pConfig->lpDescription = (LPSTR)0xdeadbeef;
1067 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1068 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1069 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1070 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1072 SetLastError(0xdeadbeef);
1073 needed = 0;
1074 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1075 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1076 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1077 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1079 if(!pChangeServiceConfig2A)
1081 skip("function ChangeServiceConfig2A not present\n");
1082 goto cleanup;
1085 pConfig->lpDescription = (LPSTR) description;
1086 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1087 ok(ret, "ChangeServiceConfig2A failed\n");
1088 if (!ret) {
1089 goto cleanup;
1092 SetLastError(0xdeadbeef);
1093 needed = 0;
1094 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1095 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1096 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1097 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1098 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1100 SetLastError(0xdeadbeef);
1101 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1102 ok(!ret, "expected QueryServiceConfig2A to fail\n");
1103 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1105 SetLastError(0xdeadbeef);
1106 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1107 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1108 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1109 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1111 SetLastError(0xdeadbeef);
1112 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1113 ok(ret, "expected QueryServiceConfig2A to succeed\n");
1114 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1115 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1117 if(!pQueryServiceConfig2W)
1119 skip("function QueryServiceConfig2W not present\n");
1120 goto cleanup;
1122 SetLastError(0xdeadbeef);
1123 needed = 0;
1124 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1125 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1126 ok(!ret, "expected QueryServiceConfig2W to fail\n");
1127 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1128 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1130 SetLastError(0xdeadbeef);
1131 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1132 ok(ret, "expected QueryServiceConfig2W to succeed\n");
1134 cleanup:
1135 DeleteService(svc_handle);
1137 CloseServiceHandle(svc_handle);
1139 /* Wait a while. The following test does a CreateService again */
1140 Sleep(1000);
1142 CloseServiceHandle(scm_handle);
1145 static void test_refcount(void)
1147 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1148 static const CHAR servicename [] = "Winetest";
1149 static const CHAR pathname [] = "we_dont_care.exe";
1150 BOOL ret;
1152 /* Get a handle to the Service Control Manager */
1153 SetLastError(0xdeadbeef);
1154 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1155 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1157 skip("Not enough rights to get a handle to the manager\n");
1158 return;
1161 /* Create a service */
1162 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1163 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1164 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1165 ok(svc_handle1 != NULL, "Expected success\n");
1167 /* Get a handle to this new service */
1168 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1169 ok(svc_handle2 != NULL, "Expected success\n");
1171 /* Get another handle to this new service */
1172 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1173 ok(svc_handle3 != NULL, "Expected success\n");
1175 /* Check if we can close the handle to the Service Control Manager */
1176 ret = CloseServiceHandle(scm_handle);
1177 ok(ret, "Expected success\n");
1179 /* Get a new handle to the Service Control Manager */
1180 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1181 ok(scm_handle != NULL, "Expected success\n");
1183 /* Get a handle to this new service */
1184 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1185 ok(svc_handle4 != NULL, "Expected success\n");
1187 /* Delete the service */
1188 ret = DeleteService(svc_handle4);
1189 ok(ret, "Expected success\n");
1191 /* We cannot create the same service again as it's still marked as 'being deleted'.
1192 * The reason is that we still have 4 open handles to this service even though we
1193 * closed the handle to the Service Control Manager in between.
1195 SetLastError(0xdeadbeef);
1196 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1197 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1198 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1199 todo_wine
1201 ok(!svc_handle5, "Expected failure\n");
1202 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1203 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1206 /* FIXME: Remove this when Wine is fixed */
1207 if (svc_handle5)
1209 DeleteService(svc_handle5);
1210 CloseServiceHandle(svc_handle5);
1213 /* Close all the handles to the service and try again */
1214 ret = CloseServiceHandle(svc_handle4);
1215 ok(ret, "Expected success\n");
1216 ret = CloseServiceHandle(svc_handle3);
1217 ok(ret, "Expected success\n");
1218 ret = CloseServiceHandle(svc_handle2);
1219 ok(ret, "Expected success\n");
1220 ret = CloseServiceHandle(svc_handle1);
1221 ok(ret, "Expected success\n");
1223 /* Wait a while. Doing a CreateService too soon will result again
1224 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1226 Sleep(1000);
1228 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1229 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1230 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1231 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1232 ok(svc_handle5 != NULL, "Expected success\n");
1234 /* Delete the service */
1235 ret = DeleteService(svc_handle5);
1236 ok(ret, "Expected success\n");
1238 /* Wait a while. Just in case one of the following tests does a CreateService again */
1239 Sleep(1000);
1241 CloseServiceHandle(svc_handle5);
1242 CloseServiceHandle(scm_handle);
1245 START_TEST(service)
1247 SC_HANDLE scm_handle;
1249 /* Bail out if we are on win98 */
1250 SetLastError(0xdeadbeef);
1251 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1253 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1255 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1256 return;
1258 CloseServiceHandle(scm_handle);
1260 init_function_pointers();
1262 /* First some parameter checking */
1263 test_open_scm();
1264 test_open_svc();
1265 test_create_delete_svc();
1266 test_get_displayname();
1267 test_get_servicekeyname();
1268 test_close();
1269 /* Test the creation, querying and deletion of a service */
1270 test_sequence();
1271 test_queryconfig2();
1272 /* The main reason for this test is to check if any refcounting is used
1273 * and what the rules are
1275 test_refcount();