2 * Unit tests for service functions
4 * Copyright (c) 2007 Paul Vriens
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/test.h"
34 static const CHAR spooler
[] = "Spooler"; /* Should be available on all platforms */
36 static void test_open_scm(void)
40 /* No access rights */
41 SetLastError(0xdeadbeef);
42 scm_handle
= OpenSCManagerA(NULL
, NULL
, 0);
43 ok(scm_handle
!= NULL
, "Expected success\n");
44 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
45 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
46 GetLastError() == ERROR_IO_PENDING
/* W2K */,
47 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
48 CloseServiceHandle(scm_handle
);
50 /* Unknown database name */
51 SetLastError(0xdeadbeef);
52 scm_handle
= OpenSCManagerA(NULL
, "DoesNotExist", SC_MANAGER_CONNECT
);
53 ok(!scm_handle
, "Expected failure\n");
54 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
55 CloseServiceHandle(scm_handle
); /* Just in case */
57 /* MSDN says only ServiceActive is allowed, or NULL */
58 SetLastError(0xdeadbeef);
59 scm_handle
= OpenSCManagerA(NULL
, SERVICES_FAILED_DATABASEA
, SC_MANAGER_CONNECT
);
60 ok(!scm_handle
, "Expected failure\n");
61 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST
, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
62 CloseServiceHandle(scm_handle
); /* Just in case */
64 /* Remote unknown host */
65 SetLastError(0xdeadbeef);
66 scm_handle
= OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
67 ok(!scm_handle
, "Expected failure\n");
69 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE
, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
70 CloseServiceHandle(scm_handle
); /* Just in case */
72 /* Proper call with an empty hostname */
73 SetLastError(0xdeadbeef);
74 scm_handle
= OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
75 ok(scm_handle
!= NULL
, "Expected success\n");
76 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
77 GetLastError() == ERROR_ENVVAR_NOT_FOUND
/* NT4 */ ||
78 GetLastError() == 0xdeadbeef /* XP */ ||
79 GetLastError() == ERROR_IO_PENDING
/* W2K */,
80 "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
81 CloseServiceHandle(scm_handle
);
83 /* Again a correct one */
84 SetLastError(0xdeadbeef);
85 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
86 ok(scm_handle
!= NULL
, "Expected success\n");
87 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
88 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
89 GetLastError() == ERROR_IO_PENDING
/* W2K */,
90 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
91 CloseServiceHandle(scm_handle
);
94 static void test_open_svc(void)
96 SC_HANDLE scm_handle
, svc_handle
;
98 /* All NULL (invalid access rights) */
99 SetLastError(0xdeadbeef);
100 svc_handle
= OpenServiceA(NULL
, NULL
, 0);
101 ok(!svc_handle
, "Expected failure\n");
102 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
104 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
107 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
108 SetLastError(0xdeadbeef);
109 svc_handle
= OpenServiceA(scm_handle
, NULL
, GENERIC_READ
);
110 ok(!svc_handle
, "Expected failure\n");
111 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
112 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
113 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
115 /* Nonexistent service */
116 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
117 SetLastError(0xdeadbeef);
118 svc_handle
= OpenServiceA(scm_handle
, "deadbeef", GENERIC_READ
);
119 ok(!svc_handle
, "Expected failure\n");
120 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
121 CloseServiceHandle(scm_handle
);
123 /* Proper SCM handle but different access rights */
124 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
125 SetLastError(0xdeadbeef);
126 svc_handle
= OpenServiceA(scm_handle
, "Spooler", GENERIC_WRITE
);
127 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
128 skip("Not enough rights to get a handle to the service\n");
131 ok(svc_handle
!= NULL
, "Expected success\n");
132 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
133 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
134 GetLastError() == 0xdeadbeef /* XP, NT4 */,
135 "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
136 CloseServiceHandle(svc_handle
);
138 CloseServiceHandle(scm_handle
);
141 static void test_create_delete_svc(void)
143 SC_HANDLE scm_handle
, svc_handle1
;
144 CHAR username
[UNLEN
+ 1], domain
[MAX_PATH
];
145 DWORD user_size
= UNLEN
+ 1;
146 CHAR account
[UNLEN
+ 3];
147 static const CHAR servicename
[] = "Winetest";
148 static const CHAR pathname
[] = "we_dont_care.exe";
149 static const CHAR empty
[] = "";
150 static const CHAR password
[] = "secret";
151 BOOL spooler_exists
= FALSE
;
154 DWORD display_size
= sizeof(display
);
156 /* Get the username and turn it into an account to be used in some tests */
157 GetUserNameA(username
, &user_size
);
158 /* Get the domainname to cater for that situation */
159 if (GetEnvironmentVariableA("USERDOMAIN", domain
, MAX_PATH
))
160 sprintf(account
, "%s\\%s", domain
, username
);
162 sprintf(account
, ".\\%s", username
);
165 SetLastError(0xdeadbeef);
166 svc_handle1
= CreateServiceA(NULL
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
167 ok(!svc_handle1
, "Expected failure\n");
168 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
170 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
172 /* Only a valid handle to the Service Control Manager */
173 SetLastError(0xdeadbeef);
174 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
175 ok(!svc_handle1
, "Expected failure\n");
176 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
177 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
178 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
180 /* Now with a servicename */
181 SetLastError(0xdeadbeef);
182 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
183 ok(!svc_handle1
, "Expected failure\n");
184 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
185 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
186 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
188 /* Or just a binary name */
189 SetLastError(0xdeadbeef);
190 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
191 ok(!svc_handle1
, "Expected failure\n");
192 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
193 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
194 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
196 /* Both servicename and binary name (We only have connect rights) */
197 SetLastError(0xdeadbeef);
198 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
199 ok(!svc_handle1
, "Expected failure\n");
200 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
202 /* They can even be empty at this stage of parameter checking */
203 SetLastError(0xdeadbeef);
204 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
205 ok(!svc_handle1
, "Expected failure\n");
206 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
208 SetLastError(0xdeadbeef);
209 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
210 ok(!svc_handle1
, "Expected failure\n");
211 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
213 /* Open the Service Control Manager with minimal rights for creation
214 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
216 CloseServiceHandle(scm_handle
);
217 SetLastError(0xdeadbeef);
218 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
219 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
221 skip("Not enough rights to get a handle to the manager\n");
225 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
227 /* Empty strings for servicename and binary name are checked */
228 SetLastError(0xdeadbeef);
229 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
230 ok(!svc_handle1
, "Expected failure\n");
231 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
233 SetLastError(0xdeadbeef);
234 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
235 ok(!svc_handle1
, "Expected failure\n");
236 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
238 SetLastError(0xdeadbeef);
239 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
240 ok(!svc_handle1
, "Expected failure\n");
241 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
243 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
244 * an ERROR_INVALID_PARAMETER)
246 SetLastError(0xdeadbeef);
247 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
248 SERVICE_DISABLED
, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
249 ok(!svc_handle1
, "Expected failure\n");
250 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
252 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
254 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
255 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
257 SetLastError(0xdeadbeef);
258 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
,
259 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
260 ok(!svc_handle1
, "Expected failure\n");
261 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
263 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
264 SetLastError(0xdeadbeef);
265 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_INTERACTIVE_PROCESS
,
266 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
267 ok(!svc_handle1
, "Expected failure\n");
268 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
270 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
271 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
273 SetLastError(0xdeadbeef);
274 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
275 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, account
, password
);
276 ok(!svc_handle1
, "Expected failure\n");
277 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
279 /* Illegal (start-type is not a mask and should only be one of the possibilities)
280 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
281 * it's most likely not the wanted start-type)
283 SetLastError(0xdeadbeef);
284 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
,
285 SERVICE_AUTO_START
| SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
286 ok(!svc_handle1
, "Expected failure\n");
287 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
289 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
290 SetLastError(0xdeadbeef);
291 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
292 SERVICE_BOOT_START
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
293 ok(!svc_handle1
, "Expected failure\n");
294 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
296 /* The service already exists (check first, just in case) */
297 svc_handle1
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
300 spooler_exists
= TRUE
;
301 CloseServiceHandle(svc_handle1
);
302 SetLastError(0xdeadbeef);
303 svc_handle1
= CreateServiceA(scm_handle
, spooler
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
304 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
305 ok(!svc_handle1
, "Expected failure\n");
306 ok(GetLastError() == ERROR_SERVICE_EXISTS
, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
309 skip("Spooler service doesn't exist\n");
311 /* To find an existing displayname we check the 'Spooler' service. Although the registry
312 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
313 * to the servicename and can't be used as well for a new displayname.
317 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, display
, &display_size
);
320 skip("Could not retrieve a displayname for the Spooler service\n");
323 svc_handle1
= CreateServiceA(scm_handle
, servicename
, display
, 0, SERVICE_WIN32_OWN_PROCESS
,
324 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
325 ok(!svc_handle1
, "Expected failure\n");
326 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME
,
327 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
331 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
333 /* Windows doesn't care about the access rights for creation (which makes
334 * sense as there is no service yet) as long as there are sufficient
335 * rights to the manager.
337 SetLastError(0xdeadbeef);
338 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
339 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
340 ok(svc_handle1
!= NULL
, "Could not create the service : %d\n", GetLastError());
341 ok(GetLastError() == ERROR_SUCCESS
/* W2K3, Vista */ ||
342 GetLastError() == 0xdeadbeef /* NT4, XP */ ||
343 GetLastError() == ERROR_IO_PENDING
/* W2K */,
344 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
346 /* DeleteService however must have proper rights */
347 SetLastError(0xdeadbeef);
348 ret
= DeleteService(svc_handle1
);
349 ok(!ret
, "Expected failure\n");
350 ok(GetLastError() == ERROR_ACCESS_DENIED
,
351 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
353 /* Open the service with minimal rights for deletion.
354 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
356 CloseServiceHandle(svc_handle1
);
357 svc_handle1
= OpenServiceA(scm_handle
, servicename
, DELETE
);
359 /* Now that we have the proper rights, we should be able to delete */
360 SetLastError(0xdeadbeef);
361 ret
= DeleteService(svc_handle1
);
362 ok(ret
, "Expected success\n");
363 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
364 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
365 GetLastError() == ERROR_IO_PENDING
/* W2K */,
366 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
368 CloseServiceHandle(svc_handle1
);
370 CloseServiceHandle(scm_handle
);
372 /* Wait a while. One of the following tests also does a CreateService for the
373 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
374 * error if we do this to quick. Vista seems more picky then the others.
378 /* And a final NULL check */
379 SetLastError(0xdeadbeef);
380 ret
= DeleteService(NULL
);
381 ok(!ret
, "Expected failure\n");
382 ok(GetLastError() == ERROR_INVALID_HANDLE
,
383 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
386 static void test_get_displayname(void)
388 SC_HANDLE scm_handle
, svc_handle
;
390 CHAR displayname
[4096];
391 WCHAR displaynameW
[2048];
392 DWORD displaysize
, tempsize
, tempsizeW
;
393 static const CHAR deadbeef
[] = "Deadbeef";
394 static const WCHAR spoolerW
[] = {'S','p','o','o','l','e','r',0};
395 static const CHAR servicename
[] = "Winetest";
396 static const CHAR pathname
[] = "we_dont_care.exe";
398 /* Having NULL for the size of the buffer will crash on W2K3 */
400 SetLastError(0xdeadbeef);
401 ret
= GetServiceDisplayNameA(NULL
, NULL
, NULL
, &displaysize
);
402 ok(!ret
, "Expected failure\n");
403 ok(GetLastError() == ERROR_INVALID_HANDLE
,
404 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
406 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
408 SetLastError(0xdeadbeef);
409 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, NULL
, &displaysize
);
410 ok(!ret
, "Expected failure\n");
411 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
412 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
413 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
415 SetLastError(0xdeadbeef);
416 displaysize
= sizeof(displayname
);
417 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, displayname
, &displaysize
);
418 ok(!ret
, "Expected failure\n");
419 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
420 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
421 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
423 /* Test for nonexistent service */
424 SetLastError(0xdeadbeef);
426 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
427 ok(!ret
, "Expected failure\n");
428 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
429 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
431 /* Check if 'Spooler' exists */
432 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
435 skip("Spooler service doesn't exist\n");
436 CloseServiceHandle(scm_handle
);
439 CloseServiceHandle(svc_handle
);
441 /* Retrieve the needed size for the buffer */
442 SetLastError(0xdeadbeef);
444 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
445 ok(!ret
, "Expected failure\n");
446 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
447 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
448 tempsize
= displaysize
;
451 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
452 ok(!ret
, "Expected failure\n");
453 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
454 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
455 ok(displaysize
== tempsize
, "Buffer size mismatch (%d vs %d)\n", tempsize
, displaysize
);
457 /* Buffer is too small */
458 SetLastError(0xdeadbeef);
459 displaysize
= (tempsize
/ 2);
460 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
461 ok(!ret
, "Expected failure\n");
462 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
463 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
464 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
466 /* First try with a buffer that should be big enough to hold
467 * the ANSI string (and terminating character). This succeeds on Windows
468 * although when asked (see above 2 tests) it will return twice the needed size.
470 SetLastError(0xdeadbeef);
471 displaysize
= (tempsize
/ 2) + 1;
472 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
473 ok(ret
, "Expected success\n");
474 ok(displaysize
== ((tempsize
/ 2) + 1), "Expected no change for the needed buffer size\n");
475 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
476 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
477 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
478 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
480 /* Now with the original returned size */
481 SetLastError(0xdeadbeef);
482 displaysize
= tempsize
;
483 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
484 ok(ret
, "Expected success\n");
485 ok(displaysize
== tempsize
, "Expected no change for the needed buffer size\n");
486 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
487 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
488 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
489 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
491 /* And with a bigger than needed buffer */
492 SetLastError(0xdeadbeef);
493 displaysize
= tempsize
* 2;
494 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
495 ok(ret
, "Expected success\n");
496 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
497 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
498 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
499 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
500 /* Test that shows that if the buffersize is enough, it's not changed */
501 ok(displaysize
== tempsize
* 2, "Expected no change for the needed buffer size\n");
502 ok(lstrlen(displayname
) == tempsize
/2,
503 "Expected the buffer to be twice the length of the string\n") ;
505 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
506 SetLastError(0xdeadbeef);
508 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, NULL
, &displaysize
);
509 ok(!ret
, "Expected failure\n");
510 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
511 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
513 /* Buffer is too small */
514 SetLastError(0xdeadbeef);
515 tempsizeW
= displaysize
;
516 displaysize
= tempsizeW
/ 2;
517 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
518 ok(!ret
, "Expected failure\n");
519 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
520 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
521 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
523 /* Now with the original returned size */
524 SetLastError(0xdeadbeef);
525 displaysize
= tempsizeW
;
526 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
527 ok(!ret
, "Expected failure\n");
528 ok(displaysize
= tempsizeW
, "Expected the needed buffersize\n");
529 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
530 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
532 /* And with a bigger than needed buffer */
533 SetLastError(0xdeadbeef);
534 displaysize
= tempsizeW
+ 1; /* This caters for the null terminating character */
535 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
536 ok(ret
, "Expected success\n");
537 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
538 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
539 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
540 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
541 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
542 ok(lstrlenW(displaynameW
) == displaysize
,
543 "Expected the buffer to be the length of the string\n") ;
544 ok(tempsize
/ 2 == tempsizeW
,
545 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
547 CloseServiceHandle(scm_handle
);
549 /* Test for a service without a displayname (which is valid). This should return
550 * the servicename itself.
552 SetLastError(0xdeadbeef);
553 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
554 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
556 skip("Not enough rights to get a handle to the manager\n");
560 SetLastError(0xdeadbeef);
561 svc_handle
= CreateServiceA(scm_handle
, servicename
, NULL
, DELETE
,
562 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
563 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
564 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
567 CloseServiceHandle(scm_handle
);
571 /* Retrieve the needed size for the buffer */
572 SetLastError(0xdeadbeef);
574 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, NULL
, &displaysize
);
575 ok(!ret
, "Expected failure\n");
576 ok(displaysize
== lstrlen(servicename
) * 2,
577 "Expected the displaysize to be twice the size of the servicename\n");
578 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
579 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
581 /* Buffer is too small */
582 SetLastError(0xdeadbeef);
583 tempsize
= displaysize
;
584 displaysize
= (tempsize
/ 2);
585 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
586 ok(!ret
, "Expected failure\n");
587 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
588 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
589 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
591 /* Get the displayname */
592 SetLastError(0xdeadbeef);
593 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
594 ok(ret
, "Expected success\n");
595 ok(!lstrcmpi(displayname
, servicename
),
596 "Expected displayname to be %s, got %s\n", servicename
, displayname
);
597 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
598 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
599 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
600 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
602 /* Delete the service */
603 ret
= DeleteService(svc_handle
);
604 ok(ret
, "Expected success\n");
606 CloseServiceHandle(svc_handle
);
607 CloseServiceHandle(scm_handle
);
609 /* Wait a while. Just in case one of the following tests does a CreateService again */
613 static void test_get_servicekeyname(void)
615 SC_HANDLE scm_handle
, svc_handle
;
616 CHAR servicename
[4096];
617 CHAR displayname
[4096];
618 WCHAR servicenameW
[4096];
619 WCHAR displaynameW
[4096];
620 DWORD servicesize
, displaysize
, tempsize
;
622 static const CHAR deadbeef
[] = "Deadbeef";
623 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
625 /* Having NULL for the size of the buffer will crash on W2K3 */
627 SetLastError(0xdeadbeef);
628 ret
= GetServiceKeyNameA(NULL
, NULL
, NULL
, &servicesize
);
629 ok(!ret
, "Expected failure\n");
630 ok(GetLastError() == ERROR_INVALID_HANDLE
,
631 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
633 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
636 SetLastError(0xdeadbeef);
637 ret
= GetServiceKeyNameA(scm_handle
, NULL
, NULL
, &servicesize
);
638 ok(!ret
, "Expected failure\n");
639 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
640 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
641 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
642 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
644 /* Valid handle and buffer but no displayname */
646 SetLastError(0xdeadbeef);
647 ret
= GetServiceKeyNameA(scm_handle
, NULL
, servicename
, &servicesize
);
648 ok(!ret
, "Expected failure\n");
649 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
650 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
651 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
652 todo_wine
ok(servicesize
== 200, "Service size expected 1, got %d\n", servicesize
);
654 /* Test for nonexistent displayname */
655 SetLastError(0xdeadbeef);
656 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, NULL
, &servicesize
);
657 ok(!ret
, "Expected failure\n");
658 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
659 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
660 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
663 strcpy(servicename
, "ABC");
664 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
665 ok(!ret
, "Expected failure\n");
666 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
667 ok(servicename
[0] == 0, "Service name not empty\n");
670 servicenameW
[0] = 'A';
671 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
672 ok(!ret
, "Expected failure\n");
673 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
674 ok(servicenameW
[0] == 0, "Service name not empty\n");
677 strcpy(servicename
, "ABC");
678 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
679 ok(!ret
, "Expected failure\n");
680 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
681 ok(servicename
[0] == 'A', "Service name changed\n");
684 servicenameW
[0] = 'A';
685 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
686 ok(!ret
, "Expected failure\n");
687 todo_wine
ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
688 ok(servicenameW
[0] == 'A', "Service name changed\n");
690 /* Check if 'Spooler' exists */
691 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
694 skip("Spooler service doesn't exist\n");
695 CloseServiceHandle(scm_handle
);
698 CloseServiceHandle(svc_handle
);
700 /* Get the displayname for the 'Spooler' service */
701 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
702 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
704 /* Retrieve the needed size for the buffer */
705 SetLastError(0xdeadbeef);
707 ret
= GetServiceKeyNameA(scm_handle
, displayname
, NULL
, &servicesize
);
708 ok(!ret
, "Expected failure\n");
709 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
710 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
712 /* Valid call with the correct buffersize */
713 SetLastError(0xdeadbeef);
714 tempsize
= servicesize
;
716 ret
= GetServiceKeyNameA(scm_handle
, displayname
, servicename
, &servicesize
);
717 ok(ret
, "Expected success\n");
718 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
719 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
720 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
721 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
724 ok(lstrlen(servicename
) == tempsize
/2,
725 "Expected the buffer to be twice the length of the string\n") ;
726 ok(!lstrcmpi(servicename
, spooler
), "Expected %s, got %s\n", spooler
, servicename
);
727 ok(servicesize
== (tempsize
* 2),
728 "Expected servicesize not to change if buffer not insufficient\n") ;
731 MultiByteToWideChar(CP_ACP
, 0, displayname
, -1, displaynameW
, sizeof(displaynameW
)/2);
732 SetLastError(0xdeadbeef);
734 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
735 ok(ret
, "Expected success\n");
736 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
737 GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
738 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
739 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
742 ok(lstrlen(servicename
) == tempsize
/2,
743 "Expected the buffer to be twice the length of the string\n") ;
744 ok(servicesize
== lstrlenW(servicenameW
),
745 "Expected servicesize not to change if buffer not insufficient\n") ;
748 SetLastError(0xdeadbeef);
750 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
751 ok(!ret
, "Expected failure\n");
752 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
753 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
754 ok(servicenameW
[0] == 0, "Buffer not empty\n");
756 CloseServiceHandle(scm_handle
);
759 static void test_close(void)
765 SetLastError(0xdeadbeef);
766 ret
= CloseServiceHandle(NULL
);
767 ok(!ret
, "Expected failure\n");
768 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
770 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
773 handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
774 SetLastError(0xdeadbeef);
775 ret
= CloseServiceHandle(handle
);
776 ok(ret
, "Expected success\n");
777 ok(GetLastError() == ERROR_IO_PENDING
/* W2K */ ||
778 GetLastError() == ERROR_SUCCESS
/* W2K3 */ ||
779 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */,
780 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
783 static void test_sequence(void)
785 SC_HANDLE scm_handle
, svc_handle
;
787 QUERY_SERVICE_CONFIGA
*config
;
789 static const CHAR servicename
[] = "Winetest";
790 static const CHAR displayname
[] = "Winetest dummy service";
791 static const CHAR displayname2
[] = "Winetest dummy service (2)";
792 static const CHAR pathname
[] = "we_dont_care.exe";
793 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
794 static const CHAR password
[] = "";
795 static const CHAR empty
[] = "";
796 static const CHAR localsystem
[] = "LocalSystem";
798 SetLastError(0xdeadbeef);
799 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
801 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
803 skip("Not enough rights to get a handle to the manager\n");
807 ok(scm_handle
!= NULL
, "Could not get a handle to the manager: %d\n", GetLastError());
809 if (!scm_handle
) return;
811 /* Create a dummy service */
812 SetLastError(0xdeadbeef);
813 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
814 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
815 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
817 if (!svc_handle
&& (GetLastError() == ERROR_SERVICE_EXISTS
))
819 /* We try and open the service and do the rest of the tests. Some could
820 * fail if the tests were changed between these runs.
822 trace("Deletion probably didn't work last time\n");
823 SetLastError(0xdeadbeef);
824 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
825 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
827 skip("Not enough rights to open the service\n");
828 CloseServiceHandle(scm_handle
);
831 ok(svc_handle
!= NULL
, "Could not open the service : %d\n", GetLastError());
833 else if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
835 skip("Not enough rights to create the service\n");
836 CloseServiceHandle(scm_handle
);
840 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
842 if (!svc_handle
) return;
845 * Before we do a QueryServiceConfig we should check the registry. This will make sure
846 * that the correct keys are used.
849 /* Request the size for the buffer */
850 SetLastError(0xdeadbeef);
851 ret
= QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
852 ok(!ret
, "Expected failure\n");
853 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
855 config
= HeapAlloc(GetProcessHeap(), 0, needed
);
857 SetLastError(0xdeadbeef);
858 ret
= QueryServiceConfigA(svc_handle
, config
, given
, &needed
);
859 ok(ret
, "Expected success\n");
860 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
861 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
862 GetLastError() == ERROR_IO_PENDING
/* W2K */,
863 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
866 ok(given
== needed
, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given
, needed
);
868 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
869 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
870 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
871 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
872 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
873 ok(config
->dwErrorControl
== SERVICE_ERROR_IGNORE
, "Expected SERVICE_ERROR_IGNORE, got %d\n", config
->dwErrorControl
);
874 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
875 ok(!strcmp(config
->lpLoadOrderGroup
, empty
), "Expected an empty string, got '%s'\n", config
->lpLoadOrderGroup
);
876 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
877 /* TODO: Show the double 0 terminated string */
880 ok(!memcmp(config
->lpDependencies
, dependencies
, sizeof(dependencies
)), "Wrong string\n");
882 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
883 ok(!strcmp(config
->lpDisplayName
, displayname
), "Expected '%s', got '%s'\n", displayname
, config
->lpDisplayName
);
885 ok(ChangeServiceConfigA(svc_handle
, SERVICE_NO_CHANGE
, SERVICE_NO_CHANGE
, SERVICE_ERROR_NORMAL
, NULL
, "TestGroup2", NULL
, NULL
, NULL
, NULL
, displayname2
),
886 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
888 QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
889 config
= HeapReAlloc(GetProcessHeap(), 0, config
, needed
);
890 ok(QueryServiceConfigA(svc_handle
, config
, needed
, &needed
), "QueryServiceConfig failed\n");
891 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
892 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
893 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
894 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
895 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
896 ok(config
->dwErrorControl
== SERVICE_ERROR_NORMAL
, "Expected SERVICE_ERROR_NORMAL, got %d\n", config
->dwErrorControl
);
897 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
898 ok(!strcmp(config
->lpLoadOrderGroup
, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config
->lpLoadOrderGroup
);
899 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
900 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
901 ok(!strcmp(config
->lpDisplayName
, displayname2
), "Expected '%s', got '%s'\n", displayname2
, config
->lpDisplayName
);
903 SetLastError(0xdeadbeef);
904 ret
= DeleteService(svc_handle
);
905 ok(ret
, "Expected success\n");
906 ok(GetLastError() == ERROR_SUCCESS
/* W2K3 */||
907 GetLastError() == 0xdeadbeef /* NT4, XP, Vista */ ||
908 GetLastError() == ERROR_IO_PENDING
/* W2K */,
909 "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
911 CloseServiceHandle(svc_handle
);
913 /* Wait a while. The following test does a CreateService again */
916 CloseServiceHandle(scm_handle
);
917 HeapFree(GetProcessHeap(), 0, config
);
920 static void test_queryconfig2(void)
922 SC_HANDLE scm_handle
, svc_handle
;
924 DWORD expected
, needed
;
925 BYTE buffer
[MAX_PATH
];
926 LPSERVICE_DESCRIPTIONA pConfig
= (LPSERVICE_DESCRIPTIONA
)buffer
;
927 static const CHAR servicename
[] = "Winetest";
928 static const CHAR displayname
[] = "Winetest dummy service";
929 static const CHAR pathname
[] = "we_dont_care.exe";
930 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
931 static const CHAR password
[] = "";
932 static const CHAR description
[] = "Description";
933 HMODULE dllhandle
= GetModuleHandleA("advapi32.dll");
934 BOOL (WINAPI
*pChangeServiceConfig2A
)(SC_HANDLE
,DWORD
,LPVOID
)
935 = (void*)GetProcAddress(dllhandle
, "ChangeServiceConfig2A");
936 BOOL (WINAPI
*pQueryServiceConfig2A
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
)
937 = (void*)GetProcAddress(dllhandle
, "QueryServiceConfig2A");
938 BOOL (WINAPI
*pQueryServiceConfig2W
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
)
939 = (void*)GetProcAddress(dllhandle
, "QueryServiceConfig2W");
940 if(!pQueryServiceConfig2A
)
942 skip("function QueryServiceConfig2A not present\n");
946 SetLastError(0xdeadbeef);
947 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
951 if(GetLastError() == ERROR_ACCESS_DENIED
)
952 skip("Not enough rights to get a handle to the manager\n");
954 ok(FALSE
, "Could not get a handle to the manager: %d\n", GetLastError());
958 /* Create a dummy service */
959 SetLastError(0xdeadbeef);
960 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
961 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
962 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
966 if(GetLastError() == ERROR_SERVICE_EXISTS
)
968 /* We try and open the service and do the rest of the tests. Some could
969 * fail if the tests were changed between these runs.
971 trace("Deletion probably didn't work last time\n");
972 SetLastError(0xdeadbeef);
973 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
976 if(GetLastError() == ERROR_ACCESS_DENIED
)
977 skip("Not enough rights to open the service\n");
979 ok(FALSE
, "Could not open the service : %d\n", GetLastError());
980 CloseServiceHandle(scm_handle
);
984 if (GetLastError() == ERROR_ACCESS_DENIED
)
986 skip("Not enough rights to create the service\n");
987 CloseServiceHandle(scm_handle
);
990 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
993 CloseServiceHandle(scm_handle
);
997 SetLastError(0xdeadbeef);
998 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
999 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1000 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1002 SetLastError(0xdeadbeef);
1003 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1004 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1005 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1007 SetLastError(0xdeadbeef);
1008 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1009 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1010 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1012 SetLastError(0xdeadbeef);
1013 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1014 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1015 ok((ERROR_INVALID_ADDRESS
== GetLastError()) || (ERROR_INSUFFICIENT_BUFFER
== GetLastError()),
1016 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1018 SetLastError(0xdeadbeef);
1019 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1020 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1021 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1024 SetLastError(0xdeadbeef);
1025 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
)-1,&needed
);
1026 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1027 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1028 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1031 pConfig
->lpDescription
= (LPSTR
)0xdeadbeef;
1032 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1033 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1034 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1035 ok(!pConfig
->lpDescription
, "expected lpDescription to be NULL, got %p\n", pConfig
->lpDescription
);
1037 SetLastError(0xdeadbeef);
1039 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1040 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1041 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1042 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1044 if(!pChangeServiceConfig2A
)
1046 skip("function ChangeServiceConfig2A not present\n");
1050 pConfig
->lpDescription
= (LPSTR
) description
;
1051 ret
= pChangeServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
);
1052 ok(ret
, "ChangeServiceConfig2A failed\n");
1057 SetLastError(0xdeadbeef);
1059 expected
= sizeof(SERVICE_DESCRIPTIONA
) + sizeof(description
) * sizeof(WCHAR
); /* !! */
1060 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1061 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1062 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1063 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1065 SetLastError(0xdeadbeef);
1066 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
-1,&needed
);
1067 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1068 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1070 SetLastError(0xdeadbeef);
1071 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
,&needed
);
1072 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1073 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1074 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1076 SetLastError(0xdeadbeef);
1077 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
+ 1,&needed
);
1078 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1079 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1080 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1082 if(!pQueryServiceConfig2W
)
1084 skip("function QueryServiceConfig2W not present\n");
1087 SetLastError(0xdeadbeef);
1089 expected
= sizeof(SERVICE_DESCRIPTIONW
) + sizeof(WCHAR
) * sizeof(description
);
1090 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1091 ok(!ret
, "expected QueryServiceConfig2W to fail\n");
1092 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1093 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1095 SetLastError(0xdeadbeef);
1096 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
,&needed
);
1097 ok(ret
, "expected QueryServiceConfig2W to succeed\n");
1100 DeleteService(svc_handle
);
1102 CloseServiceHandle(svc_handle
);
1104 /* Wait a while. The following test does a CreateService again */
1107 CloseServiceHandle(scm_handle
);
1110 static void test_refcount(void)
1112 SC_HANDLE scm_handle
, svc_handle1
, svc_handle2
, svc_handle3
, svc_handle4
, svc_handle5
;
1113 static const CHAR servicename
[] = "Winetest";
1114 static const CHAR pathname
[] = "we_dont_care.exe";
1117 /* Get a handle to the Service Control Manager */
1118 SetLastError(0xdeadbeef);
1119 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1120 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1122 skip("Not enough rights to get a handle to the manager\n");
1126 /* Create a service */
1127 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1128 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1129 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1130 ok(svc_handle1
!= NULL
, "Expected success\n");
1132 /* Get a handle to this new service */
1133 svc_handle2
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1134 ok(svc_handle2
!= NULL
, "Expected success\n");
1136 /* Get another handle to this new service */
1137 svc_handle3
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
1138 ok(svc_handle3
!= NULL
, "Expected success\n");
1140 /* Check if we can close the handle to the Service Control Manager */
1141 ret
= CloseServiceHandle(scm_handle
);
1142 ok(ret
, "Expected success\n");
1144 /* Get a new handle to the Service Control Manager */
1145 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1146 ok(scm_handle
!= NULL
, "Expected success\n");
1148 /* Get a handle to this new service */
1149 svc_handle4
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1150 ok(svc_handle4
!= NULL
, "Expected success\n");
1152 /* Delete the service */
1153 ret
= DeleteService(svc_handle4
);
1154 ok(ret
, "Expected success\n");
1156 /* We cannot create the same service again as it's still marked as 'being deleted'.
1157 * The reason is that we still have 4 open handles to this service even though we
1158 * closed the handle to the Service Control Manager in between.
1160 SetLastError(0xdeadbeef);
1161 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1162 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1163 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1166 ok(!svc_handle5
, "Expected failure\n");
1167 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE
,
1168 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
1171 /* FIXME: Remove this when Wine is fixed */
1174 DeleteService(svc_handle5
);
1175 CloseServiceHandle(svc_handle5
);
1178 /* Close all the handles to the service and try again */
1179 ret
= CloseServiceHandle(svc_handle4
);
1180 ok(ret
, "Expected success\n");
1181 ret
= CloseServiceHandle(svc_handle3
);
1182 ok(ret
, "Expected success\n");
1183 ret
= CloseServiceHandle(svc_handle2
);
1184 ok(ret
, "Expected success\n");
1185 ret
= CloseServiceHandle(svc_handle1
);
1186 ok(ret
, "Expected success\n");
1188 /* Wait a while. Doing a CreateService too soon will result again
1189 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
1193 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
1194 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
1195 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
1196 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
1197 ok(svc_handle5
!= NULL
, "Expected success\n");
1199 /* Delete the service */
1200 ret
= DeleteService(svc_handle5
);
1201 ok(ret
, "Expected success\n");
1203 /* Wait a while. Just in case one of the following tests does a CreateService again */
1206 CloseServiceHandle(svc_handle5
);
1207 CloseServiceHandle(scm_handle
);
1212 SC_HANDLE scm_handle
;
1214 /* Bail out if we are on win98 */
1215 SetLastError(0xdeadbeef);
1216 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1218 if (!scm_handle
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
1220 skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
1223 CloseServiceHandle(scm_handle
);
1225 /* First some parameter checking */
1228 test_create_delete_svc();
1229 test_get_displayname();
1230 test_get_servicekeyname();
1232 /* Test the creation, querying and deletion of a service */
1234 test_queryconfig2();
1235 /* The main reason for this test is to check if any refcounting is used
1236 * and what the rules are