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