Changeset 66922 in vbox for trunk/src/VBox/Main/src-all/win
- Timestamp:
- May 16, 2017 7:34:21 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 115449
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c
r66358 r66922 40 40 #include <iprt/string.h> 41 41 #include <iprt/uuid.h> 42 #include <iprt/utf16.h> 42 43 43 44 … … 2281 2282 2282 2283 2284 BOOL IsInstalledWindowsService(const WCHAR* wszServiceName) 2285 { 2286 BOOL bResult = FALSE; 2287 SC_HANDLE hSCM; 2288 SC_HANDLE hService; 2289 2290 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2291 2292 if (hSCM != NULL) 2293 { 2294 hService = OpenService(hSCM, wszServiceName, SERVICE_QUERY_CONFIG); 2295 if (hService != NULL) 2296 { 2297 bResult = TRUE; 2298 CloseServiceHandle(hService); 2299 } 2300 CloseServiceHandle(hSCM); 2301 } 2302 return bResult; 2303 } 2304 2305 2306 BOOL InstallWindowsService(const WCHAR* wszVBoxDir, 2307 const WCHAR* wszServiceModule, 2308 const WCHAR* wszServiceName, 2309 const WCHAR* wszServiceDisplayName, 2310 const WCHAR* wszServiceDescription 2311 ) 2312 { 2313 #define QUOTES_SPACE 2 2314 2315 WCHAR szFilePath[MAX_PATH + QUOTES_SPACE]; 2316 size_t dirLen; 2317 size_t moduleLen; 2318 SC_HANDLE hSCM; 2319 SC_HANDLE hService; 2320 SERVICE_DESCRIPTION sd; 2321 2322 if (IsInstalledWindowsService(wszServiceName)) 2323 return TRUE; 2324 2325 // Make the executable file path 2326 dirLen = RTUtf16Len(wszVBoxDir); 2327 moduleLen = RTUtf16Len(wszServiceModule); 2328 2329 if (dirLen + moduleLen >= MAX_PATH + QUOTES_SPACE || 2330 !RT_SUCCESS(RTUtf16Copy(szFilePath + 1, MAX_PATH + QUOTES_SPACE - 1, wszVBoxDir)) || 2331 !RT_SUCCESS(RTUtf16Copy(szFilePath + dirLen + 1, MAX_PATH + QUOTES_SPACE - dirLen - 1, wszServiceModule))) 2332 { 2333 LogWarnFunc(("Error: The path to a windows service module is too long\n")); 2334 return FALSE; 2335 } 2336 2337 // Quote the FilePath before calling CreateService 2338 szFilePath[0] = L'\"'; 2339 szFilePath[dirLen + moduleLen + 1] = L'\"'; 2340 szFilePath[dirLen + moduleLen + 2] = 0; 2341 2342 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2343 if (hSCM == NULL) 2344 { 2345 LogWarnFunc(("Error: Could not open Service Manager\n")); 2346 Assert(0); 2347 return FALSE; 2348 } 2349 2350 hService = CreateService( 2351 hSCM, wszServiceName, wszServiceDisplayName, 2352 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 2353 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 2354 szFilePath, NULL, NULL, L"RPCSS\0", NULL, NULL); 2355 2356 if (hService == NULL) 2357 { 2358 CloseServiceHandle(hSCM); 2359 LogWarnFunc(("Error: Could not start service\n")); 2360 Assert(0); 2361 return FALSE; 2362 } 2363 2364 sd.lpDescription = (LPWSTR)wszServiceDescription; 2365 if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd)) 2366 { 2367 LogWarnFunc(("Error: could not set service description. code: %x\n", 2368 GetLastError())); 2369 Assert(0); 2370 } 2371 2372 CloseServiceHandle(hService); 2373 CloseServiceHandle(hSCM); 2374 return TRUE; 2375 } 2376 2377 BOOL UninstallWindowsService(const WCHAR* wszServiceName) 2378 { 2379 SC_HANDLE hSCM; 2380 SC_HANDLE hService; 2381 SERVICE_STATUS status; 2382 BOOL bRet; 2383 BOOL bDelete; 2384 2385 if (!IsInstalledWindowsService(wszServiceName)) 2386 return TRUE; 2387 2388 hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 2389 2390 if (hSCM == NULL) 2391 { 2392 LogWarnFunc(("Error: Could not open Service Manager\n")); 2393 Assert(0); 2394 return FALSE; 2395 } 2396 2397 hService = OpenService(hSCM, wszServiceName, SERVICE_STOP | DELETE); 2398 2399 if (hService == NULL) 2400 { 2401 CloseServiceHandle(hSCM); 2402 hSCM = NULL; 2403 LogWarnFunc(("Error: Could not open service\n")); 2404 Assert(0); 2405 return FALSE; 2406 } 2407 2408 bRet = ControlService(hService, SERVICE_CONTROL_STOP, &status); 2409 if (!bRet) 2410 { 2411 DWORD dwError = GetLastError(); 2412 if (!((dwError == ERROR_SERVICE_NOT_ACTIVE) || 2413 (dwError == ERROR_SERVICE_CANNOT_ACCEPT_CTRL 2414 && status.dwCurrentState == SERVICE_STOP_PENDING))) 2415 { 2416 CloseServiceHandle(hSCM); 2417 hSCM = NULL; 2418 LogWarnFunc(("Could not stop service\n")); 2419 Assert(0); 2420 } 2421 } 2422 2423 bDelete = DeleteService(hService); 2424 CloseServiceHandle(hService); 2425 CloseServiceHandle(hSCM); 2426 2427 if (!bDelete) 2428 { 2429 LogWarnFunc(("Error: Could not delete service\n")); 2430 Assert(0); 2431 return FALSE; 2432 } 2433 2434 return TRUE; 2435 } 2436 2437 2438 static void vbpsUpdateVBoxSDSWindowsService(VBPSREGSTATE* pState, const WCHAR* wszVBoxDir) 2439 { 2440 const WCHAR* wszModuleName = L"VBoxSDS.exe"; 2441 const WCHAR* wszServiceName = L"VBoxSDS"; 2442 const WCHAR* wszServiceDisplayName = L"VirtualBox system service"; 2443 const WCHAR* wszServiceDescription = L"Used as a COM server for VirtualBox API."; 2444 2445 if (pState->fUpdate) 2446 { 2447 if (!InstallWindowsService(wszVBoxDir, 2448 wszModuleName, 2449 wszServiceName, 2450 wszServiceDisplayName, 2451 wszServiceDescription)) 2452 { 2453 LogWarnFunc(("Error: Windows service '%ls' cannot be registered\n", wszServiceName)); 2454 pState->rc = E_FAIL; 2455 } 2456 } 2457 else if(pState->fDelete) 2458 { 2459 if (!UninstallWindowsService(wszServiceName)) 2460 { 2461 LogWarnFunc(("Error: Windows service '%ls' cannot be unregistered\n", wszServiceName)); 2462 pState->rc = E_FAIL; 2463 } 2464 } 2465 } 2466 2467 2468 2283 2469 /** 2284 2470 * Gently update the COM registrations for VirtualBox. … … 2316 2502 if (rc == ERROR_SUCCESS && !vbpsIsUpToDate(&State)) 2317 2503 { 2504 2505 #ifdef VBOX_WITH_SDS 2506 vbpsUpdateVBoxSDSWindowsService(&State, wszVBoxDir); 2507 #endif 2318 2508 vbpsUpdateTypeLibRegistration(&State, wszVBoxDir, fIs32On64); 2319 2509 vbpsUpdateProxyStubRegistration(&State, wszVBoxDir, fIs32On64); … … 2336 2526 if (rc == ERROR_SUCCESS && !vbpsIsUpToDate(&State)) 2337 2527 { 2528 #ifdef VBOX_WITH_SDS 2529 vbpsUpdateVBoxSDSWindowsService(&State, wszVBoxDir); 2530 #endif 2338 2531 vbpsUpdateTypeLibRegistration(&State, wszVBoxDir, !fIs32On64); 2339 2532 vbpsUpdateProxyStubRegistration(&State, wszVBoxDir, !fIs32On64);
Note:
See TracChangeset
for help on using the changeset viewer.