VirtualBox

Changeset 42234 in vbox


Ignore:
Timestamp:
Jul 19, 2012 4:43:43 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
79270
Message:

Guest Control 2.0: Update.

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

Legend:

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

    r42214 r42234  
    9191    void Destroy(void);
    9292
    93     eVBoxGuestCtrlCallbackType Type(void);
     93    int Signal(int rc = VINF_SUCCESS, const Utf8Str &strMsg = "");
     94
     95    Utf8Str GetMessage(void) { return mMessage; }
     96
     97    eVBoxGuestCtrlCallbackType GetType(void) { return mType; }
    9498
    9599    int Wait(ULONG uTimeoutMS);
     
    109113    /** The event semaphore triggering the*/
    110114    RTSEMEVENT                  hEventSem;
    111     /** Extended error information, if any. */
    112     ErrorInfo                   mErrorInfo;
     115    /** Overall result code. */
     116    int                         mRC;
     117    /** Error / information message to the
     118     *  result code. */
     119    Utf8Str                     mMessage;
    113120};
    114121typedef std::map < uint32_t, GuestCtrlCallback* > GuestCtrlCallbacks;
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r42216 r42234  
    7474    bool isReady(void);
    7575    ULONG getPID(void) { return mData.mPID; }
    76     int onGuestDisconnected(void);
    77     int onProcessInputStatus(uint32_t uStatus, uint32_t uFlags, uint32_t cbDataProcessed);
    78     int onProcessStatusChange(uint32_t uStatus, uint32_t uFlags, uint32_t uPID);
    79     int onProcessOutput(uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData);
     76    int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData);
     77    int onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData);
     78    int onProcessStatusChange(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECSTATUS pData);
     79    int onProcessOutput(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECOUT pData);
    8080    int prepareExecuteEnv(const char *pszEnv, void **ppvList, ULONG *pcbList, ULONG *pcEnvVars);
    8181    int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData);
     82    int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
    8283    int startProcess(void);
    8384    static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser);
     
    105106        ULONG                    mPID;
    106107        /** Internal, host-side process ID. */
    107         ULONG                 mProcessID;
     108        ULONG                    mProcessID;
    108109        /** The current process status. */
    109110        ProcessStatus_T          mStatus;
     
    112113        /** The next upcoming context ID. */
    113114        ULONG                    mNextContextID;
     115        /** Flag indicating someone is waiting for an event. */
     116        bool                     mWaiting;
     117        /** The waiting mutex. */
     118        RTSEMMUTEX               mWaitMutex;
     119        /** The waiting flag(s). */
     120        uint32_t                 mWaitFlags;
    114121        /** The waiting event. */
    115         RTSEMEVENT               mEvent;
     122        RTSEMEVENT               mWaitEvent;
    116123    } mData;
    117124};
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42214 r42234  
    139139}
    140140
    141 eVBoxGuestCtrlCallbackType GuestCtrlCallback::Type(void)
    142 {
    143     return mType;
     141int GuestCtrlCallback::Signal(int rc /*= VINF_SUCCESS*/, const Utf8Str &strMsg /*= "" */)
     142{
     143    AssertReturn(hEventSem != NIL_RTSEMEVENT, VERR_CANCELLED);
     144    return RTSemEventSignal(hEventSem);
    144145}
    145146
    146147int GuestCtrlCallback::Wait(ULONG uTimeoutMS)
    147148{
    148     Assert(hEventSem != NIL_RTSEMEVENT);
     149    AssertReturn(hEventSem != NIL_RTSEMEVENT, VERR_CANCELLED);
    149150
    150151    RTMSINTERVAL msInterval = uTimeoutMS;
    151152    if (!uTimeoutMS)
    152153        msInterval = RT_INDEFINITE_WAIT;
    153     return RTSemEventWait(hEventSem, msInterval);
     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;
    154162}
    155163
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42216 r42234  
    7676    mData.mStatus = ProcessStatus_Undefined;
    7777    mData.mStarted = false;
     78    mData.mWaiting = false;
     79    mData.mWaitFlags = 0;
     80    mData.mWaitMutex = NIL_RTSEMMUTEX;
     81    mData.mWaitEvent = NIL_RTSEMEVENT;
    7882
    7983    return BaseFinalConstruct();
     
    103107    mData.mConsole = aConsole;
    104108    mData.mParent = aSession;
    105     mData.mPID = 0; /* Will be assigned by the guest OS later. */
    106109    mData.mProcessID = aProcessID;
    107110    mData.mStatus = ProcessStatus_Starting;
    108111    /* Everything else will be set by the actual starting routine. */
     112
     113    int rc = RTSemEventCreate(&mData.mWaitEvent);
     114    if (RT_FAILURE(rc))
     115        return rc;
     116
     117    rc = RTSemMutexCreate(&mData.mWaitMutex);
     118    if (RT_FAILURE(rc))
     119        return rc;
    109120
    110121    /* Asynchronously start the process on the guest by kicking off a
     
    113124    AssertReturn(pTask->isOk(), pTask->rc());
    114125
    115     int rc = RTThreadCreate(NULL, GuestProcess::startProcessThread,
    116                             (void *)pTask.get(), 0,
    117                             RTTHREADTYPE_MAIN_WORKER, 0,
    118                             "gctlPrcStart");
     126    rc = RTThreadCreate(NULL, GuestProcess::startProcessThread,
     127                        (void *)pTask.get(), 0,
     128                        RTTHREADTYPE_MAIN_WORKER, 0,
     129                        "gctlPrcStart");
    119130    if (RT_SUCCESS(rc))
    120131    {
     
    141152    if (autoUninitSpan.uninitDone())
    142153        return;
     154
     155    int rc = RTSemEventDestroy(mData.mWaitEvent);
     156    AssertRC(rc);
     157    rc = RTSemMutexDestroy(mData.mWaitMutex);
     158    AssertRC(rc);
     159
     160    LogFlowFuncLeaveRC(rc);
    143161}
    144162
     
    347365    AssertReturn(cbData, VERR_INVALID_PARAMETER);
    348366
    349     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     367    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    350368
    351369    GuestCtrlCallbacks::const_iterator it
     
    362380            case GUEST_DISCONNECTED:
    363381            {
    364                 PCALLBACKDATACLIENTDISCONNECTED pCBData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvData);
    365                 AssertPtr(pCBData);
     382                PCALLBACKDATACLIENTDISCONNECTED pCallbackData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvData);
     383                AssertPtr(pCallbackData);
    366384                AssertReturn(sizeof(CALLBACKDATACLIENTDISCONNECTED) == cbData, VERR_INVALID_PARAMETER);
    367                 AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    368 
    369                 rc = onGuestDisconnected(); /* Affects all callbacks. */
     385                AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     386
     387                rc = onGuestDisconnected(pCallback, pCallbackData); /* Affects all callbacks. */
    370388                break;
    371389            }
     
    373391            case GUEST_EXEC_SEND_STATUS:
    374392            {
    375                 PCALLBACKDATAEXECSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvData);
    376                 AssertPtr(pCBData);
     393                PCALLBACKDATAEXECSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvData);
     394                AssertPtr(pCallbackData);
    377395                AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbData, VERR_INVALID_PARAMETER);
    378                 AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    379 
    380                 rc = onProcessStatusChange(pCBData->u32Status, pCBData->u32Flags, pCBData->u32PID);
     396                AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     397
     398                rc = onProcessStatusChange(pCallback, pCallbackData);
    381399                break;
    382400            }
     
    384402            case GUEST_EXEC_SEND_OUTPUT:
    385403            {
    386                 PCALLBACKDATAEXECOUT pCBData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvData);
    387                 AssertPtr(pCBData);
     404                PCALLBACKDATAEXECOUT pCallbackData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvData);
     405                AssertPtr(pCallbackData);
    388406                AssertReturn(sizeof(CALLBACKDATAEXECOUT) == cbData, VERR_INVALID_PARAMETER);
    389                 AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    390 
    391                 Assert(mData.mPID == pCBData->u32PID);
    392                 rc = onProcessOutput(pCBData->u32HandleId, pCBData->u32Flags, pCBData->pvData, pCBData->cbData);
     407                AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     408
     409                Assert(mData.mPID == pCallbackData->u32PID);
     410                rc = onProcessOutput(pCallback, pCallbackData);
    393411                break;
    394412            }
     
    396414            case GUEST_EXEC_SEND_INPUT_STATUS:
    397415            {
    398                 PCALLBACKDATAEXECINSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvData);
    399                 AssertPtr(pCBData);
     416                PCALLBACKDATAEXECINSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvData);
     417                AssertPtr(pCallbackData);
    400418                AssertReturn(sizeof(CALLBACKDATAEXECINSTATUS) == cbData, VERR_INVALID_PARAMETER);
    401                 AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    402 
    403                 Assert(mData.mPID == pCBData->u32PID);
    404                 rc = onProcessInputStatus(pCBData->u32Status, pCBData->u32Flags, pCBData->cbProcessed);
     419                AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     420
     421                Assert(mData.mPID == pCallbackData->u32PID);
     422                rc = onProcessInputStatus(pCallback, pCallbackData);
    405423                break;
    406424            }
     
    439457}
    440458
    441 int GuestProcess::onGuestDisconnected(void)
    442 {
    443     LogFlowFunc(("uPID=%RU32", mData.mPID));
    444 
    445     LogFlowFuncLeave();
    446     return 0;
    447 }
    448 
    449 int GuestProcess::onProcessInputStatus(uint32_t uStatus, uint32_t uFlags, uint32_t cbDataProcessed)
    450 {
    451     LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, cbDataProcessed=%RU32\n",
    452                  mData.mPID, uStatus, uFlags, cbDataProcessed));
    453 
    454     LogFlowFuncLeave();
    455     return 0;
    456 }
    457 
    458 int GuestProcess::onProcessStatusChange(uint32_t uStatus, uint32_t uFlags, uint32_t uPID)
    459 {
    460     LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32\n",
    461                  uPID, uStatus, uFlags));
    462 
    463     LogFlowFuncLeave();
    464     return 0;
    465 }
    466 
    467 int GuestProcess::onProcessOutput(uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData)
    468 {
    469     LogFlowFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32\n",
    470                  mData.mPID, uHandle, uFlags, pvData, cbData));
    471 
    472     LogFlowFuncLeave();
    473     return 0;
     459int GuestProcess::onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData)
     460{
     461    LogFlowFunc(("uPID=%RU32, pCallback=%p, pData=%p", mData.mPID, pCallback, pData));
     462
     463    /* First, signal callback in every case. */
     464    pCallback->Signal();
     465
     466    Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
     467    int rc = RTSemEventSignal(mData.mWaitEvent);
     468    AssertRC(rc);
     469
     470    LogFlowFuncLeaveRC(rc);
     471    return rc;
     472}
     473
     474int GuestProcess::onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData)
     475{
     476    LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, cbProcessed=%RU32, pCallback=%p, pData=%p\n",
     477                 mData.mPID, pData->u32Status, pData->u32Flags, pData->cbProcessed, pCallback, pData));
     478
     479    int rc = VINF_SUCCESS;
     480
     481    /** @todo Fill data into callback. */
     482
     483    /* First, signal callback in every case. */
     484    pCallback->Signal();
     485
     486    /* Then do the WaitFor signalling stuff. */
     487    if (mData.mWaitFlags & ProcessWaitForFlag_StdIn)
     488    {
     489        Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
     490        rc = RTSemEventSignal(mData.mWaitEvent);
     491        AssertRC(rc);
     492    }
     493
     494    LogFlowFuncLeaveRC(rc);
     495    return rc;
     496}
     497
     498int GuestProcess::onProcessStatusChange(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECSTATUS pData)
     499{
     500    LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, pCallback=%p, pData=%p\n",
     501                 pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData));
     502
     503    int rc = VINF_SUCCESS;
     504
     505    /* Get data from the callback payload. */
     506    mData.mStatus = (ProcessStatus_T)pData->u32Status;
     507    if (mData.mPID)
     508        Assert(mData.mPID == pData->u32PID);
     509
     510    Utf8Str strCallbackMsg;
     511    bool fSignal = false;
     512    switch (pData->u32Status)
     513    {
     514        case PROC_STS_STARTED:
     515            fSignal = (   (mData.mWaitFlags & ProcessWaitForFlag_Start)
     516                       || (mData.mWaitFlags & ProcessWaitForFlag_Status));
     517            mData.mPID = pData->u32PID;
     518            mData.mStarted = true;
     519
     520            rc = pCallback->Signal(VINF_SUCCESS,
     521                                   Utf8StrFmt(tr("Guest process \"%s\" was started (PID %RU32)"),
     522                                              mData.mProcess.mCommand.c_str(), mData.mPID));
     523            break;
     524
     525        case PROC_STS_TEN:
     526        {
     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            break;
     532        }
     533
     534        case PROC_STS_TES:
     535        {
     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);
     540            break;
     541        }
     542
     543        case PROC_STS_TEA:
     544        {
     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);
     549            break;
     550        }
     551
     552        case PROC_STS_TOK:
     553        {
     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);
     558            break;
     559        }
     560
     561        case PROC_STS_TOA:
     562        {
     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);
     567            break;
     568        }
     569
     570        case PROC_STS_DWN:
     571        {
     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()));
     575            /*
     576             * If mFlags has CreateProcessFlag_IgnoreOrphanedProcesses set, we don't report an error to
     577             * our progress object. This is helpful for waiters which rely on the success of our progress object
     578             * even if the executed process was killed because the system/VBoxService is shutting down.
     579             *
     580             * In this case mFlags contains the actual execution flags reached in via Guest::ExecuteProcess().
     581             */
     582            rc = pCallback->Signal(  mData.mProcess.mFlags & ProcessCreateFlag_IgnoreOrphanedProcesses
     583                                   ? VINF_SUCCESS : VERR_CANCELLED, strErrDetail);
     584            break;
     585        }
     586
     587        case PROC_STS_ERROR:
     588        {
     589            /* Note: It's not required that the process
     590             * has been started before. */
     591            Utf8Str strErrDetail;
     592            if (pData->u32PID)
     593            {
     594                strErrDetail = Utf8StrFmt(tr("Guest process (PID %RU32) could not be started because of rc=%Rrc"),
     595                                          pData->u32PID, pData->u32Flags);
     596            }
     597            else
     598            {
     599                switch (pData->u32Flags) /* u32Flags member contains the IPRT error code from guest side. */
     600                {
     601                    case VERR_FILE_NOT_FOUND: /* This is the most likely error. */
     602                        strErrDetail = Utf8StrFmt(tr("The specified file was not found on guest"));
     603                        break;
     604
     605                    case VERR_PATH_NOT_FOUND:
     606                        strErrDetail = Utf8StrFmt(tr("Could not resolve path to specified file was not found on guest"));
     607                        break;
     608
     609                    case VERR_BAD_EXE_FORMAT:
     610                        strErrDetail = Utf8StrFmt(tr("The specified file is not an executable format on guest"));
     611                        break;
     612
     613                    case VERR_AUTHENTICATION_FAILURE:
     614                        strErrDetail = Utf8StrFmt(tr("The specified user was not able to logon on guest"));
     615                        break;
     616
     617                    case VERR_TIMEOUT:
     618                        strErrDetail = Utf8StrFmt(tr("The guest did not respond within time"));
     619                        break;
     620
     621                    case VERR_CANCELLED:
     622                        strErrDetail = Utf8StrFmt(tr("The execution operation was canceled"));
     623                        break;
     624
     625                    case VERR_PERMISSION_DENIED:
     626                        strErrDetail = Utf8StrFmt(tr("Invalid user/password credentials"));
     627                        break;
     628
     629                    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"));
     631                        break;
     632
     633                    default:
     634                        strErrDetail = Utf8StrFmt(tr("Guest process reported error %Rrc"),
     635                                                  pData->u32Flags);
     636                        break;
     637                }
     638
     639                AssertMsg(!strErrDetail.isEmpty());
     640                rc = pCallback->Signal(pData->u32Flags /* rc from guest. */, strErrDetail);
     641            }
     642            fSignal = mData.mWaitFlags & ProcessWaitForFlag_Status;
     643            break;
     644        }
     645
     646        case PROC_STS_UNDEFINED:
     647        default:
     648            rc = pCallback->Signal(VERR_NOT_SUPPORTED,
     649                                   Utf8StrFmt(tr("Got unsupported process status %RU32, skipping"), pData->u32Status));
     650            fSignal = true; /* Signal in any case. */
     651            break;
     652    }
     653
     654    if (!fSignal)
     655        fSignal = mData.mWaitFlags & ProcessWaitForFlag_Status;
     656    if (fSignal)
     657    {
     658        Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
     659        int rc2 = RTSemEventSignal(mData.mWaitEvent);
     660        if (RT_SUCCESS(rc))
     661            rc = rc2;
     662    }
     663
     664    LogFlowFuncLeaveRC(rc);
     665    return rc;
     666}
     667
     668int GuestProcess::onProcessOutput(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECOUT pData)
     669{
     670    LogFlowFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32, pCallback=%p, pData=%p\n",
     671                 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData));
     672
     673    int rc = VINF_SUCCESS;
     674
     675    /** @todo Fill data into callback. */
     676
     677    /* First, signal callback in every case. */
     678    pCallback->Signal();
     679
     680    /* Then do the WaitFor signalling stuff. */
     681    bool fSignal = false;
     682    if (    (mData.mWaitFlags & ProcessWaitForFlag_StdOut)
     683         || (mData.mWaitFlags & ProcessWaitForFlag_StdErr))
     684    {
     685        fSignal = true;
     686    }
     687    else if (   (mData.mWaitFlags & ProcessWaitForFlag_StdOut)
     688             && (pData->u32HandleId == OUTPUT_HANDLE_ID_STDOUT))
     689    {
     690        fSignal = true;
     691    }
     692    else if (   (mData.mWaitFlags & ProcessWaitForFlag_StdErr)
     693             && (pData->u32HandleId == OUTPUT_HANDLE_ID_STDERR))
     694    {
     695        fSignal = true;
     696    }
     697
     698    if (fSignal)
     699    {
     700        Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
     701        rc = RTSemEventSignal(mData.mWaitEvent);
     702        AssertRC(rc);
     703    }
     704
     705    LogFlowFuncLeaveRC(rc);
     706    return rc;
    474707}
    475708
     
    484717    LogFlowFuncLeave();
    485718    return 0;
     719}
     720
     721int GuestProcess::sendCommand(uint32_t uFunction,
     722                              uint32_t uParms, PVBOXHGCMSVCPARM paParms)
     723{
     724    LogFlowFuncEnter();
     725
     726    const ComObjPtr<Console> pConsole(mData.mConsole);
     727    Assert(!pConsole.isNull());
     728
     729    VMMDev *pVMMDev = NULL;
     730    {
     731        /* Make sure mParent is valid, so set the read lock while using.
     732         * Do not keep this lock while doing the actual call, because in the meanwhile
     733         * another thread could request a write lock which would be a bad idea ... */
     734        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     735
     736        /* Forward the information to the VMM device. */
     737        pVMMDev = pConsole->getVMMDev();
     738    }
     739
     740    LogFlowFunc(("uFunction=%RU32, uParms=%RU32\n", uFunction, uParms));
     741    int rc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", uFunction, uParms, paParms);
     742    if (RT_FAILURE(rc))
     743    {
     744    }
     745
     746    LogFlowFuncLeaveRC(rc);
     747    return rc;
    486748}
    487749
     
    568830                paParms[i++].setUInt32(mData.mProcess.mTimeoutMS);
    569831
    570             const ComObjPtr<Console> pConsole(mData.mConsole);
    571             Assert(!pConsole.isNull());
    572 
    573             VMMDev *pVMMDev = NULL;
    574             {
    575                 /* Make sure mParent is valid, so set the read lock while using.
    576                  * Do not keep this lock while doing the actual call, because in the meanwhile
    577                  * another thread could request a write lock which would be a bad idea ... */
    578                 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    579 
    580                 /* Forward the information to the VMM device. */
    581                 pVMMDev = pConsole->getVMMDev();
    582             }
    583 
    584             LogFlowFunc(("hgcmHostCall numParms=%d, CID=%RU32\n", i, uContextID));
    585             rc = pVMMDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD,
    586                                        i, paParms);
     832            rc = sendCommand(HOST_EXEC_CMD, i, paParms);
    587833        }
    588834
     
    633879int GuestProcess::waitFor(uint32_t fFlags, ULONG uTimeoutMS, ProcessWaitReason_T *penmReason)
    634880{
    635     LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p\n",
    636                  fFlags, uTimeoutMS, penmReason));
    637 
    638     LogFlowFuncLeave();
    639     return 0;
     881    LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p, mWaitEvent=%p\n",
     882                 fFlags, uTimeoutMS, penmReason, &mData.mWaitEvent));
     883
     884    Assert(mData.mWaitEvent != NIL_RTSEMEVENT);
     885
     886    if (ASMAtomicReadBool(&mData.mWaiting))
     887        return VERR_ALREADY_EXISTS;
     888
     889    int rc = RTSemMutexRequest(mData.mWaitMutex, uTimeoutMS);
     890    if (RT_SUCCESS(rc))
     891    {
     892        ASMAtomicWriteBool(&mData.mWaiting, true);
     893        rc = RTSemEventWait(mData.mWaitEvent, uTimeoutMS);
     894        if (RT_SUCCESS(rc))
     895        {
     896            /** @todo Error handling after waiting. */
     897        }
     898
     899        int rc2 = RTSemMutexRelease(mData.mWaitMutex);
     900        if (RT_SUCCESS(rc))
     901            rc = rc2;
     902    }
     903
     904    LogFlowFuncLeaveRC(rc);
     905    return rc;
    640906}
    641907
     
    717983    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    718984
    719     uint32_t fFlags = ProcessWaitForFlag_None;
     985    uint32_t fWaitFor = ProcessWaitForFlag_None;
    720986    com::SafeArray<ProcessWaitForFlag_T> flags(ComSafeArrayInArg(aFlags));
    721987    for (size_t i = 0; i < flags.size(); i++)
    722         fFlags |= flags[i];
    723 
    724     int rc = waitFor(fFlags, aTimeoutMS, aReason);
     988        fWaitFor |= flags[i];
     989
     990    int rc = waitFor(fWaitFor, aTimeoutMS, aReason);
    725991    /** @todo Do setError() here. */
    726992    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
Note: See TracChangeset for help on using the changeset viewer.

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