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