advapi32/tests: Don't test the contents of an uninitialized buffer.
[wine] / dlls / advapi32 / tests / service.c
1 /*
2  * Unit tests for service functions
3  *
4  * Copyright (c) 2007 Paul Vriens
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
28 #include "winsvc.h"
29 #include "lmcons.h"
30
31 #include "wine/test.h"
32
33 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
34
35 static void test_open_scm(void)
36 {
37     SC_HANDLE scm_handle;
38
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);
48
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 */
55
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 */
62
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");
67     todo_wine
68     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
69     CloseServiceHandle(scm_handle); /* Just in case */
70
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);
81
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);
91 }
92
93 static void test_open_svc(void)
94 {
95     SC_HANDLE scm_handle, svc_handle;
96
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());
102
103     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
104
105     /* NULL service */
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());
113
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);
121
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");
128     else
129     {
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);
136     }
137     CloseServiceHandle(scm_handle);
138 }
139
140 static void test_create_delete_svc(void)
141 {
142     SC_HANDLE scm_handle, svc_handle1;
143     CHAR username[UNLEN + 1], *domain;
144     DWORD user_size = UNLEN + 1, domain_size = 0;
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;
151     BOOL ret;
152     CHAR display[4096];
153     DWORD display_size = sizeof(display);
154
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     GetComputerNameEx(ComputerNameDnsDomain, NULL, &domain_size);
159     domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
160     GetComputerNameEx(ComputerNameDnsDomain, domain, &domain_size);
161     if (domain_size > 1)
162         sprintf(account, "%s\\%s", domain, username);
163     else
164         sprintf(account, ".\\%s", username);
165     HeapFree(GetProcessHeap(), 0, domain);
166
167     /* All NULL */
168     SetLastError(0xdeadbeef);
169     svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
170     ok(!svc_handle1, "Expected failure\n");
171     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
172
173     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
174
175     /* Only a valid handle to the Service Control Manager */
176     SetLastError(0xdeadbeef);
177     svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
178     ok(!svc_handle1, "Expected failure\n");
179     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
180        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
181        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
182
183     /* Now with a servicename */
184     SetLastError(0xdeadbeef);
185     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
186     ok(!svc_handle1, "Expected failure\n");
187     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
188        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
189        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
190
191     /* Or just a binary name */
192     SetLastError(0xdeadbeef);
193     svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
194     ok(!svc_handle1, "Expected failure\n");
195     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
196        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
197        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
198
199     /* Both servicename and binary name (We only have connect rights) */
200     SetLastError(0xdeadbeef);
201     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
202     ok(!svc_handle1, "Expected failure\n");
203     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
204
205     /* They can even be empty at this stage of parameter checking */
206     SetLastError(0xdeadbeef);
207     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
208     ok(!svc_handle1, "Expected failure\n");
209     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
210
211     SetLastError(0xdeadbeef);
212     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
213     ok(!svc_handle1, "Expected failure\n");
214     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
215
216     /* Open the Service Control Manager with minimal rights for creation
217      * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
218      */
219     CloseServiceHandle(scm_handle);
220     SetLastError(0xdeadbeef);
221     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
222     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
223     {
224         skip("Not enough rights to get a handle to the manager\n");
225         return;
226     }
227
228     /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
229
230     /* Empty strings for servicename and binary name are checked */
231     SetLastError(0xdeadbeef);
232     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
233     ok(!svc_handle1, "Expected failure\n");
234     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
235
236     SetLastError(0xdeadbeef);
237     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
238     ok(!svc_handle1, "Expected failure\n");
239     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
240
241     SetLastError(0xdeadbeef);
242     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
243     ok(!svc_handle1, "Expected failure\n");
244     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
245
246     /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
247      * an ERROR_INVALID_PARAMETER)
248      */
249     SetLastError(0xdeadbeef);
250     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
251                                  SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
252     ok(!svc_handle1, "Expected failure\n");
253     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
254
255     /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
256
257     /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
258      * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
259      */
260     SetLastError(0xdeadbeef);
261     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
262                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
263     ok(!svc_handle1, "Expected failure\n");
264     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
265
266     /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
267     SetLastError(0xdeadbeef);
268     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
269                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
270     ok(!svc_handle1, "Expected failure\n");
271     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
272
273     /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
274      * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
275      */
276     SetLastError(0xdeadbeef);
277     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
278                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
279     ok(!svc_handle1, "Expected failure\n");
280     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
281
282     /* Illegal (start-type is not a mask and should only be one of the possibilities)
283      * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
284      * it's most likely not the wanted start-type)
285      */
286     SetLastError(0xdeadbeef);
287     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
288                                  SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
289     ok(!svc_handle1, "Expected failure\n");
290     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
291
292     /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
293     SetLastError(0xdeadbeef);
294     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
295                                  SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
296     ok(!svc_handle1, "Expected failure\n");
297     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
298
299     /* The service already exists (check first, just in case) */
300     svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
301     if (svc_handle1)
302     {
303         spooler_exists = TRUE;
304         CloseServiceHandle(svc_handle1);
305         SetLastError(0xdeadbeef);
306         svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
307                                      SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
308         ok(!svc_handle1, "Expected failure\n");
309         ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
310     }
311     else
312         skip("Spooler service doesn't exist\n");
313
314     /* To find an existing displayname we check the 'Spooler' service. Although the registry
315      * doesn't show DisplayName on NT4, this call will return a displayname which is equal
316      * to the servicename and can't be used as well for a new displayname.
317      */
318     if (spooler_exists)
319     {
320         ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
321
322         if (!ret)
323             skip("Could not retrieve a displayname for the Spooler service\n");
324         else
325         {
326             svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
327                                          SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
328             ok(!svc_handle1, "Expected failure\n");
329             ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
330                "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
331         }
332     }
333     else
334         skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
335
336     /* Windows doesn't care about the access rights for creation (which makes
337      * sense as there is no service yet) as long as there are sufficient
338      * rights to the manager.
339      */
340     SetLastError(0xdeadbeef);
341     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
342                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
343     ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
344     ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
345        GetLastError() == 0xdeadbeef       /* NT4, XP */ ||
346        GetLastError() == ERROR_IO_PENDING /* W2K */,
347        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
348
349     /* DeleteService however must have proper rights */
350     SetLastError(0xdeadbeef);
351     ret = DeleteService(svc_handle1);
352     ok(!ret, "Expected failure\n");
353     ok(GetLastError() == ERROR_ACCESS_DENIED,
354        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
355
356     /* Open the service with minimal rights for deletion.
357      * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
358      */
359     CloseServiceHandle(svc_handle1);
360     svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
361
362     /* Now that we have the proper rights, we should be able to delete */
363     SetLastError(0xdeadbeef);
364     ret = DeleteService(svc_handle1);
365     ok(ret, "Expected success\n");
366     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
367        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */ ||
368        GetLastError() == ERROR_IO_PENDING /* W2K */,
369        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
370
371     CloseServiceHandle(svc_handle1);
372
373     CloseServiceHandle(scm_handle);
374
375     /* Wait a while. One of the following tests also does a CreateService for the
376      * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
377      * error if we do this to quick. Vista seems more picky then the others.
378      */
379     Sleep(1000);
380
381     /* And a final NULL check */
382     SetLastError(0xdeadbeef);
383     ret = DeleteService(NULL);
384     ok(!ret, "Expected failure\n");
385     ok(GetLastError() == ERROR_INVALID_HANDLE,
386         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
387 }
388
389 static void test_get_displayname(void)
390 {
391     SC_HANDLE scm_handle, svc_handle;
392     BOOL ret;
393     CHAR displayname[4096];
394     WCHAR displaynameW[2048];
395     DWORD displaysize, tempsize, tempsizeW;
396     static const CHAR deadbeef[] = "Deadbeef";
397     static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
398     static const CHAR servicename[] = "Winetest";
399     static const CHAR pathname[] = "we_dont_care.exe";
400
401     /* Having NULL for the size of the buffer will crash on W2K3 */
402
403     SetLastError(0xdeadbeef);
404     ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
405     ok(!ret, "Expected failure\n");
406     ok(GetLastError() == ERROR_INVALID_HANDLE,
407        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
408
409     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
410
411     SetLastError(0xdeadbeef);
412     ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
413     ok(!ret, "Expected failure\n");
414     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
415        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
416        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
417
418     SetLastError(0xdeadbeef);
419     displaysize = sizeof(displayname);
420     ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
421     ok(!ret, "Expected failure\n");
422     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
423        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
424        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
425
426     /* Test for nonexistent service */
427     SetLastError(0xdeadbeef);
428     displaysize = -1;
429     ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
430     ok(!ret, "Expected failure\n");
431     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
432        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
433
434     /* Check if 'Spooler' exists */
435     svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
436     if (!svc_handle)
437     {
438         skip("Spooler service doesn't exist\n");
439         CloseServiceHandle(scm_handle);
440         return;
441     }
442     CloseServiceHandle(svc_handle);
443
444     /* Retrieve the needed size for the buffer */
445     SetLastError(0xdeadbeef);
446     displaysize = -1;
447     ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
448     ok(!ret, "Expected failure\n");
449     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
450        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
451
452     /* Buffer is too small */
453     SetLastError(0xdeadbeef);
454     tempsize = displaysize;
455     displaysize = (tempsize / 2);
456     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
457     ok(!ret, "Expected failure\n");
458     ok(displaysize == tempsize, "Expected the needed buffersize\n");
459     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
460        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
461
462     /* First try with a buffer that should be big enough to hold
463      * the ANSI string (and terminating character). This succeeds on Windows
464      *  although when asked (see above 2 tests) it will return twice the needed size.
465      */
466     SetLastError(0xdeadbeef);
467     displaysize = (tempsize / 2) + 1;
468     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
469     ok(ret, "Expected success\n");
470     ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
471     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
472        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
473        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
474        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
475
476     /* Now with the original returned size */
477     SetLastError(0xdeadbeef);
478     displaysize = tempsize;
479     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
480     ok(ret, "Expected success\n");
481     ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
482     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
483        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
484        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
485        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
486
487     /* And with a bigger than needed buffer */
488     SetLastError(0xdeadbeef);
489     displaysize = tempsize * 2;
490     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
491     ok(ret, "Expected success\n");
492     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
493        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
494        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
495        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
496     /* Test that shows that if the buffersize is enough, it's not changed */
497     ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
498     ok(lstrlen(displayname) == tempsize/2,
499        "Expected the buffer to be twice the length of the string\n") ;
500
501     /* Do the buffer(size) tests also for GetServiceDisplayNameW */
502     SetLastError(0xdeadbeef);
503     displaysize = -1;
504     ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
505     ok(!ret, "Expected failure\n");
506     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
507        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
508
509     /* Buffer is too small */
510     SetLastError(0xdeadbeef);
511     tempsizeW = displaysize;
512     displaysize = tempsizeW / 2;
513     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
514     ok(!ret, "Expected failure\n");
515     ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
516     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
517        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
518
519     /* Now with the original returned size */
520     SetLastError(0xdeadbeef);
521     displaysize = tempsizeW;
522     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
523     ok(!ret, "Expected failure\n");
524     ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
525     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
526        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
527
528     /* And with a bigger than needed buffer */
529     SetLastError(0xdeadbeef);
530     displaysize = tempsizeW + 1; /* This caters for the null terminating character */
531     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
532     ok(ret, "Expected success\n");
533     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
534        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
535        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
536        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
537     ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
538     ok(lstrlenW(displaynameW) == displaysize,
539        "Expected the buffer to be the length of the string\n") ;
540     ok(tempsize / 2 == tempsizeW,
541        "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
542
543     CloseServiceHandle(scm_handle);
544
545     /* Test for a service without a displayname (which is valid). This should return
546      * the servicename itself.
547      */
548     SetLastError(0xdeadbeef);
549     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
550     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
551     {
552         skip("Not enough rights to get a handle to the manager\n");
553         return;
554     }
555
556     SetLastError(0xdeadbeef);
557     svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
558                                 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
559                                 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
560     ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
561     if (!svc_handle)
562     {
563         CloseServiceHandle(scm_handle);
564         return;
565     }
566
567     /* Retrieve the needed size for the buffer */
568     SetLastError(0xdeadbeef);
569     displaysize = -1;
570     ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
571     ok(!ret, "Expected failure\n");
572     ok(displaysize == lstrlen(servicename) * 2,
573        "Expected the displaysize to be twice the size of the servicename\n");
574     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
575        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
576
577     /* Buffer is too small */
578     SetLastError(0xdeadbeef);
579     tempsize = displaysize;
580     displaysize = (tempsize / 2);
581     ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
582     ok(!ret, "Expected failure\n");
583     ok(displaysize == tempsize, "Expected the needed buffersize\n");
584     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
585        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
586
587     /* Get the displayname */
588     SetLastError(0xdeadbeef);
589     ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
590     ok(ret, "Expected success\n");
591     ok(!lstrcmpi(displayname, servicename),
592        "Expected displayname to be %s, got %s\n", servicename, displayname);
593     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
594        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
595        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
596        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
597
598     /* Delete the service */
599     ret = DeleteService(svc_handle);
600     ok(ret, "Expected success\n");
601
602     CloseServiceHandle(svc_handle);
603     CloseServiceHandle(scm_handle);
604
605     /* Wait a while. Just in case one of the following tests does a CreateService again */
606     Sleep(1000);
607 }
608
609 static void test_get_servicekeyname(void)
610 {
611     SC_HANDLE scm_handle, svc_handle;
612     CHAR servicename[4096];
613     CHAR displayname[4096];
614     DWORD servicesize, displaysize, tempsize;
615     BOOL ret;
616     static const CHAR deadbeef[] = "Deadbeef";
617
618     /* Having NULL for the size of the buffer will crash on W2K3 */
619
620     SetLastError(0xdeadbeef);
621     ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
622     ok(!ret, "Expected failure\n");
623     todo_wine
624     ok(GetLastError() == ERROR_INVALID_HANDLE,
625        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
626
627     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
628
629     SetLastError(0xdeadbeef);
630     ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
631     ok(!ret, "Expected failure\n");
632     todo_wine
633     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
634        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
635        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
636
637     /* Valid handle and buffer but no displayname */
638     SetLastError(0xdeadbeef);
639     ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
640     ok(!ret, "Expected failure\n");
641     todo_wine
642     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
643        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
644        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
645
646     /* Test for nonexistent displayname */
647     SetLastError(0xdeadbeef);
648     ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
649     ok(!ret, "Expected failure\n");
650     todo_wine
651     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
652        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
653
654     /* Check if 'Spooler' exists */
655     svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
656     if (!svc_handle)
657     {
658         skip("Spooler service doesn't exist\n");
659         CloseServiceHandle(scm_handle);
660         return;
661     }
662     CloseServiceHandle(svc_handle);
663
664     /* Get the displayname for the 'Spooler' service */
665     GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
666     GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
667
668     /* Retrieve the needed size for the buffer */
669     SetLastError(0xdeadbeef);
670     servicesize = 0;
671     ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
672     ok(!ret, "Expected failure\n");
673     todo_wine
674     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
675        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
676
677     /* Valid call with the correct buffersize */
678     SetLastError(0xdeadbeef);
679     tempsize = servicesize;
680     servicesize *= 2;
681     ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
682     todo_wine
683     ok(ret, "Expected success\n");
684     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
685        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
686        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
687        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
688     if (ret)
689     {
690         ok(lstrlen(servicename) == tempsize/2,
691            "Expected the buffer to be twice the length of the string\n") ;
692         ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
693     }
694
695     CloseServiceHandle(scm_handle);
696 }
697
698 static void test_close(void)
699 {
700     SC_HANDLE handle;
701     BOOL ret;
702
703     /* NULL handle */
704     SetLastError(0xdeadbeef);
705     ret = CloseServiceHandle(NULL);
706     todo_wine
707     {
708     ok(!ret, "Expected failure\n");
709     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
710     }
711
712     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
713
714     /* Proper call */
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());
723 }
724
725 static void test_sequence(void)
726 {
727     SC_HANDLE scm_handle, svc_handle;
728     BOOL ret;
729     QUERY_SERVICE_CONFIGA *config;
730     DWORD given, needed;
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\0";
735     static const CHAR password    [] = "";
736     static const CHAR empty       [] = "";
737     static const CHAR localsystem [] = "LocalSystem";
738
739     SetLastError(0xdeadbeef);
740     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
741
742     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
743     {
744         skip("Not enough rights to get a handle to the manager\n");
745         return;
746     }
747     else
748         ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
749
750     if (!scm_handle) return;
751
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);
757
758     if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
759     {
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.
762          */
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))
767         {
768             skip("Not enough rights to open the service\n");
769             CloseServiceHandle(scm_handle);        
770             return;
771         }
772         ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
773     }
774     else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
775     {
776         skip("Not enough rights to create the service\n");
777         CloseServiceHandle(scm_handle);        
778         return;
779     }
780     else
781         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
782
783     if (!svc_handle) return;
784
785     /* TODO:
786      * Before we do a QueryServiceConfig we should check the registry. This will make sure
787      * that the correct keys are used.
788      */
789
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());
795
796     config = HeapAlloc(GetProcessHeap(), 0, needed);
797     given = needed;
798     SetLastError(0xdeadbeef);
799     ret = QueryServiceConfigA(svc_handle, config, given, &needed);
800     ok(ret, "Expected success\n");
801     todo_wine
802     {
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);
808     }
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 */
819     todo_wine
820     {
821     ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
822     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
823     }
824     ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
825     
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());
833     
834     CloseServiceHandle(svc_handle);
835
836     /* Wait a while. The following test does a CreateService again */
837     Sleep(1000);
838
839     CloseServiceHandle(scm_handle);
840 }
841
842 static void test_refcount(void)
843 {
844     SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
845     static const CHAR servicename         [] = "Winetest";
846     static const CHAR pathname            [] = "we_dont_care.exe";
847     BOOL ret;
848
849     /* Get a handle to the Service Control Manager */
850     SetLastError(0xdeadbeef);
851     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
852     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
853     {
854         skip("Not enough rights to get a handle to the manager\n");
855         return;
856     }
857
858     /* Create a service */
859     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
860                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
861                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
862     ok(svc_handle1 != NULL, "Expected success\n");
863
864     /* Get a handle to this new service */
865     svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
866     ok(svc_handle2 != NULL, "Expected success\n");
867
868     /* Get another handle to this new service */
869     svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
870     ok(svc_handle3 != NULL, "Expected success\n");
871
872     /* Check if we can close the handle to the Service Control Manager */
873     ret = CloseServiceHandle(scm_handle);
874     ok(ret, "Expected success\n");
875
876     /* Get a new handle to the Service Control Manager */
877     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
878     ok(scm_handle != NULL, "Expected success\n");
879
880     /* Get a handle to this new service */
881     svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
882     ok(svc_handle4 != NULL, "Expected success\n");
883
884     /* Delete the service */
885     ret = DeleteService(svc_handle4);
886     ok(ret, "Expected success\n");
887
888     /* We cannot create the same service again as it's still marked as 'being deleted'.
889      * The reason is that we still have 4 open handles to this service even though we
890      * closed the handle to the Service Control Manager in between.
891      */
892     SetLastError(0xdeadbeef);
893     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
894                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
895                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
896     todo_wine
897     {
898     ok(!svc_handle5, "Expected failure\n");
899     ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
900        "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
901     }
902
903     /* FIXME: Remove this when Wine is fixed */
904     if (svc_handle5)
905     {
906         DeleteService(svc_handle5);
907         CloseServiceHandle(svc_handle5);
908     }
909
910     /* Close all the handles to the service and try again */
911     ret = CloseServiceHandle(svc_handle4);
912     ok(ret, "Expected success\n");
913     ret = CloseServiceHandle(svc_handle3);
914     ok(ret, "Expected success\n");
915     ret = CloseServiceHandle(svc_handle2);
916     ok(ret, "Expected success\n");
917     ret = CloseServiceHandle(svc_handle1);
918     ok(ret, "Expected success\n");
919
920     /* Wait a while. Doing a CreateService too soon will result again
921      * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
922      */
923     Sleep(1000);
924
925     /* We succeed now as all handles are closed (tested this also with a long SLeep() */
926     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
927                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
928                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
929     ok(svc_handle5 != NULL, "Expected success\n");
930
931     /* Delete the service */
932     ret = DeleteService(svc_handle5);
933     ok(ret, "Expected success\n");
934
935     /* Wait a while. Just in case one of the following tests does a CreateService again */
936     Sleep(1000);
937
938     CloseServiceHandle(svc_handle5);
939     CloseServiceHandle(scm_handle);
940 }
941
942 START_TEST(service)
943 {
944     SC_HANDLE scm_handle;
945
946     /* Bail out if we are on win98 */
947     SetLastError(0xdeadbeef);
948     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
949
950     if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
951     {
952         skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
953         return;
954     }
955     CloseServiceHandle(scm_handle);
956
957     /* First some parameter checking */
958     test_open_scm();
959     test_open_svc();
960     test_create_delete_svc();
961     test_get_displayname();
962     test_get_servicekeyname();
963     test_close();
964     /* Test the creation, querying and deletion of a service */
965     test_sequence();
966     /* The main reason for this test is to check if any refcounting is used
967      * and what the rules are
968      */
969     test_refcount();
970 }