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