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