1 /*
2 * Unit tests for service functions
3 *
4 * Copyright (c) 2007 Paul Vriens
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
28 #include "winsvc.h"
29 #include "winnls.h"
30 #include "lmcons.h"
31 #include "aclapi.h"
32
33 #include "wine/test.h"
34
35 static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
36
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,
46 DWORD, LPDWORD);
47
48 static void init_function_pointers(void)
49 {
50 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
51
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");
58 }
59
60 static void test_open_scm(void)
61 {
62 SC_HANDLE scm_handle;
63
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);
69
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 */
76
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 */
83
84 /* Remote unknown host */
85 SetLastError(0xdeadbeef);
86 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
87 todo_wine
88 {
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());
92 }
93 CloseServiceHandle(scm_handle); /* Just in case */
94
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);
100
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);
106 }
107
108 static void test_open_svc(void)
109 {
110 SC_HANDLE scm_handle, svc_handle;
111 CHAR displayname[4096];
112 DWORD displaysize;
113
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());
119
120 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
121
122 /* NULL service */
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());
130
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);
138
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");
145 else
146 {
147 ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError());
148 CloseServiceHandle(svc_handle);
149 }
150
151 /* Test to show we can't open a service with the displayname */
152
153 /* Retrieve the needed size for the buffer */
154 displaysize = 0;
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.
160 */
161 if (!lstrcmpi(spooler, displayname))
162 {
163 skip("displayname equals servicename\n");
164 CloseServiceHandle(scm_handle);
165 return;
166 }
167
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());
172 /* Just in case */
173 CloseServiceHandle(svc_handle);
174
175 CloseServiceHandle(scm_handle);
176 }
177
178 static void test_create_delete_svc(void)
179 {
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;
189 BOOL ret;
190 CHAR display[4096];
191 DWORD display_size = sizeof(display);
192
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);
198 else
199 sprintf(account, ".\\%s", username);
200
201 /* All NULL */
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());
206
207 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
208
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());
216
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());
224
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());
232
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());
238
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());
244
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());
249
250 /* Open the Service Control Manager with minimal rights for creation
251 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE')
252 */
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))
257 {
258 skip("Not enough rights to get a handle to the manager\n");
259 return;
260 }
261
262 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */
263
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());
269
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());
274
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());
279
280 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed
281 * an ERROR_INVALID_PARAMETER)
282 */
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());
288
289 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */
290
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)
293 */
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());
299
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());
306
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.
309 */
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());
316
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)
320 */
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());
326
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());
333
334 /* The service already exists (check first, just in case) */
335 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ);
336 if (svc_handle1)
337 {
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());
345 }
346 else
347 skip("Spooler service doesn't exist\n");
348
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.
352 */
353 if (spooler_exists)
354 {
355 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size);
356
357 if (!ret)
358 skip("Could not retrieve a displayname for the Spooler service\n");
359 else
360 {
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());
366 }
367 }
368 else
369 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n");
370
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.
374 */
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());
379
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());
386
387 /* Open the service with minimal rights for deletion.
388 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE')
389 */
390 CloseServiceHandle(svc_handle1);
391 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE);
392
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());
397
398 CloseServiceHandle(svc_handle1);
399 CloseServiceHandle(scm_handle);
400
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.
404 */
405 Sleep(1000);
406
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());
413 }
414
415 static void test_get_displayname(void)
416 {
417 SC_HANDLE scm_handle, svc_handle;
418 BOOL ret;
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";
428
429 /* Having NULL for the size of the buffer will crash on W2K3 */
430
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());
436
437 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
438
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());
445
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());
453
454 /* Test for nonexistent service */
455 SetLastError(0xdeadbeef);
456 displaysize = -1;
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());
461
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);
468
469 displaysize = 15;
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");
477
478 displaysize = 15;
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");
486
487 displaysize = 0;
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");
495
496 displaysize = 0;
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");
504
505 displaysize = 1;
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");
513
514 displaysize = 1;
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");
522
523 displaysize = 2;
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");
531
532 displaysize = 2;
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");
540
541 /* Check if 'Spooler' exists */
542 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
543 if (!svc_handle)
544 {
545 skip("Spooler service doesn't exist\n");
546 CloseServiceHandle(scm_handle);
547 return;
548 }
549 CloseServiceHandle(svc_handle);
550
551 /* Retrieve the needed size for the buffer */
552 SetLastError(0xdeadbeef);
553 displaysize = -1;
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;
559
560 displaysize = 0;
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);
566
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());
575
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.
579 */
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");
585
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");
592
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") ;
602
603 /* Do the buffer(size) tests also for GetServiceDisplayNameW */
604 SetLastError(0xdeadbeef);
605 displaysize = -1;
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());
610
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());
620
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());
629
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");
640
641 CloseServiceHandle(scm_handle);
642
643 /* Test for a service without a displayname (which is valid). This should return
644 * the servicename itself.
645 */
646 SetLastError(0xdeadbeef);
647 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
648 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
649 {
650 skip("Not enough rights to get a handle to the manager\n");
651 return;
652 }
653
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());
659 if (!svc_handle)
660 {
661 CloseServiceHandle(scm_handle);
662 return;
663 }
664
665 /* Retrieve the needed size for the buffer */
666 SetLastError(0xdeadbeef);
667 displaysize = -1;
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());
674
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());
684
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);
691
692 /* Delete the service */
693 ret = DeleteService(svc_handle);
694 ok(ret, "Expected success (err=%d)\n", GetLastError());
695
696 CloseServiceHandle(svc_handle);
697 CloseServiceHandle(scm_handle);
698
699 /* Wait a while. Just in case one of the following tests does a CreateService again */
700 Sleep(1000);
701 }
702
703 static void test_get_servicekeyname(void)
704 {
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;
711 BOOL ret;
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};
715
716 /* Having NULL for the size of the buffer will crash on W2K3 */
717
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());
723
724 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
725
726 servicesize = 200;
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);
734
735 /* Valid handle and buffer but no displayname */
736 servicesize = 200;
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);
744
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);
752
753 servicesize = 15;
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");
761
762 servicesize = 15;
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");
770
771 servicesize = 0;
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");
779
780 servicesize = 0;
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");
788
789 servicesize = 1;
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");
797
798 servicesize = 1;
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");
806
807 servicesize = 2;
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");
815
816 servicesize = 2;
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");
824
825 /* Check if 'Spooler' exists */
826 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ);
827 if (!svc_handle)
828 {
829 skip("Spooler service doesn't exist\n");
830 CloseServiceHandle(scm_handle);
831 return;
832 }
833 CloseServiceHandle(svc_handle);
834
835 /* Get the displayname for the 'Spooler' service */
836 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize);
837 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize);
838
839 /* Retrieve the needed size for the buffer */
840 SetLastError(0xdeadbeef);
841 servicesize = 0;
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());
846
847 /* Valid call with the correct buffersize */
848 SetLastError(0xdeadbeef);
849 tempsize = servicesize;
850 servicesize *= 2;
851 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize);
852 ok(ret, "Expected success, got error %u\n", GetLastError());
853 if (ret)
854 {
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") ;
860 }
861
862 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2);
863 SetLastError(0xdeadbeef);
864 servicesize *= 2;
865 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize);
866 ok(ret, "Expected success, got error %u\n", GetLastError());
867 if (ret)
868 {
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") ;
873 }
874
875 SetLastError(0xdeadbeef);
876 servicesize = 3;
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");
882
883 CloseServiceHandle(scm_handle);
884 }
885
886 static void test_query_svc(void)
887 {
888 SC_HANDLE scm_handle, svc_handle;
889 BOOL ret;
890 SERVICE_STATUS status;
891 SERVICE_STATUS_PROCESS *statusproc;
892 DWORD bufsize, needed;
893
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());
900
901 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
902
903 /* Check if 'Spooler' exists.
904 * Open with not enough rights to query the status.
905 */
906 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
907 if (!svc_handle)
908 {
909 skip("Spooler service doesn't exist\n");
910 CloseServiceHandle(scm_handle);
911 return;
912 }
913
914 SetLastError(0xdeadbeef);
915 ret = QueryServiceStatus(svc_handle, NULL);
916 ok(!ret, "Expected failure\n");
917 todo_wine
918 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
919 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
920 "Unexpected last error %d\n", GetLastError());
921
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());
927
928 /* Open the service with just enough rights.
929 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS')
930 */
931 CloseServiceHandle(svc_handle);
932 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
933
934 SetLastError(0xdeadbeef);
935 ret = QueryServiceStatus(svc_handle, &status);
936 ok(ret, "Expected success, got error %u\n", GetLastError());
937
938 CloseServiceHandle(svc_handle);
939
940 /* More or less the same tests for QueryServiceStatusEx */
941
942 /* Open service with not enough rights to query the status */
943 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ);
944
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");
949 todo_wine
950 ok(GetLastError() == ERROR_INVALID_LEVEL,
951 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
952
953 /* Passing a NULL parameter for the needed buffer size
954 * will crash on anything but NT4.
955 */
956
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)
962 {
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());
968 }
969
970 /* Pass a correct buffer and buffersize but a NULL handle */
971 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
972 bufsize = needed;
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);
979
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)
985 {
986 ok(!ret, "Expected failure\n");
987 todo_wine
988 {
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());
993 }
994 }
995
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);
1005
1006 /* Open the service with just enough rights. */
1007 CloseServiceHandle(svc_handle);
1008 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS);
1009
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");
1019 else
1020 ok(statusproc->dwProcessId == 0,
1021 "Expect no process id for this stopped service\n");
1022 HeapFree(GetProcessHeap(), 0, statusproc);
1023
1024 CloseServiceHandle(svc_handle);
1025 CloseServiceHandle(scm_handle);
1026 }
1027
1028 static void test_enum_svc(void)
1029 {
1030 SC_HANDLE scm_handle;
1031 BOOL ret;
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;
1037 INT i;
1038
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");
1043 todo_wine
1044 ok(GetLastError() == ERROR_INVALID_HANDLE,
1045 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1046
1047 /* Open the service control manager with not enough rights at first */
1048 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1049
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");
1054 todo_wine
1055 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1056 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1057 "Unexpected last error %d\n", GetLastError());
1058
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");
1065 todo_wine
1066 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1067 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1068 "Unexpected last error %d\n", GetLastError());
1069
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");
1077 todo_wine
1078 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1079 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1080 "Unexpected last error %d\n", GetLastError());
1081
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");
1088 todo_wine
1089 {
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());
1095 }
1096
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");
1103 todo_wine
1104 {
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());
1110 }
1111
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");
1119 todo_wine
1120 {
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());
1126 }
1127
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");
1135 todo_wine
1136 {
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);
1140 }
1141 ok(GetLastError() == ERROR_ACCESS_DENIED,
1142 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
1143
1144 /* Open the service control manager with the needed rights */
1145 CloseServiceHandle(scm_handle);
1146 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1147
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");
1155 todo_wine
1156 {
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());
1161 }
1162
1163 /* Store the needed bytes */
1164 tempneeded = needed;
1165
1166 /* Allocate the correct needed bytes */
1167 services = HeapAlloc(GetProcessHeap(), 0, needed);
1168 bufsize = 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);
1174 todo_wine
1175 {
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");
1179 }
1180 HeapFree(GetProcessHeap(), 0, services);
1181
1182 /* Store the number of returned services */
1183 tempreturned = returned;
1184
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");
1194 todo_wine
1195 {
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());
1200 }
1201
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;
1206 resume = 0;
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");
1211 todo_wine
1212 {
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());
1218 }
1219
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);
1228 todo_wine
1229 {
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);
1233 }
1234 ok(resume == 0, "Expected the resume handle to be 0\n");
1235 HeapFree(GetProcessHeap(), 0, services);
1236
1237 /* See if things add up */
1238
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
1242 * drivers.
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.
1245 *
1246 * Both reasons make calculations for drivers not so useful
1247 */
1248
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);
1256
1257 servicecountactive = returned;
1258
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);
1266
1267 servicecountinactive = returned;
1268
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);
1276
1277 /* Check if total is the same as active and inactive win32 services */
1278 todo_wine
1279 ok(returned == (servicecountactive + servicecountinactive),
1280 "Something wrong in the calculation\n");
1281
1282 /* Get all drivers and services
1283 *
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).
1286 */
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);
1292
1293 /* Loop through all those returned drivers and services */
1294 for (i = 0; ret && i < returned; i++)
1295 {
1296 SERVICE_STATUS status = services[i].ServiceStatus;
1297
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");
1301
1302 /* Decrement the counters to see if the functions calls return the same
1303 * numbers as the contents of these structures.
1304 */
1305 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1306 {
1307 if (status.dwCurrentState == SERVICE_RUNNING)
1308 servicecountactive--;
1309 else
1310 servicecountinactive--;
1311 }
1312 }
1313 HeapFree(GetProcessHeap(), 0, services);
1314
1315 todo_wine
1316 {
1317 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1318 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1319 }
1320
1321 CloseServiceHandle(scm_handle);
1322
1323 /* More or less the same for EnumServicesStatusExA */
1324
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");
1329 todo_wine
1330 ok(GetLastError() == ERROR_INVALID_LEVEL,
1331 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
1332
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");
1337 todo_wine
1338 ok(GetLastError() == ERROR_INVALID_HANDLE,
1339 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1340
1341 /* Open the service control manager with not enough rights at first */
1342 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
1343
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");
1348 todo_wine
1349 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1350 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1351 "Unexpected last error %d\n", GetLastError());
1352
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");
1360 todo_wine
1361 ok(GetLastError() == ERROR_INVALID_ADDRESS ||
1362 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
1363 "Unexpected last error %d\n", GetLastError());
1364
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");
1370 todo_wine
1371 {
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());
1376 }
1377
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);
1385 todo_wine
1386 {
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());
1391 }
1392
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);
1401 todo_wine
1402 {
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());
1407 }
1408
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);
1417 todo_wine
1418 {
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());
1423 }
1424
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);
1433 todo_wine
1434 {
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());
1439 }
1440
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");
1448 todo_wine
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());
1454
1455 /* All parameters are correct, access rights are wrong but the
1456 * group name won't be checked yet.
1457 */
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");
1464 todo_wine
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());
1470
1471 /* Open the service control manager with the needed rights */
1472 CloseServiceHandle(scm_handle);
1473 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
1474
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);
1483 todo_wine
1484 {
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());
1488 }
1489
1490 /* TODO: Create a test that makes sure we enumerate all services that don't
1491 * belong to a group. (specifying "").
1492 */
1493
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);
1502 todo_wine
1503 {
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());
1507 }
1508
1509 /* Store the needed bytes */
1510 tempneeded = needed;
1511
1512 /* Allocate the correct needed bytes */
1513 exservices = HeapAlloc(GetProcessHeap(), 0, needed);
1514 bufsize = 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);
1520 todo_wine
1521 {
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");
1525 }
1526 HeapFree(GetProcessHeap(), 0, exservices);
1527
1528 /* Store the number of returned services */
1529 tempreturned = returned;
1530
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");
1540 todo_wine
1541 {
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());
1546 }
1547
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;
1552 resume = 0;
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");
1557 todo_wine
1558 {
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());
1564 }
1565
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);
1574 todo_wine
1575 {
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");
1578 }
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);
1582
1583 /* See if things add up */
1584
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);
1592
1593 servicecountactive = returned;
1594
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);
1602
1603 servicecountinactive = returned;
1604
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);
1612
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");
1616
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);
1623
1624 /* Loop through all those returned drivers and services */
1625 for (i = 0; i < returned; i++)
1626 {
1627 SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess;
1628
1629
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");
1633
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.
1637 */
1638 if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER))
1639 {
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");
1643 }
1644
1645 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))
1646 {
1647 if (status.dwCurrentState == SERVICE_RUNNING)
1648 {
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);
1652
1653 servicecountactive--;
1654 }
1655 else
1656 {
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);
1660
1661 servicecountinactive--;
1662 }
1663 }
1664 }
1665 HeapFree(GetProcessHeap(), 0, exservices);
1666
1667 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive);
1668 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive);
1669
1670 CloseServiceHandle(scm_handle);
1671 }
1672
1673 static void test_close(void)
1674 {
1675 SC_HANDLE handle;
1676 BOOL ret;
1677
1678 /* NULL handle */
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());
1683
1684 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
1685
1686 /* Proper call */
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());
1691 }
1692
1693 static void test_sequence(void)
1694 {
1695 SC_HANDLE scm_handle, svc_handle;
1696 BOOL ret;
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";
1707
1708 SetLastError(0xdeadbeef);
1709 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1710
1711 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1712 {
1713 skip("Not enough rights to get a handle to the manager\n");
1714 return;
1715 }
1716 else
1717 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
1718
1719 if (!scm_handle) return;
1720
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);
1726
1727 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
1728 {
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.
1731 */
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))
1736 {
1737 skip("Not enough rights to open the service\n");
1738 CloseServiceHandle(scm_handle);
1739 return;
1740 }
1741 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
1742 }
1743 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
1744 {
1745 skip("Not enough rights to create the service\n");
1746 CloseServiceHandle(scm_handle);
1747 return;
1748 }
1749 else
1750 {
1751 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1752 if ((svc_handle != NULL) && (pGetSecurityInfo != NULL))
1753 {
1754 PSID sidOwner, sidGroup;
1755 PACL dacl, sacl;
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);
1759 }
1760 }
1761
1762 if (!svc_handle) return;
1763
1764 /* TODO:
1765 * Before we do a QueryServiceConfig we should check the registry. This will make sure
1766 * that the correct keys are used.
1767 */
1768
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());
1774
1775 config = HeapAlloc(GetProcessHeap(), 0, needed);
1776 given = needed;
1777 SetLastError(0xdeadbeef);
1778 ret = QueryServiceConfigA(svc_handle, config, given, &needed);
1779 ok(ret, "Expected success, got error %u\n", GetLastError());
1780
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 */
1791 todo_wine
1792 {
1793 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
1794 }
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);
1797
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());
1800
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);
1815
1816 SetLastError(0xdeadbeef);
1817 ret = DeleteService(svc_handle);
1818 ok(ret, "Expected success, got error %u\n", GetLastError());
1819 CloseServiceHandle(svc_handle);
1820
1821 /* Wait a while. The following test does a CreateService again */
1822 Sleep(1000);
1823
1824 CloseServiceHandle(scm_handle);
1825 HeapFree(GetProcessHeap(), 0, config);
1826 }
1827
1828 static void test_queryconfig2(void)
1829 {
1830 SC_HANDLE scm_handle, svc_handle;
1831 BOOL ret;
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";
1841
1842 if(!pQueryServiceConfig2A)
1843 {
1844 win_skip("function QueryServiceConfig2A not present\n");
1845 return;
1846 }
1847
1848 SetLastError(0xdeadbeef);
1849 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
1850
1851 if (!scm_handle)
1852 {
1853 if(GetLastError() == ERROR_ACCESS_DENIED)
1854 skip("Not enough rights to get a handle to the manager\n");
1855 else
1856 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError());
1857 return;
1858 }
1859
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);
1865
1866 if (!svc_handle)
1867 {
1868 if(GetLastError() == ERROR_SERVICE_EXISTS)
1869 {
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.
1872 */
1873 trace("Deletion probably didn't work last time\n");
1874 SetLastError(0xdeadbeef);
1875 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
1876 if (!svc_handle)
1877 {
1878 if(GetLastError() == ERROR_ACCESS_DENIED)
1879 skip("Not enough rights to open the service\n");
1880 else
1881 ok(FALSE, "Could not open the service : %d\n", GetLastError());
1882 CloseServiceHandle(scm_handle);
1883 return;
1884 }
1885 }
1886 if (GetLastError() == ERROR_ACCESS_DENIED)
1887 {
1888 skip("Not enough rights to create the service\n");
1889 CloseServiceHandle(scm_handle);
1890 return;
1891 }
1892 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
1893 if (!svc_handle)
1894 {
1895 CloseServiceHandle(scm_handle);
1896 return;
1897 }
1898 }
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());
1903
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());
1908
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());
1913
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());
1919
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());
1924
1925 needed = 0;
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);
1931
1932 needed = 0;
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);
1938
1939 SetLastError(0xdeadbeef);
1940 needed = 0;
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);
1945
1946 if(!pChangeServiceConfig2A)
1947 {
1948 win_skip("function ChangeServiceConfig2A not present\n");
1949 goto cleanup;
1950 }
1951
1952 pConfig->lpDescription = (LPSTR) description;
1953 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer);
1954 ok(ret, "ChangeServiceConfig2A failed\n");
1955 if (!ret) {
1956 goto cleanup;
1957 }
1958
1959 SetLastError(0xdeadbeef);
1960 needed = 0;
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);
1966
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());
1971
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);
1977
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);
1983
1984 if(!pQueryServiceConfig2W)
1985 {
1986 win_skip("function QueryServiceConfig2W not present\n");
1987 goto cleanup;
1988 }
1989 SetLastError(0xdeadbeef);
1990 needed = 0;
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);
1996
1997 SetLastError(0xdeadbeef);
1998 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
1999 ok(ret, "expected QueryServiceConfig2W to succeed\n");
2000
2001 cleanup:
2002 DeleteService(svc_handle);
2003
2004 CloseServiceHandle(svc_handle);
2005
2006 /* Wait a while. The following test does a CreateService again */
2007 Sleep(1000);
2008
2009 CloseServiceHandle(scm_handle);
2010 }
2011
2012 static void test_refcount(void)
2013 {
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";
2017 BOOL ret;
2018
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))
2023 {
2024 skip("Not enough rights to get a handle to the manager\n");
2025 return;
2026 }
2027
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());
2033
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());
2037
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());
2041
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());
2045
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());
2049
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());
2053
2054 /* Delete the service */
2055 ret = DeleteService(svc_handle4);
2056 ok(ret, "Expected success (err=%d)\n", GetLastError());
2057
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.
2061 */
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);
2066 todo_wine
2067 {
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());
2071 }
2072
2073 /* FIXME: Remove this when Wine is fixed */
2074 if (svc_handle5)
2075 {
2076 DeleteService(svc_handle5);
2077 CloseServiceHandle(svc_handle5);
2078 }
2079
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());
2089
2090 /* Wait a while. Doing a CreateService too soon will result again
2091 * in an ERROR_SERVICE_MARKED_FOR_DELETE error.
2092 */
2093 Sleep(1000);
2094
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());
2100
2101 /* Delete the service */
2102 ret = DeleteService(svc_handle5);
2103 ok(ret, "Expected success (err=%d)\n", GetLastError());
2104
2105 /* Wait a while. Just in case one of the following tests does a CreateService again */
2106 Sleep(1000);
2107
2108 CloseServiceHandle(svc_handle5);
2109 CloseServiceHandle(scm_handle);
2110 }
2111
2112 START_TEST(service)
2113 {
2114 SC_HANDLE scm_handle;
2115
2116 /* Bail out if we are on win98 */
2117 SetLastError(0xdeadbeef);
2118 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
2119
2120 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2121 {
2122 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
2123 return;
2124 }
2125 CloseServiceHandle(scm_handle);
2126
2127 init_function_pointers();
2128
2129 /* First some parameter checking */
2130 test_open_scm();
2131 test_open_svc();
2132 test_create_delete_svc();
2133 test_get_displayname();
2134 test_get_servicekeyname();
2135 test_query_svc();
2136 test_enum_svc();
2137 test_close();
2138 /* Test the creation, querying and deletion of a service */
2139 test_sequence();
2140 test_queryconfig2();
2141 /* The main reason for this test is to check if any refcounting is used
2142 * and what the rules are
2143 */
2144 test_refcount();
2145 }
2146
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.