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