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