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 BOOL (WINAPI
*pChangeServiceConfig2A
)(SC_HANDLE
,DWORD
,LPVOID
);
37 static BOOL (WINAPI
*pQueryServiceConfig2A
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
);
38 static BOOL (WINAPI
*pQueryServiceConfig2W
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
);
40 static void init_function_pointers(void)
42 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
44 pChangeServiceConfig2A
= (void*)GetProcAddress(hadvapi32
, "ChangeServiceConfig2A");
45 pQueryServiceConfig2A
= (void*)GetProcAddress(hadvapi32
, "QueryServiceConfig2A");
46 pQueryServiceConfig2W
= (void*)GetProcAddress(hadvapi32
, "QueryServiceConfig2W");
49 static void test_open_scm(void)
53 /* No access rights */
54 SetLastError(0xdeadbeef);
55 scm_handle
= OpenSCManagerA(NULL
, NULL
, 0);
56 ok(scm_handle
!= NULL
, "Expected success\n");
57 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
58 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
59 GetLastError() == ERROR_IO_PENDING
/* W2K */,
60 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
61 CloseServiceHandle(scm_handle
);
63 /* Unknown database name */
64 SetLastError(0xdeadbeef);
65 scm_handle
= OpenSCManagerA(NULL
, "DoesNotExist", SC_MANAGER_CONNECT
);
66 ok(!scm_handle
, "Expected failure\n");
67 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
68 CloseServiceHandle(scm_handle
); /* Just in case */
70 /* MSDN says only ServiceActive is allowed, or NULL */
71 SetLastError(0xdeadbeef);
72 scm_handle
= OpenSCManagerA(NULL
, SERVICES_FAILED_DATABASEA
, SC_MANAGER_CONNECT
);
73 ok(!scm_handle
, "Expected failure\n");
74 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST
, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
75 CloseServiceHandle(scm_handle
); /* Just in case */
77 /* Remote unknown host */
78 SetLastError(0xdeadbeef);
79 scm_handle
= OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
80 ok(!scm_handle
, "Expected failure\n");
82 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE
|| GetLastError() == RPC_S_INVALID_NET_ADDR
/* w2k8 */,
83 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
84 CloseServiceHandle(scm_handle
); /* Just in case */
86 /* Proper call with an empty hostname */
87 SetLastError(0xdeadbeef);
88 scm_handle
= OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
89 ok(scm_handle
!= NULL
, "Expected success\n");
90 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
91 GetLastError() == ERROR_ENVVAR_NOT_FOUND
/* NT4 */ ||
92 GetLastError() == 0xdeadbeef /* XP */ ||
93 GetLastError() == ERROR_IO_PENDING
/* W2K */,
94 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
95 CloseServiceHandle(scm_handle
);
97 /* Again a correct one */
98 SetLastError(0xdeadbeef);
99 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
100 ok(scm_handle
!= NULL
, "Expected success\n");
101 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
102 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
103 GetLastError() == ERROR_IO_PENDING
/* W2K */,
104 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
105 CloseServiceHandle(scm_handle
);
108 static void test_open_svc(void)
110 SC_HANDLE scm_handle
, svc_handle
;
111 CHAR displayname
[4096];
114 /* All NULL (invalid access rights) */
115 SetLastError(0xdeadbeef);
116 svc_handle
= OpenServiceA(NULL
, NULL
, 0);
117 ok(!svc_handle
, "Expected failure\n");
118 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
120 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
123 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
124 SetLastError(0xdeadbeef);
125 svc_handle
= OpenServiceA(scm_handle
, NULL
, GENERIC_READ
);
126 ok(!svc_handle
, "Expected failure\n");
127 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
128 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
129 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
131 /* Nonexistent service */
132 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
133 SetLastError(0xdeadbeef);
134 svc_handle
= OpenServiceA(scm_handle
, "deadbeef", GENERIC_READ
);
135 ok(!svc_handle
, "Expected failure\n");
136 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
137 CloseServiceHandle(scm_handle
);
139 /* Proper SCM handle but different access rights */
140 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
141 SetLastError(0xdeadbeef);
142 svc_handle
= OpenServiceA(scm_handle
, "Spooler", GENERIC_WRITE
);
143 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
144 skip("Not enough rights to get a handle to the service\n");
147 ok(svc_handle
!= NULL
, "Expected success\n");
148 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
149 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
150 GetLastError() == 0xdeadbeef /* XP, NT4 */,
151 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
152 CloseServiceHandle(svc_handle
);
155 /* Test to show we can't open a service with the displayname */
157 /* Retrieve the needed size for the buffer */
159 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
160 /* Get the displayname */
161 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
162 /* Try to open the service with this displayname, unless the displayname equals
163 * the servicename as that would defeat the purpose of this test.
165 if (!lstrcmpi(spooler
, displayname
))
167 skip("displayname equals servicename\n");
168 CloseServiceHandle(scm_handle
);
172 SetLastError(0xdeadbeef);
173 svc_handle
= OpenServiceA(scm_handle
, displayname
, GENERIC_READ
);
174 ok(!svc_handle
, "Expected failure\n");
175 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
177 CloseServiceHandle(svc_handle
);
179 CloseServiceHandle(scm_handle
);
182 static void test_create_delete_svc(void)
184 SC_HANDLE scm_handle
, svc_handle1
;
185 CHAR username
[UNLEN
+ 1], domain
[MAX_PATH
];
186 DWORD user_size
= UNLEN
+ 1;
187 CHAR account
[UNLEN
+ 3];
188 static const CHAR servicename
[] = "Winetest";
189 static const CHAR pathname
[] = "we_dont_care.exe";
190 static const CHAR empty
[] = "";
191 static const CHAR password
[] = "secret";
192 BOOL spooler_exists
= FALSE
;
195 DWORD display_size
= sizeof(display
);
197 /* Get the username and turn it into an account to be used in some tests */
198 GetUserNameA(username
, &user_size
);
199 /* Get the domainname to cater for that situation */
200 if (GetEnvironmentVariableA("USERDOMAIN", domain
, MAX_PATH
))
201 sprintf(account
, "%s\\%s", domain
, username
);
203 sprintf(account
, ".\\%s", username
);
206 SetLastError(0xdeadbeef);
207 svc_handle1
= CreateServiceA(NULL
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
208 ok(!svc_handle1
, "Expected failure\n");
209 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
211 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
213 /* Only a valid handle to the Service Control Manager */
214 SetLastError(0xdeadbeef);
215 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
216 ok(!svc_handle1
, "Expected failure\n");
217 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
218 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
219 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
221 /* Now with a servicename */
222 SetLastError(0xdeadbeef);
223 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
224 ok(!svc_handle1
, "Expected failure\n");
225 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
226 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
227 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
229 /* Or just a binary name */
230 SetLastError(0xdeadbeef);
231 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
232 ok(!svc_handle1
, "Expected failure\n");
233 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
234 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
235 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
237 /* Both servicename and binary name (We only have connect rights) */
238 SetLastError(0xdeadbeef);
239 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
240 ok(!svc_handle1
, "Expected failure\n");
241 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
243 /* They can even be empty at this stage of parameter checking */
244 SetLastError(0xdeadbeef);
245 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
246 ok(!svc_handle1
, "Expected failure\n");
247 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
249 SetLastError(0xdeadbeef);
250 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
251 ok(!svc_handle1
, "Expected failure\n");
252 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
254 /* Open the Service Control Manager with minimal rights for creation
255 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
257 CloseServiceHandle(scm_handle
);
258 SetLastError(0xdeadbeef);
259 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
260 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
262 skip("Not enough rights to get a handle to the manager\n");
266 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
268 /* Empty strings for servicename and binary name are checked */
269 SetLastError(0xdeadbeef);
270 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
271 ok(!svc_handle1
, "Expected failure\n");
272 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
274 SetLastError(0xdeadbeef);
275 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 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 SetLastError(0xdeadbeef);
280 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
281 ok(!svc_handle1
, "Expected failure\n");
282 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
284 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
285 * an ERROR_INVALID_PARAMETER)
287 SetLastError(0xdeadbeef);
288 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
289 SERVICE_DISABLED
, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
290 ok(!svc_handle1
, "Expected failure\n");
291 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
293 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
295 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
296 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
298 SetLastError(0xdeadbeef);
299 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
,
300 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
301 ok(!svc_handle1
, "Expected failure\n");
302 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
304 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
305 SetLastError(0xdeadbeef);
306 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_INTERACTIVE_PROCESS
,
307 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
308 ok(!svc_handle1
, "Expected failure\n");
309 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
311 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
312 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
314 SetLastError(0xdeadbeef);
315 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
316 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, account
, password
);
317 ok(!svc_handle1
, "Expected failure\n");
318 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
320 /* Illegal (start-type is not a mask and should only be one of the possibilities)
321 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
322 * it's most likely not the wanted start-type)
324 SetLastError(0xdeadbeef);
325 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
,
326 SERVICE_AUTO_START
| SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
327 ok(!svc_handle1
, "Expected failure\n");
328 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
330 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
331 SetLastError(0xdeadbeef);
332 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
333 SERVICE_BOOT_START
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
334 ok(!svc_handle1
, "Expected failure\n");
335 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
337 /* The service already exists (check first, just in case) */
338 svc_handle1
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
341 spooler_exists
= TRUE
;
342 CloseServiceHandle(svc_handle1
);
343 SetLastError(0xdeadbeef);
344 svc_handle1
= CreateServiceA(scm_handle
, spooler
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
345 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
346 ok(!svc_handle1
, "Expected failure\n");
347 ok(GetLastError() == ERROR_SERVICE_EXISTS
, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
350 skip("Spooler service doesn't exist\n");
352 /* To find an existing displayname we check the 'Spooler' service. Although the registry
353 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
354 * to the servicename and can't be used as well for a new displayname.
358 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, display
, &display_size
);
361 skip("Could not retrieve a displayname for the Spooler service\n");
364 svc_handle1
= CreateServiceA(scm_handle
, servicename
, display
, 0, SERVICE_WIN32_OWN_PROCESS
,
365 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
366 ok(!svc_handle1
, "Expected failure\n");
367 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME
,
368 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
372 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
374 /* Windows doesn't care about the access rights for creation (which makes
375 * sense as there is no service yet) as long as there are sufficient
376 * rights to the manager.
378 SetLastError(0xdeadbeef);
379 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
380 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
381 ok(svc_handle1
!= NULL
, "Could not create the service : %d\n", GetLastError());
382 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
383 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
384 GetLastError() == ERROR_IO_PENDING
/* W2K */,
385 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
387 /* DeleteService however must have proper rights */
388 SetLastError(0xdeadbeef);
389 ret
= DeleteService(svc_handle1
);
390 ok(!ret
, "Expected failure\n");
391 ok(GetLastError() == ERROR_ACCESS_DENIED
,
392 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
394 /* Open the service with minimal rights for deletion.
395 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
397 CloseServiceHandle(svc_handle1
);
398 svc_handle1
= OpenServiceA(scm_handle
, servicename
, DELETE
);
400 /* Now that we have the proper rights, we should be able to delete */
401 SetLastError(0xdeadbeef);
402 ret
= DeleteService(svc_handle1
);
403 ok(ret
, "Expected success\n");
404 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
405 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
406 GetLastError() == ERROR_IO_PENDING
/* W2K */,
407 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
409 CloseServiceHandle(svc_handle1
);
411 CloseServiceHandle(scm_handle
);
413 /* Wait a while. One of the following tests also does a CreateService for the
414 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
415 * error if we do this to quick. Vista seems more picky then the others.
419 /* And a final NULL check */
420 SetLastError(0xdeadbeef);
421 ret
= DeleteService(NULL
);
422 ok(!ret
, "Expected failure\n");
423 ok(GetLastError() == ERROR_INVALID_HANDLE
,
424 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
427 static void test_get_displayname(void)
429 SC_HANDLE scm_handle
, svc_handle
;
431 CHAR displayname
[4096];
432 WCHAR displaynameW
[2048];
433 DWORD displaysize
, tempsize
, tempsizeW
;
434 static const CHAR deadbeef
[] = "Deadbeef";
435 static const WCHAR spoolerW
[] = {'S','p','o','o','l','e','r',0};
436 static const CHAR servicename
[] = "Winetest";
437 static const CHAR pathname
[] = "we_dont_care.exe";
439 /* Having NULL for the size of the buffer will crash on W2K3 */
441 SetLastError(0xdeadbeef);
442 ret
= GetServiceDisplayNameA(NULL
, NULL
, NULL
, &displaysize
);
443 ok(!ret
, "Expected failure\n");
444 ok(GetLastError() == ERROR_INVALID_HANDLE
,
445 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
447 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
449 SetLastError(0xdeadbeef);
450 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, NULL
, &displaysize
);
451 ok(!ret
, "Expected failure\n");
452 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
453 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
454 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
456 SetLastError(0xdeadbeef);
457 displaysize
= sizeof(displayname
);
458 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, displayname
, &displaysize
);
459 ok(!ret
, "Expected failure\n");
460 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
461 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
462 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
464 /* Test for nonexistent service */
465 SetLastError(0xdeadbeef);
467 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
468 ok(!ret
, "Expected failure\n");
469 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
470 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
472 /* Check if 'Spooler' exists */
473 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
476 skip("Spooler service doesn't exist\n");
477 CloseServiceHandle(scm_handle
);
480 CloseServiceHandle(svc_handle
);
482 /* Retrieve the needed size for the buffer */
483 SetLastError(0xdeadbeef);
485 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
486 ok(!ret
, "Expected failure\n");
487 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
488 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
489 tempsize
= displaysize
;
492 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
493 ok(!ret
, "Expected failure\n");
494 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
495 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
496 ok(displaysize
== tempsize
, "Buffer size mismatch (%d vs %d)\n", tempsize
, displaysize
);
498 /* Buffer is too small */
499 SetLastError(0xdeadbeef);
500 displaysize
= (tempsize
/ 2);
501 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
502 ok(!ret
, "Expected failure\n");
503 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
504 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
505 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
507 /* First try with a buffer that should be big enough to hold
508 * the ANSI string (and terminating character). This succeeds on Windows
509 * although when asked (see above 2 tests) it will return twice the needed size.
511 SetLastError(0xdeadbeef);
512 displaysize
= (tempsize
/ 2) + 1;
513 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
514 ok(ret
, "Expected success\n");
515 ok(displaysize
== ((tempsize
/ 2) + 1), "Expected no change for the needed buffer size\n");
516 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
517 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
518 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
519 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
521 /* Now with the original returned size */
522 SetLastError(0xdeadbeef);
523 displaysize
= tempsize
;
524 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
525 ok(ret
, "Expected success\n");
526 ok(displaysize
== tempsize
, "Expected no change for the needed buffer size\n");
527 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
528 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
529 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
530 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
532 /* And with a bigger than needed buffer */
533 SetLastError(0xdeadbeef);
534 displaysize
= tempsize
* 2;
535 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
536 ok(ret
, "Expected success\n");
537 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
538 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
539 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
540 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
541 /* Test that shows that if the buffersize is enough, it's not changed */
542 ok(displaysize
== tempsize
* 2, "Expected no change for the needed buffer size\n");
543 ok(lstrlen(displayname
) == tempsize
/2,
544 "Expected the buffer to be twice the length of the string\n") ;
546 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
547 SetLastError(0xdeadbeef);
549 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, NULL
, &displaysize
);
550 ok(!ret
, "Expected failure\n");
551 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
552 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
554 /* Buffer is too small */
555 SetLastError(0xdeadbeef);
556 tempsizeW
= displaysize
;
557 displaysize
= tempsizeW
/ 2;
558 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
559 ok(!ret
, "Expected failure\n");
560 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
561 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
562 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
564 /* Now with the original returned size */
565 SetLastError(0xdeadbeef);
566 displaysize
= tempsizeW
;
567 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
568 ok(!ret
, "Expected failure\n");
569 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
570 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
571 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
573 /* And with a bigger than needed buffer */
574 SetLastError(0xdeadbeef);
575 displaysize
= tempsizeW
+ 1; /* This caters for the null terminating character */
576 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
577 ok(ret
, "Expected success\n");
578 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
579 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
580 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
581 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
582 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
583 ok(lstrlenW(displaynameW
) == displaysize
,
584 "Expected the buffer to be the length of the string\n") ;
585 ok(tempsize
/ 2 == tempsizeW
,
586 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
588 CloseServiceHandle(scm_handle
);
590 /* Test for a service without a displayname (which is valid). This should return
591 * the servicename itself.
593 SetLastError(0xdeadbeef);
594 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
595 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
597 skip("Not enough rights to get a handle to the manager\n");
601 SetLastError(0xdeadbeef);
602 svc_handle
= CreateServiceA(scm_handle
, servicename
, NULL
, DELETE
,
603 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
604 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
605 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
608 CloseServiceHandle(scm_handle
);
612 /* Retrieve the needed size for the buffer */
613 SetLastError(0xdeadbeef);
615 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, NULL
, &displaysize
);
616 ok(!ret
, "Expected failure\n");
617 ok(displaysize
== lstrlen(servicename
) * 2,
618 "Expected the displaysize to be twice the size of the servicename\n");
619 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
620 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
622 /* Buffer is too small */
623 SetLastError(0xdeadbeef);
624 tempsize
= displaysize
;
625 displaysize
= (tempsize
/ 2);
626 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
627 ok(!ret
, "Expected failure\n");
628 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
629 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
630 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
632 /* Get the displayname */
633 SetLastError(0xdeadbeef);
634 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
635 ok(ret
, "Expected success\n");
636 ok(!lstrcmpi(displayname
, servicename
),
637 "Expected displayname to be %s, got %s\n", servicename
, displayname
);
638 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
639 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
640 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
641 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
643 /* Delete the service */
644 ret
= DeleteService(svc_handle
);
645 ok(ret
, "Expected success\n");
647 CloseServiceHandle(svc_handle
);
648 CloseServiceHandle(scm_handle
);
650 /* Wait a while. Just in case one of the following tests does a CreateService again */
654 static void test_get_servicekeyname(void)
656 SC_HANDLE scm_handle
, svc_handle
;
657 CHAR servicename
[4096];
658 CHAR displayname
[4096];
659 WCHAR servicenameW
[4096];
660 WCHAR displaynameW
[4096];
661 DWORD servicesize
, displaysize
, tempsize
;
663 static const CHAR deadbeef
[] = "Deadbeef";
664 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
666 /* Having NULL for the size of the buffer will crash on W2K3 */
668 SetLastError(0xdeadbeef);
669 ret
= GetServiceKeyNameA(NULL
, NULL
, NULL
, &servicesize
);
670 ok(!ret
, "Expected failure\n");
671 ok(GetLastError() == ERROR_INVALID_HANDLE
,
672 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
674 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
677 SetLastError(0xdeadbeef);
678 ret
= GetServiceKeyNameA(scm_handle
, NULL
, NULL
, &servicesize
);
679 ok(!ret
, "Expected failure\n");
680 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
681 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
682 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
683 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
685 /* Valid handle and buffer but no displayname */
687 SetLastError(0xdeadbeef);
688 ret
= GetServiceKeyNameA(scm_handle
, NULL
, servicename
, &servicesize
);
689 ok(!ret
, "Expected failure\n");
690 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
691 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
692 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
693 todo_wine
ok(servicesize
== 200, "Service size expected 1, got %d\n", servicesize
);
695 /* Test for nonexistent displayname */
696 SetLastError(0xdeadbeef);
697 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, NULL
, &servicesize
);
698 ok(!ret
, "Expected failure\n");
699 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
700 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
701 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
704 strcpy(servicename
, "ABC");
705 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
706 ok(!ret
, "Expected failure\n");
707 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
708 ok(servicename
[0] == 0, "Service name not empty\n");
711 servicenameW
[0] = 'A';
712 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
713 ok(!ret
, "Expected failure\n");
714 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
715 ok(servicenameW
[0] == 0, "Service name not empty\n");
718 strcpy(servicename
, "ABC");
719 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
720 ok(!ret
, "Expected failure\n");
721 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
722 ok(servicename
[0] == 'A', "Service name changed\n");
725 servicenameW
[0] = 'A';
726 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
727 ok(!ret
, "Expected failure\n");
728 todo_wine
ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
729 ok(servicenameW
[0] == 'A', "Service name changed\n");
731 /* Check if 'Spooler' exists */
732 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
735 skip("Spooler service doesn't exist\n");
736 CloseServiceHandle(scm_handle
);
739 CloseServiceHandle(svc_handle
);
741 /* Get the displayname for the 'Spooler' service */
742 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
743 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
745 /* Retrieve the needed size for the buffer */
746 SetLastError(0xdeadbeef);
748 ret
= GetServiceKeyNameA(scm_handle
, displayname
, NULL
, &servicesize
);
749 ok(!ret
, "Expected failure\n");
750 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
751 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
753 /* Valid call with the correct buffersize */
754 SetLastError(0xdeadbeef);
755 tempsize
= servicesize
;
757 ret
= GetServiceKeyNameA(scm_handle
, displayname
, servicename
, &servicesize
);
758 ok(ret
, "Expected success\n");
759 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
760 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
761 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
762 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
765 ok(lstrlen(servicename
) == tempsize
/2,
766 "Expected the buffer to be twice the length of the string\n") ;
767 ok(!lstrcmpi(servicename
, spooler
), "Expected %s, got %s\n", spooler
, servicename
);
768 ok(servicesize
== (tempsize
* 2),
769 "Expected servicesize not to change if buffer not insufficient\n") ;
772 MultiByteToWideChar(CP_ACP
, 0, displayname
, -1, displaynameW
, sizeof(displaynameW
)/2);
773 SetLastError(0xdeadbeef);
775 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
776 ok(ret
, "Expected success\n");
777 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
778 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
779 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
780 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
783 ok(lstrlen(servicename
) == tempsize
/2,
784 "Expected the buffer to be twice the length of the string\n") ;
785 ok(servicesize
== lstrlenW(servicenameW
),
786 "Expected servicesize not to change if buffer not insufficient\n") ;
789 SetLastError(0xdeadbeef);
791 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
792 ok(!ret
, "Expected failure\n");
793 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
794 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
795 ok(servicenameW
[0] == 0, "Buffer not empty\n");
797 CloseServiceHandle(scm_handle
);
800 static void test_query_svc(void)
802 SC_HANDLE scm_handle
, svc_handle
;
804 SERVICE_STATUS status
;
806 /* All NULL or wrong */
807 SetLastError(0xdeadbeef);
808 ret
= QueryServiceStatus(NULL
, NULL
);
809 ok(!ret
, "Expected failure\n");
810 ok(GetLastError() == ERROR_INVALID_HANDLE
,
811 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
813 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
815 /* Check if 'Spooler' exists.
816 * Open with not enough rights to query the status.
818 svc_handle
= OpenServiceA(scm_handle
, spooler
, STANDARD_RIGHTS_READ
);
821 skip("Spooler service doesn't exist\n");
822 CloseServiceHandle(scm_handle
);
826 SetLastError(0xdeadbeef);
827 ret
= QueryServiceStatus(svc_handle
, NULL
);
828 ok(!ret
, "Expected failure\n");
830 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
831 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
832 "Unexpected last error %d\n", GetLastError());
834 SetLastError(0xdeadbeef);
835 ret
= QueryServiceStatus(svc_handle
, &status
);
836 ok(!ret
, "Expected failure\n");
837 ok(GetLastError() == ERROR_ACCESS_DENIED
,
838 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
840 /* Open the service with just enough rights.
841 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
843 CloseServiceHandle(svc_handle
);
844 svc_handle
= OpenServiceA(scm_handle
, spooler
, SERVICE_QUERY_STATUS
);
846 SetLastError(0xdeadbeef);
847 ret
= QueryServiceStatus(svc_handle
, &status
);
848 ok(ret
, "Expected success\n");
849 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
850 GetLastError() == 0xdeadbeef /* NT4, XP and Vista */ ||
851 GetLastError() == ERROR_IO_PENDING
/* W2K */,
852 "Unexpected last error %d\n", GetLastError());
854 CloseServiceHandle(svc_handle
);
855 CloseServiceHandle(scm_handle
);
858 static void test_close(void)
864 SetLastError(0xdeadbeef);
865 ret
= CloseServiceHandle(NULL
);
866 ok(!ret
, "Expected failure\n");
867 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
869 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
872 handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
873 SetLastError(0xdeadbeef);
874 ret
= CloseServiceHandle(handle
);
875 ok(ret
, "Expected success\n");
876 ok(GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
877 GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
878 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
879 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
882 static void test_sequence(void)
884 SC_HANDLE scm_handle
, svc_handle
;
886 QUERY_SERVICE_CONFIGA
*config
;
888 static const CHAR servicename
[] = "Winetest";
889 static const CHAR displayname
[] = "Winetest dummy service";
890 static const CHAR displayname2
[] = "Winetest dummy service (2)";
891 static const CHAR pathname
[] = "we_dont_care.exe";
892 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
893 static const CHAR password
[] = "";
894 static const CHAR empty
[] = "";
895 static const CHAR localsystem
[] = "LocalSystem";
897 SetLastError(0xdeadbeef);
898 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
900 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
902 skip("Not enough rights to get a handle to the manager\n");
906 ok(scm_handle
!= NULL
, "Could not get a handle to the manager: %d\n", GetLastError());
908 if (!scm_handle
) return;
910 /* Create a dummy service */
911 SetLastError(0xdeadbeef);
912 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
913 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
914 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
916 if (!svc_handle
&& (GetLastError() == ERROR_SERVICE_EXISTS
))
918 /* We try and open the service and do the rest of the tests. Some could
919 * fail if the tests were changed between these runs.
921 trace("Deletion probably didn't work last time\n");
922 SetLastError(0xdeadbeef);
923 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
924 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
926 skip("Not enough rights to open the service\n");
927 CloseServiceHandle(scm_handle
);
930 ok(svc_handle
!= NULL
, "Could not open the service : %d\n", GetLastError());
932 else if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
934 skip("Not enough rights to create the service\n");
935 CloseServiceHandle(scm_handle
);
939 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
941 if (!svc_handle
) return;
944 * Before we do a QueryServiceConfig we should check the registry. This will make sure
945 * that the correct keys are used.
948 /* Request the size for the buffer */
949 SetLastError(0xdeadbeef);
950 ret
= QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
951 ok(!ret
, "Expected failure\n");
952 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
954 config
= HeapAlloc(GetProcessHeap(), 0, needed
);
956 SetLastError(0xdeadbeef);
957 ret
= QueryServiceConfigA(svc_handle
, config
, given
, &needed
);
958 ok(ret
, "Expected success\n");
959 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
960 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
961 GetLastError() == ERROR_IO_PENDING
/* W2K */,
962 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
965 ok(given
== needed
, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given
, needed
);
967 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
968 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
969 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
970 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
971 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
972 ok(config
->dwErrorControl
== SERVICE_ERROR_IGNORE
, "Expected SERVICE_ERROR_IGNORE, got %d\n", config
->dwErrorControl
);
973 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
974 ok(!strcmp(config
->lpLoadOrderGroup
, empty
), "Expected an empty string, got '%s'\n", config
->lpLoadOrderGroup
);
975 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
976 /* TODO: Show the double 0 terminated string */
979 ok(!memcmp(config
->lpDependencies
, dependencies
, sizeof(dependencies
)), "Wrong string\n");
981 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
982 ok(!strcmp(config
->lpDisplayName
, displayname
), "Expected '%s', got '%s'\n", displayname
, config
->lpDisplayName
);
984 ok(ChangeServiceConfigA(svc_handle
, SERVICE_NO_CHANGE
, SERVICE_NO_CHANGE
, SERVICE_ERROR_NORMAL
, NULL
, "TestGroup2", NULL
, NULL
, NULL
, NULL
, displayname2
),
985 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
987 QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
988 config
= HeapReAlloc(GetProcessHeap(), 0, config
, needed
);
989 ok(QueryServiceConfigA(svc_handle
, config
, needed
, &needed
), "QueryServiceConfig failed\n");
990 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
991 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
992 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
993 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
994 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
995 ok(config
->dwErrorControl
== SERVICE_ERROR_NORMAL
, "Expected SERVICE_ERROR_NORMAL, got %d\n", config
->dwErrorControl
);
996 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
997 ok(!strcmp(config
->lpLoadOrderGroup
, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config
->lpLoadOrderGroup
);
998 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
999 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
1000 ok(!strcmp(config
->lpDisplayName
, displayname2
), "Expected '%s', got '%s'\n", displayname2
, config
->lpDisplayName
);
1002 SetLastError(0xdeadbeef);
1003 ret
= DeleteService(svc_handle
);
1004 ok(ret
, "Expected success\n");
1005 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
1006 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
1007 GetLastError() == ERROR_IO_PENDING
/* W2K */,
1008 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
1010 CloseServiceHandle(svc_handle
);
1012 /* Wait a while. The following test does a CreateService again */
1015 CloseServiceHandle(scm_handle
);
1016 HeapFree(GetProcessHeap(), 0, config
);
1019 static void test_queryconfig2(void)
1021 SC_HANDLE scm_handle
, svc_handle
;
1023 DWORD expected
, needed
;
1024 BYTE buffer
[MAX_PATH
];
1025 LPSERVICE_DESCRIPTIONA pConfig
= (LPSERVICE_DESCRIPTIONA
)buffer
;
1026 static const CHAR servicename
[] = "Winetest";
1027 static const CHAR displayname
[] = "Winetest dummy service";
1028 static const CHAR pathname
[] = "we_dont_care.exe";
1029 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
1030 static const CHAR password
[] = "";
1031 static const CHAR description
[] = "Description";
1033 if(!pQueryServiceConfig2A
)
1035 skip("function QueryServiceConfig2A not present\n");
1039 SetLastError(0xdeadbeef);
1040 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1044 if(GetLastError() == ERROR_ACCESS_DENIED
)
1045 skip("Not enough rights to get a handle to the manager\n");
1047 ok(FALSE
, "Could not get a handle to the manager: %d\n", GetLastError());
1051 /* Create a dummy service */
1052 SetLastError(0xdeadbeef);
1053 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
1054 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
1055 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
1059 if(GetLastError() == ERROR_SERVICE_EXISTS
)
1061 /* We try and open the service and do the rest of the tests. Some could
1062 * fail if the tests were changed between these runs.
1064 trace("Deletion probably didn't work last time\n");
1065 SetLastError(0xdeadbeef);
1066 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1069 if(GetLastError() == ERROR_ACCESS_DENIED
)
1070 skip("Not enough rights to open the service\n");
1072 ok(FALSE
, "Could not open the service : %d\n", GetLastError());
1073 CloseServiceHandle(scm_handle
);
1077 if (GetLastError() == ERROR_ACCESS_DENIED
)
1079 skip("Not enough rights to create the service\n");
1080 CloseServiceHandle(scm_handle
);
1083 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1086 CloseServiceHandle(scm_handle
);
1090 SetLastError(0xdeadbeef);
1091 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1092 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1093 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1095 SetLastError(0xdeadbeef);
1096 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1097 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1098 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1100 SetLastError(0xdeadbeef);
1101 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1102 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1103 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1105 SetLastError(0xdeadbeef);
1106 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1107 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1108 ok((ERROR_INVALID_ADDRESS
== GetLastError()) || (ERROR_INSUFFICIENT_BUFFER
== GetLastError()),
1109 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1111 SetLastError(0xdeadbeef);
1112 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1113 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1114 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1117 SetLastError(0xdeadbeef);
1118 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
)-1,&needed
);
1119 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1120 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1121 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1124 pConfig
->lpDescription
= (LPSTR
)0xdeadbeef;
1125 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1126 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1127 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1128 ok(!pConfig
->lpDescription
, "expected lpDescription to be NULL, got %p\n", pConfig
->lpDescription
);
1130 SetLastError(0xdeadbeef);
1132 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1133 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1134 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1135 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1137 if(!pChangeServiceConfig2A
)
1139 skip("function ChangeServiceConfig2A not present\n");
1143 pConfig
->lpDescription
= (LPSTR
) description
;
1144 ret
= pChangeServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
);
1145 ok(ret
, "ChangeServiceConfig2A failed\n");
1150 SetLastError(0xdeadbeef);
1152 expected
= sizeof(SERVICE_DESCRIPTIONA
) + sizeof(description
) * sizeof(WCHAR
); /* !! */
1153 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1154 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1155 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1156 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1158 SetLastError(0xdeadbeef);
1159 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
-1,&needed
);
1160 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1161 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1163 SetLastError(0xdeadbeef);
1164 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
,&needed
);
1165 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1166 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1167 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1169 SetLastError(0xdeadbeef);
1170 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
+ 1,&needed
);
1171 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1172 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1173 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1175 if(!pQueryServiceConfig2W
)
1177 skip("function QueryServiceConfig2W not present\n");
1180 SetLastError(0xdeadbeef);
1182 expected
= sizeof(SERVICE_DESCRIPTIONW
) + sizeof(WCHAR
) * sizeof(description
);
1183 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1184 ok(!ret
, "expected QueryServiceConfig2W to fail\n");
1185 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1186 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1188 SetLastError(0xdeadbeef);
1189 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
,&needed
);
1190 ok(ret
, "expected QueryServiceConfig2W to succeed\n");
1193 DeleteService(svc_handle
);
1195 CloseServiceHandle(svc_handle
);
1197 /* Wait a while. The following test does a CreateService again */
1200 CloseServiceHandle(scm_handle
);
1203 static void test_refcount(void)
1205 SC_HANDLE scm_handle
, svc_handle1
, svc_handle2
, svc_handle3
, svc_handle4
, svc_handle5
;
1206 static const CHAR servicename
[] = "Winetest";
1207 static const CHAR pathname
[] = "we_dont_care.exe";
1210 /* Get a handle to the Service Control Manager */
1211 SetLastError(0xdeadbeef);
1212 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1213 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1215 skip("Not enough rights to get a handle to the manager\n");
1219 /* Create a service */
1220 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1221 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1222 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1223 ok(svc_handle1
!= NULL
, "Expected success\n");
1225 /* Get a handle to this new service */
1226 svc_handle2
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1227 ok(svc_handle2
!= NULL
, "Expected success\n");
1229 /* Get another handle to this new service */
1230 svc_handle3
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1231 ok(svc_handle3
!= NULL
, "Expected success\n");
1233 /* Check if we can close the handle to the Service Control Manager */
1234 ret
= CloseServiceHandle(scm_handle
);
1235 ok(ret
, "Expected success\n");
1237 /* Get a new handle to the Service Control Manager */
1238 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1239 ok(scm_handle
!= NULL
, "Expected success\n");
1241 /* Get a handle to this new service */
1242 svc_handle4
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1243 ok(svc_handle4
!= NULL
, "Expected success\n");
1245 /* Delete the service */
1246 ret
= DeleteService(svc_handle4
);
1247 ok(ret
, "Expected success\n");
1249 /* We cannot create the same service again as it's still marked as 'being deleted'.
1250 * The reason is that we still have 4 open handles to this service even though we
1251 * closed the handle to the Service Control Manager in between.
1253 SetLastError(0xdeadbeef);
1254 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1255 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1256 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1259 ok(!svc_handle5
, "Expected failure\n");
1260 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE
,
1261 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1264 /* FIXME: Remove this when Wine is fixed */
1267 DeleteService(svc_handle5
);
1268 CloseServiceHandle(svc_handle5
);
1271 /* Close all the handles to the service and try again */
1272 ret
= CloseServiceHandle(svc_handle4
);
1273 ok(ret
, "Expected success\n");
1274 ret
= CloseServiceHandle(svc_handle3
);
1275 ok(ret
, "Expected success\n");
1276 ret
= CloseServiceHandle(svc_handle2
);
1277 ok(ret
, "Expected success\n");
1278 ret
= CloseServiceHandle(svc_handle1
);
1279 ok(ret
, "Expected success\n");
1281 /* Wait a while. Doing a CreateService too soon will result again
1282 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1286 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1287 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1288 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1289 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1290 ok(svc_handle5
!= NULL
, "Expected success\n");
1292 /* Delete the service */
1293 ret
= DeleteService(svc_handle5
);
1294 ok(ret
, "Expected success\n");
1296 /* Wait a while. Just in case one of the following tests does a CreateService again */
1299 CloseServiceHandle(svc_handle5
);
1300 CloseServiceHandle(scm_handle
);
1305 SC_HANDLE scm_handle
;
1307 /* Bail out if we are on win98 */
1308 SetLastError(0xdeadbeef);
1309 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1311 if (!scm_handle
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
1313 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1316 CloseServiceHandle(scm_handle
);
1318 init_function_pointers();
1320 /* First some parameter checking */
1323 test_create_delete_svc();
1324 test_get_displayname();
1325 test_get_servicekeyname();
1328 /* Test the creation, querying and deletion of a service */
1330 test_queryconfig2();
1331 /* The main reason for this test is to check if any refcounting is used
1332 * and what the rules are