- Timestamp:
- Nov 17, 2017 7:26:40 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c
r69692 r69727 2297 2297 2298 2298 2299 BOOL IsInstalledWindowsService(const WCHAR* wszServiceName) 2300 { 2301 BOOL bResult = FALSE; 2302 SC_HANDLE hSCM; 2303 SC_HANDLE hService; 2304 2305 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2299 #ifdef VBOX_WITH_SDS 2300 2301 static BOOL vbpsIsInstalledWindowsService(const WCHAR *pwszServiceName) 2302 { 2303 BOOL fRet = FALSE; 2304 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2306 2305 if (hSCM != NULL) 2307 2306 { 2308 hService = OpenService(hSCM,wszServiceName, SERVICE_QUERY_CONFIG);2307 SC_HANDLE hService = OpenService(hSCM, pwszServiceName, SERVICE_QUERY_CONFIG); 2309 2308 if (hService != NULL) 2310 2309 { 2311 bResult = TRUE;2312 2310 CloseServiceHandle(hService); 2311 fRet = TRUE; 2313 2312 } 2314 2313 CloseServiceHandle(hSCM); 2315 2314 } 2316 return bResult; 2317 } 2318 2319 2320 BOOL InstallWindowsService(const WCHAR* wszVBoxDir, 2321 const WCHAR* wszServiceModule, 2322 const WCHAR* wszServiceName, 2323 const WCHAR* wszServiceDisplayName, 2324 const WCHAR* wszServiceDescription 2325 ) 2326 { 2327 #define QUOTES_SPACE 2 2328 2329 WCHAR szFilePath[MAX_PATH + QUOTES_SPACE]; 2330 size_t dirLen; 2331 size_t moduleLen; 2332 SC_HANDLE hSCM; 2333 SC_HANDLE hService; 2334 SERVICE_DESCRIPTION sd; 2335 2336 if (IsInstalledWindowsService(wszServiceName)) 2337 return TRUE; 2338 2339 // Make the executable file path 2340 dirLen = RTUtf16Len(wszVBoxDir); 2341 moduleLen = RTUtf16Len(wszServiceModule); 2342 2343 if ( dirLen + moduleLen + 2 >= MAX_PATH + QUOTES_SPACE 2344 || !RT_SUCCESS(RTUtf16Copy(szFilePath + 1, MAX_PATH + QUOTES_SPACE - 1, wszVBoxDir)) 2345 || !RT_SUCCESS(RTUtf16Copy(szFilePath + dirLen + 1, MAX_PATH + QUOTES_SPACE - dirLen - 1, wszServiceModule))) 2346 { 2347 LogWarnFunc(("Error: The path to a windows service module is too long\n")); 2348 return FALSE; 2349 } 2350 2351 // Quote the FilePath before calling CreateService 2352 szFilePath[0] = L'\"'; 2353 szFilePath[dirLen + moduleLen + 1] = L'\"'; 2354 szFilePath[dirLen + moduleLen + 2] = 0; 2355 2356 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2357 if (hSCM == NULL) 2358 { 2359 LogWarnFunc(("Error: Could not open Service Manager\n")); 2360 Assert(0); 2361 return FALSE; 2362 } 2363 2364 hService = CreateService(hSCM, wszServiceName, wszServiceDisplayName, 2365 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 2366 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 2367 szFilePath, NULL, NULL, L"RPCSS\0", NULL, NULL); 2368 if (hService == NULL) 2369 { 2370 CloseServiceHandle(hSCM); 2371 LogWarnFunc(("Error: Could not start service\n")); 2372 Assert(0); 2373 return FALSE; 2374 } 2375 2376 sd.lpDescription = (LPWSTR)wszServiceDescription; 2377 if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd)) 2378 { 2379 LogWarnFunc(("Error: could not set service description. code: %x\n", 2380 GetLastError())); 2381 Assert(0); 2382 } 2383 2384 CloseServiceHandle(hService); 2385 CloseServiceHandle(hSCM); 2386 return TRUE; 2387 } 2388 2389 BOOL UninstallWindowsService(const WCHAR* wszServiceName) 2390 { 2391 SC_HANDLE hSCM; 2392 SC_HANDLE hService; 2393 SERVICE_STATUS status; 2394 BOOL bRet; 2395 BOOL bDelete; 2396 2397 if (!IsInstalledWindowsService(wszServiceName)) 2398 return TRUE; 2399 2400 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2401 if (hSCM == NULL) 2402 { 2403 LogWarnFunc(("Error: Could not open Service Manager\n")); 2404 Assert(0); 2405 return FALSE; 2406 } 2407 2408 hService = OpenService(hSCM, wszServiceName, SERVICE_STOP | DELETE); 2409 if (hService == NULL) 2410 { 2411 CloseServiceHandle(hSCM); 2412 hSCM = NULL; 2413 LogWarnFunc(("Error: Could not open service\n")); 2414 Assert(0); 2415 return FALSE; 2416 } 2417 2418 bRet = ControlService(hService, SERVICE_CONTROL_STOP, &status); 2419 if (!bRet) 2420 { 2421 DWORD dwError = GetLastError(); 2422 if (!( dwError == ERROR_SERVICE_NOT_ACTIVE 2423 || ( dwError == ERROR_SERVICE_CANNOT_ACCEPT_CTRL 2424 && status.dwCurrentState == SERVICE_STOP_PENDING))) 2315 return fRet; 2316 } 2317 2318 2319 BOOL vbpsInstallWindowsService(const WCHAR *pwszVBoxDir, const WCHAR *pwszServiceModule, const WCHAR *pwszServiceName, 2320 const WCHAR *pwszServiceDisplayName, const WCHAR *pwszServiceDescription) 2321 { 2322 BOOL fRet = vbpsIsInstalledWindowsService(pwszServiceName); 2323 if (!fRet) 2324 { 2325 /* Make double quoted executable file path. ASSUMES pwszVBoxDir ends with a slash! */ 2326 WCHAR wszFilePath[MAX_PATH + 2]; 2327 int rc = RTUtf16CopyAscii(wszFilePath, RT_ELEMENTS(wszFilePath), "\""); 2328 if (RT_SUCCESS(rc)) 2329 rc = RTUtf16Cat(wszFilePath, RT_ELEMENTS(wszFilePath), pwszVBoxDir); 2330 if (RT_SUCCESS(rc)) 2331 rc = RTUtf16Cat(wszFilePath, RT_ELEMENTS(wszFilePath), pwszServiceModule); 2332 if (RT_SUCCESS(rc)) 2333 rc = RTUtf16CatAscii(wszFilePath, RT_ELEMENTS(wszFilePath), "\""); 2334 if (RT_SUCCESS(rc)) 2425 2335 { 2336 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2337 if (hSCM != NULL) 2338 { 2339 SC_HANDLE hService = CreateService(hSCM, pwszServiceName, pwszServiceDisplayName, 2340 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 2341 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 2342 wszFilePath, NULL, NULL, L"RPCSS\0", NULL, NULL); 2343 if (hService != NULL) 2344 { 2345 SERVICE_DESCRIPTION sd; 2346 sd.lpDescription = (WCHAR *)pwszServiceDescription; 2347 if (ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd)) 2348 fRet = TRUE; 2349 else 2350 AssertMsgFailed(("Could not set service description for %ls: %u\n", pwszServiceName, GetLastError())); 2351 CloseServiceHandle(hService); 2352 } 2353 else 2354 AssertMsgFailed(("Could not create service %ls: %u\n", pwszServiceName, GetLastError())); 2355 CloseServiceHandle(hSCM); 2356 } 2357 else 2358 AssertMsgFailed(("Could not open service %ls: %u\n", pwszServiceName, GetLastError())); 2359 } 2360 else 2361 AssertMsgFailed(("Could not open Service Manager: %u\n", GetLastError())); 2362 } 2363 return fRet; 2364 } 2365 2366 2367 BOOL vbpsUninstallWindowsService(const WCHAR *pwszServiceName) 2368 { 2369 BOOL fRet = !vbpsIsInstalledWindowsService(pwszServiceName); 2370 if (!fRet) 2371 { 2372 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2373 if (hSCM != NULL) 2374 { 2375 SC_HANDLE hService = OpenService(hSCM, pwszServiceName, SERVICE_STOP | DELETE); 2376 if (hService) 2377 { 2378 DWORD dwErr; 2379 SERVICE_STATUS Status; 2380 RT_ZERO(Status); 2381 fRet = ControlService(hService, SERVICE_CONTROL_STOP, &Status); 2382 dwErr = GetLastError(); 2383 if ( fRet 2384 || dwErr == ERROR_SERVICE_NOT_ACTIVE 2385 || ( dwErr == ERROR_SERVICE_CANNOT_ACCEPT_CTRL 2386 && Status.dwCurrentState == SERVICE_STOP_PENDING) ) 2387 { 2388 fRet = DeleteService(hService); 2389 AssertMsg(fRet, ("Could not delete service %ls: %u\n", pwszServiceName, GetLastError())); 2390 } 2391 else 2392 AssertMsgFailed(("Could not stop service %ls: %u (state=%u)\n", pwszServiceName, dwErr, Status.dwCurrentState)); 2393 CloseServiceHandle(hService); 2394 } 2395 else 2396 AssertMsgFailed(("Could not open service %ls: %u\n", pwszServiceName, GetLastError())); 2426 2397 CloseServiceHandle(hSCM); 2427 hSCM = NULL;2428 LogWarnFunc(("Could not stop service\n"));2429 Assert(0);2430 2398 } 2431 } 2432 2433 bDelete = DeleteService(hService); 2434 CloseServiceHandle(hService); 2435 CloseServiceHandle(hSCM); 2436 2437 if (!bDelete) 2438 { 2439 LogWarnFunc(("Error: Could not delete service\n")); 2440 Assert(0); 2441 return FALSE; 2442 } 2443 2444 return TRUE; 2445 } 2446 2447 2448 static void vbpsUpdateVBoxSDSWindowsService(VBPSREGSTATE* pState, const WCHAR* wszVBoxDir) 2449 { 2450 const WCHAR* wszModuleName = L"VBoxSDS.exe"; 2451 const WCHAR* wszServiceName = L"VBoxSDS"; 2452 const WCHAR* wszServiceDisplayName = L"VirtualBox system service"; 2453 const WCHAR* wszServiceDescription = L"Used as a COM server for VirtualBox API."; 2399 else 2400 AssertMsgFailed(("Could not open Service Manager: %u\n", GetLastError())); 2401 } 2402 return fRet; 2403 } 2404 2405 2406 static void vbpsUpdateVBoxSDSWindowsService(VBPSREGSTATE *pState, const WCHAR *pwszVBoxDir) 2407 { 2408 const WCHAR s_wszModuleName[] = L"VBoxSDS.exe"; 2409 const WCHAR s_wszServiceName[] = L"VBoxSDS"; 2410 const WCHAR s_wszServiceDisplayName[] = L"VirtualBox system service"; 2411 const WCHAR s_wszServiceDescription[] = L"Used as a COM server for VirtualBox API."; 2454 2412 2455 2413 if (pState->fUpdate) 2456 2414 { 2457 if (!InstallWindowsService(wszVBoxDir, 2458 wszModuleName, 2459 wszServiceName, 2460 wszServiceDisplayName, 2461 wszServiceDescription)) 2415 if (!vbpsInstallWindowsService(pwszVBoxDir, s_wszModuleName, s_wszServiceName, 2416 s_wszServiceDisplayName, s_wszServiceDescription)) 2462 2417 { 2463 LogWarnFunc(("Error: Windows service '%ls' cannot be registered\n", wszServiceName));2418 LogWarnFunc(("Error: Windows service '%ls' cannot be registered\n", s_wszServiceName)); 2464 2419 pState->rc = E_FAIL; 2465 2420 } 2466 2421 } 2467 else if (pState->fDelete)2468 { 2469 if (! UninstallWindowsService(wszServiceName))2422 else if (pState->fDelete) 2423 { 2424 if (!vbpsUninstallWindowsService(s_wszServiceName)) 2470 2425 { 2471 LogWarnFunc(("Error: Windows service '%ls' cannot be unregistered\n", wszServiceName));2426 LogWarnFunc(("Error: Windows service '%ls' cannot be unregistered\n", s_wszServiceName)); 2472 2427 pState->rc = E_FAIL; 2473 2428 } 2474 2429 } 2475 2430 } 2431 2432 #endif /* VBOX_WITH_SDS */ 2476 2433 2477 2434
Note:
See TracChangeset
for help on using the changeset viewer.