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