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