VirtualBox

Changeset 42411 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 26, 2012 2:07:13 PM (12 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r42382 r42411  
    88048804  <enum
    88058805    name="ProcessWaitForFlag"
    8806     uuid="858a99aa-4b3c-4863-9726-87386671f408"
     8806    uuid="23b550c7-78e1-437e-98f0-65fd9757bcd2"
    88078807    >
    88088808    <desc>
     
    88128812    <const name="None"                    value="0">
    88138813      <desc>TODO</desc>
    8814     </const>   
    8815     <const name="Exit"                    value="1">
     8814    </const>
     8815    <const name="Start"                   value="1">
     8816      <desc>TODO</desc>
     8817    </const>
     8818    <const name="Terminate"               value="2">
     8819      <desc>TODO</desc>
     8820    </const>       
     8821    <const name="StdIn"                   value="4">
    88168822      <desc>TODO</desc>
    88178823    </const>   
    8818     <const name="StdIn"                   value="2">
     8824    <const name="StdOut"                  value="8">
    88198825      <desc>TODO</desc>
    88208826    </const>   
    8821     <const name="StdOut"                  value="4">
     8827    <const name="StdErr"                  value="16">
    88228828      <desc>TODO</desc>
    8823     </const>   
    8824     <const name="StdErr"                  value="8">
    8825       <desc>TODO</desc>
    8826     </const>   
    8827     <const name="Start"                   value="16">
    8828       <desc>TODO</desc>
    8829     </const>   
    8830     <const name="Status"                  value="32">
    8831       <desc>TODO</desc>
    8832     </const>   
     8829    </const>           
    88338830  </enum>
    88348831 
    88358832  <enum
    88368833    name="ProcessWaitResult"
    8837     uuid="b03af138-c812-45eb-939d-5d564bd0b89a"
     8834    uuid="c593a234-21ee-4a67-85ef-ba0cc9b9b86a"
    88388835    >
    88398836    <desc>
     
    88418838    </desc>
    88428839
    8843     <const name="None"                   value="0">
     8840    <const name="None"                    value="0">
    88448841      <desc>TODO</desc>
    88458842    </const>
    8846     <const name="Status"                 value="1">
     8843    <const name="Start"                   value="1">
     8844      <desc>TODO</desc>
     8845    </const>
     8846    <const name="Terminate"               value="2">
     8847      <desc>TODO</desc>
     8848    </const>
     8849    <const name="Status"                  value="3">
    88478850      <desc>TODO</desc>
    88488851    </const>   
    8849     <const name="Error"                  value="10">
     8852    <const name="Error"                   value="4">
    88508853      <desc>TODO</desc>
    88518854    </const>   
    8852     <const name="Timeout"                value="50">
     8855    <const name="Timeout"                 value="5">
    88538856      <desc>TODO</desc>
    88548857    </const>   
    8855     <const name="StdIn"                  value="100">
     8858    <const name="StdIn"                   value="6">
    88568859      <desc>TODO</desc>
    88578860    </const>   
    8858     <const name="StdOut"                 value="150">
     8861    <const name="StdOut"                  value="7">
    88598862      <desc>TODO</desc>
    88608863    </const>   
    8861     <const name="StdErr"                 value="200">
     8864    <const name="StdErr"                  value="8">
    88628865      <desc>TODO</desc>
    88638866    </const>   
     
    89448947  <enum
    89458948    name="ProcessCreateFlag"
    8946     uuid="1497c881-70b4-42dd-8b42-2ad76f004e3f"
     8949    uuid="91c8aba8-2e62-4fe5-b744-fcbd607971e2"
    89478950    >
    89488951    <desc>
     
    89658968    <const name="NoProfile"               value="8">
    89668969      <desc>Do not use the user's profile data when exeuting a process. Only available for Windows guests.</desc>
     8970    </const>
     8971    <const name="WaitForStdOut"           value="16">
     8972      <desc>The guest process waits until all data from stdout is read out.</desc>
     8973    </const>
     8974    <const name="WaitForStdErr"           value="32">
     8975      <desc>The guest process waits until all data from stderr is read out.</desc>
    89678976    </const>
    89688977  </enum>
     
    91819190  <interface
    91829191    name="IGuestSession" extends="$unknown"
    9183     uuid="530aef35-6a48-455c-960c-aac5792abc38"
     9192    uuid="47a344ec-8495-49ad-bfab-8cd0ff8eb3cf"
    91849193    wsmap="managed"
    91859194    >
     
    92219230    </attribute>
    92229231   
    9223     <attribute name="timeout" type="unsigned long" readonly="yes">
     9232    <attribute name="timeout" type="unsigned long" readonly="no">
    92249233      <desc>
    92259234        TODO
     
    97529761    </method>
    97539762   
    9754     <method name="SetTimeout">
     9763    <method name="SymlinkCreate">
    97559764      <desc>
    97569765        TODO
     
    97609769        </result>
    97619770      </desc>
    9762       <param name="timeoutMS" type="unsigned long" dir="in">
     9771      <param name="source" type="wstring" dir="in">
    97639772        <desc>TODO</desc>
    97649773      </param>
     9774      <param name="target" type="wstring" dir="in">
     9775        <desc>TODO</desc>
     9776      </param>
     9777      <param name="type" type="SymlinkType" dir="in">
     9778        <desc>TODO</desc>
     9779      </param>
    97659780    </method>
    97669781   
    9767     <method name="SymlinkCreate">
     9782    <method name="SymlinkExists">
    97689783      <desc>
    97699784        TODO
     
    97739788        </result>
    97749789      </desc>
    9775       <param name="source" type="wstring" dir="in">
     9790      <param name="symlink" type="wstring" dir="in">
    97769791        <desc>TODO</desc>
    97779792      </param>
    9778       <param name="target" type="wstring" dir="in">
     9793      <param name="exists" type="boolean" dir="return">
    97799794        <desc>TODO</desc>
    97809795      </param>
    9781       <param name="type" type="SymlinkType" dir="in">
    9782         <desc>TODO</desc>
    9783       </param>
    97849796    </method>
    97859797   
    9786     <method name="SymlinkExists">
     9798    <method name="SymlinkRead">
    97879799      <desc>
    97889800        TODO
     
    97959807        <desc>TODO</desc>
    97969808      </param>
    9797       <param name="exists" type="boolean" dir="return">
     9809      <param name="flags" type="SymlinkReadFlag" dir="in" safearray="yes">
    97989810        <desc>TODO</desc>
    97999811      </param>
     9812      <param name="target" type="wstring" dir="return">
     9813        <desc>TODO</desc>
     9814      </param>
    98009815    </method>
    98019816   
    9802     <method name="SymlinkRead">
     9817    <method name="SymlinkRemoveDirectory">
    98039818      <desc>
    98049819        TODO
     
    98089823        </result>
    98099824      </desc>
    9810       <param name="symlink" type="wstring" dir="in">
     9825      <param name="path" type="wstring" dir="in">
    98119826        <desc>TODO</desc>
    98129827      </param>
    9813       <param name="flags" type="SymlinkReadFlag" dir="in" safearray="yes">
    9814         <desc>TODO</desc>
    9815       </param>
    9816       <param name="target" type="wstring" dir="return">
    9817         <desc>TODO</desc>
    9818       </param>
    98199828    </method>
    98209829   
    9821     <method name="SymlinkRemoveDirectory">
     9830    <method name="SymlinkRemoveFile">
    98229831      <desc>
    98239832        TODO
     
    98279836        </result>
    98289837      </desc>
    9829       <param name="path" type="wstring" dir="in">
    9830         <desc>TODO</desc>
    9831       </param>
    9832     </method>
    9833    
    9834     <method name="SymlinkRemoveFile">
    9835       <desc>
    9836         TODO
    9837 
    9838         <result name="VBOX_E_NOT_SUPPORTED">
    9839           TODO
    9840         </result>
    9841       </desc>
    98429838      <param name="file" type="wstring" dir="in">
    98439839        <desc>TODO</desc>
     
    98499845  <interface
    98509846    name="IProcess" extends="$unknown"
    9851     uuid="8a308a2f-bea6-4786-80a0-4d07cd4bacaa"
     9847    uuid="f55af4a1-e280-40ac-83e1-921c0abcaf18"
    98529848    wsmap="managed"
    98539849    >
     
    99039899      </desc>
    99049900    </attribute>
     9901    <attribute name="name" type="wstring" readonly="yes">
     9902      <desc>
     9903        TODO
     9904        <note>
     9905          TODO
     9906        </note>
     9907      </desc>
     9908    </attribute>
    99059909   
    99069910    <method name="WaitFor">
    99079911      <desc>
    99089912        TODO
     9913
     9914        <result name="VBOX_E_NOT_SUPPORTED">
     9915          TODO
     9916        </result>
     9917      </desc>
     9918      <param name="waitFor" type="unsigned long" dir="in">
     9919        <desc>TODO</desc>
     9920      </param>
     9921      <param name="timeoutMS" type="unsigned long" dir="in">
     9922        <desc>TODO</desc>
     9923      </param>
     9924      <param name="reason" type="ProcessWaitResult" dir="return">
     9925        <desc>TODO</desc>
     9926      </param>
     9927    </method>
     9928   
     9929    <method name="WaitForArray">
     9930      <desc>
     9931        Scriptable version of <link to="#waitFor" />.
    99099932
    99109933        <result name="VBOX_E_NOT_SUPPORTED">
     
    1038810411  <interface
    1038910412    name="IGuest" extends="$unknown"
    10390     uuid="1413d910-e533-47af-a71b-919c106d2472"
     10413    uuid="9e0b07b1-490f-4413-8955-0a16515aac12"
    1039110414    wsmap="managed"
    1039210415    >
     
    1080510828        </desc>
    1080610829      </param>
    10807     </method>   
     10830    </method>
     10831   
     10832    <method name="findSession">
     10833      <desc>
     10834        TODO
     10835      </desc>     
     10836      <param name="sessionName" type="wstring" dir="in">
     10837        <desc>
     10838          TODO
     10839        </desc>
     10840      </param>
     10841      <param name="sessions" type="IGuestSession" safearray="yes" dir="return">
     10842        <desc>
     10843          TODO
     10844        </desc>
     10845      </param>
     10846    </method>
    1080810847   
    1080910848    <method name="executeProcess">
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r42358 r42411  
    127127    void Destroy(void);
    128128
     129    int FillData(const void *pData, size_t cbData);
     130
    129131    int Init(eVBoxGuestCtrlCallbackType enmType);
    130132
  • trunk/src/VBox/Main/include/GuestImpl.h

    r42354 r42411  
    134134    STDMETHOD(UpdateGuestAdditions)(IN_BSTR aSource, ULONG aFlags, IProgress **aProgress);
    135135    STDMETHOD(CreateSession)(IN_BSTR aUser, IN_BSTR aPassword, IN_BSTR aDomain, IN_BSTR aSessionName, IGuestSession **aGuestSession);
     136    STDMETHOD(FindSession)(IN_BSTR aSessionName, ComSafeArrayOut(IGuestSession *, aSessions));
    136137
    137138    // Public methods that are not in IDL (only called internally).
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r42358 r42411  
    5757    STDMETHOD(COMGETTER(ExecutablePath))(BSTR *aExecutablePath);
    5858    STDMETHOD(COMGETTER(ExitCode))(LONG *aExitCode);
     59    STDMETHOD(COMGETTER(Name))(BSTR *aName);
    5960    STDMETHOD(COMGETTER(Pid))(ULONG *aPID);
    6061    STDMETHOD(COMGETTER(Status))(ProcessStatus_T *aStatus);
     
    6263    STDMETHOD(Read)(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData));
    6364    STDMETHOD(Terminate)(void);
    64     STDMETHOD(WaitFor)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason);
     65    STDMETHOD(WaitFor)(ULONG aWaitFlags, ULONG aTimeoutMS, ProcessWaitResult_T *aReason);
     66    STDMETHOD(WaitForArray)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason);
    6567    STDMETHOD(Write)(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten);
    6668    /** @}  */
     
    7981    int terminateProcess(void);
    8082    int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult);
    81     HRESULT waitResultToErrorEx(const GuestProcessWaitResult &waitResult, bool fLog);
    8283    int writeData(ULONG uHandle, BYTE const *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten);
    8384    /** @}  */
     
    8889    inline int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID);
    8990    inline int callbackRemove(ULONG uContextID);
     91    inline bool isAlive(void);
     92    HRESULT hgcmResultToError(int rc);
    9093    int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData);
    9194    int onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData);
     
    9699    int signalWaiters(ProcessWaitResult_T enmWaitResult, int rc = VINF_SUCCESS);
    97100    static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser);
     101    HRESULT waitResultToErrorEx(const GuestProcessWaitResult &waitResult, bool fLog);
    98102    /** @}  */
    99103
     
    109113        /** All related callbacks to this process. */
    110114        GuestCtrlCallbacks       mCallbacks;
     115        /** The process' name. */
     116        Utf8Str                  mName;
    111117        /** The process start information. */
    112118        GuestProcessInfo         mProcess;
     
    119125        /** The current process status. */
    120126        ProcessStatus_T          mStatus;
    121         /** Flag indicating whether the process has been started
    122          *  so that it can't be started a second time. */
    123         bool                     mStarted;
    124127        /** The next upcoming context ID. */
    125128        ULONG                    mNextContextID;
     129        /** The mutex for protecting the waiter(s). */
     130        RTSEMMUTEX               mWaitMutex;
    126131        /** How many waiters? At the moment there can only
    127132         *  be one. */
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42354 r42411  
    6161    STDMETHOD(COMGETTER(Id))(ULONG *aId);
    6262    STDMETHOD(COMGETTER(Timeout))(ULONG *aTimeout);
     63    STDMETHOD(COMSETTER(Timeout))(ULONG aTimeout);
    6364    STDMETHOD(COMGETTER(Environment))(ComSafeArrayOut(BSTR, aEnvironment));
    6465    STDMETHOD(COMGETTER(Processes))(ComSafeArrayOut(IGuestProcess *, aProcesses));
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r42354 r42411  
    28342834}
    28352835
     2836STDMETHODIMP Guest::FindSession(IN_BSTR aSessionName, ComSafeArrayOut(IGuestSession *, aSessions))
     2837{
     2838    ReturnComNotImplemented();
     2839}
     2840
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42358 r42411  
    206206    }
    207207    cbData = 0;
     208}
     209
     210int GuestCtrlCallback::FillData(const void *pData, size_t cbData)
     211{
     212    if (!cbData)
     213        return VINF_SUCCESS;
     214    AssertPtr(pData);
     215
     216    Assert(pvData == NULL); /* Can't reuse callbacks! */
     217    pvData = RTMemAlloc(cbData);
     218    if (!pvData)
     219        return VERR_NO_MEMORY;
     220
     221    memcpy(pvData, pData, cbData);
     222
     223    return VINF_SUCCESS;
    208224}
    209225
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42358 r42411  
    7575    mData.mProcessID = 0;
    7676    mData.mStatus = ProcessStatus_Undefined;
    77     mData.mStarted = false;
    7877
    7978    mData.mWaitCount = 0;
    80     mData.mWaitEvent = NIL_RTSEMEVENT;
     79    mData.mWaitEvent = NULL;
    8180
    8281    HRESULT hr = BaseFinalConstruct();
     
    148147    LogFlowThisFuncEnter();
    149148
     149    CheckComArgOutSafeArrayPointerValid(aArguments);
     150
    150151    AutoCaller autoCaller(this);
    151152    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    152 
    153     CheckComArgOutSafeArrayPointerValid(aArguments);
    154153
    155154    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    179178    LogFlowThisFuncEnter();
    180179
     180    CheckComArgOutSafeArrayPointerValid(aEnvironment);
     181
    181182    AutoCaller autoCaller(this);
    182183    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    183 
    184     CheckComArgOutSafeArrayPointerValid(aEnvironment);
    185184
    186185    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    206205    LogFlowThisFuncEnter();
    207206
     207    CheckComArgOutPointerValid(aExecutablePath);
     208
    208209    AutoCaller autoCaller(this);
    209210    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    225226    LogFlowThisFuncEnter();
    226227
     228    CheckComArgOutPointerValid(aExitCode);
     229
    227230    AutoCaller autoCaller(this);
    228231    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    237240}
    238241
    239 STDMETHODIMP GuestProcess::COMGETTER(Pid)(ULONG *aPID)
     242STDMETHODIMP GuestProcess::COMGETTER(Name)(BSTR *aName)
    240243{
    241244#ifndef VBOX_WITH_GUEST_CONTROL
     
    243246#else
    244247    LogFlowThisFuncEnter();
     248
     249    CheckComArgOutPointerValid(aName);
     250
     251    AutoCaller autoCaller(this);
     252    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     253
     254    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     255
     256    mData.mName.cloneTo(aName);
     257
     258    LogFlowFuncLeaveRC(S_OK);
     259    return S_OK;
     260#endif /* VBOX_WITH_GUEST_CONTROL */
     261}
     262
     263STDMETHODIMP GuestProcess::COMGETTER(Pid)(ULONG *aPID)
     264{
     265#ifndef VBOX_WITH_GUEST_CONTROL
     266    ReturnComNotImplemented();
     267#else
     268    LogFlowThisFuncEnter();
     269
     270    CheckComArgOutPointerValid(aPID);
    245271
    246272    AutoCaller autoCaller(this);
     
    436462}
    437463
     464inline bool GuestProcess::isAlive(void)
     465{
     466    return (   mData.mStatus == ProcessStatus_Started
     467            || mData.mStatus == ProcessStatus_Paused
     468            || mData.mStatus == ProcessStatus_Terminating);
     469}
     470
    438471void GuestProcess::close(void)
    439472{
     
    467500}
    468501
     502HRESULT GuestProcess::hgcmResultToError(int rc)
     503{
     504    if (RT_SUCCESS(rc))
     505        return S_OK;
     506
     507    HRESULT hr;
     508    if (rc == VERR_INVALID_VM_HANDLE)
     509        hr = setErrorNoLog(VBOX_E_VM_ERROR,
     510                           tr("VMM device is not available (is the VM running?)"));
     511    else if (rc == VERR_NOT_FOUND)
     512        hr = setErrorNoLog(VBOX_E_IPRT_ERROR,
     513                           tr("The guest execution service is not ready (yet)"));
     514    else if (rc == VERR_HGCM_SERVICE_NOT_FOUND)
     515        hr= setErrorNoLog(VBOX_E_IPRT_ERROR,
     516                          tr("The guest execution service is not available"));
     517    else /* HGCM call went wrong. */
     518        hr = setErrorNoLog(E_UNEXPECTED,
     519                           tr("The HGCM call failed with error %Rrc"), rc);
     520    return hr;
     521}
     522
    469523bool GuestProcess::isReady(void)
    470524{
     
    518572    uint32_t uWaitFlags = mData.mWaitEvent
    519573                        ? mData.mWaitEvent->GetWaitFlags() : 0;
    520     if (   (uWaitFlags & ProcessWaitForFlag_Status)
    521         || (uWaitFlags & ProcessWaitForFlag_StdIn))
     574    if (uWaitFlags & ProcessWaitForFlag_StdIn)
    522575        rc = signalWaiters(ProcessWaitResult_StdIn);
    523576    AssertRC(rc);
     
    556609            mData.mStatus = ProcessStatus_Started;
    557610            mData.mPID = pData->u32PID;
    558             mData.mStarted = true;
    559611            break;
    560612        }
     
    562614        case PROC_STS_TEN:
    563615        {
    564             fSignal = (uWaitFlags & ProcessWaitForFlag_Exit);
     616            fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate);
    565617            enmWaitResult = ProcessWaitResult_Status;
    566618
     
    572624        case PROC_STS_TES:
    573625        {
    574             fSignal = (uWaitFlags & ProcessWaitForFlag_Exit);
     626            fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate);
    575627            enmWaitResult = ProcessWaitResult_Status;
    576628
     
    584636        case PROC_STS_TEA:
    585637        {
    586             fSignal = (uWaitFlags & ProcessWaitForFlag_Exit);
     638            fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate);
    587639            enmWaitResult = ProcessWaitResult_Status;
    588640
     
    595647        case PROC_STS_TOK:
    596648        {
    597             fSignal = (uWaitFlags & ProcessWaitForFlag_Exit);
     649            fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate);
    598650            enmWaitResult = ProcessWaitResult_Timeout;
    599651
     
    606658        case PROC_STS_TOA:
    607659        {
    608             fSignal = (uWaitFlags & ProcessWaitForFlag_Exit);
     660            fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate);
    609661            enmWaitResult = ProcessWaitResult_Timeout;
    610662
     
    617669        case PROC_STS_DWN:
    618670        {
    619             fSignal = (uWaitFlags & ProcessWaitForFlag_Exit);
     671            fSignal = (uWaitFlags & ProcessWaitForFlag_Terminate);
    620672            enmWaitResult = ProcessWaitResult_Status;
    621673
     
    667719    rc = pCallback->Signal(callbackRC);
    668720
    669     if (!fSignal)
    670         fSignal = (uWaitFlags & ProcessWaitForFlag_Status);
    671721    if (fSignal)
    672722    {
     
    688738                 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData));
    689739
    690     int rc = VINF_SUCCESS;
    691 
    692     /** @todo Fill data into callback. */
     740    /* Copy data into callback. */
     741    int rc = pCallback->FillData(pData->pvData, pData->cbData);
    693742
    694743    /* First, signal callback in every case. */
    695     pCallback->Signal();
     744    int rc2 = pCallback->Signal();
     745    if (RT_SUCCESS(rc))
     746        rc = rc2;
    696747
    697748    /* Then do the WaitFor signalling stuff. */
     
    716767    }
    717768
    718     if (!fSignal)
    719         fSignal = (uWaitFlags & ProcessWaitForFlag_Status);
    720 
    721769    if (fSignal)
    722         rc = signalWaiters(  pData->u32HandleId == OUTPUT_HANDLE_ID_STDOUT
    723                            ? ProcessWaitResult_StdOut : ProcessWaitResult_StdErr);
     770    {
     771        rc2 = signalWaiters(  pData->u32HandleId == OUTPUT_HANDLE_ID_STDOUT
     772                            ? ProcessWaitResult_StdOut : ProcessWaitResult_StdErr);
     773        if (RT_SUCCESS(rc))
     774            rc = rc2;
     775    }
    724776    AssertRC(rc);
    725777
     
    767819                 enmWaitResult, rc, mData.mWaitCount, mData.mWaitEvent));
    768820
    769     /* Note: No locking here -- already done in the callback dispatcher. */
    770 
    771     AssertPtr(mData.mWaitEvent);
    772     int rc2 = mData.mWaitEvent->Signal(enmWaitResult, rc);
     821    /* Note: No write locking here -- already done in the callback dispatcher. */
     822
     823    int rc2 = VINF_SUCCESS;
     824    if (mData.mWaitEvent)
     825        rc2 = mData.mWaitEvent->Signal(enmWaitResult, rc);
    773826    LogFlowFuncLeaveRC(rc2);
    774827    return rc2;
     
    780833                 mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags));
    781834
    782     AssertReturn(!mData.mStarted, VERR_ALREADY_EXISTS);
     835    /* Wait until the caller function (if kicked off by a thread)
     836     * has returned and continue operation. */
     837    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    783838
    784839    int rc;
     
    788843        return VERR_NO_MEMORY;
    789844
    790     {
    791         /* Wait until the caller function (if kicked off by a thread)
    792          * has returned and continue operation. */
    793         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    794 
    795         mData.mStatus = ProcessStatus_Starting;
    796 
    797         /* Create callback and add it to the map. */
    798         rc = pCallbackStart->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START);
    799         if (RT_SUCCESS(rc))
    800             rc = callbackAdd(pCallbackStart, &uContextID);
    801     }
    802 
     845    mData.mStatus = ProcessStatus_Starting;
     846
     847    /* Create callback and add it to the map. */
     848    rc = pCallbackStart->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START);
    803849    if (RT_SUCCESS(rc))
    804     {
    805         AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     850        rc = callbackAdd(pCallbackStart, &uContextID);
     851
     852    if (RT_SUCCESS(rc))
     853    {
     854      //  AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    806855
    807856        GuestSession *pSession = mData.mParent;
     
    867916            RTStrFree(pszArgs);
    868917
     918        if (RT_FAILURE(rc))
     919            mData.mStatus = ProcessStatus_Error;
     920
    869921        uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS;
    870922
     
    877929             * Note: Be sure not keeping a AutoRead/WriteLock here.
    878930             */
    879             LogFlowFunc((tr("Waiting for callback (%RU32ms) ...\n"), uTimeoutMS));
     931            LogFlowFunc(("Waiting for callback (%RU32ms) ...\n", uTimeoutMS));
    880932            rc = pCallbackStart->Wait(uTimeoutMS);
    881933            if (RT_SUCCESS(rc)) /* Wait was successful, check for supplied information. */
    882934            {
    883935                rc = pCallbackStart->GetResultCode();
    884                 LogFlowFunc((tr("Callback returned rc=%Rrc\n"), rc));
     936                LogFlowFunc(("Callback returned rc=%Rrc\n", rc));
    885937            }
    886938            else
     
    936988    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    937989
    938     int rcIgnored = pProcess->startProcess();
    939     LogFlowFuncLeaveRC(rcIgnored);
     990    int rc = pProcess->startProcess();
     991    if (RT_FAILURE(rc))
     992    {
     993        /** @todo What now? */
     994    }
     995
     996    LogFlowFuncLeaveRC(rc);
    940997    return VINF_SUCCESS;
    941998}
     
    9511008int GuestProcess::waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult)
    9521009{
    953     LogFlowFunc(("fWaitFlags=%x, uTimeoutMS=%RU32, mWaitCount=%RU32, mWaitEvent=%p\n",
    954                  fWaitFlags, uTimeoutMS, mData.mWaitCount, mData.mWaitEvent));
     1010    LogFlowThisFuncEnter();
    9551011
    9561012    AssertReturn(fWaitFlags, VERR_INVALID_PARAMETER);
    9571013
    9581014    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1015
     1016    LogFlowFunc(("fWaitFlags=%x, uTimeoutMS=%RU32, mStatus=%RU32, mWaitCount=%RU32, mWaitEvent=%p\n",
     1017                 fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent));
     1018
     1019    ProcessStatus curStatus = mData.mStatus;
     1020
     1021    guestResult.mResult = ProcessWaitResult_None;
     1022    guestResult.mRC = VINF_SUCCESS;
     1023
     1024#if 1
     1025    if (   (fWaitFlags &  ProcessWaitForFlag_Start)
     1026        && (curStatus  != ProcessStatus_Undefined))
     1027    {
     1028        guestResult.mResult = ProcessWaitResult_Start; /** @todo Fix this. */
     1029    }
     1030#else
     1031    if (   (fWaitFlags & ProcessWaitForFlag_Terminate)
     1032        || (fWaitFlags & ProcessWaitForFlag_StdIn)
     1033        || (fWaitFlags & ProcessWaitForFlag_StdOut)
     1034        || (fWaitFlags & ProcessWaitForFlag_StdErr))
     1035    {
     1036        switch (mData.mStatus)
     1037        {
     1038            case ProcessStatus_TerminatedNormally:
     1039            case ProcessStatus_TerminatedSignal:
     1040            case ProcessStatus_TerminatedAbnormally:
     1041            case ProcessStatus_Down:
     1042                guestResult.mResult = ProcessWaitResult_Terminate;
     1043                break;
     1044
     1045            case ProcessStatus_TimedOutKilled:
     1046            case ProcessStatus_TimedOutAbnormally:
     1047                guestResult.mResult = ProcessWaitResult_Timeout;
     1048                break;
     1049
     1050            case ProcessStatus_Error:
     1051                guestResult.mResult = ProcessWaitResult_Error;
     1052                break;
     1053
     1054            default:
     1055                AssertMsgFailed(("Unhandled process status %ld\n", mData.mStatus));
     1056                return VERR_NOT_IMPLEMENTED;
     1057        }
     1058    }
     1059    else if (fWaitFlags & ProcessWaitForFlag_Start)
     1060    {
     1061        switch (mData.mStatus)
     1062        {
     1063            case ProcessStatus_Started:
     1064            case ProcessStatus_Paused:
     1065            case ProcessStatus_Terminating:
     1066                guestResult.mResult = ProcessWaitResult_Start;
     1067                break;
     1068
     1069            default:
     1070                AssertMsgFailed(("Unhandled process status %ld\n", mData.mStatus));
     1071                return VERR_NOT_IMPLEMENTED;
     1072        }
     1073    }
     1074#endif
     1075
     1076    /* No waiting needed? Return immediately. */
     1077    if (guestResult.mResult != ProcessWaitResult_None)
     1078        return VINF_SUCCESS;
    9591079
    9601080    if (mData.mWaitCount > 0)
     
    9621082    mData.mWaitCount++;
    9631083
    964     Assert(mData.mWaitEvent == NIL_RTSEMEVENT);
     1084    Assert(mData.mWaitEvent == NULL);
    9651085    mData.mWaitEvent = new GuestProcessEvent(fWaitFlags);
    9661086    AssertPtrReturn(mData.mWaitEvent, VERR_NO_MEMORY);
     
    9711091    if (RT_SUCCESS(rc))
    9721092        guestResult = mData.mWaitEvent->GetResult();
     1093
     1094    alock.acquire(); /* Get the lock again. */
    9731095
    9741096    /* Note: The caller always is responsible of deleting the
     
    9771099    mData.mWaitEvent = NULL;
    9781100
     1101    mData.mWaitCount--;
     1102
    9791103    LogFlowFuncLeaveRC(rc);
    9801104    return rc;
     
    9961120
    9971121        case ProcessStatus_TerminatedNormally:
    998             strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated normally (exit code: %d)"),
     1122            strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated normally (exit code: %ld)"),
    9991123                                mData.mProcess.mCommand.c_str(), mData.mPID, mData.mExitCode);
    10001124            break;
     
    10021126        case ProcessStatus_TerminatedSignal:
    10031127        {
    1004             strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated through signal (signal: %d)"),
     1128            strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated through signal (signal: %ld)"),
    10051129                                mData.mProcess.mCommand.c_str(), mData.mPID, mData.mExitCode);
    10061130            break;
     
    10091133        case ProcessStatus_TerminatedAbnormally:
    10101134        {
    1011             strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated abnormally (exit code: %d)"),
     1135            strMsg = Utf8StrFmt(tr("Guest process \"%s\" (PID %RU32) terminated abnormally (exit code: %ld)"),
    10121136                                mData.mProcess.mCommand.c_str(), mData.mPID, mData.mExitCode);
    10131137            break;
     
    10841208                        break;
    10851209
     1210                    case VERR_NOT_AVAILABLE:
     1211                       strMsg += Utf8StrFmt(tr("Guest control service is not ready"));
     1212
    10861213                    default:
    10871214                        strMsg += Utf8StrFmt(tr("Reported error %Rrc"), rc);
     
    11831310}
    11841311
    1185 STDMETHODIMP GuestProcess::WaitFor(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason)
     1312STDMETHODIMP GuestProcess::WaitFor(ULONG aWaitFlags, ULONG aTimeoutMS, ProcessWaitResult_T *aReason)
     1313{
     1314#ifndef VBOX_WITH_GUEST_CONTROL
     1315    ReturnComNotImplemented();
     1316#else
     1317    LogFlowThisFuncEnter();
     1318
     1319    CheckComArgOutPointerValid(aReason);
     1320
     1321    AutoCaller autoCaller(this);
     1322    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1323
     1324    /*
     1325     * Note: Do not hold any locks here while waiting!
     1326     */
     1327    HRESULT hr;
     1328
     1329    GuestProcessWaitResult waitRes;
     1330    int rc = waitFor(aWaitFlags, aTimeoutMS, waitRes);
     1331    if (RT_SUCCESS(rc))
     1332    {
     1333        hr = waitResultToErrorEx(waitRes, true /* fLog */);
     1334        if (SUCCEEDED(hr))
     1335            *aReason = waitRes.mResult;
     1336    }
     1337    else
     1338        hr = setError(VBOX_E_IPRT_ERROR,
     1339                      tr("Waiting for process \"%s\" (PID %RU32) failed with rc=%Rrc"),
     1340                      mData.mProcess.mCommand.c_str(), mData.mPID, rc);
     1341    LogFlowFuncLeaveRC(hr);
     1342    return hr;
     1343#endif /* VBOX_WITH_GUEST_CONTROL */
     1344}
     1345
     1346STDMETHODIMP GuestProcess::WaitForArray(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason)
    11861347{
    11871348#ifndef VBOX_WITH_GUEST_CONTROL
     
    12031364        fWaitFor |= flags[i];
    12041365
    1205     HRESULT hr;
    1206 
    1207     GuestProcessWaitResult guestResult;
    1208     int rc = waitFor(fWaitFor, aTimeoutMS, guestResult);
    1209     if (RT_SUCCESS(rc))
    1210     {
    1211         hr = waitResultToErrorEx(guestResult, true /* fLog */);
    1212         if (SUCCEEDED(hr))
    1213             *aReason = guestResult.mResult;
    1214     }
    1215     else
    1216         hr = setError(VBOX_E_IPRT_ERROR,
    1217                       tr("Waiting for process \"%s\" (PID %RU32) failed with rc=%Rrc"),
    1218                       mData.mProcess.mCommand.c_str(), mData.mPID, rc);
     1366    HRESULT hr = WaitFor(fWaitFor, aTimeoutMS, aReason);
     1367
    12191368    LogFlowFuncLeaveRC(hr);
    12201369    return hr;
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42354 r42411  
    240240}
    241241
     242STDMETHODIMP GuestSession::COMSETTER(Timeout)(ULONG aTimeout)
     243{
     244#ifndef VBOX_WITH_GUEST_CONTROL
     245    ReturnComNotImplemented();
     246#else
     247    LogFlowThisFuncEnter();
     248
     249    AutoCaller autoCaller(this);
     250    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     251
     252    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     253
     254    mData.mTimeout = aTimeout;
     255
     256    LogFlowFuncLeaveRC(S_OK);
     257    return S_OK;
     258#endif /* VBOX_WITH_GUEST_CONTROL */
     259}
     260
    242261STDMETHODIMP GuestSession::COMGETTER(Environment)(ComSafeArrayOut(BSTR, aEnvironment))
    243262{
     
    435454            && !(procInfo.mFlags & ProcessCreateFlag_WaitForProcessStartOnly)
    436455            && !(procInfo.mFlags & ProcessCreateFlag_Hidden)
    437             && !(procInfo.mFlags & ProcessCreateFlag_NoProfile))
     456            && !(procInfo.mFlags & ProcessCreateFlag_NoProfile)
     457            && !(procInfo.mFlags & ProcessCreateFlag_WaitForStdOut)
     458            && !(procInfo.mFlags & ProcessCreateFlag_WaitForStdErr))
    438459        {
    439460            return VERR_INVALID_PARAMETER;
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