mshtml: Rename call_event to fire_event.
[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     ok(GetLastError() == ERROR_INVALID_LEVEL,
960        "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
961
962     /* Passing a NULL parameter for the needed buffer size
963      * will crash on anything but NT4.
964      */
965
966     /* Only info level is correct. It looks like the buffer/size is checked second */
967     SetLastError(0xdeadbeef);
968     ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, NULL, 0, &needed);
969     /* NT4 checks the handle first */
970     if (GetLastError() != ERROR_INVALID_HANDLE)
971     {
972         ok(!ret, "Expected failure\n");
973         ok(needed == sizeof(SERVICE_STATUS_PROCESS),
974            "Needed buffersize is wrong : %d\n", needed);
975         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
976            "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
977     }
978
979     /* Pass a correct buffer and buffersize but a NULL handle */
980     statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
981     bufsize = needed;
982     SetLastError(0xdeadbeef);
983     ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
984     ok(!ret, "Expected failure\n");
985     ok(GetLastError() == ERROR_INVALID_HANDLE,
986        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
987     HeapFree(GetProcessHeap(), 0, statusproc);
988
989     /* Correct handle and info level */
990     SetLastError(0xdeadbeef);
991     ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, NULL, 0, &needed);
992     /* NT4 doesn't return the needed size */
993     if (GetLastError() != ERROR_INVALID_PARAMETER)
994     {
995         ok(!ret, "Expected failure\n");
996         ok(needed == sizeof(SERVICE_STATUS_PROCESS),
997            "Needed buffersize is wrong : %d\n", needed);
998         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
999            "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1000     }
1001
1002     /* All parameters are OK but we don't have enough rights */
1003     statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1004     bufsize = sizeof(SERVICE_STATUS_PROCESS);
1005     SetLastError(0xdeadbeef);
1006     ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
1007     ok(!ret, "Expected failure\n");
1008     ok(GetLastError() == ERROR_ACCESS_DENIED,
1009        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1010     HeapFree(GetProcessHeap(), 0, statusproc);
1011
1012     /* Open the service with just enough rights. */
1013     CloseServiceHandle(svc_handle);
1014     svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
1015
1016     /* Everything should be fine now. */
1017     statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
1018     bufsize = sizeof(SERVICE_STATUS_PROCESS);
1019     SetLastError(0xdeadbeef);
1020     ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed);
1021     ok(ret, "Expected success, got error %u\n", GetLastError());
1022     if (statusproc->dwCurrentState == SERVICE_RUNNING)
1023         ok(statusproc->dwProcessId != 0,
1024            "Expect a process id for this running service\n");
1025     else
1026         ok(statusproc->dwProcessId == 0,
1027            "Expect no process id for this stopped service\n");
1028     HeapFree(GetProcessHeap(), 0, statusproc);
1029
1030     CloseServiceHandle(svc_handle);
1031     CloseServiceHandle(scm_handle);
1032 }
1033
1034 static void test_enum_svc(void)
1035 {
1036     SC_HANDLE scm_handle;
1037     BOOL ret;
1038     DWORD bufsize, needed, returned, resume;
1039     DWORD neededW, returnedW;
1040     DWORD tempneeded, tempreturned, missing;
1041     DWORD servicecountactive, servicecountinactive;
1042     ENUM_SERVICE_STATUS *services;
1043     ENUM_SERVICE_STATUSW *servicesW;
1044     ENUM_SERVICE_STATUS_PROCESS *exservices;
1045     UINT i;
1046
1047     /* All NULL or wrong  */
1048     SetLastError(0xdeadbeef);
1049     ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1050     ok(!ret, "Expected failure\n");
1051     ok(GetLastError() == ERROR_INVALID_HANDLE,
1052        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1053
1054     SetLastError(0xdeadbeef);
1055     ret = EnumServicesStatusW(NULL, 1, 0, NULL, 0, NULL, NULL, NULL);
1056     ok(!ret, "Expected failure\n");
1057     ok(GetLastError() == ERROR_INVALID_HANDLE,
1058        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1059
1060     /* Open the service control manager with not enough rights at first */
1061     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1062
1063     /* Valid handle but rest is still NULL or wrong  */
1064     SetLastError(0xdeadbeef);
1065     ret = EnumServicesStatusA(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1066     ok(!ret, "Expected failure\n");
1067     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1068        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1069        "Unexpected last error %d\n", GetLastError());
1070
1071     SetLastError(0xdeadbeef);
1072     ret = EnumServicesStatusW(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL);
1073     ok(!ret, "Expected failure\n");
1074     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1075        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1076        "Unexpected last error %d\n", GetLastError());
1077
1078     /* Don't specify the two required pointers */
1079     returned = 0xdeadbeef;
1080     SetLastError(0xdeadbeef);
1081     ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1082     ok(!ret, "Expected failure\n");
1083     ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1084     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1085        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1086        "Unexpected last error %d\n", GetLastError());
1087
1088     returned = 0xdeadbeef;
1089     SetLastError(0xdeadbeef);
1090     ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL);
1091     ok(!ret, "Expected failure\n");
1092     ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1093     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1094        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1095        "Unexpected last error %d\n", GetLastError());
1096
1097     /* Don't specify the two required pointers */
1098     needed = 0xdeadbeef;
1099     SetLastError(0xdeadbeef);
1100     ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1101     ok(!ret, "Expected failure\n");
1102     ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1103        "Expected no change to the needed buffer variable\n");
1104     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1105        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1106        "Unexpected last error %d\n", GetLastError());
1107
1108     needed = 0xdeadbeef;
1109     SetLastError(0xdeadbeef);
1110     ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL);
1111     ok(!ret, "Expected failure\n");
1112     ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1113        "Expected no change to the needed buffer variable\n");
1114     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1115        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1116        "Unexpected last error %d\n", GetLastError());
1117
1118     /* No valid servicetype and servicestate */
1119     needed = 0xdeadbeef;
1120     returned = 0xdeadbeef;
1121     SetLastError(0xdeadbeef);
1122     ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1123     ok(!ret, "Expected failure\n");
1124     ok(needed == 0 || broken(needed != 0), /* nt4 */
1125        "Expected needed buffer size to be set to 0, got %d\n", needed);
1126     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1127     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1128        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1129
1130     needed = 0xdeadbeef;
1131     returned = 0xdeadbeef;
1132     SetLastError(0xdeadbeef);
1133     ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL);
1134     ok(!ret, "Expected failure\n");
1135     ok(needed == 0 || broken(needed != 0), /* nt4 */
1136        "Expected needed buffer size to be set to 0, got %d\n", needed);
1137     ok(returned == 0 || broken(returned != 0), /* nt4 */
1138        "Expected number of services to be set to 0, got %d\n", returned);
1139     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1140        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1141
1142     /* No valid servicestate */
1143     needed = 0xdeadbeef;
1144     returned = 0xdeadbeef;
1145     SetLastError(0xdeadbeef);
1146     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1147     ok(!ret, "Expected failure\n");
1148     ok(needed == 0 || broken(needed != 0), /* nt4 */
1149        "Expected needed buffer size to be set to 0, got %d\n", needed);
1150     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1151     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1152        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1153
1154     needed = 0xdeadbeef;
1155     returned = 0xdeadbeef;
1156     SetLastError(0xdeadbeef);
1157     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL);
1158     ok(!ret, "Expected failure\n");
1159     ok(needed == 0 || broken(needed != 0), /* nt4 */
1160        "Expected needed buffer size to be set to 0, got %d\n", needed);
1161     ok(returned == 0 || broken(returned != 0), /* nt4 */
1162        "Expected number of services to be set to 0, got %d\n", returned);
1163     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1164        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1165
1166     /* No valid servicetype */
1167     needed = 0xdeadbeef;
1168     returned = 0xdeadbeef;
1169     SetLastError(0xdeadbeef);
1170     ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1171     ok(!ret, "Expected failure\n");
1172     ok(needed == 0 || broken(needed != 0), /* nt4 */
1173        "Expected needed buffer size to be set to 0, got %d\n", needed);
1174     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1175     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1176        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1177
1178     needed = 0xdeadbeef;
1179     returned = 0xdeadbeef;
1180     SetLastError(0xdeadbeef);
1181     ret = EnumServicesStatusW(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1182     ok(!ret, "Expected failure\n");
1183     ok(needed == 0 || broken(needed != 0), /* nt4 */
1184        "Expected needed buffer size to be set to 0, got %d\n", needed);
1185     ok(returned == 0 || broken(returned != 0), /* nt4 */
1186        "Expected number of services to be set to 0, got %d\n", returned);
1187     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1188        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1189
1190     /* All parameters are correct but our access rights are wrong */
1191     needed = 0xdeadbeef;
1192     returned = 0xdeadbeef;
1193     SetLastError(0xdeadbeef);
1194     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1195     ok(!ret, "Expected failure\n");
1196     ok(needed == 0 || broken(needed != 0), /* nt4 */
1197        "Expected needed buffer size to be set to 0, got %d\n", needed);
1198     ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned);
1199     ok(GetLastError() == ERROR_ACCESS_DENIED,
1200        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1201
1202     needed = 0xdeadbeef;
1203     returned = 0xdeadbeef;
1204     SetLastError(0xdeadbeef);
1205     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1206     ok(!ret, "Expected failure\n");
1207     ok(needed == 0 || broken(needed != 0), /* nt4 */
1208        "Expected needed buffer size to be set to 0, got %d\n", needed);
1209     ok(returned == 0 || broken(returned != 0), /* nt4 */
1210        "Expected number of services to be set to 0, got %d\n", returned);
1211     ok(GetLastError() == ERROR_ACCESS_DENIED,
1212        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1213
1214     /* Open the service control manager with the needed rights */
1215     CloseServiceHandle(scm_handle);
1216     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1217
1218     /* All parameters are correct. Request the needed buffer size */
1219     needed = 0xdeadbeef;
1220     returned = 0xdeadbeef;
1221     SetLastError(0xdeadbeef);
1222     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL);
1223     ok(!ret, "Expected failure\n");
1224     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1225     ok(returned == 0, "Expected no service returned, got %d\n", returned);
1226     ok(GetLastError() == ERROR_MORE_DATA,
1227        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1228
1229     /* Test to show we get the same needed buffer size for the W-call */
1230     neededW = 0xdeadbeef;
1231     returnedW = 0xdeadbeef;
1232     SetLastError(0xdeadbeef);
1233     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &neededW, &returnedW, NULL);
1234     ok(!ret, "Expected failure\n");
1235     ok(neededW != 0xdeadbeef && neededW > 0, "Expected the needed buffer size for this one service\n");
1236     ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n");
1237     ok(returnedW == 0, "Expected no service returned, got %d\n", returnedW);
1238     ok(GetLastError() == ERROR_MORE_DATA,
1239        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1240
1241     /* Store the needed bytes */
1242     tempneeded = needed;
1243
1244     /* Allocate the correct needed bytes */
1245     services = HeapAlloc(GetProcessHeap(), 0, needed);
1246     bufsize = needed;
1247     needed = 0xdeadbeef;
1248     returned = 0xdeadbeef;
1249     SetLastError(0xdeadbeef);
1250     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1251                               services, bufsize, &needed, &returned, NULL);
1252     ok(ret, "Expected success, got error %u\n", GetLastError());
1253     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1254     ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n");
1255     HeapFree(GetProcessHeap(), 0, services);
1256
1257     /* Store the number of returned services */
1258     tempreturned = returned;
1259
1260     servicesW = HeapAlloc(GetProcessHeap(), 0, neededW);
1261     bufsize = neededW;
1262     neededW = 0xdeadbeef;
1263     returnedW = 0xdeadbeef;
1264     SetLastError(0xdeadbeef);
1265     ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1266                               servicesW, bufsize, &neededW, &returnedW, NULL);
1267     ok(ret, "Expected success, got error %u\n", GetLastError());
1268     ok(neededW == 0, "Expected needed buffer to be 0 as we are done\n");
1269     ok(returnedW != 0xdeadbeef && returnedW > 0, "Expected some returned services\n");
1270     HeapFree(GetProcessHeap(), 0, servicesW);
1271
1272     /* Allocate less than the needed bytes and don't specify a resume handle */
1273     services = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1274     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1275     needed = 0xdeadbeef;
1276     returned = 0xdeadbeef;
1277     SetLastError(0xdeadbeef);
1278     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1279                               services, bufsize, &needed, &returned, NULL);
1280     ok(!ret, "Expected failure\n");
1281     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1282     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1283     ok(GetLastError() == ERROR_MORE_DATA,
1284        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1285
1286     /* Allocate less than the needed bytes, this time with a correct resume handle */
1287     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1288     needed = 0xdeadbeef;
1289     returned = 0xdeadbeef;
1290     resume = 0;
1291     SetLastError(0xdeadbeef);
1292     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1293                               services, bufsize, &needed, &returned, &resume);
1294     ok(!ret, "Expected failure\n");
1295     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n");
1296     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1297     todo_wine ok(resume, "Expected a resume handle\n");
1298     ok(GetLastError() == ERROR_MORE_DATA,
1299        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1300
1301     /* Fetch the missing services but pass a bigger buffer size */
1302     missing = tempreturned - returned;
1303     bufsize = tempneeded;
1304     needed = 0xdeadbeef;
1305     returned = 0xdeadbeef;
1306     SetLastError(0xdeadbeef);
1307     ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL,
1308                               services, bufsize, &needed, &returned, &resume);
1309     ok(ret, "Expected success, got error %u\n", GetLastError());
1310     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1311     ok(returned == missing, "Expected %u services to be returned\n", missing);
1312     ok(resume == 0, "Expected the resume handle to be 0\n");
1313     HeapFree(GetProcessHeap(), 0, services);
1314
1315     /* See if things add up */
1316
1317     /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1318      * and doesn't count the others as inactive. This means that Vista could
1319      * show a total that is greater than the sum of active and inactive
1320      * drivers.
1321      * The number of active and inactive drivers is greatly influenced by the
1322      * time when tests are run, immediately after boot or later for example.
1323      *
1324      * Both reasons make calculations for drivers not so useful
1325      */
1326
1327     /* Get the number of active win32 services */
1328     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0,
1329                         &needed, &returned, NULL);
1330     services = HeapAlloc(GetProcessHeap(), 0, needed);
1331     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services,
1332                         needed, &needed, &returned, NULL);
1333     HeapFree(GetProcessHeap(), 0, services);
1334
1335     servicecountactive = returned;
1336
1337     /* Get the number of inactive win32 services */
1338     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0,
1339                         &needed, &returned, NULL);
1340     services = HeapAlloc(GetProcessHeap(), 0, needed);
1341     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services,
1342                         needed, &needed, &returned, NULL);
1343     HeapFree(GetProcessHeap(), 0, services);
1344
1345     servicecountinactive = returned;
1346
1347     /* Get the number of win32 services */
1348     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
1349                         &needed, &returned, NULL);
1350     services = HeapAlloc(GetProcessHeap(), 0, needed);
1351     EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services,
1352                         needed, &needed, &returned, NULL);
1353     HeapFree(GetProcessHeap(), 0, services);
1354
1355     /* Check if total is the same as active and inactive win32 services */
1356     ok(returned == (servicecountactive + servicecountinactive),
1357        "Something wrong in the calculation\n");
1358
1359     /* Get all drivers and services
1360      *
1361      * Fetch the status of the last call as failing could make the following tests crash
1362      * on Wine (we don't return anything yet).
1363      */
1364     EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1365                         NULL, 0, &needed, &returned, NULL);
1366     services = HeapAlloc(GetProcessHeap(), 0, needed);
1367     ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL,
1368                               services, needed, &needed, &returned, NULL);
1369
1370     /* Loop through all those returned drivers and services */
1371     for (i = 0; ret && i < returned; i++)
1372     {
1373         SERVICE_STATUS status = services[i].ServiceStatus;
1374
1375         /* lpServiceName and lpDisplayName should always be filled */
1376         ok(lstrlenA(services[i].lpServiceName) > 0, "Expected a service name\n");
1377         ok(lstrlenA(services[i].lpDisplayName) > 0, "Expected a display name\n");
1378
1379         /* Decrement the counters to see if the functions calls return the same
1380          * numbers as the contents of these structures.
1381          */
1382         if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1383         {
1384             if (status.dwCurrentState == SERVICE_STOPPED)
1385                 servicecountinactive--;
1386             else
1387                 servicecountactive--;
1388         }
1389     }
1390     HeapFree(GetProcessHeap(), 0, services);
1391
1392     ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1393     ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1394
1395     CloseServiceHandle(scm_handle);
1396
1397     /* More or less the same for EnumServicesStatusExA */
1398
1399     /* All NULL or wrong */
1400     SetLastError(0xdeadbeef);
1401     ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1402     ok(!ret, "Expected failure\n");
1403     ok(GetLastError() == ERROR_INVALID_LEVEL,
1404        "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1405
1406     /* All NULL or wrong, just the info level is correct */
1407     SetLastError(0xdeadbeef);
1408     ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1409     ok(!ret, "Expected failure\n");
1410     ok(GetLastError() == ERROR_INVALID_HANDLE,
1411        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1412
1413     /* Open the service control manager with not enough rights at first */
1414     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1415
1416     /* Valid handle and info level but rest is still NULL or wrong */
1417     SetLastError(0xdeadbeef);
1418     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL);
1419     ok(!ret, "Expected failure\n");
1420     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1421        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1422        "Unexpected last error %d\n", GetLastError());
1423
1424     /* Don't specify the two required pointers */
1425     needed = 0xdeadbeef;
1426     SetLastError(0xdeadbeef);
1427     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL);
1428     ok(!ret, "Expected failure\n");
1429     ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */
1430        "Expected no change to the needed buffer variable\n");
1431     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1432        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1433        "Unexpected last error %d\n", GetLastError());
1434
1435     /* Don't specify the two required pointers */
1436     returned = 0xdeadbeef;
1437     SetLastError(0xdeadbeef);
1438     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL);
1439     ok(!ret, "Expected failure\n");
1440     ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n");
1441     ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1442        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1443        "Unexpected last error %d\n", GetLastError());
1444
1445     /* No valid servicetype and servicestate */
1446     needed = 0xdeadbeef;
1447     returned = 0xdeadbeef;
1448     SetLastError(0xdeadbeef);
1449     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL);
1450     ok(!ret, "Expected failure\n");
1451     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1452     ok(needed == 0 || broken(needed != 0), /* nt4 */
1453        "Expected needed buffer size to be set to 0, got %d\n", needed);
1454     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1455        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1456
1457     /* No valid servicestate */
1458     needed = 0xdeadbeef;
1459     returned = 0xdeadbeef;
1460     SetLastError(0xdeadbeef);
1461     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0,
1462                                  &needed, &returned, NULL, NULL);
1463     ok(!ret, "Expected failure\n");
1464     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1465     ok(needed == 0 || broken(needed != 0), /* nt4 */
1466        "Expected needed buffer size to be set to 0, got %d\n", needed);
1467     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1468        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1469
1470     /* No valid servicetype */
1471     needed = 0xdeadbeef;
1472     returned = 0xdeadbeef;
1473     SetLastError(0xdeadbeef);
1474     ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0,
1475                                  &needed, &returned, NULL, NULL);
1476     ok(!ret, "Expected failure\n");
1477     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1478     ok(needed == 0 || broken(needed != 0), /* nt4 */
1479        "Expected needed buffer size to be set to 0, got %d\n", needed);
1480     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1481        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1482
1483     /* No valid servicetype and servicestate and unknown service group */
1484     needed = 0xdeadbeef;
1485     returned = 0xdeadbeef;
1486     SetLastError(0xdeadbeef);
1487     ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed,
1488                                  &returned, NULL, "deadbeef_group");
1489     ok(!ret, "Expected failure\n");
1490     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1491     ok(needed == 0 || broken(needed != 0), /* nt4 */
1492        "Expected needed buffer size to be set to 0, got %d\n", needed);
1493     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1494        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1495
1496     /* All parameters are correct but our access rights are wrong */
1497     needed = 0xdeadbeef;
1498     returned = 0xdeadbeef;
1499     SetLastError(0xdeadbeef);
1500     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1501                                  NULL, 0, &needed, &returned, NULL, NULL);
1502     ok(!ret, "Expected failure\n");
1503     ok(needed == 0 || broken(needed != 0), /* nt4 */
1504        "Expected needed buffer size to be set to 0, got %d\n", needed);
1505     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1506     ok(GetLastError() == ERROR_ACCESS_DENIED,
1507        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1508
1509     /* All parameters are correct, access rights are wrong but the
1510      * group name won't be checked yet.
1511      */
1512     needed = 0xdeadbeef;
1513     returned = 0xdeadbeef;
1514     SetLastError(0xdeadbeef);
1515     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1516                                  NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1517     ok(!ret, "Expected failure\n");
1518     ok(needed == 0 || broken(needed != 0), /* nt4 */
1519        "Expected needed buffer size to be set to 0, got %d\n", needed);
1520     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1521     ok(GetLastError() == ERROR_ACCESS_DENIED,
1522        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1523
1524     /* Open the service control manager with the needed rights */
1525     CloseServiceHandle(scm_handle);
1526     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1527
1528     /* All parameters are correct and the group will be checked */
1529     needed = 0xdeadbeef;
1530     returned = 0xdeadbeef;
1531     SetLastError(0xdeadbeef);
1532     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1533                                  NULL, 0, &needed, &returned, NULL, "deadbeef_group");
1534     ok(!ret, "Expected failure\n");
1535     ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned);
1536     ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed);
1537     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
1538        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1539
1540     /* TODO: Create a test that makes sure we enumerate all services that don't
1541      * belong to a group. (specifying "").
1542      */
1543
1544     /* All parameters are correct. Request the needed buffer size */
1545     needed = 0xdeadbeef;
1546     returned = 0xdeadbeef;
1547     SetLastError(0xdeadbeef);
1548     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1549                                  NULL, 0, &needed, &returned, NULL, NULL);
1550     ok(!ret, "Expected failure\n");
1551     ok(returned == 0, "Expected no service returned, got %d\n", returned);
1552     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1553     ok(GetLastError() == ERROR_MORE_DATA,
1554        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1555
1556     /* Test to show we get the same needed buffer size for the W-call */
1557     neededW = 0xdeadbeef;
1558     ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1559                                  NULL, 0, &neededW, &returnedW, NULL, NULL);
1560     ok(!ret, "Expected failure\n");
1561     ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n");
1562
1563     /* Store the needed bytes */
1564     tempneeded = needed;
1565
1566     /* Allocate the correct needed bytes */
1567     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1568     bufsize = needed;
1569     needed = 0xdeadbeef;
1570     returned = 0xdeadbeef;
1571     SetLastError(0xdeadbeef);
1572     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1573                                  (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1574     ok(ret, "Expected success, got error %u\n", GetLastError());
1575     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1576     ok(returned == tempreturned, "Expected the same number of service from this function\n");
1577     HeapFree(GetProcessHeap(), 0, exservices);
1578
1579     /* Store the number of returned services */
1580     tempreturned = returned;
1581
1582     /* Allocate less than the needed bytes and don't specify a resume handle */
1583     exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded);
1584     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1585     needed = 0xdeadbeef;
1586     returned = 0xdeadbeef;
1587     SetLastError(0xdeadbeef);
1588     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1589                                  (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL);
1590     ok(!ret, "Expected failure\n");
1591     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1592     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1593     ok(GetLastError() == ERROR_MORE_DATA,
1594        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1595
1596     /* Allocate less than the needed bytes, this time with a correct resume handle */
1597     bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUS);
1598     needed = 0xdeadbeef;
1599     returned = 0xdeadbeef;
1600     resume = 0;
1601     SetLastError(0xdeadbeef);
1602     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1603                                  (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1604     ok(!ret, "Expected failure\n");
1605     ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n");
1606     ok(returned < tempreturned, "Expected fewer services to be returned\n");
1607     todo_wine ok(resume, "Expected a resume handle\n");
1608     ok(GetLastError() == ERROR_MORE_DATA,
1609        "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1610
1611     /* Fetch that last service but pass a bigger buffer size */
1612     missing = tempreturned - returned;
1613     bufsize = tempneeded;
1614     needed = 0xdeadbeef;
1615     returned = 0xdeadbeef;
1616     SetLastError(0xdeadbeef);
1617     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1618                                  (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL);
1619     ok(ret, "Expected success, got error %u\n", GetLastError());
1620     ok(needed == 0, "Expected needed buffer to be 0 as we are done\n");
1621     ok(returned == missing, "Expected %u services to be returned\n", missing);
1622     ok(resume == 0, "Expected the resume handle to be 0\n");
1623     HeapFree(GetProcessHeap(), 0, exservices);
1624
1625     /* See if things add up */
1626
1627     /* Get the number of active win32 services */
1628     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1629                            NULL, 0, &needed, &returned, NULL, NULL);
1630     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1631     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE,
1632                            (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1633     HeapFree(GetProcessHeap(), 0, exservices);
1634
1635     servicecountactive = returned;
1636
1637     /* Get the number of inactive win32 services */
1638     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1639                            NULL, 0, &needed, &returned, NULL, NULL);
1640     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1641     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE,
1642                            (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1643     HeapFree(GetProcessHeap(), 0, exservices);
1644
1645     servicecountinactive = returned;
1646
1647     /* Get the number of win32 services */
1648     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1649                            NULL, 0, &needed, &returned, NULL, NULL);
1650     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1651     pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
1652                            (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1653     HeapFree(GetProcessHeap(), 0, exservices);
1654
1655     /* Check if total is the same as active and inactive win32 services */
1656     ok(returned == (servicecountactive + servicecountinactive),
1657        "Something wrong in the calculation\n");
1658
1659     /* Get all drivers and services */
1660     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1661                                  SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL);
1662     ok(!ret, "Expected failure\n");
1663     exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1664     ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER,
1665                                  SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL);
1666     ok(ret, "Expected success %u\n", GetLastError());
1667
1668     /* Loop through all those returned drivers and services */
1669     for (i = 0; i < returned; i++)
1670     {
1671         SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
1672
1673         /* lpServiceName and lpDisplayName should always be filled */
1674         ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n");
1675         ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n");
1676
1677         /* Decrement the counters to see if the functions calls return the
1678          * same numbers as the contents of these structures.
1679          * Check some process id specifics.
1680          */
1681         if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
1682         {
1683             /* We shouldn't have a process id for drivers */
1684             ok(status.dwProcessId == 0,
1685                "This driver shouldn't have an associated process id\n");
1686         }
1687
1688         if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1689         {
1690             if (status.dwCurrentState != SERVICE_STOPPED)
1691             {
1692                 /* We expect a process id for every running service */
1693                 ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n",
1694                    exservices[i].lpServiceName);
1695
1696                 servicecountactive--;
1697             }
1698             else
1699             {
1700                 /* We shouldn't have a process id for inactive services */
1701                 ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n",
1702                    exservices[i].lpServiceName, status.dwCurrentState);
1703
1704                 servicecountinactive--;
1705             }
1706         }
1707     }
1708     HeapFree(GetProcessHeap(), 0, exservices);
1709
1710     ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1711     ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1712
1713     CloseServiceHandle(scm_handle);
1714 }
1715
1716 static void test_close(void)
1717 {
1718     SC_HANDLE handle;
1719     BOOL ret;
1720
1721     /* NULL handle */
1722     SetLastError(0xdeadbeef);
1723     ret = CloseServiceHandle(NULL);
1724     ok(!ret, "Expected failure\n");
1725     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1726
1727     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1728
1729     /* Proper call */
1730     handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1731     SetLastError(0xdeadbeef);
1732     ret = CloseServiceHandle(handle);
1733     ok(ret, "Expected success got error %u\n", GetLastError());
1734 }
1735
1736 static void test_sequence(void)
1737 {
1738     SC_HANDLE scm_handle, svc_handle;
1739     BOOL ret;
1740     QUERY_SERVICE_CONFIGA *config;
1741     DWORD given, needed;
1742     static const CHAR servicename [] = "Winetest";
1743     static const CHAR displayname [] = "Winetest dummy service";
1744     static const CHAR displayname2[] = "Winetest dummy service (2)";
1745     static const CHAR pathname    [] = "we_dont_care.exe";
1746     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1747     static const CHAR password    [] = "";
1748     static const CHAR empty       [] = "";
1749     static const CHAR localsystem [] = "LocalSystem";
1750
1751     SetLastError(0xdeadbeef);
1752     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1753
1754     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1755     {
1756         skip("Not enough rights to get a handle to the manager\n");
1757         return;
1758     }
1759     else
1760         ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
1761
1762     if (!scm_handle) return;
1763
1764     /* Create a dummy service */
1765     SetLastError(0xdeadbeef);
1766     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1767         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1768         pathname, NULL, NULL, dependencies, NULL, password);
1769
1770     if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
1771     {
1772         /* We try and open the service and do the rest of the tests. Some could
1773          * fail if the tests were changed between these runs.
1774          */
1775         trace("Deletion probably didn't work last time\n");
1776         SetLastError(0xdeadbeef);
1777         svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1778         if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1779         {
1780             skip("Not enough rights to open the service\n");
1781             CloseServiceHandle(scm_handle);        
1782             return;
1783         }
1784         ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
1785     }
1786     else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1787     {
1788         skip("Not enough rights to create the service\n");
1789         CloseServiceHandle(scm_handle);        
1790         return;
1791     }
1792     else
1793     {
1794         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1795         if ((svc_handle != NULL) && (pGetSecurityInfo != NULL))
1796         {
1797             PSID sidOwner, sidGroup;
1798             PACL dacl, sacl;
1799             PSECURITY_DESCRIPTOR pSD;
1800             HRESULT retval = pGetSecurityInfo(svc_handle,SE_SERVICE,DACL_SECURITY_INFORMATION,&sidOwner,&sidGroup,&dacl,&sacl,&pSD);
1801             todo_wine ok(ERROR_SUCCESS == retval, "Expected GetSecurityInfo to succeed: result %d\n",retval);
1802         }
1803     }
1804
1805     if (!svc_handle) return;
1806
1807     /* TODO:
1808      * Before we do a QueryServiceConfig we should check the registry. This will make sure
1809      * that the correct keys are used.
1810      */
1811
1812     /* Request the size for the buffer */
1813     SetLastError(0xdeadbeef);
1814     ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1815     ok(!ret, "Expected failure\n");
1816     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1817
1818     config = HeapAlloc(GetProcessHeap(), 0, needed);
1819     given = needed;
1820     SetLastError(0xdeadbeef);
1821     ret = QueryServiceConfigA(svc_handle, config, given, &needed);
1822     ok(ret, "Expected success, got error %u\n", GetLastError());
1823
1824     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1825         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1826     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1827         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1828     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1829     ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
1830     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1831     ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
1832     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1833     /* TODO: Show the double 0 terminated string */
1834     todo_wine
1835     {
1836     ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
1837     }
1838     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1839     ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
1840
1841     ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2",
1842                                NULL, NULL, NULL, NULL, displayname2);
1843     ok(ret, "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1844
1845     QueryServiceConfigA(svc_handle, NULL, 0, &needed);
1846     config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
1847     ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
1848     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
1849         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
1850     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
1851         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
1852     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
1853     ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
1854     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
1855     ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
1856     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
1857     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
1858     ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
1859
1860     SetLastError(0xdeadbeef);
1861     ret = DeleteService(svc_handle);
1862     ok(ret, "Expected success, got error %u\n", GetLastError());
1863     CloseServiceHandle(svc_handle);
1864
1865     /* Wait a while. The following test does a CreateService again */
1866     Sleep(1000);
1867
1868     CloseServiceHandle(scm_handle);
1869     HeapFree(GetProcessHeap(), 0, config);
1870 }
1871
1872 static void test_queryconfig2(void)
1873 {
1874     SC_HANDLE scm_handle, svc_handle;
1875     BOOL ret;
1876     DWORD expected, needed;
1877     BYTE buffer[MAX_PATH];
1878     LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
1879     static const CHAR servicename [] = "Winetest";
1880     static const CHAR displayname [] = "Winetest dummy service";
1881     static const CHAR pathname    [] = "we_dont_care.exe";
1882     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
1883     static const CHAR password    [] = "";
1884     static const CHAR description [] = "Description";
1885
1886     if(!pQueryServiceConfig2A)
1887     {
1888         win_skip("function QueryServiceConfig2A not present\n");
1889         return;
1890     }
1891
1892     SetLastError(0xdeadbeef);
1893     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1894
1895     if (!scm_handle)
1896     {
1897         if(GetLastError() == ERROR_ACCESS_DENIED)
1898             skip("Not enough rights to get a handle to the manager\n");
1899         else
1900             ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
1901         return;
1902     }
1903
1904     /* Create a dummy service */
1905     SetLastError(0xdeadbeef);
1906     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
1907         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
1908         pathname, NULL, NULL, dependencies, NULL, password);
1909
1910     if (!svc_handle)
1911     {
1912         if(GetLastError() == ERROR_SERVICE_EXISTS)
1913         {
1914             /* We try and open the service and do the rest of the tests. Some could
1915              * fail if the tests were changed between these runs.
1916              */
1917             trace("Deletion probably didn't work last time\n");
1918             SetLastError(0xdeadbeef);
1919             svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1920             if (!svc_handle)
1921             {
1922                 if(GetLastError() == ERROR_ACCESS_DENIED)
1923                     skip("Not enough rights to open the service\n");
1924                 else
1925                     ok(FALSE, "Could not open the service : %d\n", GetLastError());
1926                 CloseServiceHandle(scm_handle);
1927                 return;
1928             }
1929         }
1930         if (GetLastError() == ERROR_ACCESS_DENIED)
1931         {
1932             skip("Not enough rights to create the service\n");
1933             CloseServiceHandle(scm_handle);
1934             return;
1935         }
1936         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1937         if (!svc_handle)
1938         {
1939             CloseServiceHandle(scm_handle);
1940             return;
1941         }
1942     }
1943     SetLastError(0xdeadbeef);
1944     ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1945     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1946     ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1947
1948     SetLastError(0xdeadbeef);
1949     ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1950     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1951     ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1952
1953     SetLastError(0xdeadbeef);
1954     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1955     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1956     ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1957
1958     SetLastError(0xdeadbeef);
1959     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1960     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1961     ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1962        "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1963
1964     SetLastError(0xdeadbeef);
1965     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1966     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1967     ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1968
1969     needed = 0;
1970     SetLastError(0xdeadbeef);
1971     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1972     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1973     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1974     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1975
1976     needed = 0;
1977     pConfig->lpDescription = (LPSTR)0xdeadbeef;
1978     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1979     ok(ret, "expected QueryServiceConfig2A to succeed\n");
1980     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1981     ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1982
1983     SetLastError(0xdeadbeef);
1984     needed = 0;
1985     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1986     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1987     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1988     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1989
1990     if(!pChangeServiceConfig2A)
1991     {
1992         win_skip("function ChangeServiceConfig2A not present\n");
1993         goto cleanup;
1994     }
1995
1996     pConfig->lpDescription = (LPSTR) description;
1997     ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1998     ok(ret, "ChangeServiceConfig2A failed\n");
1999     if (!ret) {
2000         goto cleanup;
2001     }
2002
2003     SetLastError(0xdeadbeef);
2004     needed = 0;
2005     expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
2006     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
2007     ok(!ret, "expected QueryServiceConfig2A to fail\n");
2008     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2009     ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
2010
2011     SetLastError(0xdeadbeef);
2012     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
2013     ok(!ret, "expected QueryServiceConfig2A to fail\n");
2014     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2015
2016     SetLastError(0xdeadbeef);
2017     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
2018     ok(ret, "expected QueryServiceConfig2A to succeed\n");
2019     ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
2020         "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
2021
2022     SetLastError(0xdeadbeef);
2023     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
2024     ok(ret, "expected QueryServiceConfig2A to succeed\n");
2025     ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
2026         "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
2027
2028     if(!pQueryServiceConfig2W)
2029     {
2030         win_skip("function QueryServiceConfig2W not present\n");
2031         goto cleanup;
2032     }
2033     SetLastError(0xdeadbeef);
2034     needed = 0;
2035     expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
2036     ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
2037     ok(!ret, "expected QueryServiceConfig2W to fail\n");
2038     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
2039     ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
2040
2041     SetLastError(0xdeadbeef);
2042     ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
2043     ok(ret, "expected QueryServiceConfig2W to succeed\n");
2044
2045 cleanup:
2046     DeleteService(svc_handle);
2047
2048     CloseServiceHandle(svc_handle);
2049
2050     /* Wait a while. The following test does a CreateService again */
2051     Sleep(1000);
2052
2053     CloseServiceHandle(scm_handle);
2054 }
2055
2056 static void test_refcount(void)
2057 {
2058     SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
2059     static const CHAR servicename         [] = "Winetest";
2060     static const CHAR pathname            [] = "we_dont_care.exe";
2061     BOOL ret;
2062
2063     /* Get a handle to the Service Control Manager */
2064     SetLastError(0xdeadbeef);
2065     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2066     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
2067     {
2068         skip("Not enough rights to get a handle to the manager\n");
2069         return;
2070     }
2071
2072     /* Create a service */
2073     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2074                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2075                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2076     ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError());
2077
2078     /* Get a handle to this new service */
2079     svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2080     ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError());
2081
2082     /* Get another handle to this new service */
2083     svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
2084     ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError());
2085
2086     /* Check if we can close the handle to the Service Control Manager */
2087     ret = CloseServiceHandle(scm_handle);
2088     ok(ret, "Expected success (err=%d)\n", GetLastError());
2089
2090     /* Get a new handle to the Service Control Manager */
2091     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2092     ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError());
2093
2094     /* Get a handle to this new service */
2095     svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
2096     ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError());
2097
2098     /* Delete the service */
2099     ret = DeleteService(svc_handle4);
2100     ok(ret, "Expected success (err=%d)\n", GetLastError());
2101
2102     /* We cannot create the same service again as it's still marked as 'being deleted'.
2103      * The reason is that we still have 4 open handles to this service even though we
2104      * closed the handle to the Service Control Manager in between.
2105      */
2106     SetLastError(0xdeadbeef);
2107     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2108                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2109                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2110     todo_wine
2111     {
2112     ok(!svc_handle5, "Expected failure\n");
2113     ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
2114        "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2115     }
2116
2117     /* FIXME: Remove this when Wine is fixed */
2118     if (svc_handle5)
2119     {
2120         DeleteService(svc_handle5);
2121         CloseServiceHandle(svc_handle5);
2122     }
2123
2124     /* Close all the handles to the service and try again */
2125     ret = CloseServiceHandle(svc_handle4);
2126     ok(ret, "Expected success (err=%d)\n", GetLastError());
2127     ret = CloseServiceHandle(svc_handle3);
2128     ok(ret, "Expected success (err=%d)\n", GetLastError());
2129     ret = CloseServiceHandle(svc_handle2);
2130     ok(ret, "Expected success (err=%d)\n", GetLastError());
2131     ret = CloseServiceHandle(svc_handle1);
2132     ok(ret, "Expected success (err=%d)\n", GetLastError());
2133
2134     /* Wait a while. Doing a CreateService too soon will result again
2135      * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2136      */
2137     Sleep(1000);
2138
2139     /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2140     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
2141                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
2142                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
2143     ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError());
2144
2145     /* Delete the service */
2146     ret = DeleteService(svc_handle5);
2147     ok(ret, "Expected success (err=%d)\n", GetLastError());
2148
2149     /* Wait a while. Just in case one of the following tests does a CreateService again */
2150     Sleep(1000);
2151
2152     CloseServiceHandle(svc_handle5);
2153     CloseServiceHandle(scm_handle);
2154 }
2155
2156 START_TEST(service)
2157 {
2158     SC_HANDLE scm_handle;
2159
2160     /* Bail out if we are on win98 */
2161     SetLastError(0xdeadbeef);
2162     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2163
2164     if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2165     {
2166         win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2167         return;
2168     }
2169     CloseServiceHandle(scm_handle);
2170
2171     init_function_pointers();
2172
2173     /* First some parameter checking */
2174     test_open_scm();
2175     test_open_svc();
2176     test_create_delete_svc();
2177     test_get_displayname();
2178     test_get_servicekeyname();
2179     test_query_svc();
2180     test_enum_svc();
2181     test_close();
2182     /* Test the creation, querying and deletion of a service */
2183     test_sequence();
2184     test_queryconfig2();
2185     /* The main reason for this test is to check if any refcounting is used
2186      * and what the rules are
2187      */
2188     test_refcount();
2189 }