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 static CHAR selfname[MAX_PATH]; 37 38 static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID); 39 static BOOL (WINAPI *pChangeServiceConfig2W)(SC_HANDLE,DWORD,LPVOID); 40 static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD, 41 DWORD, LPBYTE, DWORD, LPDWORD, 42 LPDWORD, LPDWORD, LPCSTR); 43 static BOOL (WINAPI *pEnumServicesStatusExW)(SC_HANDLE, SC_ENUM_TYPE, DWORD, 44 DWORD, LPBYTE, DWORD, LPDWORD, 45 LPDWORD, LPDWORD, LPCWSTR); 46 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, 47 PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); 48 static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); 49 static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); 50 static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, 51 DWORD, LPDWORD); 52 static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION, 53 PSECURITY_DESCRIPTOR, DWORD, LPDWORD); 54 static DWORD (WINAPI *pNotifyServiceStatusChangeW)(SC_HANDLE,DWORD,SERVICE_NOTIFYW*); 55 56 static void init_function_pointers(void) 57 { 58 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); 59 60 pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2A"); 61 pChangeServiceConfig2W = (void*)GetProcAddress(hadvapi32, "ChangeServiceConfig2W"); 62 pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExA"); 63 pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32, "EnumServicesStatusExW"); 64 pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo"); 65 pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A"); 66 pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W"); 67 pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx"); 68 pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity"); 69 pNotifyServiceStatusChangeW = (void*)GetProcAddress(hadvapi32, "NotifyServiceStatusChangeW"); 70 } 71 72 static void test_open_scm(void) 73 { 74 SC_HANDLE scm_handle; 75 76 /* No access rights */ 77 SetLastError(0xdeadbeef); 78 scm_handle = OpenSCManagerA(NULL, NULL, 0); 79 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); 80 CloseServiceHandle(scm_handle); 81 82 /* Unknown database name */ 83 SetLastError(0xdeadbeef); 84 scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT); 85 ok(!scm_handle, "Expected failure\n"); 86 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); 87 CloseServiceHandle(scm_handle); /* Just in case */ 88 89 /* MSDN says only ServiceActive is allowed, or NULL */ 90 SetLastError(0xdeadbeef); 91 scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT); 92 ok(!scm_handle, "Expected failure\n"); 93 ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError()); 94 CloseServiceHandle(scm_handle); /* Just in case */ 95 96 /* Remote unknown host */ 97 SetLastError(0xdeadbeef); 98 scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT); 99 todo_wine 100 { 101 ok(!scm_handle, "Expected failure\n"); 102 ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* w2k8 */, 103 "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n", GetLastError()); 104 } 105 CloseServiceHandle(scm_handle); /* Just in case */ 106 107 /* Proper call with an empty hostname */ 108 scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT); 109 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); 110 CloseServiceHandle(scm_handle); 111 112 /* Again a correct one */ 113 SetLastError(0xdeadbeef); 114 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 115 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_IO_PENDING) /* win2k */, 116 "Expected ERROR_SUCCESS, got %u\n", GetLastError()); 117 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); 118 CloseServiceHandle(scm_handle); 119 } 120 121 static void test_open_svc(void) 122 { 123 SC_HANDLE scm_handle, svc_handle; 124 CHAR displayname[4096]; 125 DWORD displaysize; 126 127 /* All NULL (invalid access rights) */ 128 SetLastError(0xdeadbeef); 129 svc_handle = OpenServiceA(NULL, NULL, 0); 130 ok(!svc_handle, "Expected failure\n"); 131 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 132 133 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */ 134 135 /* NULL service */ 136 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 137 SetLastError(0xdeadbeef); 138 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ); 139 ok(!svc_handle, "Expected failure\n"); 140 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || 141 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 142 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 143 CloseServiceHandle(scm_handle); 144 145 /* Nonexistent service */ 146 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 147 SetLastError(0xdeadbeef); 148 svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ); 149 ok(!svc_handle, "Expected failure\n"); 150 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 151 CloseServiceHandle(scm_handle); 152 153 /* Proper SCM handle but different access rights */ 154 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 155 SetLastError(0xdeadbeef); 156 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_WRITE); 157 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 158 skip("Not enough rights to get a handle to the service\n"); 159 else 160 { 161 ok(svc_handle != NULL, "Expected success, got error %u\n", GetLastError()); 162 CloseServiceHandle(svc_handle); 163 } 164 165 /* Test to show we can't open a service with the displayname */ 166 167 /* Retrieve the needed size for the buffer */ 168 displaysize = 0; 169 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); 170 /* Get the displayname */ 171 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); 172 /* Try to open the service with this displayname, unless the displayname equals 173 * the servicename as that would defeat the purpose of this test. 174 */ 175 if (!lstrcmpiA(spooler, displayname)) 176 { 177 skip("displayname equals servicename\n"); 178 CloseServiceHandle(scm_handle); 179 return; 180 } 181 182 SetLastError(0xdeadbeef); 183 svc_handle = OpenServiceA(scm_handle, displayname, GENERIC_READ); 184 ok(!svc_handle, "Expected failure\n"); 185 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 186 /* Just in case */ 187 CloseServiceHandle(svc_handle); 188 189 CloseServiceHandle(scm_handle); 190 } 191 192 static void test_create_delete_svc(void) 193 { 194 SC_HANDLE scm_handle, svc_handle1, svc_handle2; 195 CHAR username[UNLEN + 1], domain[MAX_PATH]; 196 DWORD user_size = UNLEN + 1; 197 CHAR account[MAX_PATH + UNLEN + 1]; 198 static const CHAR servicename [] = "Winetest"; 199 static const CHAR pathname [] = "we_dont_care.exe"; 200 static const CHAR empty [] = ""; 201 static const CHAR password [] = "secret"; 202 BOOL spooler_exists = FALSE; 203 BOOL ret; 204 CHAR display[4096]; 205 DWORD display_size = sizeof(display); 206 207 /* Get the username and turn it into an account to be used in some tests */ 208 GetUserNameA(username, &user_size); 209 /* Get the domainname to cater for that situation */ 210 if (GetEnvironmentVariableA("USERDOMAIN", domain, MAX_PATH)) 211 sprintf(account, "%s\\%s", domain, username); 212 else 213 sprintf(account, ".\\%s", username); 214 215 /* All NULL */ 216 SetLastError(0xdeadbeef); 217 svc_handle1 = CreateServiceA(NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); 218 ok(!svc_handle1, "Expected failure\n"); 219 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 220 221 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 222 223 /* Only a valid handle to the Service Control Manager */ 224 SetLastError(0xdeadbeef); 225 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); 226 ok(!svc_handle1, "Expected failure\n"); 227 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ || 228 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 229 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 230 231 /* Now with a servicename */ 232 SetLastError(0xdeadbeef); 233 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL); 234 ok(!svc_handle1, "Expected failure\n"); 235 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ || 236 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 237 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 238 239 /* Or just a binary name */ 240 SetLastError(0xdeadbeef); 241 svc_handle1 = CreateServiceA(scm_handle, NULL, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); 242 ok(!svc_handle1, "Expected failure\n"); 243 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, W2K3, XP, Vista */ || 244 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 245 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 246 247 /* Both servicename and binary name (We only have connect rights) */ 248 SetLastError(0xdeadbeef); 249 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); 250 ok(!svc_handle1, "Expected failure\n"); 251 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 252 253 /* They can even be empty at this stage of parameter checking */ 254 SetLastError(0xdeadbeef); 255 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); 256 ok(!svc_handle1, "Expected failure\n"); 257 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 258 259 SetLastError(0xdeadbeef); 260 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); 261 ok(!svc_handle1, "Expected failure\n"); 262 ok(GetLastError() == ERROR_ACCESS_DENIED, "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 263 264 /* Open the Service Control Manager with minimal rights for creation 265 * (Verified with 'SC_MANAGER_ALL_ACCESS &~ SC_MANAGER_CREATE_SERVICE') 266 */ 267 CloseServiceHandle(scm_handle); 268 SetLastError(0xdeadbeef); 269 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 270 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 271 { 272 skip("Not enough rights to get a handle to the manager\n"); 273 return; 274 } 275 276 /* TODO: It looks like account (ServiceStartName) and (maybe) password are checked at this place */ 277 278 /* Empty strings for servicename and binary name are checked */ 279 SetLastError(0xdeadbeef); 280 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, pathname, NULL, NULL, NULL, NULL, NULL); 281 ok(!svc_handle1, "Expected failure\n"); 282 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); 283 284 SetLastError(0xdeadbeef); 285 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, 0, 0, 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 SetLastError(0xdeadbeef); 290 svc_handle1 = CreateServiceA(scm_handle, empty, NULL, 0, 0, 0, 0, empty, NULL, NULL, NULL, NULL, NULL); 291 ok(!svc_handle1, "Expected failure\n"); 292 ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError()); 293 294 /* Valid call (as we will see later) except for the empty binary name (to proof it's indeed 295 * an ERROR_INVALID_PARAMETER) 296 */ 297 SetLastError(0xdeadbeef); 298 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS, 299 SERVICE_DISABLED, 0, empty, NULL, NULL, NULL, NULL, NULL); 300 ok(!svc_handle1, "Expected failure\n"); 301 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 302 303 /* Windows checks if the 'service type', 'access type' and the combination of them are valid, so let's test that */ 304 305 /* Illegal (service-type, which is used as a mask can't have a mix. Except the one with 306 * SERVICE_INTERACTIVE_PROCESS which will be tested below in a valid call) 307 */ 308 SetLastError(0xdeadbeef); 309 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS, 310 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 311 ok(!svc_handle1, "Expected failure\n"); 312 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 313 314 /* Illegal (SERVICE_INTERACTIVE_PROCESS is only allowed with SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS) */ 315 SetLastError(0xdeadbeef); 316 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_FILE_SYSTEM_DRIVER | SERVICE_INTERACTIVE_PROCESS, 317 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 318 ok(!svc_handle1, "Expected failure\n"); 319 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 320 321 /* Illegal (this combination is only allowed when the LocalSystem account (ServiceStartName) is used) 322 * Not having a correct account would have resulted in an ERROR_INVALID_SERVICE_ACCOUNT. 323 */ 324 SetLastError(0xdeadbeef); 325 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 326 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, account, password); 327 ok(!svc_handle1, "Expected failure\n"); 328 ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_SERVICE_ACCOUNT, 329 "Expected ERROR_INVALID_PARAMETER or ERROR_INVALID_SERVICE_ACCOUNT, got %d\n", GetLastError()); 330 331 /* Illegal (start-type is not a mask and should only be one of the possibilities) 332 * Remark : 'OR'-ing them could result in a valid possibility (but doesn't make sense as 333 * it's most likely not the wanted start-type) 334 */ 335 SetLastError(0xdeadbeef); 336 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS, 337 SERVICE_AUTO_START | SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 338 ok(!svc_handle1, "Expected failure\n"); 339 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 340 341 /* Illegal (SERVICE_BOOT_START and SERVICE_SYSTEM_START are only allowed for driver services) */ 342 SetLastError(0xdeadbeef); 343 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS, 344 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); 345 ok(!svc_handle1, "Expected failure\n"); 346 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 347 348 /* Test if ServiceType can be a combined one for drivers */ 349 SetLastError(0xdeadbeef); 350 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER, 351 SERVICE_BOOT_START, 0, pathname, NULL, NULL, NULL, NULL, NULL); 352 ok(!svc_handle1, "Expected failure\n"); 353 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 354 355 /* The service already exists (check first, just in case) */ 356 svc_handle1 = OpenServiceA(scm_handle, spooler, GENERIC_READ); 357 if (svc_handle1) 358 { 359 spooler_exists = TRUE; 360 CloseServiceHandle(svc_handle1); 361 SetLastError(0xdeadbeef); 362 svc_handle1 = CreateServiceA(scm_handle, spooler, NULL, 0, SERVICE_WIN32_OWN_PROCESS, 363 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 364 ok(!svc_handle1, "Expected failure\n"); 365 ok(GetLastError() == ERROR_SERVICE_EXISTS, "Expected ERROR_SERVICE_EXISTS, got %d\n", GetLastError()); 366 } 367 else 368 skip("Spooler service doesn't exist\n"); 369 370 /* To find an existing displayname we check the 'Spooler' service. Although the registry 371 * doesn't show DisplayName on NT4, this call will return a displayname which is equal 372 * to the servicename and can't be used as well for a new displayname. 373 */ 374 if (spooler_exists) 375 { 376 ret = GetServiceDisplayNameA(scm_handle, spooler, display, &display_size); 377 378 if (!ret) 379 skip("Could not retrieve a displayname for the Spooler service\n"); 380 else 381 { 382 svc_handle1 = CreateServiceA(scm_handle, servicename, display, 0, SERVICE_WIN32_OWN_PROCESS, 383 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 384 ok(!svc_handle1, "Expected failure for display name '%s'\n", display); 385 ok(GetLastError() == ERROR_DUPLICATE_SERVICE_NAME, 386 "Expected ERROR_DUPLICATE_SERVICE_NAME, got %d\n", GetLastError()); 387 } 388 } 389 else 390 skip("Could not retrieve a displayname (Spooler service doesn't exist)\n"); 391 392 /* Windows doesn't care about the access rights for creation (which makes 393 * sense as there is no service yet) as long as there are sufficient 394 * rights to the manager. 395 */ 396 SetLastError(0xdeadbeef); 397 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 398 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 399 ok(svc_handle1 != NULL, "Could not create the service : %d\n", GetLastError()); 400 401 /* DeleteService however must have proper rights */ 402 SetLastError(0xdeadbeef); 403 ret = DeleteService(svc_handle1); 404 ok(!ret, "Expected failure\n"); 405 ok(GetLastError() == ERROR_ACCESS_DENIED, 406 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 407 408 /* Open the service with minimal rights for deletion. 409 * (Verified with 'SERVICE_ALL_ACCESS &~ DELETE') 410 */ 411 CloseServiceHandle(svc_handle1); 412 svc_handle1 = OpenServiceA(scm_handle, servicename, DELETE); 413 414 /* Now that we have the proper rights, we should be able to delete */ 415 SetLastError(0xdeadbeef); 416 ret = DeleteService(svc_handle1); 417 ok(ret, "Expected success, got error %u\n", GetLastError()); 418 419 /* Service is marked for delete, but handle is still open. Try to open service again. */ 420 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ); 421 ok(svc_handle2 != NULL, "got %p, error %u\n", svc_handle2, GetLastError()); 422 CloseServiceHandle(svc_handle2); 423 424 CloseServiceHandle(svc_handle1); 425 CloseServiceHandle(scm_handle); 426 427 /* Wait a while. One of the following tests also does a CreateService for the 428 * same servicename and this would result in an ERROR_SERVICE_MARKED_FOR_DELETE 429 * error if we do this too quickly. Vista seems more picky than the others. 430 */ 431 Sleep(1000); 432 433 /* And a final NULL check */ 434 SetLastError(0xdeadbeef); 435 ret = DeleteService(NULL); 436 ok(!ret, "Expected failure\n"); 437 ok(GetLastError() == ERROR_INVALID_HANDLE, 438 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 439 } 440 441 static void test_get_displayname(void) 442 { 443 SC_HANDLE scm_handle, svc_handle; 444 BOOL ret; 445 CHAR displayname[4096]; 446 WCHAR displaynameW[2048]; 447 DWORD displaysize, tempsize, tempsizeW; 448 static const CHAR deadbeef[] = "Deadbeef"; 449 static const WCHAR spoolerW[] = {'S','p','o','o','l','e','r',0}; 450 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0}; 451 static const WCHAR abcW[] = {'A','B','C',0}; 452 static const CHAR servicename[] = "Winetest"; 453 static const CHAR pathname[] = "we_dont_care.exe"; 454 455 /* Having NULL for the size of the buffer will crash on W2K3 */ 456 457 SetLastError(0xdeadbeef); 458 ret = GetServiceDisplayNameA(NULL, NULL, NULL, &displaysize); 459 ok(!ret, "Expected failure\n"); 460 ok(GetLastError() == ERROR_INVALID_HANDLE, 461 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 462 463 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 464 465 SetLastError(0xdeadbeef); 466 ret = GetServiceDisplayNameA(scm_handle, NULL, NULL, &displaysize); 467 ok(!ret, "Expected failure\n"); 468 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || 469 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 470 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 471 472 SetLastError(0xdeadbeef); 473 displaysize = sizeof(displayname); 474 ret = GetServiceDisplayNameA(scm_handle, NULL, displayname, &displaysize); 475 ok(!ret, "Expected failure\n"); 476 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || 477 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 478 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 479 480 /* Test for nonexistent service */ 481 SetLastError(0xdeadbeef); 482 displaysize = -1; 483 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &displaysize); 484 ok(!ret, "Expected failure\n"); 485 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 486 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 487 488 SetLastError(0xdeadbeef); 489 ret = GetServiceDisplayNameA(scm_handle, deadbeef, NULL, &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 495 displaysize = 15; 496 strcpy(displayname, "ABC"); 497 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); 498 ok(!ret, "Expected failure\n"); 499 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 500 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 501 todo_wine ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize); 502 ok(displayname[0] == 0, "Service name not empty\n"); 503 504 displaysize = 15; 505 lstrcpyW( displaynameW, abcW ); 506 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); 507 ok(!ret, "Expected failure\n"); 508 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 509 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 510 ok(displaysize == 15, "Service size expected 15, got %d\n", displaysize); 511 ok(displaynameW[0] == 0, "Service name not empty\n"); 512 513 displaysize = 0; 514 strcpy(displayname, "ABC"); 515 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); 516 ok(!ret, "Expected failure\n"); 517 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 518 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 519 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize); 520 ok(displayname[0] == 'A', "Service name changed\n"); 521 522 displaysize = 0; 523 lstrcpyW( displaynameW, abcW ); 524 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); 525 ok(!ret, "Expected failure\n"); 526 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); 527 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 528 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 529 ok(displaynameW[0] == 'A', "Service name changed\n"); 530 531 displaysize = 1; 532 strcpy(displayname, "ABC"); 533 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); 534 ok(!ret, "Expected failure\n"); 535 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 536 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 537 todo_wine ok(displaysize == 1, "Service size expected 1, got %d\n", displaysize); 538 ok(displayname[0] == 0, "Service name not empty\n"); 539 540 displaysize = 1; 541 lstrcpyW( displaynameW, abcW ); 542 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); 543 ok(!ret, "Expected failure\n"); 544 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); 545 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 546 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 547 ok(displaynameW[0] == 'A', "Service name changed\n"); 548 549 displaysize = 2; 550 strcpy(displayname, "ABC"); 551 ret = GetServiceDisplayNameA(scm_handle, deadbeef, displayname, &displaysize); 552 ok(!ret, "Expected failure\n"); 553 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 554 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 555 todo_wine ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); 556 ok(displayname[0] == 0, "Service name not empty\n"); 557 558 displaysize = 2; 559 lstrcpyW( displaynameW, abcW ); 560 ret = GetServiceDisplayNameW(scm_handle, deadbeefW, displaynameW, &displaysize); 561 ok(!ret, "Expected failure\n"); 562 ok(displaysize == 2, "Service size expected 2, got %d\n", displaysize); 563 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 564 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 565 ok(displaynameW[0] == 0, "Service name not empty\n"); 566 567 /* Check if 'Spooler' exists */ 568 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ); 569 if (!svc_handle) 570 { 571 skip("Spooler service doesn't exist\n"); 572 CloseServiceHandle(scm_handle); 573 return; 574 } 575 CloseServiceHandle(svc_handle); 576 577 /* Retrieve the needed size for the buffer */ 578 SetLastError(0xdeadbeef); 579 displaysize = -1; 580 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); 581 ok(!ret, "Expected failure\n"); 582 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 583 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 584 tempsize = displaysize; 585 586 displaysize = 0; 587 ret = GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); 588 ok(!ret, "Expected failure\n"); 589 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 590 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 591 ok(displaysize == tempsize, "Buffer size mismatch (%d vs %d)\n", tempsize, displaysize); 592 593 /* Buffer is too small */ 594 SetLastError(0xdeadbeef); 595 displaysize = (tempsize / 2); 596 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); 597 ok(!ret, "Expected failure\n"); 598 ok(displaysize == tempsize, "Expected the needed buffersize\n"); 599 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 600 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 601 602 /* First try with a buffer that should be big enough to hold 603 * the ANSI string (and terminating character). This succeeds on Windows 604 * although when asked (see above 2 tests) it will return twice the needed size. 605 */ 606 SetLastError(0xdeadbeef); 607 displaysize = (tempsize / 2) + 1; 608 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); 609 ok(ret, "Expected success, got error %u\n", GetLastError()); 610 ok(displaysize == ((tempsize / 2) + 1), "Expected no change for the needed buffer size\n"); 611 612 /* Now with the original returned size */ 613 SetLastError(0xdeadbeef); 614 displaysize = tempsize; 615 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); 616 ok(ret, "Expected success, got error %u\n", GetLastError()); 617 ok(displaysize == tempsize, "Expected no change for the needed buffer size\n"); 618 619 /* And with a bigger than needed buffer */ 620 SetLastError(0xdeadbeef); 621 displaysize = tempsize * 2; 622 ret = GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); 623 ok(ret, "Expected success, got error %u\n", GetLastError()); 624 /* Test that shows that if the buffersize is enough, it's not changed */ 625 ok(displaysize == tempsize * 2, "Expected no change for the needed buffer size\n"); 626 ok(strlen(displayname) == tempsize/2, 627 "Expected the buffer to be twice the length of the string\n") ; 628 629 /* Do the buffer(size) tests also for GetServiceDisplayNameW */ 630 SetLastError(0xdeadbeef); 631 displaysize = -1; 632 ret = GetServiceDisplayNameW(scm_handle, spoolerW, NULL, &displaysize); 633 ok(!ret, "Expected failure\n"); 634 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 635 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 636 637 /* Buffer is too small */ 638 SetLastError(0xdeadbeef); 639 tempsizeW = displaysize; 640 displaysize = tempsizeW / 2; 641 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize); 642 ok(!ret, "Expected failure\n"); 643 ok(displaysize == tempsizeW, "Expected the needed buffersize\n"); 644 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 645 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 646 647 /* Now with the original returned size */ 648 SetLastError(0xdeadbeef); 649 displaysize = tempsizeW; 650 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize); 651 ok(!ret, "Expected failure\n"); 652 ok(displaysize == tempsizeW, "Expected the needed buffersize\n"); 653 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 654 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 655 656 /* And with a bigger than needed buffer */ 657 SetLastError(0xdeadbeef); 658 displaysize = tempsizeW + 1; /* This caters for the null terminating character */ 659 ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize); 660 ok(ret, "Expected success, got error %u\n", GetLastError()); 661 ok(displaysize == tempsizeW, "Expected the needed buffersize\n"); 662 ok(lstrlenW(displaynameW) == displaysize, 663 "Expected the buffer to be the length of the string\n") ; 664 ok(tempsize / 2 == tempsizeW, 665 "Expected the needed buffersize (in bytes) to be the same for the A and W call\n"); 666 667 CloseServiceHandle(scm_handle); 668 669 /* Test for a service without a displayname (which is valid). This should return 670 * the servicename itself. 671 */ 672 SetLastError(0xdeadbeef); 673 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE); 674 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 675 { 676 skip("Not enough rights to get a handle to the manager\n"); 677 return; 678 } 679 680 SetLastError(0xdeadbeef); 681 svc_handle = CreateServiceA(scm_handle, servicename, NULL, DELETE, 682 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 683 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 684 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError()); 685 if (!svc_handle) 686 { 687 CloseServiceHandle(scm_handle); 688 return; 689 } 690 691 /* Retrieve the needed size for the buffer */ 692 SetLastError(0xdeadbeef); 693 displaysize = -1; 694 ret = GetServiceDisplayNameA(scm_handle, servicename, NULL, &displaysize); 695 ok(!ret, "Expected failure\n"); 696 ok(displaysize == strlen(servicename) * 2, 697 "Expected the displaysize to be twice the size of the servicename\n"); 698 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 699 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 700 701 /* Buffer is too small */ 702 SetLastError(0xdeadbeef); 703 tempsize = displaysize; 704 displaysize = (tempsize / 2); 705 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize); 706 ok(!ret, "Expected failure\n"); 707 ok(displaysize == tempsize, "Expected the needed buffersize\n"); 708 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 709 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 710 711 /* Get the displayname */ 712 SetLastError(0xdeadbeef); 713 ret = GetServiceDisplayNameA(scm_handle, servicename, displayname, &displaysize); 714 ok(ret, "Expected success, got error %u\n", GetLastError()); 715 ok(!lstrcmpiA(displayname, servicename), 716 "Expected displayname to be %s, got %s\n", servicename, displayname); 717 718 /* Delete the service */ 719 ret = DeleteService(svc_handle); 720 ok(ret, "Expected success (err=%d)\n", GetLastError()); 721 722 CloseServiceHandle(svc_handle); 723 CloseServiceHandle(scm_handle); 724 725 /* Wait a while. Just in case one of the following tests does a CreateService again */ 726 Sleep(1000); 727 } 728 729 static void test_get_servicekeyname(void) 730 { 731 SC_HANDLE scm_handle, svc_handle; 732 CHAR servicename[4096]; 733 CHAR displayname[4096]; 734 WCHAR servicenameW[4096]; 735 WCHAR displaynameW[4096]; 736 DWORD servicesize, displaysize, tempsize; 737 BOOL ret; 738 static const CHAR deadbeef[] = "Deadbeef"; 739 static const WCHAR deadbeefW[] = {'D','e','a','d','b','e','e','f',0}; 740 static const WCHAR abcW[] = {'A','B','C',0}; 741 742 /* Having NULL for the size of the buffer will crash on W2K3 */ 743 744 SetLastError(0xdeadbeef); 745 ret = GetServiceKeyNameA(NULL, NULL, NULL, &servicesize); 746 ok(!ret, "Expected failure\n"); 747 ok(GetLastError() == ERROR_INVALID_HANDLE, 748 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 749 750 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 751 752 servicesize = 200; 753 SetLastError(0xdeadbeef); 754 ret = GetServiceKeyNameA(scm_handle, NULL, NULL, &servicesize); 755 ok(!ret, "Expected failure\n"); 756 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || 757 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 758 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 759 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); 760 761 /* Valid handle and buffer but no displayname */ 762 servicesize = 200; 763 SetLastError(0xdeadbeef); 764 ret = GetServiceKeyNameA(scm_handle, NULL, servicename, &servicesize); 765 ok(!ret, "Expected failure\n"); 766 ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || 767 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 768 "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 769 todo_wine ok(servicesize == 200, "Service size expected 1, got %d\n", servicesize); 770 771 /* Test for nonexistent displayname */ 772 SetLastError(0xdeadbeef); 773 ret = GetServiceKeyNameA(scm_handle, deadbeef, NULL, &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 779 servicesize = 15; 780 strcpy(servicename, "ABC"); 781 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); 782 ok(!ret, "Expected failure\n"); 783 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 784 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 785 todo_wine ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize); 786 ok(servicename[0] == 0, "Service name not empty\n"); 787 788 servicesize = 15; 789 lstrcpyW( servicenameW, abcW ); 790 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); 791 ok(!ret, "Expected failure\n"); 792 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 793 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 794 ok(servicesize == 15, "Service size expected 15, got %d\n", servicesize); 795 ok(servicenameW[0] == 0, "Service name not empty\n"); 796 797 servicesize = 0; 798 strcpy(servicename, "ABC"); 799 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); 800 ok(!ret, "Expected failure\n"); 801 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 802 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 803 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); 804 ok(servicename[0] == 'A', "Service name changed\n"); 805 806 servicesize = 0; 807 lstrcpyW( servicenameW, abcW ); 808 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); 809 ok(!ret, "Expected failure\n"); 810 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); 811 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 812 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 813 ok(servicenameW[0] == 'A', "Service name changed\n"); 814 815 servicesize = 1; 816 strcpy(servicename, "ABC"); 817 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); 818 ok(!ret, "Expected failure\n"); 819 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 820 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 821 todo_wine ok(servicesize == 1, "Service size expected 1, got %d\n", servicesize); 822 ok(servicename[0] == 0, "Service name not empty\n"); 823 824 servicesize = 1; 825 lstrcpyW( servicenameW, abcW ); 826 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); 827 ok(!ret, "Expected failure\n"); 828 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); 829 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 830 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 831 ok(servicenameW[0] == 'A', "Service name changed\n"); 832 833 servicesize = 2; 834 strcpy(servicename, "ABC"); 835 ret = GetServiceKeyNameA(scm_handle, deadbeef, servicename, &servicesize); 836 ok(!ret, "Expected failure\n"); 837 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 838 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 839 todo_wine ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); 840 ok(servicename[0] == 0, "Service name not empty\n"); 841 842 servicesize = 2; 843 lstrcpyW( servicenameW, abcW ); 844 ret = GetServiceKeyNameW(scm_handle, deadbeefW, servicenameW, &servicesize); 845 ok(!ret, "Expected failure\n"); 846 ok(servicesize == 2, "Service size expected 2, got %d\n", servicesize); 847 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 848 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 849 ok(servicenameW[0] == 0, "Service name not empty\n"); 850 851 /* Check if 'Spooler' exists */ 852 svc_handle = OpenServiceA(scm_handle, spooler, GENERIC_READ); 853 if (!svc_handle) 854 { 855 skip("Spooler service doesn't exist\n"); 856 CloseServiceHandle(scm_handle); 857 return; 858 } 859 CloseServiceHandle(svc_handle); 860 861 /* Get the displayname for the 'Spooler' service */ 862 GetServiceDisplayNameA(scm_handle, spooler, NULL, &displaysize); 863 GetServiceDisplayNameA(scm_handle, spooler, displayname, &displaysize); 864 865 /* Retrieve the needed size for the buffer */ 866 SetLastError(0xdeadbeef); 867 servicesize = 0; 868 ret = GetServiceKeyNameA(scm_handle, displayname, NULL, &servicesize); 869 ok(!ret, "Expected failure\n"); 870 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 871 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 872 873 /* Valid call with the correct buffersize */ 874 SetLastError(0xdeadbeef); 875 tempsize = servicesize; 876 servicesize *= 2; 877 ret = GetServiceKeyNameA(scm_handle, displayname, servicename, &servicesize); 878 ok(ret, "Expected success, got error %u\n", GetLastError()); 879 if (ret) 880 { 881 ok(strlen(servicename) == tempsize/2, 882 "Expected the buffer to be twice the length of the string\n") ; 883 ok(!lstrcmpiA(servicename, spooler), "Expected %s, got %s\n", spooler, servicename); 884 ok(servicesize == (tempsize * 2), 885 "Expected servicesize not to change if buffer not insufficient\n") ; 886 } 887 888 MultiByteToWideChar(CP_ACP, 0, displayname, -1, displaynameW, sizeof(displaynameW)/2); 889 SetLastError(0xdeadbeef); 890 servicesize *= 2; 891 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize); 892 ok(ret, "Expected success, got error %u\n", GetLastError()); 893 if (ret) 894 { 895 ok(strlen(servicename) == tempsize/2, 896 "Expected the buffer to be twice the length of the string\n") ; 897 ok(servicesize == lstrlenW(servicenameW), 898 "Expected servicesize not to change if buffer not insufficient\n") ; 899 } 900 901 SetLastError(0xdeadbeef); 902 servicesize = 3; 903 ret = GetServiceKeyNameW(scm_handle, displaynameW, servicenameW, &servicesize); 904 ok(!ret, "Expected failure\n"); 905 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 906 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 907 ok(servicenameW[0] == 0, "Buffer not empty\n"); 908 909 CloseServiceHandle(scm_handle); 910 } 911 912 static void test_query_svc(void) 913 { 914 SC_HANDLE scm_handle, svc_handle; 915 BOOL ret; 916 SERVICE_STATUS status; 917 SERVICE_STATUS_PROCESS *statusproc; 918 DWORD bufsize, needed; 919 920 /* All NULL or wrong */ 921 SetLastError(0xdeadbeef); 922 ret = QueryServiceStatus(NULL, NULL); 923 ok(!ret, "Expected failure\n"); 924 ok(GetLastError() == ERROR_INVALID_HANDLE, 925 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 926 927 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 928 929 /* Check if 'Spooler' exists. 930 * Open with not enough rights to query the status. 931 */ 932 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ); 933 if (!svc_handle) 934 { 935 skip("Spooler service doesn't exist\n"); 936 CloseServiceHandle(scm_handle); 937 return; 938 } 939 940 SetLastError(0xdeadbeef); 941 ret = QueryServiceStatus(svc_handle, NULL); 942 ok(!ret, "Expected failure\n"); 943 ok(GetLastError() == ERROR_INVALID_ADDRESS || 944 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 945 "Unexpected last error %d\n", GetLastError()); 946 947 SetLastError(0xdeadbeef); 948 ret = QueryServiceStatus(svc_handle, &status); 949 ok(!ret, "Expected failure\n"); 950 ok(GetLastError() == ERROR_ACCESS_DENIED, 951 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 952 953 /* Open the service with just enough rights. 954 * (Verified with 'SERVICE_ALL_ACCESS &~ SERVICE_QUERY_STATUS') 955 */ 956 CloseServiceHandle(svc_handle); 957 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS); 958 959 SetLastError(0xdeadbeef); 960 ret = QueryServiceStatus(svc_handle, &status); 961 ok(ret, "Expected success, got error %u\n", GetLastError()); 962 963 CloseServiceHandle(svc_handle); 964 965 /* More or less the same tests for QueryServiceStatusEx */ 966 if (!pQueryServiceStatusEx) 967 { 968 win_skip( "QueryServiceStatusEx not available\n" ); 969 CloseServiceHandle(scm_handle); 970 return; 971 } 972 973 /* Open service with not enough rights to query the status */ 974 svc_handle = OpenServiceA(scm_handle, spooler, STANDARD_RIGHTS_READ); 975 976 /* All NULL or wrong, this proves that info level is checked first */ 977 SetLastError(0xdeadbeef); 978 ret = pQueryServiceStatusEx(NULL, 1, NULL, 0, NULL); 979 ok(!ret, "Expected failure\n"); 980 ok(GetLastError() == ERROR_INVALID_LEVEL, 981 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError()); 982 983 /* Passing a NULL parameter for the needed buffer size 984 * will crash on anything but NT4. 985 */ 986 987 /* Only info level is correct. It looks like the buffer/size is checked second */ 988 SetLastError(0xdeadbeef); 989 ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, NULL, 0, &needed); 990 /* NT4 checks the handle first */ 991 if (GetLastError() != ERROR_INVALID_HANDLE) 992 { 993 ok(!ret, "Expected failure\n"); 994 ok(needed == sizeof(SERVICE_STATUS_PROCESS), 995 "Needed buffersize is wrong : %d\n", needed); 996 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 997 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 998 } 999 1000 /* Pass a correct buffer and buffersize but a NULL handle */ 1001 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS)); 1002 bufsize = needed; 1003 SetLastError(0xdeadbeef); 1004 ret = pQueryServiceStatusEx(NULL, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed); 1005 ok(!ret, "Expected failure\n"); 1006 ok(GetLastError() == ERROR_INVALID_HANDLE, 1007 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 1008 HeapFree(GetProcessHeap(), 0, statusproc); 1009 1010 /* Correct handle and info level */ 1011 SetLastError(0xdeadbeef); 1012 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, NULL, 0, &needed); 1013 /* NT4 doesn't return the needed size */ 1014 if (GetLastError() != ERROR_INVALID_PARAMETER) 1015 { 1016 ok(!ret, "Expected failure\n"); 1017 ok(needed == sizeof(SERVICE_STATUS_PROCESS), 1018 "Needed buffersize is wrong : %d\n", needed); 1019 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 1020 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 1021 } 1022 1023 /* All parameters are OK but we don't have enough rights */ 1024 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS)); 1025 bufsize = sizeof(SERVICE_STATUS_PROCESS); 1026 SetLastError(0xdeadbeef); 1027 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed); 1028 ok(!ret, "Expected failure\n"); 1029 ok(GetLastError() == ERROR_ACCESS_DENIED, 1030 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1031 HeapFree(GetProcessHeap(), 0, statusproc); 1032 1033 /* Open the service with just enough rights. */ 1034 CloseServiceHandle(svc_handle); 1035 svc_handle = OpenServiceA(scm_handle, spooler, SERVICE_QUERY_STATUS); 1036 1037 /* Everything should be fine now. */ 1038 statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS)); 1039 bufsize = sizeof(SERVICE_STATUS_PROCESS); 1040 SetLastError(0xdeadbeef); 1041 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, &needed); 1042 ok(ret, "Expected success, got error %u\n", GetLastError()); 1043 if (statusproc->dwCurrentState == SERVICE_RUNNING) 1044 ok(statusproc->dwProcessId != 0, 1045 "Expect a process id for this running service\n"); 1046 else 1047 ok(statusproc->dwProcessId == 0, 1048 "Expect no process id for this stopped service\n"); 1049 1050 /* same call with null needed pointer */ 1051 SetLastError(0xdeadbeef); 1052 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)statusproc, bufsize, NULL); 1053 ok(!ret, "Expected failure\n"); 1054 ok(broken(GetLastError() == ERROR_INVALID_PARAMETER) /* NT4 */ || 1055 GetLastError() == ERROR_INVALID_ADDRESS, "got %d\n", GetLastError()); 1056 1057 HeapFree(GetProcessHeap(), 0, statusproc); 1058 1059 CloseServiceHandle(svc_handle); 1060 CloseServiceHandle(scm_handle); 1061 } 1062 1063 static void test_enum_svc(void) 1064 { 1065 SC_HANDLE scm_handle; 1066 BOOL ret; 1067 DWORD bufsize, needed, returned, resume; 1068 DWORD neededW, returnedW; 1069 DWORD tempneeded, tempreturned, missing; 1070 DWORD servicecountactive, servicecountinactive; 1071 ENUM_SERVICE_STATUSA *services; 1072 ENUM_SERVICE_STATUSW *servicesW; 1073 ENUM_SERVICE_STATUS_PROCESSA *exservices; 1074 UINT i; 1075 1076 /* All NULL or wrong */ 1077 SetLastError(0xdeadbeef); 1078 ret = EnumServicesStatusA(NULL, 1, 0, NULL, 0, NULL, NULL, NULL); 1079 ok(!ret, "Expected failure\n"); 1080 ok(GetLastError() == ERROR_INVALID_HANDLE, 1081 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 1082 1083 SetLastError(0xdeadbeef); 1084 ret = EnumServicesStatusW(NULL, 1, 0, NULL, 0, NULL, NULL, NULL); 1085 ok(!ret, "Expected failure\n"); 1086 ok(GetLastError() == ERROR_INVALID_HANDLE, 1087 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 1088 1089 /* Open the service control manager with not enough rights at first */ 1090 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 1091 1092 /* Valid handle but rest is still NULL or wrong */ 1093 SetLastError(0xdeadbeef); 1094 ret = EnumServicesStatusA(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL); 1095 ok(!ret, "Expected failure\n"); 1096 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1097 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1098 "Unexpected last error %d\n", GetLastError()); 1099 1100 SetLastError(0xdeadbeef); 1101 ret = EnumServicesStatusW(scm_handle, 1, 0, NULL, 0, NULL, NULL, NULL); 1102 ok(!ret, "Expected failure\n"); 1103 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1104 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1105 "Unexpected last error %d\n", GetLastError()); 1106 1107 /* Don't specify the two required pointers */ 1108 returned = 0xdeadbeef; 1109 SetLastError(0xdeadbeef); 1110 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL); 1111 ok(!ret, "Expected failure\n"); 1112 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n"); 1113 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1114 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1115 "Unexpected last error %d\n", GetLastError()); 1116 1117 returned = 0xdeadbeef; 1118 SetLastError(0xdeadbeef); 1119 ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, NULL, &returned, NULL); 1120 ok(!ret, "Expected failure\n"); 1121 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n"); 1122 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1123 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1124 "Unexpected last error %d\n", GetLastError()); 1125 1126 /* Don't specify the two required pointers */ 1127 needed = 0xdeadbeef; 1128 SetLastError(0xdeadbeef); 1129 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL); 1130 ok(!ret, "Expected failure\n"); 1131 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */ 1132 "Expected no change to the needed buffer variable\n"); 1133 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1134 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1135 "Unexpected last error %d\n", GetLastError()); 1136 1137 needed = 0xdeadbeef; 1138 SetLastError(0xdeadbeef); 1139 ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, NULL, NULL); 1140 ok(!ret, "Expected failure\n"); 1141 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */ 1142 "Expected no change to the needed buffer variable\n"); 1143 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1144 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1145 "Unexpected last error %d\n", GetLastError()); 1146 1147 /* No valid servicetype and servicestate */ 1148 needed = 0xdeadbeef; 1149 returned = 0xdeadbeef; 1150 SetLastError(0xdeadbeef); 1151 ret = EnumServicesStatusA(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL); 1152 ok(!ret, "Expected failure\n"); 1153 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1154 "Expected needed buffer size to be set to 0, got %d\n", needed); 1155 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); 1156 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1157 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1158 1159 needed = 0xdeadbeef; 1160 returned = 0xdeadbeef; 1161 SetLastError(0xdeadbeef); 1162 ret = EnumServicesStatusW(scm_handle, 0, 0, NULL, 0, &needed, &returned, NULL); 1163 ok(!ret, "Expected failure\n"); 1164 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1165 "Expected needed buffer size to be set to 0, got %d\n", needed); 1166 ok(returned == 0 || broken(returned != 0), /* nt4 */ 1167 "Expected number of services to be set to 0, got %d\n", returned); 1168 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1169 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1170 1171 /* No valid servicestate */ 1172 needed = 0xdeadbeef; 1173 returned = 0xdeadbeef; 1174 SetLastError(0xdeadbeef); 1175 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL); 1176 ok(!ret, "Expected failure\n"); 1177 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1178 "Expected needed buffer size to be set to 0, got %d\n", needed); 1179 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); 1180 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1181 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1182 1183 needed = 0xdeadbeef; 1184 returned = 0xdeadbeef; 1185 SetLastError(0xdeadbeef); 1186 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, 0, NULL, 0, &needed, &returned, NULL); 1187 ok(!ret, "Expected failure\n"); 1188 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1189 "Expected needed buffer size to be set to 0, got %d\n", needed); 1190 ok(returned == 0 || broken(returned != 0), /* nt4 */ 1191 "Expected number of services to be set to 0, got %d\n", returned); 1192 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1193 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1194 1195 /* No valid servicetype */ 1196 needed = 0xdeadbeef; 1197 returned = 0xdeadbeef; 1198 SetLastError(0xdeadbeef); 1199 ret = EnumServicesStatusA(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); 1200 ok(!ret, "Expected failure\n"); 1201 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1202 "Expected needed buffer size to be set to 0, got %d\n", needed); 1203 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); 1204 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1205 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1206 1207 needed = 0xdeadbeef; 1208 returned = 0xdeadbeef; 1209 SetLastError(0xdeadbeef); 1210 ret = EnumServicesStatusW(scm_handle, 0, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); 1211 ok(!ret, "Expected failure\n"); 1212 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1213 "Expected needed buffer size to be set to 0, got %d\n", needed); 1214 ok(returned == 0 || broken(returned != 0), /* nt4 */ 1215 "Expected number of services to be set to 0, got %d\n", returned); 1216 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1217 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1218 1219 /* All parameters are correct but our access rights are wrong */ 1220 needed = 0xdeadbeef; 1221 returned = 0xdeadbeef; 1222 SetLastError(0xdeadbeef); 1223 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); 1224 ok(!ret, "Expected failure\n"); 1225 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1226 "Expected needed buffer size to be set to 0, got %d\n", needed); 1227 ok(returned == 0, "Expected number of services to be set to 0, got %d\n", returned); 1228 ok(GetLastError() == ERROR_ACCESS_DENIED, 1229 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1230 1231 needed = 0xdeadbeef; 1232 returned = 0xdeadbeef; 1233 SetLastError(0xdeadbeef); 1234 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); 1235 ok(!ret, "Expected failure\n"); 1236 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1237 "Expected needed buffer size to be set to 0, got %d\n", needed); 1238 ok(returned == 0 || broken(returned != 0), /* nt4 */ 1239 "Expected number of services to be set to 0, got %d\n", returned); 1240 ok(GetLastError() == ERROR_ACCESS_DENIED, 1241 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1242 1243 /* Open the service control manager with the needed rights */ 1244 CloseServiceHandle(scm_handle); 1245 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); 1246 1247 /* All parameters are correct. Request the needed buffer size */ 1248 needed = 0xdeadbeef; 1249 returned = 0xdeadbeef; 1250 SetLastError(0xdeadbeef); 1251 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL); 1252 ok(!ret, "Expected failure\n"); 1253 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n"); 1254 ok(returned == 0, "Expected no service returned, got %d\n", returned); 1255 ok(GetLastError() == ERROR_MORE_DATA, 1256 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1257 1258 /* Test to show we get the same needed buffer size for the W-call */ 1259 neededW = 0xdeadbeef; 1260 returnedW = 0xdeadbeef; 1261 SetLastError(0xdeadbeef); 1262 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &neededW, &returnedW, NULL); 1263 ok(!ret, "Expected failure\n"); 1264 ok(neededW != 0xdeadbeef && neededW > 0, "Expected the needed buffer size for this one service\n"); 1265 ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); 1266 ok(returnedW == 0, "Expected no service returned, got %d\n", returnedW); 1267 ok(GetLastError() == ERROR_MORE_DATA, 1268 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1269 1270 /* Store the needed bytes */ 1271 tempneeded = needed; 1272 1273 /* Allocate the correct needed bytes */ 1274 services = HeapAlloc(GetProcessHeap(), 0, needed); 1275 bufsize = needed; 1276 needed = 0xdeadbeef; 1277 returned = 0xdeadbeef; 1278 SetLastError(0xdeadbeef); 1279 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, 1280 services, bufsize, &needed, &returned, NULL); 1281 ok(ret, "Expected success, got error %u\n", GetLastError()); 1282 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); 1283 ok(returned != 0xdeadbeef && returned > 0, "Expected some returned services\n"); 1284 HeapFree(GetProcessHeap(), 0, services); 1285 1286 /* Store the number of returned services */ 1287 tempreturned = returned; 1288 1289 servicesW = HeapAlloc(GetProcessHeap(), 0, neededW); 1290 bufsize = neededW; 1291 neededW = 0xdeadbeef; 1292 returnedW = 0xdeadbeef; 1293 SetLastError(0xdeadbeef); 1294 ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, 1295 servicesW, bufsize, &neededW, &returnedW, NULL); 1296 ok(ret, "Expected success, got error %u\n", GetLastError()); 1297 ok(neededW == 0, "Expected needed buffer to be 0 as we are done\n"); 1298 ok(returnedW != 0xdeadbeef && returnedW > 0, "Expected some returned services\n"); 1299 HeapFree(GetProcessHeap(), 0, servicesW); 1300 1301 /* Allocate less than the needed bytes and don't specify a resume handle */ 1302 services = HeapAlloc(GetProcessHeap(), 0, tempneeded); 1303 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); 1304 needed = 0xdeadbeef; 1305 returned = 0xdeadbeef; 1306 SetLastError(0xdeadbeef); 1307 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, 1308 services, bufsize, &needed, &returned, NULL); 1309 ok(!ret, "Expected failure\n"); 1310 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n"); 1311 ok(returned < tempreturned, "Expected fewer services to be returned\n"); 1312 ok(GetLastError() == ERROR_MORE_DATA, 1313 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1314 1315 /* Allocate less than the needed bytes, this time with a correct resume handle */ 1316 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); 1317 needed = 0xdeadbeef; 1318 returned = 0xdeadbeef; 1319 resume = 0; 1320 SetLastError(0xdeadbeef); 1321 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, 1322 services, bufsize, &needed, &returned, &resume); 1323 ok(!ret, "Expected failure\n"); 1324 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size for this one service\n"); 1325 ok(returned < tempreturned, "Expected fewer services to be returned\n"); 1326 todo_wine ok(resume, "Expected a resume handle\n"); 1327 ok(GetLastError() == ERROR_MORE_DATA, 1328 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1329 1330 /* Fetch the missing services but pass a bigger buffer size */ 1331 missing = tempreturned - returned; 1332 bufsize = tempneeded; 1333 needed = 0xdeadbeef; 1334 returned = 0xdeadbeef; 1335 SetLastError(0xdeadbeef); 1336 ret = EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, 1337 services, bufsize, &needed, &returned, &resume); 1338 ok(ret, "Expected success, got error %u\n", GetLastError()); 1339 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); 1340 ok(returned == missing, "Expected %u services to be returned\n", missing); 1341 ok(resume == 0, "Expected the resume handle to be 0\n"); 1342 HeapFree(GetProcessHeap(), 0, services); 1343 1344 /* See if things add up */ 1345 1346 /* Vista only shows the drivers with a state of SERVICE_RUNNING as active 1347 * and doesn't count the others as inactive. This means that Vista could 1348 * show a total that is greater than the sum of active and inactive 1349 * drivers. 1350 * The number of active and inactive drivers is greatly influenced by the 1351 * time when tests are run, immediately after boot or later for example. 1352 * 1353 * Both reasons make calculations for drivers not so useful 1354 */ 1355 1356 /* Get the number of active win32 services */ 1357 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, 1358 &needed, &returned, NULL); 1359 services = HeapAlloc(GetProcessHeap(), 0, needed); 1360 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_ACTIVE, services, 1361 needed, &needed, &returned, NULL); 1362 HeapFree(GetProcessHeap(), 0, services); 1363 1364 servicecountactive = returned; 1365 1366 /* Get the number of inactive win32 services */ 1367 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, NULL, 0, 1368 &needed, &returned, NULL); 1369 services = HeapAlloc(GetProcessHeap(), 0, needed); 1370 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_INACTIVE, services, 1371 needed, &needed, &returned, NULL); 1372 HeapFree(GetProcessHeap(), 0, services); 1373 1374 servicecountinactive = returned; 1375 1376 /* Get the number of win32 services */ 1377 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, 1378 &needed, &returned, NULL); 1379 services = HeapAlloc(GetProcessHeap(), 0, needed); 1380 EnumServicesStatusA(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, services, 1381 needed, &needed, &returned, NULL); 1382 HeapFree(GetProcessHeap(), 0, services); 1383 1384 /* Check if total is the same as active and inactive win32 services */ 1385 ok(returned == (servicecountactive + servicecountinactive), 1386 "Something wrong in the calculation\n"); 1387 1388 /* Get all drivers and services 1389 * 1390 * Fetch the status of the last call as failing could make the following tests crash 1391 * on Wine (we don't return anything yet). 1392 */ 1393 EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, 1394 NULL, 0, &needed, &returned, NULL); 1395 services = HeapAlloc(GetProcessHeap(), 0, needed); 1396 ret = EnumServicesStatusA(scm_handle, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, 1397 services, needed, &needed, &returned, NULL); 1398 1399 /* Loop through all those returned drivers and services */ 1400 for (i = 0; ret && i < returned; i++) 1401 { 1402 SERVICE_STATUS status = services[i].ServiceStatus; 1403 1404 /* lpServiceName and lpDisplayName should always be filled */ 1405 ok(services[i].lpServiceName[0], "Expected a service name\n"); 1406 ok(services[i].lpDisplayName && services[i].lpDisplayName[0], "Expected a display name\n"); 1407 1408 /* Decrement the counters to see if the functions calls return the same 1409 * numbers as the contents of these structures. 1410 */ 1411 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS)) 1412 { 1413 if (status.dwCurrentState == SERVICE_STOPPED) 1414 servicecountinactive--; 1415 else 1416 servicecountactive--; 1417 } 1418 } 1419 HeapFree(GetProcessHeap(), 0, services); 1420 1421 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive); 1422 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive); 1423 1424 CloseServiceHandle(scm_handle); 1425 1426 /* More or less the same for EnumServicesStatusExA */ 1427 if (!pEnumServicesStatusExA) 1428 { 1429 win_skip( "EnumServicesStatusExA not available\n" ); 1430 return; 1431 } 1432 1433 /* All NULL or wrong */ 1434 SetLastError(0xdeadbeef); 1435 ret = pEnumServicesStatusExA(NULL, 1, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); 1436 ok(!ret, "Expected failure\n"); 1437 ok(GetLastError() == ERROR_INVALID_LEVEL, 1438 "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError()); 1439 1440 /* All NULL or wrong, just the info level is correct */ 1441 SetLastError(0xdeadbeef); 1442 ret = pEnumServicesStatusExA(NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); 1443 ok(!ret, "Expected failure\n"); 1444 ok(GetLastError() == ERROR_INVALID_HANDLE, 1445 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 1446 1447 /* Open the service control manager with not enough rights at first */ 1448 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 1449 1450 /* Valid handle and info level but rest is still NULL or wrong */ 1451 SetLastError(0xdeadbeef); 1452 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL); 1453 ok(!ret, "Expected failure\n"); 1454 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1455 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1456 "Unexpected last error %d\n", GetLastError()); 1457 1458 /* Don't specify the two required pointers */ 1459 needed = 0xdeadbeef; 1460 SetLastError(0xdeadbeef); 1461 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, NULL, NULL, NULL); 1462 ok(!ret, "Expected failure\n"); 1463 ok(needed == 0xdeadbeef || broken(needed != 0xdeadbeef), /* nt4 */ 1464 "Expected no change to the needed buffer variable\n"); 1465 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1466 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1467 "Unexpected last error %d\n", GetLastError()); 1468 1469 /* Don't specify the two required pointers */ 1470 returned = 0xdeadbeef; 1471 SetLastError(0xdeadbeef); 1472 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, NULL, &returned, NULL, NULL); 1473 ok(!ret, "Expected failure\n"); 1474 ok(returned == 0xdeadbeef, "Expected no change to the number of services variable\n"); 1475 ok(GetLastError() == ERROR_INVALID_ADDRESS || 1476 GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, 1477 "Unexpected last error %d\n", GetLastError()); 1478 1479 /* No valid servicetype and servicestate */ 1480 needed = 0xdeadbeef; 1481 returned = 0xdeadbeef; 1482 SetLastError(0xdeadbeef); 1483 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, &returned, NULL, NULL); 1484 ok(!ret, "Expected failure\n"); 1485 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1486 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1487 "Expected needed buffer size to be set to 0, got %d\n", needed); 1488 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1489 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1490 1491 /* No valid servicestate */ 1492 needed = 0xdeadbeef; 1493 returned = 0xdeadbeef; 1494 SetLastError(0xdeadbeef); 1495 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, 0, NULL, 0, 1496 &needed, &returned, NULL, NULL); 1497 ok(!ret, "Expected failure\n"); 1498 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1499 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1500 "Expected needed buffer size to be set to 0, got %d\n", needed); 1501 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1502 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1503 1504 /* No valid servicetype */ 1505 needed = 0xdeadbeef; 1506 returned = 0xdeadbeef; 1507 SetLastError(0xdeadbeef); 1508 ret = pEnumServicesStatusExA(scm_handle, 0, 0, SERVICE_STATE_ALL, NULL, 0, 1509 &needed, &returned, NULL, NULL); 1510 ok(!ret, "Expected failure\n"); 1511 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1512 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1513 "Expected needed buffer size to be set to 0, got %d\n", needed); 1514 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1515 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1516 1517 /* No valid servicetype and servicestate and unknown service group */ 1518 needed = 0xdeadbeef; 1519 returned = 0xdeadbeef; 1520 SetLastError(0xdeadbeef); 1521 ret = pEnumServicesStatusExA(scm_handle, 0, 0, 0, NULL, 0, &needed, 1522 &returned, NULL, "deadbeef_group"); 1523 ok(!ret, "Expected failure\n"); 1524 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1525 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1526 "Expected needed buffer size to be set to 0, got %d\n", needed); 1527 ok(GetLastError() == ERROR_INVALID_PARAMETER, 1528 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1529 1530 /* All parameters are correct but our access rights are wrong */ 1531 needed = 0xdeadbeef; 1532 returned = 0xdeadbeef; 1533 SetLastError(0xdeadbeef); 1534 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1535 NULL, 0, &needed, &returned, NULL, NULL); 1536 ok(!ret, "Expected failure\n"); 1537 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1538 "Expected needed buffer size to be set to 0, got %d\n", needed); 1539 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1540 ok(GetLastError() == ERROR_ACCESS_DENIED, 1541 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1542 1543 /* All parameters are correct, access rights are wrong but the 1544 * group name won't be checked yet. 1545 */ 1546 needed = 0xdeadbeef; 1547 returned = 0xdeadbeef; 1548 SetLastError(0xdeadbeef); 1549 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1550 NULL, 0, &needed, &returned, NULL, "deadbeef_group"); 1551 ok(!ret, "Expected failure\n"); 1552 ok(needed == 0 || broken(needed != 0), /* nt4 */ 1553 "Expected needed buffer size to be set to 0, got %d\n", needed); 1554 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1555 ok(GetLastError() == ERROR_ACCESS_DENIED, 1556 "Expected ERROR_ACCESS_DENIED, got %d\n", GetLastError()); 1557 1558 /* Open the service control manager with the needed rights */ 1559 CloseServiceHandle(scm_handle); 1560 scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); 1561 1562 /* All parameters are correct and the group will be checked */ 1563 needed = 0xdeadbeef; 1564 returned = 0xdeadbeef; 1565 SetLastError(0xdeadbeef); 1566 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1567 NULL, 0, &needed, &returned, NULL, "deadbeef_group"); 1568 ok(!ret, "Expected failure\n"); 1569 ok(returned == 0, "Expected number of service to be set to 0, got %d\n", returned); 1570 ok(needed == 0, "Expected needed buffer size to be set to 0, got %d\n", needed); 1571 ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, 1572 "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError()); 1573 1574 /* TODO: Create a test that makes sure we enumerate all services that don't 1575 * belong to a group. (specifying ""). 1576 */ 1577 1578 /* All parameters are correct. Request the needed buffer size */ 1579 needed = 0xdeadbeef; 1580 returned = 0xdeadbeef; 1581 SetLastError(0xdeadbeef); 1582 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1583 NULL, 0, &needed, &returned, NULL, NULL); 1584 ok(!ret, "Expected failure\n"); 1585 ok(returned == 0, "Expected no service returned, got %d\n", returned); 1586 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); 1587 ok(GetLastError() == ERROR_MORE_DATA, 1588 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1589 1590 /* Test to show we get the same needed buffer size for the W-call */ 1591 neededW = 0xdeadbeef; 1592 ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1593 NULL, 0, &neededW, &returnedW, NULL, NULL); 1594 ok(!ret, "Expected failure\n"); 1595 ok(neededW == needed, "Expected needed buffersize to be the same for A- and W-calls\n"); 1596 1597 /* Store the needed bytes */ 1598 tempneeded = needed; 1599 1600 /* Allocate the correct needed bytes */ 1601 exservices = HeapAlloc(GetProcessHeap(), 0, needed); 1602 bufsize = needed; 1603 needed = 0xdeadbeef; 1604 returned = 0xdeadbeef; 1605 SetLastError(0xdeadbeef); 1606 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1607 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL); 1608 ok(ret, "Expected success, got error %u\n", GetLastError()); 1609 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); 1610 ok(returned == tempreturned, "Expected the same number of service from this function\n"); 1611 HeapFree(GetProcessHeap(), 0, exservices); 1612 1613 /* Store the number of returned services */ 1614 tempreturned = returned; 1615 1616 /* Allocate less than the needed bytes and don't specify a resume handle */ 1617 exservices = HeapAlloc(GetProcessHeap(), 0, tempneeded); 1618 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); 1619 needed = 0xdeadbeef; 1620 returned = 0xdeadbeef; 1621 SetLastError(0xdeadbeef); 1622 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1623 (BYTE*)exservices, bufsize, &needed, &returned, NULL, NULL); 1624 ok(!ret, "Expected failure\n"); 1625 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); 1626 ok(returned < tempreturned, "Expected fewer services to be returned\n"); 1627 ok(GetLastError() == ERROR_MORE_DATA, 1628 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1629 1630 /* Allocate less than the needed bytes, this time with a correct resume handle */ 1631 bufsize = (tempreturned - 1) * sizeof(ENUM_SERVICE_STATUSA); 1632 needed = 0xdeadbeef; 1633 returned = 0xdeadbeef; 1634 resume = 0; 1635 SetLastError(0xdeadbeef); 1636 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1637 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL); 1638 ok(!ret, "Expected failure\n"); 1639 ok(needed != 0xdeadbeef && needed > 0, "Expected the needed buffer size\n"); 1640 ok(returned < tempreturned, "Expected fewer services to be returned\n"); 1641 todo_wine ok(resume, "Expected a resume handle\n"); 1642 ok(GetLastError() == ERROR_MORE_DATA, 1643 "Expected ERROR_MORE_DATA, got %d\n", GetLastError()); 1644 1645 /* Fetch that last service but pass a bigger buffer size */ 1646 missing = tempreturned - returned; 1647 bufsize = tempneeded; 1648 needed = 0xdeadbeef; 1649 returned = 0xdeadbeef; 1650 SetLastError(0xdeadbeef); 1651 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1652 (BYTE*)exservices, bufsize, &needed, &returned, &resume, NULL); 1653 ok(ret, "Expected success, got error %u\n", GetLastError()); 1654 ok(needed == 0, "Expected needed buffer to be 0 as we are done\n"); 1655 ok(returned == missing, "Expected %u services to be returned\n", missing); 1656 ok(resume == 0, "Expected the resume handle to be 0\n"); 1657 HeapFree(GetProcessHeap(), 0, exservices); 1658 1659 /* See if things add up */ 1660 1661 /* Get the number of active win32 services */ 1662 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE, 1663 NULL, 0, &needed, &returned, NULL, NULL); 1664 exservices = HeapAlloc(GetProcessHeap(), 0, needed); 1665 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_ACTIVE, 1666 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); 1667 HeapFree(GetProcessHeap(), 0, exservices); 1668 1669 servicecountactive = returned; 1670 1671 /* Get the number of inactive win32 services */ 1672 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE, 1673 NULL, 0, &needed, &returned, NULL, NULL); 1674 exservices = HeapAlloc(GetProcessHeap(), 0, needed); 1675 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_INACTIVE, 1676 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); 1677 HeapFree(GetProcessHeap(), 0, exservices); 1678 1679 servicecountinactive = returned; 1680 1681 /* Get the number of win32 services */ 1682 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1683 NULL, 0, &needed, &returned, NULL, NULL); 1684 exservices = HeapAlloc(GetProcessHeap(), 0, needed); 1685 pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL, 1686 (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); 1687 HeapFree(GetProcessHeap(), 0, exservices); 1688 1689 /* Check if total is the same as active and inactive win32 services */ 1690 ok(returned == (servicecountactive + servicecountinactive), 1691 "Something wrong in the calculation\n"); 1692 1693 /* Get all drivers and services */ 1694 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER, 1695 SERVICE_STATE_ALL, NULL, 0, &needed, &returned, NULL, NULL); 1696 ok(!ret, "Expected failure\n"); 1697 exservices = HeapAlloc(GetProcessHeap(), 0, needed); 1698 ret = pEnumServicesStatusExA(scm_handle, 0, SERVICE_WIN32 | SERVICE_DRIVER, 1699 SERVICE_STATE_ALL, (BYTE*)exservices, needed, &needed, &returned, NULL, NULL); 1700 ok(ret, "Expected success %u\n", GetLastError()); 1701 1702 /* Loop through all those returned drivers and services */ 1703 for (i = 0; i < returned; i++) 1704 { 1705 SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess; 1706 1707 /* lpServiceName and lpDisplayName should always be filled */ 1708 ok(exservices[i].lpServiceName[0], "Expected a service name\n"); 1709 ok(exservices[i].lpDisplayName && exservices[i].lpDisplayName[0], "Expected a display name\n"); 1710 1711 /* Decrement the counters to see if the functions calls return the 1712 * same numbers as the contents of these structures. 1713 * Check some process id specifics. 1714 */ 1715 if (status.dwServiceType & (SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER)) 1716 { 1717 /* We shouldn't have a process id for drivers */ 1718 ok(status.dwProcessId == 0, 1719 "This driver shouldn't have an associated process id\n"); 1720 } 1721 1722 if (status.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS)) 1723 { 1724 if (status.dwCurrentState != SERVICE_STOPPED) 1725 { 1726 /* We expect a process id for every running service */ 1727 ok(status.dwProcessId > 0, "Expected a process id for this running service (%s)\n", 1728 exservices[i].lpServiceName); 1729 1730 servicecountactive--; 1731 } 1732 else 1733 { 1734 /* We shouldn't have a process id for inactive services */ 1735 ok(status.dwProcessId == 0, "Service %s state %u shouldn't have an associated process id\n", 1736 exservices[i].lpServiceName, status.dwCurrentState); 1737 1738 servicecountinactive--; 1739 } 1740 } 1741 } 1742 HeapFree(GetProcessHeap(), 0, exservices); 1743 1744 ok(servicecountactive == 0, "Active services mismatch %u\n", servicecountactive); 1745 ok(servicecountinactive == 0, "Inactive services mismatch %u\n", servicecountinactive); 1746 1747 CloseServiceHandle(scm_handle); 1748 } 1749 1750 static void test_close(void) 1751 { 1752 SC_HANDLE handle; 1753 BOOL ret; 1754 1755 /* NULL handle */ 1756 SetLastError(0xdeadbeef); 1757 ret = CloseServiceHandle(NULL); 1758 ok(!ret, "Expected failure\n"); 1759 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); 1760 1761 /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */ 1762 1763 /* Proper call */ 1764 handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); 1765 SetLastError(0xdeadbeef); 1766 ret = CloseServiceHandle(handle); 1767 ok(ret, "Expected success got error %u\n", GetLastError()); 1768 } 1769 1770 static void test_sequence(void) 1771 { 1772 SC_HANDLE scm_handle, svc_handle; 1773 BOOL ret, is_nt4; 1774 QUERY_SERVICE_CONFIGA *config; 1775 DWORD given, needed; 1776 static const CHAR servicename [] = "Winetest"; 1777 static const CHAR displayname [] = "Winetest dummy service"; 1778 static const CHAR displayname2[] = "Winetest dummy service (2)"; 1779 static const CHAR pathname [] = "we_dont_care.exe"; 1780 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0"; 1781 static const CHAR password [] = ""; 1782 static const CHAR empty [] = ""; 1783 static const CHAR localsystem [] = "LocalSystem"; 1784 1785 SetLastError(0xdeadbeef); 1786 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); 1787 1788 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 1789 { 1790 skip("Not enough rights to get a handle to the manager\n"); 1791 return; 1792 } 1793 else 1794 ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError()); 1795 1796 if (!scm_handle) return; 1797 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ); 1798 is_nt4=(svc_handle == NULL && GetLastError() == ERROR_INVALID_PARAMETER); 1799 CloseServiceHandle(svc_handle); 1800 1801 /* Create a dummy service */ 1802 SetLastError(0xdeadbeef); 1803 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL, 1804 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE, 1805 pathname, NULL, NULL, dependencies, NULL, password); 1806 1807 if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS)) 1808 { 1809 /* We try and open the service and do the rest of the tests. Some could 1810 * fail if the tests were changed between these runs. 1811 */ 1812 trace("Deletion probably didn't work last time\n"); 1813 SetLastError(0xdeadbeef); 1814 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL); 1815 if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 1816 { 1817 skip("Not enough rights to open the service\n"); 1818 CloseServiceHandle(scm_handle); 1819 return; 1820 } 1821 ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError()); 1822 } 1823 else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 1824 { 1825 skip("Not enough rights to create the service\n"); 1826 CloseServiceHandle(scm_handle); 1827 return; 1828 } 1829 else 1830 { 1831 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError()); 1832 if ((svc_handle != NULL) && (pGetSecurityInfo != NULL)) 1833 { 1834 PSID sidOwner, sidGroup; 1835 PACL dacl, sacl; 1836 PSECURITY_DESCRIPTOR pSD; 1837 DWORD error, n1, n2; 1838 HRESULT retval; 1839 BOOL bret; 1840 1841 /* Test using GetSecurityInfo to obtain security information */ 1842 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, &sidOwner, 1843 &sidGroup, &dacl, &sacl, &pSD); 1844 LocalFree(pSD); 1845 ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); 1846 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, 1847 NULL, NULL, NULL, &pSD); 1848 LocalFree(pSD); 1849 ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); 1850 if (!is_nt4) 1851 { 1852 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, 1853 NULL, &dacl, NULL, &pSD); 1854 ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); 1855 LocalFree(pSD); 1856 SetLastError(0xdeadbeef); 1857 retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, 1858 NULL, NULL, NULL, NULL); 1859 error = GetLastError(); 1860 ok(retval == ERROR_INVALID_PARAMETER, "Expected GetSecurityInfo to fail: result %d\n", retval); 1861 ok(error == 0xdeadbeef, "Unexpected last error %d\n", error); 1862 } 1863 else 1864 win_skip("A NULL security descriptor in GetSecurityInfo results in an exception on NT4.\n"); 1865 1866 /* Test using QueryServiceObjectSecurity to obtain security information */ 1867 SetLastError(0xdeadbeef); 1868 bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, NULL, 0, &n1); 1869 error = GetLastError(); 1870 ok(!bret, "Expected QueryServiceObjectSecurity to fail: result %d\n", bret); 1871 ok(error == ERROR_INSUFFICIENT_BUFFER || 1872 broken(error == ERROR_INVALID_ADDRESS) || broken(error == ERROR_INVALID_PARAMETER), 1873 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", error); 1874 if (error != ERROR_INSUFFICIENT_BUFFER) n1 = 1024; 1875 pSD = LocalAlloc(0, n1); 1876 bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, pSD, n1, &n2); 1877 ok(bret, "Expected QueryServiceObjectSecurity to succeed: result %d\n", bret); 1878 LocalFree(pSD); 1879 } 1880 } 1881 1882 if (!svc_handle) { 1883 CloseServiceHandle(scm_handle); 1884 return; 1885 } 1886 1887 /* TODO: 1888 * Before we do a QueryServiceConfig we should check the registry. This will make sure 1889 * that the correct keys are used. 1890 */ 1891 1892 /* Request the size for the buffer */ 1893 SetLastError(0xdeadbeef); 1894 ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed); 1895 ok(!ret, "Expected failure\n"); 1896 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 1897 1898 config = HeapAlloc(GetProcessHeap(), 0, needed); 1899 given = needed; 1900 SetLastError(0xdeadbeef); 1901 ret = QueryServiceConfigA(svc_handle, config, given, &needed); 1902 ok(ret, "Expected success, got error %u\n", GetLastError()); 1903 1904 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName && 1905 config->lpDisplayName, "Expected all string struct members to be non-NULL\n"); 1906 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS), 1907 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType); 1908 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType); 1909 ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl); 1910 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName); 1911 ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup); 1912 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId); 1913 /* TODO: Show the double 0 terminated string */ 1914 todo_wine 1915 { 1916 ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n"); 1917 } 1918 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName); 1919 ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName); 1920 1921 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_ERROR_NORMAL, NULL, "TestGroup2", 1922 NULL, NULL, NULL, NULL, displayname2); 1923 ok(ret, "ChangeServiceConfig failed (err=%d)\n", GetLastError()); 1924 1925 QueryServiceConfigA(svc_handle, NULL, 0, &needed); 1926 config = HeapReAlloc(GetProcessHeap(), 0, config, needed); 1927 ok(QueryServiceConfigA(svc_handle, config, needed, &needed), "QueryServiceConfig failed\n"); 1928 ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName && 1929 config->lpDisplayName, "Expected all string struct members to be non-NULL\n"); 1930 ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS), 1931 "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType); 1932 ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType); 1933 ok(config->dwErrorControl == SERVICE_ERROR_NORMAL, "Expected SERVICE_ERROR_NORMAL, got %d\n", config->dwErrorControl); 1934 ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName); 1935 ok(!strcmp(config->lpLoadOrderGroup, "TestGroup2"), "Expected 'TestGroup2', got '%s'\n", config->lpLoadOrderGroup); 1936 ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId); 1937 ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName); 1938 ok(!strcmp(config->lpDisplayName, displayname2), "Expected '%s', got '%s'\n", displayname2, config->lpDisplayName); 1939 1940 SetLastError(0xdeadbeef); 1941 ret = DeleteService(svc_handle); 1942 ok(ret, "Expected success, got error %u\n", GetLastError()); 1943 CloseServiceHandle(svc_handle); 1944 1945 /* Wait a while. The following test does a CreateService again */ 1946 Sleep(1000); 1947 1948 CloseServiceHandle(scm_handle); 1949 HeapFree(GetProcessHeap(), 0, config); 1950 } 1951 1952 static void test_queryconfig2(void) 1953 { 1954 SC_HANDLE scm_handle, svc_handle; 1955 BOOL ret; 1956 DWORD expected, needed; 1957 BYTE buffer[MAX_PATH]; 1958 LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer; 1959 LPSERVICE_DESCRIPTIONW pConfigW = (LPSERVICE_DESCRIPTIONW)buffer; 1960 SERVICE_PRESHUTDOWN_INFO preshutdown_info; 1961 static const CHAR servicename [] = "Winetest"; 1962 static const CHAR displayname [] = "Winetest dummy service"; 1963 static const CHAR pathname [] = "we_dont_care.exe"; 1964 static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0"; 1965 static const CHAR password [] = ""; 1966 static const CHAR description [] = "Description"; 1967 static const CHAR description_empty[] = ""; 1968 static const WCHAR descriptionW [] = {'D','e','s','c','r','i','p','t','i','o','n','W',0}; 1969 static const WCHAR descriptionW_empty[] = {0}; 1970 1971 if(!pQueryServiceConfig2A) 1972 { 1973 win_skip("function QueryServiceConfig2A not present\n"); 1974 return; 1975 } 1976 1977 SetLastError(0xdeadbeef); 1978 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); 1979 1980 if (!scm_handle) 1981 { 1982 if(GetLastError() == ERROR_ACCESS_DENIED) 1983 skip("Not enough rights to get a handle to the manager\n"); 1984 else 1985 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError()); 1986 return; 1987 } 1988 1989 /* Create a dummy service */ 1990 SetLastError(0xdeadbeef); 1991 svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL, 1992 SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE, 1993 pathname, NULL, NULL, dependencies, NULL, password); 1994 1995 if (!svc_handle) 1996 { 1997 if(GetLastError() == ERROR_SERVICE_EXISTS) 1998 { 1999 /* We try and open the service and do the rest of the tests. Some could 2000 * fail if the tests were changed between these runs. 2001 */ 2002 trace("Deletion probably didn't work last time\n"); 2003 SetLastError(0xdeadbeef); 2004 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL); 2005 if (!svc_handle) 2006 { 2007 if(GetLastError() == ERROR_ACCESS_DENIED) 2008 skip("Not enough rights to open the service\n"); 2009 else 2010 ok(FALSE, "Could not open the service : %d\n", GetLastError()); 2011 CloseServiceHandle(scm_handle); 2012 return; 2013 } 2014 } 2015 if (GetLastError() == ERROR_ACCESS_DENIED) 2016 { 2017 skip("Not enough rights to create the service\n"); 2018 CloseServiceHandle(scm_handle); 2019 return; 2020 } 2021 ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError()); 2022 if (!svc_handle) 2023 { 2024 CloseServiceHandle(scm_handle); 2025 return; 2026 } 2027 } 2028 SetLastError(0xdeadbeef); 2029 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed); 2030 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2031 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError()); 2032 2033 SetLastError(0xdeadbeef); 2034 ret = pQueryServiceConfig2A(svc_handle,0xfff0,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL); 2035 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2036 ok(ERROR_INVALID_LEVEL == GetLastError(), "expected error ERROR_INVALID_LEVEL, got %d\n", GetLastError()); 2037 2038 SetLastError(0xdeadbeef); 2039 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),NULL); 2040 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2041 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError()); 2042 2043 SetLastError(0xdeadbeef); 2044 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),&needed); 2045 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2046 ok((ERROR_INVALID_ADDRESS == GetLastError()) || (ERROR_INSUFFICIENT_BUFFER == GetLastError()), 2047 "expected error ERROR_INVALID_ADDRESS or ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2048 2049 SetLastError(0xdeadbeef); 2050 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,sizeof(SERVICE_DESCRIPTIONA),NULL); 2051 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2052 ok(ERROR_INVALID_ADDRESS == GetLastError(), "expected error ERROR_INVALID_ADDRESS, got %d\n", GetLastError()); 2053 2054 needed = 0; 2055 SetLastError(0xdeadbeef); 2056 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA)-1,&needed); 2057 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2058 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2059 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed); 2060 2061 needed = 0; 2062 pConfig->lpDescription = (LPSTR)0xdeadbeef; 2063 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed); 2064 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2065 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed); 2066 ok(!pConfig->lpDescription, "expected lpDescription to be NULL, got %p\n", pConfig->lpDescription); 2067 2068 SetLastError(0xdeadbeef); 2069 needed = 0; 2070 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed); 2071 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2072 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2073 ok(needed == sizeof(SERVICE_DESCRIPTIONA), "got %d\n", needed); 2074 2075 if(!pChangeServiceConfig2A) 2076 { 2077 win_skip("function ChangeServiceConfig2A not present\n"); 2078 goto cleanup; 2079 } 2080 2081 pConfig->lpDescription = (LPSTR) description; 2082 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer); 2083 ok(ret, "ChangeServiceConfig2A failed\n"); 2084 if (!ret) { 2085 goto cleanup; 2086 } 2087 2088 SetLastError(0xdeadbeef); 2089 needed = 0; 2090 expected = sizeof(SERVICE_DESCRIPTIONA) + sizeof(description) * sizeof(WCHAR); /* !! */ 2091 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,sizeof(SERVICE_DESCRIPTIONA),&needed); 2092 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2093 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2094 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed); 2095 2096 SetLastError(0xdeadbeef); 2097 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed-1,&needed); 2098 ok(!ret, "expected QueryServiceConfig2A to fail\n"); 2099 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2100 2101 SetLastError(0xdeadbeef); 2102 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer,needed,&needed); 2103 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2104 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription), 2105 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription); 2106 2107 SetLastError(0xdeadbeef); 2108 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed + 1,&needed); 2109 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2110 ok(pConfig->lpDescription && !strcmp(description,pConfig->lpDescription), 2111 "expected lpDescription to be %s, got %s\n",description ,pConfig->lpDescription); 2112 2113 if(!pQueryServiceConfig2W) 2114 { 2115 win_skip("function QueryServiceConfig2W not present\n"); 2116 goto cleanup; 2117 } 2118 SetLastError(0xdeadbeef); 2119 needed = 0; 2120 expected = sizeof(SERVICE_DESCRIPTIONW) + sizeof(WCHAR) * sizeof(description); 2121 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,NULL,0,&needed); 2122 ok(!ret, "expected QueryServiceConfig2W to fail\n"); 2123 ok(ERROR_INSUFFICIENT_BUFFER == GetLastError(), "expected error ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); 2124 ok(needed == expected, "expected needed to be %d, got %d\n", expected, needed); 2125 2126 SetLastError(0xdeadbeef); 2127 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed); 2128 ok(ret, "expected QueryServiceConfig2W to succeed\n"); 2129 2130 pConfig->lpDescription = (LPSTR)description; 2131 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); 2132 ok(ret, "expected ChangeServiceConfig2A to succeed\n"); 2133 2134 pConfig->lpDescription = NULL; 2135 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); 2136 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2137 ok(pConfig->lpDescription && !strcmp(description, pConfig->lpDescription), 2138 "expected lpDescription to be %s, got %s\n", description, pConfig->lpDescription); 2139 2140 pConfig->lpDescription = NULL; 2141 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); 2142 ok(ret, "expected ChangeServiceConfig2A to succeed\n"); 2143 2144 pConfig->lpDescription = NULL; 2145 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); 2146 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2147 ok(pConfig->lpDescription && !strcmp(description, pConfig->lpDescription), 2148 "expected lpDescription to be %s, got %s\n", description, pConfig->lpDescription); 2149 2150 pConfig->lpDescription = (LPSTR)description_empty; 2151 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); 2152 ok(ret, "expected ChangeServiceConfig2A to succeed\n"); 2153 2154 pConfig->lpDescription = (void*)0xdeadbeef; 2155 ret = pQueryServiceConfig2A(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); 2156 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2157 ok(!pConfig->lpDescription, 2158 "expected lpDescription to be null, got %s\n", pConfig->lpDescription); 2159 2160 pConfigW->lpDescription = (LPWSTR)descriptionW; 2161 ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); 2162 ok(ret, "expected ChangeServiceConfig2W to succeed\n"); 2163 2164 pConfigW->lpDescription = NULL; 2165 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); 2166 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2167 ok(pConfigW->lpDescription && !lstrcmpW(descriptionW, pConfigW->lpDescription), 2168 "expected lpDescription to be %s, got %s\n", wine_dbgstr_w(descriptionW), wine_dbgstr_w(pConfigW->lpDescription)); 2169 2170 pConfigW->lpDescription = NULL; 2171 ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); 2172 ok(ret, "expected ChangeServiceConfig2W to succeed\n"); 2173 2174 pConfigW->lpDescription = NULL; 2175 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); 2176 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2177 ok(pConfigW->lpDescription && !lstrcmpW(descriptionW, pConfigW->lpDescription), 2178 "expected lpDescription to be %s, got %s\n", wine_dbgstr_w(descriptionW), wine_dbgstr_w(pConfigW->lpDescription)); 2179 2180 pConfigW->lpDescription = (LPWSTR)descriptionW_empty; 2181 ret = pChangeServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, &buffer); 2182 ok(ret, "expected ChangeServiceConfig2W to succeed\n"); 2183 2184 pConfigW->lpDescription = (void*)0xdeadbeef; 2185 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION, buffer, sizeof(buffer), &needed); 2186 ok(ret, "expected QueryServiceConfig2A to succeed\n"); 2187 ok(!pConfigW->lpDescription, 2188 "expected lpDescription to be null, got %s\n", wine_dbgstr_w(pConfigW->lpDescription)); 2189 2190 SetLastError(0xdeadbeef); 2191 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, 2192 (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed); 2193 if(!ret && GetLastError()==ERROR_INVALID_LEVEL) 2194 { 2195 /* Win2k3 and older */ 2196 win_skip("SERVICE_CONFIG_PRESHUTDOWN_INFO not supported\n"); 2197 goto cleanup; 2198 } 2199 ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError()); 2200 ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed); 2201 ok(preshutdown_info.dwPreshutdownTimeout == 180000, "Default PreshutdownTimeout = %d\n", 2202 preshutdown_info.dwPreshutdownTimeout); 2203 2204 SetLastError(0xdeadbeef); 2205 preshutdown_info.dwPreshutdownTimeout = -1; 2206 ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, 2207 (LPVOID)&preshutdown_info); 2208 ok(ret, "expected ChangeServiceConfig2A to succeed (%d)\n", GetLastError()); 2209 2210 ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO, 2211 (LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed); 2212 ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError()); 2213 ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed); 2214 ok(preshutdown_info.dwPreshutdownTimeout == -1, "New PreshutdownTimeout = %d\n", 2215 preshutdown_info.dwPreshutdownTimeout); 2216 2217 cleanup: 2218 DeleteService(svc_handle); 2219 2220 CloseServiceHandle(svc_handle); 2221 2222 /* Wait a while. The following test does a CreateService again */ 2223 Sleep(1000); 2224 2225 CloseServiceHandle(scm_handle); 2226 } 2227 2228 static DWORD try_start_stop(SC_HANDLE svc_handle, const char* name, DWORD is_nt4) 2229 { 2230 BOOL ret; 2231 DWORD le1, le2; 2232 SERVICE_STATUS status; 2233 2234 #ifdef __REACTOS__ 2235 fprintf(stdout, "ROSTESTS-56: Hello sysreg, I am awake\n"); 2236 #endif 2237 ret = StartServiceA(svc_handle, 0, NULL); 2238 le1 = GetLastError(); 2239 ok(!ret, "%s: StartServiceA() should have failed\n", name); 2240 2241 if (pQueryServiceStatusEx) 2242 { 2243 DWORD needed; 2244 SERVICE_STATUS_PROCESS statusproc; 2245 2246 ret = pQueryServiceStatusEx(svc_handle, SC_STATUS_PROCESS_INFO, (BYTE*)&statusproc, sizeof(statusproc), &needed); 2247 ok(ret, "%s: QueryServiceStatusEx() failed le=%u\n", name, GetLastError()); 2248 ok(statusproc.dwCurrentState == SERVICE_STOPPED, "%s: should be stopped state=%x\n", name, statusproc.dwCurrentState); 2249 ok(statusproc.dwProcessId == 0, "%s: ProcessId should be 0 instead of %x\n", name, statusproc.dwProcessId); 2250 } 2251 2252 ret = StartServiceA(svc_handle, 0, NULL); 2253 le2 = GetLastError(); 2254 ok(!ret, "%s: StartServiceA() should have failed\n", name); 2255 ok(le2 == le1, "%s: the second try should yield the same error: %u != %u\n", name, le1, le2); 2256 2257 status.dwCurrentState = 0xdeadbeef; 2258 ret = ControlService(svc_handle, SERVICE_CONTROL_STOP, &status); 2259 le2 = GetLastError(); 2260 ok(!ret, "%s: ControlService() should have failed\n", name); 2261 ok(le2 == ERROR_SERVICE_NOT_ACTIVE, "%s: %d != ERROR_SERVICE_NOT_ACTIVE\n", name, le2); 2262 ok(status.dwCurrentState == SERVICE_STOPPED || 2263 broken(is_nt4), /* NT4 returns a random value */ 2264 "%s: should be stopped state=%x\n", name, status.dwCurrentState); 2265 2266 return le1; 2267 } 2268 2269 #define PHASE_STOPPED 1 2270 #define PHASE_RUNNING 2 2271 2272 struct notify_data { 2273 SERVICE_NOTIFYW notify; 2274 SC_HANDLE svc; 2275 BOOL was_called; 2276 DWORD phase; 2277 }; 2278 2279 static void CALLBACK notify_cb(void *user) 2280 { 2281 struct notify_data *data = user; 2282 switch (data->phase) 2283 { 2284 case PHASE_STOPPED: 2285 ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, 2286 "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); 2287 ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_STOPPED, 2288 "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); 2289 ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_STOPPED, 2290 "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); 2291 break; 2292 2293 case PHASE_RUNNING: 2294 ok(data->notify.dwNotificationStatus == ERROR_SUCCESS, 2295 "Got wrong notification status: %u\n", data->notify.dwNotificationStatus); 2296 ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_RUNNING, 2297 "Got wrong service state: 0x%x\n", data->notify.ServiceStatus.dwCurrentState); 2298 ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_RUNNING, 2299 "Got wrong notification triggered: 0x%x\n", data->notify.dwNotificationTriggered); 2300 break; 2301 } 2302 2303 data->was_called = TRUE; 2304 } 2305 2306 static void test_servicenotify(SC_HANDLE scm_handle, const char *servicename) 2307 { 2308 DWORD dr, dr2; 2309 struct notify_data data; 2310 struct notify_data data2; 2311 BOOL br; 2312 SERVICE_STATUS status; 2313 HANDLE svc, svc2; 2314 2315 if(!pNotifyServiceStatusChangeW){ 2316 win_skip("No NotifyServiceStatusChangeW\n"); 2317 return; 2318 } 2319 2320 svc = OpenServiceA(scm_handle, servicename, GENERIC_ALL); 2321 svc2 = OpenServiceA(scm_handle, servicename, GENERIC_ALL); 2322 ok(svc != NULL && svc2 != NULL, "Failed to open service\n"); 2323 if(!svc || !svc2) 2324 return; 2325 2326 /* receive stopped notification, then start service */ 2327 memset(&data.notify, 0, sizeof(data.notify)); 2328 data.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; 2329 data.notify.pfnNotifyCallback = ¬ify_cb; 2330 data.notify.pContext = &data; 2331 data.svc = svc; 2332 data.phase = PHASE_STOPPED; 2333 data.was_called = FALSE; 2334 2335 dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); 2336 ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); 2337 2338 dr = SleepEx(100, TRUE); 2339 ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); 2340 ok(data.was_called == TRUE, "APC wasn't called\n"); 2341 2342 br = StartServiceA(svc, 0, NULL); 2343 ok(br, "StartService failed: %u\n", GetLastError()); 2344 2345 /* receive running notification */ 2346 data.phase = PHASE_RUNNING; 2347 data.was_called = FALSE; 2348 2349 dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); 2350 ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); 2351 2352 dr = SleepEx(100, TRUE); 2353 ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); 2354 ok(data.was_called == TRUE, "APC wasn't called\n"); 2355 2356 /* cannot register two notifications */ 2357 data.phase = PHASE_STOPPED; 2358 data.was_called = FALSE; 2359 2360 dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); 2361 ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); 2362 2363 memset(&data2.notify, 0, sizeof(data2.notify)); 2364 data2.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; 2365 data2.notify.pfnNotifyCallback = ¬ify_cb; 2366 data2.notify.pContext = &data2; 2367 2368 dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data2.notify); 2369 ok(dr == ERROR_SUCCESS || /* win8+ */ 2370 dr == ERROR_ALREADY_REGISTERED, "NotifyServiceStatusChangeW gave wrong result: %u\n", dr); 2371 2372 /* should receive no notification because status has not changed. 2373 * on win8+, SleepEx quits early but the callback is still not invoked. */ 2374 dr2 = SleepEx(100, TRUE); 2375 ok((dr == ERROR_SUCCESS && dr2 == WAIT_IO_COMPLETION) || /* win8+ */ 2376 (dr == ERROR_ALREADY_REGISTERED && dr2 == 0), "Got wrong SleepEx result: %u\n", dr); 2377 ok(data.was_called == FALSE, "APC should not have been called\n"); 2378 2379 /* stop service and receive notifiction */ 2380 br = ControlService(svc, SERVICE_CONTROL_STOP, &status); 2381 ok(br, "ControlService failed: %u\n", GetLastError()); 2382 2383 dr = SleepEx(100, TRUE); 2384 ok(dr == WAIT_IO_COMPLETION, "Got wrong SleepEx result: %u\n", dr); 2385 ok(data.was_called == TRUE, "APC wasn't called\n"); 2386 2387 /* test cancelation: create notify on svc that will block until service 2388 * start; close svc; start service on svc2; verify that notification does 2389 * not happen */ 2390 2391 data.phase = PHASE_RUNNING; 2392 data.was_called = FALSE; 2393 dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED | SERVICE_NOTIFY_RUNNING, &data.notify); 2394 ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr); 2395 2396 CloseServiceHandle(svc); 2397 2398 br = StartServiceA(svc2, 0, NULL); 2399 ok(br, "StartService failed: %u\n", GetLastError()); 2400 2401 dr = SleepEx(100, TRUE); 2402 ok(dr == 0, "Got wrong SleepEx result: %u\n", dr); 2403 ok(data.was_called == FALSE, "APC should not have been called\n"); 2404 2405 br = ControlService(svc2, SERVICE_CONTROL_STOP, &status); 2406 ok(br, "ControlService failed: %u\n", GetLastError()); 2407 2408 CloseServiceHandle(svc2); 2409 } 2410 2411 static void test_start_stop(void) 2412 { 2413 BOOL ret; 2414 SC_HANDLE scm_handle, svc_handle; 2415 DWORD le, is_nt4; 2416 static const char servicename[] = "Winetest"; 2417 char cmd[MAX_PATH+20]; 2418 const char* displayname; 2419 2420 SetLastError(0xdeadbeef); 2421 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); 2422 if (!scm_handle) 2423 { 2424 if(GetLastError() == ERROR_ACCESS_DENIED) 2425 skip("Not enough rights to get a handle to the manager\n"); 2426 else 2427 ok(FALSE, "Could not get a handle to the manager: %d\n", GetLastError()); 2428 return; 2429 } 2430 2431 /* Detect NT4 */ 2432 svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ); 2433 is_nt4=(svc_handle == NULL && GetLastError() == ERROR_INVALID_PARAMETER); 2434 2435 /* Do some cleanup in case a previous run crashed */ 2436 svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL); 2437 if (svc_handle) 2438 { 2439 DeleteService(svc_handle); 2440 CloseServiceHandle(svc_handle); 2441 } 2442 2443 /* Create a dummy disabled service */ 2444 sprintf(cmd, "\"%s\" service exit", selfname); 2445 displayname = "Winetest Disabled Service"; 2446 svc_handle = CreateServiceA(scm_handle, servicename, displayname, 2447 GENERIC_ALL, SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, 2448 SERVICE_DISABLED, SERVICE_ERROR_IGNORE, cmd, NULL, 2449 NULL, NULL, NULL, NULL); 2450 if (!svc_handle) 2451 { 2452 if(GetLastError() == ERROR_ACCESS_DENIED) 2453 skip("Not enough rights to create the service\n"); 2454 else 2455 ok(FALSE, "Could not create the service: %d\n", GetLastError()); 2456 goto cleanup; 2457 } 2458 le = try_start_stop(svc_handle, displayname, is_nt4); 2459 ok(le == ERROR_SERVICE_DISABLED, "%d != ERROR_SERVICE_DISABLED\n", le); 2460 2461 /* Then one with a bad path */ 2462 displayname = "Winetest Bad Path"; 2463 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, "c:\\no_such_file.exe", NULL, NULL, NULL, NULL, NULL, displayname); 2464 ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError()); 2465 try_start_stop(svc_handle, displayname, is_nt4); 2466 2467 if (is_nt4) 2468 { 2469 /* NT4 does not detect when a service fails to start and uses an 2470 * insanely long timeout: 120s. So skip the rest of the tests. 2471 */ 2472 win_skip("Skip some service start/stop tests on NT4\n"); 2473 goto cleanup; 2474 } 2475 2476 if (!winetest_interactive) 2477 { 2478 skip("ROSTESTS-151: Skipping service start timeout tests because they take too long. This is not a bug!\n"); 2479 goto cleanup; 2480 } 2481 2482 /* Again with a process that exits right away */ 2483 displayname = "Winetest Exit Service"; 2484 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname); 2485 ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError()); 2486 le = try_start_stop(svc_handle, displayname, is_nt4); 2487 ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d != ERROR_SERVICE_REQUEST_TIMEOUT\n", le); 2488 2489 /* create a real service and test notifications */ 2490 sprintf(cmd, "%s service serve", selfname); 2491 displayname = "Winetest Service"; 2492 ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname); 2493 ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError()); 2494 test_servicenotify(scm_handle, servicename); 2495 2496 cleanup: 2497 if (svc_handle) 2498 { 2499 DeleteService(svc_handle); 2500 CloseServiceHandle(svc_handle); 2501 } 2502 2503 /* Wait a while. The following test does a CreateService again */ 2504 Sleep(1000); 2505 2506 CloseServiceHandle(scm_handle); 2507 } 2508 2509 static void test_refcount(void) 2510 { 2511 SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5; 2512 static const CHAR servicename [] = "Winetest"; 2513 static const CHAR pathname [] = "we_dont_care.exe"; 2514 BOOL ret; 2515 2516 /* Get a handle to the Service Control Manager */ 2517 SetLastError(0xdeadbeef); 2518 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); 2519 if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED)) 2520 { 2521 skip("Not enough rights to get a handle to the manager\n"); 2522 return; 2523 } 2524 2525 /* Create a service */ 2526 svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, 2527 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 2528 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 2529 ok(svc_handle1 != NULL, "Expected success, got error %u\n", GetLastError()); 2530 2531 /* Get a handle to this new service */ 2532 svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ); 2533 ok(svc_handle2 != NULL, "Expected success, got error %u\n", GetLastError()); 2534 2535 /* Get another handle to this new service */ 2536 svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ); 2537 ok(svc_handle3 != NULL, "Expected success, got error %u\n", GetLastError()); 2538 2539 /* Check if we can close the handle to the Service Control Manager */ 2540 ret = CloseServiceHandle(scm_handle); 2541 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2542 2543 /* Get a new handle to the Service Control Manager */ 2544 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); 2545 ok(scm_handle != NULL, "Expected success, got error %u\n", GetLastError()); 2546 2547 /* Get a handle to this new service */ 2548 svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL); 2549 ok(svc_handle4 != NULL, "Expected success, got error %u\n", GetLastError()); 2550 2551 /* Delete the service */ 2552 ret = DeleteService(svc_handle4); 2553 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2554 2555 /* We cannot create the same service again as it's still marked as 'being deleted'. 2556 * The reason is that we still have 4 open handles to this service even though we 2557 * closed the handle to the Service Control Manager in between. 2558 */ 2559 SetLastError(0xdeadbeef); 2560 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, 2561 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 2562 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 2563 ok(!svc_handle5, "Expected failure\n"); 2564 ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE, 2565 "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError()); 2566 2567 /* Close all the handles to the service and try again */ 2568 ret = CloseServiceHandle(svc_handle4); 2569 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2570 ret = CloseServiceHandle(svc_handle3); 2571 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2572 ret = CloseServiceHandle(svc_handle2); 2573 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2574 ret = CloseServiceHandle(svc_handle1); 2575 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2576 2577 /* Wait a while. Doing a CreateService too soon will result again 2578 * in an ERROR_SERVICE_MARKED_FOR_DELETE error. 2579 */ 2580 Sleep(1000); 2581 2582 /* We succeed now as all handles are closed (tested this also with a long SLeep() */ 2583 svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, 2584 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, 2585 SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); 2586 ok(svc_handle5 != NULL, "Expected success, got error %u\n", GetLastError()); 2587 2588 /* Delete the service */ 2589 ret = DeleteService(svc_handle5); 2590 ok(ret, "Expected success (err=%d)\n", GetLastError()); 2591 2592 /* Wait a while. Just in case one of the following tests does a CreateService again */ 2593 Sleep(1000); 2594 2595 CloseServiceHandle(svc_handle5); 2596 CloseServiceHandle(scm_handle); 2597 } 2598 2599 static DWORD WINAPI ctrl_handler(DWORD ctl, DWORD type, void *data, void *user) 2600 { 2601 HANDLE evt = user; 2602 2603 switch(ctl){ 2604 case SERVICE_CONTROL_STOP: 2605 SetEvent(evt); 2606 break; 2607 case SERVICE_CONTROL_INTERROGATE: 2608 return NO_ERROR; 2609 } 2610 2611 return ERROR_CALL_NOT_IMPLEMENTED; 2612 } 2613 2614 static void WINAPI service_main(DWORD argc, char **argv) 2615 { 2616 SERVICE_STATUS_HANDLE st_handle; 2617 SERVICE_STATUS st; 2618 HANDLE evt = CreateEventW(0, FALSE, FALSE, 0); 2619 2620 st_handle = RegisterServiceCtrlHandlerExA("", &ctrl_handler, evt); 2621 2622 st.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 2623 st.dwServiceSpecificExitCode = 0; 2624 st.dwCurrentState = SERVICE_RUNNING; 2625 st.dwWin32ExitCode = NO_ERROR; 2626 st.dwWaitHint = 0; 2627 st.dwControlsAccepted = SERVICE_ACCEPT_STOP; 2628 st.dwCheckPoint = 0; 2629 2630 SetServiceStatus(st_handle, &st); 2631 2632 WaitForSingleObject(evt, 5000); 2633 2634 st.dwCurrentState = SERVICE_STOPPED; 2635 2636 SetServiceStatus(st_handle, &st); 2637 } 2638 2639 static void run_service(void) 2640 { 2641 char empty[] = {0}; 2642 SERVICE_TABLE_ENTRYA table[] = { 2643 {empty, &service_main }, 2644 {0, 0} 2645 }; 2646 2647 StartServiceCtrlDispatcherA(table); 2648 } 2649 2650 START_TEST(service) 2651 { 2652 SC_HANDLE scm_handle; 2653 int myARGC; 2654 char** myARGV; 2655 2656 myARGC = winetest_get_mainargs(&myARGV); 2657 GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL); 2658 if (myARGC >= 3) 2659 { 2660 if (strcmp(myARGV[2], "serve") == 0) 2661 run_service(); 2662 return; 2663 } 2664 2665 /* Bail out if we are on win98 */ 2666 SetLastError(0xdeadbeef); 2667 scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); 2668 2669 if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 2670 { 2671 win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n"); 2672 return; 2673 } 2674 CloseServiceHandle(scm_handle); 2675 2676 init_function_pointers(); 2677 2678 /* First some parameter checking */ 2679 test_open_scm(); 2680 test_open_svc(); 2681 test_create_delete_svc(); 2682 test_get_displayname(); 2683 test_get_servicekeyname(); 2684 test_query_svc(); 2685 test_enum_svc(); 2686 test_close(); 2687 /* Test the creation, querying and deletion of a service */ 2688 test_sequence(); 2689 test_queryconfig2(); 2690 test_start_stop(); 2691 /* The main reason for this test is to check if any refcounting is used 2692 * and what the rules are 2693 */ 2694 test_refcount(); 2695 } 2696