VirtualBox

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


Ignore:
Timestamp:
Apr 3, 2017 9:09:37 PM (8 years ago)
Author:
vboxsync
Message:

VBox/Main: ​​​bugref:3300: VBoxSVC from terminal server session is not 'visible' - extended validation for VBoxSDS issues

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/Makefile.kmk

    r66279 r66411  
    990990        $(PATH_STAGE_LIB)/VBoxAPIWrap-x86$(VBOX_SUFF_LIB)
    991991 VBoxClient-x86_LIBS.win = $(NO_SUCH_VARIABLE)
    992  VBoxClient-x86_LIBS.win.x86 = $(PATH_TOOL_$(VBOX_VCC_TOOL_STEM)X86_LIB)/delayimp.lib
     992 VBoxClient-x86_LIBS.win.x86 += \
     993    $(PATH_TOOL_$(VBOX_VCC_TOOL_STEM)X86_LIB)/delayimp.lib \
     994        $(PATH_SDK_$(VBOX_WINPSDK)_LIB.x86)/WbemUuid.Lib
    993995 VBoxClient-x86_CLEAN.win += $(VBoxClient-x86_0_OUTDIR)/VBoxClient-x86.rgs
    994996 src-client/win/VBoxClient-x86.rc_DEPS = \
  • trunk/src/VBox/Main/include/VirtualBoxClientImpl.h

    r63814 r66411  
    7171#endif
    7272
     73#ifdef VBOX_WITH_SDS
     74    DWORD getServiceAccount(const wchar_t* wszServiceName, wchar_t* wszAccountName, size_t cbAccountNameSize);
     75    HRESULT isServiceDisabled(const wchar_t* wszServiceName, bool* pOutIsDisabled);
     76#endif
     77
    7378    static DECLCALLBACK(int) SVCWatcherThread(RTTHREAD ThreadSelf, void *pvUser);
    7479
  • trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp

    r66279 r66411  
    2828#include <iprt/semaphore.h>
    2929#include <iprt/cpp/utils.h>
     30#include <iprt/utf16.h>
    3031#ifdef RT_OS_WINDOWS
    3132# include <iprt/ldr.h>
    3233# include <msi.h>
     34# include <WbemIdl.h>
    3335#endif
    3436
     
    7678    if (FAILED(rc))
    7779    {
    78         //AssertComRCThrow(rc, setError(rc,
    79         //    tr("Could not create VirtualBoxSDS bridge object for VirtualBoxClient")));
    8080        Assert(SUCCEEDED(rc));
    8181        return rc;
     
    8484    rc = aVirtualBoxSDS->get_VirtualBox(aVirtualBox.asOutParam());
    8585    if (FAILED(rc))
    86     {
    8786        Assert(SUCCEEDED(rc));
    88         //AssertComRCThrow(rc, setError(rc,
    89         //    tr("Could not create VirtualBox object for VirtualBoxClient")));
    90     }
     87
    9188    return rc;
    9289}
     
    103100    if (FAILED(rc))
    104101    {
    105         //AssertComRCThrow(rc, setError(rc,
    106         //    tr("Could not create VirtualBoxSDS bridge object for VirtualBoxClient")));
    107102        LogRel(("ReleaseVirtualBox - instantiation of IVirtualBoxSDS failed, %x\n", rc));
    108103        Assert(SUCCEEDED(rc));
     
    117112    }
    118113    return rc;
     114}
     115
     116
     117DWORD VirtualBoxClient::getServiceAccount(
     118    const wchar_t* wszServiceName,
     119    wchar_t* wszAccountName,
     120    size_t cbAccountNameSize
     121    )
     122{
     123    SC_HANDLE schSCManager;
     124    SC_HANDLE schService;
     125    LPQUERY_SERVICE_CONFIG pSc = NULL;
     126    DWORD dwBytesNeeded;
     127    int dwError;
     128
     129    Assert(wszServiceName);
     130    Assert(wszAccountName);
     131    Assert(cbAccountNameSize);
     132
     133    // Get a handle to the SCM database.
     134    schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
     135    if (NULL == schSCManager)
     136    {
     137        dwError = GetLastError();
     138        LogRel(("Error: could not open SCM: %Rhrc\n"));
     139        return RTErrConvertFromWin32(dwError);
     140    }
     141
     142    // Get a handle to the service.
     143    schService = OpenService(schSCManager, wszServiceName, SERVICE_QUERY_CONFIG);
     144    if (schService == NULL)
     145    {
     146        dwError = GetLastError();
     147        CloseServiceHandle(schSCManager);
     148        LogRel(("Error: Could not open service: %Rwc\n", dwError));
     149        return RTErrConvertFromWin32(dwError);
     150    }
     151
     152    // Get the configuration information.
     153    if (!QueryServiceConfig(schService, NULL, 0, &dwBytesNeeded))
     154    {
     155        dwError = GetLastError();
     156        if (ERROR_INSUFFICIENT_BUFFER == dwError)
     157        {
     158            pSc = (LPQUERY_SERVICE_CONFIG)malloc(dwBytesNeeded);
     159            if (!pSc)
     160            {
     161                LogRel(("Error: allocating memory for service config, %Rwc\n", dwError));
     162                CloseServiceHandle(schSCManager);
     163                CloseServiceHandle(schService);
     164                return RTErrConvertFromWin32(dwError);
     165            }
     166            if (!QueryServiceConfig(schService, pSc, dwBytesNeeded, &dwBytesNeeded))
     167            {
     168                dwError = GetLastError();
     169                LogRel(("Error: error in querying service config, %Rwc\n", dwError));
     170                free(pSc);
     171                CloseServiceHandle(schService);
     172                CloseServiceHandle(schSCManager);
     173                return RTErrConvertFromWin32(dwError);
     174            }
     175        }
     176    }
     177
     178    dwError = RTUtf16Copy((RTUTF16*)wszAccountName, cbAccountNameSize / sizeof(RTUTF16),
     179        (RTUTF16*)pSc->lpServiceStartName);
     180    if (RT_FAILURE(dwError))
     181    {
     182        LogRel(("Error: cannot copy account name to destination, %Rrc\n", dwError));
     183        free(pSc);
     184        CloseServiceHandle(schService);
     185        CloseServiceHandle(schSCManager);
     186        return RTErrConvertFromWin32(dwError);
     187    }
     188
     189    free(pSc);
     190    CloseServiceHandle(schService);
     191    CloseServiceHandle(schSCManager);
     192    return VINF_SUCCESS;
     193}
     194
     195
     196HRESULT VirtualBoxClient::isServiceDisabled(const wchar_t* wszServiceName, bool* pOutIsDisabled)
     197{
     198    Assert(pOutIsDisabled);
     199    Assert(wszServiceName);
     200    ComPtr<IWbemLocator> aLocator;
     201    ComPtr<IWbemServices> aService;
     202
     203    HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0,
     204        CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)aLocator.asOutParam());
     205    if (FAILED(hr))
     206    {
     207        LogRel(("Error: Cannot instantiate WbemLocator: %Rhrc", hr));
     208        return hr;
     209    }
     210
     211    hr = aLocator->ConnectServer(
     212        com::Bstr(L"ROOT\\CIMV2").raw(), // Object path of WMI namespace
     213        NULL,                    // User name. NULL = current user
     214        NULL,                    // User password. NULL = current
     215        0,                       // Locale. NULL indicates current
     216        NULL,                    // Security flags.
     217        0,                       // Authority (for example, Kerberos)
     218        0,                       // Context object
     219        aService.asOutParam()    // pointer to IWbemServices proxy
     220    );
     221    if (FAILED(hr))
     222    {
     223        LogRel(("Error: Cannot connect to Wbem Service: %Rhrc\n", hr));
     224        return hr;
     225    }
     226
     227    // query settings for VBoxSDS windows service
     228    ComPtr<IEnumWbemClassObject> aEnumerator;
     229    hr = aService->ExecQuery(
     230        com::Bstr("WQL").raw(),
     231        com::BstrFmt("SELECT * FROM Win32_Service WHERE Name='%ls'", wszServiceName).raw(),
     232        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
     233        NULL,
     234        aEnumerator.asOutParam());
     235    if (FAILED(hr) || aEnumerator == NULL)
     236    {
     237        LogRel(("Error: querying service settings from WMI: %Rhrc\n", hr));
     238        return hr;
     239    }
     240
     241    ULONG uReturn = 0;
     242    ComPtr<IWbemClassObject> aVBoxSDSObj;
     243    hr = aEnumerator->Next(WBEM_INFINITE, 1, aVBoxSDSObj.asOutParam(), &uReturn);
     244    if (FAILED(hr))
     245    {
     246        LogRel(("Error: Cannot get Service WMI record: %Rhrc\n", hr));
     247        return hr;
     248    }
     249    if (aVBoxSDSObj == NULL || uReturn == 0)
     250    {
     251        LogRel(("Error: Service record didn't exist in WMI: %Rhrc\n", hr));
     252        return hr;
     253    }
     254
     255    VARIANT vtProp;
     256    VariantInit(&vtProp);
     257
     258    // Get "StartMode" property
     259    hr = aVBoxSDSObj->Get(L"StartMode", 0, &vtProp, 0, 0);
     260    if (FAILED(hr) || (vtProp.vt & VT_NULL) == VT_NULL)
     261    {
     262        LogRel(("Error: Didn't found StartMode property: %Rhrc\n", hr));
     263        return hr;
     264    }
     265   
     266    Assert((vtProp.vt & VT_BSTR) == VT_BSTR);
     267
     268    *pOutIsDisabled = RTUtf16Cmp((RTUTF16*)vtProp.bstrVal,
     269        (RTUTF16*)L"Disabled") == 0;
     270
     271    LogRel(("Service start mode is '%ls' \n", vtProp.bstrVal));
     272
     273    VariantClear(&vtProp);
     274
     275    return S_OK;
    119276}
    120277
     
    130287
    131288#ifdef VBOX_WITH_SDS
    132     // TODO: AM rework for final version
    133289    // setup COM Security to enable impersonation
    134290    // This works for console Virtual Box clients, GUI has own security settings
     
    143299                                                             EOAC_NONE,
    144300                                                             NULL);
    145     //Assert(RPC_E_TOO_LATE != hrGUICoInitializeSecurity);
    146301    Assert(SUCCEEDED(hrGUICoInitializeSecurity) || hrGUICoInitializeSecurity == RPC_E_TOO_LATE);
    147302#endif
     
    257412HRESULT VirtualBoxClient::i_investigateVirtualBoxObjectCreationFailure(HRESULT hrcCaller)
    258413{
    259     // TODO: AM place creation of VBox through SDS
    260414     /*
    261415     * First step is to try get an IUnknown interface of the VirtualBox object.
     
    266420     */
    267421    IUnknown *pUnknown = NULL;
     422
     423#ifdef VBOX_WITH_SDS
     424    // Check the VBOXSDS service running account name is SYSTEM
     425    wchar_t wszBuffer[256];
     426    int dwError = getServiceAccount(L"VBoxSDS", wszBuffer, sizeof(wszBuffer));
     427    if(RT_FAILURE(dwError))
     428        return setError(hrcCaller, tr("Failed to instantiate CLSID_VirtualBox using VBoxSDS: The VBoxSDS is unavailable: %Rwc"), dwError);
     429
     430    LogRelFunc(("VBoxSDS service is running under '%ls' account.\n", wszBuffer));
     431
     432    if(RTUtf16Cmp(L"LocalSystem", wszBuffer) != 0)
     433        return setError(hrcCaller,
     434            tr("VBoxSDS should be run under SYSTEM account, but it started under '%ls' account:\n"
     435                "Change VBoxSDS Windows Service Logon parameters in Service Control Manager. \n%Rhrc"
     436               ), wszBuffer, hrcCaller);
     437
     438    bool bIsVBoxSDSDisabled = false;
     439    HRESULT hrc = isServiceDisabled(L"VBoxSDS", &bIsVBoxSDSDisabled);
     440    if (FAILED(hrc))
     441    {
     442        return setError(hrcCaller, tr("Failed to get information about VBoxSDS using WMI:: %Rhrc & %Rhrc"), hrcCaller, hrc);
     443    }
     444    if (bIsVBoxSDSDisabled)
     445    {
     446        return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox using VBoxSDS: "
     447            "VBoxSDS windows service disabled.\n"
     448            "Enable VBoxSDS Windows Service using Windows Service Management Console.\n %Rhrc"), hrcCaller);
     449    }
     450
     451    // Check the VBoxSDS windows service is enabled
     452    ComPtr<IVirtualBox> aVirtualBox;
     453    hrc = CreateVirtualBoxThroughSDS(aVirtualBox);
     454    if (FAILED(hrc))
     455    {
     456        if (hrc == hrcCaller)
     457            return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox using VBoxSDS: %Rhrc"), hrcCaller);
     458        return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox using VBoxSDS: %Rhrc & %Rhrc"), hrcCaller, hrc);
     459    }
     460
     461    hrc = aVirtualBox.queryInterfaceTo<IUnknown>(&pUnknown);
     462    if (FAILED(hrc))
     463    {
     464        if (hrc == hrcCaller)
     465            return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox using VBoxSDS: %Rhrc"), hrcCaller);
     466        return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox using VBoxSDS: %Rhrc & %Rhrc"), hrcCaller, hrc);
     467    }
     468#else
    268469    HRESULT hrc = CoCreateInstance(CLSID_VirtualBox, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)&pUnknown);
    269470    if (FAILED(hrc))
     
    273474        return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox: %Rhrc & %Rhrc"), hrcCaller, hrc);
    274475    }
     476#endif
    275477
    276478    /*
     
    530732/////////////////////////////////////////////////////////////////////////////
    531733
     734
     735// TODO: AM Add pinging of VBoxSDS
    532736/*static*/
    533737DECLCALLBACK(int) VirtualBoxClient::SVCWatcherThread(RTTHREAD ThreadSelf,
Note: See TracChangeset for help on using the changeset viewer.

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