advapi32: Fix test under w2k8.
[wine] / dlls / advapi32 / tests / service.c
1 /*
2  * Unit tests for service functions
3  *
4  * Copyright (c) 2007 Paul Vriens
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
28 #include "winsvc.h"
29 #include "winnls.h"
30 #include "lmcons.h"
31
32 #include "wine/test.h"
33
34 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
35
36 static void test_open_scm(void)
37 {
38     SC_HANDLE scm_handle;
39
40     /* No access rights */
41     SetLastError(0xdeadbeef);
42     scm_handle = OpenSCManagerA(NULL, NULL, 0);
43     ok(scm_handle != NULL, "Expected success\n");
44     ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
45        GetLastError() == 0xdeadbeef       /* NT4, XP */ ||
46        GetLastError() == ERROR_IO_PENDING /* W2K */,
47        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
48     CloseServiceHandle(scm_handle);
49
50     /* Unknown database name */
51     SetLastError(0xdeadbeef);
52     scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
53     ok(!scm_handle, "Expected failure\n");
54     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
55     CloseServiceHandle(scm_handle); /* Just in case */
56
57     /* MSDN says only ServiceActive is allowed, or NULL */
58     SetLastError(0xdeadbeef);
59     scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
60     ok(!scm_handle, "Expected failure\n");
61     ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
62     CloseServiceHandle(scm_handle); /* Just in case */
63
64     /* Remote unknown host */
65     SetLastError(0xdeadbeef);
66     scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
67     ok(!scm_handle, "Expected failure\n");
68     todo_wine
69     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */,
70        "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
71     CloseServiceHandle(scm_handle); /* Just in case */
72
73     /* Proper call with an empty hostname */
74     SetLastError(0xdeadbeef);
75     scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
76     ok(scm_handle != NULL, "Expected success\n");
77     ok(GetLastError() == ERROR_SUCCESS          /* W2K3, Vista */ ||
78        GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
79        GetLastError() == 0xdeadbeef             /* XP */ ||
80        GetLastError() == ERROR_IO_PENDING       /* W2K */,
81        "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
82     CloseServiceHandle(scm_handle);
83
84     /* Again a correct one */
85     SetLastError(0xdeadbeef);
86     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
87     ok(scm_handle != NULL, "Expected success\n");
88     ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
89        GetLastError() == 0xdeadbeef       /* NT4, XP */ ||
90        GetLastError() == ERROR_IO_PENDING /* W2K */,
91        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
92     CloseServiceHandle(scm_handle);
93 }
94
95 static void test_open_svc(void)
96 {
97     SC_HANDLE scm_handle, svc_handle;
98     CHAR displayname[4096];
99     DWORD displaysize;
100
101     /* All NULL (invalid access rights) */
102     SetLastError(0xdeadbeef);
103     svc_handle = OpenServiceA(NULL, NULL, 0);
104     ok(!svc_handle, "Expected failure\n");
105     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
106
107     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
108
109     /* NULL service */
110     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
111     SetLastError(0xdeadbeef);
112     svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
113     ok(!svc_handle, "Expected failure\n");
114     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
115        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
116        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
117
118     /* Nonexistent service */
119     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
120     SetLastError(0xdeadbeef);
121     svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
122     ok(!svc_handle, "Expected failure\n");
123     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
124     CloseServiceHandle(scm_handle);
125
126     /* Proper SCM handle but different access rights */
127     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
128     SetLastError(0xdeadbeef);
129     svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
130     if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
131         skip("Not enough rights to get a handle to the service\n");
132     else
133     {
134         ok(svc_handle != NULL, "Expected success\n");
135         ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
136            GetLastError() == ERROR_IO_PENDING /* W2K */ ||
137            GetLastError() == 0xdeadbeef       /* XP, NT4 */,
138            "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
139         CloseServiceHandle(svc_handle);
140     }
141
142     /* Test to show we can't open a service with the displayname */
143
144     /* Retrieve the needed size for the buffer */
145     displaysize = 0;
146     GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
147     /* Get the displayname */
148     GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
149     /* Try to open the service with this displayname, unless the displayname equals
150      * the servicename as that would defeat the purpose of this test.
151      */
152     if (!lstrcmpi(spooler, displayname))
153     {
154         skip("displayname equals servicename\n");
155         CloseServiceHandle(scm_handle);
156         return;
157     }
158
159     SetLastError(0xdeadbeef);
160     svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ);
161     ok(!svc_handle, "Expected failure\n");
162     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
163     /* Just in case */
164     CloseServiceHandle(svc_handle);
165
166     CloseServiceHandle(scm_handle);
167 }
168
169 static void test_create_delete_svc(void)
170 {
171     SC_HANDLE scm_handle, svc_handle1;
172     CHAR username[UNLEN + 1], domain[MAX_PATH];
173     DWORD user_size = UNLEN + 1;
174     CHAR account[UNLEN + 3];
175     static const CHAR servicename         [] = "Winetest";
176     static const CHAR pathname            [] = "we_dont_care.exe";
177     static const CHAR empty               [] = "";
178     static const CHAR password            [] = "secret";
179     BOOL spooler_exists = FALSE;
180     BOOL ret;
181     CHAR display[4096];
182     DWORD display_size = sizeof(display);
183
184     /* Get the username and turn it into an account to be used in some tests */
185     GetUserNameA(username, &user_size);
186     /* Get the domainname to cater for that situation */
187     if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH))
188         sprintf(account, "%s\\%s", domain, username);
189     else
190         sprintf(account, ".\\%s", username);
191
192     /* All NULL */
193     SetLastError(0xdeadbeef);
194     svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
195     ok(!svc_handle1, "Expected failure\n");
196     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
197
198     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
199
200     /* Only a valid handle to the Service Control Manager */
201     SetLastError(0xdeadbeef);
202     svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
203     ok(!svc_handle1, "Expected failure\n");
204     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
205        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
206        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
207
208     /* Now with a servicename */
209     SetLastError(0xdeadbeef);
210     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);
211     ok(!svc_handle1, "Expected failure\n");
212     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
213        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
214        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
215
216     /* Or just a binary name */
217     SetLastError(0xdeadbeef);
218     svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
219     ok(!svc_handle1, "Expected failure\n");
220     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, W2K3, XP, Vista */ ||
221        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
222        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
223
224     /* Both servicename and binary name (We only have connect rights) */
225     SetLastError(0xdeadbeef);
226     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
227     ok(!svc_handle1, "Expected failure\n");
228     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
229
230     /* They can even be empty at this stage of parameter checking */
231     SetLastError(0xdeadbeef);
232     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
233     ok(!svc_handle1, "Expected failure\n");
234     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
235
236     SetLastError(0xdeadbeef);
237     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
238     ok(!svc_handle1, "Expected failure\n");
239     ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
240
241     /* Open the Service Control Manager with minimal rights for creation
242      * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
243      */
244     CloseServiceHandle(scm_handle);
245     SetLastError(0xdeadbeef);
246     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
247     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
248     {
249         skip("Not enough rights to get a handle to the manager\n");
250         return;
251     }
252
253     /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
254
255     /* Empty strings for servicename and binary name are checked */
256     SetLastError(0xdeadbeef);
257     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL);
258     ok(!svc_handle1, "Expected failure\n");
259     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
260
261     SetLastError(0xdeadbeef);
262     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
263     ok(!svc_handle1, "Expected failure\n");
264     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
265
266     SetLastError(0xdeadbeef);
267     svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL);
268     ok(!svc_handle1, "Expected failure\n");
269     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
270
271     /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
272      * an ERROR_INVALID_PARAMETER)
273      */
274     SetLastError(0xdeadbeef);
275     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
276                                  SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL);
277     ok(!svc_handle1, "Expected failure\n");
278     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
279
280     /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
281
282     /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
283      * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
284      */
285     SetLastError(0xdeadbeef);
286     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS,
287                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
288     ok(!svc_handle1, "Expected failure\n");
289     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
290
291     /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
292     SetLastError(0xdeadbeef);
293     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS,
294                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
295     ok(!svc_handle1, "Expected failure\n");
296     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
297
298     /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
299      * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
300      */
301     SetLastError(0xdeadbeef);
302     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
303                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password);
304     ok(!svc_handle1, "Expected failure\n");
305     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
306
307     /* Illegal (start-type is not a mask and should only be one of the possibilities)
308      * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
309      * it's most likely not the wanted start-type)
310      */
311     SetLastError(0xdeadbeef);
312     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS,
313                                  SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
314     ok(!svc_handle1, "Expected failure\n");
315     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
316
317     /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
318     SetLastError(0xdeadbeef);
319     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
320                                  SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL);
321     ok(!svc_handle1, "Expected failure\n");
322     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
323
324     /* The service already exists (check first, just in case) */
325     svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
326     if (svc_handle1)
327     {
328         spooler_exists = TRUE;
329         CloseServiceHandle(svc_handle1);
330         SetLastError(0xdeadbeef);
331         svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS,
332                                      SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
333         ok(!svc_handle1, "Expected failure\n");
334         ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
335     }
336     else
337         skip("Spooler service doesn't exist\n");
338
339     /* To find an existing displayname we check the 'Spooler' service. Although the registry
340      * doesn't show DisplayName on NT4, this call will return a displayname which is equal
341      * to the servicename and can't be used as well for a new displayname.
342      */
343     if (spooler_exists)
344     {
345         ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
346
347         if (!ret)
348             skip("Could not retrieve a displayname for the Spooler service\n");
349         else
350         {
351             svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS,
352                                          SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
353             ok(!svc_handle1, "Expected failure\n");
354             ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME,
355                "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
356         }
357     }
358     else
359         skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
360
361     /* Windows doesn't care about the access rights for creation (which makes
362      * sense as there is no service yet) as long as there are sufficient
363      * rights to the manager.
364      */
365     SetLastError(0xdeadbeef);
366     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
367                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
368     ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError());
369     ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
370        GetLastError() == 0xdeadbeef       /* NT4, XP */ ||
371        GetLastError() == ERROR_IO_PENDING /* W2K */,
372        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
373
374     /* DeleteService however must have proper rights */
375     SetLastError(0xdeadbeef);
376     ret = DeleteService(svc_handle1);
377     ok(!ret, "Expected failure\n");
378     ok(GetLastError() == ERROR_ACCESS_DENIED,
379        "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
380
381     /* Open the service with minimal rights for deletion.
382      * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
383      */
384     CloseServiceHandle(svc_handle1);
385     svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
386
387     /* Now that we have the proper rights, we should be able to delete */
388     SetLastError(0xdeadbeef);
389     ret = DeleteService(svc_handle1);
390     ok(ret, "Expected success\n");
391     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
392        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */ ||
393        GetLastError() == ERROR_IO_PENDING /* W2K */,
394        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
395
396     CloseServiceHandle(svc_handle1);
397
398     CloseServiceHandle(scm_handle);
399
400     /* Wait a while. One of the following tests also does a CreateService for the
401      * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
402      * error if we do this to quick. Vista seems more picky then the others.
403      */
404     Sleep(1000);
405
406     /* And a final NULL check */
407     SetLastError(0xdeadbeef);
408     ret = DeleteService(NULL);
409     ok(!ret, "Expected failure\n");
410     ok(GetLastError() == ERROR_INVALID_HANDLE,
411         "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
412 }
413
414 static void test_get_displayname(void)
415 {
416     SC_HANDLE scm_handle, svc_handle;
417     BOOL ret;
418     CHAR displayname[4096];
419     WCHAR displaynameW[2048];
420     DWORD displaysize, tempsize, tempsizeW;
421     static const CHAR deadbeef[] = "Deadbeef";
422     static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0};
423     static const CHAR servicename[] = "Winetest";
424     static const CHAR pathname[] = "we_dont_care.exe";
425
426     /* Having NULL for the size of the buffer will crash on W2K3 */
427
428     SetLastError(0xdeadbeef);
429     ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize);
430     ok(!ret, "Expected failure\n");
431     ok(GetLastError() == ERROR_INVALID_HANDLE,
432        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
433
434     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
435
436     SetLastError(0xdeadbeef);
437     ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize);
438     ok(!ret, "Expected failure\n");
439     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
440        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
441        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
442
443     SetLastError(0xdeadbeef);
444     displaysize = sizeof(displayname);
445     ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize);
446     ok(!ret, "Expected failure\n");
447     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
448        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
449        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
450
451     /* Test for nonexistent service */
452     SetLastError(0xdeadbeef);
453     displaysize = -1;
454     ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize);
455     ok(!ret, "Expected failure\n");
456     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
457        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
458
459     /* Check if 'Spooler' exists */
460     svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
461     if (!svc_handle)
462     {
463         skip("Spooler service doesn't exist\n");
464         CloseServiceHandle(scm_handle);
465         return;
466     }
467     CloseServiceHandle(svc_handle);
468
469     /* Retrieve the needed size for the buffer */
470     SetLastError(0xdeadbeef);
471     displaysize = -1;
472     ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
473     ok(!ret, "Expected failure\n");
474     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
475        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
476     tempsize = displaysize;
477
478     displaysize = 0;
479     ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
480     ok(!ret, "Expected failure\n");
481     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
482        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
483     ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize);
484
485     /* Buffer is too small */
486     SetLastError(0xdeadbeef);
487     displaysize = (tempsize / 2);
488     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
489     ok(!ret, "Expected failure\n");
490     ok(displaysize == tempsize, "Expected the needed buffersize\n");
491     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
492        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
493
494     /* First try with a buffer that should be big enough to hold
495      * the ANSI string (and terminating character). This succeeds on Windows
496      *  although when asked (see above 2 tests) it will return twice the needed size.
497      */
498     SetLastError(0xdeadbeef);
499     displaysize = (tempsize / 2) + 1;
500     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
501     ok(ret, "Expected success\n");
502     ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n");
503     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
504        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
505        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
506        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
507
508     /* Now with the original returned size */
509     SetLastError(0xdeadbeef);
510     displaysize = tempsize;
511     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
512     ok(ret, "Expected success\n");
513     ok(displaysize == tempsize, "Expected no change for the needed buffer size\n");
514     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
515        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
516        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
517        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
518
519     /* And with a bigger than needed buffer */
520     SetLastError(0xdeadbeef);
521     displaysize = tempsize * 2;
522     ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
523     ok(ret, "Expected success\n");
524     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
525        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
526        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
527        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
528     /* Test that shows that if the buffersize is enough, it's not changed */
529     ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n");
530     ok(lstrlen(displayname) == tempsize/2,
531        "Expected the buffer to be twice the length of the string\n") ;
532
533     /* Do the buffer(size) tests also for GetServiceDisplayNameW */
534     SetLastError(0xdeadbeef);
535     displaysize = -1;
536     ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize);
537     ok(!ret, "Expected failure\n");
538     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
539        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
540
541     /* Buffer is too small */
542     SetLastError(0xdeadbeef);
543     tempsizeW = displaysize;
544     displaysize = tempsizeW / 2;
545     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
546     ok(!ret, "Expected failure\n");
547     ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
548     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
549        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
550
551     /* Now with the original returned size */
552     SetLastError(0xdeadbeef);
553     displaysize = tempsizeW;
554     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
555     ok(!ret, "Expected failure\n");
556     ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
557     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
558        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
559
560     /* And with a bigger than needed buffer */
561     SetLastError(0xdeadbeef);
562     displaysize = tempsizeW + 1; /* This caters for the null terminating character */
563     ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
564     ok(ret, "Expected success\n");
565     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
566        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
567        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
568        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
569     ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
570     ok(lstrlenW(displaynameW) == displaysize,
571        "Expected the buffer to be the length of the string\n") ;
572     ok(tempsize / 2 == tempsizeW,
573        "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
574
575     CloseServiceHandle(scm_handle);
576
577     /* Test for a service without a displayname (which is valid). This should return
578      * the servicename itself.
579      */
580     SetLastError(0xdeadbeef);
581     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
582     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
583     {
584         skip("Not enough rights to get a handle to the manager\n");
585         return;
586     }
587
588     SetLastError(0xdeadbeef);
589     svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE,
590                                 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
591                                 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
592     ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
593     if (!svc_handle)
594     {
595         CloseServiceHandle(scm_handle);
596         return;
597     }
598
599     /* Retrieve the needed size for the buffer */
600     SetLastError(0xdeadbeef);
601     displaysize = -1;
602     ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize);
603     ok(!ret, "Expected failure\n");
604     ok(displaysize == lstrlen(servicename) * 2,
605        "Expected the displaysize to be twice the size of the servicename\n");
606     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
607        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
608
609     /* Buffer is too small */
610     SetLastError(0xdeadbeef);
611     tempsize = displaysize;
612     displaysize = (tempsize / 2);
613     ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
614     ok(!ret, "Expected failure\n");
615     ok(displaysize == tempsize, "Expected the needed buffersize\n");
616     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
617        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
618
619     /* Get the displayname */
620     SetLastError(0xdeadbeef);
621     ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize);
622     ok(ret, "Expected success\n");
623     ok(!lstrcmpi(displayname, servicename),
624        "Expected displayname to be %s, got %s\n", servicename, displayname);
625     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
626        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
627        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
628        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
629
630     /* Delete the service */
631     ret = DeleteService(svc_handle);
632     ok(ret, "Expected success\n");
633
634     CloseServiceHandle(svc_handle);
635     CloseServiceHandle(scm_handle);
636
637     /* Wait a while. Just in case one of the following tests does a CreateService again */
638     Sleep(1000);
639 }
640
641 static void test_get_servicekeyname(void)
642 {
643     SC_HANDLE scm_handle, svc_handle;
644     CHAR servicename[4096];
645     CHAR displayname[4096];
646     WCHAR servicenameW[4096];
647     WCHAR displaynameW[4096];
648     DWORD servicesize, displaysize, tempsize;
649     BOOL ret;
650     static const CHAR deadbeef[] = "Deadbeef";
651     static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0};
652
653     /* Having NULL for the size of the buffer will crash on W2K3 */
654
655     SetLastError(0xdeadbeef);
656     ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize);
657     ok(!ret, "Expected failure\n");
658     ok(GetLastError() == ERROR_INVALID_HANDLE,
659        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
660
661     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
662
663     servicesize = 200;
664     SetLastError(0xdeadbeef);
665     ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize);
666     ok(!ret, "Expected failure\n");
667     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
668        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
669        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
670     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
671
672     /* Valid handle and buffer but no displayname */
673     servicesize = 200;
674     SetLastError(0xdeadbeef);
675     ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize);
676     ok(!ret, "Expected failure\n");
677     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
678        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
679        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
680     todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize);
681
682     /* Test for nonexistent displayname */
683     SetLastError(0xdeadbeef);
684     ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &servicesize);
685     ok(!ret, "Expected failure\n");
686     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST,
687        "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
688     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
689
690     servicesize = 15;
691     strcpy(servicename, "ABC");
692     ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
693     ok(!ret, "Expected failure\n");
694     todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
695     ok(servicename[0] == 0, "Service name not empty\n");
696
697     servicesize = 15;
698     servicenameW[0] = 'A';
699     ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
700     ok(!ret, "Expected failure\n");
701     todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize);
702     ok(servicenameW[0] == 0, "Service name not empty\n");
703
704     servicesize = 0;
705     strcpy(servicename, "ABC");
706     ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize);
707     ok(!ret, "Expected failure\n");
708     todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize);
709     ok(servicename[0] == 'A', "Service name changed\n");
710
711     servicesize = 0;
712     servicenameW[0] = 'A';
713     ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize);
714     ok(!ret, "Expected failure\n");
715     todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize);
716     ok(servicenameW[0] == 'A', "Service name changed\n");
717
718     /* Check if 'Spooler' exists */
719     svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
720     if (!svc_handle)
721     {
722         skip("Spooler service doesn't exist\n");
723         CloseServiceHandle(scm_handle);
724         return;
725     }
726     CloseServiceHandle(svc_handle);
727
728     /* Get the displayname for the 'Spooler' service */
729     GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
730     GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
731
732     /* Retrieve the needed size for the buffer */
733     SetLastError(0xdeadbeef);
734     servicesize = 0;
735     ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize);
736     ok(!ret, "Expected failure\n");
737     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
738        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
739
740     /* Valid call with the correct buffersize */
741     SetLastError(0xdeadbeef);
742     tempsize = servicesize;
743     servicesize *= 2;
744     ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
745     ok(ret, "Expected success\n");
746     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
747        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
748        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
749        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
750     if (ret)
751     {
752         ok(lstrlen(servicename) == tempsize/2,
753            "Expected the buffer to be twice the length of the string\n") ;
754         ok(!lstrcmpi(servicename, spooler), "Expected %s, got %s\n", spooler, servicename);
755         ok(servicesize == (tempsize * 2),
756            "Expected servicesize not to change if buffer not insufficient\n") ;
757     }
758
759     MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
760     SetLastError(0xdeadbeef);
761     servicesize *= 2;
762     ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
763     ok(ret, "Expected success\n");
764     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
765        GetLastError() == ERROR_IO_PENDING /* W2K */ ||
766        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
767        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
768     if (ret)
769     {
770         ok(lstrlen(servicename) == tempsize/2,
771            "Expected the buffer to be twice the length of the string\n") ;
772         ok(servicesize == lstrlenW(servicenameW),
773            "Expected servicesize not to change if buffer not insufficient\n") ;
774     }
775
776     SetLastError(0xdeadbeef);
777     servicesize = 3;
778     ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
779     ok(!ret, "Expected failure\n");
780     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
781        "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
782     ok(servicenameW[0] == 0, "Buffer not empty\n");
783
784     CloseServiceHandle(scm_handle);
785 }
786
787 static void test_close(void)
788 {
789     SC_HANDLE handle;
790     BOOL ret;
791
792     /* NULL handle */
793     SetLastError(0xdeadbeef);
794     ret = CloseServiceHandle(NULL);
795     ok(!ret, "Expected failure\n");
796     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
797
798     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
799
800     /* Proper call */
801     handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
802     SetLastError(0xdeadbeef);
803     ret = CloseServiceHandle(handle);
804     ok(ret, "Expected success\n");
805     ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
806        GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
807        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
808        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
809 }
810
811 static void test_sequence(void)
812 {
813     SC_HANDLE scm_handle, svc_handle;
814     BOOL ret;
815     QUERY_SERVICE_CONFIGA *config;
816     DWORD given, needed;
817     static const CHAR servicename [] = "Winetest";
818     static const CHAR displayname [] = "Winetest dummy service";
819     static const CHAR displayname2[] = "Winetest dummy service (2)";
820     static const CHAR pathname    [] = "we_dont_care.exe";
821     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
822     static const CHAR password    [] = "";
823     static const CHAR empty       [] = "";
824     static const CHAR localsystem [] = "LocalSystem";
825
826     SetLastError(0xdeadbeef);
827     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
828
829     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
830     {
831         skip("Not enough rights to get a handle to the manager\n");
832         return;
833     }
834     else
835         ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
836
837     if (!scm_handle) return;
838
839     /* Create a dummy service */
840     SetLastError(0xdeadbeef);
841     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
842         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
843         pathname, NULL, NULL, dependencies, NULL, password);
844
845     if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
846     {
847         /* We try and open the service and do the rest of the tests. Some could
848          * fail if the tests were changed between these runs.
849          */
850         trace("Deletion probably didn't work last time\n");
851         SetLastError(0xdeadbeef);
852         svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
853         if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
854         {
855             skip("Not enough rights to open the service\n");
856             CloseServiceHandle(scm_handle);        
857             return;
858         }
859         ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
860     }
861     else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
862     {
863         skip("Not enough rights to create the service\n");
864         CloseServiceHandle(scm_handle);        
865         return;
866     }
867     else
868         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
869
870     if (!svc_handle) return;
871
872     /* TODO:
873      * Before we do a QueryServiceConfig we should check the registry. This will make sure
874      * that the correct keys are used.
875      */
876
877     /* Request the size for the buffer */
878     SetLastError(0xdeadbeef);
879     ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
880     ok(!ret, "Expected failure\n");
881     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
882
883     config = HeapAlloc(GetProcessHeap(), 0, needed);
884     given = needed;
885     SetLastError(0xdeadbeef);
886     ret = QueryServiceConfigA(svc_handle, config, given, &needed);
887     ok(ret, "Expected success\n");
888     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */||
889        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */ ||
890        GetLastError() == ERROR_IO_PENDING /* W2K */,
891         "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
892     todo_wine
893     {
894     ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
895     }
896     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
897         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
898     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
899         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
900     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
901     ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
902     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
903     ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
904     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
905     /* TODO: Show the double 0 terminated string */
906     todo_wine
907     {
908     ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
909     }
910     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
911     ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
912     
913     ok(ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", NULL, NULL, NULL, NULL, displayname2),
914         "ChangeServiceConfig failed (err=%d)\n", GetLastError());
915
916     QueryServiceConfigA(svc_handle, NULL, 0, &needed);
917     config = HeapReAlloc(GetProcessHeap(), 0, config, needed);
918     ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n");
919     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
920         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
921     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
922         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
923     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
924     ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl);
925     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
926     ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup);
927     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
928     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
929     ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName);
930
931     SetLastError(0xdeadbeef);
932     ret = DeleteService(svc_handle);
933     ok(ret, "Expected success\n");
934     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */||
935        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */ ||
936        GetLastError() == ERROR_IO_PENDING /* W2K */,
937         "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
938     
939     CloseServiceHandle(svc_handle);
940
941     /* Wait a while. The following test does a CreateService again */
942     Sleep(1000);
943
944     CloseServiceHandle(scm_handle);
945     HeapFree(GetProcessHeap(), 0, config);
946 }
947
948 static void test_queryconfig2(void)
949 {
950     SC_HANDLE scm_handle, svc_handle;
951     BOOL ret;
952     DWORD expected, needed;
953     BYTE buffer[MAX_PATH];
954     LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
955     static const CHAR servicename [] = "Winetest";
956     static const CHAR displayname [] = "Winetest dummy service";
957     static const CHAR pathname    [] = "we_dont_care.exe";
958     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0";
959     static const CHAR password    [] = "";
960     static const CHAR description [] = "Description";
961     HMODULE dllhandle = GetModuleHandleA("advapi32.dll");
962     BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID)
963             = (void*)GetProcAddress(dllhandle, "ChangeServiceConfig2A");
964     BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
965             = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2A");
966     BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD)
967             = (void*)GetProcAddress(dllhandle, "QueryServiceConfig2W");
968     if(!pQueryServiceConfig2A)
969     {
970         skip("function QueryServiceConfig2A not present\n");
971         return;
972     }
973
974     SetLastError(0xdeadbeef);
975     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
976
977     if (!scm_handle)
978     {
979         if(GetLastError() == ERROR_ACCESS_DENIED)
980             skip("Not enough rights to get a handle to the manager\n");
981         else
982             ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
983         return;
984     }
985
986     /* Create a dummy service */
987     SetLastError(0xdeadbeef);
988     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
989         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
990         pathname, NULL, NULL, dependencies, NULL, password);
991
992     if (!svc_handle)
993     {
994         if(GetLastError() == ERROR_SERVICE_EXISTS)
995         {
996             /* We try and open the service and do the rest of the tests. Some could
997              * fail if the tests were changed between these runs.
998              */
999             trace("Deletion probably didn't work last time\n");
1000             SetLastError(0xdeadbeef);
1001             svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1002             if (!svc_handle)
1003             {
1004                 if(GetLastError() == ERROR_ACCESS_DENIED)
1005                     skip("Not enough rights to open the service\n");
1006                 else
1007                     ok(FALSE, "Could not open the service : %d\n", GetLastError());
1008                 CloseServiceHandle(scm_handle);
1009                 return;
1010             }
1011         }
1012         if (GetLastError() == ERROR_ACCESS_DENIED)
1013         {
1014             skip("Not enough rights to create the service\n");
1015             CloseServiceHandle(scm_handle);
1016             return;
1017         }
1018         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1019         if (!svc_handle)
1020         {
1021             CloseServiceHandle(scm_handle);
1022             return;
1023         }
1024     }
1025     SetLastError(0xdeadbeef);
1026     ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1027     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1028     ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1029
1030     SetLastError(0xdeadbeef);
1031     ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1032     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1033     ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1034
1035     SetLastError(0xdeadbeef);
1036     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL);
1037     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1038     ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1039
1040     SetLastError(0xdeadbeef);
1041     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed);
1042     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1043     ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()),
1044        "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1045
1046     SetLastError(0xdeadbeef);
1047     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL);
1048     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1049     ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1050
1051     needed = 0;
1052     SetLastError(0xdeadbeef);
1053     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed);
1054     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1055     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1056     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1057
1058     needed = 0;
1059     pConfig->lpDescription = (LPSTR)0xdeadbeef;
1060     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1061     ok(ret, "expected QueryServiceConfig2A to succeed\n");
1062     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1063     ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription);
1064
1065     SetLastError(0xdeadbeef);
1066     needed = 0;
1067     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1068     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1069     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1070     ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed);
1071
1072     if(!pChangeServiceConfig2A)
1073     {
1074         skip("function ChangeServiceConfig2A not present\n");
1075         goto cleanup;
1076     }
1077
1078     pConfig->lpDescription = (LPSTR) description;
1079     ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1080     ok(ret, "ChangeServiceConfig2A failed\n");
1081     if (!ret) {
1082         goto cleanup;
1083     }
1084
1085     SetLastError(0xdeadbeef);
1086     needed = 0;
1087     expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */
1088     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed);
1089     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1090     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1091     ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1092
1093     SetLastError(0xdeadbeef);
1094     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed);
1095     ok(!ret, "expected QueryServiceConfig2A to fail\n");
1096     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1097
1098     SetLastError(0xdeadbeef);
1099     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed);
1100     ok(ret, "expected QueryServiceConfig2A to succeed\n");
1101     ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1102         "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1103
1104     SetLastError(0xdeadbeef);
1105     ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed);
1106     ok(ret, "expected QueryServiceConfig2A to succeed\n");
1107     ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription),
1108         "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription);
1109
1110     if(!pQueryServiceConfig2W)
1111     {
1112         skip("function QueryServiceConfig2W not present\n");
1113         goto cleanup;
1114     }
1115     SetLastError(0xdeadbeef);
1116     needed = 0;
1117     expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description);
1118     ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed);
1119     ok(!ret, "expected QueryServiceConfig2W to fail\n");
1120     ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1121     ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed);
1122
1123     SetLastError(0xdeadbeef);
1124     ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1125     ok(ret, "expected QueryServiceConfig2W to succeed\n");
1126
1127 cleanup:
1128     DeleteService(svc_handle);
1129
1130     CloseServiceHandle(svc_handle);
1131
1132     /* Wait a while. The following test does a CreateService again */
1133     Sleep(1000);
1134
1135     CloseServiceHandle(scm_handle);
1136 }
1137
1138 static void test_refcount(void)
1139 {
1140     SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
1141     static const CHAR servicename         [] = "Winetest";
1142     static const CHAR pathname            [] = "we_dont_care.exe";
1143     BOOL ret;
1144
1145     /* Get a handle to the Service Control Manager */
1146     SetLastError(0xdeadbeef);
1147     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1148     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1149     {
1150         skip("Not enough rights to get a handle to the manager\n");
1151         return;
1152     }
1153
1154     /* Create a service */
1155     svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1156                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1157                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1158     ok(svc_handle1 != NULL, "Expected success\n");
1159
1160     /* Get a handle to this new service */
1161     svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1162     ok(svc_handle2 != NULL, "Expected success\n");
1163
1164     /* Get another handle to this new service */
1165     svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
1166     ok(svc_handle3 != NULL, "Expected success\n");
1167
1168     /* Check if we can close the handle to the Service Control Manager */
1169     ret = CloseServiceHandle(scm_handle);
1170     ok(ret, "Expected success\n");
1171
1172     /* Get a new handle to the Service Control Manager */
1173     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1174     ok(scm_handle != NULL, "Expected success\n");
1175
1176     /* Get a handle to this new service */
1177     svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1178     ok(svc_handle4 != NULL, "Expected success\n");
1179
1180     /* Delete the service */
1181     ret = DeleteService(svc_handle4);
1182     ok(ret, "Expected success\n");
1183
1184     /* We cannot create the same service again as it's still marked as 'being deleted'.
1185      * The reason is that we still have 4 open handles to this service even though we
1186      * closed the handle to the Service Control Manager in between.
1187      */
1188     SetLastError(0xdeadbeef);
1189     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1190                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1191                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1192     todo_wine
1193     {
1194     ok(!svc_handle5, "Expected failure\n");
1195     ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
1196        "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1197     }
1198
1199     /* FIXME: Remove this when Wine is fixed */
1200     if (svc_handle5)
1201     {
1202         DeleteService(svc_handle5);
1203         CloseServiceHandle(svc_handle5);
1204     }
1205
1206     /* Close all the handles to the service and try again */
1207     ret = CloseServiceHandle(svc_handle4);
1208     ok(ret, "Expected success\n");
1209     ret = CloseServiceHandle(svc_handle3);
1210     ok(ret, "Expected success\n");
1211     ret = CloseServiceHandle(svc_handle2);
1212     ok(ret, "Expected success\n");
1213     ret = CloseServiceHandle(svc_handle1);
1214     ok(ret, "Expected success\n");
1215
1216     /* Wait a while. Doing a CreateService too soon will result again
1217      * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1218      */
1219     Sleep(1000);
1220
1221     /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1222     svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
1223                                  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
1224                                  SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
1225     ok(svc_handle5 != NULL, "Expected success\n");
1226
1227     /* Delete the service */
1228     ret = DeleteService(svc_handle5);
1229     ok(ret, "Expected success\n");
1230
1231     /* Wait a while. Just in case one of the following tests does a CreateService again */
1232     Sleep(1000);
1233
1234     CloseServiceHandle(svc_handle5);
1235     CloseServiceHandle(scm_handle);
1236 }
1237
1238 START_TEST(service)
1239 {
1240     SC_HANDLE scm_handle;
1241
1242     /* Bail out if we are on win98 */
1243     SetLastError(0xdeadbeef);
1244     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1245
1246     if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1247     {
1248         skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1249         return;
1250     }
1251     CloseServiceHandle(scm_handle);
1252
1253     /* First some parameter checking */
1254     test_open_scm();
1255     test_open_svc();
1256     test_create_delete_svc();
1257     test_get_displayname();
1258     test_get_servicekeyname();
1259     test_close();
1260     /* Test the creation, querying and deletion of a service */
1261     test_sequence();
1262     test_queryconfig2();
1263     /* The main reason for this test is to check if any refcounting is used
1264      * and what the rules are
1265      */
1266     test_refcount();
1267 }