VirtualBox

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


Ignore:
Timestamp:
Mar 6, 2013 4:40:36 PM (12 years ago)
Author:
vboxsync
Message:

GuestCtrl: More code for guest session infrastructure handling (untested, work in progress). Added IGuestSession.status for (later) asynchronous handling.

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

Legend:

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

    r44649 r44935  
    89228922
    89238923  <enum
     8924    name="GuestSessionStatus"
     8925    uuid="ac2669da-4624-44f2-85b5-0b0bfb8d8673"
     8926    >
     8927    <desc>
     8928      Guest session statuses.
     8929    </desc>
     8930    <const name="Undefined"               value="0">
     8931      <desc>Guest session is in an undefined state.</desc>
     8932    </const>
     8933    <const name="Starting"                value="10">
     8934      <desc>Guest session is being started.</desc>
     8935    </const>
     8936    <const name="Started"                 value="100">
     8937      <desc>Guest session has been started.</desc>
     8938    </const>
     8939    <const name="Terminating"             value="480">
     8940      <desc>Guest session is being terminated.</desc>
     8941    </const>
     8942    <const name="Terminated"              value="500">
     8943      <desc>Guest session terminated normally.</desc>
     8944    </const>
     8945    <const name="TimedOutKilled"          value="512">
     8946      <desc>Guest session timed out and was killed.</desc>
     8947    </const>
     8948    <const name="TimedOutAbnormally"      value="513">
     8949      <desc>Guest session timed out and was not killed successfully.</desc>
     8950    </const>
     8951    <const name="Down"                    value="600">
     8952      <desc>Service/OS is stopping, guest session was killed.</desc>
     8953    </const>
     8954    <const name="Error"                   value="800">
     8955      <desc>Something went wrong.</desc>
     8956    </const>
     8957  </enum>
     8958
     8959  <enum
    89248960    name="FileSeekType"
    89258961    uuid="1b73f4f3-3515-4073-a506-76878d9e2541"
     
    92329268      <desc>Process is in an undefined state.</desc>
    92339269    </const>
    9234 
    92359270    <const name="Starting"                value="10">
    92369271      <desc>Process is being started.</desc>
     
    93479382  <interface
    93489383    name="IGuestSession" extends="$unknown"
    9349     uuid="57eb82a8-822b-42c1-9d1c-5c54bc3d3250"
     9384    uuid="8490516f-9c2c-49e9-b283-35f3ce463f69"
    93509385    wsmap="managed"
    93519386    >
     
    93999434        </result>
    94009435      </desc>
     9436    </attribute>
     9437
     9438    <attribute name="status" type="GuestSessionStatus" readonly="yes">
     9439      <desc>Returns the current session status.</desc>
    94019440    </attribute>
    94029441
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r44863 r44935  
    318318
    319319/**
    320  * Structure for keeping all the relevant process
    321  * starting parameters around.
     320 * Structure for keeping all the relevant guest session
     321 * startup parameters around.
     322 */
     323class GuestSessionStartupInfo
     324{
     325public:
     326
     327    GuestSessionStartupInfo(void)
     328        : mIsInternal(false /* Non-internal session */),
     329          mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */),
     330          mOpenFlags(0 /* No opening flags set */) { }
     331
     332    /** The session's friendly name. Optional. */
     333    Utf8Str                     mName;
     334    /** The session's unique ID. Used to encode
     335     *  a context ID. */
     336    uint32_t                    mID;
     337    /** Flag indicating if this is an internal session
     338     *  or not. Internal session are not accessible by
     339     *  public API clients. */
     340    bool                        mIsInternal;
     341    /** Timeout (in ms) used for opening the session. */
     342    uint32_t                    mOpenTimeoutMS;
     343    /** Session opening flags. */
     344    uint32_t                    mOpenFlags;
     345};
     346
     347
     348/**
     349 * Structure for keeping all the relevant guest process
     350 * startup parameters around.
    322351 */
    323352class GuestProcessStartupInfo
     
    341370    /** Process priority. */
    342371    ProcessPriority_T           mPriority;
    343     /** Process affinity. */
     372    /** Process affinity. At the moment we
     373     *  only support 64 VCPUs. API and
     374     *  guest can do more already!  */
    344375    uint64_t                    mAffinity;
    345376};
  • trunk/src/VBox/Main/include/GuestImpl.h

    r44863 r44935  
    141141    Console    *getConsole(void) { return mParent; }
    142142    int         sessionRemove(GuestSession *pSession);
    143     int         sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain,
    144                               const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession);
     143    int         sessionCreate(const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession);
    145144    inline bool sessionExists(uint32_t uSessionID);
    146145#endif
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r44863 r44935  
    105105    struct Data
    106106    {
    107         /** The process start information. */
     107        /** The process startup information. */
    108108        GuestProcessStartupInfo  mProcess;
    109109        /** Exit code if process has been terminated. */
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r44863 r44935  
    8181public:
    8282
    83     int Run(void);
     83    int Run(int *pGuestRc);
    8484    int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
    8585    static int taskThread(RTTHREAD Thread, void *pvUser);
     
    251251    DECLARE_EMPTY_CTOR_DTOR(GuestSession)
    252252
    253     int     init(Guest *aGuest, ULONG aSessionID, Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName);
     253    int     init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds);
    254254    void    uninit(void);
    255255    HRESULT FinalConstruct(void);
     
    263263    STDMETHOD(COMGETTER(Name))(BSTR *aName);
    264264    STDMETHOD(COMGETTER(Id))(ULONG *aId);
     265    STDMETHOD(COMGETTER(Status))(GuestSessionStatus_T *aStatus);
    265266    STDMETHOD(COMGETTER(Timeout))(ULONG *aTimeout);
    266267    STDMETHOD(COMSETTER(Timeout))(ULONG aTimeout);
     
    343344    const GuestEnvironment &getEnvironment(void);
    344345    Utf8Str                 getName(void);
    345     ULONG                   getId(void) { return mData.mId; }
     346    ULONG                   getId(void) { return mData.mSession.mID; }
     347    static Utf8Str          guestErrorToString(int guestRc);
    346348    int                     onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, GuestCtrlCallback *pCallback, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
    347     int                     openSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
     349    int                     openSession(int *pGuestRc);
     350    int                     openSessionAsync(void);
     351    static DECLCALLBACK(int)
     352                            openSessionThread(RTTHREAD Thread, void *pvUser);
    348353    Guest                  *getParent(void) { return mData.mParent; }
    349354    uint32_t                getProtocolVersion(void) { return mData.mProtocolVersion; }
     
    353358    inline int              processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
    354359    int                     sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
     360    static HRESULT          setErrorExternal(VirtualBoxBase *pInterface, int guestRc);
    355361    int                     startTaskAsync(const Utf8Str &strTaskDesc, GuestSessionTask *pTask, ComObjPtr<Progress> &pProgress);
    356362    int                     queryInfo(void);
     
    361367    struct Data
    362368    {
     369        /** Pointer to the parent (Guest). */
     370        Guest                      *mParent;
     371        /** The session credentials. */
     372        GuestCredentials            mCredentials;
     373        /** The session's startup info. */
     374        GuestSessionStartupInfo     mSession;
     375        /** The session's current status. */
     376        GuestSessionStatus_T        mStatus;
     377        /** The session's environment block. Can be
     378         *  overwritten/extended by ProcessCreate(Ex). */
     379        GuestEnvironment            mEnvironment;
     380        /** The session callback, needed for communicating
     381         *  with the guest. */
     382        GuestCtrlCallback           mCallback;
     383        /** Directory objects bound to this session. */
     384        SessionDirectories          mDirectories;
     385        /** File objects bound to this session. */
     386        SessionFiles                mFiles;
     387        /** Process objects bound to this session. */
     388        SessionProcesses            mProcesses;
    363389        /** Guest control protocol version to be used.
    364390         *  Guest Additions < VBox 4.3 have version 1,
    365391         *  any newer version will have version 2. */
    366         uint32_t             mProtocolVersion;
    367         /** Flag indicating if this is an internal session
    368          *  or not. Internal session are not accessible by clients. */
    369         bool                 fInternal;
    370         /** Pointer to the parent (Guest). */
    371         Guest               *mParent;
    372         /** The session credentials. */
    373         GuestCredentials     mCredentials;
    374         /** The (optional) session name. */
    375         Utf8Str              mName;
    376         /** The session ID. */
    377         ULONG                mId;
    378         /** The session timeout. Default is 30s. */
    379         ULONG                mTimeout;
    380         /** The session's environment block. Can be
    381          *  overwritten/extended by ProcessCreate(Ex). */
    382         GuestEnvironment     mEnvironment;
    383         /** The session callback, needed for communicating
    384          *  with the guest. */
    385         GuestCtrlCallback    mCallback;
    386         /** Directory objects bound to this session. */
    387         SessionDirectories   mDirectories;
    388         /** File objects bound to this session. */
    389         SessionFiles         mFiles;
    390         /** Process objects bound to this session. */
    391         SessionProcesses     mProcesses;
     392        uint32_t                    mProtocolVersion;
     393        /** Session timeout (in ms). */
     394        uint32_t                    mTimeout;
    392395        /** Total number of session objects (processes,
    393396         *  files, ...). */
    394         uint32_t             mNumObjects;
     397        uint32_t                    mNumObjects;
    395398    } mData;
    396399};
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r44863 r44935  
    142142    HRESULT hr = S_OK;
    143143
    144     /* Create an anonymous session. This is required to run the Guest Additions
    145      * update process with administrative rights. */
     144    /*
     145     * Create an anonymous session. This is required to run the Guest Additions
     146     * update process with administrative rights.
     147     */
     148    GuestSessionStartupInfo startupInfo;
     149    startupInfo.mName = "Updating Guest Additions";
     150
     151    GuestCredentials guestCreds;
     152    RT_ZERO(guestCreds);
     153
    146154    ComObjPtr<GuestSession> pSession;
    147     int rc = sessionCreate("" /* User */, "" /* Password */, "" /* Domain */,
    148                            "Updating Guest Additions" /* Name */, pSession);
     155    int rc = sessionCreate(startupInfo, guestCreds, pSession);
    149156    if (RT_FAILURE(rc))
    150157    {
     
    166173    {
    167174        Assert(!pSession.isNull());
    168         rc = pSession->queryInfo();
     175        int guestRc;
     176        rc = pSession->openSession(&guestRc);
    169177        if (RT_FAILURE(rc))
    170178        {
    171             hr = setError(VBOX_E_IPRT_ERROR, tr("Could not query guest session information: %Rrc"), rc);
     179            /** @todo Handle guestRc! */
     180
     181            hr = setError(VBOX_E_IPRT_ERROR, tr("Could not open guest session: %Rrc"), rc);
    172182        }
    173183        else
     
    208218    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    209219
     220    LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n",
     221                  pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol));
     222
    210223    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    211224
     
    260273            {
    261274                case GUEST_DISCONNECTED:
    262                    break;
     275                    rc = pSession->dispatchToThis(pCtxCb, pSvcCb);
     276                    break;
    263277
    264278                case GUEST_SESSION_NOTIFY:
     
    310324                         (GuestSession *)itSessions->second, itSessions->second->getId(), mData.mGuestSessions.size() - 1));
    311325
    312             mData.mGuestSessions.erase(itSessions);
     326            mData.mGuestSessions.erase(itSessions++);
    313327
    314328            rc = VINF_SUCCESS;
     
    321335}
    322336
    323 int Guest::sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain,
    324                          const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession)
     337int Guest::sessionCreate(const GuestSessionStartupInfo &ssInfo,
     338                         const GuestCredentials &guestCreds, ComObjPtr<GuestSession> &pGuestSession)
    325339{
    326340    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    348362                uNewSessionID = 0;
    349363
    350             if (++uTries == UINT32_MAX)
     364            if (++uTries == VBOX_GUESTCTRL_MAX_SESSIONS)
    351365                break; /* Don't try too hard. */
    352366        }
     
    357371        if (FAILED(hr)) throw VERR_COM_UNEXPECTED;
    358372
    359         rc = pGuestSession->queryInfo();
    360         if (RT_FAILURE(rc)) throw rc;
    361         rc = pGuestSession->init(this, uNewSessionID,
    362                                  strUser, strPassword, strDomain, strSessionName);
     373        /** @todo Use an overloaded copy operator. Later. */
     374        GuestSessionStartupInfo startupInfo;
     375        startupInfo.mID = uNewSessionID; /* Assign new session ID. */
     376        startupInfo.mName = ssInfo.mName;
     377        startupInfo.mOpenFlags = ssInfo.mOpenFlags;
     378        startupInfo.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS;
     379
     380        GuestCredentials guestCredentials;
     381        if (!guestCreds.mUser.isEmpty())
     382        {
     383            /** @todo Use an overloaded copy operator. Later. */
     384            guestCredentials.mUser = guestCreds.mUser;
     385            guestCredentials.mPassword = guestCreds.mPassword;
     386            guestCredentials.mDomain = guestCreds.mDomain;
     387        }
     388        else
     389        {
     390            /* Internal (annonymous) session. */
     391            startupInfo.mIsInternal = true;
     392        }
     393
     394        rc = pGuestSession->init(this, startupInfo, guestCredentials);
    363395        if (RT_FAILURE(rc)) throw rc;
    364396
     
    373405         * involve the main dispatcher to run. */
    374406        alock.release();
    375 
    376         /** @todo Do we need an openSessioAsync() call? This might be
    377          *        a problem on webservice calls (= timeouts) if opening the
    378          *        guest session takes too long -> Then we also would
    379          *        need some session.getStatus() API call! */
    380 
    381         /* Open (create) the session on the guest. */
    382         int guestRc;
    383         rc = pGuestSession->openSession(0 /* Flags */, 30 * 1000 /* 30s timeout */,
    384                                         &guestRc);
    385         if (RT_FAILURE(rc))
    386         {
    387             switch (rc)
    388             {
    389                 case VERR_MAX_PROCS_REACHED:
    390                     hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"),
    391                                                         VBOX_GUESTCTRL_MAX_SESSIONS);
    392                     break;
    393 
    394                 /** @todo Add more errors here. */
    395 
    396                 default:
    397                     hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session, rc=%Rrc"), rc);
    398                     break;
    399             }
    400 
    401             /* Remove failed session again. */
    402             int rc2 = sessionRemove(pGuestSession);
    403             AssertRC(rc2);
    404         }
    405         else
    406             LogFlowFunc(("Created new guest session (pSession=%p, ID=%RU32), now %zu sessions total\n",
    407                          (GuestSession *)pGuestSession, uNewSessionID, mData.mGuestSessions.size()));
    408407    }
    409408    catch (int rc2)
     
    433432    LogFlowFuncEnter();
    434433
    435     /* Do not allow anonymous sessions (with system rights) with official API. */
     434    /* Do not allow anonymous sessions (with system rights) with public API. */
    436435    if (RT_UNLIKELY((aUser) == NULL || *(aUser) == '\0'))
    437436        return setError(E_INVALIDARG, tr("No user name specified"));
     
    442441    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    443442
    444     HRESULT hr = S_OK;
     443    GuestSessionStartupInfo startupInfo;
     444    startupInfo.mName = aSessionName;
     445
     446    GuestCredentials guestCreds;
     447    guestCreds.mUser = aUser;
     448    guestCreds.mPassword = aPassword;
     449    guestCreds.mDomain = aDomain;
    445450
    446451    ComObjPtr<GuestSession> pSession;
    447     int rc = sessionCreate(aUser, aPassword, aDomain, aSessionName, pSession);
     452    int rc = sessionCreate(startupInfo, guestCreds, pSession);
    448453    if (RT_SUCCESS(rc))
    449454    {
     
    454459    }
    455460
     461    int guestRc;
     462    if (RT_SUCCESS(rc))
     463    {
     464        /** @todo Do we need to use openSessioAsync() here? Otherwise
     465         *        there might be a problem on webservice calls (= timeouts)
     466         *        if opening the guest session takes too long -> Use
     467         *        the new session.getStatus() API call! */
     468
     469        /* Open (fork) the session on the guest. */
     470        rc = pSession->openSession(&guestRc);
     471        if (RT_SUCCESS(rc))
     472        {
     473            LogFlowFunc(("Created new guest session (pSession=%p), now %zu sessions total\n",
     474                         (GuestSession *)pSession, mData.mGuestSessions.size()));
     475        }
     476    }
     477
     478    HRESULT hr = S_OK;
     479
    456480    if (RT_FAILURE(rc))
    457481    {
    458482        switch (rc)
    459483        {
     484            case VERR_GENERAL_FAILURE: /** @todo Special guest control rc needed! */
     485                hr = GuestSession::setErrorExternal(this, guestRc);
     486                break;
     487
    460488            case VERR_MAX_PROCS_REACHED:
    461489                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"),
     
    465493            /** @todo Add more errors here. */
    466494
    467            default:
    468                 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session, rc=%Rrc"), rc);
     495            default:
     496                hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc);
    469497                break;
    470498        }
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r44863 r44935  
    405405 *
    406406 * In protocol v1 we don't have the possibility to terminate/kill
    407  * processes so it can happen that a formerly start process A
     407 * processes so it can happen that a formerly started process A
    408408 * (which has the context ID 0 (session=0, process=0, count=0) will
    409409 * send a delayed message to the host if this process has already
     
    428428                   ? VINF_SUCCESS : VERR_NOT_FOUND;
    429429        }
     430#ifndef DEBUG_andy
    430431        /* This should never happen! */
    431432        AssertReleaseMsg(mData.mPID == uPID, ("Unterminated guest process (PID %RU32) sent data to a newly started process (PID %RU32)\n",
    432433                                              uPID, mData.mPID));
     434#endif
    433435    }
    434436
     
    12471249
    12481250    /* Create callback and add it to the map. */
    1249     uint32_t uContextID = 0;
     1251    uint32_t uContextID;
    12501252    if (RT_SUCCESS(vrc))
    12511253        vrc = callbackAdd(pCallbackTerminate, &uContextID);
     
    12751277        {
    12761278            int guestRc = pCallbackTerminate->GetResultCode();
    1277             LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc));
     1279            if (RT_SUCCESS(guestRc))
     1280            {
     1281                /* Nothing to do here right now. */
     1282            }
     1283            else
     1284                vrc = VERR_GENERAL_FAILURE; /** @todo Special guest control rc needed! */
     1285
    12781286            if (pGuestRc)
    12791287                *pGuestRc = guestRc;
     1288            LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc));
    12801289        }
    12811290    }
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r44863 r44935  
    4444#include <VBox/log.h>
    4545
     46
     47/**
     48 * Base class representing an internal
     49 * asynchronous session task.
     50 */
     51class GuestSessionTaskInternal
     52{
     53public:
     54
     55    GuestSessionTaskInternal(GuestSession *pSession)
     56        : mSession(pSession),
     57          mRC(VINF_SUCCESS) { }
     58
     59    virtual ~GuestSessionTaskInternal(void) { }
     60
     61    int rc(void) const { return mRC; }
     62    bool isOk(void) const { return RT_SUCCESS(mRC); }
     63    const ComObjPtr<GuestSession> &Session(void) const { return mSession; }
     64
     65protected:
     66
     67    const ComObjPtr<GuestSession>    mSession;
     68    int                              mRC;
     69};
     70
     71/**
     72 * Class for asynchronously opening a guest session.
     73 */
     74class GuestSessionTaskInternalOpen : public GuestSessionTaskInternal
     75{
     76public:
     77
     78    GuestSessionTaskInternalOpen(GuestSession *pSession)
     79        : GuestSessionTaskInternal(pSession) { }
     80};
     81
    4682// constructor / destructor
    4783/////////////////////////////////////////////////////////////////////////////
     
    68104/**
    69105 * Initializes a guest session but does *not* open in on the guest side
    70  * yet. This needs to be done via the openSession() call.
     106 * yet. This needs to be done via the openSession() / openSessionAsync calls.
    71107 *
    72108 * @return  IPRT status code.
    73  * @param   aGuest
    74  * @param   aSessionID
    75  * @param   aUser
    76  * @param   aPassword
    77  * @param   aDomain
    78  * @param   aName
     109 ** @todo Docs!
    79110 */
    80 int GuestSession::init(Guest *aGuest, ULONG aSessionID,
    81                        Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName)
    82 {
    83     LogFlowThisFuncEnter();
    84 
    85     AssertPtrReturn(aGuest, VERR_INVALID_POINTER);
     111int GuestSession::init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo,
     112                       const GuestCredentials &guestCreds)
     113{
     114    LogFlowThisFunc(("pGuest=%p, ssInfo=%p, guestCreds=%p\n",
     115                      pGuest, &ssInfo, &guestCreds));
     116
     117    AssertPtrReturn(pGuest, VERR_INVALID_POINTER);
    86118
    87119    /* Enclose the state transition NotReady->InInit->Ready. */
     
    89121    AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED);
    90122
    91     mData.mTimeout = 30 * 60 * 1000; /* Session timeout is 30 mins by default. */
    92     mData.mParent = aGuest;
    93     mData.mId = aSessionID;
    94 
    95     mData.mCredentials.mUser = aUser;
    96     mData.mCredentials.mPassword = aPassword;
    97     mData.mCredentials.mDomain = aDomain;
    98     mData.mName = aName;
     123    mData.mParent = pGuest;
     124
     125    /* Copy over startup info. */
     126    /** @todo Use an overloaded copy operator. Later. */
     127    mData.mSession.mID = ssInfo.mID;
     128    mData.mSession.mIsInternal = ssInfo.mIsInternal;
     129    mData.mSession.mName = ssInfo.mName;
     130    mData.mSession.mOpenFlags = ssInfo.mOpenFlags;
     131    mData.mSession.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS;
     132
     133    /** @todo Use an overloaded copy operator. Later. */
     134    mData.mCredentials.mUser = guestCreds.mUser;
     135    mData.mCredentials.mPassword = guestCreds.mPassword;
     136    mData.mCredentials.mDomain = guestCreds.mDomain;
     137
     138    mData.mStatus = GuestSessionStatus_Undefined;
    99139    mData.mNumObjects = 0;
    100140
    101     /* Confirm a successful initialization when it's the case. */
    102     autoInitSpan.setSucceeded();
    103 
    104     LogFlowFuncLeaveRC(VINF_SUCCESS);
    105     return VINF_SUCCESS;
     141    int rc = queryInfo();
     142    if (RT_SUCCESS(rc))
     143    {
     144        /* Confirm a successful initialization when it's the case. */
     145        autoInitSpan.setSucceeded();
     146    }
     147    else
     148        autoInitSpan.setFailed();
     149
     150    LogFlowFuncLeaveRC(rc);
     151    return rc;
    106152}
    107153
     
    228274    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    229275
    230     mData.mName.cloneTo(aName);
     276    mData.mSession.mName.cloneTo(aName);
    231277
    232278    LogFlowFuncLeaveRC(S_OK);
     
    249295    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    250296
    251     *aId = mData.mId;
     297    *aId = mData.mSession.mID;
    252298
    253299    LogFlowFuncLeaveRC(S_OK);
     
    256302}
    257303
    258 STDMETHODIMP GuestSession::COMGETTER(Timeout)(ULONG *aTimeout)
    259 {
    260 #ifndef VBOX_WITH_GUEST_CONTROL
    261     ReturnComNotImplemented();
    262 #else
    263     LogFlowThisFuncEnter();
    264 
    265     CheckComArgOutPointerValid(aTimeout);
     304STDMETHODIMP GuestSession::COMGETTER(Status)(GuestSessionStatus_T *aStatus)
     305{
     306#ifndef VBOX_WITH_GUEST_CONTROL
     307    ReturnComNotImplemented();
     308#else
     309    LogFlowThisFuncEnter();
     310
     311    CheckComArgOutPointerValid(aStatus);
    266312
    267313    AutoCaller autoCaller(this);
     
    270316    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    271317
    272     *aTimeout = mData.mTimeout;
     318    *aStatus = mData.mStatus;
    273319
    274320    LogFlowFuncLeaveRC(S_OK);
     
    277323}
    278324
    279 STDMETHODIMP GuestSession::COMSETTER(Timeout)(ULONG aTimeout)
    280 {
    281 #ifndef VBOX_WITH_GUEST_CONTROL
    282     ReturnComNotImplemented();
    283 #else
    284     LogFlowThisFuncEnter();
    285 
    286     AutoCaller autoCaller(this);
    287     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    288 
    289     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    290 
    291     mData.mTimeout = aTimeout;
     325STDMETHODIMP GuestSession::COMGETTER(Timeout)(ULONG *aTimeout)
     326{
     327#ifndef VBOX_WITH_GUEST_CONTROL
     328    ReturnComNotImplemented();
     329#else
     330    LogFlowThisFuncEnter();
     331
     332    CheckComArgOutPointerValid(aTimeout);
     333
     334    AutoCaller autoCaller(this);
     335    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     336
     337    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     338
     339    *aTimeout = mData.mTimeout;
    292340
    293341    LogFlowFuncLeaveRC(S_OK);
     
    296344}
    297345
     346STDMETHODIMP GuestSession::COMSETTER(Timeout)(ULONG aTimeout)
     347{
     348#ifndef VBOX_WITH_GUEST_CONTROL
     349    ReturnComNotImplemented();
     350#else
     351    LogFlowThisFuncEnter();
     352
     353    AutoCaller autoCaller(this);
     354    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     355
     356    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     357
     358    mData.mTimeout = aTimeout;
     359
     360    LogFlowFuncLeaveRC(S_OK);
     361    return S_OK;
     362#endif /* VBOX_WITH_GUEST_CONTROL */
     363}
     364
    298365STDMETHODIMP GuestSession::COMGETTER(Environment)(ComSafeArrayOut(BSTR, aEnvironment))
    299366{
     
    311378
    312379    size_t cEnvVars = mData.mEnvironment.Size();
    313     LogFlowThisFunc(("%s cEnvVars=%RU32\n", mData.mName.c_str(), cEnvVars));
     380    LogFlowThisFunc(("[%s]: cEnvVars=%RU32\n",
     381                     mData.mSession.mName.c_str(), cEnvVars));
    314382    com::SafeArray<BSTR> environment(cEnvVars);
    315383
     
    431499    if (mData.mProtocolVersion < 2)
    432500    {
    433         LogFlowThisFunc(("Installed Guest Additions don't support closing separate sessions\n"));
     501        LogFlowThisFunc(("Installed Guest Additions don't support closing dedicated sessions, skipping\n"));
    434502        return VINF_SUCCESS;
    435503    }
     504
     505    /** @todo uFlags validation. */
    436506
    437507    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    446516    if (RT_SUCCESS(vrc))
    447517    {
    448         uint32_t uContextID = VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mId, 0 /* Object */, 0 /* Count */);
     518        /* The context ID only contains this session's ID; all other
     519         * parameters like object and the count itself are not needed
     520         * and therefore 0. */
     521        uint32_t uContextID = VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mSession.mID /* Session ID */,
     522                                                            0 /* Object */, 0 /* Count */);
    449523
    450524        VBOXHGCMSVCPARM paParms[4];
     
    452526        int i = 0;
    453527        paParms[i++].setUInt32(uContextID);
    454         paParms[i++].setUInt32(0 /* Flags, unused. */);
     528        paParms[i++].setUInt32(uFlags);
    455529
    456530        vrc = sendCommand(HOST_SESSION_CLOSE, i, paParms);
     
    468542        {
    469543            int guestRc = mData.mCallback.GetResultCode();
     544            if (RT_SUCCESS(guestRc))
     545            {
     546                /* Nothing to do here right now. */
     547            }
     548            else
     549                vrc = VERR_GENERAL_FAILURE; /** @todo Special guest control rc needed! */
     550
    470551            if (pGuestRc)
    471552                *pGuestRc = guestRc;
    472553            LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc));
    473554        }
    474         else
    475             vrc = VERR_TIMEOUT;
    476555    }
    477556
     
    499578            Assert(mData.mDirectories.size());
    500579            LogFlowFunc(("Removing directory \"%s\" (Session: %RU32) (now total %ld directories)\n",
    501                          Utf8Str(strName).c_str(), mData.mId, mData.mDirectories.size() - 1));
     580                         Utf8Str(strName).c_str(), mData.mSession.mID, mData.mDirectories.size() - 1));
    502581
    503582            mData.mDirectories.erase(itDirs);
     
    637716
    638717    LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n",
    639                  strPath.c_str(), mData.mId));
     718                 strPath.c_str(), mData.mSession.mID));
    640719
    641720    LogFlowFuncLeaveRC(vrc);
     
    721800#ifdef DEBUG
    722801    LogFlowThisFunc(("ID=%RU32, uContextID=%RU32, uFunction=%RU32, pSvcCb=%p\n",
    723                      mData.mId, pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
     802                     mData.mSession.mID, pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
    724803#endif
    725804
     
    727806    switch (pCbCtx->uFunction)
    728807    {
     808        case GUEST_DISCONNECTED:
     809            /** @todo Handle closing all processes. */
     810            break;
     811
    729812        case GUEST_SESSION_NOTIFY:
    730813        {
     
    736819        default:
    737820            /* Silently skip unknown callbacks. */
     821            rc = VERR_NOT_SUPPORTED;
    738822            break;
    739823    }
     
    773857            Assert(mData.mNumObjects);
    774858            LogFlowThisFunc(("Removing file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n",
    775                              Utf8Str(strName).c_str(), mData.mId, mData.mFiles.size() - 1, mData.mNumObjects - 1));
     859                             Utf8Str(strName).c_str(), mData.mSession.mID, mData.mFiles.size() - 1, mData.mNumObjects - 1));
    776860#ifdef DEBUG
    777861            ULONG cRefs = pFile->AddRef();
     
    874958
    875959    LogFlowFunc(("Added new file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n",
    876                  openInfo.mFileName.c_str(), mData.mId, mData.mFiles.size(), mData.mNumObjects));
     960                 openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects));
    877961
    878962    LogFlowFuncLeaveRC(rc);
     
    9571041Utf8Str GuestSession::getName(void)
    9581042{
    959     return mData.mName;
     1043    return mData.mSession.mName;
     1044}
     1045
     1046/* static */
     1047Utf8Str GuestSession::guestErrorToString(int guestRc)
     1048{
     1049    Utf8Str strError;
     1050
     1051    /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
     1052    switch (guestRc)
     1053    {
     1054        case VERR_INVALID_VM_HANDLE:
     1055            strError += Utf8StrFmt(tr("VMM device is not available (is the VM running?)"));
     1056            break;
     1057
     1058        case VERR_HGCM_SERVICE_NOT_FOUND:
     1059            strError += Utf8StrFmt(tr("The guest execution service is not available"));
     1060            break;
     1061
     1062        case VERR_AUTHENTICATION_FAILURE:
     1063            strError += Utf8StrFmt(tr("The specified user was not able to logon on guest"));
     1064            break;
     1065
     1066        case VERR_TIMEOUT:
     1067            strError += Utf8StrFmt(tr("The guest did not respond within time"));
     1068            break;
     1069
     1070        case VERR_CANCELLED:
     1071            strError += Utf8StrFmt(tr("The session operation was canceled"));
     1072            break;
     1073
     1074        case VERR_PERMISSION_DENIED:
     1075            strError += Utf8StrFmt(tr("Invalid user/password credentials"));
     1076            break;
     1077
     1078        case VERR_MAX_PROCS_REACHED:
     1079            strError += Utf8StrFmt(tr("Maximum number of parallel guest processes has been reached"));
     1080            break;
     1081
     1082        case VERR_NOT_EQUAL: /** @todo Imprecise to the user; can mean anything and all. */
     1083            strError += Utf8StrFmt(tr("Unable to retrieve requested information"));
     1084            break;
     1085
     1086        case VERR_NOT_FOUND:
     1087            strError += Utf8StrFmt(tr("The guest execution service is not ready (yet)"));
     1088            break;
     1089
     1090        default:
     1091            strError += Utf8StrFmt("%Rrc", guestRc);
     1092            break;
     1093    }
     1094
     1095    return strError;
    9601096}
    9611097
     
    9751111    pSvcCbData->mpaParms[2].getUInt32(&dataCb.uResult);
    9761112
    977     int rcCb = dataCb.uResult; /** @todo uint32_t vs. int. */
    978 
    9791113    LogFlowThisFunc(("ID=%RU32, uType=%RU32, rc=%Rrc, pCallback=%p, pData=%p\n",
    980                      mData.mId, dataCb.uType, rcCb, pCallback, pSvcCbData));
     1114                     mData.mSession.mID, dataCb.uType, dataCb.uResult, pCallback, pSvcCbData));
    9811115
    9821116    int vrc = VINF_SUCCESS;
     1117
     1118    int guestRc = dataCb.uResult; /** @todo uint32_t vs. int. */
     1119    switch (dataCb.uType)
     1120    {
     1121        case GUEST_SESSION_NOTIFYTYPE_ERROR:
     1122            mData.mStatus = GuestSessionStatus_Error;
     1123            break;
     1124
     1125        case GUEST_SESSION_NOTIFYTYPE_OPEN:
     1126            if (RT_FAILURE(guestRc))
     1127                mData.mStatus = GuestSessionStatus_Started;
     1128            break;
     1129
     1130        case GUEST_SESSION_NOTIFYTYPE_CLOSE:
     1131            if (RT_FAILURE(guestRc))
     1132                mData.mStatus = GuestSessionStatus_Terminated;
     1133            break;
     1134
     1135        default:
     1136            vrc = VERR_NOT_SUPPORTED;
     1137            break;
     1138    }
     1139
     1140    if (RT_SUCCESS(vrc))
     1141    {
     1142        if (RT_FAILURE(guestRc))
     1143            mData.mStatus = GuestSessionStatus_Error;
     1144    }
     1145    else if (vrc == VERR_NOT_SUPPORTED)
     1146    {
     1147        /* Also let the callback know. */
     1148        guestRc = VERR_NOT_SUPPORTED;
     1149    }
    9831150
    9841151    /*
     
    9871154    if (pCallback)
    9881155    {
    989         vrc = pCallback->SetData(&dataCb, sizeof(dataCb));
    990 
    991         int rc2 = pCallback->Signal(rcCb);
    992         if (RT_SUCCESS(vrc))
    993             vrc = rc2;
    994     }
     1156        int rc2 = pCallback->SetData(&dataCb, sizeof(dataCb));
     1157        AssertRC(rc2);
     1158        rc2 = pCallback->Signal(guestRc);
     1159        AssertRC(rc2);
     1160    }
     1161
     1162    LogFlowThisFunc(("ID=%RU32, guestRc=%Rrc\n",
     1163                     mData.mSession.mID, guestRc));
    9951164
    9961165    LogFlowFuncLeaveRC(vrc);
     
    9981167}
    9991168
    1000 int GuestSession::openSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc)
     1169int GuestSession::openSession(int *pGuestRc)
    10011170{
    10021171    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    10031172
    1004     LogFlowThisFunc(("uProtocolVersion=%RU32, uFlags=%x, uTimeoutMS=%RU32\n",
    1005                      mData.mProtocolVersion, uFlags, uTimeoutMS));
     1173    LogFlowThisFunc(("uProtocolVersion=%RU32, openFlags=%x, openTimeoutMS=%RU32\n",
     1174                     mData.mProtocolVersion, mData.mSession.mOpenFlags, mData.mSession.mOpenTimeoutMS));
    10061175
    10071176    /* Legacy Guest Additions don't support opening dedicated
    1008        guest sessions. */
     1177       guest sessions. Simply return success here. */
    10091178    if (mData.mProtocolVersion < 2)
    10101179    {
    1011         LogFlowThisFunc(("Installed Guest Additions don't support opening separate sessions\n"));
     1180        mData.mStatus = GuestSessionStatus_Started;
     1181
     1182        LogFlowThisFunc(("Installed Guest Additions don't support opening dedicated sessions, skipping\n"));
    10121183        return VINF_SUCCESS;
    10131184    }
    10141185
    1015     /** @todo uFlags validation. */
     1186    /** @todo mData.mSession.uFlags validation. */
     1187
     1188    /* Set current session status. */
     1189    mData.mStatus = GuestSessionStatus_Starting;
    10161190
    10171191    /* Destroy a pending callback request. */
     
    10251199    {
    10261200        uint32_t uContextID =
    1027             VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mId, 0 /* Object */, 0 /* Count */);
     1201            VBOX_GUESTCTRL_CONTEXTID_MAKE(mData.mSession.mID /* Session ID */,
     1202                                          0 /* Object */, 0 /* Count */);
    10281203
    10291204        VBOXHGCMSVCPARM paParms[8];
     
    10381213        paParms[i++].setPointer((void*)mData.mCredentials.mDomain.c_str(),
    10391214                                (ULONG)mData.mCredentials.mDomain.length() + 1);
    1040         paParms[i++].setUInt32(uFlags);
     1215        paParms[i++].setUInt32(mData.mSession.mOpenFlags);
    10411216
    10421217        vrc = sendCommand(HOST_SESSION_CREATE, i, paParms);
     
    10491224         * Note: Be sure not keeping a AutoRead/WriteLock here.
    10501225         */
    1051         LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", uTimeoutMS));
    1052         vrc = mData.mCallback.Wait(uTimeoutMS);
     1226        LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", mData.mSession.mOpenTimeoutMS));
     1227        vrc = mData.mCallback.Wait(mData.mSession.mOpenTimeoutMS);
    10531228        if (RT_SUCCESS(vrc)) /* Wait was successful, check for supplied information. */
    10541229        {
    10551230            int guestRc = mData.mCallback.GetResultCode();
     1231            if (RT_SUCCESS(guestRc))
     1232            {
     1233                /* Nothing to do here right now. */
     1234            }
     1235            else
     1236                vrc = VERR_GENERAL_FAILURE; /** @todo Special guest control rc needed! */
     1237
    10561238            if (pGuestRc)
    10571239                *pGuestRc = guestRc;
    10581240            LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc));
    10591241        }
    1060         else
    1061             vrc = VERR_TIMEOUT;
    1062     }
    1063 
    1064     AutoWriteLock awlock(this COMMA_LOCKVAL_SRC_POS);
     1242    }
     1243
     1244    alock.acquire();
    10651245
    10661246    /* Destroy callback. */
     
    10711251}
    10721252
     1253int GuestSession::openSessionAsync(void)
     1254{
     1255    LogFlowThisFuncEnter();
     1256
     1257    int vrc;
     1258
     1259    try
     1260    {
     1261        /* Asynchronously open the session on the guest by kicking off a
     1262         * worker thread. */
     1263        std::auto_ptr<GuestSessionTaskInternalOpen> pTask(new GuestSessionTaskInternalOpen(this));
     1264        AssertReturn(pTask->isOk(), pTask->rc());
     1265
     1266        vrc = RTThreadCreate(NULL, GuestSession::openSessionThread,
     1267                             (void *)pTask.get(), 0,
     1268                             RTTHREADTYPE_MAIN_WORKER, 0,
     1269                             "gctlSesOpen");
     1270        if (RT_SUCCESS(vrc))
     1271        {
     1272            /* pTask is now owned by openSessionThread(), so release it. */
     1273            pTask.release();
     1274        }
     1275    }
     1276    catch(std::bad_alloc &)
     1277    {
     1278        vrc = VERR_NO_MEMORY;
     1279    }
     1280
     1281    LogFlowFuncLeaveRC(vrc);
     1282    return vrc;
     1283}
     1284
     1285/* static */
     1286DECLCALLBACK(int) GuestSession::openSessionThread(RTTHREAD Thread, void *pvUser)
     1287{
     1288    LogFlowFunc(("pvUser=%p\n", pvUser));
     1289
     1290    std::auto_ptr<GuestSessionTaskInternalOpen> pTask(static_cast<GuestSessionTaskInternalOpen*>(pvUser));
     1291    AssertPtr(pTask.get());
     1292
     1293    const ComObjPtr<GuestSession> pSession(pTask->Session());
     1294    Assert(!pSession.isNull());
     1295
     1296    AutoCaller autoCaller(pSession);
     1297    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1298
     1299    int vrc = pSession->openSession(NULL /* Guest rc, ignored */);
     1300    /* Nothing to do here anymore. */
     1301
     1302    LogFlowFuncLeaveRC(vrc);
     1303    return vrc;
     1304}
     1305
    10731306int GuestSession::processRemoveFromList(GuestProcess *pProcess)
    10741307{
     
    10971330            Assert(mData.mNumObjects);
    10981331            LogFlowFunc(("Removing process (Session: %RU32) with process ID=%RU32, guest PID=%RU32 (now total %ld processes, %ld objects)\n",
    1099                          mData.mId, pCurProc->getObjectID(), uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1));
     1332                         mData.mSession.mID, pCurProc->getObjectID(), uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1));
    11001333
    11011334            mData.mProcesses.erase(itProcs);
     
    11921425            uNewProcessID = 0;
    11931426
    1194         if (++uTries == UINT32_MAX)
     1427        if (++uTries == VBOX_GUESTCTRL_MAX_OBJECTS)
    11951428            break; /* Don't try too hard. */
    11961429    }
     
    12151448
    12161449    LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes, %ld objects)\n",
    1217                  mData.mId, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects));
     1450                 mData.mSession.mID, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects));
    12181451
    12191452    return rc;
     
    12851518    LogFlowFuncLeaveRC(vrc);
    12861519    return vrc;
     1520}
     1521
     1522/* static */
     1523HRESULT GuestSession::setErrorExternal(VirtualBoxBase *pInterface, int guestRc)
     1524{
     1525    AssertPtr(pInterface);
     1526    AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n"));
     1527
     1528    return pInterface->setError(VBOX_E_IPRT_ERROR, GuestSession::guestErrorToString(guestRc).c_str());
    12871529}
    12881530
     
    13281570int GuestSession::queryInfo(void)
    13291571{
    1330 #if 1
    1331     /* Since the new functions were not implemented yet, force Main to use protocol ver 1. */
     1572#ifndef DEBUG_andy
     1573    /* Since the new functions are not fully implemented yet, force Main
     1574       to use protocol ver 1 so far. */
     1575    mData.mProtocolVersion = 1;
     1576#else
     1577 #if 1
     1578    /* For debugging only: Hardcode version. */
    13321579    mData.mProtocolVersion = 2;
    1333 #else
     1580 #else
    13341581    /*
    13351582     * Try querying the guest control protocol version running on the guest.
     
    13511598        LogRel((tr("Warning: Guest Additions are older (%ld.%ld) than host capabilities for guest control, please upgrade them. Using protocol version %ld now\n"),
    13521599                VBOX_FULL_VERSION_GET_MAJOR(uVerAdditions), VBOX_FULL_VERSION_GET_MINOR(uVerAdditions), mData.mProtocolVersion));
     1600 #endif
    13531601#endif
    13541602    return VINF_SUCCESS;
     
    13721620    int rc = closeSession(0 /* Flags */, 30 * 1000 /* Timeout */,
    13731621                          &guestRc);
    1374     if (RT_FAILURE(rc))
    1375     {
    1376 
    1377     }
     1622    /* On failure don't return here, instead do all the cleanup
     1623     * work first and then return an error. */
    13781624
    13791625    /* Remove ourselves from the session list. */
    1380     mData.mParent->sessionRemove(this);
     1626    int rc2 = mData.mParent->sessionRemove(this);
     1627    if (RT_SUCCESS(rc))
     1628        rc = rc2;
    13811629
    13821630    /*
     
    13871635    uninit();
    13881636
    1389     LogFlowFuncLeave();
     1637    LogFlowFuncLeaveRC(rc);
     1638    if (RT_FAILURE(rc))
     1639    {
     1640        /** @todo Handle guestRc! */
     1641        return setError(VBOX_E_IPRT_ERROR,
     1642                        tr("Closing guest session failed with %Rrc\n"), rc);
     1643    }
     1644
    13901645    return S_OK;
    13911646#endif /* VBOX_WITH_GUEST_CONTROL */
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r44869 r44935  
    176176}
    177177
    178 int SessionTaskOpen::Run(void)
     178int SessionTaskOpen::Run(int *pGuestRc)
    179179{
    180180    LogFlowThisFuncEnter();
     
    186186    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    187187
    188     int vrc = pSession->openSession(mFlags, mTimeoutMS,
    189                                     NULL /* Guest rc, ignored */);
     188    int vrc = pSession->openSession(pGuestRc);
    190189    /* Nothing to do here anymore. */
    191190
     
    215214
    216215    LogFlowFunc(("pTask=%p\n", task.get()));
    217     return task->Run();
     216    return task->Run(NULL /* guestRc */);
    218217}
    219218
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