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