VirtualBox

Changeset 95353 in vbox for trunk/src/VBox/Main/src-global


Ignore:
Timestamp:
Jun 23, 2022 10:35:25 AM (3 years ago)
Author:
vboxsync
Message:

FE/VBoxAutostart/adi: Added documentation for running in session 0 + made running in session 0 runtime-configurable through the Windows registry (disabled by default). ​bugref:9341

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-global/win/VirtualBoxSDSImpl.cpp

    r95274 r95353  
    226226}
    227227
     228/* static */
     229bool VirtualBoxSDS::i_isFeatureEnabled(com::Utf8Str const &a_rStrFeature)
     230{
     231    HKEY hKey;
     232    LSTATUS lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Oracle\\VirtualBox\\VBoxSDS", 0, KEY_READ, &hKey);
     233    /* Treat any errors as the feature is off. Because the actual error value doesn't matter. */
     234    if (lrc != ERROR_SUCCESS)
     235        return false;
     236
     237    PRTUTF16 pwszFeature;
     238    int rc = RTStrToUtf16(a_rStrFeature.c_str(), &pwszFeature);
     239    AssertRCReturn(rc, false);
     240
     241    DWORD dwType = 0;
     242    DWORD dwValue = 0;
     243    DWORD cbValue = sizeof(DWORD);
     244    lrc = RegQueryValueExW(hKey, pwszFeature, NULL, &dwType, (LPBYTE)&dwValue, &cbValue);
     245
     246    RTUtf16Free(pwszFeature);
     247
     248    bool const fEnabled =    lrc     == ERROR_SUCCESS
     249                          && dwType  == REG_DWORD
     250                          /* A lot of people are used to putting 0xFF or similar to DWORDs for enabling stuff. */
     251                          && dwValue >= 1;
     252
     253    RegCloseKey(hKey);
     254    return fEnabled;
     255}
    228256
    229257
     
    305333                {
    306334#ifdef VBOX_WITH_VBOXSVC_SESSION_0
    307                     /* Get user token. */
    308                     HANDLE hThreadToken = NULL;
    309                     hrc = CoImpersonateClient();
    310                     if (SUCCEEDED(hrc))
     335                    DWORD dwSessionId = 0;
     336                    if (VirtualBoxSDS::i_isFeatureEnabled("ServerSession0"))
    311337                    {
    312                         hrc = E_FAIL;
    313                         if (OpenThreadToken(GetCurrentThread(),
    314                                               TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE
    315                                             | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE,
    316                                             TRUE /* OpenAsSelf - for impersonation at SecurityIdentification level */,
    317                                             &hThreadToken))
     338                        /* Get user token. */
     339                        HANDLE hThreadToken = NULL;
     340                        hrc = CoImpersonateClient();
     341                        if (SUCCEEDED(hrc))
    318342                        {
    319                             HANDLE hNewToken;
    320                             if (DuplicateTokenEx(hThreadToken, MAXIMUM_ALLOWED, NULL /*SecurityAttribs*/,
    321                                                     SecurityIdentification, TokenPrimary, &hNewToken))
     343                            hrc = E_FAIL;
     344                            if (OpenThreadToken(GetCurrentThread(),
     345                                                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE
     346                                                | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE,
     347                                                TRUE /* OpenAsSelf - for impersonation at SecurityIdentification level */,
     348                                                &hThreadToken))
    322349                            {
    323                                 CloseHandle(hThreadToken);
    324                                 hThreadToken = hNewToken;
    325                                 hrc = S_OK;
     350                                HANDLE hNewToken;
     351                                if (DuplicateTokenEx(hThreadToken, MAXIMUM_ALLOWED, NULL /*SecurityAttribs*/,
     352                                                        SecurityIdentification, TokenPrimary, &hNewToken))
     353                                {
     354                                    CloseHandle(hThreadToken);
     355                                    hThreadToken = hNewToken;
     356                                    hrc = S_OK;
     357                                }
     358                                else
     359                                    LogRel(("registerVBoxSVC: DuplicateTokenEx failed: %ld\n", GetLastError()));
    326360                            }
    327361                            else
    328                                 LogRel(("registerVBoxSVC: DuplicateTokenEx failed: %ld\n", GetLastError()));
     362                                LogRel(("registerVBoxSVC: OpenThreadToken failed: %ld\n", GetLastError()));
     363
     364                            CoRevertToSelf();
    329365                        }
    330366                        else
    331                             LogRel(("registerVBoxSVC: OpenThreadToken failed: %ld\n", GetLastError()));
    332 
    333                         CoRevertToSelf();
    334                     }
    335                     else
    336                         LogRel(("registerVBoxSVC: CoImpersonateClient failed: %Rhrc\n", hrc));
    337 
    338                     /* check windows session */
    339                     DWORD dwSessionId = 0;
    340                     if (SUCCEEDED(hrc) && hThreadToken != NULL)
    341                     {
    342                         hrc = E_FAIL;
    343                         DWORD cbSessionId = sizeof(DWORD);
    344                         if (GetTokenInformation(hThreadToken, TokenSessionId, (LPVOID)&dwSessionId, cbSessionId, &cbSessionId))
     367                            LogRel(("registerVBoxSVC: CoImpersonateClient failed: %Rhrc\n", hrc));
     368
     369                        /* check windows session */
     370                        if (SUCCEEDED(hrc) && hThreadToken != NULL)
    345371                        {
    346                             if (cbSessionId == sizeof(DWORD))
    347                                 hrc = S_OK;
     372                            hrc = E_FAIL;
     373                            DWORD cbSessionId = sizeof(DWORD);
     374                            if (GetTokenInformation(hThreadToken, TokenSessionId, (LPVOID)&dwSessionId, cbSessionId, &cbSessionId))
     375                            {
     376                                if (cbSessionId == sizeof(DWORD))
     377                                    hrc = S_OK;
     378                                else
     379                                    LogRel(("registerVBoxSVC: GetTokenInformation return value has invalid size\n"));
     380                            }
    348381                            else
    349                                 LogRel(("registerVBoxSVC: GetTokenInformation return value has invalid size\n"));
     382                                LogRel(("registerVBoxSVC: GetTokenInformation failed: %ld\n", GetLastError()));
    350383                        }
    351                         else
    352                             LogRel(("registerVBoxSVC: GetTokenInformation failed: %ld\n", GetLastError()));
    353                     }
    354                     if (SUCCEEDED(hrc) && dwSessionId != 0)
    355                     {
    356                         /* if VBoxSVC in the Windows session 0 is not started or if it did not
    357                             * registered during a minute, start new one */
    358                         if (   pUserData->m_pidTheChosenOne == NIL_RTPROCESS
    359                             || GetTickCount() - pUserData->m_tickTheChosenOne > 60 * 1000)
     384                        /* Either the "VBoxSVC in windows session 0" feature is off or the request from VBoxSVC running
     385                         * in windows session 0. */
     386                        if (SUCCEEDED(hrc) && dwSessionId != 0)
    360387                        {
    361                             uint32_t uSessionId = 0;
    362                             if (SetTokenInformation(hThreadToken, TokenSessionId, &uSessionId, sizeof(uint32_t)))
     388                            /* if VBoxSVC in the Windows session 0 is not started or if it did not
     389                                * registered during a minute, start new one */
     390                            if (   pUserData->m_pidTheChosenOne == NIL_RTPROCESS
     391                                || GetTickCount() - pUserData->m_tickTheChosenOne > 60 * 1000)
    363392                            {
    364                                 /* start VBoxSVC process */
    365                                 /* Get the path to the executable directory w/ trailing slash: */
    366                                 char szPath[RTPATH_MAX];
    367                                 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
    368                                 AssertRCReturn(vrc, vrc);
    369                                 size_t cbBufLeft = RTPathEnsureTrailingSeparator(szPath, sizeof(szPath));
    370                                 AssertReturn(cbBufLeft > 0, VERR_FILENAME_TOO_LONG);
    371                                 char *pszNamePart = &szPath[cbBufLeft]; NOREF(pszNamePart);
    372                                 cbBufLeft = sizeof(szPath) - cbBufLeft;
    373                                 static const char s_szVirtualBox_exe[] = "VBoxSVC.exe";
    374                                 vrc = RTStrCopy(pszNamePart, cbBufLeft, s_szVirtualBox_exe);
    375                                 AssertRCReturn(vrc, vrc);
    376                                 const char *apszArgs[] =
     393                                uint32_t uSessionId = 0;
     394                                if (SetTokenInformation(hThreadToken, TokenSessionId, &uSessionId, sizeof(uint32_t)))
    377395                                {
    378                                     szPath,
    379                                     "--registervbox",
    380                                     NULL
    381                                 };
    382 
    383                                 RTPROCESS pid;
    384                                 vrc = RTProcCreateEx(szPath,
    385                                                      apszArgs,
    386                                                      RTENV_DEFAULT,
    387                                                      RTPROC_FLAGS_TOKEN_SUPPLIED,
    388                                                      NULL, NULL, NULL, NULL, NULL, &hThreadToken, &pid);
    389 
    390                                 if (RT_SUCCESS(vrc))
    391                                 {
    392                                     pUserData->m_pidTheChosenOne = pid;
    393                                     pUserData->m_tickTheChosenOne = GetTickCount();
    394                                     hrc = E_PENDING;
     396                                    /* start VBoxSVC process */
     397                                    /* Get the path to the executable directory w/ trailing slash: */
     398                                    char szPath[RTPATH_MAX];
     399                                    int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
     400                                    AssertRCReturn(vrc, vrc);
     401                                    size_t cbBufLeft = RTPathEnsureTrailingSeparator(szPath, sizeof(szPath));
     402                                    AssertReturn(cbBufLeft > 0, VERR_FILENAME_TOO_LONG);
     403                                    char *pszNamePart = &szPath[cbBufLeft]; NOREF(pszNamePart);
     404                                    cbBufLeft = sizeof(szPath) - cbBufLeft;
     405                                    static const char s_szVirtualBox_exe[] = "VBoxSVC.exe";
     406                                    vrc = RTStrCopy(pszNamePart, cbBufLeft, s_szVirtualBox_exe);
     407                                    AssertRCReturn(vrc, vrc);
     408                                    const char *apszArgs[] =
     409                                    {
     410                                        szPath,
     411                                        "--registervbox",
     412                                        NULL
     413                                    };
     414
     415                                    RTPROCESS pid;
     416                                    vrc = RTProcCreateEx(szPath,
     417                                                        apszArgs,
     418                                                        RTENV_DEFAULT,
     419                                                        RTPROC_FLAGS_TOKEN_SUPPLIED,
     420                                                        NULL, NULL, NULL, NULL, NULL, &hThreadToken, &pid);
     421
     422                                    if (RT_SUCCESS(vrc))
     423                                    {
     424                                        pUserData->m_pidTheChosenOne = pid;
     425                                        pUserData->m_tickTheChosenOne = GetTickCount();
     426                                        hrc = E_PENDING;
     427                                    }
     428                                    else
     429                                        LogRel(("registerVBoxSVC: Create VBoxSVC process failed: %Rrc\n", vrc));
    395430                                }
    396431                                else
    397                                     LogRel(("registerVBoxSVC: Create VBoxSVC process failed: %Rrc\n", vrc));
     432                                {
     433                                    hrc = E_FAIL;
     434                                    LogRel(("registerVBoxSVC: SetTokenInformation failed: %ld\n", GetLastError()));
     435                                }
    398436                            }
    399                             else
    400                             {
    401                                 hrc = E_FAIL;
    402                                 LogRel(("registerVBoxSVC: SetTokenInformation failed: %ld\n", GetLastError()));
    403                             }
     437                            else /* the VBoxSVC in Windows session 0 already started */
     438                                hrc = E_PENDING;
    404439                        }
    405                         else /* the VBoxSVC in Windows session 0 already started */
    406                             hrc = E_PENDING;
    407                     }
    408                     CloseHandle(hThreadToken);
     440                        CloseHandle(hThreadToken);
     441                    } /* Feature enabled */
    409442
    410443                    if (SUCCEEDED(hrc) && dwSessionId == 0)
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