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
30 #include "wine/test.h"
32 static void test_open_scm(void)
36 /* No access rights */
37 SetLastError(0xdeadbeef);
38 scm_handle = OpenSCManagerA(NULL, NULL, 0);
39 ok(scm_handle != NULL, "Expected success\n");
40 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
41 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
42 GetLastError() == ERROR_IO_PENDING /* W2K */,
43 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
44 CloseServiceHandle(scm_handle);
46 /* Unknown database name */
47 SetLastError(0xdeadbeef);
48 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
49 ok(!scm_handle, "Expected failure\n");
50 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
51 CloseServiceHandle(scm_handle); /* Just in case */
53 /* MSDN says only ServiceActive is allowed, or NULL */
54 SetLastError(0xdeadbeef);
55 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
56 ok(!scm_handle, "Expected failure\n");
57 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
58 CloseServiceHandle(scm_handle); /* Just in case */
60 /* Remote unknown host */
61 SetLastError(0xdeadbeef);
62 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
63 ok(!scm_handle, "Expected failure\n");
65 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
66 CloseServiceHandle(scm_handle); /* Just in case */
68 /* Proper call with an empty hostname */
69 SetLastError(0xdeadbeef);
70 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
71 ok(scm_handle != NULL, "Expected success\n");
72 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
73 GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
74 GetLastError() == 0xdeadbeef /* XP */ ||
75 GetLastError() == ERROR_IO_PENDING /* W2K */,
76 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
77 CloseServiceHandle(scm_handle);
79 /* Again a correct one */
80 SetLastError(0xdeadbeef);
81 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
82 ok(scm_handle != NULL, "Expected success\n");
83 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
84 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
85 GetLastError() == ERROR_IO_PENDING /* W2K */,
86 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
87 CloseServiceHandle(scm_handle);
90 static void test_open_svc(void)
92 SC_HANDLE scm_handle, svc_handle;
94 /* All NULL (invalid access rights) */
95 SetLastError(0xdeadbeef);
96 svc_handle = OpenServiceA(NULL, NULL, 0);
97 ok(!svc_handle, "Expected failure\n");
98 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
100 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
103 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
104 SetLastError(0xdeadbeef);
105 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
106 ok(!svc_handle, "Expected failure\n");
107 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ ||
108 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
109 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
111 /* Non-existent service */
112 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
113 SetLastError(0xdeadbeef);
114 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
115 ok(!svc_handle, "Expected failure\n");
116 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
117 CloseServiceHandle(scm_handle);
119 /* Proper SCM handle but different access rights */
120 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
121 SetLastError(0xdeadbeef);
122 svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
123 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
124 skip("Not enough rights to get a handle to the service\n");
127 ok(svc_handle != NULL, "Expected success\n");
128 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
129 GetLastError() == ERROR_IO_PENDING /* W2K */ ||
130 GetLastError() == 0xdeadbeef /* XP, NT4 */,
131 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
132 CloseServiceHandle(svc_handle);
134 CloseServiceHandle(scm_handle);
137 static void test_create_delete_svc(void)
139 SC_HANDLE scm_handle, svc_handle1;
140 CHAR username[UNLEN + 1];
141 DWORD user_size = UNLEN + 1;
142 CHAR account[UNLEN + 3];
143 static const CHAR servicename [] = "Winetest";
144 static const CHAR pathname [] = "we_dont_care.exe";
145 static const CHAR empty [] = "";
146 static const CHAR spooler [] = "Spooler"; /* Should be available on all platforms */
147 static const CHAR password [] = "secret";
148 BOOL spooler_exists = FALSE;
151 DWORD display_size = sizeof(display);
153 /* Get the username and turn it into an account to be used in some tests */
154 GetUserNameA(username, &user_size);
155 lstrcpy(account, ".\\");
156 lstrcat(account, username);
159 SetLastError(0xdeadbeef);
160 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
161 ok(!svc_handle1, "Expected failure\n");
162 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
164 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
166 /* Only a valid handle to the Service Control Manager */
167 SetLastError(0xdeadbeef);
168 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
169 ok(!svc_handle1, "Expected failure\n");
170 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
171 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
172 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
174 /* Now with a servicename */
175 SetLastError(0xdeadbeef);
176 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
177 ok(!svc_handle1, "Expected failure\n");
178 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
179 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
180 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
182 /* Or just a binary name */
183 SetLastError(0xdeadbeef);
184 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
185 ok(!svc_handle1, "Expected failure\n");
186 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ ||
187 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
188 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
190 /* Both servicename and binary name (We only have connect rights) */
191 SetLastError(0xdeadbeef);
192 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
193 ok(!svc_handle1, "Expected failure\n");
194 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
196 /* They can even be empty at this stage of parameter checking */
197 SetLastError(0xdeadbeef);
198 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
199 ok(!svc_handle1, "Expected failure\n");
200 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
202 SetLastError(0xdeadbeef);
203 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, 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 /* Open the Service Control Manager with minimal rights for creation
208 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
210 CloseServiceHandle(scm_handle);
211 SetLastError(0xdeadbeef);
212 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
213 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
215 skip("Not enough rights to get a handle to the manager\n");
219 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
221 /* Empty strings for servicename and binary name are checked */
222 SetLastError(0xdeadbeef);
223 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
224 ok(!svc_handle1, "Expected failure\n");
225 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
227 SetLastError(0xdeadbeef);
228 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
229 ok(!svc_handle1, "Expected failure\n");
230 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
232 SetLastError(0xdeadbeef);
233 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
234 ok(!svc_handle1, "Expected failure\n");
235 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
237 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
238 * an ERROR_INVALID_PARAMETER)
240 SetLastError(0xdeadbeef);
241 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
242 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
243 ok(!svc_handle1, "Expected failure\n");
244 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
246 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
248 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
249 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
251 SetLastError(0xdeadbeef);
252 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
253 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
254 ok(!svc_handle1, "Expected failure\n");
255 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
257 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
258 SetLastError(0xdeadbeef);
259 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
260 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
261 ok(!svc_handle1, "Expected failure\n");
262 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
264 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
265 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
267 SetLastError(0xdeadbeef);
268 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
269 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
270 ok(!svc_handle1, "Expected failure\n");
271 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
273 /* Illegal (start-type is not a mask and should only be one of the possibilities)
274 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
275 * it's most likely not the wanted start-type)
277 SetLastError(0xdeadbeef);
278 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
279 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
280 ok(!svc_handle1, "Expected failure\n");
281 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
283 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
284 SetLastError(0xdeadbeef);
285 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
286 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
287 ok(!svc_handle1, "Expected failure\n");
288 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
290 /* The service already exists (check first, just in case) */
291 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
294 spooler_exists = TRUE;
295 CloseServiceHandle(svc_handle1);
296 SetLastError(0xdeadbeef);
297 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
298 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
299 ok(!svc_handle1, "Expected failure\n");
300 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
303 skip("Spooler service doesn't exist\n");
305 /* To find an existing displayname we check the 'Spooler' service. Although the registry
306 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
307 * to the servicename and can't be used as well for a new displayname.
311 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
314 skip("Could not retrieve a displayname for the Spooler service\n");
317 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
318 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
319 ok(!svc_handle1, "Expected failure\n");
320 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
321 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
325 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
327 /* Windows doesn't care about the access rights for creation (which makes
328 * sense as there is no service yet) as long as there are sufficient
329 * rights to the manager.
331 SetLastError(0xdeadbeef);
332 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
333 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
334 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
335 ok(GetLastError() == ERROR_SUCCESS /* W2K3, Vista */ ||
336 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
337 GetLastError() == ERROR_IO_PENDING /* W2K */,
338 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
340 /* DeleteService however must have proper rights */
341 SetLastError(0xdeadbeef);
342 ret = DeleteService(svc_handle1);
343 ok(!ret, "Expected failure\n");
344 ok(GetLastError() == ERROR_ACCESS_DENIED,
345 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
347 /* Open the service with minimal rights for deletion.
348 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
350 CloseServiceHandle(svc_handle1);
351 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
353 /* Now that we have the proper rights, we should be able to delete */
354 SetLastError(0xdeadbeef);
355 ret = DeleteService(svc_handle1);
356 ok(ret, "Expected success\n");
357 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
358 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
359 GetLastError() == ERROR_IO_PENDING /* W2K */,
360 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
362 CloseServiceHandle(svc_handle1);
364 CloseServiceHandle(scm_handle);
366 /* Wait a while. One of the following tests also does a CreateService for the
367 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
368 * error if we do this to quick. Vista seems more picky then the others.
372 /* And a final NULL check */
373 SetLastError(0xdeadbeef);
374 ret = DeleteService(NULL);
375 ok(!ret, "Expected failure\n");
376 ok(GetLastError() == ERROR_INVALID_HANDLE,
377 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
380 static void test_close(void)
386 SetLastError(0xdeadbeef);
387 ret = CloseServiceHandle(NULL);
390 ok(!ret, "Expected failure\n");
391 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
394 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
397 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
398 SetLastError(0xdeadbeef);
399 ret = CloseServiceHandle(handle);
400 ok(ret, "Expected success\n");
401 ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
402 GetLastError() == ERROR_SUCCESS /* W2K3 */ ||
403 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
404 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
407 static void test_sequence(void)
409 SC_HANDLE scm_handle, svc_handle;
411 QUERY_SERVICE_CONFIGA *config;
413 static const CHAR servicename [] = "Winetest";
414 static const CHAR displayname [] = "Winetest dummy service";
415 static const CHAR pathname [] = "we_dont_care.exe";
416 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0\0";
417 static const CHAR password [] = "";
418 static const CHAR empty [] = "";
419 static const CHAR localsystem [] = "LocalSystem";
421 SetLastError(0xdeadbeef);
422 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
424 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
426 skip("Not enough rights to get a handle to the manager\n");
430 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
432 if (!scm_handle) return;
434 /* Create a dummy service */
435 SetLastError(0xdeadbeef);
436 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
437 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
438 pathname, NULL, NULL, dependencies, NULL, password);
440 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
442 /* We try and open the service and do the rest of the tests. Some could
443 * fail if the tests were changed between these runs.
445 trace("Deletion probably didn't work last time\n");
446 SetLastError(0xdeadbeef);
447 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
448 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
450 skip("Not enough rights to open the service\n");
451 CloseServiceHandle(scm_handle);
454 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
456 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
458 skip("Not enough rights to create the service\n");
459 CloseServiceHandle(scm_handle);
463 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
465 if (!svc_handle) return;
468 * Before we do a QueryServiceConfig we should check the registry. This will make sure
469 * that the correct keys are used.
472 /* Request the size for the buffer */
473 SetLastError(0xdeadbeef);
474 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
475 ok(!ret, "Expected failure\n");
476 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
478 config = HeapAlloc(GetProcessHeap(), 0, needed);
480 SetLastError(0xdeadbeef);
481 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
482 ok(ret, "Expected success\n");
485 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
486 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
487 GetLastError() == ERROR_IO_PENDING /* W2K */,
488 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
489 ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
491 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
492 config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
493 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
494 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
495 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
496 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
497 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
498 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
499 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
500 /* TODO: Show the double 0 terminated string */
503 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
504 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
506 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
508 SetLastError(0xdeadbeef);
509 ret = DeleteService(svc_handle);
510 ok(ret, "Expected success\n");
511 ok(GetLastError() == ERROR_SUCCESS /* W2K3 */||
512 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
513 GetLastError() == ERROR_IO_PENDING /* W2K */,
514 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
516 CloseServiceHandle(svc_handle);
517 CloseServiceHandle(scm_handle);
522 SC_HANDLE scm_handle;
524 /* Bail out if we are on win98 */
525 SetLastError(0xdeadbeef);
526 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
528 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
530 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
533 CloseServiceHandle(scm_handle);
535 /* First some parameter checking */
538 test_create_delete_svc();
540 /* Test the creation, querying and deletion of a service */