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
*pEnumServicesStatusExA
)(SC_HANDLE
, SC_ENUM_TYPE
, DWORD
,
38 DWORD
, LPBYTE
, DWORD
, LPDWORD
,
39 LPDWORD
, LPDWORD
, LPCSTR
);
40 static BOOL (WINAPI
*pQueryServiceConfig2A
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
);
41 static BOOL (WINAPI
*pQueryServiceConfig2W
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
);
42 static BOOL (WINAPI
*pQueryServiceStatusEx
)(SC_HANDLE
, SC_STATUS_TYPE
, LPBYTE
,
45 static void init_function_pointers(void)
47 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
49 pChangeServiceConfig2A
= (void*)GetProcAddress(hadvapi32
, "ChangeServiceConfig2A");
50 pEnumServicesStatusExA
= (void*)GetProcAddress(hadvapi32
, "EnumServicesStatusExA");
51 pQueryServiceConfig2A
= (void*)GetProcAddress(hadvapi32
, "QueryServiceConfig2A");
52 pQueryServiceConfig2W
= (void*)GetProcAddress(hadvapi32
, "QueryServiceConfig2W");
53 pQueryServiceStatusEx
= (void*)GetProcAddress(hadvapi32
, "QueryServiceStatusEx");
56 static void test_open_scm(void)
60 /* No access rights */
61 SetLastError(0xdeadbeef);
62 scm_handle
= OpenSCManagerA(NULL
, NULL
, 0);
63 ok(scm_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
64 CloseServiceHandle(scm_handle
);
66 /* Unknown database name */
67 SetLastError(0xdeadbeef);
68 scm_handle
= OpenSCManagerA(NULL
, "DoesNotExist", SC_MANAGER_CONNECT
);
69 ok(!scm_handle
, "Expected failure\n");
70 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
71 CloseServiceHandle(scm_handle
); /* Just in case */
73 /* MSDN says only ServiceActive is allowed, or NULL */
74 SetLastError(0xdeadbeef);
75 scm_handle
= OpenSCManagerA(NULL
, SERVICES_FAILED_DATABASEA
, SC_MANAGER_CONNECT
);
76 ok(!scm_handle
, "Expected failure\n");
77 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST
, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
78 CloseServiceHandle(scm_handle
); /* Just in case */
80 /* Remote unknown host */
81 SetLastError(0xdeadbeef);
82 scm_handle
= OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
85 ok(!scm_handle
, "Expected failure\n");
86 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE
|| GetLastError() == RPC_S_INVALID_NET_ADDR
/* w2k8 */,
87 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
89 CloseServiceHandle(scm_handle
); /* Just in case */
91 /* Proper call with an empty hostname */
92 SetLastError(0xdeadbeef);
93 scm_handle
= OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
94 ok(scm_handle
!= NULL
, "Expected success, got error %u\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, got error %u\n", GetLastError());
101 CloseServiceHandle(scm_handle
);
104 static void test_open_svc(void)
106 SC_HANDLE scm_handle
, svc_handle
;
107 CHAR displayname
[4096];
110 /* All NULL (invalid access rights) */
111 SetLastError(0xdeadbeef);
112 svc_handle
= OpenServiceA(NULL
, NULL
, 0);
113 ok(!svc_handle
, "Expected failure\n");
114 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
116 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
119 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
120 SetLastError(0xdeadbeef);
121 svc_handle
= OpenServiceA(scm_handle
, NULL
, GENERIC_READ
);
122 ok(!svc_handle
, "Expected failure\n");
123 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
124 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
125 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
127 /* Nonexistent service */
128 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
129 SetLastError(0xdeadbeef);
130 svc_handle
= OpenServiceA(scm_handle
, "deadbeef", GENERIC_READ
);
131 ok(!svc_handle
, "Expected failure\n");
132 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
133 CloseServiceHandle(scm_handle
);
135 /* Proper SCM handle but different access rights */
136 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
137 SetLastError(0xdeadbeef);
138 svc_handle
= OpenServiceA(scm_handle
, "Spooler", GENERIC_WRITE
);
139 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
140 skip("Not enough rights to get a handle to the service\n");
143 ok(svc_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
144 CloseServiceHandle(svc_handle
);
147 /* Test to show we can't open a service with the displayname */
149 /* Retrieve the needed size for the buffer */
151 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
152 /* Get the displayname */
153 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
154 /* Try to open the service with this displayname, unless the displayname equals
155 * the servicename as that would defeat the purpose of this test.
157 if (!lstrcmpi(spooler
, displayname
))
159 skip("displayname equals servicename\n");
160 CloseServiceHandle(scm_handle
);
164 SetLastError(0xdeadbeef);
165 svc_handle
= OpenServiceA(scm_handle
, displayname
, GENERIC_READ
);
166 ok(!svc_handle
, "Expected failure\n");
167 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
169 CloseServiceHandle(svc_handle
);
171 CloseServiceHandle(scm_handle
);
174 static void test_create_delete_svc(void)
176 SC_HANDLE scm_handle
, svc_handle1
;
177 CHAR username
[UNLEN
+ 1], domain
[MAX_PATH
];
178 DWORD user_size
= UNLEN
+ 1;
179 CHAR account
[UNLEN
+ 3];
180 static const CHAR servicename
[] = "Winetest";
181 static const CHAR pathname
[] = "we_dont_care.exe";
182 static const CHAR empty
[] = "";
183 static const CHAR password
[] = "secret";
184 BOOL spooler_exists
= FALSE
;
187 DWORD display_size
= sizeof(display
);
189 /* Get the username and turn it into an account to be used in some tests */
190 GetUserNameA(username
, &user_size
);
191 /* Get the domainname to cater for that situation */
192 if (GetEnvironmentVariableA("USERDOMAIN", domain
, MAX_PATH
))
193 sprintf(account
, "%s\\%s", domain
, username
);
195 sprintf(account
, ".\\%s", username
);
198 SetLastError(0xdeadbeef);
199 svc_handle1
= CreateServiceA(NULL
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
200 ok(!svc_handle1
, "Expected failure\n");
201 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
203 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
205 /* Only a valid handle to the Service Control Manager */
206 SetLastError(0xdeadbeef);
207 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
208 ok(!svc_handle1
, "Expected failure\n");
209 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
210 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
211 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
213 /* Now with a servicename */
214 SetLastError(0xdeadbeef);
215 svc_handle1
= CreateServiceA(scm_handle
, servicename
, 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 /* Or just a binary name */
222 SetLastError(0xdeadbeef);
223 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, pathname
, 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 /* Both servicename and binary name (We only have connect rights) */
230 SetLastError(0xdeadbeef);
231 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
232 ok(!svc_handle1
, "Expected failure\n");
233 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
235 /* They can even be empty at this stage of parameter checking */
236 SetLastError(0xdeadbeef);
237 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
238 ok(!svc_handle1
, "Expected failure\n");
239 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
241 SetLastError(0xdeadbeef);
242 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
243 ok(!svc_handle1
, "Expected failure\n");
244 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
246 /* Open the Service Control Manager with minimal rights for creation
247 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
249 CloseServiceHandle(scm_handle
);
250 SetLastError(0xdeadbeef);
251 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
252 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
254 skip("Not enough rights to get a handle to the manager\n");
258 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
260 /* Empty strings for servicename and binary name are checked */
261 SetLastError(0xdeadbeef);
262 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
263 ok(!svc_handle1
, "Expected failure\n");
264 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
266 SetLastError(0xdeadbeef);
267 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
268 ok(!svc_handle1
, "Expected failure\n");
269 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
271 SetLastError(0xdeadbeef);
272 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
273 ok(!svc_handle1
, "Expected failure\n");
274 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
276 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
277 * an ERROR_INVALID_PARAMETER)
279 SetLastError(0xdeadbeef);
280 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
281 SERVICE_DISABLED
, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
282 ok(!svc_handle1
, "Expected failure\n");
283 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
285 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
287 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
288 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
290 SetLastError(0xdeadbeef);
291 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
,
292 SERVICE_DISABLED
, 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 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
297 SetLastError(0xdeadbeef);
298 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_INTERACTIVE_PROCESS
,
299 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
300 ok(!svc_handle1
, "Expected failure\n");
301 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
303 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
304 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
306 SetLastError(0xdeadbeef);
307 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
308 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, account
, password
);
309 ok(!svc_handle1
, "Expected failure\n");
310 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT
,
311 "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError());
313 /* Illegal (start-type is not a mask and should only be one of the possibilities)
314 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
315 * it's most likely not the wanted start-type)
317 SetLastError(0xdeadbeef);
318 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
,
319 SERVICE_AUTO_START
| SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
320 ok(!svc_handle1
, "Expected failure\n");
321 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
323 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
324 SetLastError(0xdeadbeef);
325 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
326 SERVICE_BOOT_START
, 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 /* The service already exists (check first, just in case) */
331 svc_handle1
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
334 spooler_exists
= TRUE
;
335 CloseServiceHandle(svc_handle1
);
336 SetLastError(0xdeadbeef);
337 svc_handle1
= CreateServiceA(scm_handle
, spooler
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
338 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
339 ok(!svc_handle1
, "Expected failure\n");
340 ok(GetLastError() == ERROR_SERVICE_EXISTS
, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
343 skip("Spooler service doesn't exist\n");
345 /* To find an existing displayname we check the 'Spooler' service. Although the registry
346 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
347 * to the servicename and can't be used as well for a new displayname.
351 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, display
, &display_size
);
354 skip("Could not retrieve a displayname for the Spooler service\n");
357 svc_handle1
= CreateServiceA(scm_handle
, servicename
, display
, 0, SERVICE_WIN32_OWN_PROCESS
,
358 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
359 ok(!svc_handle1
, "Expected failure\n");
360 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME
,
361 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
365 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
367 /* Windows doesn't care about the access rights for creation (which makes
368 * sense as there is no service yet) as long as there are sufficient
369 * rights to the manager.
371 SetLastError(0xdeadbeef);
372 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
373 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
374 ok(svc_handle1
!= NULL
, "Could not create the service : %d\n", GetLastError());
376 /* DeleteService however must have proper rights */
377 SetLastError(0xdeadbeef);
378 ret
= DeleteService(svc_handle1
);
379 ok(!ret
, "Expected failure\n");
380 ok(GetLastError() == ERROR_ACCESS_DENIED
,
381 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
383 /* Open the service with minimal rights for deletion.
384 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
386 CloseServiceHandle(svc_handle1
);
387 svc_handle1
= OpenServiceA(scm_handle
, servicename
, DELETE
);
389 /* Now that we have the proper rights, we should be able to delete */
390 SetLastError(0xdeadbeef);
391 ret
= DeleteService(svc_handle1
);
392 ok(ret
, "Expected success, got error %u\n", GetLastError());
394 CloseServiceHandle(svc_handle1
);
395 CloseServiceHandle(scm_handle
);
397 /* Wait a while. One of the following tests also does a CreateService for the
398 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
399 * error if we do this to quick. Vista seems more picky then the others.
403 /* And a final NULL check */
404 SetLastError(0xdeadbeef);
405 ret
= DeleteService(NULL
);
406 ok(!ret
, "Expected failure\n");
407 ok(GetLastError() == ERROR_INVALID_HANDLE
,
408 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
411 static void test_get_displayname(void)
413 SC_HANDLE scm_handle
, svc_handle
;
415 CHAR displayname
[4096];
416 WCHAR displaynameW
[2048];
417 DWORD displaysize
, tempsize
, tempsizeW
;
418 static const CHAR deadbeef
[] = "Deadbeef";
419 static const WCHAR spoolerW
[] = {'S','p','o','o','l','e','r',0};
420 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
421 static const WCHAR abcW
[] = {'A','B','C',0};
422 static const CHAR servicename
[] = "Winetest";
423 static const CHAR pathname
[] = "we_dont_care.exe";
425 /* Having NULL for the size of the buffer will crash on W2K3 */
427 SetLastError(0xdeadbeef);
428 ret
= GetServiceDisplayNameA(NULL
, NULL
, NULL
, &displaysize
);
429 ok(!ret
, "Expected failure\n");
430 ok(GetLastError() == ERROR_INVALID_HANDLE
,
431 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
433 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
435 SetLastError(0xdeadbeef);
436 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, NULL
, &displaysize
);
437 ok(!ret
, "Expected failure\n");
438 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
439 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
440 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
442 SetLastError(0xdeadbeef);
443 displaysize
= sizeof(displayname
);
444 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, displayname
, &displaysize
);
445 ok(!ret
, "Expected failure\n");
446 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
447 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
448 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
450 /* Test for nonexistent service */
451 SetLastError(0xdeadbeef);
453 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
454 ok(!ret
, "Expected failure\n");
455 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
456 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
458 SetLastError(0xdeadbeef);
459 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
460 ok(!ret
, "Expected failure\n");
461 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
462 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
463 todo_wine
ok(displaysize
== 1, "Service size expected 1, got %d\n", displaysize
);
466 strcpy(displayname
, "ABC");
467 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &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());
471 todo_wine
ok(displaysize
== 15, "Service size expected 15, got %d\n", displaysize
);
472 ok(displayname
[0] == 0, "Service name not empty\n");
475 lstrcpyW( displaynameW
, abcW
);
476 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
477 ok(!ret
, "Expected failure\n");
478 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
479 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
480 ok(displaysize
== 15, "Service size expected 15, got %d\n", displaysize
);
481 ok(displaynameW
[0] == 0, "Service name not empty\n");
484 strcpy(displayname
, "ABC");
485 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
486 ok(!ret
, "Expected failure\n");
487 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
488 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
489 todo_wine
ok(displaysize
== 1, "Service size expected 1, got %d\n", displaysize
);
490 ok(displayname
[0] == 'A', "Service name changed\n");
493 lstrcpyW( displaynameW
, abcW
);
494 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
495 ok(!ret
, "Expected failure\n");
496 ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
497 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
498 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
499 ok(displaynameW
[0] == 'A', "Service name changed\n");
502 strcpy(displayname
, "ABC");
503 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
504 ok(!ret
, "Expected failure\n");
505 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
506 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
507 todo_wine
ok(displaysize
== 1, "Service size expected 1, got %d\n", displaysize
);
508 ok(displayname
[0] == 0, "Service name not empty\n");
511 lstrcpyW( displaynameW
, abcW
);
512 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
513 ok(!ret
, "Expected failure\n");
514 ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
515 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
516 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
517 ok(displaynameW
[0] == 'A', "Service name changed\n");
520 strcpy(displayname
, "ABC");
521 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
522 ok(!ret
, "Expected failure\n");
523 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
524 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
525 todo_wine
ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
526 ok(displayname
[0] == 0, "Service name not empty\n");
529 lstrcpyW( displaynameW
, abcW
);
530 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
531 ok(!ret
, "Expected failure\n");
532 ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
533 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
534 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
535 ok(displaynameW
[0] == 0, "Service name not empty\n");
537 /* Check if 'Spooler' exists */
538 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
541 skip("Spooler service doesn't exist\n");
542 CloseServiceHandle(scm_handle
);
545 CloseServiceHandle(svc_handle
);
547 /* Retrieve the needed size for the buffer */
548 SetLastError(0xdeadbeef);
550 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
551 ok(!ret
, "Expected failure\n");
552 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
553 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
554 tempsize
= displaysize
;
557 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
558 ok(!ret
, "Expected failure\n");
559 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
560 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
561 ok(displaysize
== tempsize
, "Buffer size mismatch (%d vs %d)\n", tempsize
, displaysize
);
563 /* Buffer is too small */
564 SetLastError(0xdeadbeef);
565 displaysize
= (tempsize
/ 2);
566 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
567 ok(!ret
, "Expected failure\n");
568 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
569 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
570 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
572 /* First try with a buffer that should be big enough to hold
573 * the ANSI string (and terminating character). This succeeds on Windows
574 * although when asked (see above 2 tests) it will return twice the needed size.
576 SetLastError(0xdeadbeef);
577 displaysize
= (tempsize
/ 2) + 1;
578 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
579 ok(ret
, "Expected success, got error %u\n", GetLastError());
580 ok(displaysize
== ((tempsize
/ 2) + 1), "Expected no change for the needed buffer size\n");
582 /* Now with the original returned size */
583 SetLastError(0xdeadbeef);
584 displaysize
= tempsize
;
585 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
586 ok(ret
, "Expected success, got error %u\n", GetLastError());
587 ok(displaysize
== tempsize
, "Expected no change for the needed buffer size\n");
589 /* And with a bigger than needed buffer */
590 SetLastError(0xdeadbeef);
591 displaysize
= tempsize
* 2;
592 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
593 ok(ret
, "Expected success, got error %u\n", GetLastError());
594 /* Test that shows that if the buffersize is enough, it's not changed */
595 ok(displaysize
== tempsize
* 2, "Expected no change for the needed buffer size\n");
596 ok(lstrlen(displayname
) == tempsize
/2,
597 "Expected the buffer to be twice the length of the string\n") ;
599 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
600 SetLastError(0xdeadbeef);
602 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, NULL
, &displaysize
);
603 ok(!ret
, "Expected failure\n");
604 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
605 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
607 /* Buffer is too small */
608 SetLastError(0xdeadbeef);
609 tempsizeW
= displaysize
;
610 displaysize
= tempsizeW
/ 2;
611 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
612 ok(!ret
, "Expected failure\n");
613 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
614 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
615 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
617 /* Now with the original returned size */
618 SetLastError(0xdeadbeef);
619 displaysize
= tempsizeW
;
620 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
621 ok(!ret
, "Expected failure\n");
622 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
623 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
624 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
626 /* And with a bigger than needed buffer */
627 SetLastError(0xdeadbeef);
628 displaysize
= tempsizeW
+ 1; /* This caters for the null terminating character */
629 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
630 ok(ret
, "Expected success, got error %u\n", GetLastError());
631 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
632 ok(lstrlenW(displaynameW
) == displaysize
,
633 "Expected the buffer to be the length of the string\n") ;
634 ok(tempsize
/ 2 == tempsizeW
,
635 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
637 CloseServiceHandle(scm_handle
);
639 /* Test for a service without a displayname (which is valid). This should return
640 * the servicename itself.
642 SetLastError(0xdeadbeef);
643 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
644 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
646 skip("Not enough rights to get a handle to the manager\n");
650 SetLastError(0xdeadbeef);
651 svc_handle
= CreateServiceA(scm_handle
, servicename
, NULL
, DELETE
,
652 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
653 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
654 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
657 CloseServiceHandle(scm_handle
);
661 /* Retrieve the needed size for the buffer */
662 SetLastError(0xdeadbeef);
664 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, NULL
, &displaysize
);
665 ok(!ret
, "Expected failure\n");
666 ok(displaysize
== lstrlen(servicename
) * 2,
667 "Expected the displaysize to be twice the size of the servicename\n");
668 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
669 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
671 /* Buffer is too small */
672 SetLastError(0xdeadbeef);
673 tempsize
= displaysize
;
674 displaysize
= (tempsize
/ 2);
675 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
676 ok(!ret
, "Expected failure\n");
677 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
678 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
679 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
681 /* Get the displayname */
682 SetLastError(0xdeadbeef);
683 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
684 ok(ret
, "Expected success, got error %u\n", GetLastError());
685 ok(!lstrcmpi(displayname
, servicename
),
686 "Expected displayname to be %s, got %s\n", servicename
, displayname
);
688 /* Delete the service */
689 ret
= DeleteService(svc_handle
);
690 ok(ret
, "Expected success (err=%d)\n", GetLastError());
692 CloseServiceHandle(svc_handle
);
693 CloseServiceHandle(scm_handle
);
695 /* Wait a while. Just in case one of the following tests does a CreateService again */
699 static void test_get_servicekeyname(void)
701 SC_HANDLE scm_handle
, svc_handle
;
702 CHAR servicename
[4096];
703 CHAR displayname
[4096];
704 WCHAR servicenameW
[4096];
705 WCHAR displaynameW
[4096];
706 DWORD servicesize
, displaysize
, tempsize
;
708 static const CHAR deadbeef
[] = "Deadbeef";
709 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
710 static const WCHAR abcW
[] = {'A','B','C',0};
712 /* Having NULL for the size of the buffer will crash on W2K3 */
714 SetLastError(0xdeadbeef);
715 ret
= GetServiceKeyNameA(NULL
, NULL
, NULL
, &servicesize
);
716 ok(!ret
, "Expected failure\n");
717 ok(GetLastError() == ERROR_INVALID_HANDLE
,
718 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
720 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
723 SetLastError(0xdeadbeef);
724 ret
= GetServiceKeyNameA(scm_handle
, NULL
, NULL
, &servicesize
);
725 ok(!ret
, "Expected failure\n");
726 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
727 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
728 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
729 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
731 /* Valid handle and buffer but no displayname */
733 SetLastError(0xdeadbeef);
734 ret
= GetServiceKeyNameA(scm_handle
, NULL
, servicename
, &servicesize
);
735 ok(!ret
, "Expected failure\n");
736 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
737 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
738 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
739 todo_wine
ok(servicesize
== 200, "Service size expected 1, got %d\n", servicesize
);
741 /* Test for nonexistent displayname */
742 SetLastError(0xdeadbeef);
743 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, NULL
, &servicesize
);
744 ok(!ret
, "Expected failure\n");
745 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
746 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
747 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
750 strcpy(servicename
, "ABC");
751 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
752 ok(!ret
, "Expected failure\n");
753 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
754 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
755 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
756 ok(servicename
[0] == 0, "Service name not empty\n");
759 lstrcpyW( servicenameW
, abcW
);
760 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
761 ok(!ret
, "Expected failure\n");
762 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
763 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
764 ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
765 ok(servicenameW
[0] == 0, "Service name not empty\n");
768 strcpy(servicename
, "ABC");
769 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
770 ok(!ret
, "Expected failure\n");
771 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
772 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
773 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
774 ok(servicename
[0] == 'A', "Service name changed\n");
777 lstrcpyW( servicenameW
, abcW
);
778 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
779 ok(!ret
, "Expected failure\n");
780 ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
781 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
782 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
783 ok(servicenameW
[0] == 'A', "Service name changed\n");
786 strcpy(servicename
, "ABC");
787 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
788 ok(!ret
, "Expected failure\n");
789 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
790 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
791 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
792 ok(servicename
[0] == 0, "Service name not empty\n");
795 lstrcpyW( servicenameW
, abcW
);
796 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
797 ok(!ret
, "Expected failure\n");
798 ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
799 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
800 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
801 ok(servicenameW
[0] == 'A', "Service name changed\n");
804 strcpy(servicename
, "ABC");
805 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
806 ok(!ret
, "Expected failure\n");
807 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
808 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
809 todo_wine
ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
810 ok(servicename
[0] == 0, "Service name not empty\n");
813 lstrcpyW( servicenameW
, abcW
);
814 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
815 ok(!ret
, "Expected failure\n");
816 ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
817 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
818 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
819 ok(servicenameW
[0] == 0, "Service name not empty\n");
821 /* Check if 'Spooler' exists */
822 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
825 skip("Spooler service doesn't exist\n");
826 CloseServiceHandle(scm_handle
);
829 CloseServiceHandle(svc_handle
);
831 /* Get the displayname for the 'Spooler' service */
832 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
833 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
835 /* Retrieve the needed size for the buffer */
836 SetLastError(0xdeadbeef);
838 ret
= GetServiceKeyNameA(scm_handle
, displayname
, NULL
, &servicesize
);
839 ok(!ret
, "Expected failure\n");
840 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
841 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
843 /* Valid call with the correct buffersize */
844 SetLastError(0xdeadbeef);
845 tempsize
= servicesize
;
847 ret
= GetServiceKeyNameA(scm_handle
, displayname
, servicename
, &servicesize
);
848 ok(ret
, "Expected success, got error %u\n", GetLastError());
851 ok(lstrlen(servicename
) == tempsize
/2,
852 "Expected the buffer to be twice the length of the string\n") ;
853 ok(!lstrcmpi(servicename
, spooler
), "Expected %s, got %s\n", spooler
, servicename
);
854 ok(servicesize
== (tempsize
* 2),
855 "Expected servicesize not to change if buffer not insufficient\n") ;
858 MultiByteToWideChar(CP_ACP
, 0, displayname
, -1, displaynameW
, sizeof(displaynameW
)/2);
859 SetLastError(0xdeadbeef);
861 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
862 ok(ret
, "Expected success, got error %u\n", GetLastError());
865 ok(lstrlen(servicename
) == tempsize
/2,
866 "Expected the buffer to be twice the length of the string\n") ;
867 ok(servicesize
== lstrlenW(servicenameW
),
868 "Expected servicesize not to change if buffer not insufficient\n") ;
871 SetLastError(0xdeadbeef);
873 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
874 ok(!ret
, "Expected failure\n");
875 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
876 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
877 ok(servicenameW
[0] == 0, "Buffer not empty\n");
879 CloseServiceHandle(scm_handle
);
882 static void test_query_svc(void)
884 SC_HANDLE scm_handle
, svc_handle
;
886 SERVICE_STATUS status
;
887 SERVICE_STATUS_PROCESS
*statusproc
;
888 DWORD bufsize
, needed
;
890 /* All NULL or wrong */
891 SetLastError(0xdeadbeef);
892 ret
= QueryServiceStatus(NULL
, NULL
);
893 ok(!ret
, "Expected failure\n");
894 ok(GetLastError() == ERROR_INVALID_HANDLE
,
895 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
897 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
899 /* Check if 'Spooler' exists.
900 * Open with not enough rights to query the status.
902 svc_handle
= OpenServiceA(scm_handle
, spooler
, STANDARD_RIGHTS_READ
);
905 skip("Spooler service doesn't exist\n");
906 CloseServiceHandle(scm_handle
);
910 SetLastError(0xdeadbeef);
911 ret
= QueryServiceStatus(svc_handle
, NULL
);
912 ok(!ret
, "Expected failure\n");
914 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
915 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
916 "Unexpected last error %d\n", GetLastError());
918 SetLastError(0xdeadbeef);
919 ret
= QueryServiceStatus(svc_handle
, &status
);
920 ok(!ret
, "Expected failure\n");
921 ok(GetLastError() == ERROR_ACCESS_DENIED
,
922 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
924 /* Open the service with just enough rights.
925 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
927 CloseServiceHandle(svc_handle
);
928 svc_handle
= OpenServiceA(scm_handle
, spooler
, SERVICE_QUERY_STATUS
);
930 SetLastError(0xdeadbeef);
931 ret
= QueryServiceStatus(svc_handle
, &status
);
932 ok(ret
, "Expected success, got error %u\n", GetLastError());
934 CloseServiceHandle(svc_handle
);
936 /* More or less the same tests for QueryServiceStatusEx */
938 /* Open service with not enough rights to query the status */
939 svc_handle
= OpenServiceA(scm_handle
, spooler
, STANDARD_RIGHTS_READ
);
941 /* All NULL or wrong, this proves that info level is checked first */
942 SetLastError(0xdeadbeef);
943 ret
= pQueryServiceStatusEx(NULL
, 1, NULL
, 0, NULL
);
944 ok(!ret
, "Expected failure\n");
946 ok(GetLastError() == ERROR_INVALID_LEVEL
,
947 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
949 /* Passing a NULL parameter for the needed buffer size
950 * will crash on anything but NT4.
953 /* Only info level is correct. It looks like the buffer/size is checked second */
954 SetLastError(0xdeadbeef);
955 ret
= pQueryServiceStatusEx(NULL
, 0, NULL
, 0, &needed
);
956 /* NT4 and Wine check the handle first */
957 if (GetLastError() != ERROR_INVALID_HANDLE
)
959 ok(!ret
, "Expected failure\n");
960 ok(needed
== sizeof(SERVICE_STATUS_PROCESS
),
961 "Needed buffersize is wrong : %d\n", needed
);
962 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
963 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
966 /* Pass a correct buffer and buffersize but a NULL handle */
967 statusproc
= HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS
));
969 SetLastError(0xdeadbeef);
970 ret
= pQueryServiceStatusEx(NULL
, 0, (BYTE
*)statusproc
, bufsize
, &needed
);
971 ok(!ret
, "Expected failure\n");
972 ok(GetLastError() == ERROR_INVALID_HANDLE
,
973 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
974 HeapFree(GetProcessHeap(), 0, statusproc
);
976 /* Correct handle and info level */
977 SetLastError(0xdeadbeef);
978 ret
= pQueryServiceStatusEx(svc_handle
, 0, NULL
, 0, &needed
);
979 /* NT4 doesn't return the needed size */
980 if (GetLastError() != ERROR_INVALID_PARAMETER
)
982 ok(!ret
, "Expected failure\n");
985 ok(needed
== sizeof(SERVICE_STATUS_PROCESS
),
986 "Needed buffersize is wrong : %d\n", needed
);
987 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
988 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
992 /* All parameters are OK but we don't have enough rights */
993 statusproc
= HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS
));
994 bufsize
= sizeof(SERVICE_STATUS_PROCESS
);
995 SetLastError(0xdeadbeef);
996 ret
= pQueryServiceStatusEx(svc_handle
, 0, (BYTE
*)statusproc
, bufsize
, &needed
);
997 ok(!ret
, "Expected failure\n");
998 ok(GetLastError() == ERROR_ACCESS_DENIED
,
999 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1000 HeapFree(GetProcessHeap(), 0, statusproc
);
1002 /* Open the service with just enough rights. */
1003 CloseServiceHandle(svc_handle
);
1004 svc_handle
= OpenServiceA(scm_handle
, spooler
, SERVICE_QUERY_STATUS
);
1006 /* Everything should be fine now. */
1007 statusproc
= HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS
));
1008 bufsize
= sizeof(SERVICE_STATUS_PROCESS
);
1009 SetLastError(0xdeadbeef);
1010 ret
= pQueryServiceStatusEx(svc_handle
, 0, (BYTE
*)statusproc
, bufsize
, &needed
);
1011 ok(ret
, "Expected success, got error %u\n", GetLastError());
1012 if (statusproc
->dwCurrentState
== SERVICE_RUNNING
)
1013 ok(statusproc
->dwProcessId
!= 0,
1014 "Expect a process id for this running service\n");
1016 ok(statusproc
->dwProcessId
== 0,
1017 "Expect no process id for this stopped service\n");
1018 HeapFree(GetProcessHeap(), 0, statusproc
);
1020 CloseServiceHandle(svc_handle
);
1021 CloseServiceHandle(scm_handle
);
1024 static void test_enum_svc(void)
1026 SC_HANDLE scm_handle
;
1028 DWORD bufsize
, needed
, returned
, resume
;
1029 DWORD tempneeded
, tempreturned
, missing
;
1030 DWORD servicecountactive
, servicecountinactive
;
1031 ENUM_SERVICE_STATUS
*services
;
1032 ENUM_SERVICE_STATUS_PROCESS
*exservices
;
1035 /* All NULL or wrong */
1036 SetLastError(0xdeadbeef);
1037 ret
= EnumServicesStatusA(NULL
, 1, 0, NULL
, 0, NULL
, NULL
, NULL
);
1038 ok(!ret
, "Expected failure\n");
1040 ok(GetLastError() == ERROR_INVALID_HANDLE
,
1041 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1043 /* Open the service control manager with not enough rights at first */
1044 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1046 /* Valid handle but rest is still NULL or wrong */
1047 SetLastError(0xdeadbeef);
1048 ret
= EnumServicesStatusA(scm_handle
, 1, 0, NULL
, 0, NULL
, NULL
, NULL
);
1049 ok(!ret
, "Expected failure\n");
1051 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1052 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1053 "Unexpected last error %d\n", GetLastError());
1055 /* Don't specify the two required pointers */
1056 returned
= 0xdeadbeef;
1057 SetLastError(0xdeadbeef);
1058 ret
= EnumServicesStatusA(scm_handle
, 0, 0, NULL
, 0, NULL
, &returned
, NULL
);
1059 ok(!ret
, "Expected failure\n");
1060 ok(returned
== 0xdeadbeef, "Expected no change to the number of services variable\n");
1062 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1063 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1064 "Unexpected last error %d\n", GetLastError());
1066 /* Don't specify the two required pointers */
1067 needed
= 0xdeadbeef;
1068 SetLastError(0xdeadbeef);
1069 ret
= EnumServicesStatusA(scm_handle
, 0, 0, NULL
, 0, &needed
, NULL
, NULL
);
1070 ok(!ret
, "Expected failure\n");
1071 ok(needed
== 0xdeadbeef || broken(needed
!= 0xdeadbeef), /* nt4 */
1072 "Expected no change to the needed buffer variable\n");
1074 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1075 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1076 "Unexpected last error %d\n", GetLastError());
1078 /* No valid servicetype and servicestate */
1079 needed
= 0xdeadbeef;
1080 returned
= 0xdeadbeef;
1081 SetLastError(0xdeadbeef);
1082 ret
= EnumServicesStatusA(scm_handle
, 0, 0, NULL
, 0, &needed
, &returned
, NULL
);
1083 ok(!ret
, "Expected failure\n");
1086 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1087 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1088 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1089 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1090 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1093 /* No valid servicetype and servicestate */
1094 needed
= 0xdeadbeef;
1095 returned
= 0xdeadbeef;
1096 SetLastError(0xdeadbeef);
1097 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, 0, NULL
, 0, &needed
, &returned
, NULL
);
1098 ok(!ret
, "Expected failure\n");
1101 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1102 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1103 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1104 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1105 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1108 /* No valid servicetype and servicestate */
1109 needed
= 0xdeadbeef;
1110 returned
= 0xdeadbeef;
1111 SetLastError(0xdeadbeef);
1112 ret
= EnumServicesStatusA(scm_handle
, 0, SERVICE_STATE_ALL
, NULL
, 0,
1113 &needed
, &returned
, NULL
);
1114 ok(!ret
, "Expected failure\n");
1117 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1118 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1119 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1120 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1121 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1124 /* All parameters are correct but our access rights are wrong */
1125 needed
= 0xdeadbeef;
1126 returned
= 0xdeadbeef;
1127 SetLastError(0xdeadbeef);
1128 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, NULL
, 0,
1129 &needed
, &returned
, NULL
);
1130 ok(!ret
, "Expected failure\n");
1133 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1134 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1135 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1137 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1138 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1140 /* Open the service control manager with the needed rights */
1141 CloseServiceHandle(scm_handle
);
1142 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
1144 /* All parameters are correct. Request the needed buffer size */
1145 needed
= 0xdeadbeef;
1146 returned
= 0xdeadbeef;
1147 SetLastError(0xdeadbeef);
1148 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, NULL
, 0,
1149 &needed
, &returned
, NULL
);
1150 ok(!ret
, "Expected failure\n");
1153 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size for this one service\n");
1154 ok(returned
== 0, "Expected no service returned, got %d\n", returned
);
1155 ok(GetLastError() == ERROR_MORE_DATA
,
1156 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1159 /* Store the needed bytes */
1160 tempneeded
= needed
;
1162 /* Allocate the correct needed bytes */
1163 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1165 needed
= 0xdeadbeef;
1166 returned
= 0xdeadbeef;
1167 SetLastError(0xdeadbeef);
1168 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1169 services
, bufsize
, &needed
, &returned
, NULL
);
1172 ok(ret
, "Expected success, got error %u\n", GetLastError());
1173 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1174 ok(returned
!= 0xdeadbeef && returned
> 0, "Expected some returned services\n");
1176 HeapFree(GetProcessHeap(), 0, services
);
1178 /* Store the number of returned services */
1179 tempreturned
= returned
;
1181 /* Allocate less than the needed bytes and don't specify a resume handle */
1182 services
= HeapAlloc(GetProcessHeap(), 0, tempneeded
);
1183 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1184 needed
= 0xdeadbeef;
1185 returned
= 0xdeadbeef;
1186 SetLastError(0xdeadbeef);
1187 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1188 services
, bufsize
, &needed
, &returned
, NULL
);
1189 ok(!ret
, "Expected failure\n");
1192 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size for this one service\n");
1193 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1194 ok(GetLastError() == ERROR_MORE_DATA
,
1195 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1198 /* Allocate less than the needed bytes, this time with a correct resume handle */
1199 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1200 needed
= 0xdeadbeef;
1201 returned
= 0xdeadbeef;
1203 SetLastError(0xdeadbeef);
1204 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1205 services
, bufsize
, &needed
, &returned
, &resume
);
1206 ok(!ret
, "Expected failure\n");
1209 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size for this one service\n");
1210 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1211 ok(resume
, "Expected a resume handle\n");
1212 ok(GetLastError() == ERROR_MORE_DATA
,
1213 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1216 /* Fetch the missing services but pass a bigger buffer size */
1217 missing
= tempreturned
- returned
;
1218 bufsize
= tempneeded
;
1219 needed
= 0xdeadbeef;
1220 returned
= 0xdeadbeef;
1221 SetLastError(0xdeadbeef);
1222 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1223 services
, bufsize
, &needed
, &returned
, &resume
);
1226 ok(ret
, "Expected success, got error %u\n", GetLastError());
1227 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1228 ok(returned
== missing
, "Expected %u services to be returned\n", missing
);
1230 ok(resume
== 0, "Expected the resume handle to be 0\n");
1231 HeapFree(GetProcessHeap(), 0, services
);
1233 /* See if things add up */
1235 /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1236 * and doesn't count the others as inactive. This means that Vista could
1237 * show a total that is greater than the sum of active and inactive
1239 * The number of active and inactive drivers is greatly influenced by the
1240 * time when tests are run, immediately after boot or later for example.
1242 * Both reasons make calculations for drivers not so useful
1245 /* Get the number of active win32 services */
1246 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_ACTIVE
, NULL
, 0,
1247 &needed
, &returned
, NULL
);
1248 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1249 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_ACTIVE
, services
,
1250 needed
, &needed
, &returned
, NULL
);
1251 HeapFree(GetProcessHeap(), 0, services
);
1253 servicecountactive
= returned
;
1255 /* Get the number of inactive win32 services */
1256 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_INACTIVE
, NULL
, 0,
1257 &needed
, &returned
, NULL
);
1258 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1259 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_INACTIVE
, services
,
1260 needed
, &needed
, &returned
, NULL
);
1261 HeapFree(GetProcessHeap(), 0, services
);
1263 servicecountinactive
= returned
;
1265 /* Get the number of win32 services */
1266 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, NULL
, 0,
1267 &needed
, &returned
, NULL
);
1268 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1269 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, services
,
1270 needed
, &needed
, &returned
, NULL
);
1271 HeapFree(GetProcessHeap(), 0, services
);
1273 /* Check if total is the same as active and inactive win32 services */
1275 ok(returned
== (servicecountactive
+ servicecountinactive
),
1276 "Something wrong in the calculation\n");
1278 /* Get all drivers and services
1280 * Fetch the status of the last call as failing could make the following tests crash
1281 * on Wine (we don't return anything yet).
1283 EnumServicesStatusA(scm_handle
, SERVICE_DRIVER
| SERVICE_WIN32
, SERVICE_STATE_ALL
,
1284 NULL
, 0, &needed
, &returned
, NULL
);
1285 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1286 ret
= EnumServicesStatusA(scm_handle
, SERVICE_DRIVER
| SERVICE_WIN32
, SERVICE_STATE_ALL
,
1287 services
, needed
, &needed
, &returned
, NULL
);
1289 /* Loop through all those returned drivers and services */
1290 for (i
= 0; ret
&& i
< returned
; i
++)
1292 SERVICE_STATUS status
= services
[i
].ServiceStatus
;
1294 /* lpServiceName and lpDisplayName should always be filled */
1295 ok(lstrlenA(services
[i
].lpServiceName
) > 0, "Expected a service name\n");
1296 ok(lstrlenA(services
[i
].lpDisplayName
) > 0, "Expected a display name\n");
1298 /* Decrement the counters to see if the functions calls return the same
1299 * numbers as the contents of these structures.
1301 if (status
.dwServiceType
& (SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
))
1303 if (status
.dwCurrentState
== SERVICE_RUNNING
)
1304 servicecountactive
--;
1306 servicecountinactive
--;
1309 HeapFree(GetProcessHeap(), 0, services
);
1313 ok(servicecountactive
== 0, "Active services mismatch %u\n", servicecountactive
);
1314 ok(servicecountinactive
== 0, "Inactive services mismatch %u\n", servicecountinactive
);
1317 CloseServiceHandle(scm_handle
);
1319 /* More or less the same for EnumServicesStatusExA */
1321 /* All NULL or wrong */
1322 SetLastError(0xdeadbeef);
1323 ret
= pEnumServicesStatusExA(NULL
, 1, 0, 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1324 ok(!ret
, "Expected failure\n");
1326 ok(GetLastError() == ERROR_INVALID_LEVEL
,
1327 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1329 /* All NULL or wrong, just the info level is correct */
1330 SetLastError(0xdeadbeef);
1331 ret
= pEnumServicesStatusExA(NULL
, 0, 0, 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1332 ok(!ret
, "Expected failure\n");
1334 ok(GetLastError() == ERROR_INVALID_HANDLE
,
1335 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1337 /* Open the service control manager with not enough rights at first */
1338 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1340 /* Valid handle and info level but rest is still NULL or wrong */
1341 SetLastError(0xdeadbeef);
1342 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1343 ok(!ret
, "Expected failure\n");
1345 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1346 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1347 "Unexpected last error %d\n", GetLastError());
1349 /* Don't specify the two required pointers */
1350 needed
= 0xdeadbeef;
1351 SetLastError(0xdeadbeef);
1352 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, &needed
, NULL
, NULL
, NULL
);
1353 ok(!ret
, "Expected failure\n");
1354 ok(needed
== 0xdeadbeef || broken(needed
!= 0xdeadbeef), /* nt4 */
1355 "Expected no change to the needed buffer variable\n");
1357 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1358 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1359 "Unexpected last error %d\n", GetLastError());
1361 /* Don't specify the two required pointers */
1362 returned
= 0xdeadbeef;
1363 SetLastError(0xdeadbeef);
1364 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, NULL
, &returned
, NULL
, NULL
);
1365 ok(!ret
, "Expected failure\n");
1368 ok(returned
== 0xdeadbeef, "Expected no change to the number of services variable\n");
1369 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1370 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1371 "Unexpected last error %d\n", GetLastError());
1374 /* No valid servicetype and servicestate */
1375 needed
= 0xdeadbeef;
1376 returned
= 0xdeadbeef;
1377 SetLastError(0xdeadbeef);
1378 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1379 ok(!ret
, "Expected failure\n");
1380 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1383 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1384 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1385 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1386 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1389 /* No valid servicestate */
1390 needed
= 0xdeadbeef;
1391 returned
= 0xdeadbeef;
1392 SetLastError(0xdeadbeef);
1393 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, 0, NULL
, 0,
1394 &needed
, &returned
, NULL
, NULL
);
1395 ok(!ret
, "Expected failure\n");
1396 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1399 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1400 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1401 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1402 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1405 /* No valid servicetype */
1406 needed
= 0xdeadbeef;
1407 returned
= 0xdeadbeef;
1408 SetLastError(0xdeadbeef);
1409 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, SERVICE_STATE_ALL
, NULL
, 0,
1410 &needed
, &returned
, NULL
, NULL
);
1411 ok(!ret
, "Expected failure\n");
1412 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1415 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1416 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1417 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1418 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1421 /* No valid servicetype and servicestate and unknown service group */
1422 needed
= 0xdeadbeef;
1423 returned
= 0xdeadbeef;
1424 SetLastError(0xdeadbeef);
1425 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, &needed
,
1426 &returned
, NULL
, "deadbeef_group");
1427 ok(!ret
, "Expected failure\n");
1428 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1431 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1432 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1433 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1434 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1437 /* All parameters are correct but our access rights are wrong */
1438 needed
= 0xdeadbeef;
1439 returned
= 0xdeadbeef;
1440 SetLastError(0xdeadbeef);
1441 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1442 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1443 ok(!ret
, "Expected failure\n");
1445 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1446 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1447 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1448 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1449 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1451 /* All parameters are correct, access rights are wrong but the
1452 * group name won't be checked yet.
1454 needed
= 0xdeadbeef;
1455 returned
= 0xdeadbeef;
1456 SetLastError(0xdeadbeef);
1457 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1458 NULL
, 0, &needed
, &returned
, NULL
, "deadbeef_group");
1459 ok(!ret
, "Expected failure\n");
1461 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1462 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1463 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1464 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1465 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1467 /* Open the service control manager with the needed rights */
1468 CloseServiceHandle(scm_handle
);
1469 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
1471 /* All parameters are correct and the group will be checked */
1472 needed
= 0xdeadbeef;
1473 returned
= 0xdeadbeef;
1474 SetLastError(0xdeadbeef);
1475 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1476 NULL
, 0, &needed
, &returned
, NULL
, "deadbeef_group");
1477 ok(!ret
, "Expected failure\n");
1478 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1481 ok(needed
== 0, "Expected needed buffer size to be set to 0, got %d\n", needed
);
1482 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
1483 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1486 /* TODO: Create a test that makes sure we enumerate all services that don't
1487 * belong to a group. (specifying "").
1490 /* All parameters are correct. Request the needed buffer size */
1491 needed
= 0xdeadbeef;
1492 returned
= 0xdeadbeef;
1493 SetLastError(0xdeadbeef);
1494 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1495 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1496 ok(!ret
, "Expected failure\n");
1497 ok(returned
== 0, "Expected no service returned, got %d\n", returned
);
1500 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size\n");
1501 ok(GetLastError() == ERROR_MORE_DATA
,
1502 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1505 /* Store the needed bytes */
1506 tempneeded
= needed
;
1508 /* Allocate the correct needed bytes */
1509 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1511 needed
= 0xdeadbeef;
1512 returned
= 0xdeadbeef;
1513 SetLastError(0xdeadbeef);
1514 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1515 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, NULL
, NULL
);
1518 ok(ret
, "Expected success, got error %u\n", GetLastError());
1519 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1520 ok(returned
== tempreturned
, "Expected the same number of service from this function\n");
1522 HeapFree(GetProcessHeap(), 0, exservices
);
1524 /* Store the number of returned services */
1525 tempreturned
= returned
;
1527 /* Allocate less than the needed bytes and don't specify a resume handle */
1528 exservices
= HeapAlloc(GetProcessHeap(), 0, tempneeded
);
1529 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1530 needed
= 0xdeadbeef;
1531 returned
= 0xdeadbeef;
1532 SetLastError(0xdeadbeef);
1533 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1534 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, NULL
, NULL
);
1535 ok(!ret
, "Expected failure\n");
1538 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size\n");
1539 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1540 ok(GetLastError() == ERROR_MORE_DATA
,
1541 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1544 /* Allocate less than the needed bytes, this time with a correct resume handle */
1545 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1546 needed
= 0xdeadbeef;
1547 returned
= 0xdeadbeef;
1549 SetLastError(0xdeadbeef);
1550 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1551 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, &resume
, NULL
);
1552 ok(!ret
, "Expected failure\n");
1555 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size\n");
1556 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1557 ok(resume
, "Expected a resume handle\n");
1558 ok(GetLastError() == ERROR_MORE_DATA
,
1559 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1562 /* Fetch that last service but pass a bigger buffer size */
1563 missing
= tempreturned
- returned
;
1564 bufsize
= tempneeded
;
1565 needed
= 0xdeadbeef;
1566 returned
= 0xdeadbeef;
1567 SetLastError(0xdeadbeef);
1568 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1569 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, &resume
, NULL
);
1572 ok(ret
, "Expected success, got error %u\n", GetLastError());
1573 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1575 ok(returned
== missing
, "Expected %u services to be returned\n", missing
);
1576 ok(resume
== 0, "Expected the resume handle to be 0\n");
1577 HeapFree(GetProcessHeap(), 0, exservices
);
1579 /* See if things add up */
1581 /* Get the number of active win32 services */
1582 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_ACTIVE
,
1583 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1584 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1585 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_ACTIVE
,
1586 (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1587 HeapFree(GetProcessHeap(), 0, exservices
);
1589 servicecountactive
= returned
;
1591 /* Get the number of inactive win32 services */
1592 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_INACTIVE
,
1593 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1594 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1595 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_INACTIVE
,
1596 (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1597 HeapFree(GetProcessHeap(), 0, exservices
);
1599 servicecountinactive
= returned
;
1601 /* Get the number of win32 services */
1602 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1603 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1604 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1605 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1606 (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1607 HeapFree(GetProcessHeap(), 0, exservices
);
1609 /* Check if total is the same as active and inactive win32 services */
1610 ok(returned
== (servicecountactive
+ servicecountinactive
),
1611 "Something wrong in the calculation\n");
1613 /* Get all drivers and services */
1614 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
| SERVICE_DRIVER
,
1615 SERVICE_STATE_ALL
, NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1616 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1617 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
| SERVICE_DRIVER
,
1618 SERVICE_STATE_ALL
, (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1620 /* Loop through all those returned drivers and services */
1621 for (i
= 0; i
< returned
; i
++)
1623 SERVICE_STATUS_PROCESS status
= exservices
[i
].ServiceStatusProcess
;
1626 /* lpServiceName and lpDisplayName should always be filled */
1627 ok(lstrlenA(exservices
[i
].lpServiceName
) > 0, "Expected a service name\n");
1628 ok(lstrlenA(exservices
[i
].lpDisplayName
) > 0, "Expected a display name\n");
1630 /* Decrement the counters to see if the functions calls return the
1631 * same numbers as the contents of these structures.
1632 * Check some process id specifics.
1634 if (status
.dwServiceType
& (SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_KERNEL_DRIVER
))
1636 /* We shouldn't have a process id for drivers */
1637 ok(status
.dwProcessId
== 0,
1638 "This driver shouldn't have an associated process id\n");
1641 if (status
.dwServiceType
& (SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
))
1643 if (status
.dwCurrentState
== SERVICE_RUNNING
)
1645 /* We expect a process id for every running service */
1646 ok(status
.dwProcessId
> 0, "Expected a process id for this running service (%s)\n",
1647 exservices
[i
].lpServiceName
);
1649 servicecountactive
--;
1653 /* We shouldn't have a process id for inactive services */
1654 ok(status
.dwProcessId
== 0, "Service %s state %u shouldn't have an associated process id\n",
1655 exservices
[i
].lpServiceName
, status
.dwCurrentState
);
1657 servicecountinactive
--;
1661 HeapFree(GetProcessHeap(), 0, exservices
);
1663 ok(servicecountactive
== 0, "Active services mismatch %u\n", servicecountactive
);
1664 ok(servicecountinactive
== 0, "Inactive services mismatch %u\n", servicecountinactive
);
1666 CloseServiceHandle(scm_handle
);
1669 static void test_close(void)
1675 SetLastError(0xdeadbeef);
1676 ret
= CloseServiceHandle(NULL
);
1677 ok(!ret
, "Expected failure\n");
1678 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1680 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1683 handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1684 SetLastError(0xdeadbeef);
1685 ret
= CloseServiceHandle(handle
);
1686 ok(ret
, "Expected success got error %u\n", GetLastError());
1689 static void test_sequence(void)
1691 SC_HANDLE scm_handle
, svc_handle
;
1693 QUERY_SERVICE_CONFIGA
*config
;
1694 DWORD given
, needed
;
1695 static const CHAR servicename
[] = "Winetest";
1696 static const CHAR displayname
[] = "Winetest dummy service";
1697 static const CHAR displayname2
[] = "Winetest dummy service (2)";
1698 static const CHAR pathname
[] = "we_dont_care.exe";
1699 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
1700 static const CHAR password
[] = "";
1701 static const CHAR empty
[] = "";
1702 static const CHAR localsystem
[] = "LocalSystem";
1704 SetLastError(0xdeadbeef);
1705 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1707 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1709 skip("Not enough rights to get a handle to the manager\n");
1713 ok(scm_handle
!= NULL
, "Could not get a handle to the manager: %d\n", GetLastError());
1715 if (!scm_handle
) return;
1717 /* Create a dummy service */
1718 SetLastError(0xdeadbeef);
1719 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
1720 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
1721 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
1723 if (!svc_handle
&& (GetLastError() == ERROR_SERVICE_EXISTS
))
1725 /* We try and open the service and do the rest of the tests. Some could
1726 * fail if the tests were changed between these runs.
1728 trace("Deletion probably didn't work last time\n");
1729 SetLastError(0xdeadbeef);
1730 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1731 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1733 skip("Not enough rights to open the service\n");
1734 CloseServiceHandle(scm_handle
);
1737 ok(svc_handle
!= NULL
, "Could not open the service : %d\n", GetLastError());
1739 else if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1741 skip("Not enough rights to create the service\n");
1742 CloseServiceHandle(scm_handle
);
1746 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1748 if (!svc_handle
) return;
1751 * Before we do a QueryServiceConfig we should check the registry. This will make sure
1752 * that the correct keys are used.
1755 /* Request the size for the buffer */
1756 SetLastError(0xdeadbeef);
1757 ret
= QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
1758 ok(!ret
, "Expected failure\n");
1759 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1761 config
= HeapAlloc(GetProcessHeap(), 0, needed
);
1763 SetLastError(0xdeadbeef);
1764 ret
= QueryServiceConfigA(svc_handle
, config
, given
, &needed
);
1765 ok(ret
, "Expected success, got error %u\n", GetLastError());
1767 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
1768 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
1769 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
1770 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
1771 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
1772 ok(config
->dwErrorControl
== SERVICE_ERROR_IGNORE
, "Expected SERVICE_ERROR_IGNORE, got %d\n", config
->dwErrorControl
);
1773 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
1774 ok(!strcmp(config
->lpLoadOrderGroup
, empty
), "Expected an empty string, got '%s'\n", config
->lpLoadOrderGroup
);
1775 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
1776 /* TODO: Show the double 0 terminated string */
1779 ok(!memcmp(config
->lpDependencies
, dependencies
, sizeof(dependencies
)), "Wrong string\n");
1781 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
1782 ok(!strcmp(config
->lpDisplayName
, displayname
), "Expected '%s', got '%s'\n", displayname
, config
->lpDisplayName
);
1784 ok(ChangeServiceConfigA(svc_handle
, SERVICE_NO_CHANGE
, SERVICE_NO_CHANGE
, SERVICE_ERROR_NORMAL
, NULL
, "TestGroup2", NULL
, NULL
, NULL
, NULL
, displayname2
),
1785 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1787 QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
1788 config
= HeapReAlloc(GetProcessHeap(), 0, config
, needed
);
1789 ok(QueryServiceConfigA(svc_handle
, config
, needed
, &needed
), "QueryServiceConfig failed\n");
1790 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
1791 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
1792 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
1793 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
1794 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
1795 ok(config
->dwErrorControl
== SERVICE_ERROR_NORMAL
, "Expected SERVICE_ERROR_NORMAL, got %d\n", config
->dwErrorControl
);
1796 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
1797 ok(!strcmp(config
->lpLoadOrderGroup
, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config
->lpLoadOrderGroup
);
1798 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
1799 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
1800 ok(!strcmp(config
->lpDisplayName
, displayname2
), "Expected '%s', got '%s'\n", displayname2
, config
->lpDisplayName
);
1802 SetLastError(0xdeadbeef);
1803 ret
= DeleteService(svc_handle
);
1804 ok(ret
, "Expected success, got error %u\n", GetLastError());
1805 CloseServiceHandle(svc_handle
);
1807 /* Wait a while. The following test does a CreateService again */
1810 CloseServiceHandle(scm_handle
);
1811 HeapFree(GetProcessHeap(), 0, config
);
1814 static void test_queryconfig2(void)
1816 SC_HANDLE scm_handle
, svc_handle
;
1818 DWORD expected
, needed
;
1819 BYTE buffer
[MAX_PATH
];
1820 LPSERVICE_DESCRIPTIONA pConfig
= (LPSERVICE_DESCRIPTIONA
)buffer
;
1821 static const CHAR servicename
[] = "Winetest";
1822 static const CHAR displayname
[] = "Winetest dummy service";
1823 static const CHAR pathname
[] = "we_dont_care.exe";
1824 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
1825 static const CHAR password
[] = "";
1826 static const CHAR description
[] = "Description";
1828 if(!pQueryServiceConfig2A
)
1830 win_skip("function QueryServiceConfig2A not present\n");
1834 SetLastError(0xdeadbeef);
1835 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1839 if(GetLastError() == ERROR_ACCESS_DENIED
)
1840 skip("Not enough rights to get a handle to the manager\n");
1842 ok(FALSE
, "Could not get a handle to the manager: %d\n", GetLastError());
1846 /* Create a dummy service */
1847 SetLastError(0xdeadbeef);
1848 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
1849 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
1850 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
1854 if(GetLastError() == ERROR_SERVICE_EXISTS
)
1856 /* We try and open the service and do the rest of the tests. Some could
1857 * fail if the tests were changed between these runs.
1859 trace("Deletion probably didn't work last time\n");
1860 SetLastError(0xdeadbeef);
1861 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1864 if(GetLastError() == ERROR_ACCESS_DENIED
)
1865 skip("Not enough rights to open the service\n");
1867 ok(FALSE
, "Could not open the service : %d\n", GetLastError());
1868 CloseServiceHandle(scm_handle
);
1872 if (GetLastError() == ERROR_ACCESS_DENIED
)
1874 skip("Not enough rights to create the service\n");
1875 CloseServiceHandle(scm_handle
);
1878 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1881 CloseServiceHandle(scm_handle
);
1885 SetLastError(0xdeadbeef);
1886 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1887 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1888 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1890 SetLastError(0xdeadbeef);
1891 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1892 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1893 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1895 SetLastError(0xdeadbeef);
1896 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1897 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1898 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1900 SetLastError(0xdeadbeef);
1901 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1902 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1903 ok((ERROR_INVALID_ADDRESS
== GetLastError()) || (ERROR_INSUFFICIENT_BUFFER
== GetLastError()),
1904 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1906 SetLastError(0xdeadbeef);
1907 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1908 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1909 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1912 SetLastError(0xdeadbeef);
1913 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
)-1,&needed
);
1914 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1915 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1916 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1919 pConfig
->lpDescription
= (LPSTR
)0xdeadbeef;
1920 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1921 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1922 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1923 ok(!pConfig
->lpDescription
, "expected lpDescription to be NULL, got %p\n", pConfig
->lpDescription
);
1925 SetLastError(0xdeadbeef);
1927 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1928 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1929 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1930 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1932 if(!pChangeServiceConfig2A
)
1934 win_skip("function ChangeServiceConfig2A not present\n");
1938 pConfig
->lpDescription
= (LPSTR
) description
;
1939 ret
= pChangeServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
);
1940 ok(ret
, "ChangeServiceConfig2A failed\n");
1945 SetLastError(0xdeadbeef);
1947 expected
= sizeof(SERVICE_DESCRIPTIONA
) + sizeof(description
) * sizeof(WCHAR
); /* !! */
1948 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1949 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1950 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1951 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1953 SetLastError(0xdeadbeef);
1954 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
-1,&needed
);
1955 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1956 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1958 SetLastError(0xdeadbeef);
1959 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
,&needed
);
1960 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1961 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1962 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1964 SetLastError(0xdeadbeef);
1965 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
+ 1,&needed
);
1966 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1967 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1968 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1970 if(!pQueryServiceConfig2W
)
1972 win_skip("function QueryServiceConfig2W not present\n");
1975 SetLastError(0xdeadbeef);
1977 expected
= sizeof(SERVICE_DESCRIPTIONW
) + sizeof(WCHAR
) * sizeof(description
);
1978 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1979 ok(!ret
, "expected QueryServiceConfig2W to fail\n");
1980 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1981 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1983 SetLastError(0xdeadbeef);
1984 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
,&needed
);
1985 ok(ret
, "expected QueryServiceConfig2W to succeed\n");
1988 DeleteService(svc_handle
);
1990 CloseServiceHandle(svc_handle
);
1992 /* Wait a while. The following test does a CreateService again */
1995 CloseServiceHandle(scm_handle
);
1998 static void test_refcount(void)
2000 SC_HANDLE scm_handle
, svc_handle1
, svc_handle2
, svc_handle3
, svc_handle4
, svc_handle5
;
2001 static const CHAR servicename
[] = "Winetest";
2002 static const CHAR pathname
[] = "we_dont_care.exe";
2005 /* Get a handle to the Service Control Manager */
2006 SetLastError(0xdeadbeef);
2007 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
2008 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
2010 skip("Not enough rights to get a handle to the manager\n");
2014 /* Create a service */
2015 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
2016 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
2017 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
2018 ok(svc_handle1
!= NULL
, "Expected success, got error %u\n", GetLastError());
2020 /* Get a handle to this new service */
2021 svc_handle2
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
2022 ok(svc_handle2
!= NULL
, "Expected success, got error %u\n", GetLastError());
2024 /* Get another handle to this new service */
2025 svc_handle3
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
2026 ok(svc_handle3
!= NULL
, "Expected success, got error %u\n", GetLastError());
2028 /* Check if we can close the handle to the Service Control Manager */
2029 ret
= CloseServiceHandle(scm_handle
);
2030 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2032 /* Get a new handle to the Service Control Manager */
2033 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
2034 ok(scm_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
2036 /* Get a handle to this new service */
2037 svc_handle4
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
2038 ok(svc_handle4
!= NULL
, "Expected success, got error %u\n", GetLastError());
2040 /* Delete the service */
2041 ret
= DeleteService(svc_handle4
);
2042 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2044 /* We cannot create the same service again as it's still marked as 'being deleted'.
2045 * The reason is that we still have 4 open handles to this service even though we
2046 * closed the handle to the Service Control Manager in between.
2048 SetLastError(0xdeadbeef);
2049 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
2050 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
2051 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
2054 ok(!svc_handle5
, "Expected failure\n");
2055 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE
,
2056 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2059 /* FIXME: Remove this when Wine is fixed */
2062 DeleteService(svc_handle5
);
2063 CloseServiceHandle(svc_handle5
);
2066 /* Close all the handles to the service and try again */
2067 ret
= CloseServiceHandle(svc_handle4
);
2068 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2069 ret
= CloseServiceHandle(svc_handle3
);
2070 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2071 ret
= CloseServiceHandle(svc_handle2
);
2072 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2073 ret
= CloseServiceHandle(svc_handle1
);
2074 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2076 /* Wait a while. Doing a CreateService too soon will result again
2077 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2081 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2082 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
2083 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
2084 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
2085 ok(svc_handle5
!= NULL
, "Expected success, got error %u\n", GetLastError());
2087 /* Delete the service */
2088 ret
= DeleteService(svc_handle5
);
2089 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2091 /* Wait a while. Just in case one of the following tests does a CreateService again */
2094 CloseServiceHandle(svc_handle5
);
2095 CloseServiceHandle(scm_handle
);
2100 SC_HANDLE scm_handle
;
2102 /* Bail out if we are on win98 */
2103 SetLastError(0xdeadbeef);
2104 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
2106 if (!scm_handle
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
2108 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2111 CloseServiceHandle(scm_handle
);
2113 init_function_pointers();
2115 /* First some parameter checking */
2118 test_create_delete_svc();
2119 test_get_displayname();
2120 test_get_servicekeyname();
2124 /* Test the creation, querying and deletion of a service */
2126 test_queryconfig2();
2127 /* The main reason for this test is to check if any refcounting is used
2128 * and what the rules are