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
|| GetLastError() == RPC_S_INVALID_NET_ADDR
/* w2k8 */,
70 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
71 CloseServiceHandle(scm_handle
); /* Just in case */
73 /* Proper call with an empty hostname */
74 SetLastError(0xdeadbeef);
75 scm_handle
= OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
76 ok(scm_handle
!= NULL
, "Expected success\n");
77 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
78 GetLastError() == ERROR_ENVVAR_NOT_FOUND
/* NT4 */ ||
79 GetLastError() == 0xdeadbeef /* XP */ ||
80 GetLastError() == ERROR_IO_PENDING
/* W2K */,
81 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
82 CloseServiceHandle(scm_handle
);
84 /* Again a correct one */
85 SetLastError(0xdeadbeef);
86 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
87 ok(scm_handle
!= NULL
, "Expected success\n");
88 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
89 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
90 GetLastError() == ERROR_IO_PENDING
/* W2K */,
91 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
92 CloseServiceHandle(scm_handle
);
95 static void test_open_svc(void)
97 SC_HANDLE scm_handle
, svc_handle
;
98 CHAR displayname
[4096];
101 /* All NULL (invalid access rights) */
102 SetLastError(0xdeadbeef);
103 svc_handle
= OpenServiceA(NULL
, NULL
, 0);
104 ok(!svc_handle
, "Expected failure\n");
105 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
107 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
110 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
111 SetLastError(0xdeadbeef);
112 svc_handle
= OpenServiceA(scm_handle
, NULL
, GENERIC_READ
);
113 ok(!svc_handle
, "Expected failure\n");
114 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
115 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
116 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
118 /* Nonexistent service */
119 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
120 SetLastError(0xdeadbeef);
121 svc_handle
= OpenServiceA(scm_handle
, "deadbeef", GENERIC_READ
);
122 ok(!svc_handle
, "Expected failure\n");
123 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
124 CloseServiceHandle(scm_handle
);
126 /* Proper SCM handle but different access rights */
127 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
128 SetLastError(0xdeadbeef);
129 svc_handle
= OpenServiceA(scm_handle
, "Spooler", GENERIC_WRITE
);
130 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
131 skip("Not enough rights to get a handle to the service\n");
134 ok(svc_handle
!= NULL
, "Expected success\n");
135 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
136 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
137 GetLastError() == 0xdeadbeef /* XP, NT4 */,
138 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
139 CloseServiceHandle(svc_handle
);
142 /* Test to show we can't open a service with the displayname */
144 /* Retrieve the needed size for the buffer */
146 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
147 /* Get the displayname */
148 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
149 /* Try to open the service with this displayname, unless the displayname equals
150 * the servicename as that would defeat the purpose of this test.
152 if (!lstrcmpi(spooler
, displayname
))
154 skip("displayname equals servicename\n");
155 CloseServiceHandle(scm_handle
);
159 SetLastError(0xdeadbeef);
160 svc_handle
= OpenServiceA(scm_handle
, displayname
, GENERIC_READ
);
161 ok(!svc_handle
, "Expected failure\n");
162 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
164 CloseServiceHandle(svc_handle
);
166 CloseServiceHandle(scm_handle
);
169 static void test_create_delete_svc(void)
171 SC_HANDLE scm_handle
, svc_handle1
;
172 CHAR username
[UNLEN
+ 1], domain
[MAX_PATH
];
173 DWORD user_size
= UNLEN
+ 1;
174 CHAR account
[UNLEN
+ 3];
175 static const CHAR servicename
[] = "Winetest";
176 static const CHAR pathname
[] = "we_dont_care.exe";
177 static const CHAR empty
[] = "";
178 static const CHAR password
[] = "secret";
179 BOOL spooler_exists
= FALSE
;
182 DWORD display_size
= sizeof(display
);
184 /* Get the username and turn it into an account to be used in some tests */
185 GetUserNameA(username
, &user_size
);
186 /* Get the domainname to cater for that situation */
187 if (GetEnvironmentVariableA("USERDOMAIN", domain
, MAX_PATH
))
188 sprintf(account
, "%s\\%s", domain
, username
);
190 sprintf(account
, ".\\%s", username
);
193 SetLastError(0xdeadbeef);
194 svc_handle1
= CreateServiceA(NULL
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
195 ok(!svc_handle1
, "Expected failure\n");
196 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
198 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
200 /* Only a valid handle to the Service Control Manager */
201 SetLastError(0xdeadbeef);
202 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
203 ok(!svc_handle1
, "Expected failure\n");
204 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
205 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
206 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
208 /* Now with a servicename */
209 SetLastError(0xdeadbeef);
210 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
211 ok(!svc_handle1
, "Expected failure\n");
212 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
213 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
214 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
216 /* Or just a binary name */
217 SetLastError(0xdeadbeef);
218 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
219 ok(!svc_handle1
, "Expected failure\n");
220 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
221 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
222 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
224 /* Both servicename and binary name (We only have connect rights) */
225 SetLastError(0xdeadbeef);
226 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
227 ok(!svc_handle1
, "Expected failure\n");
228 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
230 /* They can even be empty at this stage of parameter checking */
231 SetLastError(0xdeadbeef);
232 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
233 ok(!svc_handle1
, "Expected failure\n");
234 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
236 SetLastError(0xdeadbeef);
237 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
238 ok(!svc_handle1
, "Expected failure\n");
239 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
241 /* Open the Service Control Manager with minimal rights for creation
242 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
244 CloseServiceHandle(scm_handle
);
245 SetLastError(0xdeadbeef);
246 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
247 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
249 skip("Not enough rights to get a handle to the manager\n");
253 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
255 /* Empty strings for servicename and binary name are checked */
256 SetLastError(0xdeadbeef);
257 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
258 ok(!svc_handle1
, "Expected failure\n");
259 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
261 SetLastError(0xdeadbeef);
262 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
263 ok(!svc_handle1
, "Expected failure\n");
264 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
266 SetLastError(0xdeadbeef);
267 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
268 ok(!svc_handle1
, "Expected failure\n");
269 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
271 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
272 * an ERROR_INVALID_PARAMETER)
274 SetLastError(0xdeadbeef);
275 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
276 SERVICE_DISABLED
, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
277 ok(!svc_handle1
, "Expected failure\n");
278 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
280 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
282 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
283 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
285 SetLastError(0xdeadbeef);
286 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
,
287 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
288 ok(!svc_handle1
, "Expected failure\n");
289 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
291 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
292 SetLastError(0xdeadbeef);
293 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_INTERACTIVE_PROCESS
,
294 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
295 ok(!svc_handle1
, "Expected failure\n");
296 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
298 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
299 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
301 SetLastError(0xdeadbeef);
302 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
303 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, account
, password
);
304 ok(!svc_handle1
, "Expected failure\n");
305 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
307 /* Illegal (start-type is not a mask and should only be one of the possibilities)
308 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
309 * it's most likely not the wanted start-type)
311 SetLastError(0xdeadbeef);
312 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
,
313 SERVICE_AUTO_START
| SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
314 ok(!svc_handle1
, "Expected failure\n");
315 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
317 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
318 SetLastError(0xdeadbeef);
319 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
320 SERVICE_BOOT_START
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
321 ok(!svc_handle1
, "Expected failure\n");
322 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
324 /* The service already exists (check first, just in case) */
325 svc_handle1
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
328 spooler_exists
= TRUE
;
329 CloseServiceHandle(svc_handle1
);
330 SetLastError(0xdeadbeef);
331 svc_handle1
= CreateServiceA(scm_handle
, spooler
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
332 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
333 ok(!svc_handle1
, "Expected failure\n");
334 ok(GetLastError() == ERROR_SERVICE_EXISTS
, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
337 skip("Spooler service doesn't exist\n");
339 /* To find an existing displayname we check the 'Spooler' service. Although the registry
340 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
341 * to the servicename and can't be used as well for a new displayname.
345 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, display
, &display_size
);
348 skip("Could not retrieve a displayname for the Spooler service\n");
351 svc_handle1
= CreateServiceA(scm_handle
, servicename
, display
, 0, SERVICE_WIN32_OWN_PROCESS
,
352 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
353 ok(!svc_handle1
, "Expected failure\n");
354 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME
,
355 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
359 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
361 /* Windows doesn't care about the access rights for creation (which makes
362 * sense as there is no service yet) as long as there are sufficient
363 * rights to the manager.
365 SetLastError(0xdeadbeef);
366 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
367 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
368 ok(svc_handle1
!= NULL
, "Could not create the service : %d\n", GetLastError());
369 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
370 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
371 GetLastError() == ERROR_IO_PENDING
/* W2K */,
372 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
374 /* DeleteService however must have proper rights */
375 SetLastError(0xdeadbeef);
376 ret
= DeleteService(svc_handle1
);
377 ok(!ret
, "Expected failure\n");
378 ok(GetLastError() == ERROR_ACCESS_DENIED
,
379 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
381 /* Open the service with minimal rights for deletion.
382 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
384 CloseServiceHandle(svc_handle1
);
385 svc_handle1
= OpenServiceA(scm_handle
, servicename
, DELETE
);
387 /* Now that we have the proper rights, we should be able to delete */
388 SetLastError(0xdeadbeef);
389 ret
= DeleteService(svc_handle1
);
390 ok(ret
, "Expected success\n");
391 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
392 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
393 GetLastError() == ERROR_IO_PENDING
/* W2K */,
394 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
396 CloseServiceHandle(svc_handle1
);
398 CloseServiceHandle(scm_handle
);
400 /* Wait a while. One of the following tests also does a CreateService for the
401 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
402 * error if we do this to quick. Vista seems more picky then the others.
406 /* And a final NULL check */
407 SetLastError(0xdeadbeef);
408 ret
= DeleteService(NULL
);
409 ok(!ret
, "Expected failure\n");
410 ok(GetLastError() == ERROR_INVALID_HANDLE
,
411 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
414 static void test_get_displayname(void)
416 SC_HANDLE scm_handle
, svc_handle
;
418 CHAR displayname
[4096];
419 WCHAR displaynameW
[2048];
420 DWORD displaysize
, tempsize
, tempsizeW
;
421 static const CHAR deadbeef
[] = "Deadbeef";
422 static const WCHAR spoolerW
[] = {'S','p','o','o','l','e','r',0};
423 static const CHAR servicename
[] = "Winetest";
424 static const CHAR pathname
[] = "we_dont_care.exe";
426 /* Having NULL for the size of the buffer will crash on W2K3 */
428 SetLastError(0xdeadbeef);
429 ret
= GetServiceDisplayNameA(NULL
, NULL
, NULL
, &displaysize
);
430 ok(!ret
, "Expected failure\n");
431 ok(GetLastError() == ERROR_INVALID_HANDLE
,
432 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
434 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
436 SetLastError(0xdeadbeef);
437 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, NULL
, &displaysize
);
438 ok(!ret
, "Expected failure\n");
439 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
440 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
441 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
443 SetLastError(0xdeadbeef);
444 displaysize
= sizeof(displayname
);
445 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, displayname
, &displaysize
);
446 ok(!ret
, "Expected failure\n");
447 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
448 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
449 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
451 /* Test for nonexistent service */
452 SetLastError(0xdeadbeef);
454 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
455 ok(!ret
, "Expected failure\n");
456 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
457 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
459 /* Check if 'Spooler' exists */
460 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
463 skip("Spooler service doesn't exist\n");
464 CloseServiceHandle(scm_handle
);
467 CloseServiceHandle(svc_handle
);
469 /* Retrieve the needed size for the buffer */
470 SetLastError(0xdeadbeef);
472 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
473 ok(!ret
, "Expected failure\n");
474 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
475 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
476 tempsize
= displaysize
;
479 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
480 ok(!ret
, "Expected failure\n");
481 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
482 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
483 ok(displaysize
== tempsize
, "Buffer size mismatch (%d vs %d)\n", tempsize
, displaysize
);
485 /* Buffer is too small */
486 SetLastError(0xdeadbeef);
487 displaysize
= (tempsize
/ 2);
488 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
489 ok(!ret
, "Expected failure\n");
490 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
491 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
492 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
494 /* First try with a buffer that should be big enough to hold
495 * the ANSI string (and terminating character). This succeeds on Windows
496 * although when asked (see above 2 tests) it will return twice the needed size.
498 SetLastError(0xdeadbeef);
499 displaysize
= (tempsize
/ 2) + 1;
500 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
501 ok(ret
, "Expected success\n");
502 ok(displaysize
== ((tempsize
/ 2) + 1), "Expected no change for the needed buffer size\n");
503 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
504 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
505 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
506 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
508 /* Now with the original returned size */
509 SetLastError(0xdeadbeef);
510 displaysize
= tempsize
;
511 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
512 ok(ret
, "Expected success\n");
513 ok(displaysize
== tempsize
, "Expected no change for the needed buffer size\n");
514 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
515 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
516 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
517 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
519 /* And with a bigger than needed buffer */
520 SetLastError(0xdeadbeef);
521 displaysize
= tempsize
* 2;
522 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
523 ok(ret
, "Expected success\n");
524 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
525 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
526 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
527 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
528 /* Test that shows that if the buffersize is enough, it's not changed */
529 ok(displaysize
== tempsize
* 2, "Expected no change for the needed buffer size\n");
530 ok(lstrlen(displayname
) == tempsize
/2,
531 "Expected the buffer to be twice the length of the string\n") ;
533 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
534 SetLastError(0xdeadbeef);
536 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, NULL
, &displaysize
);
537 ok(!ret
, "Expected failure\n");
538 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
539 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
541 /* Buffer is too small */
542 SetLastError(0xdeadbeef);
543 tempsizeW
= displaysize
;
544 displaysize
= tempsizeW
/ 2;
545 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
546 ok(!ret
, "Expected failure\n");
547 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
548 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
549 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
551 /* Now with the original returned size */
552 SetLastError(0xdeadbeef);
553 displaysize
= tempsizeW
;
554 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
555 ok(!ret
, "Expected failure\n");
556 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
557 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
558 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
560 /* And with a bigger than needed buffer */
561 SetLastError(0xdeadbeef);
562 displaysize
= tempsizeW
+ 1; /* This caters for the null terminating character */
563 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
564 ok(ret
, "Expected success\n");
565 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
566 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
567 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
568 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
569 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
570 ok(lstrlenW(displaynameW
) == displaysize
,
571 "Expected the buffer to be the length of the string\n") ;
572 ok(tempsize
/ 2 == tempsizeW
,
573 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
575 CloseServiceHandle(scm_handle
);
577 /* Test for a service without a displayname (which is valid). This should return
578 * the servicename itself.
580 SetLastError(0xdeadbeef);
581 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
582 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
584 skip("Not enough rights to get a handle to the manager\n");
588 SetLastError(0xdeadbeef);
589 svc_handle
= CreateServiceA(scm_handle
, servicename
, NULL
, DELETE
,
590 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
591 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
592 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
595 CloseServiceHandle(scm_handle
);
599 /* Retrieve the needed size for the buffer */
600 SetLastError(0xdeadbeef);
602 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, NULL
, &displaysize
);
603 ok(!ret
, "Expected failure\n");
604 ok(displaysize
== lstrlen(servicename
) * 2,
605 "Expected the displaysize to be twice the size of the servicename\n");
606 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
607 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
609 /* Buffer is too small */
610 SetLastError(0xdeadbeef);
611 tempsize
= displaysize
;
612 displaysize
= (tempsize
/ 2);
613 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
614 ok(!ret
, "Expected failure\n");
615 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
616 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
617 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
619 /* Get the displayname */
620 SetLastError(0xdeadbeef);
621 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
622 ok(ret
, "Expected success\n");
623 ok(!lstrcmpi(displayname
, servicename
),
624 "Expected displayname to be %s, got %s\n", servicename
, displayname
);
625 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
626 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
627 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
628 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
630 /* Delete the service */
631 ret
= DeleteService(svc_handle
);
632 ok(ret
, "Expected success\n");
634 CloseServiceHandle(svc_handle
);
635 CloseServiceHandle(scm_handle
);
637 /* Wait a while. Just in case one of the following tests does a CreateService again */
641 static void test_get_servicekeyname(void)
643 SC_HANDLE scm_handle
, svc_handle
;
644 CHAR servicename
[4096];
645 CHAR displayname
[4096];
646 WCHAR servicenameW
[4096];
647 WCHAR displaynameW
[4096];
648 DWORD servicesize
, displaysize
, tempsize
;
650 static const CHAR deadbeef
[] = "Deadbeef";
651 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
653 /* Having NULL for the size of the buffer will crash on W2K3 */
655 SetLastError(0xdeadbeef);
656 ret
= GetServiceKeyNameA(NULL
, NULL
, NULL
, &servicesize
);
657 ok(!ret
, "Expected failure\n");
658 ok(GetLastError() == ERROR_INVALID_HANDLE
,
659 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
661 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
664 SetLastError(0xdeadbeef);
665 ret
= GetServiceKeyNameA(scm_handle
, NULL
, NULL
, &servicesize
);
666 ok(!ret
, "Expected failure\n");
667 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
668 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
669 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
670 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
672 /* Valid handle and buffer but no displayname */
674 SetLastError(0xdeadbeef);
675 ret
= GetServiceKeyNameA(scm_handle
, NULL
, servicename
, &servicesize
);
676 ok(!ret
, "Expected failure\n");
677 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
678 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
679 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
680 todo_wine
ok(servicesize
== 200, "Service size expected 1, got %d\n", servicesize
);
682 /* Test for nonexistent displayname */
683 SetLastError(0xdeadbeef);
684 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, NULL
, &servicesize
);
685 ok(!ret
, "Expected failure\n");
686 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
687 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
688 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
691 strcpy(servicename
, "ABC");
692 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
693 ok(!ret
, "Expected failure\n");
694 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
695 ok(servicename
[0] == 0, "Service name not empty\n");
698 servicenameW
[0] = 'A';
699 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
700 ok(!ret
, "Expected failure\n");
701 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
702 ok(servicenameW
[0] == 0, "Service name not empty\n");
705 strcpy(servicename
, "ABC");
706 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
707 ok(!ret
, "Expected failure\n");
708 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
709 ok(servicename
[0] == 'A', "Service name changed\n");
712 servicenameW
[0] = 'A';
713 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
714 ok(!ret
, "Expected failure\n");
715 todo_wine
ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
716 ok(servicenameW
[0] == 'A', "Service name changed\n");
718 /* Check if 'Spooler' exists */
719 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
722 skip("Spooler service doesn't exist\n");
723 CloseServiceHandle(scm_handle
);
726 CloseServiceHandle(svc_handle
);
728 /* Get the displayname for the 'Spooler' service */
729 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
730 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
732 /* Retrieve the needed size for the buffer */
733 SetLastError(0xdeadbeef);
735 ret
= GetServiceKeyNameA(scm_handle
, displayname
, NULL
, &servicesize
);
736 ok(!ret
, "Expected failure\n");
737 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
738 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
740 /* Valid call with the correct buffersize */
741 SetLastError(0xdeadbeef);
742 tempsize
= servicesize
;
744 ret
= GetServiceKeyNameA(scm_handle
, displayname
, servicename
, &servicesize
);
745 ok(ret
, "Expected success\n");
746 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
747 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
748 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
749 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
752 ok(lstrlen(servicename
) == tempsize
/2,
753 "Expected the buffer to be twice the length of the string\n") ;
754 ok(!lstrcmpi(servicename
, spooler
), "Expected %s, got %s\n", spooler
, servicename
);
755 ok(servicesize
== (tempsize
* 2),
756 "Expected servicesize not to change if buffer not insufficient\n") ;
759 MultiByteToWideChar(CP_ACP
, 0, displayname
, -1, displaynameW
, sizeof(displaynameW
)/2);
760 SetLastError(0xdeadbeef);
762 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
763 ok(ret
, "Expected success\n");
764 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
765 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
766 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
767 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
770 ok(lstrlen(servicename
) == tempsize
/2,
771 "Expected the buffer to be twice the length of the string\n") ;
772 ok(servicesize
== lstrlenW(servicenameW
),
773 "Expected servicesize not to change if buffer not insufficient\n") ;
776 SetLastError(0xdeadbeef);
778 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
779 ok(!ret
, "Expected failure\n");
780 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
781 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
782 ok(servicenameW
[0] == 0, "Buffer not empty\n");
784 CloseServiceHandle(scm_handle
);
787 static void test_close(void)
793 SetLastError(0xdeadbeef);
794 ret
= CloseServiceHandle(NULL
);
795 ok(!ret
, "Expected failure\n");
796 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
798 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
801 handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
802 SetLastError(0xdeadbeef);
803 ret
= CloseServiceHandle(handle
);
804 ok(ret
, "Expected success\n");
805 ok(GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
806 GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
807 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
808 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
811 static void test_sequence(void)
813 SC_HANDLE scm_handle
, svc_handle
;
815 QUERY_SERVICE_CONFIGA
*config
;
817 static const CHAR servicename
[] = "Winetest";
818 static const CHAR displayname
[] = "Winetest dummy service";
819 static const CHAR displayname2
[] = "Winetest dummy service (2)";
820 static const CHAR pathname
[] = "we_dont_care.exe";
821 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
822 static const CHAR password
[] = "";
823 static const CHAR empty
[] = "";
824 static const CHAR localsystem
[] = "LocalSystem";
826 SetLastError(0xdeadbeef);
827 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
829 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
831 skip("Not enough rights to get a handle to the manager\n");
835 ok(scm_handle
!= NULL
, "Could not get a handle to the manager: %d\n", GetLastError());
837 if (!scm_handle
) return;
839 /* Create a dummy service */
840 SetLastError(0xdeadbeef);
841 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
842 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
843 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
845 if (!svc_handle
&& (GetLastError() == ERROR_SERVICE_EXISTS
))
847 /* We try and open the service and do the rest of the tests. Some could
848 * fail if the tests were changed between these runs.
850 trace("Deletion probably didn't work last time\n");
851 SetLastError(0xdeadbeef);
852 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
853 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
855 skip("Not enough rights to open the service\n");
856 CloseServiceHandle(scm_handle
);
859 ok(svc_handle
!= NULL
, "Could not open the service : %d\n", GetLastError());
861 else if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
863 skip("Not enough rights to create the service\n");
864 CloseServiceHandle(scm_handle
);
868 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
870 if (!svc_handle
) return;
873 * Before we do a QueryServiceConfig we should check the registry. This will make sure
874 * that the correct keys are used.
877 /* Request the size for the buffer */
878 SetLastError(0xdeadbeef);
879 ret
= QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
880 ok(!ret
, "Expected failure\n");
881 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
883 config
= HeapAlloc(GetProcessHeap(), 0, needed
);
885 SetLastError(0xdeadbeef);
886 ret
= QueryServiceConfigA(svc_handle
, config
, given
, &needed
);
887 ok(ret
, "Expected success\n");
888 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
889 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
890 GetLastError() == ERROR_IO_PENDING
/* W2K */,
891 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
894 ok(given
== needed
, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given
, needed
);
896 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
897 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
898 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
899 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
900 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
901 ok(config
->dwErrorControl
== SERVICE_ERROR_IGNORE
, "Expected SERVICE_ERROR_IGNORE, got %d\n", config
->dwErrorControl
);
902 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
903 ok(!strcmp(config
->lpLoadOrderGroup
, empty
), "Expected an empty string, got '%s'\n", config
->lpLoadOrderGroup
);
904 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
905 /* TODO: Show the double 0 terminated string */
908 ok(!memcmp(config
->lpDependencies
, dependencies
, sizeof(dependencies
)), "Wrong string\n");
910 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
911 ok(!strcmp(config
->lpDisplayName
, displayname
), "Expected '%s', got '%s'\n", displayname
, config
->lpDisplayName
);
913 ok(ChangeServiceConfigA(svc_handle
, SERVICE_NO_CHANGE
, SERVICE_NO_CHANGE
, SERVICE_ERROR_NORMAL
, NULL
, "TestGroup2", NULL
, NULL
, NULL
, NULL
, displayname2
),
914 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
916 QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
917 config
= HeapReAlloc(GetProcessHeap(), 0, config
, needed
);
918 ok(QueryServiceConfigA(svc_handle
, config
, needed
, &needed
), "QueryServiceConfig failed\n");
919 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
920 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
921 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
922 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
923 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
924 ok(config
->dwErrorControl
== SERVICE_ERROR_NORMAL
, "Expected SERVICE_ERROR_NORMAL, got %d\n", config
->dwErrorControl
);
925 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
926 ok(!strcmp(config
->lpLoadOrderGroup
, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config
->lpLoadOrderGroup
);
927 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
928 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
929 ok(!strcmp(config
->lpDisplayName
, displayname2
), "Expected '%s', got '%s'\n", displayname2
, config
->lpDisplayName
);
931 SetLastError(0xdeadbeef);
932 ret
= DeleteService(svc_handle
);
933 ok(ret
, "Expected success\n");
934 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
935 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
936 GetLastError() == ERROR_IO_PENDING
/* W2K */,
937 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
939 CloseServiceHandle(svc_handle
);
941 /* Wait a while. The following test does a CreateService again */
944 CloseServiceHandle(scm_handle
);
945 HeapFree(GetProcessHeap(), 0, config
);
948 static void test_queryconfig2(void)
950 SC_HANDLE scm_handle
, svc_handle
;
952 DWORD expected
, needed
;
953 BYTE buffer
[MAX_PATH
];
954 LPSERVICE_DESCRIPTIONA pConfig
= (LPSERVICE_DESCRIPTIONA
)buffer
;
955 static const CHAR servicename
[] = "Winetest";
956 static const CHAR displayname
[] = "Winetest dummy service";
957 static const CHAR pathname
[] = "we_dont_care.exe";
958 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
959 static const CHAR password
[] = "";
960 static const CHAR description
[] = "Description";
961 HMODULE dllhandle
= GetModuleHandleA("advapi32.dll");
962 BOOL (WINAPI
*pChangeServiceConfig2A
)(SC_HANDLE
,DWORD
,LPVOID
)
963 = (void*)GetProcAddress(dllhandle
, "ChangeServiceConfig2A");
964 BOOL (WINAPI
*pQueryServiceConfig2A
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
)
965 = (void*)GetProcAddress(dllhandle
, "QueryServiceConfig2A");
966 BOOL (WINAPI
*pQueryServiceConfig2W
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
)
967 = (void*)GetProcAddress(dllhandle
, "QueryServiceConfig2W");
968 if(!pQueryServiceConfig2A
)
970 skip("function QueryServiceConfig2A not present\n");
974 SetLastError(0xdeadbeef);
975 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
979 if(GetLastError() == ERROR_ACCESS_DENIED
)
980 skip("Not enough rights to get a handle to the manager\n");
982 ok(FALSE
, "Could not get a handle to the manager: %d\n", GetLastError());
986 /* Create a dummy service */
987 SetLastError(0xdeadbeef);
988 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
989 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
990 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
994 if(GetLastError() == ERROR_SERVICE_EXISTS
)
996 /* We try and open the service and do the rest of the tests. Some could
997 * fail if the tests were changed between these runs.
999 trace("Deletion probably didn't work last time\n");
1000 SetLastError(0xdeadbeef);
1001 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1004 if(GetLastError() == ERROR_ACCESS_DENIED
)
1005 skip("Not enough rights to open the service\n");
1007 ok(FALSE
, "Could not open the service : %d\n", GetLastError());
1008 CloseServiceHandle(scm_handle
);
1012 if (GetLastError() == ERROR_ACCESS_DENIED
)
1014 skip("Not enough rights to create the service\n");
1015 CloseServiceHandle(scm_handle
);
1018 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1021 CloseServiceHandle(scm_handle
);
1025 SetLastError(0xdeadbeef);
1026 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1027 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1028 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1030 SetLastError(0xdeadbeef);
1031 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1032 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1033 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1035 SetLastError(0xdeadbeef);
1036 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1037 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1038 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1040 SetLastError(0xdeadbeef);
1041 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1042 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1043 ok((ERROR_INVALID_ADDRESS
== GetLastError()) || (ERROR_INSUFFICIENT_BUFFER
== GetLastError()),
1044 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1046 SetLastError(0xdeadbeef);
1047 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1048 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1049 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1052 SetLastError(0xdeadbeef);
1053 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
)-1,&needed
);
1054 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1055 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1056 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1059 pConfig
->lpDescription
= (LPSTR
)0xdeadbeef;
1060 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1061 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1062 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1063 ok(!pConfig
->lpDescription
, "expected lpDescription to be NULL, got %p\n", pConfig
->lpDescription
);
1065 SetLastError(0xdeadbeef);
1067 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1068 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1069 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1070 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1072 if(!pChangeServiceConfig2A
)
1074 skip("function ChangeServiceConfig2A not present\n");
1078 pConfig
->lpDescription
= (LPSTR
) description
;
1079 ret
= pChangeServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
);
1080 ok(ret
, "ChangeServiceConfig2A failed\n");
1085 SetLastError(0xdeadbeef);
1087 expected
= sizeof(SERVICE_DESCRIPTIONA
) + sizeof(description
) * sizeof(WCHAR
); /* !! */
1088 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1089 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1090 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1091 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1093 SetLastError(0xdeadbeef);
1094 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
-1,&needed
);
1095 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1096 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1098 SetLastError(0xdeadbeef);
1099 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
,&needed
);
1100 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1101 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1102 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1104 SetLastError(0xdeadbeef);
1105 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
+ 1,&needed
);
1106 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1107 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1108 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1110 if(!pQueryServiceConfig2W
)
1112 skip("function QueryServiceConfig2W not present\n");
1115 SetLastError(0xdeadbeef);
1117 expected
= sizeof(SERVICE_DESCRIPTIONW
) + sizeof(WCHAR
) * sizeof(description
);
1118 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1119 ok(!ret
, "expected QueryServiceConfig2W to fail\n");
1120 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1121 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1123 SetLastError(0xdeadbeef);
1124 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
,&needed
);
1125 ok(ret
, "expected QueryServiceConfig2W to succeed\n");
1128 DeleteService(svc_handle
);
1130 CloseServiceHandle(svc_handle
);
1132 /* Wait a while. The following test does a CreateService again */
1135 CloseServiceHandle(scm_handle
);
1138 static void test_refcount(void)
1140 SC_HANDLE scm_handle
, svc_handle1
, svc_handle2
, svc_handle3
, svc_handle4
, svc_handle5
;
1141 static const CHAR servicename
[] = "Winetest";
1142 static const CHAR pathname
[] = "we_dont_care.exe";
1145 /* Get a handle to the Service Control Manager */
1146 SetLastError(0xdeadbeef);
1147 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1148 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1150 skip("Not enough rights to get a handle to the manager\n");
1154 /* Create a service */
1155 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1156 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1157 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1158 ok(svc_handle1
!= NULL
, "Expected success\n");
1160 /* Get a handle to this new service */
1161 svc_handle2
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1162 ok(svc_handle2
!= NULL
, "Expected success\n");
1164 /* Get another handle to this new service */
1165 svc_handle3
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1166 ok(svc_handle3
!= NULL
, "Expected success\n");
1168 /* Check if we can close the handle to the Service Control Manager */
1169 ret
= CloseServiceHandle(scm_handle
);
1170 ok(ret
, "Expected success\n");
1172 /* Get a new handle to the Service Control Manager */
1173 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1174 ok(scm_handle
!= NULL
, "Expected success\n");
1176 /* Get a handle to this new service */
1177 svc_handle4
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1178 ok(svc_handle4
!= NULL
, "Expected success\n");
1180 /* Delete the service */
1181 ret
= DeleteService(svc_handle4
);
1182 ok(ret
, "Expected success\n");
1184 /* We cannot create the same service again as it's still marked as 'being deleted'.
1185 * The reason is that we still have 4 open handles to this service even though we
1186 * closed the handle to the Service Control Manager in between.
1188 SetLastError(0xdeadbeef);
1189 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1190 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1191 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1194 ok(!svc_handle5
, "Expected failure\n");
1195 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE
,
1196 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1199 /* FIXME: Remove this when Wine is fixed */
1202 DeleteService(svc_handle5
);
1203 CloseServiceHandle(svc_handle5
);
1206 /* Close all the handles to the service and try again */
1207 ret
= CloseServiceHandle(svc_handle4
);
1208 ok(ret
, "Expected success\n");
1209 ret
= CloseServiceHandle(svc_handle3
);
1210 ok(ret
, "Expected success\n");
1211 ret
= CloseServiceHandle(svc_handle2
);
1212 ok(ret
, "Expected success\n");
1213 ret
= CloseServiceHandle(svc_handle1
);
1214 ok(ret
, "Expected success\n");
1216 /* Wait a while. Doing a CreateService too soon will result again
1217 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1221 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1222 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1223 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1224 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1225 ok(svc_handle5
!= NULL
, "Expected success\n");
1227 /* Delete the service */
1228 ret
= DeleteService(svc_handle5
);
1229 ok(ret
, "Expected success\n");
1231 /* Wait a while. Just in case one of the following tests does a CreateService again */
1234 CloseServiceHandle(svc_handle5
);
1235 CloseServiceHandle(scm_handle
);
1240 SC_HANDLE scm_handle
;
1242 /* Bail out if we are on win98 */
1243 SetLastError(0xdeadbeef);
1244 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1246 if (!scm_handle
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
1248 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1251 CloseServiceHandle(scm_handle
);
1253 /* First some parameter checking */
1256 test_create_delete_svc();
1257 test_get_displayname();
1258 test_get_servicekeyname();
1260 /* Test the creation, querying and deletion of a service */
1262 test_queryconfig2();
1263 /* The main reason for this test is to check if any refcounting is used
1264 * and what the rules are