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