wined3d: Merge device_unload_resource() and reset_unload_resources().
[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 "winnls.h"
30 #include "lmcons.h"
31 #include "aclapi.h"
32
33 #include "wine/test.h"
34
35 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
36
37 static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
38 static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
39                                              DWORD, LPBYTE, DWORD, LPDWORD,
40                                              LPDWORD, LPDWORD, LPCSTR);
41 static BOOL (WINAPI *pEnumServicesStatusExW)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
42                                              DWORD, LPBYTE, DWORD, LPDWORD,
43                                              LPDWORD, LPDWORD, LPCWSTR);
44 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
45                                         PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
46 static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
47 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
48 static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
49                                             DWORD, LPDWORD);
50
51 static void init_function_pointers(void)
52 {
53     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
54
55     pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A");
56     pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA");
57     pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW");
58     pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo");
59     pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
60     pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
61     pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
62 }
63
64 static void test_open_scm(void)
65 {
66     SC_HANDLE scm_handle;
67
68     /* No access rights */
69     SetLastError(0xdeadbeef);
70     scm_handle = OpenSCManagerA(NULL, NULL, 0);
71     ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
72     CloseServiceHandle(scm_handle);
73
74     /* Unknown database name */
75     SetLastError(0xdeadbeef);
76     scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
77     ok(!scm_handle, "Expected failure\n");
78     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
79     CloseServiceHandle(scm_handle); /* Just in case */
80
81     /* MSDN says only ServiceActive is allowed, or NULL */
82     SetLastError(0xdeadbeef);
83     scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
84     ok(!scm_handle, "Expected failure\n");
85     ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
86     CloseServiceHandle(scm_handle); /* Just in case */
87
88     /* Remote unknown host */
89     SetLastError(0xdeadbeef);
90     scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
91     todo_wine
92     {
93     ok(!scm_handle, "Expected failure\n");
94     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
95        "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
96     }
97     CloseServiceHandle(scm_handle); /* Just in case */
98
99     /* Proper call with an empty hostname */
100     SetLastError(0xdeadbeef);
101     scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
102     ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
103     CloseServiceHandle(scm_handle);
104
105     /* Again a correct one */
106     SetLastError(0xdeadbeef);
107     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
108     ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
109     CloseServiceHandle(scm_handle);
110 }
111
112 static void test_open_svc(void)
113 {
114     SC_HANDLE scm_handle, svc_handle;
115     CHAR displayname[4096];
116     DWORD displaysize;
117
118     /* All NULL (invalid access rights) */
119     SetLastError(0xdeadbeef);
120     svc_handle = OpenServiceA(NULL, NULL, 0);
121     ok(!svc_handle, "Expected failure\n");
122     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
123
124     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
125
126     /* NULL service */
127     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
128     SetLastError(0xdeadbeef);
129     svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
130     ok(!svc_handle, "Expected failure\n");
131     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
132        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
133        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
134
135     /* Nonexistent service */
136     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
137     SetLastError(0xdeadbeef);
138     svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
139     ok(!svc_handle, "Expected failure\n");
140     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
141     CloseServiceHandle(scm_handle);
142
143     /* Proper SCM handle but different access rights */
144     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
145     SetLastError(0xdeadbeef);
146     svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
147     if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
148         skip("Not enough rights to get a handle to the service\n");
149     else
150     {
151         ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError());
152         CloseServiceHandle(svc_handle);
153     }
154
155     /* Test to show we can't open a service with the displayname */
156
157     /* Retrieve the needed size for the buffer */
158     displaysize = 0;
159     GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
160     /* Get the displayname */
161     GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
162     /* Try to open the service with this displayname, unless the displayname equals
163      * the servicename as that would defeat the purpose of this test.
164      */
165     if (!lstrcmpi(spooler, displayname))
166     {
167         skip("displayname equals servicename\n");
168         CloseServiceHandle(scm_handle);
169         return;
170     }
171
172     SetLastError(0xdeadbeef);
173     svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
174     ok(!svc_handle, "Expected failure\n");
175     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
176     /* Just in case */
177     CloseServiceHandle(svc_handle);
178
179     CloseServiceHandle(scm_handle);
180 }
181
182 static void test_create_delete_svc(void)
183 {
184     SC_HANDLE scm_handle, svc_handle1;
185     CHAR username[UNLEN + 1], domain[MAX_PATH];
186     DWORD user_size = UNLEN + 1;
187     CHAR account[UNLEN + 3];
188     static const CHAR servicename         [] = "Winetest";
189     static const CHAR pathname            [] = "we_dont_care.exe";
190     static const CHAR empty               [] = "";
191     static const CHAR password            [] = "secret";
192     BOOL spooler_exists = FALSE;
193     BOOL ret;
194     CHAR display[4096];
195     DWORD display_size = sizeof(display);
196
197     /* Get the username and turn it into an account to be used in some tests */
198     GetUserNameA(username, &user_size);
199     /* Get the domainname to cater for that situation */
200     if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
201         sprintf(account, "%s\\%s", domain, username);
202     else
203         sprintf(account, ".\\%s", username);
204
205     /* All NULL */
206     SetLastError(0xdeadbeef);
207     svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
208     ok(!svc_handle1, "Expected failure\n");
209     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
210
211     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
212
213     /* Only a valid handle to the Service Control Manager */
214     SetLastError(0xdeadbeef);
215     svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
216     ok(!svc_handle1, "Expected failure\n");
217     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
218        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
219        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
220
221     /* Now with a servicename */
222     SetLastError(0xdeadbeef);
223     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
224     ok(!svc_handle1, "Expected failure\n");
225     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
226        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
227        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
228
229     /* Or just a binary name */
230     SetLastError(0xdeadbeef);
231     svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
232     ok(!svc_handle1, "Expected failure\n");
233     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
234        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
235        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
236
237     /* Both servicename and binary name (We only have connect rights) */
238     SetLastError(0xdeadbeef);
239     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
240     ok(!svc_handle1, "Expected failure\n");
241     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
242
243     /* They can even be empty at this stage of parameter checking */
244     SetLastError(0xdeadbeef);
245     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
246     ok(!svc_handle1, "Expected failure\n");
247     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
248
249     SetLastError(0xdeadbeef);
250     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
251     ok(!svc_handle1, "Expected failure\n");
252     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
253
254     /* Open the Service Control Manager with minimal rights for creation
255      * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
256      */
257     CloseServiceHandle(scm_handle);
258     SetLastError(0xdeadbeef);
259     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
260     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
261     {
262         skip("Not enough rights to get a handle to the manager\n");
263         return;
264     }
265
266     /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
267
268     /* Empty strings for servicename and binary name are checked */
269     SetLastError(0xdeadbeef);
270     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
271     ok(!svc_handle1, "Expected failure\n");
272     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
273
274     SetLastError(0xdeadbeef);
275     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
276     ok(!svc_handle1, "Expected failure\n");
277     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
278
279     SetLastError(0xdeadbeef);
280     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
281     ok(!svc_handle1, "Expected failure\n");
282     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
283
284     /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
285      * an ERROR_INVALID_PARAMETER)
286      */
287     SetLastError(0xdeadbeef);
288     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
289                                  SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
290     ok(!svc_handle1, "Expected failure\n");
291     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
292
293     /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
294
295     /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
296      * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
297      */
298     SetLastError(0xdeadbeef);
299     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
300                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
301     ok(!svc_handle1, "Expected failure\n");
302     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
303
304     /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
305     SetLastError(0xdeadbeef);
306     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
307                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
308     ok(!svc_handle1, "Expected failure\n");
309     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
310
311     /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
312      * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
313      */
314     SetLastError(0xdeadbeef);
315     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
316                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
317     ok(!svc_handle1, "Expected failure\n");
318     ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT,
319        "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError());
320
321     /* Illegal (start-type is not a mask and should only be one of the possibilities)
322      * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
323      * it's most likely not the wanted start-type)
324      */
325     SetLastError(0xdeadbeef);
326     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
327                                  SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
328     ok(!svc_handle1, "Expected failure\n");
329     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
330
331     /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
332     SetLastError(0xdeadbeef);
333     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
334                                  SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
335     ok(!svc_handle1, "Expected failure\n");
336     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
337
338     /* Test if ServiceType can be a combined one for drivers */
339     SetLastError(0xdeadbeef);
340     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER,
341                                  SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
342     ok(!svc_handle1, "Expected failure\n");
343     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
344
345     /* The service already exists (check first, just in case) */
346     svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
347     if (svc_handle1)
348     {
349         spooler_exists = TRUE;
350         CloseServiceHandle(svc_handle1);
351         SetLastError(0xdeadbeef);
352         svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
353                                      SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
354         ok(!svc_handle1, "Expected failure\n");
355         ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
356     }
357     else
358         skip("Spooler service doesn't exist\n");
359
360     /* To find an existing displayname we check the 'Spooler' service. Although the registry
361      * doesn't show DisplayName on NT4, this call will return a displayname which is equal
362      * to the servicename and can't be used as well for a new displayname.
363      */
364     if (spooler_exists)
365     {
366         ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
367
368         if (!ret)
369             skip("Could not retrieve a displayname for the Spooler service\n");
370         else
371         {
372             svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
373                                          SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
374             ok(!svc_handle1, "Expected failure\n");
375             ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
376                "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
377         }
378     }
379     else
380         skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
381
382     /* Windows doesn't care about the access rights for creation (which makes
383      * sense as there is no service yet) as long as there are sufficient
384      * rights to the manager.
385      */
386     SetLastError(0xdeadbeef);
387     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
388                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
389     ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
390
391     /* DeleteService however must have proper rights */
392     SetLastError(0xdeadbeef);
393     ret = DeleteService(svc_handle1);
394     ok(!ret, "Expected failure\n");
395     ok(GetLastError() == ERROR_ACCESS_DENIED,
396        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
397
398     /* Open the service with minimal rights for deletion.
399      * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
400      */
401     CloseServiceHandle(svc_handle1);
402     svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
403
404     /* Now that we have the proper rights, we should be able to delete */
405     SetLastError(0xdeadbeef);
406     ret = DeleteService(svc_handle1);
407     ok(ret, "Expected success, got error %u\n", GetLastError());
408
409     CloseServiceHandle(svc_handle1);
410     CloseServiceHandle(scm_handle);
411
412     /* Wait a while. One of the following tests also does a CreateService for the
413      * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
414      * error if we do this to quick. Vista seems more picky then the others.
415      */
416     Sleep(1000);
417
418     /* And a final NULL check */
419     SetLastError(0xdeadbeef);
420     ret = DeleteService(NULL);
421     ok(!ret, "Expected failure\n");
422     ok(GetLastError() == ERROR_INVALID_HANDLE,
423         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
424 }
425
426 static void test_get_displayname(void)
427 {
428     SC_HANDLE scm_handle, svc_handle;
429     BOOL ret;
430     CHAR displayname[4096];
431     WCHAR displaynameW[2048];
432     DWORD displaysize, tempsize, tempsizeW;
433     static const CHAR deadbeef[] = "Deadbeef";
434     static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
435     static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
436     static const WCHAR abcW[] = {'A','B','C',0};
437     static const CHAR servicename[] = "Winetest";
438     static const CHAR pathname[] = "we_dont_care.exe";
439
440     /* Having NULL for the size of the buffer will crash on W2K3 */
441
442     SetLastError(0xdeadbeef);
443     ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
444     ok(!ret, "Expected failure\n");
445     ok(GetLastError() == ERROR_INVALID_HANDLE,
446        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
447
448     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
449
450     SetLastError(0xdeadbeef);
451     ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
452     ok(!ret, "Expected failure\n");
453     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
454        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
455        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
456
457     SetLastError(0xdeadbeef);
458     displaysize = sizeof(displayname);
459     ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
460     ok(!ret, "Expected failure\n");
461     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
462        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
463        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
464
465     /* Test for nonexistent service */
466     SetLastError(0xdeadbeef);
467     displaysize = -1;
468     ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
469     ok(!ret, "Expected failure\n");
470     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
471        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
472
473     SetLastError(0xdeadbeef);
474     ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
475     ok(!ret, "Expected failure\n");
476     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
477        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
478     todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
479
480     displaysize = 15;
481     strcpy(displayname, "ABC");
482     ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
483     ok(!ret, "Expected failure\n");
484     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
485        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
486     todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
487     ok(displayname[0] == 0, "Service name not empty\n");
488
489     displaysize = 15;
490     lstrcpyW( displaynameW, abcW );
491     ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
492     ok(!ret, "Expected failure\n");
493     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
494        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
495     ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize);
496     ok(displaynameW[0] == 0, "Service name not empty\n");
497
498     displaysize = 0;
499     strcpy(displayname, "ABC");
500     ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
501     ok(!ret, "Expected failure\n");
502     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
503        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
504     todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
505     ok(displayname[0] == 'A', "Service name changed\n");
506
507     displaysize = 0;
508     lstrcpyW( displaynameW, abcW );
509     ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
510     ok(!ret, "Expected failure\n");
511     ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
512     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
513        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
514     ok(displaynameW[0] == 'A', "Service name changed\n");
515
516     displaysize = 1;
517     strcpy(displayname, "ABC");
518     ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
519     ok(!ret, "Expected failure\n");
520     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
521        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
522     todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize);
523     ok(displayname[0] == 0, "Service name not empty\n");
524
525     displaysize = 1;
526     lstrcpyW( displaynameW, abcW );
527     ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
528     ok(!ret, "Expected failure\n");
529     ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
530     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
531        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
532     ok(displaynameW[0] == 'A', "Service name changed\n");
533
534     displaysize = 2;
535     strcpy(displayname, "ABC");
536     ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize);
537     ok(!ret, "Expected failure\n");
538     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
539        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
540     todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
541     ok(displayname[0] == 0, "Service name not empty\n");
542
543     displaysize = 2;
544     lstrcpyW( displaynameW, abcW );
545     ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize);
546     ok(!ret, "Expected failure\n");
547     ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize);
548     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
549        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
550     ok(displaynameW[0] == 0, "Service name not empty\n");
551
552     /* Check if 'Spooler' exists */
553     svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
554     if (!svc_handle)
555     {
556         skip("Spooler service doesn't exist\n");
557         CloseServiceHandle(scm_handle);
558         return;
559     }
560     CloseServiceHandle(svc_handle);
561
562     /* Retrieve the needed size for the buffer */
563     SetLastError(0xdeadbeef);
564     displaysize = -1;
565     ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
566     ok(!ret, "Expected failure\n");
567     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
568        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
569     tempsize = displaysize;
570
571     displaysize = 0;
572     ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
573     ok(!ret, "Expected failure\n");
574     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
575        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
576     ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
577
578     /* Buffer is too small */
579     SetLastError(0xdeadbeef);
580     displaysize = (tempsize / 2);
581     ret = GetServiceDisplayNameA(scm_handle, spooler, 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     /* First try with a buffer that should be big enough to hold
588      * the ANSI string (and terminating character). This succeeds on Windows
589      *  although when asked (see above 2 tests) it will return twice the needed size.
590      */
591     SetLastError(0xdeadbeef);
592     displaysize = (tempsize / 2) + 1;
593     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
594     ok(ret, "Expected success, got error %u\n", GetLastError());
595     ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
596
597     /* Now with the original returned size */
598     SetLastError(0xdeadbeef);
599     displaysize = tempsize;
600     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
601     ok(ret, "Expected success, got error %u\n", GetLastError());
602     ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
603
604     /* And with a bigger than needed buffer */
605     SetLastError(0xdeadbeef);
606     displaysize = tempsize * 2;
607     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
608     ok(ret, "Expected success, got error %u\n", GetLastError());
609     /* Test that shows that if the buffersize is enough, it's not changed */
610     ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
611     ok(strlen(displayname) == tempsize/2,
612        "Expected the buffer to be twice the length of the string\n") ;
613
614     /* Do the buffer(size) tests also for GetServiceDisplayNameW */
615     SetLastError(0xdeadbeef);
616     displaysize = -1;
617     ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
618     ok(!ret, "Expected failure\n");
619     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
620        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
621
622     /* Buffer is too small */
623     SetLastError(0xdeadbeef);
624     tempsizeW = displaysize;
625     displaysize = tempsizeW / 2;
626     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
627     ok(!ret, "Expected failure\n");
628     ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
629     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
630        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
631
632     /* Now with the original returned size */
633     SetLastError(0xdeadbeef);
634     displaysize = tempsizeW;
635     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
636     ok(!ret, "Expected failure\n");
637     ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
638     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
639        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
640
641     /* And with a bigger than needed buffer */
642     SetLastError(0xdeadbeef);
643     displaysize = tempsizeW + 1; /* This caters for the null terminating character */
644     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
645     ok(ret, "Expected success, got error %u\n", GetLastError());
646     ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
647     ok(lstrlenW(displaynameW) == displaysize,
648        "Expected the buffer to be the length of the string\n") ;
649     ok(tempsize / 2 == tempsizeW,
650        "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
651
652     CloseServiceHandle(scm_handle);
653
654     /* Test for a service without a displayname (which is valid). This should return
655      * the servicename itself.
656      */
657     SetLastError(0xdeadbeef);
658     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
659     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
660     {
661         skip("Not enough rights to get a handle to the manager\n");
662         return;
663     }
664
665     SetLastError(0xdeadbeef);
666     svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
667                                 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
668                                 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
669     ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
670     if (!svc_handle)
671     {
672         CloseServiceHandle(scm_handle);
673         return;
674     }
675
676     /* Retrieve the needed size for the buffer */
677     SetLastError(0xdeadbeef);
678     displaysize = -1;
679     ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
680     ok(!ret, "Expected failure\n");
681     ok(displaysize == strlen(servicename) * 2,
682        "Expected the displaysize to be twice the size of the servicename\n");
683     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
684        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
685
686     /* Buffer is too small */
687     SetLastError(0xdeadbeef);
688     tempsize = displaysize;
689     displaysize = (tempsize / 2);
690     ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
691     ok(!ret, "Expected failure\n");
692     ok(displaysize == tempsize, "Expected the needed buffersize\n");
693     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
694        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
695
696     /* Get the displayname */
697     SetLastError(0xdeadbeef);
698     ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
699     ok(ret, "Expected success, got error %u\n", GetLastError());
700     ok(!lstrcmpi(displayname, servicename),
701        "Expected displayname to be %s, got %s\n", servicename, displayname);
702
703     /* Delete the service */
704     ret = DeleteService(svc_handle);
705     ok(ret, "Expected success (err=%d)\n", GetLastError());
706
707     CloseServiceHandle(svc_handle);
708     CloseServiceHandle(scm_handle);
709
710     /* Wait a while. Just in case one of the following tests does a CreateService again */
711     Sleep(1000);
712 }
713
714 static void test_get_servicekeyname(void)
715 {
716     SC_HANDLE scm_handle, svc_handle;
717     CHAR servicename[4096];
718     CHAR displayname[4096];
719     WCHAR servicenameW[4096];
720     WCHAR displaynameW[4096];
721     DWORD servicesize, displaysize, tempsize;
722     BOOL ret;
723     static const CHAR deadbeef[] = "Deadbeef";
724     static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
725     static const WCHAR abcW[] = {'A','B','C',0};
726
727     /* Having NULL for the size of the buffer will crash on W2K3 */
728
729     SetLastError(0xdeadbeef);
730     ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
731     ok(!ret, "Expected failure\n");
732     ok(GetLastError() == ERROR_INVALID_HANDLE,
733        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
734
735     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
736
737     servicesize = 200;
738     SetLastError(0xdeadbeef);
739     ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
740     ok(!ret, "Expected failure\n");
741     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
742        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
743        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
744     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
745
746     /* Valid handle and buffer but no displayname */
747     servicesize = 200;
748     SetLastError(0xdeadbeef);
749     ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
750     ok(!ret, "Expected failure\n");
751     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
752        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
753        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
754     todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
755
756     /* Test for nonexistent displayname */
757     SetLastError(0xdeadbeef);
758     ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
759     ok(!ret, "Expected failure\n");
760     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
761        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
762     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
763
764     servicesize = 15;
765     strcpy(servicename, "ABC");
766     ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
767     ok(!ret, "Expected failure\n");
768     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
769        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
770     todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
771     ok(servicename[0] == 0, "Service name not empty\n");
772
773     servicesize = 15;
774     lstrcpyW( servicenameW, abcW );
775     ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
776     ok(!ret, "Expected failure\n");
777     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
778        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
779     ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
780     ok(servicenameW[0] == 0, "Service name not empty\n");
781
782     servicesize = 0;
783     strcpy(servicename, "ABC");
784     ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
785     ok(!ret, "Expected failure\n");
786     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
787        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
788     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
789     ok(servicename[0] == 'A', "Service name changed\n");
790
791     servicesize = 0;
792     lstrcpyW( servicenameW, abcW );
793     ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
794     ok(!ret, "Expected failure\n");
795     ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
796     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
797        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
798     ok(servicenameW[0] == 'A', "Service name changed\n");
799
800     servicesize = 1;
801     strcpy(servicename, "ABC");
802     ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
803     ok(!ret, "Expected failure\n");
804     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
805        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
806     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
807     ok(servicename[0] == 0, "Service name not empty\n");
808
809     servicesize = 1;
810     lstrcpyW( servicenameW, abcW );
811     ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
812     ok(!ret, "Expected failure\n");
813     ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
814     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
815        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
816     ok(servicenameW[0] == 'A', "Service name changed\n");
817
818     servicesize = 2;
819     strcpy(servicename, "ABC");
820     ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
821     ok(!ret, "Expected failure\n");
822     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
823        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
824     todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
825     ok(servicename[0] == 0, "Service name not empty\n");
826
827     servicesize = 2;
828     lstrcpyW( servicenameW, abcW );
829     ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
830     ok(!ret, "Expected failure\n");
831     ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
832     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
833        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
834     ok(servicenameW[0] == 0, "Service name not empty\n");
835
836     /* Check if 'Spooler' exists */
837     svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
838     if (!svc_handle)
839     {
840         skip("Spooler service doesn't exist\n");
841         CloseServiceHandle(scm_handle);
842         return;
843     }
844     CloseServiceHandle(svc_handle);
845
846     /* Get the displayname for the 'Spooler' service */
847     GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
848     GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
849
850     /* Retrieve the needed size for the buffer */
851     SetLastError(0xdeadbeef);
852     servicesize = 0;
853     ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
854     ok(!ret, "Expected failure\n");
855     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
856        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
857
858     /* Valid call with the correct buffersize */
859     SetLastError(0xdeadbeef);
860     tempsize = servicesize;
861     servicesize *= 2;
862     ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
863     ok(ret, "Expected success, got error %u\n", GetLastError());
864     if (ret)
865     {
866         ok(strlen(servicename) == tempsize/2,
867            "Expected the buffer to be twice the length of the string\n") ;
868         ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
869         ok(servicesize == (tempsize * 2),
870            "Expected servicesize not to change if buffer not insufficient\n") ;
871     }
872
873     MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
874     SetLastError(0xdeadbeef);
875     servicesize *= 2;
876     ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
877     ok(ret, "Expected success, got error %u\n", GetLastError());
878     if (ret)
879     {
880         ok(strlen(servicename) == tempsize/2,
881            "Expected the buffer to be twice the length of the string\n") ;
882         ok(servicesize == lstrlenW(servicenameW),
883            "Expected servicesize not to change if buffer not insufficient\n") ;
884     }
885
886     SetLastError(0xdeadbeef);
887     servicesize = 3;
888     ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
889     ok(!ret, "Expected failure\n");
890     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
891        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
892     ok(servicenameW[0] == 0, "Buffer not empty\n");
893
894     CloseServiceHandle(scm_handle);
895 }
896
897 static void test_query_svc(void)
898 {
899     SC_HANDLE scm_handle, svc_handle;
900     BOOL ret;
901     SERVICE_STATUS status;
902     SERVICE_STATUS_PROCESS *statusproc;
903     DWORD bufsize, needed;
904
905     /* All NULL or wrong  */
906     SetLastError(0xdeadbeef);
907     ret = QueryServiceStatus(NULL, NULL);
908     ok(!ret, "Expected failure\n");
909     ok(GetLastError() == ERROR_INVALID_HANDLE,
910        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
911
912     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
913
914     /* Check if 'Spooler' exists.
915      * Open with not enough rights to query the status.
916      */
917     svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
918     if (!svc_handle)
919     {
920         skip("Spooler service doesn't exist\n");
921         CloseServiceHandle(scm_handle);
922         return;
923     }
924
925     SetLastError(0xdeadbeef);
926     ret = QueryServiceStatus(svc_handle, NULL);
927     ok(!ret, "Expected failure\n");
928     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
929        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
930        "Unexpected last error %d\n", GetLastError());
931
932     SetLastError(0xdeadbeef);
933     ret = QueryServiceStatus(svc_handle, &status);
934     ok(!ret, "Expected failure\n");
935     ok(GetLastError() == ERROR_ACCESS_DENIED,
936        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
937
938     /* Open the service with just enough rights.
939      * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
940      */
941     CloseServiceHandle(svc_handle);
942     svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
943
944     SetLastError(0xdeadbeef);
945     ret = QueryServiceStatus(svc_handle, &status);
946     ok(ret, "Expected success, got error %u\n", GetLastError());
947
948     CloseServiceHandle(svc_handle);
949
950     /* More or less the same tests for QueryServiceStatusEx */
951
952     /* Open service with not enough rights to query the status */
953     svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
954
955     /* All NULL or wrong, this proves that info level is checked first */
956     SetLastError(0xdeadbeef);
957     ret = pQueryServiceStatusEx(NULL, 1, NULL, 0, NULL);
958     ok(!ret, "Expected failure\n");
959     todo_wine
960     ok(GetLastError() == ERROR_INVALID_LEVEL,
961        "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
962
963     /* Passing a NULL parameter for the needed buffer size
964      * will crash on anything but NT4.
965      */
966
967     /* Only info level is correct. It looks like the buffer/size is checked second */
968     SetLastError(0xdeadbeef);
969     ret = pQueryServiceStatusEx(NULL, 0, NULL, 0, &needed);
970     /* NT4 and Wine check the handle first */
971     if (GetLastError() != ERROR_INVALID_HANDLE)
972     {
973         ok(!ret, "Expected failure\n");
974         ok(needed == sizeof(SERVICE_STATUS_PROCESS),
975            "Needed buffersize is wrong : %d\n", needed);
976         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
977            "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
978     }
979
980     /* Pass a correct buffer and buffersize but a NULL handle */
981     statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
982     bufsize = needed;
983     SetLastError(0xdeadbeef);
984     ret = pQueryServiceStatusEx(NULL, 0, (BYTE*)statusproc, bufsize, &needed);
985     ok(!ret, "Expected failure\n");
986     ok(GetLastError() == ERROR_INVALID_HANDLE,
987        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
988     HeapFree(GetProcessHeap(), 0, statusproc);
989
990     /* Correct handle and info level */
991     SetLastError(0xdeadbeef);
992     ret = pQueryServiceStatusEx(svc_handle, 0, NULL, 0, &needed);
993     /* NT4 doesn't return the needed size */
994     if (GetLastError() != ERROR_INVALID_PARAMETER)
995     {
996         ok(!ret, "Expected failure\n");
997         todo_wine
998         {
999         ok(needed == sizeof(SERVICE_STATUS_PROCESS),
1000            "Needed buffersize is wrong : %d\n", needed);
1001         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1002            "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1003         }
1004     }
1005
1006     /* All parameters are OK but we don't have enough rights */
1007     statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1008     bufsize = sizeof(SERVICE_STATUS_PROCESS);
1009     SetLastError(0xdeadbeef);
1010     ret = pQueryServiceStatusEx(svc_handle, 0, (BYTE*)statusproc, bufsize, &needed);
1011     ok(!ret, "Expected failure\n");
1012     ok(GetLastError() == ERROR_ACCESS_DENIED,
1013        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1014     HeapFree(GetProcessHeap(), 0, statusproc);
1015
1016     /* Open the service with just enough rights. */
1017     CloseServiceHandle(svc_handle);
1018     svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
1019
1020     /* Everything should be fine now. */
1021     statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1022     bufsize = sizeof(SERVICE_STATUS_PROCESS);
1023     SetLastError(0xdeadbeef);
1024     ret = pQueryServiceStatusEx(svc_handle, 0, (BYTE*)statusproc, bufsize, &needed);
1025     ok(ret, "Expected success, got error %u\n", GetLastError());
1026     if (statusproc->dwCurrentState == SERVICE_RUNNING)
1027         ok(statusproc->dwProcessId != 0,
1028            "Expect a process id for this running service\n");
1029     else
1030         ok(statusproc->dwProcessId == 0,
1031            "Expect no process id for this stopped service\n");
1032     HeapFree(GetProcessHeap(), 0, statusproc);
1033
1034     CloseServiceHandle(svc_handle);
1035     CloseServiceHandle(scm_handle);
1036 }
1037
1038 static void test_enum_svc(void)
1039 {
1040     SC_HANDLE scm_handle;
1041     BOOL ret;
1042     DWORD bufsize, needed, returned, resume;
1043     DWORD neededW, returnedW;
1044     DWORD tempneeded, tempreturned, missing;
1045     DWORD servicecountactive, servicecountinactive;
1046     ENUM_SERVICE_STATUS *services;
1047     ENUM_SERVICE_STATUSW *servicesW;
1048     ENUM_SERVICE_STATUS_PROCESS *exservices;
1049     UINT i;
1050
1051     /* All NULL or wrong  */
1052     SetLastError(0xdeadbeef);
1053     ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1054     ok(!ret, "Expected failure\n");
1055     ok(GetLastError() == ERROR_INVALID_HANDLE,
1056        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1057
1058     SetLastError(0xdeadbeef);
1059     ret = EnumServicesStatusW(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1060     ok(!ret, "Expected failure\n");
1061     ok(GetLastError() == ERROR_INVALID_HANDLE,
1062        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1063
1064     /* Open the service control manager with not enough rights at first */
1065     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1066
1067     /* Valid handle but rest is still NULL or wrong  */
1068     SetLastError(0xdeadbeef);
1069     ret = EnumServicesStatusA(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1070     ok(!ret, "Expected failure\n");
1071     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1072        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1073        "Unexpected last error %d\n", GetLastError());
1074
1075     SetLastError(0xdeadbeef);
1076     ret = EnumServicesStatusW(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1077     ok(!ret, "Expected failure\n");
1078     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1079        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1080        "Unexpected last error %d\n", GetLastError());
1081
1082     /* Don't specify the two required pointers */
1083     returned = 0xdeadbeef;
1084     SetLastError(0xdeadbeef);
1085     ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1086     ok(!ret, "Expected failure\n");
1087     ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1088     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1089        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1090        "Unexpected last error %d\n", GetLastError());
1091
1092     returned = 0xdeadbeef;
1093     SetLastError(0xdeadbeef);
1094     ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1095     ok(!ret, "Expected failure\n");
1096     ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1097     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1098        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1099        "Unexpected last error %d\n", GetLastError());
1100
1101     /* Don't specify the two required pointers */
1102     needed = 0xdeadbeef;
1103     SetLastError(0xdeadbeef);
1104     ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1105     ok(!ret, "Expected failure\n");
1106     ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1107        "Expected no change to the needed buffer variable\n");
1108     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1109        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1110        "Unexpected last error %d\n", GetLastError());
1111
1112     needed = 0xdeadbeef;
1113     SetLastError(0xdeadbeef);
1114     ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1115     ok(!ret, "Expected failure\n");
1116     ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1117        "Expected no change to the needed buffer variable\n");
1118     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1119        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1120        "Unexpected last error %d\n", GetLastError());
1121
1122     /* No valid servicetype and servicestate */
1123     needed = 0xdeadbeef;
1124     returned = 0xdeadbeef;
1125     SetLastError(0xdeadbeef);
1126     ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1127     ok(!ret, "Expected failure\n");
1128     ok(needed == 0 || broken(needed != 0), /* nt4 */
1129        "Expected needed buffer size to be set to 0, got %d\n", needed);
1130     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1131     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1132        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1133
1134     needed = 0xdeadbeef;
1135     returned = 0xdeadbeef;
1136     SetLastError(0xdeadbeef);
1137     ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1138     ok(!ret, "Expected failure\n");
1139     ok(needed == 0 || broken(needed != 0), /* nt4 */
1140        "Expected needed buffer size to be set to 0, got %d\n", needed);
1141     ok(returned == 0 || broken(returned != 0), /* nt4 */
1142        "Expected number of services to be set to 0, got %d\n", returned);
1143     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1144        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1145
1146     /* No valid servicestate */
1147     needed = 0xdeadbeef;
1148     returned = 0xdeadbeef;
1149     SetLastError(0xdeadbeef);
1150     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1151     ok(!ret, "Expected failure\n");
1152     ok(needed == 0 || broken(needed != 0), /* nt4 */
1153        "Expected needed buffer size to be set to 0, got %d\n", needed);
1154     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1155     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1156        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1157
1158     needed = 0xdeadbeef;
1159     returned = 0xdeadbeef;
1160     SetLastError(0xdeadbeef);
1161     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1162     ok(!ret, "Expected failure\n");
1163     ok(needed == 0 || broken(needed != 0), /* nt4 */
1164        "Expected needed buffer size to be set to 0, got %d\n", needed);
1165     ok(returned == 0 || broken(returned != 0), /* nt4 */
1166        "Expected number of services to be set to 0, got %d\n", returned);
1167     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1168        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1169
1170     /* No valid servicetype */
1171     needed = 0xdeadbeef;
1172     returned = 0xdeadbeef;
1173     SetLastError(0xdeadbeef);
1174     ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1175     ok(!ret, "Expected failure\n");
1176     ok(needed == 0 || broken(needed != 0), /* nt4 */
1177        "Expected needed buffer size to be set to 0, got %d\n", needed);
1178     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1179     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1180        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1181
1182     needed = 0xdeadbeef;
1183     returned = 0xdeadbeef;
1184     SetLastError(0xdeadbeef);
1185     ret = EnumServicesStatusW(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1186     ok(!ret, "Expected failure\n");
1187     ok(needed == 0 || broken(needed != 0), /* nt4 */
1188        "Expected needed buffer size to be set to 0, got %d\n", needed);
1189     ok(returned == 0 || broken(returned != 0), /* nt4 */
1190        "Expected number of services to be set to 0, got %d\n", returned);
1191     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1192        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1193
1194     /* All parameters are correct but our access rights are wrong */
1195     needed = 0xdeadbeef;
1196     returned = 0xdeadbeef;
1197     SetLastError(0xdeadbeef);
1198     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1199     ok(!ret, "Expected failure\n");
1200     ok(needed == 0 || broken(needed != 0), /* nt4 */
1201        "Expected needed buffer size to be set to 0, got %d\n", needed);
1202     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1203     ok(GetLastError() == ERROR_ACCESS_DENIED,
1204        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1205
1206     needed = 0xdeadbeef;
1207     returned = 0xdeadbeef;
1208     SetLastError(0xdeadbeef);
1209     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1210     ok(!ret, "Expected failure\n");
1211     ok(needed == 0 || broken(needed != 0), /* nt4 */
1212        "Expected needed buffer size to be set to 0, got %d\n", needed);
1213     ok(returned == 0 || broken(returned != 0), /* nt4 */
1214        "Expected number of services to be set to 0, got %d\n", returned);
1215     ok(GetLastError() == ERROR_ACCESS_DENIED,
1216        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1217
1218     /* Open the service control manager with the needed rights */
1219     CloseServiceHandle(scm_handle);
1220     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1221
1222     /* All parameters are correct. Request the needed buffer size */
1223     needed = 0xdeadbeef;
1224     returned = 0xdeadbeef;
1225     SetLastError(0xdeadbeef);
1226     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1227     ok(!ret, "Expected failure\n");
1228     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1229     ok(returned == 0, "Expected no service returned, got %d\n", returned);
1230     ok(GetLastError() == ERROR_MORE_DATA,
1231        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1232
1233     /* Test to show we get the same needed buffer size for the W-call */
1234     neededW = 0xdeadbeef;
1235     returnedW = 0xdeadbeef;
1236     SetLastError(0xdeadbeef);
1237     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &neededW, &returnedW, NULL);
1238     ok(!ret, "Expected failure\n");
1239     ok(neededW != 0xdeadbeef && neededW > 0, "Expected the needed buffer size for this one service\n");
1240     ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n");
1241     ok(returnedW == 0, "Expected no service returned, got %d\n", returnedW);
1242     ok(GetLastError() == ERROR_MORE_DATA,
1243        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1244
1245     /* Store the needed bytes */
1246     tempneeded = needed;
1247
1248     /* Allocate the correct needed bytes */
1249     services = HeapAlloc(GetProcessHeap(), 0, needed);
1250     bufsize = needed;
1251     needed = 0xdeadbeef;
1252     returned = 0xdeadbeef;
1253     SetLastError(0xdeadbeef);
1254     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1255                               services, bufsize, &needed, &returned, NULL);
1256     ok(ret, "Expected success, got error %u\n", GetLastError());
1257     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1258     ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n");
1259     HeapFree(GetProcessHeap(), 0, services);
1260
1261     /* Store the number of returned services */
1262     tempreturned = returned;
1263
1264     servicesW = HeapAlloc(GetProcessHeap(), 0, neededW);
1265     bufsize = neededW;
1266     neededW = 0xdeadbeef;
1267     returnedW = 0xdeadbeef;
1268     SetLastError(0xdeadbeef);
1269     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1270                               servicesW, bufsize, &neededW, &returnedW, NULL);
1271     ok(ret, "Expected success, got error %u\n", GetLastError());
1272     ok(neededW == 0, "Expected needed buffer to be 0 as we are done\n");
1273     ok(returnedW != 0xdeadbeef && returnedW > 0, "Expected some returned services\n");
1274     HeapFree(GetProcessHeap(), 0, servicesW);
1275
1276     /* Allocate less than the needed bytes and don't specify a resume handle */
1277     services = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1278     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1279     needed = 0xdeadbeef;
1280     returned = 0xdeadbeef;
1281     SetLastError(0xdeadbeef);
1282     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1283                               services, bufsize, &needed, &returned, NULL);
1284     ok(!ret, "Expected failure\n");
1285     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1286     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1287     ok(GetLastError() == ERROR_MORE_DATA,
1288        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1289
1290     /* Allocate less than the needed bytes, this time with a correct resume handle */
1291     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1292     needed = 0xdeadbeef;
1293     returned = 0xdeadbeef;
1294     resume = 0;
1295     SetLastError(0xdeadbeef);
1296     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1297                               services, bufsize, &needed, &returned, &resume);
1298     ok(!ret, "Expected failure\n");
1299     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1300     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1301     todo_wine ok(resume, "Expected a resume handle\n");
1302     ok(GetLastError() == ERROR_MORE_DATA,
1303        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1304
1305     /* Fetch the missing services but pass a bigger buffer size */
1306     missing = tempreturned - returned;
1307     bufsize = tempneeded;
1308     needed = 0xdeadbeef;
1309     returned = 0xdeadbeef;
1310     SetLastError(0xdeadbeef);
1311     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1312                               services, bufsize, &needed, &returned, &resume);
1313     ok(ret, "Expected success, got error %u\n", GetLastError());
1314     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1315     ok(returned == missing, "Expected %u services to be returned\n", missing);
1316     ok(resume == 0, "Expected the resume handle to be 0\n");
1317     HeapFree(GetProcessHeap(), 0, services);
1318
1319     /* See if things add up */
1320
1321     /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1322      * and doesn't count the others as inactive. This means that Vista could
1323      * show a total that is greater than the sum of active and inactive
1324      * drivers.
1325      * The number of active and inactive drivers is greatly influenced by the
1326      * time when tests are run, immediately after boot or later for example.
1327      *
1328      * Both reasons make calculations for drivers not so useful
1329      */
1330
1331     /* Get the number of active win32 services */
1332     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0,
1333                         &needed, &returned, NULL);
1334     services = HeapAlloc(GetProcessHeap(), 0, needed);
1335     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services,
1336                         needed, &needed, &returned, NULL);
1337     HeapFree(GetProcessHeap(), 0, services);
1338
1339     servicecountactive = returned;
1340
1341     /* Get the number of inactive win32 services */
1342     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0,
1343                         &needed, &returned, NULL);
1344     services = HeapAlloc(GetProcessHeap(), 0, needed);
1345     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services,
1346                         needed, &needed, &returned, NULL);
1347     HeapFree(GetProcessHeap(), 0, services);
1348
1349     servicecountinactive = returned;
1350
1351     /* Get the number of win32 services */
1352     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1353                         &needed, &returned, NULL);
1354     services = HeapAlloc(GetProcessHeap(), 0, needed);
1355     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services,
1356                         needed, &needed, &returned, NULL);
1357     HeapFree(GetProcessHeap(), 0, services);
1358
1359     /* Check if total is the same as active and inactive win32 services */
1360     ok(returned == (servicecountactive + servicecountinactive),
1361        "Something wrong in the calculation\n");
1362
1363     /* Get all drivers and services
1364      *
1365      * Fetch the status of the last call as failing could make the following tests crash
1366      * on Wine (we don't return anything yet).
1367      */
1368     EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1369                         NULL, 0, &needed, &returned, NULL);
1370     services = HeapAlloc(GetProcessHeap(), 0, needed);
1371     ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1372                               services, needed, &needed, &returned, NULL);
1373
1374     /* Loop through all those returned drivers and services */
1375     for (i = 0; ret && i < returned; i++)
1376     {
1377         SERVICE_STATUS status = services[i].ServiceStatus;
1378
1379         /* lpServiceName and lpDisplayName should always be filled */
1380         ok(lstrlenA(services[i].lpServiceName) > 0, "Expected a service name\n");
1381         ok(lstrlenA(services[i].lpDisplayName) > 0, "Expected a display name\n");
1382
1383         /* Decrement the counters to see if the functions calls return the same
1384          * numbers as the contents of these structures.
1385          */
1386         if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1387         {
1388             if (status.dwCurrentState == SERVICE_STOPPED)
1389                 servicecountinactive--;
1390             else
1391                 servicecountactive--;
1392         }
1393     }
1394     HeapFree(GetProcessHeap(), 0, services);
1395
1396     ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1397     ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1398
1399     CloseServiceHandle(scm_handle);
1400
1401     /* More or less the same for EnumServicesStatusExA */
1402
1403     /* All NULL or wrong */
1404     SetLastError(0xdeadbeef);
1405     ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1406     ok(!ret, "Expected failure\n");
1407     ok(GetLastError() == ERROR_INVALID_LEVEL,
1408        "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1409
1410     /* All NULL or wrong, just the info level is correct */
1411     SetLastError(0xdeadbeef);
1412     ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1413     ok(!ret, "Expected failure\n");
1414     ok(GetLastError() == ERROR_INVALID_HANDLE,
1415        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1416
1417     /* Open the service control manager with not enough rights at first */
1418     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1419
1420     /* Valid handle and info level but rest is still NULL or wrong */
1421     SetLastError(0xdeadbeef);
1422     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1423     ok(!ret, "Expected failure\n");
1424     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1425        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1426        "Unexpected last error %d\n", GetLastError());
1427
1428     /* Don't specify the two required pointers */
1429     needed = 0xdeadbeef;
1430     SetLastError(0xdeadbeef);
1431     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL);
1432     ok(!ret, "Expected failure\n");
1433     ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1434        "Expected no change to the needed buffer variable\n");
1435     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1436        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1437        "Unexpected last error %d\n", GetLastError());
1438
1439     /* Don't specify the two required pointers */
1440     returned = 0xdeadbeef;
1441     SetLastError(0xdeadbeef);
1442     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL);
1443     ok(!ret, "Expected failure\n");
1444     ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1445     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1446        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1447        "Unexpected last error %d\n", GetLastError());
1448
1449     /* No valid servicetype and servicestate */
1450     needed = 0xdeadbeef;
1451     returned = 0xdeadbeef;
1452     SetLastError(0xdeadbeef);
1453     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL);
1454     ok(!ret, "Expected failure\n");
1455     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1456     ok(needed == 0 || broken(needed != 0), /* nt4 */
1457        "Expected needed buffer size to be set to 0, got %d\n", needed);
1458     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1459        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1460
1461     /* No valid servicestate */
1462     needed = 0xdeadbeef;
1463     returned = 0xdeadbeef;
1464     SetLastError(0xdeadbeef);
1465     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0,
1466                                  &needed, &returned, NULL, NULL);
1467     ok(!ret, "Expected failure\n");
1468     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1469     ok(needed == 0 || broken(needed != 0), /* nt4 */
1470        "Expected needed buffer size to be set to 0, got %d\n", needed);
1471     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1472        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1473
1474     /* No valid servicetype */
1475     needed = 0xdeadbeef;
1476     returned = 0xdeadbeef;
1477     SetLastError(0xdeadbeef);
1478     ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0,
1479                                  &needed, &returned, NULL, NULL);
1480     ok(!ret, "Expected failure\n");
1481     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1482     ok(needed == 0 || broken(needed != 0), /* nt4 */
1483        "Expected needed buffer size to be set to 0, got %d\n", needed);
1484     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1485        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1486
1487     /* No valid servicetype and servicestate and unknown service group */
1488     needed = 0xdeadbeef;
1489     returned = 0xdeadbeef;
1490     SetLastError(0xdeadbeef);
1491     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed,
1492                                  &returned, NULL, "deadbeef_group");
1493     ok(!ret, "Expected failure\n");
1494     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1495     ok(needed == 0 || broken(needed != 0), /* nt4 */
1496        "Expected needed buffer size to be set to 0, got %d\n", needed);
1497     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1498        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1499
1500     /* All parameters are correct but our access rights are wrong */
1501     needed = 0xdeadbeef;
1502     returned = 0xdeadbeef;
1503     SetLastError(0xdeadbeef);
1504     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1505                                  NULL, 0, &needed, &returned, NULL, NULL);
1506     ok(!ret, "Expected failure\n");
1507     ok(needed == 0 || broken(needed != 0), /* nt4 */
1508        "Expected needed buffer size to be set to 0, got %d\n", needed);
1509     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1510     ok(GetLastError() == ERROR_ACCESS_DENIED,
1511        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1512
1513     /* All parameters are correct, access rights are wrong but the
1514      * group name won't be checked yet.
1515      */
1516     needed = 0xdeadbeef;
1517     returned = 0xdeadbeef;
1518     SetLastError(0xdeadbeef);
1519     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1520                                  NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1521     ok(!ret, "Expected failure\n");
1522     ok(needed == 0 || broken(needed != 0), /* nt4 */
1523        "Expected needed buffer size to be set to 0, got %d\n", needed);
1524     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1525     ok(GetLastError() == ERROR_ACCESS_DENIED,
1526        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1527
1528     /* Open the service control manager with the needed rights */
1529     CloseServiceHandle(scm_handle);
1530     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1531
1532     /* All parameters are correct and the group will be checked */
1533     needed = 0xdeadbeef;
1534     returned = 0xdeadbeef;
1535     SetLastError(0xdeadbeef);
1536     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1537                                  NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1538     ok(!ret, "Expected failure\n");
1539     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1540     ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
1541     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
1542        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1543
1544     /* TODO: Create a test that makes sure we enumerate all services that don't
1545      * belong to a group. (specifying "").
1546      */
1547
1548     /* All parameters are correct. Request the needed buffer size */
1549     needed = 0xdeadbeef;
1550     returned = 0xdeadbeef;
1551     SetLastError(0xdeadbeef);
1552     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1553                                  NULL, 0, &needed, &returned, NULL, NULL);
1554     ok(!ret, "Expected failure\n");
1555     ok(returned == 0, "Expected no service returned, got %d\n", returned);
1556     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1557     ok(GetLastError() == ERROR_MORE_DATA,
1558        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1559
1560     /* Test to show we get the same needed buffer size for the W-call */
1561     neededW = 0xdeadbeef;
1562     ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1563                                  NULL, 0, &neededW, &returnedW, NULL, NULL);
1564     ok(!ret, "Expected failure\n");
1565     ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n");
1566
1567     /* Store the needed bytes */
1568     tempneeded = needed;
1569
1570     /* Allocate the correct needed bytes */
1571     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1572     bufsize = needed;
1573     needed = 0xdeadbeef;
1574     returned = 0xdeadbeef;
1575     SetLastError(0xdeadbeef);
1576     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1577                                  (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1578     ok(ret, "Expected success, got error %u\n", GetLastError());
1579     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1580     ok(returned == tempreturned, "Expected the same number of service from this function\n");
1581     HeapFree(GetProcessHeap(), 0, exservices);
1582
1583     /* Store the number of returned services */
1584     tempreturned = returned;
1585
1586     /* Allocate less than the needed bytes and don't specify a resume handle */
1587     exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1588     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1589     needed = 0xdeadbeef;
1590     returned = 0xdeadbeef;
1591     SetLastError(0xdeadbeef);
1592     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1593                                  (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1594     ok(!ret, "Expected failure\n");
1595     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1596     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1597     ok(GetLastError() == ERROR_MORE_DATA,
1598        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1599
1600     /* Allocate less than the needed bytes, this time with a correct resume handle */
1601     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1602     needed = 0xdeadbeef;
1603     returned = 0xdeadbeef;
1604     resume = 0;
1605     SetLastError(0xdeadbeef);
1606     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1607                                  (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1608     ok(!ret, "Expected failure\n");
1609     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1610     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1611     todo_wine ok(resume, "Expected a resume handle\n");
1612     ok(GetLastError() == ERROR_MORE_DATA,
1613        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1614
1615     /* Fetch that last service but pass a bigger buffer size */
1616     missing = tempreturned - returned;
1617     bufsize = tempneeded;
1618     needed = 0xdeadbeef;
1619     returned = 0xdeadbeef;
1620     SetLastError(0xdeadbeef);
1621     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1622                                  (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1623     ok(ret, "Expected success, got error %u\n", GetLastError());
1624     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1625     ok(returned == missing, "Expected %u services to be returned\n", missing);
1626     ok(resume == 0, "Expected the resume handle to be 0\n");
1627     HeapFree(GetProcessHeap(), 0, exservices);
1628
1629     /* See if things add up */
1630
1631     /* Get the number of active win32 services */
1632     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1633                            NULL, 0, &needed, &returned, NULL, NULL);
1634     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1635     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1636                            (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1637     HeapFree(GetProcessHeap(), 0, exservices);
1638
1639     servicecountactive = returned;
1640
1641     /* Get the number of inactive win32 services */
1642     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1643                            NULL, 0, &needed, &returned, NULL, NULL);
1644     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1645     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1646                            (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1647     HeapFree(GetProcessHeap(), 0, exservices);
1648
1649     servicecountinactive = returned;
1650
1651     /* Get the number of win32 services */
1652     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1653                            NULL, 0, &needed, &returned, NULL, NULL);
1654     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1655     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1656                            (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1657     HeapFree(GetProcessHeap(), 0, exservices);
1658
1659     /* Check if total is the same as active and inactive win32 services */
1660     ok(returned == (servicecountactive + servicecountinactive),
1661        "Something wrong in the calculation\n");
1662
1663     /* Get all drivers and services */
1664     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1665                                  SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
1666     ok(!ret, "Expected failure\n");
1667     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1668     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1669                                  SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1670     ok(ret, "Expected success %u\n", GetLastError());
1671
1672     /* Loop through all those returned drivers and services */
1673     for (i = 0; i < returned; i++)
1674     {
1675         SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
1676
1677         /* lpServiceName and lpDisplayName should always be filled */
1678         ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n");
1679         ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n");
1680
1681         /* Decrement the counters to see if the functions calls return the
1682          * same numbers as the contents of these structures.
1683          * Check some process id specifics.
1684          */
1685         if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
1686         {
1687             /* We shouldn't have a process id for drivers */
1688             ok(status.dwProcessId == 0,
1689                "This driver shouldn't have an associated process id\n");
1690         }
1691
1692         if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1693         {
1694             if (status.dwCurrentState != SERVICE_STOPPED)
1695             {
1696                 /* We expect a process id for every running service */
1697                 ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n",
1698                    exservices[i].lpServiceName);
1699
1700                 servicecountactive--;
1701             }
1702             else
1703             {
1704                 /* We shouldn't have a process id for inactive services */
1705                 ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n",
1706                    exservices[i].lpServiceName, status.dwCurrentState);
1707
1708                 servicecountinactive--;
1709             }
1710         }
1711     }
1712     HeapFree(GetProcessHeap(), 0, exservices);
1713
1714     ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1715     ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1716
1717     CloseServiceHandle(scm_handle);
1718 }
1719
1720 static void test_close(void)
1721 {
1722     SC_HANDLE handle;
1723     BOOL ret;
1724
1725     /* NULL handle */
1726     SetLastError(0xdeadbeef);
1727     ret = CloseServiceHandle(NULL);
1728     ok(!ret, "Expected failure\n");
1729     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1730
1731     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1732
1733     /* Proper call */
1734     handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1735     SetLastError(0xdeadbeef);
1736     ret = CloseServiceHandle(handle);
1737     ok(ret, "Expected success got error %u\n", GetLastError());
1738 }
1739
1740 static void test_sequence(void)
1741 {
1742     SC_HANDLE scm_handle, svc_handle;
1743     BOOL ret;
1744     QUERY_SERVICE_CONFIGA *config;
1745     DWORD given, needed;
1746     static const CHAR servicename [] = "Winetest";
1747     static const CHAR displayname [] = "Winetest dummy service";
1748     static const CHAR displayname2[] = "Winetest dummy service (2)";
1749     static const CHAR pathname    [] = "we_dont_care.exe";
1750     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1751     static const CHAR password    [] = "";
1752     static const CHAR empty       [] = "";
1753     static const CHAR localsystem [] = "LocalSystem";
1754
1755     SetLastError(0xdeadbeef);
1756     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1757
1758     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1759     {
1760         skip("Not enough rights to get a handle to the manager\n");
1761         return;
1762     }
1763     else
1764         ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
1765
1766     if (!scm_handle) return;
1767
1768     /* Create a dummy service */
1769     SetLastError(0xdeadbeef);
1770     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1771         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1772         pathname, NULL, NULL, dependencies, NULL, password);
1773
1774     if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
1775     {
1776         /* We try and open the service and do the rest of the tests. Some could
1777          * fail if the tests were changed between these runs.
1778          */
1779         trace("Deletion probably didn't work last time\n");
1780         SetLastError(0xdeadbeef);
1781         svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1782         if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1783         {
1784             skip("Not enough rights to open the service\n");
1785             CloseServiceHandle(scm_handle);        
1786             return;
1787         }
1788         ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
1789     }
1790     else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1791     {
1792         skip("Not enough rights to create the service\n");
1793         CloseServiceHandle(scm_handle);        
1794         return;
1795     }
1796     else
1797     {
1798         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1799         if ((svc_handle != NULL) && (pGetSecurityInfo != NULL))
1800         {
1801             PSID sidOwner, sidGroup;
1802             PACL dacl, sacl;
1803             PSECURITY_DESCRIPTOR pSD;
1804             HRESULT retval = pGetSecurityInfo(svc_handle,SE_SERVICE,DACL_SECURITY_INFORMATION,&sidOwner,&sidGroup,&dacl,&sacl,&pSD);
1805             todo_wine ok(ERROR_SUCCESS == retval, "Expected GetSecurityInfo to succeed: result %d\n",retval);
1806         }
1807     }
1808
1809     if (!svc_handle) return;
1810
1811     /* TODO:
1812      * Before we do a QueryServiceConfig we should check the registry. This will make sure
1813      * that the correct keys are used.
1814      */
1815
1816     /* Request the size for the buffer */
1817     SetLastError(0xdeadbeef);
1818     ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1819     ok(!ret, "Expected failure\n");
1820     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1821
1822     config = HeapAlloc(GetProcessHeap(), 0, needed);
1823     given = needed;
1824     SetLastError(0xdeadbeef);
1825     ret = QueryServiceConfigA(svc_handle, config, given, &needed);
1826     ok(ret, "Expected success, got error %u\n", GetLastError());
1827
1828     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1829         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1830     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1831         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1832     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1833     ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
1834     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1835     ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
1836     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1837     /* TODO: Show the double 0 terminated string */
1838     todo_wine
1839     {
1840     ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
1841     }
1842     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1843     ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
1844
1845     ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2",
1846                                NULL, NULL, NULL, NULL, displayname2);
1847     ok(ret, "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1848
1849     QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1850     config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
1851     ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
1852     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1853         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1854     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1855         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1856     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1857     ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
1858     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1859     ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
1860     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1861     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1862     ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
1863
1864     SetLastError(0xdeadbeef);
1865     ret = DeleteService(svc_handle);
1866     ok(ret, "Expected success, got error %u\n", GetLastError());
1867     CloseServiceHandle(svc_handle);
1868
1869     /* Wait a while. The following test does a CreateService again */
1870     Sleep(1000);
1871
1872     CloseServiceHandle(scm_handle);
1873     HeapFree(GetProcessHeap(), 0, config);
1874 }
1875
1876 static void test_queryconfig2(void)
1877 {
1878     SC_HANDLE scm_handle, svc_handle;
1879     BOOL ret;
1880     DWORD expected, needed;
1881     BYTE buffer[MAX_PATH];
1882     LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
1883     static const CHAR servicename [] = "Winetest";
1884     static const CHAR displayname [] = "Winetest dummy service";
1885     static const CHAR pathname    [] = "we_dont_care.exe";
1886     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1887     static const CHAR password    [] = "";
1888     static const CHAR description [] = "Description";
1889
1890     if(!pQueryServiceConfig2A)
1891     {
1892         win_skip("function QueryServiceConfig2A not present\n");
1893         return;
1894     }
1895
1896     SetLastError(0xdeadbeef);
1897     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1898
1899     if (!scm_handle)
1900     {
1901         if(GetLastError() == ERROR_ACCESS_DENIED)
1902             skip("Not enough rights to get a handle to the manager\n");
1903         else
1904             ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
1905         return;
1906     }
1907
1908     /* Create a dummy service */
1909     SetLastError(0xdeadbeef);
1910     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1911         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1912         pathname, NULL, NULL, dependencies, NULL, password);
1913
1914     if (!svc_handle)
1915     {
1916         if(GetLastError() == ERROR_SERVICE_EXISTS)
1917         {
1918             /* We try and open the service and do the rest of the tests. Some could
1919              * fail if the tests were changed between these runs.
1920              */
1921             trace("Deletion probably didn't work last time\n");
1922             SetLastError(0xdeadbeef);
1923             svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1924             if (!svc_handle)
1925             {
1926                 if(GetLastError() == ERROR_ACCESS_DENIED)
1927                     skip("Not enough rights to open the service\n");
1928                 else
1929                     ok(FALSE, "Could not open the service : %d\n", GetLastError());
1930                 CloseServiceHandle(scm_handle);
1931                 return;
1932             }
1933         }
1934         if (GetLastError() == ERROR_ACCESS_DENIED)
1935         {
1936             skip("Not enough rights to create the service\n");
1937             CloseServiceHandle(scm_handle);
1938             return;
1939         }
1940         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1941         if (!svc_handle)
1942         {
1943             CloseServiceHandle(scm_handle);
1944             return;
1945         }
1946     }
1947     SetLastError(0xdeadbeef);
1948     ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1949     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1950     ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1951
1952     SetLastError(0xdeadbeef);
1953     ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1954     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1955     ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1956
1957     SetLastError(0xdeadbeef);
1958     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1959     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1960     ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1961
1962     SetLastError(0xdeadbeef);
1963     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1964     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1965     ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1966        "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1967
1968     SetLastError(0xdeadbeef);
1969     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1970     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1971     ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1972
1973     needed = 0;
1974     SetLastError(0xdeadbeef);
1975     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1976     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1977     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1978     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1979
1980     needed = 0;
1981     pConfig->lpDescription = (LPSTR)0xdeadbeef;
1982     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1983     ok(ret, "expected QueryServiceConfig2A to succeed\n");
1984     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1985     ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1986
1987     SetLastError(0xdeadbeef);
1988     needed = 0;
1989     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1990     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1991     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1992     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1993
1994     if(!pChangeServiceConfig2A)
1995     {
1996         win_skip("function ChangeServiceConfig2A not present\n");
1997         goto cleanup;
1998     }
1999
2000     pConfig->lpDescription = (LPSTR) description;
2001     ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
2002     ok(ret, "ChangeServiceConfig2A failed\n");
2003     if (!ret) {
2004         goto cleanup;
2005     }
2006
2007     SetLastError(0xdeadbeef);
2008     needed = 0;
2009     expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
2010     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
2011     ok(!ret, "expected QueryServiceConfig2A to fail\n");
2012     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2013     ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
2014
2015     SetLastError(0xdeadbeef);
2016     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
2017     ok(!ret, "expected QueryServiceConfig2A to fail\n");
2018     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2019
2020     SetLastError(0xdeadbeef);
2021     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
2022     ok(ret, "expected QueryServiceConfig2A to succeed\n");
2023     ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
2024         "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
2025
2026     SetLastError(0xdeadbeef);
2027     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
2028     ok(ret, "expected QueryServiceConfig2A to succeed\n");
2029     ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
2030         "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
2031
2032     if(!pQueryServiceConfig2W)
2033     {
2034         win_skip("function QueryServiceConfig2W not present\n");
2035         goto cleanup;
2036     }
2037     SetLastError(0xdeadbeef);
2038     needed = 0;
2039     expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
2040     ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
2041     ok(!ret, "expected QueryServiceConfig2W to fail\n");
2042     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2043     ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
2044
2045     SetLastError(0xdeadbeef);
2046     ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
2047     ok(ret, "expected QueryServiceConfig2W to succeed\n");
2048
2049 cleanup:
2050     DeleteService(svc_handle);
2051
2052     CloseServiceHandle(svc_handle);
2053
2054     /* Wait a while. The following test does a CreateService again */
2055     Sleep(1000);
2056
2057     CloseServiceHandle(scm_handle);
2058 }
2059
2060 static void test_refcount(void)
2061 {
2062     SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
2063     static const CHAR servicename         [] = "Winetest";
2064     static const CHAR pathname            [] = "we_dont_care.exe";
2065     BOOL ret;
2066
2067     /* Get a handle to the Service Control Manager */
2068     SetLastError(0xdeadbeef);
2069     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2070     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
2071     {
2072         skip("Not enough rights to get a handle to the manager\n");
2073         return;
2074     }
2075
2076     /* Create a service */
2077     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2078                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2079                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2080     ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError());
2081
2082     /* Get a handle to this new service */
2083     svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2084     ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError());
2085
2086     /* Get another handle to this new service */
2087     svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2088     ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError());
2089
2090     /* Check if we can close the handle to the Service Control Manager */
2091     ret = CloseServiceHandle(scm_handle);
2092     ok(ret, "Expected success (err=%d)\n", GetLastError());
2093
2094     /* Get a new handle to the Service Control Manager */
2095     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2096     ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
2097
2098     /* Get a handle to this new service */
2099     svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
2100     ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError());
2101
2102     /* Delete the service */
2103     ret = DeleteService(svc_handle4);
2104     ok(ret, "Expected success (err=%d)\n", GetLastError());
2105
2106     /* We cannot create the same service again as it's still marked as 'being deleted'.
2107      * The reason is that we still have 4 open handles to this service even though we
2108      * closed the handle to the Service Control Manager in between.
2109      */
2110     SetLastError(0xdeadbeef);
2111     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2112                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2113                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2114     todo_wine
2115     {
2116     ok(!svc_handle5, "Expected failure\n");
2117     ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
2118        "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2119     }
2120
2121     /* FIXME: Remove this when Wine is fixed */
2122     if (svc_handle5)
2123     {
2124         DeleteService(svc_handle5);
2125         CloseServiceHandle(svc_handle5);
2126     }
2127
2128     /* Close all the handles to the service and try again */
2129     ret = CloseServiceHandle(svc_handle4);
2130     ok(ret, "Expected success (err=%d)\n", GetLastError());
2131     ret = CloseServiceHandle(svc_handle3);
2132     ok(ret, "Expected success (err=%d)\n", GetLastError());
2133     ret = CloseServiceHandle(svc_handle2);
2134     ok(ret, "Expected success (err=%d)\n", GetLastError());
2135     ret = CloseServiceHandle(svc_handle1);
2136     ok(ret, "Expected success (err=%d)\n", GetLastError());
2137
2138     /* Wait a while. Doing a CreateService too soon will result again
2139      * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2140      */
2141     Sleep(1000);
2142
2143     /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2144     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2145                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2146                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2147     ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError());
2148
2149     /* Delete the service */
2150     ret = DeleteService(svc_handle5);
2151     ok(ret, "Expected success (err=%d)\n", GetLastError());
2152
2153     /* Wait a while. Just in case one of the following tests does a CreateService again */
2154     Sleep(1000);
2155
2156     CloseServiceHandle(svc_handle5);
2157     CloseServiceHandle(scm_handle);
2158 }
2159
2160 START_TEST(service)
2161 {
2162     SC_HANDLE scm_handle;
2163
2164     /* Bail out if we are on win98 */
2165     SetLastError(0xdeadbeef);
2166     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2167
2168     if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2169     {
2170         win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2171         return;
2172     }
2173     CloseServiceHandle(scm_handle);
2174
2175     init_function_pointers();
2176
2177     /* First some parameter checking */
2178     test_open_scm();
2179     test_open_svc();
2180     test_create_delete_svc();
2181     test_get_displayname();
2182     test_get_servicekeyname();
2183     test_query_svc();
2184     test_enum_svc();
2185     test_close();
2186     /* Test the creation, querying and deletion of a service */
2187     test_sequence();
2188     test_queryconfig2();
2189     /* The main reason for this test is to check if any refcounting is used
2190      * and what the rules are
2191      */
2192     test_refcount();
2193 }