VirtualBox

Changeset 69791 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Nov 21, 2017 1:54:53 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119209
Message:

VirtualBoxClient: brought back some problem determination code useful for i_investigateVirtualBoxObjectCreationFailure, adjusting it a bit. (Untested as I'm on darwin host right now.)

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/VirtualBoxClientImpl.h

    r69500 r69791  
    7272
    7373#ifdef VBOX_WITH_SDS
    74     int     getServiceAccount(const wchar_t *pwszServiceName, wchar_t *pwszAccountName, size_t cwcAccountName);
    75     HRESULT isServiceDisabled(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);
    7676#endif
    7777
  • trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp

    r69783 r69791  
    110110    {
    111111        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")));
    114113
    115114        mData.m_ThreadWatcher = NIL_RTTHREAD;
     
    131130
    132131        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")));
    135133        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")));
    138135
    139136        /* HACK ALERT! This is for DllCanUnloadNow(). */
     
    148145        {
    149146            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));
    153148        }
    154149
     
    159154            RTSemEventDestroy(mData.m_SemEvWatcher);
    160155            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));
    164157        }
    165158    }
     
    189182
    190183#ifdef RT_OS_WINDOWS
     184
    191185/**
    192186 * Looks into why we failed to create the VirtualBox object.
     
    197191HRESULT VirtualBoxClient::i_investigateVirtualBoxObjectCreationFailure(HRESULT hrcCaller)
    198192{
     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
    199221    /*
    200222     * First step is to try get an IUnknown interface of the VirtualBox object.
     
    354376    return hrcCaller;
    355377}
     378
     379# ifdef VBOX_WITH_SDS
     380
     381int 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
     451HRESULT 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
    356530#endif /* RT_OS_WINDOWS */
    357531
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette