VirtualBox

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


Ignore:
Timestamp:
Jul 20, 2012 2:42:40 PM (13 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

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

Legend:

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

    r42234 r42272  
    3535using namespace guestControl;
    3636#endif
    37 
    3837
    3938/** Maximum number of guest sessions a VM can have. */
     
    6160    ((uContextID) & 0xffff)
    6261
    63 
     62/** Vector holding a process' CPU affinity. */
    6463typedef std::vector <LONG> ProcessAffinity;
     64/** Vector holding process startup arguments. */
    6565typedef std::vector <Utf8Str> ProcessArguments;
    6666
     
    9494
    9595    Utf8Str GetMessage(void) { return mMessage; }
     96
     97    int GetResultCode(void) { return mRC; }
    9698
    9799    eVBoxGuestCtrlCallbackType GetType(void) { return mType; }
     
    107109    /** Was the callback canceled? */
    108110    bool                        fCanceled;
     111    /** Did the callback complete? */
     112    bool                        fCompleted;
    109113    /** Pointer to user-supplied data. */
    110114    void                       *pvData;
     
    124128 * Simple structure mantaining guest credentials.
    125129 */
    126 class GuestCredentials
    127 {
    128 public:
    129 
    130 
    131 public:
    132 
     130struct GuestCredentials
     131{
    133132    Utf8Str                     mUser;
    134133    Utf8Str                     mPassword;
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r42234 r42272  
    7171    int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID);
    7272    int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
    73     bool callbackExists(ULONG uContextID);
     73    inline bool callbackExists(ULONG uContextID);
    7474    bool isReady(void);
    7575    ULONG getPID(void) { return mData.mPID; }
     
    8181    int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData);
    8282    int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
    83     int startProcess(void);
     83    int signalWaiters(int rc, const Utf8Str strMessage = "");
     84    int startProcess(int *pRC = NULL, Utf8Str *pstrMessage = NULL);
    8485    static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser);
    8586    int terminateProcess(void);
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42214 r42272  
    126126    const GuestEnvironment &getEnvironment(void);
    127127    int                     processClose(ComObjPtr<GuestProcess> pProcess);
    128     int                     processCreateExInteral(GuestProcessInfo &aProcInfo, IGuestProcess **aProcess);
     128    int                     processCreateExInteral(const GuestProcessInfo &aProcInfo, IGuestProcess **aProcess);
    129129    inline bool             processExists(ULONG uProcessID, ComObjPtr<GuestProcess> *pProcess);
    130130    inline int              processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r42214 r42272  
    700700    AssertPtr(pHeader);
    701701
     702#ifdef DEBUG
     703    LogFlowFunc(("uSession=%RU32, uProcess=%RU32, uCount=%RU32\n",
     704                 VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHeader->u32ContextID),
     705                 VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(pHeader->u32ContextID),
     706                 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pHeader->u32ContextID)));
     707#endif
    702708    int rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms);
    703709
     
    26752681int Guest::dispatchToSession(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
    26762682{
     2683    LogFlowFuncEnter();
     2684
    26772685    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    26782686    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     
    26802688    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    26812689
     2690    int rc;
    26822691    GuestSessions::const_iterator itSession
    26832692        = mData.mGuestSessions.find(VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID));
     
    26882697
    26892698        alock.release();
    2690         return pSession->dispatchToProcess(uContextID, uFunction, pvData, cbData);
    2691     }
    2692     return VERR_NOT_FOUND;
     2699        rc = pSession->dispatchToProcess(uContextID, uFunction, pvData, cbData);
     2700    }
     2701    else
     2702        rc = VERR_NOT_FOUND;
     2703
     2704    LogFlowFuncLeaveRC(rc);
     2705    return rc;
    26932706}
    26942707
     
    27182731
    27192732    int rc = VERR_MAX_PROCS_REACHED;
     2733    if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS)
     2734        return rc;
     2735
    27202736    try
    27212737    {
     
    27262742        for (;;)
    27272743        {
    2728             /* Is the context ID already used?  Try next ID ... */
    2729             if (!sessionExists(++uNewSessionID))
     2744            /* Is the context ID already used? */
     2745            if (!sessionExists(uNewSessionID))
    27302746            {
    27312747                rc = VINF_SUCCESS;
    27322748                break;
    27332749            }
     2750            uNewSessionID++;
    27342751
    27352752            if (++uTries == UINT32_MAX)
     
    27632780inline bool Guest::sessionExists(uint32_t uSessionID)
    27642781{
    2765     AssertReturn(uSessionID, false);
    2766 
    27672782    GuestSessions::const_iterator itSessions = mData.mGuestSessions.find(uSessionID);
    27682783    return (itSessions == mData.mGuestSessions.end()) ? false : true;
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42234 r42272  
    3737      uFlags(0),
    3838      fCanceled(false),
     39      fCompleted(false),
    3940      pvData(NULL),
    4041      cbData(0),
     
    4748      uFlags(0),
    4849      fCanceled(false),
     50      fCompleted(false),
    4951      pvData(NULL),
    5052      cbData(0),
     
    6264int GuestCtrlCallback::Cancel(void)
    6365{
     66    if (ASMAtomicReadBool(&fCompleted))
     67        return VINF_SUCCESS;
    6468    if (!ASMAtomicReadBool(&fCanceled))
    6569    {
    66         int rc = RTSemEventSignal(hEventSem);
     70        int rc = hEventSem != NIL_RTSEMEVENT
     71               ? RTSemEventSignal(hEventSem) : VINF_SUCCESS;
    6772        if (RT_SUCCESS(rc))
    6873            ASMAtomicXchgBool(&fCanceled, true);
     
    128133void GuestCtrlCallback::Destroy(void)
    129134{
     135    int rc = Cancel();
     136    AssertRC(rc);
     137
    130138    mType = VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN;
    131139    if (pvData)
     
    152160    if (!uTimeoutMS)
    153161        msInterval = RT_INDEFINITE_WAIT;
    154     int rc = RTSemEventWait(hEventSem, msInterval);
    155     if (RT_SUCCESS(rc))
    156     {
    157         /* Assign overall callback result. */
    158         rc = mRC;
    159     }
    160 
    161     return rc;
     162    return RTSemEventWait(hEventSem, msInterval);
    162163}
    163164
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42237 r42272  
    6868HRESULT GuestProcess::FinalConstruct(void)
    6969{
    70     LogFlowThisFunc(("\n"));
     70    LogFlowFuncEnter();
    7171
    7272    mData.mExitCode = 0;
     
    8181    mData.mWaitEvent = NIL_RTSEMEVENT;
    8282
    83     return BaseFinalConstruct();
     83    HRESULT hr = BaseFinalConstruct();
     84    LogFlowFuncLeaveRC(hr);
     85    return hr;
    8486}
    8587
     
    108110    mData.mParent = aSession;
    109111    mData.mProcessID = aProcessID;
     112    mData.mProcess = aProcInfo;
     113
    110114    mData.mStatus = ProcessStatus_Starting;
    111115    /* Everything else will be set by the actual starting routine. */
     
    362366int GuestProcess::callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
    363367{
     368/*    LogFlowFunc(("uPID=%RU32, uContextID=%RU32, uFunction=%RU32, pvData=%p, cbData=%z\n",
     369                 mData.mPID, uContextID, uFunction, pvData, cbData));*/
     370
    364371    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    365372    AssertReturn(cbData, VERR_INVALID_PARAMETER);
    366373
    367     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    368 
     374    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     375
     376    int rc;
    369377    GuestCtrlCallbacks::const_iterator it
    370378        = mData.mCallbacks.find(VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID));
     
    373381        GuestCtrlCallback *pCallback = it->second;
    374382        AssertPtr(pCallback);
    375 
    376         int rc;
    377383
    378384        switch (uFunction)
     
    429435                break;
    430436        }
    431 
    432         return rc;
    433     }
    434 
    435     return VERR_NOT_FOUND;
    436 }
    437 
    438 bool GuestProcess::callbackExists(ULONG uContextID)
    439 {
    440     AssertReturn(uContextID, false);
    441 
     437    }
     438    else
     439        rc = VERR_NOT_FOUND;
     440
     441    //LogFlowFuncLeaveRC(rc);
     442    return rc;
     443}
     444
     445inline bool GuestProcess::callbackExists(ULONG uContextID)
     446{
    442447    GuestCtrlCallbacks::const_iterator it = mData.mCallbacks.find(uContextID);
    443448    return (it == mData.mCallbacks.end()) ? false : true;
     
    459464int GuestProcess::onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData)
    460465{
    461     LogFlowFunc(("uPID=%RU32, pCallback=%p, pData=%p", mData.mPID, pCallback, pData));
     466    LogFlowFunc(("uPID=%RU32, pCallback=%p, pData=%p\n", mData.mPID, pCallback, pData));
    462467
    463468    /* First, signal callback in every case. */
    464469    pCallback->Signal();
    465470
    466     Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
    467     int rc = RTSemEventSignal(mData.mWaitEvent);
     471    /* Signal in any case. */
     472    int rc = signalWaiters(VERR_CANCELLED, tr("The guest got disconnected"));
    468473    AssertRC(rc);
    469474
     
    486491    /* Then do the WaitFor signalling stuff. */
    487492    if (mData.mWaitFlags & ProcessWaitForFlag_StdIn)
    488     {
    489         Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
    490         rc = RTSemEventSignal(mData.mWaitEvent);
    491         AssertRC(rc);
    492     }
     493        rc = signalWaiters(VINF_SUCCESS);
    493494
    494495    LogFlowFuncLeaveRC(rc);
     
    504505
    505506    /* Get data from the callback payload. */
    506     mData.mStatus = (ProcessStatus_T)pData->u32Status;
    507507    if (mData.mPID)
    508508        Assert(mData.mPID == pData->u32PID);
    509509
    510     Utf8Str strCallbackMsg;
     510    Utf8Str callbackMsg;
     511    int callbackRC = VINF_SUCCESS;
     512
    511513    bool fSignal = false;
    512514    switch (pData->u32Status)
     
    515517            fSignal = (   (mData.mWaitFlags & ProcessWaitForFlag_Start)
    516518                       || (mData.mWaitFlags & ProcessWaitForFlag_Status));
     519
     520            mData.mStatus = ProcessStatus_Started;
    517521            mData.mPID = pData->u32PID;
    518522            mData.mStarted = true;
    519523
    520             rc = pCallback->Signal(VINF_SUCCESS,
    521                                    Utf8StrFmt(tr("Guest process \"%s\" was started (PID %RU32)"),
    522                                               mData.mProcess.mCommand.c_str(), mData.mPID));
     524            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" was started (PID %RU32)"),
     525                                     mData.mProcess.mCommand.c_str(), mData.mPID);
     526            LogRel((callbackMsg.c_str()));
    523527            break;
    524528
    525529        case PROC_STS_TEN:
    526530        {
    527             Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated normally (exit code: %RU32)"),
    528                                               pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags);
    529             LogRel((strErrDetail.c_str()));
    530             rc = pCallback->Signal(VINF_SUCCESS, strErrDetail);
     531            mData.mStatus = ProcessStatus_TerminatedNormally;
     532
     533            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated normally (exit code: %d)"),
     534                                     mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags);
     535            LogRel((callbackMsg.c_str()));
    531536            break;
    532537        }
     
    534539        case PROC_STS_TES:
    535540        {
    536             Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated through signal (exit code: %RU32)"),
    537                                               pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags);
    538             LogRel((strErrDetail.c_str()));
    539             rc = pCallback->Signal(VERR_GENERAL_FAILURE /** @todo */, strErrDetail);
     541            mData.mStatus = ProcessStatus_TerminatedSignal;
     542
     543            callbackRC = VERR_INTERRUPTED;
     544            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated through signal (exit code: %d)"),
     545                                     mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags);
     546            LogRel((callbackMsg.c_str()));
    540547            break;
    541548        }
     
    543550        case PROC_STS_TEA:
    544551        {
    545             Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated abnormally (exit code: %RU32)"),
    546                                               pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags);
    547             LogRel((strErrDetail.c_str()));
    548             rc = pCallback->Signal(VERR_BROKEN_PIPE, strErrDetail);
     552            mData.mStatus = ProcessStatus_TerminatedAbnormally;
     553
     554            callbackRC = VERR_BROKEN_PIPE;
     555            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) terminated abnormally (exit code: %d)"),
     556                                     mData.mProcess.mCommand.c_str(), mData.mPID, pData->u32Flags);
     557            LogRel((callbackMsg.c_str()));
    549558            break;
    550559        }
     
    552561        case PROC_STS_TOK:
    553562        {
    554             Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and was killed"),
    555                                               pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID);
    556             LogRel((strErrDetail.c_str()));
    557             rc = pCallback->Signal(VERR_TIMEOUT, strErrDetail);
     563            mData.mStatus = ProcessStatus_TimedOutKilled;
     564
     565            callbackRC = VERR_TIMEOUT;
     566            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and was killed"),
     567                                     mData.mProcess.mCommand.c_str(), mData.mPID);
     568            LogRel((callbackMsg.c_str()));
    558569            break;
    559570        }
     
    561572        case PROC_STS_TOA:
    562573        {
    563             Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and could not be killed\n"),
    564                                               pData->u32PID, mData.mProcess.mCommand.c_str(), mData.mPID);
    565             LogRel((strErrDetail.c_str()));
    566             rc = pCallback->Signal(VERR_TIMEOUT, strErrDetail);
     574            mData.mStatus = ProcessStatus_TimedOutAbnormally;
     575
     576            callbackRC = VERR_TIMEOUT;
     577            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) timed out and could not be killed\n"),
     578                                     mData.mProcess.mCommand.c_str(), mData.mPID);
     579            LogRel((callbackMsg.c_str()));
    567580            break;
    568581        }
     
    570583        case PROC_STS_DWN:
    571584        {
    572             Utf8Str strErrDetail = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) was killed because system is shutting down\n"),
    573                                               mData.mProcess.mCommand.c_str(), mData.mPID);
    574             LogRel((strErrDetail.c_str()));
     585            mData.mStatus = ProcessStatus_Down;
     586
    575587            /*
    576588             * If mFlags has CreateProcessFlag_IgnoreOrphanedProcesses set, we don't report an error to
     
    580592             * In this case mFlags contains the actual execution flags reached in via Guest::ExecuteProcess().
    581593             */
    582             rc = pCallback->Signal(  mData.mProcess.mFlags & ProcessCreateFlag_IgnoreOrphanedProcesses
    583                                    ? VINF_SUCCESS : VERR_CANCELLED, strErrDetail);
     594            callbackRC = mData.mProcess.mFlags & ProcessCreateFlag_IgnoreOrphanedProcesses
     595                       ? VINF_SUCCESS : VERR_OBJECT_DESTROYED;
     596            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %u) was killed because system is shutting down\n"),
     597                                     mData.mProcess.mCommand.c_str(), mData.mPID);
     598            LogRel((callbackMsg.c_str()));
    584599            break;
    585600        }
     
    587602        case PROC_STS_ERROR:
    588603        {
     604            mData.mStatus = ProcessStatus_Error;
     605
     606            callbackRC = pData->u32Flags;
     607            callbackMsg = Utf8StrFmt(tr("Guest process \"%s\" could not be started: ", mData.mProcess.mCommand.c_str()));
     608
    589609            /* Note: It's not required that the process
    590610             * has been started before. */
    591             Utf8Str strErrDetail;
    592611            if (pData->u32PID)
    593612            {
    594                 strErrDetail = Utf8StrFmt(tr("Guest process (PID %RU32) could not be started because of rc=%Rrc"),
    595                                           pData->u32PID, pData->u32Flags);
     613                callbackMsg += Utf8StrFmt(tr("Error rc=%Rrc occured"), pData->u32Flags);
    596614            }
    597615            else
    598616            {
    599                 switch (pData->u32Flags) /* u32Flags member contains the IPRT error code from guest side. */
     617                switch (callbackRC) /* callbackRC contains the IPRT error code from guest side. */
    600618                {
    601619                    case VERR_FILE_NOT_FOUND: /* This is the most likely error. */
    602                         strErrDetail = Utf8StrFmt(tr("The specified file was not found on guest"));
     620                        callbackMsg += Utf8StrFmt(tr("The specified file was not found on guest"));
    603621                        break;
    604622
    605623                    case VERR_PATH_NOT_FOUND:
    606                         strErrDetail = Utf8StrFmt(tr("Could not resolve path to specified file was not found on guest"));
     624                        callbackMsg += Utf8StrFmt(tr("Could not resolve path to specified file was not found on guest"));
    607625                        break;
    608626
    609627                    case VERR_BAD_EXE_FORMAT:
    610                         strErrDetail = Utf8StrFmt(tr("The specified file is not an executable format on guest"));
     628                        callbackMsg += Utf8StrFmt(tr("The specified file is not an executable format on guest"));
    611629                        break;
    612630
    613631                    case VERR_AUTHENTICATION_FAILURE:
    614                         strErrDetail = Utf8StrFmt(tr("The specified user was not able to logon on guest"));
     632                        callbackMsg += Utf8StrFmt(tr("The specified user was not able to logon on guest"));
    615633                        break;
    616634
    617635                    case VERR_TIMEOUT:
    618                         strErrDetail = Utf8StrFmt(tr("The guest did not respond within time"));
     636                        callbackMsg += Utf8StrFmt(tr("The guest did not respond within time"));
    619637                        break;
    620638
    621639                    case VERR_CANCELLED:
    622                         strErrDetail = Utf8StrFmt(tr("The execution operation was canceled"));
     640                        callbackMsg += Utf8StrFmt(tr("The execution operation was canceled"));
    623641                        break;
    624642
    625643                    case VERR_PERMISSION_DENIED:
    626                         strErrDetail = Utf8StrFmt(tr("Invalid user/password credentials"));
     644                        callbackMsg += Utf8StrFmt(tr("Invalid user/password credentials"));
    627645                        break;
    628646
    629647                    case VERR_MAX_PROCS_REACHED:
    630                         strErrDetail = Utf8StrFmt(tr("Guest process could not be started because maximum number of parallel guest processes has been reached"));
     648                        callbackMsg += Utf8StrFmt(tr("Maximum number of parallel guest processes has been reached"));
    631649                        break;
    632650
    633651                    default:
    634                         strErrDetail = Utf8StrFmt(tr("Guest process reported error %Rrc"),
    635                                                   pData->u32Flags);
     652                        callbackMsg += Utf8StrFmt(tr("Reported error %Rrc"), callbackRC);
    636653                        break;
    637654                }
    638 
    639                 Assert(!strErrDetail.isEmpty());
    640                 rc = pCallback->Signal(pData->u32Flags /* rc from guest. */, strErrDetail);
    641655            }
    642             fSignal = mData.mWaitFlags & ProcessWaitForFlag_Status;
     656
     657            LogRel((callbackMsg.c_str()));
    643658            break;
    644659        }
     
    646661        case PROC_STS_UNDEFINED:
    647662        default:
    648             rc = pCallback->Signal(VERR_NOT_SUPPORTED,
    649                                    Utf8StrFmt(tr("Got unsupported process status %RU32, skipping"), pData->u32Status));
     663
     664            /* Silently skip this request. */
    650665            fSignal = true; /* Signal in any case. */
    651666            break;
    652667    }
     668
     669    /*
     670     * Now do the signalling stuff.
     671     */
     672    rc = pCallback->Signal(callbackRC, callbackMsg);
    653673
    654674    if (!fSignal)
     
    656676    if (fSignal)
    657677    {
    658         Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
    659         int rc2 = RTSemEventSignal(mData.mWaitEvent);
     678        int rc2 = signalWaiters(callbackRC, callbackMsg);
    660679        if (RT_SUCCESS(rc))
    661680            rc = rc2;
     
    748767}
    749768
    750 int GuestProcess::startProcess(void)
    751 {
     769int GuestProcess::signalWaiters(int rc, const Utf8Str strMessage)
     770{
     771    LogFlowFunc(("rc=%Rrc, strMessage=%s, mWaiting=%RTbool, mWaitEvent=%p\n",
     772                 rc, strMessage.c_str(), mData.mWaiting, mData.mWaitEvent));
     773
     774    /* Note: No locking here -- already done in the callback dispatcher. */
     775
     776    /* We have to set the error information here because the waiters are public
     777     * Main clients which rely on it. */
     778    if (RT_FAILURE(rc))
     779    {
     780        HRESULT hr = setError(VBOX_E_IPRT_ERROR, strMessage.c_str());
     781        ComAssertRC(hr);
     782    }
     783
     784    int rc2 = VINF_SUCCESS;
     785    if (   mData.mWaiting
     786        && mData.mWaitEvent != NIL_RTSEMEVENT)
     787    {
     788        rc2 = RTSemEventSignal(mData.mWaitEvent);
     789        AssertRC(rc2);
     790    }
     791
     792    LogFlowFuncLeaveRC(rc2);
     793    return rc2;
     794}
     795
     796int GuestProcess::startProcess(int *pRC, Utf8Str *pstrMessage)
     797{
     798    /* Parameters are optional. */
     799
    752800    LogFlowFunc(("aCmd=%s, aTimeoutMS=%RU32, fFlags=%x\n",
    753801                 mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags));
     
    757805    int rc;
    758806    ULONG uContextID;
    759     GuestCtrlCallback *pCallbackStart = (GuestCtrlCallback *)RTMemAlloc(sizeof(GuestCtrlCallback));
     807    GuestCtrlCallback *pCallbackStart = new GuestCtrlCallback();
    760808    if (!pCallbackStart)
    761809        return VERR_NO_MEMORY;
     
    774822    if (RT_SUCCESS(rc))
    775823    {
    776         Assert(uContextID);
    777 
    778824        ComObjPtr<GuestSession> pSession(mData.mParent);
    779825        Assert(!pSession.isNull());
     
    844890             */
    845891            rc = pCallbackStart->Wait(mData.mProcess.mTimeoutMS);
    846         }
    847     }
    848 
    849     LogFlowFuncLeave();
     892            if (RT_SUCCESS(rc)) /* Wait was successful, check for supplied information. */
     893            {
     894                if (pRC)
     895                    *pRC = pCallbackStart->GetResultCode();
     896                if (pstrMessage)
     897                    *pstrMessage = pCallbackStart->GetMessage();
     898            }
     899        }
     900    }
     901
     902    if (pCallbackStart)
     903        delete pCallbackStart;
     904
     905    LogFlowFuncLeaveRC(rc);
    850906    return rc;
    851907}
     
    862918
    863919    int rc = pProcess->startProcess();
    864 
    865     LogFlowFuncLeave();
     920    AssertRC(rc);
     921
     922    LogFlowFuncLeaveRC(rc);
    866923    return rc;
    867924}
     
    879936int GuestProcess::waitFor(uint32_t fFlags, ULONG uTimeoutMS, ProcessWaitReason_T *penmReason)
    880937{
    881     LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p, mWaitEvent=%p\n",
    882                  fFlags, uTimeoutMS, penmReason, &mData.mWaitEvent));
    883 
    884938    Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
    885939
     
    887941        return VERR_ALREADY_EXISTS;
    888942
     943    /* At the moment we only support one waiter at a time. */
    889944    int rc = RTSemMutexRequest(mData.mWaitMutex, uTimeoutMS);
    890945    if (RT_SUCCESS(rc))
     
    902957    }
    903958
    904     LogFlowFuncLeaveRC(rc);
    905959    return rc;
    906960}
     
    9811035    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    9821036
    983     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    984 
     1037    /*
     1038     * Note: Do not hold any locks here while waiting!
     1039     */
    9851040    uint32_t fWaitFor = ProcessWaitForFlag_None;
    9861041    com::SafeArray<ProcessWaitForFlag_T> flags(ComSafeArrayInArg(aFlags));
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42214 r42272  
    6161
    6262    AssertPtrReturn(aGuest, VERR_INVALID_POINTER);
    63     AssertReturn(aSessionID, VERR_INVALID_PARAMETER);
    6463
    6564    /* Enclose the state transition NotReady->InInit->Ready. */
     
    6766    AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED);
    6867
     68    mData.mTimeout = 30 * 60 * 1000; /* Session timeout is 30 mins by default. */
    6969    mData.mParent = aGuest;
    7070    mData.mId = aSessionID;
     
    352352int GuestSession::dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
    353353{
     354    LogFlowFuncEnter();
     355
    354356    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    355357    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     
    357359    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    358360
     361    int rc;
    359362    SessionProcesses::const_iterator itProc
    360363        = mData.mProcesses.find(VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID));
     
    365368
    366369        alock.release();
    367         return pProcess->callbackDispatcher(uContextID, uFunction, pvData, cbData);
    368     }
    369     return VERR_NOT_FOUND;
     370        rc = pProcess->callbackDispatcher(uContextID, uFunction, pvData, cbData);
     371    }
     372    else
     373        rc = VERR_NOT_FOUND;
     374
     375    LogFlowFuncLeaveRC(rc);
     376    return rc;
    370377}
    371378
     
    414421}
    415422
    416 int GuestSession::processCreateExInteral(GuestProcessInfo &aProcInfo, IGuestProcess **aProcess)
    417 {
    418     AssertPtrReturn(aProcess, VERR_INVALID_POINTER);
    419 
     423int GuestSession::processCreateExInteral(const GuestProcessInfo &aProcInfo, IGuestProcess **aProcess)
     424{
    420425    /* Validate flags. */
    421426    if (aProcInfo.mFlags)
     
    430435    }
    431436
     437    GuestProcessInfo procInfo = aProcInfo;
     438
    432439    /* Adjust timeout. If set to 0, we define
    433440     * an infinite timeout. */
    434     if (aProcInfo.mTimeoutMS == 0)
    435         aProcInfo.mTimeoutMS = UINT32_MAX;
     441    if (procInfo.mTimeoutMS == 0)
     442        procInfo.mTimeoutMS = UINT32_MAX;
    436443
    437444    /** @tood Implement process priority + affinity. */
    438445
    439     int rc = VERR_MAX_THRDS_REACHED;
     446    int rc = VERR_MAX_PROCS_REACHED;
     447    if (mData.mProcesses.size() >= VBOX_GUESTCTRL_MAX_PROCESSES)
     448        return rc;
    440449
    441450    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    447456    for (;;)
    448457    {
    449         /* Is the context ID already used?  Try next ID ... */
    450         if (!processExists(uNewProcessID++, NULL /* pProgress */))
     458        /* Is the context ID already used? */
     459        if (!processExists(uNewProcessID, NULL /* pProgress */))
    451460        {
    452461            /* Callback with context ID was not found. This means
     
    456465            break;
    457466        }
     467        uNewProcessID++;
    458468
    459469        if (++uTries == UINT32_MAX)
     
    470480
    471481        rc = pGuestProcess->init(mData.mParent->getConsole() /* Console */, this /* Session */,
    472                                  uNewProcessID, aProcInfo);
     482                                 uNewProcessID, procInfo);
    473483        if (RT_FAILURE(rc)) throw rc;
    474484
     
    489499inline bool GuestSession::processExists(ULONG uProcessID, ComObjPtr<GuestProcess> *pProcess)
    490500{
    491     AssertReturn(uProcessID, false);
    492 
    493501    SessionProcesses::const_iterator it = mData.mProcesses.find(uProcessID);
    494502    if (it != mData.mProcesses.end())
     
    932940    com::SafeArray<LONG> affinity;
    933941
    934     return ProcessCreateEx(aCommand, ComSafeArrayInArg(aArguments), ComSafeArrayInArg(aEnvironment),
    935                            ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinity), aProcess);
     942    HRESULT hr = ProcessCreateEx(aCommand, ComSafeArrayInArg(aArguments), ComSafeArrayInArg(aEnvironment),
     943                                 ComSafeArrayInArg(aFlags), aTimeoutMS, ProcessPriority_Default, ComSafeArrayAsInParam(affinity), aProcess);
     944    LogFlowFuncLeaveRC(hr);
     945    return hr;
    936946#endif /* VBOX_WITH_GUEST_CONTROL */
    937947}
     
    957967
    958968    procInfo.mCommand = Utf8Str(aCommand);
    959 
    960     com::SafeArray<IN_BSTR> arguments(ComSafeArrayInArg(aArguments));
    961     procInfo.mArguments.reserve(arguments.size());
    962     for (size_t i = 0; i < arguments.size(); i++)
    963         procInfo.mArguments[i] = Utf8Str(Bstr(arguments[i]));
     969    procInfo.mFlags = ProcessCreateFlag_None;
     970
     971    if (aArguments)
     972    {
     973        com::SafeArray<IN_BSTR> arguments(ComSafeArrayInArg(aArguments));
     974        procInfo.mArguments.reserve(arguments.size());
     975        for (size_t i = 0; i < arguments.size(); i++)
     976            procInfo.mArguments[i] = Utf8Str(Bstr(arguments[i]));
     977    }
    964978
    965979    int rc = VINF_SUCCESS;
    966980
    967     /* Create the process environment:
     981    /*
     982     * Create the process environment:
    968983     * - Apply the session environment in a first step, and
    969984     * - Apply environment variables specified by this call to
    970985     *   have the chance of overwriting/deleting session entries.
    971986     */
    972     procInfo.mEnvironment = mData.mEnvironment;
    973     com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aEnvironment));
    974     for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++)
    975         rc = mData.mEnvironment.Set(Utf8Str(environment[i]));
     987    procInfo.mEnvironment = mData.mEnvironment; /* Apply original session environment. */
     988    if (aEnvironment) /* Apply/overwrite environment, if set. */
     989    {
     990        com::SafeArray<IN_BSTR> environment(ComSafeArrayInArg(aEnvironment));
     991        for (size_t i = 0; i < environment.size() && RT_SUCCESS(rc); i++)
     992            rc = mData.mEnvironment.Set(Utf8Str(environment[i]));
     993    }
    976994
    977995    if (RT_SUCCESS(rc))
    978996    {
    979         com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags));
    980         for (size_t i = 0; i < flags.size(); i++)
    981             procInfo.mFlags |= flags[i];
     997        if (aFlags)
     998        {
     999            com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags));
     1000            for (size_t i = 0; i < flags.size(); i++)
     1001                procInfo.mFlags |= flags[i];
     1002        }
    9821003
    9831004        procInfo.mTimeoutMS = aTimeoutMS;
    9841005
    985         com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity));
    986         procInfo.mAffinity.reserve(affinity.size());
    987         for (size_t i = 0; i < affinity.size(); i++)
    988             procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */
     1006        if (aAffinity)
     1007        {
     1008            com::SafeArray<LONG> affinity(ComSafeArrayInArg(aAffinity));
     1009            procInfo.mAffinity.reserve(affinity.size());
     1010            for (size_t i = 0; i < affinity.size(); i++)
     1011                procInfo.mAffinity[i] = affinity[i]; /** @todo Really necessary? Later. */
     1012        }
    9891013
    9901014        procInfo.mPriority = aPriority;
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