Changeset 69791 in vbox for trunk/src/VBox/Main
- Timestamp:
- Nov 21, 2017 1:54:53 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119209
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/VirtualBoxClientImpl.h
r69500 r69791 72 72 73 73 #ifdef VBOX_WITH_SDS 74 int getServiceAccount(const wchar_t *pwszServiceName, wchar_t *pwszAccountName, size_t cwcAccountName);75 HRESULT i sServiceDisabled(const wchar_t *pwszServiceName, bool *pfOutIsDisabled);74 int i_getServiceAccount(const wchar_t *pwszServiceName, wchar_t *pwszAccountName, size_t cwcAccountName); 75 HRESULT i_isServiceDisabled(const wchar_t *pwszServiceName, bool *pfOutIsDisabled); 76 76 #endif 77 77 -
trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
r69783 r69791 110 110 { 111 111 if (ASMAtomicIncU32(&g_cInstances) != 1) 112 AssertFailedStmt(throw setError(E_FAIL, 113 tr("Attempted to create more than one VirtualBoxClient instance"))); 112 AssertFailedStmt(throw setError(E_FAIL, tr("Attempted to create more than one VirtualBoxClient instance"))); 114 113 115 114 mData.m_ThreadWatcher = NIL_RTTHREAD; … … 131 130 132 131 rc = unconst(mData.m_pEventSource).createObject(); 133 AssertComRCThrow(rc, setError(rc, 134 tr("Could not create EventSource for VirtualBoxClient"))); 132 AssertComRCThrow(rc, setError(rc, tr("Could not create EventSource for VirtualBoxClient"))); 135 133 rc = mData.m_pEventSource->init(); 136 AssertComRCThrow(rc, setError(rc, 137 tr("Could not initialize EventSource for VirtualBoxClient"))); 134 AssertComRCThrow(rc, setError(rc, tr("Could not initialize EventSource for VirtualBoxClient"))); 138 135 139 136 /* HACK ALERT! This is for DllCanUnloadNow(). */ … … 148 145 { 149 146 mData.m_SemEvWatcher = NIL_RTSEMEVENT; 150 AssertRCStmt(vrc, throw setError(VBOX_E_IPRT_ERROR, 151 tr("Failed to create semaphore (rc=%Rrc)"), 152 vrc)); 147 AssertRCStmt(vrc, throw setError(VBOX_E_IPRT_ERROR, tr("Failed to create semaphore (rc=%Rrc)"), vrc)); 153 148 } 154 149 … … 159 154 RTSemEventDestroy(mData.m_SemEvWatcher); 160 155 mData.m_SemEvWatcher = NIL_RTSEMEVENT; 161 AssertRCStmt(vrc, throw setError(VBOX_E_IPRT_ERROR, 162 tr("Failed to create watcher thread (rc=%Rrc)"), 163 vrc)); 156 AssertRCStmt(vrc, throw setError(VBOX_E_IPRT_ERROR, tr("Failed to create watcher thread (rc=%Rrc)"), vrc)); 164 157 } 165 158 } … … 189 182 190 183 #ifdef RT_OS_WINDOWS 184 191 185 /** 192 186 * Looks into why we failed to create the VirtualBox object. … … 197 191 HRESULT VirtualBoxClient::i_investigateVirtualBoxObjectCreationFailure(HRESULT hrcCaller) 198 192 { 193 # ifdef VBOX_WITH_SDS 194 /* 195 * Check that the VBoxSDS service is configured to run as LocalSystem and is enabled. 196 */ 197 WCHAR wszBuffer[256]; 198 int vrc = i_getServiceAccount(L"VBoxSDS", wszBuffer, RT_ELEMENTS(wszBuffer)); 199 if (RT_SUCCESS(vrc)) 200 { 201 LogRelFunc(("VBoxSDS service is running under the '%ls' account.\n", wszBuffer)); 202 if (RTUtf16Cmp(wszBuffer, L"LocalSystem") != 0) 203 return setError(hrcCaller, 204 tr("VBoxSDS should be run under SYSTEM account, but it started under '%ls' account:\n" 205 "Change VBoxSDS Windows Service Logon parameters in Service Control Manager. \n%Rhrc"), 206 wszBuffer, hrcCaller); 207 } 208 else 209 LogRelFunc(("VirtualBoxClient::i_getServiceAccount failed: %Rrc\n", vrc)); 210 211 bool fIsVBoxSDSDisabled = false; 212 HRESULT hrc = i_isServiceDisabled(L"VBoxSDS", &fIsVBoxSDSDisabled); 213 if (SUCCEEDED(hrc) && fIsVBoxSDSDisabled) 214 return setError(hrcCaller, 215 tr("The VBoxSDS windows service is disabled.\n" 216 "Enable VBoxSDS Windows Service using Windows Service Management Console.\n %Rhrc"), hrcCaller); 217 if (FAILED(hrc)) 218 LogRelFunc(("Warning: Failed to get information about VBoxSDS using WMI:: %Rhrc", hrc)); 219 # endif /* VBOX_WITH_SDS */ 220 199 221 /* 200 222 * First step is to try get an IUnknown interface of the VirtualBox object. … … 354 376 return hrcCaller; 355 377 } 378 379 # ifdef VBOX_WITH_SDS 380 381 int VirtualBoxClient::i_getServiceAccount(const wchar_t *pwszServiceName, wchar_t *pwszAccountName, size_t cwcAccountName) 382 { 383 AssertPtr(pwszServiceName); 384 AssertPtr(pwszAccountName); 385 Assert(cwcAccountName); 386 *pwszAccountName = '\0'; 387 388 int vrc; 389 390 // Get a handle to the SCM database. 391 SC_HANDLE hSCManager = OpenSCManagerW(NULL /*pwszMachineName*/, NULL /*pwszDatabaseName*/, SC_MANAGER_ALL_ACCESS); 392 if (hSCManager != NULL) 393 { 394 SC_HANDLE hService = OpenServiceW(hSCManager, pwszServiceName, SERVICE_QUERY_CONFIG); 395 if (hService != NULL) 396 { 397 DWORD cbNeeded = sizeof(QUERY_SERVICE_CONFIGW) + _1K; 398 if (!QueryServiceConfigW(hService, NULL, 0, &cbNeeded)) 399 { 400 Assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER); 401 LPQUERY_SERVICE_CONFIGW pSc = (LPQUERY_SERVICE_CONFIGW)RTMemTmpAllocZ(cbNeeded); 402 if (pSc) 403 { 404 DWORD cbNeeded2 = 0; 405 if (QueryServiceConfigW(hService, pSc, cbNeeded, &cbNeeded2)) 406 { 407 vrc = RTUtf16Copy(pwszAccountName, cwcAccountName, pSc->lpServiceStartName); 408 if (RT_FAILURE(vrc)) 409 LogRel(("Error: SDS service name is too long (%Rrc): %ls\n", vrc, pSc->lpServiceStartName)); 410 } 411 else 412 { 413 int dwError = GetLastError(); 414 vrc = RTErrConvertFromWin32(dwError); 415 LogRel(("Error: Failed querying service config: %Rwc (%u) -> %Rrc; cbNeeded=%d cbNeeded2=%d\n", 416 dwError, dwError, vrc, cbNeeded, cbNeeded2)); 417 } 418 RTMemTmpFree(pSc); 419 } 420 else 421 { 422 LogRel(("Error: Failed allocating %#x bytes of memory for service config!\n", cbNeeded)); 423 vrc = VERR_NO_TMP_MEMORY; 424 } 425 } 426 else 427 { 428 AssertLogRelMsgFailed(("Error: QueryServiceConfigW returns success with zero buffer!\n")); 429 vrc = VERR_IPE_UNEXPECTED_STATUS; 430 } 431 CloseServiceHandle(hService); 432 } 433 else 434 { 435 int dwError = GetLastError(); 436 vrc = RTErrConvertFromWin32(dwError); 437 LogRel(("Error: Could not open service: %Rwc (%u) -> %Rrc\n", dwError, dwError, vrc)); 438 } 439 CloseServiceHandle(hSCManager); 440 } 441 else 442 { 443 int dwError = GetLastError(); 444 vrc = RTErrConvertFromWin32(dwError); 445 LogRel(("Error: Could not open SCM: %Rwc (%u) -> %Rrc\n", dwError, dwError, vrc)); 446 } 447 return vrc; 448 } 449 450 451 HRESULT VirtualBoxClient::i_isServiceDisabled(const wchar_t *pwszServiceName, bool* pfOutIsDisabled) 452 { 453 /** @todo r=bird: there must be a way we can get this information from the 454 * service manager. This is overly complicated. */ 455 AssertPtr(pwszServiceName); 456 AssertPtr(pfOutIsDisabled); 457 *pfOutIsDisabled = false; 458 459 ComPtr<IWbemLocator> aLocator; 460 HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void **)aLocator.asOutParam()); 461 if (FAILED(hr)) 462 { 463 LogRel(("Error: Cannot instantiate WbemLocator: %Rhrc", hr)); 464 return hr; 465 } 466 467 ComPtr<IWbemServices> aService; 468 hr = aLocator->ConnectServer(com::Bstr(L"ROOT\\CIMV2").raw(), // Object path of WMI namespace 469 NULL, // User name. NULL = current user 470 NULL, // User password. NULL = current 471 0, // Locale. NULL indicates current 472 NULL, // Security flags. 473 0, // Authority (for example, Kerberos) 474 0, // Context object 475 aService.asOutParam()); // pointer to IWbemServices proxy 476 if (FAILED(hr)) 477 { 478 LogRel(("Error: Cannot connect to Wbem Service: %Rhrc\n", hr)); 479 return hr; 480 } 481 482 // query settings for VBoxSDS windows service 483 ComPtr<IEnumWbemClassObject> aEnumerator; 484 hr = aService->ExecQuery(com::Bstr("WQL").raw(), 485 com::BstrFmt("SELECT * FROM Win32_Service WHERE Name='%ls'", pwszServiceName).raw(), 486 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 487 NULL, 488 aEnumerator.asOutParam()); 489 if (FAILED(hr) || aEnumerator == NULL) 490 { 491 LogRel(("Error: querying service settings from WMI: %Rhrc\n", hr)); 492 return hr; 493 } 494 495 ULONG uReturn = 0; 496 ComPtr<IWbemClassObject> aVBoxSDSObj; 497 hr = aEnumerator->Next(WBEM_INFINITE, 1, aVBoxSDSObj.asOutParam(), &uReturn); 498 if (FAILED(hr)) 499 { 500 LogRel(("Error: Cannot get Service WMI record: %Rhrc\n", hr)); 501 return hr; 502 } 503 if (aVBoxSDSObj == NULL || uReturn == 0) 504 { 505 LogRel(("Error: Service record didn't exist in WMI: %Rhrc\n", hr)); 506 return hr; 507 } 508 509 // Get "StartMode" property 510 VARIANT vtProp; 511 VariantInit(&vtProp); 512 hr = aVBoxSDSObj->Get(L"StartMode", 0, &vtProp, 0, 0); 513 if (FAILED(hr) || (vtProp.vt & VT_NULL) == VT_NULL) 514 { 515 LogRel(("Error: Didn't found StartMode property: %Rhrc\n", hr)); 516 return hr; 517 } 518 519 Assert((vtProp.vt & VT_BSTR) == VT_BSTR); 520 521 *pfOutIsDisabled = RTUtf16Cmp((RTUTF16*)vtProp.bstrVal, (RTUTF16*)L"Disabled") == 0; 522 523 LogRel(("Service start mode is '%ls' \n", vtProp.bstrVal)); 524 VariantClear(&vtProp); 525 return S_OK; 526 } 527 528 # endif /* VBOX_WITH_SDS */ 529 356 530 #endif /* RT_OS_WINDOWS */ 357 531
Note:
See TracChangeset
for help on using the changeset viewer.