VirtualBox

Changeset 95274 in vbox


Ignore:
Timestamp:
Jun 14, 2022 10:48:33 AM (2 years ago)
Author:
vboxsync
Message:

FE/VBoxAutostart/adi: Added experimental support for running VBoxSVC session 0 (service session). Did some minor cleanup for the patch posted at comment 95. Disabled by default for now. bugref:9341

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Config.kmk

    r95270 r95274  
    779779VBOX_WITH_SECURELABEL = 1
    780780endif
     781# Start VBoxSVC in windows session 0 (services session).
     782VBOX_WITH_VBOXSVC_SESSION_0 =
    781783# The headless frontend.
    782784VBOX_WITH_HEADLESS = 1
  • trunk/include/iprt/process.h

    r93115 r95274  
    230230/** For use with RTPROC_FLAGS_SERVICE to specify a desired session ID
    231231 * (Windows only, ignored elsewhere).  The @a pvExtraData argument points to
    232  * a uint32_t containing the session ID, UINT32_MAX means any session. */
     232 * a uint32_t containing the session ID, UINT32_MAX means any session.
     233 * Can not be set with RTPROC_FLAGS_TOKEN_SUPPLIED */
    233234#define RTPROC_FLAGS_DESIRED_SESSION_ID     RT_BIT(11)
    234235/** This is a modifier to RTPROC_FLAGS_PROFILE on unix systems that makes it
     
    238239 * This is ignored on Windows as it is using UTF-16. */
    239240#define RTPROC_FLAGS_UTF8_ARGV              RT_BIT_32(13)
     241/** Create process using supplied token. The @a pvExtraData argument points to
     242 * a HANDLE containing the token used as user credentials for process creation.
     243 * Can not be set with RTPROC_FLAGS_DESIRED_SESSION_ID.
     244 * Windows only flag, ignored everywhere else. */
     245#define RTPROC_FLAGS_TOKEN_SUPPLIED         RT_BIT(14)
     246
    240247/** Valid flag mask. */
    241 #define RTPROC_FLAGS_VALID_MASK             UINT32_C(0x3fff)
     248#define RTPROC_FLAGS_VALID_MASK             UINT32_C(0x7fff)
    242249/** @}  */
    243250
  • trunk/src/VBox/Main/Makefile.kmk

    r94793 r95274  
    458458 ifdef VBOX_WITH_QTGUI
    459459VBoxSDS_DEFS += VBOX_WITH_QTGUI
     460 endif
     461 ifdef VBOX_WITH_VBOXSVC_SESSION_0
     462VBoxSDS_DEFS += VBOX_WITH_VBOXSVC_SESSION_0
    460463 endif
    461464VBoxSDS_INCS  = \
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r94981 r95274  
    2987029870
    2987129871      <method name="registerVBoxSVC">
    29872         <desc>Registers a VBoxSVC instance with the SDS.</desc>
     29872        <desc>
     29873          Registers a VBoxSVC instance with VBoxSDS. If the caller is not running
     29874          in a Windows 0 session, the method attempts to run VBoxSVC in that
     29875          session.
     29876          <result name="E_PENDING">
     29877            The caller is not running in a Windows session 0 and no VBoxSVC
     29878            is registered. VBoxSVC registration begins in Windows session 0.
     29879            You should call this method again later.
     29880          </result>
     29881        </desc>
    2987329882        <param name="vboxSVC" type="IVBoxSVCRegistration" dir="in">
    2987429883          <desc>Interface implemented by the VirtualBox class factory.</desc>
  • trunk/src/VBox/Main/src-global/win/VirtualBoxSDSImpl.cpp

    r93115 r95274  
    2222#define LOG_GROUP LOG_GROUP_MAIN_VIRTUALBOXSDS
    2323#include <VBox/com/VirtualBox.h>
     24#include <VBox/com/utils.h>
    2425#include "VirtualBoxSDSImpl.h"
    2526
     
    3132#include <iprt/asm.h>
    3233#include <iprt/critsect.h>
     34#include <iprt/env.h>
     35#include <iprt/err.h>
    3336#include <iprt/mem.h>
     37#include <iprt/path.h>
    3438#include <iprt/process.h>
    3539#include <iprt/system.h>
     
    7175    /** The PID of the chosen one. */
    7276    RTPROCESS                       m_pidTheChosenOne;
     77    /** The tick count when the process in Windows session 0 started */
     78    uint32_t                        m_tickTheChosenOne;
    7379    /** The current watcher thread index, UINT32_MAX if not watched. */
    7480    uint32_t                        m_iWatcher;
     
    8995        , m_strUsername(a_rStrUsername)
    9096        , m_pidTheChosenOne(NIL_RTPROCESS)
     97        , m_tickTheChosenOne(0)
    9198#ifdef WITH_WATCHER
    9299        , m_iWatcher(UINT32_MAX)
     
    146153        }
    147154        m_pidTheChosenOne = NIL_RTPROCESS;
     155        m_tickTheChosenOne = 0;
    148156    }
    149157
     
    250258    {
    251259        *aExistingVirtualBox = NULL;
    252 
    253260        /*
    254261         * Get the client user SID and name.
     
    263270                /*
    264271                 * If there already is a chosen one, ask it for a IVirtualBox instance
    265                  * to return to the caller.  Should it be dead or unresponsive, the caller
     272                 * to return to the caller. Should it be dead or unresponsive, the caller
    266273                 * takes its place.
    267                  */
     274                */
    268275                if (pUserData->m_ptrTheChosenOne.isNotNull())
    269276                {
     
    271278                    {
    272279                        hrc = pUserData->m_ptrTheChosenOne->GetVirtualBox(aExistingVirtualBox);
     280                        /* seems the VBoxSVC in windows session 0 is not yet finished object creation.
     281                         * Give it a time. */
     282                        if (FAILED(hrc) && GetTickCount() - pUserData->m_tickTheChosenOne < 60 * 1000)
     283                            hrc = E_PENDING;
    273284                    }
    274285                    catch (...)
     
    284295#endif
    285296                        pUserData->i_unchooseTheOne(true /*fIrregular*/);
     297                        hrc = S_OK;
    286298                    }
    287299                }
     
    289301                    hrc = S_OK;
    290302
    291                 /*
    292                  * No chosen one?  Make the caller the new chosen one!
    293                  */
    294                 if (pUserData->m_ptrTheChosenOne.isNull())
     303                /* No chosen one?  Make the caller the new chosen one! */
     304                if (SUCCEEDED(hrc) && pUserData->m_ptrTheChosenOne.isNull())
    295305                {
    296                     LogRel(("registerVBoxSVC: Making aPid=%u (%#x) the chosen one for user %s (%s)!\n",
    297                             aPid, aPid, pUserData->m_strUserSid.c_str(), pUserData->m_strUsername.c_str()));
     306#ifdef VBOX_WITH_VBOXSVC_SESSION_0
     307                    /* Get user token. */
     308                    HANDLE hThreadToken = NULL;
     309                    hrc = CoImpersonateClient();
     310                    if (SUCCEEDED(hrc))
     311                    {
     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))
     318                        {
     319                            HANDLE hNewToken;
     320                            if (DuplicateTokenEx(hThreadToken, MAXIMUM_ALLOWED, NULL /*SecurityAttribs*/,
     321                                                    SecurityIdentification, TokenPrimary, &hNewToken))
     322                            {
     323                                CloseHandle(hThreadToken);
     324                                hThreadToken = hNewToken;
     325                                hrc = S_OK;
     326                            }
     327                            else
     328                                LogRel(("registerVBoxSVC: DuplicateTokenEx failed: %ld\n", GetLastError()));
     329                        }
     330                        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))
     345                        {
     346                            if (cbSessionId == sizeof(DWORD))
     347                                hrc = S_OK;
     348                            else
     349                                LogRel(("registerVBoxSVC: GetTokenInformation return value has invalid size\n"));
     350                        }
     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)
     360                        {
     361                            uint32_t uSessionId = 0;
     362                            if (SetTokenInformation(hThreadToken, TokenSessionId, &uSessionId, sizeof(uint32_t)))
     363                            {
     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[] =
     377                                {
     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;
     395                                }
     396                                else
     397                                    LogRel(("registerVBoxSVC: Create VBoxSVC process failed: %Rrc\n", vrc));
     398                            }
     399                            else
     400                            {
     401                                hrc = E_FAIL;
     402                                LogRel(("registerVBoxSVC: SetTokenInformation failed: %ld\n", GetLastError()));
     403                            }
     404                        }
     405                        else /* the VBoxSVC in Windows session 0 already started */
     406                            hrc = E_PENDING;
     407                    }
     408                    CloseHandle(hThreadToken);
     409
     410                    if (SUCCEEDED(hrc) && dwSessionId == 0)
     411                    {
     412#endif
     413                        LogRel(("registerVBoxSVC: Making aPid=%u (%#x) the chosen one for user %s (%s)!\n",
     414                                aPid, aPid, pUserData->m_strUserSid.c_str(), pUserData->m_strUsername.c_str()));
    298415#ifdef WITH_WATCHER
    299                     /* Open the process so we can watch it. */
    300                     HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE /*fInherit*/, aPid);
    301                     if (hProcess == NULL)
    302                         hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE /*fInherit*/, aPid);
    303                     if (hProcess == NULL)
    304                         hProcess = OpenProcess(SYNCHRONIZE, FALSE /*fInherit*/, aPid);
    305                     if (hProcess != NULL)
    306                     {
    307                         if (i_watchIt(pUserData, hProcess, aPid))
     416                        /* Open the process so we can watch it. */
     417                        HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE /*fInherit*/, aPid);
     418                        if (hProcess == NULL)
     419                            hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE /*fInherit*/, aPid);
     420                        if (hProcess == NULL)
     421                            hProcess = OpenProcess(SYNCHRONIZE, FALSE /*fInherit*/, aPid);
     422                        if (hProcess != NULL)
     423                        {
     424                            if (i_watchIt(pUserData, hProcess, aPid))
    308425#endif
    309                         {
    310                             /* Make it official... */
    311                             pUserData->m_ptrTheChosenOne = aVBoxSVC;
    312                             pUserData->m_pidTheChosenOne = aPid;
    313                             hrc = S_OK;
     426                            {
     427                                /* Make it official... */
     428                                pUserData->m_ptrTheChosenOne = aVBoxSVC;
     429                                pUserData->m_pidTheChosenOne = aPid;
     430                                hrc = S_OK;
     431                            }
     432#ifdef WITH_WATCHER
     433                            else
     434                            {
     435
     436                                LogRel(("registerVBoxSVC: i_watchIt failed!\n"));
     437                                hrc = RPC_E_OUT_OF_RESOURCES;
     438                            }
    314439                        }
    315 #ifdef WITH_WATCHER
    316440                        else
    317441                        {
    318 
    319                             LogRel(("registerVBoxSVC: i_watchIt failed!\n"));
    320                             hrc = RPC_E_OUT_OF_RESOURCES;
     442                            LogRel(("registerVBoxSVC: OpenProcess() failed: %ld\n", GetLastError()));
     443                            hrc = E_ACCESSDENIED;
    321444                        }
    322                     }
    323                     else
    324                     {
    325                         LogRel(("registerVBoxSVC: OpenProcess failed: %u\n", GetLastError()));
    326                         hrc = E_ACCESSDENIED;
     445#endif
     446#ifdef VBOX_WITH_VBOXSVC_SESSION_0
    327447                    }
    328448#endif
    329449                }
    330 
    331450                pUserData->i_unlock();
    332451                pUserData->i_release();
     
    474593    a_pStrUsername->setNull();
    475594
    476     CoInitializeEx(NULL, COINIT_MULTITHREADED); // is this necessary?
    477595    HRESULT hrc = CoImpersonateClient();
    478596    if (SUCCEEDED(hrc))
     
    555673    else
    556674        LogRel(("i_GetClientUserSID: CoImpersonateClient failed: %Rhrc\n", hrc));
    557     CoUninitialize();
    558675    return fRet;
    559676}
  • trunk/src/VBox/Main/src-server/win/svcmain.cpp

    r95120 r95274  
    333333    if (SUCCEEDED(hrc))
    334334    {
    335         /*
    336          * Create VBoxSVCRegistration object and hand that to VBoxSDS.
    337          */
    338         m_pVBoxSVC = new VBoxSVCRegistration(this);
    339         hrc = m_ptrVirtualBoxSDS->RegisterVBoxSVC(m_pVBoxSVC, GetCurrentProcessId(), ppOtherVirtualBox);
     335        /* By default the RPC_C_IMP_LEVEL_IDENTIFY is used for impersonation the client. It allows
     336           ACL checking but restricts an access to system objects e.g. files. Call to CoSetProxyBlanket
     337           elevates the impersonation level up to RPC_C_IMP_LEVEL_IMPERSONATE allowing the VBoxSDS
     338           service to access the files. */
     339        hrc = CoSetProxyBlanket(m_ptrVirtualBoxSDS,
     340                                RPC_C_AUTHN_DEFAULT,
     341                                RPC_C_AUTHZ_DEFAULT,
     342                                COLE_DEFAULT_PRINCIPAL,
     343                                RPC_C_AUTHN_LEVEL_DEFAULT,
     344                                RPC_C_IMP_LEVEL_IMPERSONATE,
     345                                NULL,
     346                                EOAC_DEFAULT);
    340347        if (SUCCEEDED(hrc))
    341348        {
    342             g_fRegisteredWithVBoxSDS = !*ppOtherVirtualBox;
    343             return hrc;
    344         }
    345         m_pVBoxSVC->Release();
     349            /*
     350             * Create VBoxSVCRegistration object and hand that to VBoxSDS.
     351             */
     352            m_pVBoxSVC = new VBoxSVCRegistration(this);
     353            hrc = E_PENDING;
     354            /* we try to register IVirtualBox 10 times */
     355            for (int regTimes = 0; hrc == E_PENDING && regTimes < 10;  --regTimes)
     356            {
     357                hrc = m_ptrVirtualBoxSDS->RegisterVBoxSVC(m_pVBoxSVC, GetCurrentProcessId(), ppOtherVirtualBox);
     358                if (SUCCEEDED(hrc))
     359                {
     360                    g_fRegisteredWithVBoxSDS = !*ppOtherVirtualBox;
     361                    return hrc;
     362                }
     363                /* sleep to give a time for windows session 0 registration */
     364                if (hrc == E_PENDING)
     365                    RTThreadSleep(1000);
     366            }
     367            m_pVBoxSVC->Release();
     368        }
    346369    }
    347370    m_ptrVirtualBoxSDS.setNull();
     
    687710            break;
    688711        }
    689 
    690712        case WM_DESTROY:
    691713        {
     
    823845{
    824846    /* never called, just need to be here */
     847}
     848
     849
     850/* thread for registering the VBoxSVC started in session 0 */
     851static DWORD WINAPI threadRegisterVirtualBox(LPVOID lpParam) throw()
     852{
     853    HANDLE hEvent = (HANDLE)lpParam;
     854    HRESULT hrc = CoInitializeEx(NULL, COINIT_MULTITHREADED);
     855    if (SUCCEEDED(hrc))
     856    {
     857        /* create IVirtualBox instance */
     858        ComPtr<IVirtualBox> pVirtualBox;
     859        hrc = CoCreateInstance(CLSID_VirtualBox, NULL, CLSCTX_INPROC_SERVER /*CLSCTX_LOCAL_SERVER */, IID_IVirtualBox,
     860                               (void **)pVirtualBox.asOutParam());
     861        if (SUCCEEDED(hrc))
     862        {
     863            /* wait a minute allowing clients to connect to the instance */
     864            WaitForSingleObject(hEvent, 60 * 1000);
     865            /* remove reference. If anybody connected to IVirtualBox it will stay alive. */
     866            pVirtualBox.setNull();
     867        }
     868        CoUninitialize();
     869    }
     870    return 0L;
    825871}
    826872
     
    891937        { "-loginterval",   'I',    RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
    892938        { "/loginterval",   'I',    RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE },
     939        { "--registervbox", 'b',    RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
     940        { "-registervbox",  'b',    RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
     941        { "/registervbox",  'b',    RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE },
    893942    };
    894943
     
    901950    uint32_t        uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file
    902951    uint64_t        uHistoryFileSize = 100 * _1M;   // max 100MB per file
     952    bool            fRegisterVBox = false;
    903953
    904954    RTGETOPTSTATE   GetOptState;
     
    9811031            }
    9821032
     1033            case 'b':
     1034                fRegisterVBox = true;
     1035                break;
     1036
    9831037            default:
    9841038                /** @todo this assumes that stderr is visible, which is not
     
    11011155            Log(("SVCMain: Failed to create main window\n"));
    11021156
     1157        /* create thread to register IVirtualBox in VBoxSDS
     1158         * It is used for starting the VBoxSVC in the windows
     1159         * session 0. */
     1160        HANDLE hWaitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
     1161        HANDLE hRegisterVBoxThread = NULL;
     1162        if (fRegisterVBox)
     1163        {
     1164            DWORD  dwThreadId = 0;
     1165            hRegisterVBoxThread = CreateThread(NULL, 0, threadRegisterVirtualBox, (LPVOID)hWaitEvent,
     1166                                               0, &dwThreadId);
     1167        }
     1168
    11031169        MSG msg;
    11041170        while (GetMessage(&msg, 0, 0, 0) > 0)
     
    11091175
    11101176        DestroyMainWindow();
     1177
     1178        if (fRegisterVBox)
     1179        {
     1180            SetEvent(hWaitEvent);
     1181            WaitForSingleObject(hRegisterVBoxThread, INFINITE);
     1182            CloseHandle(hRegisterVBoxThread);
     1183            CloseHandle(hWaitEvent);
     1184        }
    11111185
    11121186        g_pModule->RevokeClassObjects();
  • trunk/src/VBox/Runtime/r3/win/process-win.cpp

    r93115 r95274  
    16121612                                  RTENV hEnv, DWORD dwCreationFlags,
    16131613                                  STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo,
    1614                                   uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession)
     1614                                  uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession,
     1615                                  HANDLE hUserToken)
    16151616{
    16161617    /*
     
    16421643    DWORD   dwErr       = NO_ERROR;
    16431644    HANDLE  hTokenLogon = INVALID_HANDLE_VALUE;
    1644     int rc;
    1645     if (fFlags & RTPROC_FLAGS_AS_IMPERSONATED_TOKEN)
     1645    int rc = VINF_SUCCESS;
     1646    if (fFlags & RTPROC_FLAGS_TOKEN_SUPPLIED)
     1647        hTokenLogon = hUserToken;
     1648    else if (fFlags & RTPROC_FLAGS_AS_IMPERSONATED_TOKEN)
    16461649        rc = rtProcWinGetThreadTokenHandle(GetCurrentThread(), &hTokenLogon);
    16471650    else if (pwszUser == NULL)
     
    18501853        if (hTokenUserDesktop != INVALID_HANDLE_VALUE)
    18511854            CloseHandle(hTokenUserDesktop);
    1852         if (hTokenLogon != INVALID_HANDLE_VALUE)
     1855        if (   !(fFlags & RTPROC_FLAGS_TOKEN_SUPPLIED)
     1856            && hTokenLogon != INVALID_HANDLE_VALUE)
    18531857            CloseHandle(hTokenLogon);
    18541858
     
    20882092                                 RTENV hEnv, DWORD dwCreationFlags,
    20892093                                 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo,
    2090                                  uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession)
     2094                                 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession,
     2095                                 HANDLE hUserToken)
    20912096{
    20922097    /*
     
    20962101     * Note! This method is very slow on W2K.
    20972102     */
    2098     if (!(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN)))
     2103    if (!(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_TOKEN_SUPPLIED)))
    20992104    {
    21002105        AssertPtr(pwszUser);
     
    21042109            return rc;
    21052110    }
    2106     return rtProcWinCreateAsUser2(pwszUser, pwszPassword, ppwszExec, pwszCmdLine,
    2107                                   hEnv, dwCreationFlags, pStartupInfo, pProcInfo, fFlags, pszExec, idDesiredSession);
     2111    return rtProcWinCreateAsUser2(pwszUser, pwszPassword, ppwszExec, pwszCmdLine, hEnv, dwCreationFlags,
     2112                                  pStartupInfo, pProcInfo, fFlags, pszExec, idDesiredSession, hUserToken);
    21082113}
    21092114
     
    22822287        AssertReturn(!(fFlags & RTPROC_FLAGS_DESIRED_SESSION_ID), VERR_INVALID_FLAGS);
    22832288
     2289    HANDLE hUserToken = NULL;
     2290    if (fFlags & RTPROC_FLAGS_TOKEN_SUPPLIED)
     2291        hUserToken = *(HANDLE *)pvExtraData;
     2292
    22842293    /*
    22852294     * Initialize the globals.
     
    22872296    int rc = RTOnce(&g_rtProcWinInitOnce, rtProcWinInitOnce, NULL);
    22882297    AssertRCReturn(rc, rc);
    2289     if (pszAsUser || (fFlags & (RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN)))
     2298    if (   pszAsUser
     2299        || (fFlags & (RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN
     2300                      | RTPROC_FLAGS_TOKEN_SUPPLIED)))
    22902301    {
    22912302        rc = RTOnce(&g_rtProcWinResolveOnce, rtProcWinResolveOnce, NULL);
     
    24452456             */
    24462457            if (   pszAsUser == NULL
    2447                 && !(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN)))
     2458                && !(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_TOKEN_SUPPLIED)))
    24482459            {
    24492460                /* Create the environment block first. */
     
    24832494                    if (RT_SUCCESS(rc))
    24842495                    {
    2485                         rc = rtProcWinCreateAsUser(pwszUser, pwszPassword,
    2486                                                    &pwszExec, pwszCmdLine, hEnv, dwCreationFlags,
    2487                                                    &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession);
     2496                        rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, &pwszExec, pwszCmdLine, hEnv, dwCreationFlags,
     2497                                                   &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession,
     2498                                                   hUserToken);
    24882499
    24892500                        if (pwszPassword && *pwszPassword)
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