2 * Unit tests for service functions
4 * Copyright (c) 2007 Paul Vriens
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.
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.
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
32 #include "wine/test.h"
34 static const CHAR spooler
[] = "Spooler"; /* Should be available on all platforms */
36 static void test_open_scm(void)
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
);
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 */
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 */
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");
69 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE
, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
70 CloseServiceHandle(scm_handle
); /* Just in case */
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
);
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
);
94 static void test_open_svc(void)
96 SC_HANDLE scm_handle
, svc_handle
;
97 CHAR displayname
[4096];
100 /* All NULL (invalid access rights) */
101 SetLastError(0xdeadbeef);
102 svc_handle
= OpenServiceA(NULL
, NULL
, 0);
103 ok(!svc_handle
, "Expected failure\n");
104 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
106 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
109 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
110 SetLastError(0xdeadbeef);
111 svc_handle
= OpenServiceA(scm_handle
, NULL
, GENERIC_READ
);
112 ok(!svc_handle
, "Expected failure\n");
113 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
114 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
115 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
117 /* Nonexistent service */
118 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
119 SetLastError(0xdeadbeef);
120 svc_handle
= OpenServiceA(scm_handle
, "deadbeef", GENERIC_READ
);
121 ok(!svc_handle
, "Expected failure\n");
122 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
123 CloseServiceHandle(scm_handle
);
125 /* Proper SCM handle but different access rights */
126 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
127 SetLastError(0xdeadbeef);
128 svc_handle
= OpenServiceA(scm_handle
, "Spooler", GENERIC_WRITE
);
129 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
130 skip("Not enough rights to get a handle to the service\n");
133 ok(svc_handle
!= NULL
, "Expected success\n");
134 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
135 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
136 GetLastError() == 0xdeadbeef /* XP, NT4 */,
137 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
138 CloseServiceHandle(svc_handle
);
141 /* Test to show we can't open a service with the displayname */
143 /* Retrieve the needed size for the buffer */
145 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
146 /* Get the displayname */
147 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
148 /* Try to open the service with this displayname, unless the displayname equals
149 * the servicename as that would defeat the purpose of this test.
151 if (!lstrcmpi(spooler
, displayname
))
153 skip("displayname equals servicename\n");
154 CloseServiceHandle(scm_handle
);
158 SetLastError(0xdeadbeef);
159 svc_handle
= OpenServiceA(scm_handle
, displayname
, GENERIC_READ
);
160 ok(!svc_handle
, "Expected failure\n");
161 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
163 CloseServiceHandle(svc_handle
);
165 CloseServiceHandle(scm_handle
);
168 static void test_create_delete_svc(void)
170 SC_HANDLE scm_handle
, svc_handle1
;
171 CHAR username
[UNLEN
+ 1], domain
[MAX_PATH
];
172 DWORD user_size
= UNLEN
+ 1;
173 CHAR account
[UNLEN
+ 3];
174 static const CHAR servicename
[] = "Winetest";
175 static const CHAR pathname
[] = "we_dont_care.exe";
176 static const CHAR empty
[] = "";
177 static const CHAR password
[] = "secret";
178 BOOL spooler_exists
= FALSE
;
181 DWORD display_size
= sizeof(display
);
183 /* Get the username and turn it into an account to be used in some tests */
184 GetUserNameA(username
, &user_size
);
185 /* Get the domainname to cater for that situation */
186 if (GetEnvironmentVariableA("USERDOMAIN", domain
, MAX_PATH
))
187 sprintf(account
, "%s\\%s", domain
, username
);
189 sprintf(account
, ".\\%s", username
);
192 SetLastError(0xdeadbeef);
193 svc_handle1
= CreateServiceA(NULL
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
194 ok(!svc_handle1
, "Expected failure\n");
195 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
197 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
199 /* Only a valid handle to the Service Control Manager */
200 SetLastError(0xdeadbeef);
201 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
202 ok(!svc_handle1
, "Expected failure\n");
203 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
204 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
205 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
207 /* Now with a servicename */
208 SetLastError(0xdeadbeef);
209 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
210 ok(!svc_handle1
, "Expected failure\n");
211 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
212 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
213 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
215 /* Or just a binary name */
216 SetLastError(0xdeadbeef);
217 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
218 ok(!svc_handle1
, "Expected failure\n");
219 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
220 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
221 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
223 /* Both servicename and binary name (We only have connect rights) */
224 SetLastError(0xdeadbeef);
225 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
226 ok(!svc_handle1
, "Expected failure\n");
227 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
229 /* They can even be empty at this stage of parameter checking */
230 SetLastError(0xdeadbeef);
231 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
232 ok(!svc_handle1
, "Expected failure\n");
233 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
235 SetLastError(0xdeadbeef);
236 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
237 ok(!svc_handle1
, "Expected failure\n");
238 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
240 /* Open the Service Control Manager with minimal rights for creation
241 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
243 CloseServiceHandle(scm_handle
);
244 SetLastError(0xdeadbeef);
245 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
246 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
248 skip("Not enough rights to get a handle to the manager\n");
252 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
254 /* Empty strings for servicename and binary name are checked */
255 SetLastError(0xdeadbeef);
256 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
257 ok(!svc_handle1
, "Expected failure\n");
258 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
260 SetLastError(0xdeadbeef);
261 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
262 ok(!svc_handle1
, "Expected failure\n");
263 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
265 SetLastError(0xdeadbeef);
266 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
267 ok(!svc_handle1
, "Expected failure\n");
268 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
270 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
271 * an ERROR_INVALID_PARAMETER)
273 SetLastError(0xdeadbeef);
274 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
275 SERVICE_DISABLED
, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
276 ok(!svc_handle1
, "Expected failure\n");
277 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
279 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
281 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
282 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
284 SetLastError(0xdeadbeef);
285 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
,
286 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
287 ok(!svc_handle1
, "Expected failure\n");
288 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
290 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
291 SetLastError(0xdeadbeef);
292 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_INTERACTIVE_PROCESS
,
293 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
294 ok(!svc_handle1
, "Expected failure\n");
295 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
297 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
298 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
300 SetLastError(0xdeadbeef);
301 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
302 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, account
, password
);
303 ok(!svc_handle1
, "Expected failure\n");
304 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
306 /* Illegal (start-type is not a mask and should only be one of the possibilities)
307 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
308 * it's most likely not the wanted start-type)
310 SetLastError(0xdeadbeef);
311 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
,
312 SERVICE_AUTO_START
| SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
313 ok(!svc_handle1
, "Expected failure\n");
314 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
316 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
317 SetLastError(0xdeadbeef);
318 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
319 SERVICE_BOOT_START
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
320 ok(!svc_handle1
, "Expected failure\n");
321 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
323 /* The service already exists (check first, just in case) */
324 svc_handle1
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
327 spooler_exists
= TRUE
;
328 CloseServiceHandle(svc_handle1
);
329 SetLastError(0xdeadbeef);
330 svc_handle1
= CreateServiceA(scm_handle
, spooler
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
331 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
332 ok(!svc_handle1
, "Expected failure\n");
333 ok(GetLastError() == ERROR_SERVICE_EXISTS
, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
336 skip("Spooler service doesn't exist\n");
338 /* To find an existing displayname we check the 'Spooler' service. Although the registry
339 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
340 * to the servicename and can't be used as well for a new displayname.
344 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, display
, &display_size
);
347 skip("Could not retrieve a displayname for the Spooler service\n");
350 svc_handle1
= CreateServiceA(scm_handle
, servicename
, display
, 0, SERVICE_WIN32_OWN_PROCESS
,
351 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
352 ok(!svc_handle1
, "Expected failure\n");
353 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME
,
354 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
358 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
360 /* Windows doesn't care about the access rights for creation (which makes
361 * sense as there is no service yet) as long as there are sufficient
362 * rights to the manager.
364 SetLastError(0xdeadbeef);
365 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
366 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
367 ok(svc_handle1
!= NULL
, "Could not create the service : %d\n", GetLastError());
368 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
369 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
370 GetLastError() == ERROR_IO_PENDING
/* W2K */,
371 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
373 /* DeleteService however must have proper rights */
374 SetLastError(0xdeadbeef);
375 ret
= DeleteService(svc_handle1
);
376 ok(!ret
, "Expected failure\n");
377 ok(GetLastError() == ERROR_ACCESS_DENIED
,
378 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
380 /* Open the service with minimal rights for deletion.
381 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
383 CloseServiceHandle(svc_handle1
);
384 svc_handle1
= OpenServiceA(scm_handle
, servicename
, DELETE
);
386 /* Now that we have the proper rights, we should be able to delete */
387 SetLastError(0xdeadbeef);
388 ret
= DeleteService(svc_handle1
);
389 ok(ret
, "Expected success\n");
390 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
391 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
392 GetLastError() == ERROR_IO_PENDING
/* W2K */,
393 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
395 CloseServiceHandle(svc_handle1
);
397 CloseServiceHandle(scm_handle
);
399 /* Wait a while. One of the following tests also does a CreateService for the
400 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
401 * error if we do this to quick. Vista seems more picky then the others.
405 /* And a final NULL check */
406 SetLastError(0xdeadbeef);
407 ret
= DeleteService(NULL
);
408 ok(!ret
, "Expected failure\n");
409 ok(GetLastError() == ERROR_INVALID_HANDLE
,
410 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
413 static void test_get_displayname(void)
415 SC_HANDLE scm_handle
, svc_handle
;
417 CHAR displayname
[4096];
418 WCHAR displaynameW
[2048];
419 DWORD displaysize
, tempsize
, tempsizeW
;
420 static const CHAR deadbeef
[] = "Deadbeef";
421 static const WCHAR spoolerW
[] = {'S','p','o','o','l','e','r',0};
422 static const CHAR servicename
[] = "Winetest";
423 static const CHAR pathname
[] = "we_dont_care.exe";
425 /* Having NULL for the size of the buffer will crash on W2K3 */
427 SetLastError(0xdeadbeef);
428 ret
= GetServiceDisplayNameA(NULL
, NULL
, NULL
, &displaysize
);
429 ok(!ret
, "Expected failure\n");
430 ok(GetLastError() == ERROR_INVALID_HANDLE
,
431 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
433 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
435 SetLastError(0xdeadbeef);
436 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, NULL
, &displaysize
);
437 ok(!ret
, "Expected failure\n");
438 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
439 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
440 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
442 SetLastError(0xdeadbeef);
443 displaysize
= sizeof(displayname
);
444 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, displayname
, &displaysize
);
445 ok(!ret
, "Expected failure\n");
446 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
447 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
448 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
450 /* Test for nonexistent service */
451 SetLastError(0xdeadbeef);
453 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
454 ok(!ret
, "Expected failure\n");
455 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
456 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
458 /* Check if 'Spooler' exists */
459 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
462 skip("Spooler service doesn't exist\n");
463 CloseServiceHandle(scm_handle
);
466 CloseServiceHandle(svc_handle
);
468 /* Retrieve the needed size for the buffer */
469 SetLastError(0xdeadbeef);
471 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
472 ok(!ret
, "Expected failure\n");
473 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
474 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
475 tempsize
= displaysize
;
478 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
479 ok(!ret
, "Expected failure\n");
480 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
481 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
482 ok(displaysize
== tempsize
, "Buffer size mismatch (%d vs %d)\n", tempsize
, displaysize
);
484 /* Buffer is too small */
485 SetLastError(0xdeadbeef);
486 displaysize
= (tempsize
/ 2);
487 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
488 ok(!ret
, "Expected failure\n");
489 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
490 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
491 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
493 /* First try with a buffer that should be big enough to hold
494 * the ANSI string (and terminating character). This succeeds on Windows
495 * although when asked (see above 2 tests) it will return twice the needed size.
497 SetLastError(0xdeadbeef);
498 displaysize
= (tempsize
/ 2) + 1;
499 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
500 ok(ret
, "Expected success\n");
501 ok(displaysize
== ((tempsize
/ 2) + 1), "Expected no change for the needed buffer size\n");
502 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
503 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
504 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
505 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
507 /* Now with the original returned size */
508 SetLastError(0xdeadbeef);
509 displaysize
= tempsize
;
510 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
511 ok(ret
, "Expected success\n");
512 ok(displaysize
== tempsize
, "Expected no change for the needed buffer size\n");
513 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
514 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
515 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
516 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
518 /* And with a bigger than needed buffer */
519 SetLastError(0xdeadbeef);
520 displaysize
= tempsize
* 2;
521 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
522 ok(ret
, "Expected success\n");
523 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
524 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
525 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
526 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
527 /* Test that shows that if the buffersize is enough, it's not changed */
528 ok(displaysize
== tempsize
* 2, "Expected no change for the needed buffer size\n");
529 ok(lstrlen(displayname
) == tempsize
/2,
530 "Expected the buffer to be twice the length of the string\n") ;
532 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
533 SetLastError(0xdeadbeef);
535 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, NULL
, &displaysize
);
536 ok(!ret
, "Expected failure\n");
537 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
538 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
540 /* Buffer is too small */
541 SetLastError(0xdeadbeef);
542 tempsizeW
= displaysize
;
543 displaysize
= tempsizeW
/ 2;
544 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
545 ok(!ret
, "Expected failure\n");
546 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
547 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
548 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
550 /* Now with the original returned size */
551 SetLastError(0xdeadbeef);
552 displaysize
= tempsizeW
;
553 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
554 ok(!ret
, "Expected failure\n");
555 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
556 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
557 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
559 /* And with a bigger than needed buffer */
560 SetLastError(0xdeadbeef);
561 displaysize
= tempsizeW
+ 1; /* This caters for the null terminating character */
562 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
563 ok(ret
, "Expected success\n");
564 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
565 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
566 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
567 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
568 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
569 ok(lstrlenW(displaynameW
) == displaysize
,
570 "Expected the buffer to be the length of the string\n") ;
571 ok(tempsize
/ 2 == tempsizeW
,
572 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
574 CloseServiceHandle(scm_handle
);
576 /* Test for a service without a displayname (which is valid). This should return
577 * the servicename itself.
579 SetLastError(0xdeadbeef);
580 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
581 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
583 skip("Not enough rights to get a handle to the manager\n");
587 SetLastError(0xdeadbeef);
588 svc_handle
= CreateServiceA(scm_handle
, servicename
, NULL
, DELETE
,
589 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
590 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
591 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
594 CloseServiceHandle(scm_handle
);
598 /* Retrieve the needed size for the buffer */
599 SetLastError(0xdeadbeef);
601 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, NULL
, &displaysize
);
602 ok(!ret
, "Expected failure\n");
603 ok(displaysize
== lstrlen(servicename
) * 2,
604 "Expected the displaysize to be twice the size of the servicename\n");
605 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
606 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
608 /* Buffer is too small */
609 SetLastError(0xdeadbeef);
610 tempsize
= displaysize
;
611 displaysize
= (tempsize
/ 2);
612 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
613 ok(!ret
, "Expected failure\n");
614 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
615 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
616 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
618 /* Get the displayname */
619 SetLastError(0xdeadbeef);
620 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
621 ok(ret
, "Expected success\n");
622 ok(!lstrcmpi(displayname
, servicename
),
623 "Expected displayname to be %s, got %s\n", servicename
, displayname
);
624 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
625 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
626 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
627 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
629 /* Delete the service */
630 ret
= DeleteService(svc_handle
);
631 ok(ret
, "Expected success\n");
633 CloseServiceHandle(svc_handle
);
634 CloseServiceHandle(scm_handle
);
636 /* Wait a while. Just in case one of the following tests does a CreateService again */
640 static void test_get_servicekeyname(void)
642 SC_HANDLE scm_handle
, svc_handle
;
643 CHAR servicename
[4096];
644 CHAR displayname
[4096];
645 WCHAR servicenameW
[4096];
646 WCHAR displaynameW
[4096];
647 DWORD servicesize
, displaysize
, tempsize
;
649 static const CHAR deadbeef
[] = "Deadbeef";
650 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
652 /* Having NULL for the size of the buffer will crash on W2K3 */
654 SetLastError(0xdeadbeef);
655 ret
= GetServiceKeyNameA(NULL
, NULL
, NULL
, &servicesize
);
656 ok(!ret
, "Expected failure\n");
657 ok(GetLastError() == ERROR_INVALID_HANDLE
,
658 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
660 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
663 SetLastError(0xdeadbeef);
664 ret
= GetServiceKeyNameA(scm_handle
, NULL
, NULL
, &servicesize
);
665 ok(!ret
, "Expected failure\n");
666 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
667 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
668 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
669 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
671 /* Valid handle and buffer but no displayname */
673 SetLastError(0xdeadbeef);
674 ret
= GetServiceKeyNameA(scm_handle
, NULL
, servicename
, &servicesize
);
675 ok(!ret
, "Expected failure\n");
676 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
677 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
678 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
679 todo_wine
ok(servicesize
== 200, "Service size expected 1, got %d\n", servicesize
);
681 /* Test for nonexistent displayname */
682 SetLastError(0xdeadbeef);
683 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, NULL
, &servicesize
);
684 ok(!ret
, "Expected failure\n");
685 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
686 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
687 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
690 strcpy(servicename
, "ABC");
691 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
692 ok(!ret
, "Expected failure\n");
693 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
694 ok(servicename
[0] == 0, "Service name not empty\n");
697 servicenameW
[0] = 'A';
698 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
699 ok(!ret
, "Expected failure\n");
700 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
701 ok(servicenameW
[0] == 0, "Service name not empty\n");
704 strcpy(servicename
, "ABC");
705 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
706 ok(!ret
, "Expected failure\n");
707 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
708 ok(servicename
[0] == 'A', "Service name changed\n");
711 servicenameW
[0] = 'A';
712 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
713 ok(!ret
, "Expected failure\n");
714 todo_wine
ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
715 ok(servicenameW
[0] == 'A', "Service name changed\n");
717 /* Check if 'Spooler' exists */
718 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
721 skip("Spooler service doesn't exist\n");
722 CloseServiceHandle(scm_handle
);
725 CloseServiceHandle(svc_handle
);
727 /* Get the displayname for the 'Spooler' service */
728 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
729 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
731 /* Retrieve the needed size for the buffer */
732 SetLastError(0xdeadbeef);
734 ret
= GetServiceKeyNameA(scm_handle
, displayname
, NULL
, &servicesize
);
735 ok(!ret
, "Expected failure\n");
736 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
737 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
739 /* Valid call with the correct buffersize */
740 SetLastError(0xdeadbeef);
741 tempsize
= servicesize
;
743 ret
= GetServiceKeyNameA(scm_handle
, displayname
, servicename
, &servicesize
);
744 ok(ret
, "Expected success\n");
745 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
746 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
747 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
748 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
751 ok(lstrlen(servicename
) == tempsize
/2,
752 "Expected the buffer to be twice the length of the string\n") ;
753 ok(!lstrcmpi(servicename
, spooler
), "Expected %s, got %s\n", spooler
, servicename
);
754 ok(servicesize
== (tempsize
* 2),
755 "Expected servicesize not to change if buffer not insufficient\n") ;
758 MultiByteToWideChar(CP_ACP
, 0, displayname
, -1, displaynameW
, sizeof(displaynameW
)/2);
759 SetLastError(0xdeadbeef);
761 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
762 ok(ret
, "Expected success\n");
763 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
764 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
765 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
766 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
769 ok(lstrlen(servicename
) == tempsize
/2,
770 "Expected the buffer to be twice the length of the string\n") ;
771 ok(servicesize
== lstrlenW(servicenameW
),
772 "Expected servicesize not to change if buffer not insufficient\n") ;
775 SetLastError(0xdeadbeef);
777 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
778 ok(!ret
, "Expected failure\n");
779 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
780 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
781 ok(servicenameW
[0] == 0, "Buffer not empty\n");
783 CloseServiceHandle(scm_handle
);
786 static void test_close(void)
792 SetLastError(0xdeadbeef);
793 ret
= CloseServiceHandle(NULL
);
794 ok(!ret
, "Expected failure\n");
795 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
797 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
800 handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
801 SetLastError(0xdeadbeef);
802 ret
= CloseServiceHandle(handle
);
803 ok(ret
, "Expected success\n");
804 ok(GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
805 GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
806 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
807 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
810 static void test_sequence(void)
812 SC_HANDLE scm_handle
, svc_handle
;
814 QUERY_SERVICE_CONFIGA
*config
;
816 static const CHAR servicename
[] = "Winetest";
817 static const CHAR displayname
[] = "Winetest dummy service";
818 static const CHAR displayname2
[] = "Winetest dummy service (2)";
819 static const CHAR pathname
[] = "we_dont_care.exe";
820 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
821 static const CHAR password
[] = "";
822 static const CHAR empty
[] = "";
823 static const CHAR localsystem
[] = "LocalSystem";
825 SetLastError(0xdeadbeef);
826 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
828 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
830 skip("Not enough rights to get a handle to the manager\n");
834 ok(scm_handle
!= NULL
, "Could not get a handle to the manager: %d\n", GetLastError());
836 if (!scm_handle
) return;
838 /* Create a dummy service */
839 SetLastError(0xdeadbeef);
840 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
841 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
842 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
844 if (!svc_handle
&& (GetLastError() == ERROR_SERVICE_EXISTS
))
846 /* We try and open the service and do the rest of the tests. Some could
847 * fail if the tests were changed between these runs.
849 trace("Deletion probably didn't work last time\n");
850 SetLastError(0xdeadbeef);
851 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
852 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
854 skip("Not enough rights to open the service\n");
855 CloseServiceHandle(scm_handle
);
858 ok(svc_handle
!= NULL
, "Could not open the service : %d\n", GetLastError());
860 else if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
862 skip("Not enough rights to create the service\n");
863 CloseServiceHandle(scm_handle
);
867 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
869 if (!svc_handle
) return;
872 * Before we do a QueryServiceConfig we should check the registry. This will make sure
873 * that the correct keys are used.
876 /* Request the size for the buffer */
877 SetLastError(0xdeadbeef);
878 ret
= QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
879 ok(!ret
, "Expected failure\n");
880 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
882 config
= HeapAlloc(GetProcessHeap(), 0, needed
);
884 SetLastError(0xdeadbeef);
885 ret
= QueryServiceConfigA(svc_handle
, config
, given
, &needed
);
886 ok(ret
, "Expected success\n");
887 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
888 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
889 GetLastError() == ERROR_IO_PENDING
/* W2K */,
890 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
893 ok(given
== needed
, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given
, needed
);
895 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
896 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
897 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
898 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
899 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
900 ok(config
->dwErrorControl
== SERVICE_ERROR_IGNORE
, "Expected SERVICE_ERROR_IGNORE, got %d\n", config
->dwErrorControl
);
901 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
902 ok(!strcmp(config
->lpLoadOrderGroup
, empty
), "Expected an empty string, got '%s'\n", config
->lpLoadOrderGroup
);
903 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
904 /* TODO: Show the double 0 terminated string */
907 ok(!memcmp(config
->lpDependencies
, dependencies
, sizeof(dependencies
)), "Wrong string\n");
909 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
910 ok(!strcmp(config
->lpDisplayName
, displayname
), "Expected '%s', got '%s'\n", displayname
, config
->lpDisplayName
);
912 ok(ChangeServiceConfigA(svc_handle
, SERVICE_NO_CHANGE
, SERVICE_NO_CHANGE
, SERVICE_ERROR_NORMAL
, NULL
, "TestGroup2", NULL
, NULL
, NULL
, NULL
, displayname2
),
913 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
915 QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
916 config
= HeapReAlloc(GetProcessHeap(), 0, config
, needed
);
917 ok(QueryServiceConfigA(svc_handle
, config
, needed
, &needed
), "QueryServiceConfig failed\n");
918 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
919 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
920 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
921 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
922 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
923 ok(config
->dwErrorControl
== SERVICE_ERROR_NORMAL
, "Expected SERVICE_ERROR_NORMAL, got %d\n", config
->dwErrorControl
);
924 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
925 ok(!strcmp(config
->lpLoadOrderGroup
, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config
->lpLoadOrderGroup
);
926 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
927 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
928 ok(!strcmp(config
->lpDisplayName
, displayname2
), "Expected '%s', got '%s'\n", displayname2
, config
->lpDisplayName
);
930 SetLastError(0xdeadbeef);
931 ret
= DeleteService(svc_handle
);
932 ok(ret
, "Expected success\n");
933 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
934 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
935 GetLastError() == ERROR_IO_PENDING
/* W2K */,
936 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
938 CloseServiceHandle(svc_handle
);
940 /* Wait a while. The following test does a CreateService again */
943 CloseServiceHandle(scm_handle
);
944 HeapFree(GetProcessHeap(), 0, config
);
947 static void test_queryconfig2(void)
949 SC_HANDLE scm_handle
, svc_handle
;
951 DWORD expected
, needed
;
952 BYTE buffer
[MAX_PATH
];
953 LPSERVICE_DESCRIPTIONA pConfig
= (LPSERVICE_DESCRIPTIONA
)buffer
;
954 static const CHAR servicename
[] = "Winetest";
955 static const CHAR displayname
[] = "Winetest dummy service";
956 static const CHAR pathname
[] = "we_dont_care.exe";
957 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
958 static const CHAR password
[] = "";
959 static const CHAR description
[] = "Description";
960 HMODULE dllhandle
= GetModuleHandleA("advapi32.dll");
961 BOOL (WINAPI
*pChangeServiceConfig2A
)(SC_HANDLE
,DWORD
,LPVOID
)
962 = (void*)GetProcAddress(dllhandle
, "ChangeServiceConfig2A");
963 BOOL (WINAPI
*pQueryServiceConfig2A
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
)
964 = (void*)GetProcAddress(dllhandle
, "QueryServiceConfig2A");
965 BOOL (WINAPI
*pQueryServiceConfig2W
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
)
966 = (void*)GetProcAddress(dllhandle
, "QueryServiceConfig2W");
967 if(!pQueryServiceConfig2A
)
969 skip("function QueryServiceConfig2A not present\n");
973 SetLastError(0xdeadbeef);
974 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
978 if(GetLastError() == ERROR_ACCESS_DENIED
)
979 skip("Not enough rights to get a handle to the manager\n");
981 ok(FALSE
, "Could not get a handle to the manager: %d\n", GetLastError());
985 /* Create a dummy service */
986 SetLastError(0xdeadbeef);
987 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
988 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
989 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
993 if(GetLastError() == ERROR_SERVICE_EXISTS
)
995 /* We try and open the service and do the rest of the tests. Some could
996 * fail if the tests were changed between these runs.
998 trace("Deletion probably didn't work last time\n");
999 SetLastError(0xdeadbeef);
1000 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1003 if(GetLastError() == ERROR_ACCESS_DENIED
)
1004 skip("Not enough rights to open the service\n");
1006 ok(FALSE
, "Could not open the service : %d\n", GetLastError());
1007 CloseServiceHandle(scm_handle
);
1011 if (GetLastError() == ERROR_ACCESS_DENIED
)
1013 skip("Not enough rights to create the service\n");
1014 CloseServiceHandle(scm_handle
);
1017 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1020 CloseServiceHandle(scm_handle
);
1024 SetLastError(0xdeadbeef);
1025 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1026 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1027 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1029 SetLastError(0xdeadbeef);
1030 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1031 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1032 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1034 SetLastError(0xdeadbeef);
1035 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1036 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1037 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1039 SetLastError(0xdeadbeef);
1040 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1041 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1042 ok((ERROR_INVALID_ADDRESS
== GetLastError()) || (ERROR_INSUFFICIENT_BUFFER
== GetLastError()),
1043 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1045 SetLastError(0xdeadbeef);
1046 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1047 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1048 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1051 SetLastError(0xdeadbeef);
1052 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
)-1,&needed
);
1053 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1054 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1055 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1058 pConfig
->lpDescription
= (LPSTR
)0xdeadbeef;
1059 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1060 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1061 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1062 ok(!pConfig
->lpDescription
, "expected lpDescription to be NULL, got %p\n", pConfig
->lpDescription
);
1064 SetLastError(0xdeadbeef);
1066 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1067 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1068 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1069 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1071 if(!pChangeServiceConfig2A
)
1073 skip("function ChangeServiceConfig2A not present\n");
1077 pConfig
->lpDescription
= (LPSTR
) description
;
1078 ret
= pChangeServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
);
1079 ok(ret
, "ChangeServiceConfig2A failed\n");
1084 SetLastError(0xdeadbeef);
1086 expected
= sizeof(SERVICE_DESCRIPTIONA
) + sizeof(description
) * sizeof(WCHAR
); /* !! */
1087 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1088 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1089 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1090 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1092 SetLastError(0xdeadbeef);
1093 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
-1,&needed
);
1094 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1095 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1097 SetLastError(0xdeadbeef);
1098 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
,&needed
);
1099 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1100 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1101 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1103 SetLastError(0xdeadbeef);
1104 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
+ 1,&needed
);
1105 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1106 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1107 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1109 if(!pQueryServiceConfig2W
)
1111 skip("function QueryServiceConfig2W not present\n");
1114 SetLastError(0xdeadbeef);
1116 expected
= sizeof(SERVICE_DESCRIPTIONW
) + sizeof(WCHAR
) * sizeof(description
);
1117 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1118 ok(!ret
, "expected QueryServiceConfig2W to fail\n");
1119 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1120 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1122 SetLastError(0xdeadbeef);
1123 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
,&needed
);
1124 ok(ret
, "expected QueryServiceConfig2W to succeed\n");
1127 DeleteService(svc_handle
);
1129 CloseServiceHandle(svc_handle
);
1131 /* Wait a while. The following test does a CreateService again */
1134 CloseServiceHandle(scm_handle
);
1137 static void test_refcount(void)
1139 SC_HANDLE scm_handle
, svc_handle1
, svc_handle2
, svc_handle3
, svc_handle4
, svc_handle5
;
1140 static const CHAR servicename
[] = "Winetest";
1141 static const CHAR pathname
[] = "we_dont_care.exe";
1144 /* Get a handle to the Service Control Manager */
1145 SetLastError(0xdeadbeef);
1146 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1147 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1149 skip("Not enough rights to get a handle to the manager\n");
1153 /* Create a service */
1154 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1155 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1156 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1157 ok(svc_handle1
!= NULL
, "Expected success\n");
1159 /* Get a handle to this new service */
1160 svc_handle2
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1161 ok(svc_handle2
!= NULL
, "Expected success\n");
1163 /* Get another handle to this new service */
1164 svc_handle3
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1165 ok(svc_handle3
!= NULL
, "Expected success\n");
1167 /* Check if we can close the handle to the Service Control Manager */
1168 ret
= CloseServiceHandle(scm_handle
);
1169 ok(ret
, "Expected success\n");
1171 /* Get a new handle to the Service Control Manager */
1172 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1173 ok(scm_handle
!= NULL
, "Expected success\n");
1175 /* Get a handle to this new service */
1176 svc_handle4
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1177 ok(svc_handle4
!= NULL
, "Expected success\n");
1179 /* Delete the service */
1180 ret
= DeleteService(svc_handle4
);
1181 ok(ret
, "Expected success\n");
1183 /* We cannot create the same service again as it's still marked as 'being deleted'.
1184 * The reason is that we still have 4 open handles to this service even though we
1185 * closed the handle to the Service Control Manager in between.
1187 SetLastError(0xdeadbeef);
1188 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1189 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1190 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1193 ok(!svc_handle5
, "Expected failure\n");
1194 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE
,
1195 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1198 /* FIXME: Remove this when Wine is fixed */
1201 DeleteService(svc_handle5
);
1202 CloseServiceHandle(svc_handle5
);
1205 /* Close all the handles to the service and try again */
1206 ret
= CloseServiceHandle(svc_handle4
);
1207 ok(ret
, "Expected success\n");
1208 ret
= CloseServiceHandle(svc_handle3
);
1209 ok(ret
, "Expected success\n");
1210 ret
= CloseServiceHandle(svc_handle2
);
1211 ok(ret
, "Expected success\n");
1212 ret
= CloseServiceHandle(svc_handle1
);
1213 ok(ret
, "Expected success\n");
1215 /* Wait a while. Doing a CreateService too soon will result again
1216 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1220 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1221 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1222 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1223 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1224 ok(svc_handle5
!= NULL
, "Expected success\n");
1226 /* Delete the service */
1227 ret
= DeleteService(svc_handle5
);
1228 ok(ret
, "Expected success\n");
1230 /* Wait a while. Just in case one of the following tests does a CreateService again */
1233 CloseServiceHandle(svc_handle5
);
1234 CloseServiceHandle(scm_handle
);
1239 SC_HANDLE scm_handle
;
1241 /* Bail out if we are on win98 */
1242 SetLastError(0xdeadbeef);
1243 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1245 if (!scm_handle
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
1247 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1250 CloseServiceHandle(scm_handle
);
1252 /* First some parameter checking */
1255 test_create_delete_svc();
1256 test_get_displayname();
1257 test_get_servicekeyname();
1259 /* Test the creation, querying and deletion of a service */
1261 test_queryconfig2();
1262 /* The main reason for this test is to check if any refcounting is used
1263 * and what the rules are