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