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
33 #include "wine/test.h"
35 static const CHAR spooler
[] = "Spooler"; /* Should be available on all platforms */
37 static BOOL (WINAPI
*pChangeServiceConfig2A
)(SC_HANDLE
,DWORD
,LPVOID
);
38 static BOOL (WINAPI
*pEnumServicesStatusExA
)(SC_HANDLE
, SC_ENUM_TYPE
, DWORD
,
39 DWORD
, LPBYTE
, DWORD
, LPDWORD
,
40 LPDWORD
, LPDWORD
, LPCSTR
);
41 static DWORD (WINAPI
*pGetSecurityInfo
)(HANDLE
, SE_OBJECT_TYPE
, SECURITY_INFORMATION
,
42 PSID
*, PSID
*, PACL
*, PACL
*, PSECURITY_DESCRIPTOR
*);
43 static BOOL (WINAPI
*pQueryServiceConfig2A
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
);
44 static BOOL (WINAPI
*pQueryServiceConfig2W
)(SC_HANDLE
,DWORD
,LPBYTE
,DWORD
,LPDWORD
);
45 static BOOL (WINAPI
*pQueryServiceStatusEx
)(SC_HANDLE
, SC_STATUS_TYPE
, LPBYTE
,
48 static void init_function_pointers(void)
50 HMODULE hadvapi32
= GetModuleHandleA("advapi32.dll");
52 pChangeServiceConfig2A
= (void*)GetProcAddress(hadvapi32
, "ChangeServiceConfig2A");
53 pEnumServicesStatusExA
= (void*)GetProcAddress(hadvapi32
, "EnumServicesStatusExA");
54 pGetSecurityInfo
= (void *)GetProcAddress(hadvapi32
, "GetSecurityInfo");
55 pQueryServiceConfig2A
= (void*)GetProcAddress(hadvapi32
, "QueryServiceConfig2A");
56 pQueryServiceConfig2W
= (void*)GetProcAddress(hadvapi32
, "QueryServiceConfig2W");
57 pQueryServiceStatusEx
= (void*)GetProcAddress(hadvapi32
, "QueryServiceStatusEx");
60 static void test_open_scm(void)
64 /* No access rights */
65 SetLastError(0xdeadbeef);
66 scm_handle
= OpenSCManagerA(NULL
, NULL
, 0);
67 ok(scm_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
68 CloseServiceHandle(scm_handle
);
70 /* Unknown database name */
71 SetLastError(0xdeadbeef);
72 scm_handle
= OpenSCManagerA(NULL
, "DoesNotExist", SC_MANAGER_CONNECT
);
73 ok(!scm_handle
, "Expected failure\n");
74 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
75 CloseServiceHandle(scm_handle
); /* Just in case */
77 /* MSDN says only ServiceActive is allowed, or NULL */
78 SetLastError(0xdeadbeef);
79 scm_handle
= OpenSCManagerA(NULL
, SERVICES_FAILED_DATABASEA
, SC_MANAGER_CONNECT
);
80 ok(!scm_handle
, "Expected failure\n");
81 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST
, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
82 CloseServiceHandle(scm_handle
); /* Just in case */
84 /* Remote unknown host */
85 SetLastError(0xdeadbeef);
86 scm_handle
= OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
89 ok(!scm_handle
, "Expected failure\n");
90 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE
|| GetLastError() == RPC_S_INVALID_NET_ADDR
/* w2k8 */,
91 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError());
93 CloseServiceHandle(scm_handle
); /* Just in case */
95 /* Proper call with an empty hostname */
96 SetLastError(0xdeadbeef);
97 scm_handle
= OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA
, SC_MANAGER_CONNECT
);
98 ok(scm_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
99 CloseServiceHandle(scm_handle
);
101 /* Again a correct one */
102 SetLastError(0xdeadbeef);
103 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
104 ok(scm_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
105 CloseServiceHandle(scm_handle
);
108 static void test_open_svc(void)
110 SC_HANDLE scm_handle
, svc_handle
;
111 CHAR displayname
[4096];
114 /* All NULL (invalid access rights) */
115 SetLastError(0xdeadbeef);
116 svc_handle
= OpenServiceA(NULL
, NULL
, 0);
117 ok(!svc_handle
, "Expected failure\n");
118 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
120 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
123 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
124 SetLastError(0xdeadbeef);
125 svc_handle
= OpenServiceA(scm_handle
, NULL
, GENERIC_READ
);
126 ok(!svc_handle
, "Expected failure\n");
127 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
128 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
129 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
131 /* Nonexistent service */
132 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
133 SetLastError(0xdeadbeef);
134 svc_handle
= OpenServiceA(scm_handle
, "deadbeef", GENERIC_READ
);
135 ok(!svc_handle
, "Expected failure\n");
136 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
137 CloseServiceHandle(scm_handle
);
139 /* Proper SCM handle but different access rights */
140 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
141 SetLastError(0xdeadbeef);
142 svc_handle
= OpenServiceA(scm_handle
, "Spooler", GENERIC_WRITE
);
143 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
144 skip("Not enough rights to get a handle to the service\n");
147 ok(svc_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
148 CloseServiceHandle(svc_handle
);
151 /* Test to show we can't open a service with the displayname */
153 /* Retrieve the needed size for the buffer */
155 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
156 /* Get the displayname */
157 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
158 /* Try to open the service with this displayname, unless the displayname equals
159 * the servicename as that would defeat the purpose of this test.
161 if (!lstrcmpi(spooler
, displayname
))
163 skip("displayname equals servicename\n");
164 CloseServiceHandle(scm_handle
);
168 SetLastError(0xdeadbeef);
169 svc_handle
= OpenServiceA(scm_handle
, displayname
, GENERIC_READ
);
170 ok(!svc_handle
, "Expected failure\n");
171 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
173 CloseServiceHandle(svc_handle
);
175 CloseServiceHandle(scm_handle
);
178 static void test_create_delete_svc(void)
180 SC_HANDLE scm_handle
, svc_handle1
;
181 CHAR username
[UNLEN
+ 1], domain
[MAX_PATH
];
182 DWORD user_size
= UNLEN
+ 1;
183 CHAR account
[UNLEN
+ 3];
184 static const CHAR servicename
[] = "Winetest";
185 static const CHAR pathname
[] = "we_dont_care.exe";
186 static const CHAR empty
[] = "";
187 static const CHAR password
[] = "secret";
188 BOOL spooler_exists
= FALSE
;
191 DWORD display_size
= sizeof(display
);
193 /* Get the username and turn it into an account to be used in some tests */
194 GetUserNameA(username
, &user_size
);
195 /* Get the domainname to cater for that situation */
196 if (GetEnvironmentVariableA("USERDOMAIN", domain
, MAX_PATH
))
197 sprintf(account
, "%s\\%s", domain
, username
);
199 sprintf(account
, ".\\%s", username
);
202 SetLastError(0xdeadbeef);
203 svc_handle1
= CreateServiceA(NULL
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
204 ok(!svc_handle1
, "Expected failure\n");
205 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
207 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
209 /* Only a valid handle to the Service Control Manager */
210 SetLastError(0xdeadbeef);
211 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
212 ok(!svc_handle1
, "Expected failure\n");
213 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
214 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
215 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
217 /* Now with a servicename */
218 SetLastError(0xdeadbeef);
219 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
220 ok(!svc_handle1
, "Expected failure\n");
221 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
222 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
223 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
225 /* Or just a binary name */
226 SetLastError(0xdeadbeef);
227 svc_handle1
= CreateServiceA(scm_handle
, NULL
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
228 ok(!svc_handle1
, "Expected failure\n");
229 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, W2K3, XP, Vista */ ||
230 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
231 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
233 /* Both servicename and binary name (We only have connect rights) */
234 SetLastError(0xdeadbeef);
235 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
236 ok(!svc_handle1
, "Expected failure\n");
237 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
239 /* They can even be empty at this stage of parameter checking */
240 SetLastError(0xdeadbeef);
241 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
242 ok(!svc_handle1
, "Expected failure\n");
243 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
245 SetLastError(0xdeadbeef);
246 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
247 ok(!svc_handle1
, "Expected failure\n");
248 ok(GetLastError() == ERROR_ACCESS_DENIED
, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
250 /* Open the Service Control Manager with minimal rights for creation
251 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
253 CloseServiceHandle(scm_handle
);
254 SetLastError(0xdeadbeef);
255 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
256 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
258 skip("Not enough rights to get a handle to the manager\n");
262 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
264 /* Empty strings for servicename and binary name are checked */
265 SetLastError(0xdeadbeef);
266 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
267 ok(!svc_handle1
, "Expected failure\n");
268 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
270 SetLastError(0xdeadbeef);
271 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
272 ok(!svc_handle1
, "Expected failure\n");
273 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
275 SetLastError(0xdeadbeef);
276 svc_handle1
= CreateServiceA(scm_handle
, empty
, NULL
, 0, 0, 0, 0, empty
, NULL
, NULL
, NULL
, NULL
, NULL
);
277 ok(!svc_handle1
, "Expected failure\n");
278 ok(GetLastError() == ERROR_INVALID_NAME
, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
280 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
281 * an ERROR_INVALID_PARAMETER)
283 SetLastError(0xdeadbeef);
284 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
285 SERVICE_DISABLED
, 0, empty
, 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 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
291 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with
292 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call)
294 SetLastError(0xdeadbeef);
295 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
,
296 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
297 ok(!svc_handle1
, "Expected failure\n");
298 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
300 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */
301 SetLastError(0xdeadbeef);
302 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_INTERACTIVE_PROCESS
,
303 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
304 ok(!svc_handle1
, "Expected failure\n");
305 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
307 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used)
308 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT.
310 SetLastError(0xdeadbeef);
311 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
312 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, account
, password
);
313 ok(!svc_handle1
, "Expected failure\n");
314 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT
,
315 "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError());
317 /* Illegal (start-type is not a mask and should only be one of the possibilities)
318 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as
319 * it's most likely not the wanted start-type)
321 SetLastError(0xdeadbeef);
322 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
, SERVICE_WIN32_OWN_PROCESS
,
323 SERVICE_AUTO_START
| SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
324 ok(!svc_handle1
, "Expected failure\n");
325 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
327 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */
328 SetLastError(0xdeadbeef);
329 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
330 SERVICE_BOOT_START
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
331 ok(!svc_handle1
, "Expected failure\n");
332 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
334 /* The service already exists (check first, just in case) */
335 svc_handle1
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
338 spooler_exists
= TRUE
;
339 CloseServiceHandle(svc_handle1
);
340 SetLastError(0xdeadbeef);
341 svc_handle1
= CreateServiceA(scm_handle
, spooler
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
,
342 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
343 ok(!svc_handle1
, "Expected failure\n");
344 ok(GetLastError() == ERROR_SERVICE_EXISTS
, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError());
347 skip("Spooler service doesn't exist\n");
349 /* To find an existing displayname we check the 'Spooler' service. Although the registry
350 * doesn't show DisplayName on NT4, this call will return a displayname which is equal
351 * to the servicename and can't be used as well for a new displayname.
355 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, display
, &display_size
);
358 skip("Could not retrieve a displayname for the Spooler service\n");
361 svc_handle1
= CreateServiceA(scm_handle
, servicename
, display
, 0, SERVICE_WIN32_OWN_PROCESS
,
362 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
363 ok(!svc_handle1
, "Expected failure\n");
364 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME
,
365 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError());
369 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
371 /* Windows doesn't care about the access rights for creation (which makes
372 * sense as there is no service yet) as long as there are sufficient
373 * rights to the manager.
375 SetLastError(0xdeadbeef);
376 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, 0, SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
377 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
378 ok(svc_handle1
!= NULL
, "Could not create the service : %d\n", GetLastError());
380 /* DeleteService however must have proper rights */
381 SetLastError(0xdeadbeef);
382 ret
= DeleteService(svc_handle1
);
383 ok(!ret
, "Expected failure\n");
384 ok(GetLastError() == ERROR_ACCESS_DENIED
,
385 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
387 /* Open the service with minimal rights for deletion.
388 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
390 CloseServiceHandle(svc_handle1
);
391 svc_handle1
= OpenServiceA(scm_handle
, servicename
, DELETE
);
393 /* Now that we have the proper rights, we should be able to delete */
394 SetLastError(0xdeadbeef);
395 ret
= DeleteService(svc_handle1
);
396 ok(ret
, "Expected success, got error %u\n", GetLastError());
398 CloseServiceHandle(svc_handle1
);
399 CloseServiceHandle(scm_handle
);
401 /* Wait a while. One of the following tests also does a CreateService for the
402 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE
403 * error if we do this to quick. Vista seems more picky then the others.
407 /* And a final NULL check */
408 SetLastError(0xdeadbeef);
409 ret
= DeleteService(NULL
);
410 ok(!ret
, "Expected failure\n");
411 ok(GetLastError() == ERROR_INVALID_HANDLE
,
412 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
415 static void test_get_displayname(void)
417 SC_HANDLE scm_handle
, svc_handle
;
419 CHAR displayname
[4096];
420 WCHAR displaynameW
[2048];
421 DWORD displaysize
, tempsize
, tempsizeW
;
422 static const CHAR deadbeef
[] = "Deadbeef";
423 static const WCHAR spoolerW
[] = {'S','p','o','o','l','e','r',0};
424 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
425 static const WCHAR abcW
[] = {'A','B','C',0};
426 static const CHAR servicename
[] = "Winetest";
427 static const CHAR pathname
[] = "we_dont_care.exe";
429 /* Having NULL for the size of the buffer will crash on W2K3 */
431 SetLastError(0xdeadbeef);
432 ret
= GetServiceDisplayNameA(NULL
, NULL
, NULL
, &displaysize
);
433 ok(!ret
, "Expected failure\n");
434 ok(GetLastError() == ERROR_INVALID_HANDLE
,
435 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
437 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
439 SetLastError(0xdeadbeef);
440 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, NULL
, &displaysize
);
441 ok(!ret
, "Expected failure\n");
442 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
443 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
444 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
446 SetLastError(0xdeadbeef);
447 displaysize
= sizeof(displayname
);
448 ret
= GetServiceDisplayNameA(scm_handle
, NULL
, displayname
, &displaysize
);
449 ok(!ret
, "Expected failure\n");
450 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
451 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
452 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
454 /* Test for nonexistent service */
455 SetLastError(0xdeadbeef);
457 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
458 ok(!ret
, "Expected failure\n");
459 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
460 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
462 SetLastError(0xdeadbeef);
463 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, NULL
, &displaysize
);
464 ok(!ret
, "Expected failure\n");
465 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
466 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
467 todo_wine
ok(displaysize
== 1, "Service size expected 1, got %d\n", displaysize
);
470 strcpy(displayname
, "ABC");
471 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
472 ok(!ret
, "Expected failure\n");
473 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
474 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
475 todo_wine
ok(displaysize
== 15, "Service size expected 15, got %d\n", displaysize
);
476 ok(displayname
[0] == 0, "Service name not empty\n");
479 lstrcpyW( displaynameW
, abcW
);
480 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
481 ok(!ret
, "Expected failure\n");
482 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
483 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
484 ok(displaysize
== 15, "Service size expected 15, got %d\n", displaysize
);
485 ok(displaynameW
[0] == 0, "Service name not empty\n");
488 strcpy(displayname
, "ABC");
489 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
490 ok(!ret
, "Expected failure\n");
491 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
492 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
493 todo_wine
ok(displaysize
== 1, "Service size expected 1, got %d\n", displaysize
);
494 ok(displayname
[0] == 'A', "Service name changed\n");
497 lstrcpyW( displaynameW
, abcW
);
498 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
499 ok(!ret
, "Expected failure\n");
500 ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
501 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
502 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
503 ok(displaynameW
[0] == 'A', "Service name changed\n");
506 strcpy(displayname
, "ABC");
507 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
508 ok(!ret
, "Expected failure\n");
509 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
510 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
511 todo_wine
ok(displaysize
== 1, "Service size expected 1, got %d\n", displaysize
);
512 ok(displayname
[0] == 0, "Service name not empty\n");
515 lstrcpyW( displaynameW
, abcW
);
516 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
517 ok(!ret
, "Expected failure\n");
518 ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
519 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
520 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
521 ok(displaynameW
[0] == 'A', "Service name changed\n");
524 strcpy(displayname
, "ABC");
525 ret
= GetServiceDisplayNameA(scm_handle
, deadbeef
, displayname
, &displaysize
);
526 ok(!ret
, "Expected failure\n");
527 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
528 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
529 todo_wine
ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
530 ok(displayname
[0] == 0, "Service name not empty\n");
533 lstrcpyW( displaynameW
, abcW
);
534 ret
= GetServiceDisplayNameW(scm_handle
, deadbeefW
, displaynameW
, &displaysize
);
535 ok(!ret
, "Expected failure\n");
536 ok(displaysize
== 2, "Service size expected 2, got %d\n", displaysize
);
537 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
538 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
539 ok(displaynameW
[0] == 0, "Service name not empty\n");
541 /* Check if 'Spooler' exists */
542 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
545 skip("Spooler service doesn't exist\n");
546 CloseServiceHandle(scm_handle
);
549 CloseServiceHandle(svc_handle
);
551 /* Retrieve the needed size for the buffer */
552 SetLastError(0xdeadbeef);
554 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
555 ok(!ret
, "Expected failure\n");
556 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
557 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
558 tempsize
= displaysize
;
561 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
562 ok(!ret
, "Expected failure\n");
563 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
564 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
565 ok(displaysize
== tempsize
, "Buffer size mismatch (%d vs %d)\n", tempsize
, displaysize
);
567 /* Buffer is too small */
568 SetLastError(0xdeadbeef);
569 displaysize
= (tempsize
/ 2);
570 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
571 ok(!ret
, "Expected failure\n");
572 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
573 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
574 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
576 /* First try with a buffer that should be big enough to hold
577 * the ANSI string (and terminating character). This succeeds on Windows
578 * although when asked (see above 2 tests) it will return twice the needed size.
580 SetLastError(0xdeadbeef);
581 displaysize
= (tempsize
/ 2) + 1;
582 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
583 ok(ret
, "Expected success, got error %u\n", GetLastError());
584 ok(displaysize
== ((tempsize
/ 2) + 1), "Expected no change for the needed buffer size\n");
586 /* Now with the original returned size */
587 SetLastError(0xdeadbeef);
588 displaysize
= tempsize
;
589 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
590 ok(ret
, "Expected success, got error %u\n", GetLastError());
591 ok(displaysize
== tempsize
, "Expected no change for the needed buffer size\n");
593 /* And with a bigger than needed buffer */
594 SetLastError(0xdeadbeef);
595 displaysize
= tempsize
* 2;
596 ret
= GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
597 ok(ret
, "Expected success, got error %u\n", GetLastError());
598 /* Test that shows that if the buffersize is enough, it's not changed */
599 ok(displaysize
== tempsize
* 2, "Expected no change for the needed buffer size\n");
600 ok(lstrlen(displayname
) == tempsize
/2,
601 "Expected the buffer to be twice the length of the string\n") ;
603 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
604 SetLastError(0xdeadbeef);
606 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, NULL
, &displaysize
);
607 ok(!ret
, "Expected failure\n");
608 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
609 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
611 /* Buffer is too small */
612 SetLastError(0xdeadbeef);
613 tempsizeW
= displaysize
;
614 displaysize
= tempsizeW
/ 2;
615 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
616 ok(!ret
, "Expected failure\n");
617 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
618 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
619 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
621 /* Now with the original returned size */
622 SetLastError(0xdeadbeef);
623 displaysize
= tempsizeW
;
624 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
625 ok(!ret
, "Expected failure\n");
626 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
627 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
628 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
630 /* And with a bigger than needed buffer */
631 SetLastError(0xdeadbeef);
632 displaysize
= tempsizeW
+ 1; /* This caters for the null terminating character */
633 ret
= GetServiceDisplayNameW(scm_handle
, spoolerW
, displaynameW
, &displaysize
);
634 ok(ret
, "Expected success, got error %u\n", GetLastError());
635 ok(displaysize
== tempsizeW
, "Expected the needed buffersize\n");
636 ok(lstrlenW(displaynameW
) == displaysize
,
637 "Expected the buffer to be the length of the string\n") ;
638 ok(tempsize
/ 2 == tempsizeW
,
639 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n");
641 CloseServiceHandle(scm_handle
);
643 /* Test for a service without a displayname (which is valid). This should return
644 * the servicename itself.
646 SetLastError(0xdeadbeef);
647 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CREATE_SERVICE
);
648 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
650 skip("Not enough rights to get a handle to the manager\n");
654 SetLastError(0xdeadbeef);
655 svc_handle
= CreateServiceA(scm_handle
, servicename
, NULL
, DELETE
,
656 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
657 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
658 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
661 CloseServiceHandle(scm_handle
);
665 /* Retrieve the needed size for the buffer */
666 SetLastError(0xdeadbeef);
668 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, NULL
, &displaysize
);
669 ok(!ret
, "Expected failure\n");
670 ok(displaysize
== lstrlen(servicename
) * 2,
671 "Expected the displaysize to be twice the size of the servicename\n");
672 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
673 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
675 /* Buffer is too small */
676 SetLastError(0xdeadbeef);
677 tempsize
= displaysize
;
678 displaysize
= (tempsize
/ 2);
679 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
680 ok(!ret
, "Expected failure\n");
681 ok(displaysize
== tempsize
, "Expected the needed buffersize\n");
682 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
683 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
685 /* Get the displayname */
686 SetLastError(0xdeadbeef);
687 ret
= GetServiceDisplayNameA(scm_handle
, servicename
, displayname
, &displaysize
);
688 ok(ret
, "Expected success, got error %u\n", GetLastError());
689 ok(!lstrcmpi(displayname
, servicename
),
690 "Expected displayname to be %s, got %s\n", servicename
, displayname
);
692 /* Delete the service */
693 ret
= DeleteService(svc_handle
);
694 ok(ret
, "Expected success (err=%d)\n", GetLastError());
696 CloseServiceHandle(svc_handle
);
697 CloseServiceHandle(scm_handle
);
699 /* Wait a while. Just in case one of the following tests does a CreateService again */
703 static void test_get_servicekeyname(void)
705 SC_HANDLE scm_handle
, svc_handle
;
706 CHAR servicename
[4096];
707 CHAR displayname
[4096];
708 WCHAR servicenameW
[4096];
709 WCHAR displaynameW
[4096];
710 DWORD servicesize
, displaysize
, tempsize
;
712 static const CHAR deadbeef
[] = "Deadbeef";
713 static const WCHAR deadbeefW
[] = {'D','e','a','d','b','e','e','f',0};
714 static const WCHAR abcW
[] = {'A','B','C',0};
716 /* Having NULL for the size of the buffer will crash on W2K3 */
718 SetLastError(0xdeadbeef);
719 ret
= GetServiceKeyNameA(NULL
, NULL
, NULL
, &servicesize
);
720 ok(!ret
, "Expected failure\n");
721 ok(GetLastError() == ERROR_INVALID_HANDLE
,
722 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
724 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
727 SetLastError(0xdeadbeef);
728 ret
= GetServiceKeyNameA(scm_handle
, NULL
, NULL
, &servicesize
);
729 ok(!ret
, "Expected failure\n");
730 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
731 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
732 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
733 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
735 /* Valid handle and buffer but no displayname */
737 SetLastError(0xdeadbeef);
738 ret
= GetServiceKeyNameA(scm_handle
, NULL
, servicename
, &servicesize
);
739 ok(!ret
, "Expected failure\n");
740 ok(GetLastError() == ERROR_INVALID_ADDRESS
/* W2K, XP, W2K3, Vista */ ||
741 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
742 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
743 todo_wine
ok(servicesize
== 200, "Service size expected 1, got %d\n", servicesize
);
745 /* Test for nonexistent displayname */
746 SetLastError(0xdeadbeef);
747 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, NULL
, &servicesize
);
748 ok(!ret
, "Expected failure\n");
749 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
750 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
751 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
754 strcpy(servicename
, "ABC");
755 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
756 ok(!ret
, "Expected failure\n");
757 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
758 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
759 todo_wine
ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
760 ok(servicename
[0] == 0, "Service name not empty\n");
763 lstrcpyW( servicenameW
, abcW
);
764 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
765 ok(!ret
, "Expected failure\n");
766 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
767 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
768 ok(servicesize
== 15, "Service size expected 15, got %d\n", servicesize
);
769 ok(servicenameW
[0] == 0, "Service name not empty\n");
772 strcpy(servicename
, "ABC");
773 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
774 ok(!ret
, "Expected failure\n");
775 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
776 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
777 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
778 ok(servicename
[0] == 'A', "Service name changed\n");
781 lstrcpyW( servicenameW
, abcW
);
782 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
783 ok(!ret
, "Expected failure\n");
784 ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
785 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
786 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
787 ok(servicenameW
[0] == 'A', "Service name changed\n");
790 strcpy(servicename
, "ABC");
791 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
792 ok(!ret
, "Expected failure\n");
793 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
794 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
795 todo_wine
ok(servicesize
== 1, "Service size expected 1, got %d\n", servicesize
);
796 ok(servicename
[0] == 0, "Service name not empty\n");
799 lstrcpyW( servicenameW
, abcW
);
800 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
801 ok(!ret
, "Expected failure\n");
802 ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
803 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
804 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
805 ok(servicenameW
[0] == 'A', "Service name changed\n");
808 strcpy(servicename
, "ABC");
809 ret
= GetServiceKeyNameA(scm_handle
, deadbeef
, servicename
, &servicesize
);
810 ok(!ret
, "Expected failure\n");
811 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
812 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
813 todo_wine
ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
814 ok(servicename
[0] == 0, "Service name not empty\n");
817 lstrcpyW( servicenameW
, abcW
);
818 ret
= GetServiceKeyNameW(scm_handle
, deadbeefW
, servicenameW
, &servicesize
);
819 ok(!ret
, "Expected failure\n");
820 ok(servicesize
== 2, "Service size expected 2, got %d\n", servicesize
);
821 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
822 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
823 ok(servicenameW
[0] == 0, "Service name not empty\n");
825 /* Check if 'Spooler' exists */
826 svc_handle
= OpenServiceA(scm_handle
, spooler
, GENERIC_READ
);
829 skip("Spooler service doesn't exist\n");
830 CloseServiceHandle(scm_handle
);
833 CloseServiceHandle(svc_handle
);
835 /* Get the displayname for the 'Spooler' service */
836 GetServiceDisplayNameA(scm_handle
, spooler
, NULL
, &displaysize
);
837 GetServiceDisplayNameA(scm_handle
, spooler
, displayname
, &displaysize
);
839 /* Retrieve the needed size for the buffer */
840 SetLastError(0xdeadbeef);
842 ret
= GetServiceKeyNameA(scm_handle
, displayname
, NULL
, &servicesize
);
843 ok(!ret
, "Expected failure\n");
844 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
845 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
847 /* Valid call with the correct buffersize */
848 SetLastError(0xdeadbeef);
849 tempsize
= servicesize
;
851 ret
= GetServiceKeyNameA(scm_handle
, displayname
, servicename
, &servicesize
);
852 ok(ret
, "Expected success, got error %u\n", GetLastError());
855 ok(lstrlen(servicename
) == tempsize
/2,
856 "Expected the buffer to be twice the length of the string\n") ;
857 ok(!lstrcmpi(servicename
, spooler
), "Expected %s, got %s\n", spooler
, servicename
);
858 ok(servicesize
== (tempsize
* 2),
859 "Expected servicesize not to change if buffer not insufficient\n") ;
862 MultiByteToWideChar(CP_ACP
, 0, displayname
, -1, displaynameW
, sizeof(displaynameW
)/2);
863 SetLastError(0xdeadbeef);
865 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
866 ok(ret
, "Expected success, got error %u\n", GetLastError());
869 ok(lstrlen(servicename
) == tempsize
/2,
870 "Expected the buffer to be twice the length of the string\n") ;
871 ok(servicesize
== lstrlenW(servicenameW
),
872 "Expected servicesize not to change if buffer not insufficient\n") ;
875 SetLastError(0xdeadbeef);
877 ret
= GetServiceKeyNameW(scm_handle
, displaynameW
, servicenameW
, &servicesize
);
878 ok(!ret
, "Expected failure\n");
879 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
880 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
881 ok(servicenameW
[0] == 0, "Buffer not empty\n");
883 CloseServiceHandle(scm_handle
);
886 static void test_query_svc(void)
888 SC_HANDLE scm_handle
, svc_handle
;
890 SERVICE_STATUS status
;
891 SERVICE_STATUS_PROCESS
*statusproc
;
892 DWORD bufsize
, needed
;
894 /* All NULL or wrong */
895 SetLastError(0xdeadbeef);
896 ret
= QueryServiceStatus(NULL
, NULL
);
897 ok(!ret
, "Expected failure\n");
898 ok(GetLastError() == ERROR_INVALID_HANDLE
,
899 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
901 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
903 /* Check if 'Spooler' exists.
904 * Open with not enough rights to query the status.
906 svc_handle
= OpenServiceA(scm_handle
, spooler
, STANDARD_RIGHTS_READ
);
909 skip("Spooler service doesn't exist\n");
910 CloseServiceHandle(scm_handle
);
914 SetLastError(0xdeadbeef);
915 ret
= QueryServiceStatus(svc_handle
, NULL
);
916 ok(!ret
, "Expected failure\n");
918 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
919 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
920 "Unexpected last error %d\n", GetLastError());
922 SetLastError(0xdeadbeef);
923 ret
= QueryServiceStatus(svc_handle
, &status
);
924 ok(!ret
, "Expected failure\n");
925 ok(GetLastError() == ERROR_ACCESS_DENIED
,
926 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
928 /* Open the service with just enough rights.
929 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
931 CloseServiceHandle(svc_handle
);
932 svc_handle
= OpenServiceA(scm_handle
, spooler
, SERVICE_QUERY_STATUS
);
934 SetLastError(0xdeadbeef);
935 ret
= QueryServiceStatus(svc_handle
, &status
);
936 ok(ret
, "Expected success, got error %u\n", GetLastError());
938 CloseServiceHandle(svc_handle
);
940 /* More or less the same tests for QueryServiceStatusEx */
942 /* Open service with not enough rights to query the status */
943 svc_handle
= OpenServiceA(scm_handle
, spooler
, STANDARD_RIGHTS_READ
);
945 /* All NULL or wrong, this proves that info level is checked first */
946 SetLastError(0xdeadbeef);
947 ret
= pQueryServiceStatusEx(NULL
, 1, NULL
, 0, NULL
);
948 ok(!ret
, "Expected failure\n");
950 ok(GetLastError() == ERROR_INVALID_LEVEL
,
951 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
953 /* Passing a NULL parameter for the needed buffer size
954 * will crash on anything but NT4.
957 /* Only info level is correct. It looks like the buffer/size is checked second */
958 SetLastError(0xdeadbeef);
959 ret
= pQueryServiceStatusEx(NULL
, 0, NULL
, 0, &needed
);
960 /* NT4 and Wine check the handle first */
961 if (GetLastError() != ERROR_INVALID_HANDLE
)
963 ok(!ret
, "Expected failure\n");
964 ok(needed
== sizeof(SERVICE_STATUS_PROCESS
),
965 "Needed buffersize is wrong : %d\n", needed
);
966 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
967 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
970 /* Pass a correct buffer and buffersize but a NULL handle */
971 statusproc
= HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS
));
973 SetLastError(0xdeadbeef);
974 ret
= pQueryServiceStatusEx(NULL
, 0, (BYTE
*)statusproc
, bufsize
, &needed
);
975 ok(!ret
, "Expected failure\n");
976 ok(GetLastError() == ERROR_INVALID_HANDLE
,
977 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
978 HeapFree(GetProcessHeap(), 0, statusproc
);
980 /* Correct handle and info level */
981 SetLastError(0xdeadbeef);
982 ret
= pQueryServiceStatusEx(svc_handle
, 0, NULL
, 0, &needed
);
983 /* NT4 doesn't return the needed size */
984 if (GetLastError() != ERROR_INVALID_PARAMETER
)
986 ok(!ret
, "Expected failure\n");
989 ok(needed
== sizeof(SERVICE_STATUS_PROCESS
),
990 "Needed buffersize is wrong : %d\n", needed
);
991 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
992 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
996 /* All parameters are OK but we don't have enough rights */
997 statusproc
= HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS
));
998 bufsize
= sizeof(SERVICE_STATUS_PROCESS
);
999 SetLastError(0xdeadbeef);
1000 ret
= pQueryServiceStatusEx(svc_handle
, 0, (BYTE
*)statusproc
, bufsize
, &needed
);
1001 ok(!ret
, "Expected failure\n");
1002 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1003 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1004 HeapFree(GetProcessHeap(), 0, statusproc
);
1006 /* Open the service with just enough rights. */
1007 CloseServiceHandle(svc_handle
);
1008 svc_handle
= OpenServiceA(scm_handle
, spooler
, SERVICE_QUERY_STATUS
);
1010 /* Everything should be fine now. */
1011 statusproc
= HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS
));
1012 bufsize
= sizeof(SERVICE_STATUS_PROCESS
);
1013 SetLastError(0xdeadbeef);
1014 ret
= pQueryServiceStatusEx(svc_handle
, 0, (BYTE
*)statusproc
, bufsize
, &needed
);
1015 ok(ret
, "Expected success, got error %u\n", GetLastError());
1016 if (statusproc
->dwCurrentState
== SERVICE_RUNNING
)
1017 ok(statusproc
->dwProcessId
!= 0,
1018 "Expect a process id for this running service\n");
1020 ok(statusproc
->dwProcessId
== 0,
1021 "Expect no process id for this stopped service\n");
1022 HeapFree(GetProcessHeap(), 0, statusproc
);
1024 CloseServiceHandle(svc_handle
);
1025 CloseServiceHandle(scm_handle
);
1028 static void test_enum_svc(void)
1030 SC_HANDLE scm_handle
;
1032 DWORD bufsize
, needed
, returned
, resume
;
1033 DWORD tempneeded
, tempreturned
, missing
;
1034 DWORD servicecountactive
, servicecountinactive
;
1035 ENUM_SERVICE_STATUS
*services
;
1036 ENUM_SERVICE_STATUS_PROCESS
*exservices
;
1039 /* All NULL or wrong */
1040 SetLastError(0xdeadbeef);
1041 ret
= EnumServicesStatusA(NULL
, 1, 0, NULL
, 0, NULL
, NULL
, NULL
);
1042 ok(!ret
, "Expected failure\n");
1044 ok(GetLastError() == ERROR_INVALID_HANDLE
,
1045 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1047 /* Open the service control manager with not enough rights at first */
1048 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1050 /* Valid handle but rest is still NULL or wrong */
1051 SetLastError(0xdeadbeef);
1052 ret
= EnumServicesStatusA(scm_handle
, 1, 0, NULL
, 0, NULL
, NULL
, NULL
);
1053 ok(!ret
, "Expected failure\n");
1055 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1056 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1057 "Unexpected last error %d\n", GetLastError());
1059 /* Don't specify the two required pointers */
1060 returned
= 0xdeadbeef;
1061 SetLastError(0xdeadbeef);
1062 ret
= EnumServicesStatusA(scm_handle
, 0, 0, NULL
, 0, NULL
, &returned
, NULL
);
1063 ok(!ret
, "Expected failure\n");
1064 ok(returned
== 0xdeadbeef, "Expected no change to the number of services variable\n");
1066 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1067 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1068 "Unexpected last error %d\n", GetLastError());
1070 /* Don't specify the two required pointers */
1071 needed
= 0xdeadbeef;
1072 SetLastError(0xdeadbeef);
1073 ret
= EnumServicesStatusA(scm_handle
, 0, 0, NULL
, 0, &needed
, NULL
, NULL
);
1074 ok(!ret
, "Expected failure\n");
1075 ok(needed
== 0xdeadbeef || broken(needed
!= 0xdeadbeef), /* nt4 */
1076 "Expected no change to the needed buffer variable\n");
1078 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1079 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1080 "Unexpected last error %d\n", GetLastError());
1082 /* No valid servicetype and servicestate */
1083 needed
= 0xdeadbeef;
1084 returned
= 0xdeadbeef;
1085 SetLastError(0xdeadbeef);
1086 ret
= EnumServicesStatusA(scm_handle
, 0, 0, NULL
, 0, &needed
, &returned
, NULL
);
1087 ok(!ret
, "Expected failure\n");
1090 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1091 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1092 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1093 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1094 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1097 /* No valid servicetype and servicestate */
1098 needed
= 0xdeadbeef;
1099 returned
= 0xdeadbeef;
1100 SetLastError(0xdeadbeef);
1101 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, 0, NULL
, 0, &needed
, &returned
, NULL
);
1102 ok(!ret
, "Expected failure\n");
1105 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1106 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1107 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1108 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1109 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1112 /* No valid servicetype and servicestate */
1113 needed
= 0xdeadbeef;
1114 returned
= 0xdeadbeef;
1115 SetLastError(0xdeadbeef);
1116 ret
= EnumServicesStatusA(scm_handle
, 0, SERVICE_STATE_ALL
, NULL
, 0,
1117 &needed
, &returned
, NULL
);
1118 ok(!ret
, "Expected failure\n");
1121 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1122 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1123 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1124 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1125 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1128 /* All parameters are correct but our access rights are wrong */
1129 needed
= 0xdeadbeef;
1130 returned
= 0xdeadbeef;
1131 SetLastError(0xdeadbeef);
1132 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, NULL
, 0,
1133 &needed
, &returned
, NULL
);
1134 ok(!ret
, "Expected failure\n");
1137 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1138 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1139 ok(returned
== 0, "Expected number of services to be set to 0, got %d\n", returned
);
1141 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1142 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1144 /* Open the service control manager with the needed rights */
1145 CloseServiceHandle(scm_handle
);
1146 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
1148 /* All parameters are correct. Request the needed buffer size */
1149 needed
= 0xdeadbeef;
1150 returned
= 0xdeadbeef;
1151 SetLastError(0xdeadbeef);
1152 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, NULL
, 0,
1153 &needed
, &returned
, NULL
);
1154 ok(!ret
, "Expected failure\n");
1157 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size for this one service\n");
1158 ok(returned
== 0, "Expected no service returned, got %d\n", returned
);
1159 ok(GetLastError() == ERROR_MORE_DATA
,
1160 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1163 /* Store the needed bytes */
1164 tempneeded
= needed
;
1166 /* Allocate the correct needed bytes */
1167 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1169 needed
= 0xdeadbeef;
1170 returned
= 0xdeadbeef;
1171 SetLastError(0xdeadbeef);
1172 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1173 services
, bufsize
, &needed
, &returned
, NULL
);
1176 ok(ret
, "Expected success, got error %u\n", GetLastError());
1177 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1178 ok(returned
!= 0xdeadbeef && returned
> 0, "Expected some returned services\n");
1180 HeapFree(GetProcessHeap(), 0, services
);
1182 /* Store the number of returned services */
1183 tempreturned
= returned
;
1185 /* Allocate less than the needed bytes and don't specify a resume handle */
1186 services
= HeapAlloc(GetProcessHeap(), 0, tempneeded
);
1187 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1188 needed
= 0xdeadbeef;
1189 returned
= 0xdeadbeef;
1190 SetLastError(0xdeadbeef);
1191 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1192 services
, bufsize
, &needed
, &returned
, NULL
);
1193 ok(!ret
, "Expected failure\n");
1196 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size for this one service\n");
1197 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1198 ok(GetLastError() == ERROR_MORE_DATA
,
1199 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1202 /* Allocate less than the needed bytes, this time with a correct resume handle */
1203 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1204 needed
= 0xdeadbeef;
1205 returned
= 0xdeadbeef;
1207 SetLastError(0xdeadbeef);
1208 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1209 services
, bufsize
, &needed
, &returned
, &resume
);
1210 ok(!ret
, "Expected failure\n");
1213 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size for this one service\n");
1214 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1215 ok(resume
, "Expected a resume handle\n");
1216 ok(GetLastError() == ERROR_MORE_DATA
,
1217 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1220 /* Fetch the missing services but pass a bigger buffer size */
1221 missing
= tempreturned
- returned
;
1222 bufsize
= tempneeded
;
1223 needed
= 0xdeadbeef;
1224 returned
= 0xdeadbeef;
1225 SetLastError(0xdeadbeef);
1226 ret
= EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1227 services
, bufsize
, &needed
, &returned
, &resume
);
1230 ok(ret
, "Expected success, got error %u\n", GetLastError());
1231 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1232 ok(returned
== missing
, "Expected %u services to be returned\n", missing
);
1234 ok(resume
== 0, "Expected the resume handle to be 0\n");
1235 HeapFree(GetProcessHeap(), 0, services
);
1237 /* See if things add up */
1239 /* Vista only shows the drivers with a state of SERVICE_RUNNING as active
1240 * and doesn't count the others as inactive. This means that Vista could
1241 * show a total that is greater than the sum of active and inactive
1243 * The number of active and inactive drivers is greatly influenced by the
1244 * time when tests are run, immediately after boot or later for example.
1246 * Both reasons make calculations for drivers not so useful
1249 /* Get the number of active win32 services */
1250 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_ACTIVE
, NULL
, 0,
1251 &needed
, &returned
, NULL
);
1252 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1253 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_ACTIVE
, services
,
1254 needed
, &needed
, &returned
, NULL
);
1255 HeapFree(GetProcessHeap(), 0, services
);
1257 servicecountactive
= returned
;
1259 /* Get the number of inactive win32 services */
1260 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_INACTIVE
, NULL
, 0,
1261 &needed
, &returned
, NULL
);
1262 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1263 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_INACTIVE
, services
,
1264 needed
, &needed
, &returned
, NULL
);
1265 HeapFree(GetProcessHeap(), 0, services
);
1267 servicecountinactive
= returned
;
1269 /* Get the number of win32 services */
1270 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, NULL
, 0,
1271 &needed
, &returned
, NULL
);
1272 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1273 EnumServicesStatusA(scm_handle
, SERVICE_WIN32
, SERVICE_STATE_ALL
, services
,
1274 needed
, &needed
, &returned
, NULL
);
1275 HeapFree(GetProcessHeap(), 0, services
);
1277 /* Check if total is the same as active and inactive win32 services */
1279 ok(returned
== (servicecountactive
+ servicecountinactive
),
1280 "Something wrong in the calculation\n");
1282 /* Get all drivers and services
1284 * Fetch the status of the last call as failing could make the following tests crash
1285 * on Wine (we don't return anything yet).
1287 EnumServicesStatusA(scm_handle
, SERVICE_DRIVER
| SERVICE_WIN32
, SERVICE_STATE_ALL
,
1288 NULL
, 0, &needed
, &returned
, NULL
);
1289 services
= HeapAlloc(GetProcessHeap(), 0, needed
);
1290 ret
= EnumServicesStatusA(scm_handle
, SERVICE_DRIVER
| SERVICE_WIN32
, SERVICE_STATE_ALL
,
1291 services
, needed
, &needed
, &returned
, NULL
);
1293 /* Loop through all those returned drivers and services */
1294 for (i
= 0; ret
&& i
< returned
; i
++)
1296 SERVICE_STATUS status
= services
[i
].ServiceStatus
;
1298 /* lpServiceName and lpDisplayName should always be filled */
1299 ok(lstrlenA(services
[i
].lpServiceName
) > 0, "Expected a service name\n");
1300 ok(lstrlenA(services
[i
].lpDisplayName
) > 0, "Expected a display name\n");
1302 /* Decrement the counters to see if the functions calls return the same
1303 * numbers as the contents of these structures.
1305 if (status
.dwServiceType
& (SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
))
1307 if (status
.dwCurrentState
== SERVICE_RUNNING
)
1308 servicecountactive
--;
1310 servicecountinactive
--;
1313 HeapFree(GetProcessHeap(), 0, services
);
1317 ok(servicecountactive
== 0, "Active services mismatch %u\n", servicecountactive
);
1318 ok(servicecountinactive
== 0, "Inactive services mismatch %u\n", servicecountinactive
);
1321 CloseServiceHandle(scm_handle
);
1323 /* More or less the same for EnumServicesStatusExA */
1325 /* All NULL or wrong */
1326 SetLastError(0xdeadbeef);
1327 ret
= pEnumServicesStatusExA(NULL
, 1, 0, 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1328 ok(!ret
, "Expected failure\n");
1330 ok(GetLastError() == ERROR_INVALID_LEVEL
,
1331 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1333 /* All NULL or wrong, just the info level is correct */
1334 SetLastError(0xdeadbeef);
1335 ret
= pEnumServicesStatusExA(NULL
, 0, 0, 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1336 ok(!ret
, "Expected failure\n");
1338 ok(GetLastError() == ERROR_INVALID_HANDLE
,
1339 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1341 /* Open the service control manager with not enough rights at first */
1342 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1344 /* Valid handle and info level but rest is still NULL or wrong */
1345 SetLastError(0xdeadbeef);
1346 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, NULL
, NULL
, NULL
, NULL
);
1347 ok(!ret
, "Expected failure\n");
1349 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1350 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1351 "Unexpected last error %d\n", GetLastError());
1353 /* Don't specify the two required pointers */
1354 needed
= 0xdeadbeef;
1355 SetLastError(0xdeadbeef);
1356 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, &needed
, NULL
, NULL
, NULL
);
1357 ok(!ret
, "Expected failure\n");
1358 ok(needed
== 0xdeadbeef || broken(needed
!= 0xdeadbeef), /* nt4 */
1359 "Expected no change to the needed buffer variable\n");
1361 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1362 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1363 "Unexpected last error %d\n", GetLastError());
1365 /* Don't specify the two required pointers */
1366 returned
= 0xdeadbeef;
1367 SetLastError(0xdeadbeef);
1368 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, NULL
, &returned
, NULL
, NULL
);
1369 ok(!ret
, "Expected failure\n");
1372 ok(returned
== 0xdeadbeef, "Expected no change to the number of services variable\n");
1373 ok(GetLastError() == ERROR_INVALID_ADDRESS
||
1374 GetLastError() == ERROR_INVALID_PARAMETER
/* NT4 */,
1375 "Unexpected last error %d\n", GetLastError());
1378 /* No valid servicetype and servicestate */
1379 needed
= 0xdeadbeef;
1380 returned
= 0xdeadbeef;
1381 SetLastError(0xdeadbeef);
1382 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1383 ok(!ret
, "Expected failure\n");
1384 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1387 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1388 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1389 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1390 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1393 /* No valid servicestate */
1394 needed
= 0xdeadbeef;
1395 returned
= 0xdeadbeef;
1396 SetLastError(0xdeadbeef);
1397 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, 0, NULL
, 0,
1398 &needed
, &returned
, NULL
, NULL
);
1399 ok(!ret
, "Expected failure\n");
1400 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1403 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1404 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1405 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1406 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1409 /* No valid servicetype */
1410 needed
= 0xdeadbeef;
1411 returned
= 0xdeadbeef;
1412 SetLastError(0xdeadbeef);
1413 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, SERVICE_STATE_ALL
, NULL
, 0,
1414 &needed
, &returned
, NULL
, NULL
);
1415 ok(!ret
, "Expected failure\n");
1416 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1419 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1420 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1421 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1422 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1425 /* No valid servicetype and servicestate and unknown service group */
1426 needed
= 0xdeadbeef;
1427 returned
= 0xdeadbeef;
1428 SetLastError(0xdeadbeef);
1429 ret
= pEnumServicesStatusExA(scm_handle
, 0, 0, 0, NULL
, 0, &needed
,
1430 &returned
, NULL
, "deadbeef_group");
1431 ok(!ret
, "Expected failure\n");
1432 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1435 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1436 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1437 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1438 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1441 /* All parameters are correct but our access rights are wrong */
1442 needed
= 0xdeadbeef;
1443 returned
= 0xdeadbeef;
1444 SetLastError(0xdeadbeef);
1445 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1446 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1447 ok(!ret
, "Expected failure\n");
1449 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1450 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1451 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1452 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1453 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1455 /* All parameters are correct, access rights are wrong but the
1456 * group name won't be checked yet.
1458 needed
= 0xdeadbeef;
1459 returned
= 0xdeadbeef;
1460 SetLastError(0xdeadbeef);
1461 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1462 NULL
, 0, &needed
, &returned
, NULL
, "deadbeef_group");
1463 ok(!ret
, "Expected failure\n");
1465 ok(needed
== 0 || broken(needed
!= 0), /* nt4 */
1466 "Expected needed buffer size to be set to 0, got %d\n", needed
);
1467 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1468 ok(GetLastError() == ERROR_ACCESS_DENIED
,
1469 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1471 /* Open the service control manager with the needed rights */
1472 CloseServiceHandle(scm_handle
);
1473 scm_handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_ENUMERATE_SERVICE
);
1475 /* All parameters are correct and the group will be checked */
1476 needed
= 0xdeadbeef;
1477 returned
= 0xdeadbeef;
1478 SetLastError(0xdeadbeef);
1479 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1480 NULL
, 0, &needed
, &returned
, NULL
, "deadbeef_group");
1481 ok(!ret
, "Expected failure\n");
1482 ok(returned
== 0, "Expected number of service to be set to 0, got %d\n", returned
);
1485 ok(needed
== 0, "Expected needed buffer size to be set to 0, got %d\n", needed
);
1486 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST
,
1487 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
1490 /* TODO: Create a test that makes sure we enumerate all services that don't
1491 * belong to a group. (specifying "").
1494 /* All parameters are correct. Request the needed buffer size */
1495 needed
= 0xdeadbeef;
1496 returned
= 0xdeadbeef;
1497 SetLastError(0xdeadbeef);
1498 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1499 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1500 ok(!ret
, "Expected failure\n");
1501 ok(returned
== 0, "Expected no service returned, got %d\n", returned
);
1504 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size\n");
1505 ok(GetLastError() == ERROR_MORE_DATA
,
1506 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1509 /* Store the needed bytes */
1510 tempneeded
= needed
;
1512 /* Allocate the correct needed bytes */
1513 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1515 needed
= 0xdeadbeef;
1516 returned
= 0xdeadbeef;
1517 SetLastError(0xdeadbeef);
1518 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1519 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, NULL
, NULL
);
1522 ok(ret
, "Expected success, got error %u\n", GetLastError());
1523 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1524 ok(returned
== tempreturned
, "Expected the same number of service from this function\n");
1526 HeapFree(GetProcessHeap(), 0, exservices
);
1528 /* Store the number of returned services */
1529 tempreturned
= returned
;
1531 /* Allocate less than the needed bytes and don't specify a resume handle */
1532 exservices
= HeapAlloc(GetProcessHeap(), 0, tempneeded
);
1533 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1534 needed
= 0xdeadbeef;
1535 returned
= 0xdeadbeef;
1536 SetLastError(0xdeadbeef);
1537 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1538 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, NULL
, NULL
);
1539 ok(!ret
, "Expected failure\n");
1542 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size\n");
1543 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1544 ok(GetLastError() == ERROR_MORE_DATA
,
1545 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1548 /* Allocate less than the needed bytes, this time with a correct resume handle */
1549 bufsize
= (tempreturned
- 1) * sizeof(ENUM_SERVICE_STATUS
);
1550 needed
= 0xdeadbeef;
1551 returned
= 0xdeadbeef;
1553 SetLastError(0xdeadbeef);
1554 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1555 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, &resume
, NULL
);
1556 ok(!ret
, "Expected failure\n");
1559 ok(needed
!= 0xdeadbeef && needed
> 0, "Expected the needed buffer size\n");
1560 ok(returned
< tempreturned
, "Expected fewer services to be returned\n");
1561 ok(resume
, "Expected a resume handle\n");
1562 ok(GetLastError() == ERROR_MORE_DATA
,
1563 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
1566 /* Fetch that last service but pass a bigger buffer size */
1567 missing
= tempreturned
- returned
;
1568 bufsize
= tempneeded
;
1569 needed
= 0xdeadbeef;
1570 returned
= 0xdeadbeef;
1571 SetLastError(0xdeadbeef);
1572 ret
= pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1573 (BYTE
*)exservices
, bufsize
, &needed
, &returned
, &resume
, NULL
);
1576 ok(ret
, "Expected success, got error %u\n", GetLastError());
1577 ok(needed
== 0, "Expected needed buffer to be 0 as we are done\n");
1579 ok(returned
== missing
, "Expected %u services to be returned\n", missing
);
1580 ok(resume
== 0, "Expected the resume handle to be 0\n");
1581 HeapFree(GetProcessHeap(), 0, exservices
);
1583 /* See if things add up */
1585 /* Get the number of active win32 services */
1586 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_ACTIVE
,
1587 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1588 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1589 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_ACTIVE
,
1590 (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1591 HeapFree(GetProcessHeap(), 0, exservices
);
1593 servicecountactive
= returned
;
1595 /* Get the number of inactive win32 services */
1596 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_INACTIVE
,
1597 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1598 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1599 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_INACTIVE
,
1600 (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1601 HeapFree(GetProcessHeap(), 0, exservices
);
1603 servicecountinactive
= returned
;
1605 /* Get the number of win32 services */
1606 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1607 NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1608 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1609 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
, SERVICE_STATE_ALL
,
1610 (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1611 HeapFree(GetProcessHeap(), 0, exservices
);
1613 /* Check if total is the same as active and inactive win32 services */
1614 ok(returned
== (servicecountactive
+ servicecountinactive
),
1615 "Something wrong in the calculation\n");
1617 /* Get all drivers and services */
1618 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
| SERVICE_DRIVER
,
1619 SERVICE_STATE_ALL
, NULL
, 0, &needed
, &returned
, NULL
, NULL
);
1620 exservices
= HeapAlloc(GetProcessHeap(), 0, needed
);
1621 pEnumServicesStatusExA(scm_handle
, 0, SERVICE_WIN32
| SERVICE_DRIVER
,
1622 SERVICE_STATE_ALL
, (BYTE
*)exservices
, needed
, &needed
, &returned
, NULL
, NULL
);
1624 /* Loop through all those returned drivers and services */
1625 for (i
= 0; i
< returned
; i
++)
1627 SERVICE_STATUS_PROCESS status
= exservices
[i
].ServiceStatusProcess
;
1630 /* lpServiceName and lpDisplayName should always be filled */
1631 ok(lstrlenA(exservices
[i
].lpServiceName
) > 0, "Expected a service name\n");
1632 ok(lstrlenA(exservices
[i
].lpDisplayName
) > 0, "Expected a display name\n");
1634 /* Decrement the counters to see if the functions calls return the
1635 * same numbers as the contents of these structures.
1636 * Check some process id specifics.
1638 if (status
.dwServiceType
& (SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_KERNEL_DRIVER
))
1640 /* We shouldn't have a process id for drivers */
1641 ok(status
.dwProcessId
== 0,
1642 "This driver shouldn't have an associated process id\n");
1645 if (status
.dwServiceType
& (SERVICE_WIN32_OWN_PROCESS
| SERVICE_WIN32_SHARE_PROCESS
))
1647 if (status
.dwCurrentState
== SERVICE_RUNNING
)
1649 /* We expect a process id for every running service */
1650 ok(status
.dwProcessId
> 0, "Expected a process id for this running service (%s)\n",
1651 exservices
[i
].lpServiceName
);
1653 servicecountactive
--;
1657 /* We shouldn't have a process id for inactive services */
1658 ok(status
.dwProcessId
== 0, "Service %s state %u shouldn't have an associated process id\n",
1659 exservices
[i
].lpServiceName
, status
.dwCurrentState
);
1661 servicecountinactive
--;
1665 HeapFree(GetProcessHeap(), 0, exservices
);
1667 ok(servicecountactive
== 0, "Active services mismatch %u\n", servicecountactive
);
1668 ok(servicecountinactive
== 0, "Inactive services mismatch %u\n", servicecountinactive
);
1670 CloseServiceHandle(scm_handle
);
1673 static void test_close(void)
1679 SetLastError(0xdeadbeef);
1680 ret
= CloseServiceHandle(NULL
);
1681 ok(!ret
, "Expected failure\n");
1682 ok(GetLastError() == ERROR_INVALID_HANDLE
, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1684 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1687 handle
= OpenSCManagerA(NULL
, NULL
, SC_MANAGER_CONNECT
);
1688 SetLastError(0xdeadbeef);
1689 ret
= CloseServiceHandle(handle
);
1690 ok(ret
, "Expected success got error %u\n", GetLastError());
1693 static void test_sequence(void)
1695 SC_HANDLE scm_handle
, svc_handle
;
1697 QUERY_SERVICE_CONFIGA
*config
;
1698 DWORD given
, needed
;
1699 static const CHAR servicename
[] = "Winetest";
1700 static const CHAR displayname
[] = "Winetest dummy service";
1701 static const CHAR displayname2
[] = "Winetest dummy service (2)";
1702 static const CHAR pathname
[] = "we_dont_care.exe";
1703 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
1704 static const CHAR password
[] = "";
1705 static const CHAR empty
[] = "";
1706 static const CHAR localsystem
[] = "LocalSystem";
1708 SetLastError(0xdeadbeef);
1709 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1711 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1713 skip("Not enough rights to get a handle to the manager\n");
1717 ok(scm_handle
!= NULL
, "Could not get a handle to the manager: %d\n", GetLastError());
1719 if (!scm_handle
) return;
1721 /* Create a dummy service */
1722 SetLastError(0xdeadbeef);
1723 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
1724 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
1725 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
1727 if (!svc_handle
&& (GetLastError() == ERROR_SERVICE_EXISTS
))
1729 /* We try and open the service and do the rest of the tests. Some could
1730 * fail if the tests were changed between these runs.
1732 trace("Deletion probably didn't work last time\n");
1733 SetLastError(0xdeadbeef);
1734 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1735 if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1737 skip("Not enough rights to open the service\n");
1738 CloseServiceHandle(scm_handle
);
1741 ok(svc_handle
!= NULL
, "Could not open the service : %d\n", GetLastError());
1743 else if (!svc_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
1745 skip("Not enough rights to create the service\n");
1746 CloseServiceHandle(scm_handle
);
1751 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1752 if ((svc_handle
!= NULL
) && (pGetSecurityInfo
!= NULL
))
1754 PSID sidOwner
, sidGroup
;
1756 PSECURITY_DESCRIPTOR pSD
;
1757 HRESULT retval
= pGetSecurityInfo(svc_handle
,SE_SERVICE
,DACL_SECURITY_INFORMATION
,&sidOwner
,&sidGroup
,&dacl
,&sacl
,&pSD
);
1758 todo_wine
ok(ERROR_SUCCESS
== retval
, "Expected GetSecurityInfo to succeed: result %d\n",retval
);
1762 if (!svc_handle
) return;
1765 * Before we do a QueryServiceConfig we should check the registry. This will make sure
1766 * that the correct keys are used.
1769 /* Request the size for the buffer */
1770 SetLastError(0xdeadbeef);
1771 ret
= QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
1772 ok(!ret
, "Expected failure\n");
1773 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1775 config
= HeapAlloc(GetProcessHeap(), 0, needed
);
1777 SetLastError(0xdeadbeef);
1778 ret
= QueryServiceConfigA(svc_handle
, config
, given
, &needed
);
1779 ok(ret
, "Expected success, got error %u\n", GetLastError());
1781 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
1782 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
1783 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
1784 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
1785 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
1786 ok(config
->dwErrorControl
== SERVICE_ERROR_IGNORE
, "Expected SERVICE_ERROR_IGNORE, got %d\n", config
->dwErrorControl
);
1787 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
1788 ok(!strcmp(config
->lpLoadOrderGroup
, empty
), "Expected an empty string, got '%s'\n", config
->lpLoadOrderGroup
);
1789 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
1790 /* TODO: Show the double 0 terminated string */
1793 ok(!memcmp(config
->lpDependencies
, dependencies
, sizeof(dependencies
)), "Wrong string\n");
1795 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
1796 ok(!strcmp(config
->lpDisplayName
, displayname
), "Expected '%s', got '%s'\n", displayname
, config
->lpDisplayName
);
1798 ok(ChangeServiceConfigA(svc_handle
, SERVICE_NO_CHANGE
, SERVICE_NO_CHANGE
, SERVICE_ERROR_NORMAL
, NULL
, "TestGroup2", NULL
, NULL
, NULL
, NULL
, displayname2
),
1799 "ChangeServiceConfig failed (err=%d)\n", GetLastError());
1801 QueryServiceConfigA(svc_handle
, NULL
, 0, &needed
);
1802 config
= HeapReAlloc(GetProcessHeap(), 0, config
, needed
);
1803 ok(QueryServiceConfigA(svc_handle
, config
, needed
, &needed
), "QueryServiceConfig failed\n");
1804 ok(config
->lpBinaryPathName
&& config
->lpLoadOrderGroup
&& config
->lpDependencies
&& config
->lpServiceStartName
&&
1805 config
->lpDisplayName
, "Expected all string struct members to be non-NULL\n");
1806 ok(config
->dwServiceType
== (SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
),
1807 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config
->dwServiceType
);
1808 ok(config
->dwStartType
== SERVICE_DISABLED
, "Expected SERVICE_DISABLED, got %d\n", config
->dwStartType
);
1809 ok(config
->dwErrorControl
== SERVICE_ERROR_NORMAL
, "Expected SERVICE_ERROR_NORMAL, got %d\n", config
->dwErrorControl
);
1810 ok(!strcmp(config
->lpBinaryPathName
, pathname
), "Expected '%s', got '%s'\n", pathname
, config
->lpBinaryPathName
);
1811 ok(!strcmp(config
->lpLoadOrderGroup
, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config
->lpLoadOrderGroup
);
1812 ok(config
->dwTagId
== 0, "Expected 0, got %d\n", config
->dwTagId
);
1813 ok(!strcmp(config
->lpServiceStartName
, localsystem
), "Expected 'LocalSystem', got '%s'\n", config
->lpServiceStartName
);
1814 ok(!strcmp(config
->lpDisplayName
, displayname2
), "Expected '%s', got '%s'\n", displayname2
, config
->lpDisplayName
);
1816 SetLastError(0xdeadbeef);
1817 ret
= DeleteService(svc_handle
);
1818 ok(ret
, "Expected success, got error %u\n", GetLastError());
1819 CloseServiceHandle(svc_handle
);
1821 /* Wait a while. The following test does a CreateService again */
1824 CloseServiceHandle(scm_handle
);
1825 HeapFree(GetProcessHeap(), 0, config
);
1828 static void test_queryconfig2(void)
1830 SC_HANDLE scm_handle
, svc_handle
;
1832 DWORD expected
, needed
;
1833 BYTE buffer
[MAX_PATH
];
1834 LPSERVICE_DESCRIPTIONA pConfig
= (LPSERVICE_DESCRIPTIONA
)buffer
;
1835 static const CHAR servicename
[] = "Winetest";
1836 static const CHAR displayname
[] = "Winetest dummy service";
1837 static const CHAR pathname
[] = "we_dont_care.exe";
1838 static const CHAR dependencies
[] = "Master1\0Master2\0+MasterGroup1\0";
1839 static const CHAR password
[] = "";
1840 static const CHAR description
[] = "Description";
1842 if(!pQueryServiceConfig2A
)
1844 win_skip("function QueryServiceConfig2A not present\n");
1848 SetLastError(0xdeadbeef);
1849 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
1853 if(GetLastError() == ERROR_ACCESS_DENIED
)
1854 skip("Not enough rights to get a handle to the manager\n");
1856 ok(FALSE
, "Could not get a handle to the manager: %d\n", GetLastError());
1860 /* Create a dummy service */
1861 SetLastError(0xdeadbeef);
1862 svc_handle
= CreateServiceA(scm_handle
, servicename
, displayname
, GENERIC_ALL
,
1863 SERVICE_INTERACTIVE_PROCESS
| SERVICE_WIN32_OWN_PROCESS
, SERVICE_DISABLED
, SERVICE_ERROR_IGNORE
,
1864 pathname
, NULL
, NULL
, dependencies
, NULL
, password
);
1868 if(GetLastError() == ERROR_SERVICE_EXISTS
)
1870 /* We try and open the service and do the rest of the tests. Some could
1871 * fail if the tests were changed between these runs.
1873 trace("Deletion probably didn't work last time\n");
1874 SetLastError(0xdeadbeef);
1875 svc_handle
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
1878 if(GetLastError() == ERROR_ACCESS_DENIED
)
1879 skip("Not enough rights to open the service\n");
1881 ok(FALSE
, "Could not open the service : %d\n", GetLastError());
1882 CloseServiceHandle(scm_handle
);
1886 if (GetLastError() == ERROR_ACCESS_DENIED
)
1888 skip("Not enough rights to create the service\n");
1889 CloseServiceHandle(scm_handle
);
1892 ok(svc_handle
!= NULL
, "Could not create the service : %d\n", GetLastError());
1895 CloseServiceHandle(scm_handle
);
1899 SetLastError(0xdeadbeef);
1900 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1901 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1902 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1904 SetLastError(0xdeadbeef);
1905 ret
= pQueryServiceConfig2A(svc_handle
,0xfff0,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1906 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1907 ok(ERROR_INVALID_LEVEL
== GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1909 SetLastError(0xdeadbeef);
1910 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1911 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1912 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1914 SetLastError(0xdeadbeef);
1915 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1916 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1917 ok((ERROR_INVALID_ADDRESS
== GetLastError()) || (ERROR_INSUFFICIENT_BUFFER
== GetLastError()),
1918 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1920 SetLastError(0xdeadbeef);
1921 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,sizeof(SERVICE_DESCRIPTIONA
),NULL
);
1922 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1923 ok(ERROR_INVALID_ADDRESS
== GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError());
1926 SetLastError(0xdeadbeef);
1927 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
)-1,&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
);
1933 pConfig
->lpDescription
= (LPSTR
)0xdeadbeef;
1934 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1935 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1936 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1937 ok(!pConfig
->lpDescription
, "expected lpDescription to be NULL, got %p\n", pConfig
->lpDescription
);
1939 SetLastError(0xdeadbeef);
1941 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1942 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1943 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1944 ok(needed
== sizeof(SERVICE_DESCRIPTIONA
), "got %d\n", needed
);
1946 if(!pChangeServiceConfig2A
)
1948 win_skip("function ChangeServiceConfig2A not present\n");
1952 pConfig
->lpDescription
= (LPSTR
) description
;
1953 ret
= pChangeServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
);
1954 ok(ret
, "ChangeServiceConfig2A failed\n");
1959 SetLastError(0xdeadbeef);
1961 expected
= sizeof(SERVICE_DESCRIPTIONA
) + sizeof(description
) * sizeof(WCHAR
); /* !! */
1962 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,sizeof(SERVICE_DESCRIPTIONA
),&needed
);
1963 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1964 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1965 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1967 SetLastError(0xdeadbeef);
1968 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
-1,&needed
);
1969 ok(!ret
, "expected QueryServiceConfig2A to fail\n");
1970 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1972 SetLastError(0xdeadbeef);
1973 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
,needed
,&needed
);
1974 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1975 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1976 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1978 SetLastError(0xdeadbeef);
1979 ret
= pQueryServiceConfig2A(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
+ 1,&needed
);
1980 ok(ret
, "expected QueryServiceConfig2A to succeed\n");
1981 ok(pConfig
->lpDescription
&& !strcmp(description
,pConfig
->lpDescription
),
1982 "expected lpDescription to be %s, got %s\n",description
,pConfig
->lpDescription
);
1984 if(!pQueryServiceConfig2W
)
1986 win_skip("function QueryServiceConfig2W not present\n");
1989 SetLastError(0xdeadbeef);
1991 expected
= sizeof(SERVICE_DESCRIPTIONW
) + sizeof(WCHAR
) * sizeof(description
);
1992 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,NULL
,0,&needed
);
1993 ok(!ret
, "expected QueryServiceConfig2W to fail\n");
1994 ok(ERROR_INSUFFICIENT_BUFFER
== GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
1995 ok(needed
== expected
, "expected needed to be %d, got %d\n", expected
, needed
);
1997 SetLastError(0xdeadbeef);
1998 ret
= pQueryServiceConfig2W(svc_handle
, SERVICE_CONFIG_DESCRIPTION
,buffer
, needed
,&needed
);
1999 ok(ret
, "expected QueryServiceConfig2W to succeed\n");
2002 DeleteService(svc_handle
);
2004 CloseServiceHandle(svc_handle
);
2006 /* Wait a while. The following test does a CreateService again */
2009 CloseServiceHandle(scm_handle
);
2012 static void test_refcount(void)
2014 SC_HANDLE scm_handle
, svc_handle1
, svc_handle2
, svc_handle3
, svc_handle4
, svc_handle5
;
2015 static const CHAR servicename
[] = "Winetest";
2016 static const CHAR pathname
[] = "we_dont_care.exe";
2019 /* Get a handle to the Service Control Manager */
2020 SetLastError(0xdeadbeef);
2021 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
2022 if (!scm_handle
&& (GetLastError() == ERROR_ACCESS_DENIED
))
2024 skip("Not enough rights to get a handle to the manager\n");
2028 /* Create a service */
2029 svc_handle1
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
2030 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
2031 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
2032 ok(svc_handle1
!= NULL
, "Expected success, got error %u\n", GetLastError());
2034 /* Get a handle to this new service */
2035 svc_handle2
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
2036 ok(svc_handle2
!= NULL
, "Expected success, got error %u\n", GetLastError());
2038 /* Get another handle to this new service */
2039 svc_handle3
= OpenServiceA(scm_handle
, servicename
, GENERIC_READ
);
2040 ok(svc_handle3
!= NULL
, "Expected success, got error %u\n", GetLastError());
2042 /* Check if we can close the handle to the Service Control Manager */
2043 ret
= CloseServiceHandle(scm_handle
);
2044 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2046 /* Get a new handle to the Service Control Manager */
2047 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
2048 ok(scm_handle
!= NULL
, "Expected success, got error %u\n", GetLastError());
2050 /* Get a handle to this new service */
2051 svc_handle4
= OpenServiceA(scm_handle
, servicename
, GENERIC_ALL
);
2052 ok(svc_handle4
!= NULL
, "Expected success, got error %u\n", GetLastError());
2054 /* Delete the service */
2055 ret
= DeleteService(svc_handle4
);
2056 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2058 /* We cannot create the same service again as it's still marked as 'being deleted'.
2059 * The reason is that we still have 4 open handles to this service even though we
2060 * closed the handle to the Service Control Manager in between.
2062 SetLastError(0xdeadbeef);
2063 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
2064 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
2065 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
2068 ok(!svc_handle5
, "Expected failure\n");
2069 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE
,
2070 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
2073 /* FIXME: Remove this when Wine is fixed */
2076 DeleteService(svc_handle5
);
2077 CloseServiceHandle(svc_handle5
);
2080 /* Close all the handles to the service and try again */
2081 ret
= CloseServiceHandle(svc_handle4
);
2082 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2083 ret
= CloseServiceHandle(svc_handle3
);
2084 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2085 ret
= CloseServiceHandle(svc_handle2
);
2086 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2087 ret
= CloseServiceHandle(svc_handle1
);
2088 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2090 /* Wait a while. Doing a CreateService too soon will result again
2091 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2095 /* We succeed now as all handles are closed (tested this also with a long SLeep() */
2096 svc_handle5
= CreateServiceA(scm_handle
, servicename
, NULL
, GENERIC_ALL
,
2097 SERVICE_WIN32_OWN_PROCESS
| SERVICE_INTERACTIVE_PROCESS
,
2098 SERVICE_DISABLED
, 0, pathname
, NULL
, NULL
, NULL
, NULL
, NULL
);
2099 ok(svc_handle5
!= NULL
, "Expected success, got error %u\n", GetLastError());
2101 /* Delete the service */
2102 ret
= DeleteService(svc_handle5
);
2103 ok(ret
, "Expected success (err=%d)\n", GetLastError());
2105 /* Wait a while. Just in case one of the following tests does a CreateService again */
2108 CloseServiceHandle(svc_handle5
);
2109 CloseServiceHandle(scm_handle
);
2114 SC_HANDLE scm_handle
;
2116 /* Bail out if we are on win98 */
2117 SetLastError(0xdeadbeef);
2118 scm_handle
= OpenSCManagerA(NULL
, NULL
, GENERIC_ALL
);
2120 if (!scm_handle
&& (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
))
2122 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2125 CloseServiceHandle(scm_handle
);
2127 init_function_pointers();
2129 /* First some parameter checking */
2132 test_create_delete_svc();
2133 test_get_displayname();
2134 test_get_servicekeyname();
2138 /* Test the creation, querying and deletion of a service */
2140 test_queryconfig2();
2141 /* The main reason for this test is to check if any refcounting is used
2142 * and what the rules are