VirtualBox

Changeset 71406 in vbox


Ignore:
Timestamp:
Mar 20, 2018 2:44:24 PM (7 years ago)
Author:
vboxsync
Message:

Guest Control: Revamped internal object [un]registration and organization to provide faster lookups and avoid code duplication. No protocol changes.

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

Legend:

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

    r71314 r71406  
    686686    /** The session's friendly name. Optional. */
    687687    Utf8Str                     mName;
    688     /** The session's unique ID. Used to encode
    689      *  a context ID. */
     688    /** The session's unique ID. Used to encode a context ID. */
    690689    uint32_t                    mID;
    691690    /** Flag indicating if this is an internal session
     
    907906    GuestWaitEventPayload(uint32_t uTypePayload,
    908907                          const void *pvPayload, uint32_t cbPayload)
    909     {
     908        : uType(0),
     909          cbData(0),
     910          pvData(NULL)
     911    {
     912        int rc = copyFrom(uTypePayload, pvPayload, cbPayload);
     913        if (RT_FAILURE(rc))
     914            throw rc;
     915    }
     916
     917    virtual ~GuestWaitEventPayload(void)
     918    {
     919        Clear();
     920    }
     921
     922    GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that)
     923    {
     924        CopyFromDeep(that);
     925        return *this;
     926    }
     927
     928public:
     929
     930    void Clear(void)
     931    {
     932        if (pvData)
     933        {
     934            Assert(cbData);
     935            RTMemFree(pvData);
     936            cbData = 0;
     937            pvData = NULL;
     938        }
     939        uType = 0;
     940    }
     941
     942    int CopyFromDeep(const GuestWaitEventPayload &payload)
     943    {
     944        return copyFrom(payload.uType, payload.pvData, payload.cbData);
     945    }
     946
     947    const void* Raw(void) const { return pvData; }
     948
     949    size_t Size(void) const { return cbData; }
     950
     951    uint32_t Type(void) const { return uType; }
     952
     953    void* MutableRaw(void) { return pvData; }
     954
     955    Utf8Str ToString(void)
     956    {
     957        const char  *pszStr = (const char *)pvData;
     958              size_t cbStr  = cbData;
     959
     960        if (RT_FAILURE(RTStrValidateEncodingEx(pszStr, cbStr,
     961                                               RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED | RTSTR_VALIDATE_ENCODING_EXACT_LENGTH)))
     962        {
     963            AssertFailed();
     964            return "";
     965        }
     966
     967        return Utf8Str(pszStr, cbStr);
     968    }
     969
     970protected:
     971
     972    int copyFrom(uint32_t uTypePayload, const void *pvPayload, uint32_t cbPayload)
     973    {
     974        if (cbPayload > _64K) /* Paranoia. */
     975            return VERR_TOO_MUCH_DATA;
     976
     977        Clear();
     978
     979        int rc = VINF_SUCCESS;
     980
    910981        if (cbPayload)
    911982        {
     
    918989                cbData = cbPayload;
    919990            }
    920             else /* Throw IPRT error. */
    921                 throw VERR_NO_MEMORY;
     991            else
     992                rc = VERR_NO_MEMORY;
    922993        }
    923994        else
     
    928999            cbData = 0;
    9291000        }
    930     }
    931 
    932     virtual ~GuestWaitEventPayload(void)
    933     {
    934         Clear();
    935     }
    936 
    937     GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that)
    938     {
    939         CopyFromDeep(that);
    940         return *this;
    941     }
    942 
    943 public:
    944 
    945     void Clear(void)
    946     {
    947         if (pvData)
    948         {
    949             RTMemFree(pvData);
    950             cbData = 0;
    951             pvData = NULL;
    952         }
    953         uType = 0;
    954     }
    955 
    956     int CopyFromDeep(const GuestWaitEventPayload &payload)
    957     {
    958         Clear();
    959 
    960         int rc = VINF_SUCCESS;
    961         if (payload.cbData)
    962         {
    963             Assert(payload.cbData);
    964             pvData = RTMemAlloc(payload.cbData);
    965             if (pvData)
    966             {
    967                 memcpy(pvData, payload.pvData, payload.cbData);
    968                 cbData = payload.cbData;
    969                 uType = payload.uType;
    970             }
    971             else
    972                 rc = VERR_NO_MEMORY;
    973         }
    9741001
    9751002        return rc;
    976     }
    977 
    978     const void* Raw(void) const { return pvData; }
    979 
    980     size_t Size(void) const { return cbData; }
    981 
    982     uint32_t Type(void) const { return uType; }
    983 
    984     void* MutableRaw(void) { return pvData; }
    985 
    986     Utf8Str ToString(void)
    987     {
    988         const char  *pszStr = (const char *)pvData;
    989               size_t cbStr  = cbData;
    990 
    991         if (!RTStrValidateEncodingEx(pszStr, cbStr,
    992                                      RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED | RTSTR_VALIDATE_ENCODING_EXACT_LENGTH))
    993             return "";
    994 
    995         return Utf8Str(pszStr, cbStr);
    9961003    }
    9971004
     
    10031010    uint32_t cbData;
    10041011    /** Pointer to actual payload data. */
    1005     void *pvData;
     1012    void    *pvData;
    10061013};
    10071014
     
    11141121    int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID);
    11151122    int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent);
    1116     int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
     1123    int registerWaitEventEx(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
    11171124    int unregisterWaitEvent(GuestWaitEvent *pEvent);
    11181125    int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent);
  • trunk/src/VBox/Main/include/GuestDirectoryImpl.h

    r71250 r71406  
    3737    DECLARE_EMPTY_CTOR_DTOR(GuestDirectory)
    3838
    39     int     init(Console *pConsole, GuestSession *pSession, ULONG uDirID, const GuestDirectoryOpenInfo &openInfo);
     39    int     init(Console *pConsole, GuestSession *pSession, ULONG aObjectID, const GuestDirectoryOpenInfo &openInfo);
    4040    void    uninit(void);
    4141
     
    7979        /** The directory's open info. */
    8080        GuestDirectoryOpenInfo     mOpenInfo;
    81         /** The directory's ID. */
    82         uint32_t                   mID;
    8381        /** The process tool instance to use. */
    8482        GuestProcessTool           mProcessTool;
  • trunk/src/VBox/Main/include/GuestFileImpl.h

    r69500 r71406  
    123123        /** The file's initial size on open. */
    124124        uint64_t                mInitialSize;
    125         /** The file's ID. */
    126         uint32_t                mID;
    127125        /** The current file status. */
    128126        FileStatus_T            mStatus;
  • trunk/src/VBox/Main/include/GuestImpl.h

    r69500 r71406  
    55
    66/*
    7  * Copyright (C) 2006-2017 Oracle Corporation
     7 * Copyright (C) 2006-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    202202#ifdef VBOX_WITH_GUEST_CONTROL
    203203        GuestSessions               mGuestSessions;
    204         uint32_t                    mNextSessionID;
    205204#endif
    206205    } mData;
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r71301 r71406  
    4040    DECLARE_EMPTY_CTOR_DTOR(GuestProcess)
    4141
    42     int     init(Console *aConsole, GuestSession *aSession, ULONG aProcessID,
     42    int     init(Console *aConsole, GuestSession *aSession, ULONG aObjectID,
    4343                 const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv);
    4444    void    uninit(void);
     
    147147        /** Exit code if process has been terminated. */
    148148        LONG                     mExitCode;
    149         /** PID reported from the guest. */
     149        /** PID reported from the guest.
     150         *  Note: This is *not* the internal object ID! */
    150151        ULONG                    mPID;
    151152        /** The current process status. */
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r71345 r71406  
    3030
    3131#include <iprt/isofs.h> /* For UpdateAdditions. */
     32
     33#include <deque>
    3234
    3335class Guest;
     
    493495    typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
    494496
     497    /** Guest session object type enumeration. */
     498    enum SESSIONOBJECTTYPE
     499    {
     500        /** Anonymous object. */
     501        SESSIONOBJECTTYPE_ANONYMOUS  = 0,
     502        /** Session object. */
     503        SESSIONOBJECTTYPE_SESSION    = 1,
     504        /** Directory object. */
     505        SESSIONOBJECTTYPE_DIRECTORY  = 2,
     506        /** File object. */
     507        SESSIONOBJECTTYPE_FILE       = 3,
     508        /** Process object. */
     509        SESSIONOBJECTTYPE_PROCESS    = 4,
     510        /** The usual 32-bit hack. */
     511        SESSIONOBJECTTYPE_32BIT_HACK = 0x7fffffff
     512    };
     513
     514    struct SessionObject
     515    {
     516        /** Creation timestamp (in ms). */
     517        uint64_t          tsCreatedMs;
     518        /** The object type. */
     519        SESSIONOBJECTTYPE enmType;
     520    };
     521
     522    /** Map containing all objects bound to a guest session.
     523     *  The key specifies the (global) context ID. */
     524    typedef std::map <uint32_t, SessionObject> SessionObjects;
     525    /** Queue containing context IDs which are no longer in use.
     526     *  Useful for quickly retrieving a new, unused context ID. */
     527    typedef std::deque <uint32_t>              SessionObjectsFree;
     528
    495529public:
    496530    /** @name Public internal methods.
    497531     * @todo r=bird: Most of these are public for no real reason...
    498532     * @{ */
    499     int                     i_copyToGuestCreateDir(const com::Utf8Str &aDestination, uint32_t fFlags, int *pGuestRc);
    500533    int                     i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
    501534    inline bool             i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
    502     int                     i_directoryRemoveFromList(GuestDirectory *pDirectory);
     535    int                     i_directoryUnregister(GuestDirectory *pDirectory);
    503536    int                     i_directoryRemove(const Utf8Str &strPath, uint32_t uFlags, int *pGuestRc);
    504537    int                     i_directoryCreate(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, int *pGuestRc);
    505     int                     i_objectCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,
    506                                                Utf8Str &strName, int *pGuestRc);
    507538    int                     i_directoryOpen(const GuestDirectoryOpenInfo &openInfo,
    508539                                            ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc);
    509540    int                     i_directoryQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
    510     int                     i_dispatchToDirectory(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    511     int                     i_dispatchToFile(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    512541    int                     i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    513     int                     i_dispatchToProcess(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    514542    int                     i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    515543    inline bool             i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
    516     int                     i_fileRemoveFromList(GuestFile *pFile);
     544    int                     i_fileUnregister(GuestFile *pFile);
    517545    int                     i_fileRemove(const Utf8Str &strPath, int *pGuestRc);
    518546    int                     i_fileOpen(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pGuestRc);
    519547    int                     i_fileQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
    520548    int                     i_fileQuerySize(const Utf8Str &strPath, bool fFollowSymlinks, int64_t *pllSize, int *pGuestRc);
     549    int                     i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,
     550                                           Utf8Str &strName, int *pGuestRc);
    521551    int                     i_fsQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
    522552    const GuestCredentials &i_getCredentials(void);
     
    533563    Guest                  *i_getParent(void) { return mParent; }
    534564    uint32_t                i_getProtocolVersion(void) { return mData.mProtocolVersion; }
     565    int                     i_objectRegister(SESSIONOBJECTTYPE enmType, uint32_t *puObjectID);
     566    int                     i_objectRegisterEx(SESSIONOBJECTTYPE enmType, uint32_t fFlags, uint32_t *puObjectID);
     567    int                     i_objectUnregister(uint32_t uObjectID);
    535568    int                     i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *pGuestRc);
    536569    int                     i_pathUserDocuments(Utf8Str &strPath, int *prcGuest);
    537570    int                     i_pathUserHome(Utf8Str &strPath, int *prcGuest);
    538     int                     i_processRemoveFromList(GuestProcess *pProcess);
     571    int                     i_processUnregister(GuestProcess *pProcess);
    539572    int                     i_processCreateEx(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
    540573    inline bool             i_processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess);
     
    571604        /** The session's startup info. */
    572605        GuestSessionStartupInfo     mSession;
     606        /** The session's object ID.
     607         *  Needed for registering wait events which are bound directly to this session. */
     608        uint32_t                    mObjectID;
    573609        /** The session's current status. */
    574610        GuestSessionStatus_T        mStatus;
     
    586622        /** Process objects bound to this session. */
    587623        SessionProcesses            mProcesses;
     624        /** Map of registered session objects (files, directories, ...). */
     625        SessionObjects              mObjects;
     626        /** Queue of object IDs which are not used anymore (free list).
     627         *  Acts as a "free list" for the mObjects map. */
     628        SessionObjectsFree          mObjectsFree;
    588629        /** Guest control protocol version to be used.
    589630         *  Guest Additions < VBox 4.3 have version 1,
     
    592633        /** Session timeout (in ms). */
    593634        uint32_t                    mTimeout;
    594         /** Total number of session objects (processes,
    595          *  files, ...). */
    596         uint32_t                    mNumObjects;
    597635        /** The last returned session status
    598636         *  returned from the guest side. */
     
    611649            , mFiles(rThat.mFiles)
    612650            , mProcesses(rThat.mProcesses)
     651            , mObjects(rThat.mObjects)
     652            , mObjectsFree(rThat.mObjectsFree)
    613653            , mProtocolVersion(rThat.mProtocolVersion)
    614654            , mTimeout(rThat.mTimeout)
    615             , mNumObjects(rThat.mNumObjects)
    616655            , mRC(rThat.mRC)
    617656        { }
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r71349 r71406  
    8080     * changes to the object state.
    8181     */
    82     LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
    83                  pvExtension, u32Function, pvData, cbData));
     82    Log2Func(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
     83              pvExtension, u32Function, pvData, cbData));
     84
    8485    ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension);
    8586    Assert(!pGuest.isNull());
     
    9394     */
    9495    if (cbData != sizeof(VBOXGUESTCTRLHOSTCALLBACK))
    95         return VERR_NOT_SUPPORTED;
    96     PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData;
     96    {
     97        AssertMsgFailed(("Guest control host callback data has wrong size (expected %zu, got %zu)\n",
     98                         sizeof(VBOXGUESTCTRLHOSTCALLBACK), cbData));
     99        return VINF_SUCCESS; /* Never return any errors back to the guest here. */
     100    }
     101
     102    const PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData;
    97103    AssertPtr(pSvcCb);
    98104
    99     if (!pSvcCb->mParms) /* At least context ID must be present. */
    100         return VERR_INVALID_PARAMETER;
    101 
    102     uint32_t uContextID;
    103     int rc = pSvcCb->mpaParms[0].getUInt32(&uContextID);
    104     AssertMsgRCReturn(rc, ("Unable to extract callback context ID, pvData=%p\n", pSvcCb), rc);
    105 #ifdef DEBUG
    106     LogFlowFunc(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32\n",
    107                  uContextID,
    108                  VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID),
    109                  VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID),
    110                  VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID)));
    111 #endif
    112 
    113     VBOXGUESTCTRLHOSTCBCTX ctxCb = { u32Function, uContextID };
    114     rc = pGuest->i_dispatchToSession(&ctxCb, pSvcCb);
    115 
    116     LogFlowFunc(("Returning rc=%Rrc\n", rc));
    117     return rc;
     105    if (pSvcCb->mParms) /* At least context ID must be present. */
     106    {
     107        uint32_t uContextID;
     108        int rc = pSvcCb->mpaParms[0].getUInt32(&uContextID);
     109        AssertMsgRCReturn(rc, ("Unable to extract callback context ID, pvData=%p\n", pSvcCb),
     110                          VINF_SUCCESS /* Never return any errors back to the guest here */);
     111
     112        VBOXGUESTCTRLHOSTCBCTX ctxCb = { u32Function, uContextID };
     113        rc = pGuest->i_dispatchToSession(&ctxCb, pSvcCb);
     114
     115        Log2Func(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32, rc=%Rrc\n",
     116                  uContextID,
     117                  VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID),
     118                  VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID),
     119                  VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID), rc));
     120    }
     121
     122    /* Never return any errors back to the guest here. */
     123    return VINF_SUCCESS;
    118124}
    119125
     
    128134    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    129135
    130     LogFlowFunc(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n",
    131                   pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol));
     136    Log2Func(("uFunction=%RU32, uContextID=%RU32, uProtocol=%RU32\n", pCtxCb->uFunction, pCtxCb->uContextID, pCtxCb->uProtocol));
    132137
    133138    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    134139
    135     uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID);
    136 #ifdef DEBUG
    137     LogFlowFunc(("uSessionID=%RU32 (%zu total)\n",
    138                  uSessionID, mData.mGuestSessions.size()));
    139 #endif
    140     GuestSessions::const_iterator itSession
    141         = mData.mGuestSessions.find(uSessionID);
     140    const uint32_t uSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pCtxCb->uContextID);
     141
     142    Log2Func(("uSessionID=%RU32 (%zu total)\n", uSessionID, mData.mGuestSessions.size()));
     143
     144    GuestSessions::const_iterator itSession = mData.mGuestSessions.find(uSessionID);
    142145
    143146    int rc;
     
    188191                    break;
    189192
     193                /* Process stuff. */
    190194                case GUEST_EXEC_STATUS:
    191195                case GUEST_EXEC_OUTPUT:
    192196                case GUEST_EXEC_INPUT_STATUS:
    193197                case GUEST_EXEC_IO_NOTIFY:
    194                     rc = pSession->i_dispatchToProcess(pCtxCb, pSvcCb);
     198                    rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb);
    195199                    break;
    196200
     201                /* File stuff. */
    197202                case GUEST_FILE_NOTIFY:
    198                     rc = pSession->i_dispatchToFile(pCtxCb, pSvcCb);
     203                    rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb);
    199204                    break;
    200205
     206                /* Session stuff. */
    201207                case GUEST_SESSION_NOTIFY:
    202208                    rc = pSession->i_dispatchToThis(pCtxCb, pSvcCb);
     
    204210
    205211                default:
    206                     /*
    207                      * Try processing generic messages which might
    208                      * (or might not) supported by certain objects.
    209                      * If the message either is not found or supported
    210                      * by the approprirate object, try handling it
    211                      * in this session object.
    212                      */
    213212                    rc = pSession->i_dispatchToObject(pCtxCb, pSvcCb);
    214                     if (   rc == VERR_NOT_FOUND
    215                         || rc == VERR_NOT_SUPPORTED)
    216                     {
    217                         alock.acquire();
    218 
    219                         rc = pSession->dispatchGeneric(pCtxCb, pSvcCb);
    220                     }
    221 #ifndef DEBUG_andy
    222                     if (rc == VERR_NOT_IMPLEMENTED)
    223                         AssertMsgFailed(("Received not handled function %RU32\n", pCtxCb->uFunction));
    224 #endif
    225213                    break;
    226214            }
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r71326 r71406  
    681681}
    682682
     683/**
     684 * Handles generic messages not bound to a specific object type.
     685 *
     686 * @return VBox status code. VERR_NOT_FOUND if no handler has been found or VERR_NOT_SUPPORTED
     687 *         if this class does not support the specified callback.
     688 * @param  pCtxCb               Host callback context.
     689 * @param  pSvcCb               Service callback data.
     690 */
    683691int GuestBase::dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
    684692{
     
    692700    try
    693701    {
    694         LogFlowFunc(("uFunc=%RU32, cParms=%RU32\n",
    695                      pCtxCb->uFunction, pSvcCb->mParms));
     702        Log2Func(("uFunc=%RU32, cParms=%RU32\n", pCtxCb->uFunction, pSvcCb->mParms));
    696703
    697704        switch (pCtxCb->uFunction)
     
    716723                    GuestWaitEventPayload evPayload(dataCb.uType, dataCb.pvPayload, dataCb.cbPayload);
    717724                    vrc = signalWaitEventInternal(pCtxCb, dataCb.rc, &evPayload);
    718                     if (vrc == VERR_NOT_FOUND)
    719                         vrc = VINF_SUCCESS;
    720725                }
    721726                else
     
    766771}
    767772
    768 int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID,
    769                                  GuestWaitEvent **ppEvent)
     773/**
     774 * Registers (creates) a new wait event based on a given session and object ID.
     775 *
     776 * From those IDs an unique context ID (CID) will be built, which only can be
     777 * around once at a time.
     778 *
     779 * @returns IPRT status code. VERR_ALREADY_EXISTS if an event with the given session
     780 *          and object ID already has been registered.
     781 *
     782 * @param   uSessionID              Session ID to register wait event for.
     783 * @param   uObjectID               Object ID to register wait event for.
     784 * @param   ppEvent                 Pointer to registered (created) wait event on success.
     785 *                                  Must be destroyed with unregisterWaitEvent().
     786 */
     787int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent)
    770788{
    771789    GuestEventTypes eventTypesEmpty;
    772     return registerWaitEvent(uSessionID, uObjectID, eventTypesEmpty, ppEvent);
    773 }
    774 
    775 /**
    776  * Registers (creates) a new wait event based on a given session and object ID.
     790    return registerWaitEventEx(uSessionID, uObjectID, eventTypesEmpty, ppEvent);
     791}
     792
     793/**
     794 * Registers (creates) a new wait event based on a given session, object ID
     795 * and a list of event types to wait for.
    777796 *
    778797 * From those IDs an unique context ID (CID) will be built, which only can be
     
    788807 *                                  Must be destroyed with unregisterWaitEvent().
    789808 */
    790 int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID,
    791                                  const GuestEventTypes &lstEvents,
    792                                  GuestWaitEvent **ppEvent)
     809int GuestBase::registerWaitEventEx(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents,
     810                                   GuestWaitEvent **ppEvent)
    793811{
    794812    AssertPtrReturn(ppEvent, VERR_INVALID_POINTER);
     
    11071125{
    11081126    AssertPtr(mSession);
    1109     return GuestBase::registerWaitEvent(mSession->i_getId(), mObjectID, lstEvents, ppEvent);
     1127    return GuestBase::registerWaitEventEx(mSession->i_getId(), mObjectID, lstEvents, ppEvent);
    11101128}
    11111129
  • trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp

    r71302 r71406  
    5858/////////////////////////////////////////////////////////////////////////////
    5959
    60 int GuestDirectory::init(Console *pConsole, GuestSession *pSession,
    61                          ULONG uDirID, const GuestDirectoryOpenInfo &openInfo)
    62 {
    63     LogFlowThisFunc(("pConsole=%p, pSession=%p, uDirID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n",
    64                      pConsole, pSession, uDirID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(),
    65                      openInfo.mFlags));
     60int GuestDirectory::init(Console *pConsole, GuestSession *pSession, ULONG aObjectID, const GuestDirectoryOpenInfo &openInfo)
     61{
     62    LogFlowThisFunc(("pConsole=%p, pSession=%p, aObjectID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n",
     63                     pConsole, pSession, aObjectID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(), openInfo.mFlags));
    6664
    6765    AssertPtrReturn(pConsole, VERR_INVALID_POINTER);
     
    7270    AssertReturn(autoInitSpan.isOk(), E_FAIL);
    7371
    74     int vrc = bindToSession(pConsole, pSession, uDirID /* Object ID */);
     72    int vrc = bindToSession(pConsole, pSession, aObjectID);
    7573    if (RT_SUCCESS(vrc))
    7674    {
    77         mSession = pSession;
    78 
    79         mData.mID = uDirID;
     75        mSession  = pSession;
     76        mObjectID = aObjectID;
     77
    8078        mData.mOpenInfo = openInfo;
    8179    }
     
    262260
    263261    AssertPtr(mSession);
    264     int rc2 = mSession->i_directoryRemoveFromList(this);
     262    int rc2 = mSession->i_directoryUnregister(this);
    265263    if (RT_SUCCESS(rc))
    266264        rc = rc2;
  • trunk/src/VBox/Main/src-client/GuestFileImpl.cpp

    r71299 r71406  
    135135 * @param   pConsole                Pointer to console object.
    136136 * @param   pSession                Pointer to session object.
    137  * @param   uFileID                 Host-based file ID (part of the context ID).
     137 * @param   aObjectID               The object's ID.
    138138 * @param   openInfo                File opening information.
    139139 */
    140140int GuestFile::init(Console *pConsole, GuestSession *pSession,
    141                     ULONG uFileID, const GuestFileOpenInfo &openInfo)
    142 {
    143     LogFlowThisFunc(("pConsole=%p, pSession=%p, uFileID=%RU32, strPath=%s\n",
    144                      pConsole, pSession, uFileID, openInfo.mFileName.c_str()));
     141                    ULONG aObjectID, const GuestFileOpenInfo &openInfo)
     142{
     143    LogFlowThisFunc(("pConsole=%p, pSession=%p, aObjectID=%RU32, strPath=%s\n",
     144                     pConsole, pSession, aObjectID, openInfo.mFileName.c_str()));
    145145
    146146    AssertPtrReturn(pConsole, VERR_INVALID_POINTER);
     
    151151    AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED);
    152152
    153     int vrc = bindToSession(pConsole, pSession, uFileID /* Object ID */);
     153    int vrc = bindToSession(pConsole, pSession, aObjectID);
    154154    if (RT_SUCCESS(vrc))
    155155    {
    156156        mSession = pSession;
    157157
    158         mData.mID = uFileID;
    159158        mData.mInitialSize = 0;
    160159        mData.mStatus = FileStatus_Undefined;
     
    278277    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    279278
    280     *aId = mData.mID;
     279    *aId = mObjectID;
    281280
    282281    return S_OK;
     
    381380    int i = 0;
    382381    paParms[i++].setUInt32(pEvent->ContextID());
    383     paParms[i++].setUInt32(mData.mID /* Guest file ID */);
     382    paParms[i++].setUInt32(mObjectID /* Guest file ID */);
    384383
    385384    vrc = sendCommand(HOST_FILE_CLOSE, i, paParms);
     
    453452        AssertRC(rc2);
    454453
    455         rc2 = signalWaitEventInternal(pCbCtx,
    456                                       rcGuest, NULL /* pPayload */);
     454        rc2 = signalWaitEventInternal(pCbCtx, rcGuest, NULL /* pPayload */);
    457455        AssertRC(rc2);
    458456
     
    476474                pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);
    477475
    478                 AssertMsg(mData.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
    479                           ("File ID %RU32 does not match context ID %RU32\n", mData.mID,
     476                AssertMsg(mObjectID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
     477                          ("File ID %RU32 does not match object ID %RU32\n", mObjectID,
    480478                           VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID)));
    481479
     
    687685    vrc = sendCommand(HOST_FILE_OPEN, i, paParms);
    688686    if (RT_SUCCESS(vrc))
    689         vrc = i_waitForStatusChange(pEvent, uTimeoutMS,
    690                                     NULL /* FileStatus */, prcGuest);
     687        vrc = i_waitForStatusChange(pEvent, uTimeoutMS, NULL /* FileStatus */, prcGuest);
    691688
    692689    unregisterWaitEvent(pEvent);
     
    730727    int i = 0;
    731728    paParms[i++].setUInt32(pEvent->ContextID());
    732     paParms[i++].setUInt32(mData.mID /* File handle */);
     729    paParms[i++].setUInt32(mObjectID /* File handle */);
    733730    paParms[i++].setUInt32(uSize /* Size (in bytes) to read */);
    734731
     
    785782    int i = 0;
    786783    paParms[i++].setUInt32(pEvent->ContextID());
    787     paParms[i++].setUInt32(mData.mID /* File handle */);
     784    paParms[i++].setUInt32(mObjectID /* File handle */);
    788785    paParms[i++].setUInt64(uOffset /* Offset (in bytes) to start reading */);
    789786    paParms[i++].setUInt32(uSize /* Size (in bytes) to read */);
     
    842839    int i = 0;
    843840    paParms[i++].setUInt32(pEvent->ContextID());
    844     paParms[i++].setUInt32(mData.mID /* File handle */);
     841    paParms[i++].setUInt32(mObjectID /* File handle */);
    845842    paParms[i++].setUInt32(eSeekType /* Seek method */);
    846843    /** @todo uint64_t vs. int64_t! */
     
    10911088    int i = 0;
    10921089    paParms[i++].setUInt32(pEvent->ContextID());
    1093     paParms[i++].setUInt32(mData.mID /* File handle */);
     1090    paParms[i++].setUInt32(mObjectID /* File handle */);
    10941091    paParms[i++].setUInt32(cbData /* Size (in bytes) to write */);
    10951092    paParms[i++].setPointer(pvData, cbData);
     
    11501147    int i = 0;
    11511148    paParms[i++].setUInt32(pEvent->ContextID());
    1152     paParms[i++].setUInt32(mData.mID /* File handle */);
     1149    paParms[i++].setUInt32(mObjectID /* File handle */);
    11531150    paParms[i++].setUInt64(uOffset /* Offset where to starting writing */);
    11541151    paParms[i++].setUInt32(cbData /* Size (in bytes) to write */);
     
    11891186
    11901187    AssertPtr(mSession);
    1191     int rc2 = mSession->i_fileRemoveFromList(this);
     1188    int rc2 = mSession->i_fileUnregister(this);
    11921189    if (RT_SUCCESS(rc))
    11931190        rc = rc2;
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r71349 r71406  
    178178/////////////////////////////////////////////////////////////////////////////
    179179
    180 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID,
     180int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aObjectID,
    181181                       const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv)
    182182{
    183     LogFlowThisFunc(("aConsole=%p, aSession=%p, aProcessID=%RU32 pBaseEnv=%p\n",
    184                      aConsole, aSession, aProcessID, pBaseEnv));
     183    LogFlowThisFunc(("aConsole=%p, aSession=%p, aObjectID=%RU32, pBaseEnv=%p\n",
     184                     aConsole, aSession, aObjectID, pBaseEnv));
    185185
    186186    AssertPtrReturn(aConsole, VERR_INVALID_POINTER);
     
    193193    HRESULT hr;
    194194
    195     int vrc = bindToSession(aConsole, aSession, aProcessID /* Object ID */);
     195    int vrc = bindToSession(aConsole, aSession, aObjectID);
    196196    if (RT_SUCCESS(vrc))
    197197    {
     
    293293    }
    294294
     295    AssertPtr(mSession);
     296    mSession->i_processUnregister(this);
     297
    295298    baseUninit();
    296299
    297     LogFlowThisFunc(("Returning rc=%Rrc, rcGuest=%Rrc\n",
    298                      vrc, rcGuest));
     300    LogFlowThisFunc(("Returning rc=%Rrc, rcGuest=%Rrc\n", vrc, rcGuest));
    299301    RT_NOREF_PV(vrc);
    300302}
     
    337339    }
    338340    else
    339         hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by the guest additions"));
     341        hrc = setError(VBOX_E_NOT_SUPPORTED, tr("The base environment feature is not supported by installed Guest Additions"));
    340342    LogFlowThisFuncLeave();
    341343    return hrc;
     
    18041806
    18051807    int rcGuest;
    1806     int vrc = i_terminateProcess(30 * 1000 /* Timeout in ms */,
    1807                                  &rcGuest);
     1808    int vrc = i_terminateProcess(30 * 1000 /* Timeout in ms */, &rcGuest);
    18081809    if (RT_FAILURE(vrc))
    18091810    {
     
    18311832     * still can hold references to it. */
    18321833    AssertPtr(mSession);
    1833     int rc2 = mSession->i_processRemoveFromList(this);
     1834    int rc2 = mSession->i_processUnregister(this);
    18341835    if (RT_SUCCESS(vrc))
    18351836        vrc = rc2;
     
    19521953GuestProcessTool::~GuestProcessTool(void)
    19531954{
    1954     terminate(30 * 1000, NULL /* prcGuest */);
     1955     if (!pProcess.isNull())
     1956     {
     1957         /* Terminate (and unregister) process. */
     1958         pProcess->uninit();
     1959
     1960         /* Release reference. */
     1961         pProcess.setNull();
     1962     }
    19551963}
    19561964
     
    24392447    LogFlowThisFuncEnter();
    24402448
    2441     int rc = VINF_SUCCESS;
     2449    int rc;
    24422450    if (!pProcess.isNull())
    2443     {
    24442451        rc = pProcess->i_terminateProcess(uTimeoutMS, prcGuest);
    2445         pProcess.setNull();
    2446     }
    24472452    else
    24482453        rc = VERR_NOT_FOUND;
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r71349 r71406  
    208208    mData.mSession.mOpenTimeoutMS = ssInfo.mOpenTimeoutMS;
    209209
     210    /* Copy over session credentials. */
    210211    /** @todo Use an overloaded copy operator. Later. */
    211212    mData.mCredentials.mUser = guestCreds.mUser;
     
    216217    mData.mRC = VINF_SUCCESS;
    217218    mData.mStatus = GuestSessionStatus_Undefined;
    218     mData.mNumObjects = 0;
    219219    mData.mpBaseEnvironment = NULL;
    220     int rc = mData.mEnvironmentChanges.initChangeRecord();
     220
     221    /*
     222     * Register an object for the session itself to clearly
     223     * distinguish callbacks which are for this session directly, or for
     224     * objects (like files, directories, ...) which are bound to this session.
     225     */
     226    int rc = i_objectRegister(SESSIONOBJECTTYPE_SESSION, &mData.mObjectID);
    221227    if (RT_SUCCESS(rc))
    222228    {
    223         rc = RTCritSectInit(&mWaitEventCritSect);
    224         AssertRC(rc);
    225     }
     229        rc = mData.mEnvironmentChanges.initChangeRecord();
     230        if (RT_SUCCESS(rc))
     231        {
     232            rc = RTCritSectInit(&mWaitEventCritSect);
     233            AssertRC(rc);
     234        }
     235    }
     236
    226237    if (RT_SUCCESS(rc))
    227238        rc = i_determineProtocolVersion();
     239
    228240    if (RT_SUCCESS(rc))
    229241    {
     
    298310         itDirs != mData.mDirectories.end(); ++itDirs)
    299311    {
    300         Assert(mData.mNumObjects);
    301         mData.mNumObjects--;
    302312        itDirs->second->i_onRemove();
    303313        itDirs->second->uninit();
     
    310320         itFiles != mData.mFiles.end(); ++itFiles)
    311321    {
    312         Assert(mData.mNumObjects);
    313         mData.mNumObjects--;
    314322        itFiles->second->i_onRemove();
    315323        itFiles->second->uninit();
     
    322330         itProcs != mData.mProcesses.end(); ++itProcs)
    323331    {
    324         Assert(mData.mNumObjects);
    325         mData.mNumObjects--;
    326332        itProcs->second->i_onRemove();
    327333        itProcs->second->uninit();
     
    329335    mData.mProcesses.clear();
    330336
     337    /* Unregister the session's object ID. */
     338    i_objectUnregister(mData.mObjectID);
     339
     340    mData.mObjects.clear();
     341    mData.mObjectsFree.clear();
     342
    331343    mData.mEnvironmentChanges.reset();
    332344
     
    336348        mData.mpBaseEnvironment = NULL;
    337349    }
    338 
    339     AssertMsg(mData.mNumObjects == 0,
    340               ("mNumObjects=%RU32 when it should be 0\n", mData.mNumObjects));
    341350
    342351    /* Unitialize our local listener. */
     
    698707        eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged);
    699708
    700         vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */,
    701                                 eventTypes, &pEvent);
     709        vrc = registerWaitEventEx(mData.mSession.mID, mData.mObjectID, eventTypes, &pEvent);
    702710    }
    703711    catch (std::bad_alloc)
     
    815823}
    816824
    817 int GuestSession::i_directoryRemoveFromList(GuestDirectory *pDirectory)
     825/**
     826 * Unregisters a directory object from a session.
     827 *
     828 * @return VBox status code. VERR_NOT_FOUND if the directory is not registered (anymore).
     829 * @param  pDirectory           Directory object to unregister from session.
     830 */
     831int GuestSession::i_directoryUnregister(GuestDirectory *pDirectory)
    818832{
    819833    AssertPtrReturn(pDirectory, VERR_INVALID_POINTER);
    820834
     835    LogFlowThisFunc(("pDirectory=%p\n", pDirectory));
     836
    821837    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    822838
    823     int rc = VERR_NOT_FOUND;
    824 
    825     SessionDirectories::iterator itDirs = mData.mDirectories.begin();
    826     while (itDirs != mData.mDirectories.end())
    827     {
    828         if (pDirectory == itDirs->second)
    829         {
    830             /* Make sure to consume the pointer before the one of the
    831              * iterator gets released. */
    832             ComObjPtr<GuestDirectory> pDir = pDirectory;
    833 
    834             Bstr strName;
    835             HRESULT hr = itDirs->second->COMGETTER(DirectoryName)(strName.asOutParam());
    836             ComAssertComRC(hr);
    837 
    838             Assert(mData.mDirectories.size());
    839             Assert(mData.mNumObjects);
    840             LogFlowFunc(("Removing directory \"%s\" (Session: %RU32) (now total %zu processes, %RU32 objects)\n",
    841                          Utf8Str(strName).c_str(), mData.mSession.mID, mData.mDirectories.size() - 1, mData.mNumObjects - 1));
    842 
    843             rc = pDirectory->i_onRemove();
    844             mData.mDirectories.erase(itDirs);
    845             mData.mNumObjects--;
    846 
    847             pDir.setNull();
    848             break;
    849         }
    850 
    851         ++itDirs;
    852     }
     839    const uint32_t uObjectID = pDirectory->getObjectID();
     840
     841    LogFlowFunc(("Removing directory (objectID=%RU32) ...\n", uObjectID));
     842
     843    int rc = i_objectUnregister(uObjectID);
     844    if (RT_FAILURE(rc))
     845        return rc;
     846
     847    SessionDirectories::iterator itDirs = mData.mDirectories.find(uObjectID);
     848    AssertReturn(itDirs != mData.mDirectories.end(), VERR_NOT_FOUND);
     849
     850    /* Make sure to consume the pointer before the one of the iterator gets released. */
     851    ComObjPtr<GuestDirectory> pDirConsumed = pDirectory;
     852
     853    LogFlowFunc(("Removing directory ID=%RU32 (session %RU32, now total %zu directories)\n",
     854                 uObjectID, mData.mSession.mID, mData.mDirectories.size()));
     855
     856    rc = pDirConsumed->i_onRemove();
     857    AssertRCReturn(rc, rc);
     858
     859    mData.mDirectories.erase(itDirs);
     860
     861    alock.release(); /* Release lock before firing off event. */
     862
     863//    fireGuestDirectoryRegisteredEvent(mEventSource, this /* Session */, pDirConsumed, false /* Process unregistered */);
     864
     865    pDirConsumed.setNull();
    853866
    854867    LogFlowFuncLeaveRC(rc);
     
    866879
    867880    GuestWaitEvent *pEvent = NULL;
    868     int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */,
    869                                 &pEvent);
     881    int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
    870882    if (RT_FAILURE(vrc))
    871883        return vrc;
     
    896908}
    897909
    898 int GuestSession::i_objectCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath,
    899                                      bool fDirectory, Utf8Str &strName, int *prcGuest)
     910int GuestSession::i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory, Utf8Str &strName,
     911                                 int *prcGuest)
    900912{
    901913    AssertPtrReturn(prcGuest, VERR_INVALID_POINTER);
     
    931943    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    932944    GuestCtrlStreamObjects stdOut;
    933     int vrc = GuestProcessTool::runEx(this, procInfo,
    934                                         &stdOut, 1 /* cStrmOutObjects */,
    935                                         &vrcGuest);
     945    int vrc = GuestProcessTool::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
    936946    if (!GuestProcess::i_isGuestError(vrc))
    937947    {
     
    971981    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    972982
    973     int rc = VERR_GSTCTL_MAX_OBJECTS_REACHED;
    974     if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS)
    975         return rc;
    976 
    977     /* Create a new (host-based) directory ID and assign it. */
    978     uint32_t uNewDirID = 0;
    979     ULONG uTries = 0;
    980 
    981     for (;;)
    982     {
    983         /* Is the directory ID already used? */
    984         if (!i_directoryExists(uNewDirID, NULL /* pDirectory */))
    985         {
    986             /* Callback with context ID was not found. This means
    987              * we can use this context ID for our new callback we want
    988              * to add below. */
    989             rc = VINF_SUCCESS;
    990             break;
    991         }
    992         uNewDirID++;
    993         if (uNewDirID == VBOX_GUESTCTRL_MAX_OBJECTS)
    994             uNewDirID = 0;
    995 
    996         if (++uTries == UINT32_MAX)
    997             break; /* Don't try too hard. */
    998     }
    999 
     983    /* Register a new object ID. */
     984    uint32_t uObjectID;
     985    int rc = i_objectRegister(SESSIONOBJECTTYPE_DIRECTORY, &uObjectID);
    1000986    if (RT_FAILURE(rc))
    1001987        return rc;
     
    1009995    AssertPtr(pConsole);
    1010996
    1011     int vrc = pDirectory->init(pConsole, this /* Parent */,
    1012                                uNewDirID, openInfo);
     997    int vrc = pDirectory->init(pConsole, this /* Parent */, uObjectID, openInfo);
    1013998    if (RT_FAILURE(vrc))
    1014999        return vrc;
     
    10241009    {
    10251010        /* Add the created directory to our map. */
    1026         mData.mDirectories[uNewDirID] = pDirectory;
    1027         mData.mNumObjects++;
    1028         Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS);
    1029 
    1030         LogFlowFunc(("Added new guest directory \"%s\" (Session: %RU32) (now total %zu dirs, %RU32 objects)\n",
    1031                      openInfo.mPath.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects));
     1011        mData.mDirectories[uObjectID] = pDirectory;
     1012
     1013        LogFlowFunc(("Added new guest directory \"%s\" (Session: %RU32) (now total %zu directories)\n",
     1014                     openInfo.mPath.c_str(), mData.mSession.mID, mData.mDirectories.size()));
    10321015
    10331016        alock.release(); /* Release lock before firing off event. */
     
    10511034}
    10521035
    1053 int GuestSession::i_dispatchToDirectory(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
     1036/**
     1037 * Dispatches a host callback to its corresponding object.
     1038 *
     1039 * @return VBox status code. VERR_NOT_FOUND if no corresponding object was found.
     1040 * @param  pCtxCb               Host callback context.
     1041 * @param  pSvcCb               Service callback data.
     1042 */
     1043int GuestSession::i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
    10541044{
    10551045    LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));
     
    10581048    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    10591049
    1060     if (pSvcCb->mParms < 3)
    1061         return VERR_INVALID_PARAMETER;
    1062 
    10631050    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    10641051
    1065     uint32_t uDirID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
    1066 #ifdef DEBUG
    1067     LogFlowFunc(("uDirID=%RU32 (%zu total)\n",
    1068                  uDirID, mData.mFiles.size()));
    1069 #endif
    1070     int rc;
    1071     SessionDirectories::const_iterator itDir
    1072         = mData.mDirectories.find(uDirID);
    1073     if (itDir != mData.mDirectories.end())
    1074     {
    1075         ComObjPtr<GuestDirectory> pDirectory(itDir->second);
    1076         Assert(!pDirectory.isNull());
    1077 
    1078         alock.release();
    1079 
    1080         rc = pDirectory->i_callbackDispatcher(pCtxCb, pSvcCb);
    1081     }
    1082     else
    1083         rc = VERR_NOT_FOUND;
    1084 
    1085     LogFlowFuncLeaveRC(rc);
    1086     return rc;
    1087 }
    1088 
    1089 int GuestSession::i_dispatchToFile(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
    1090 {
    1091     LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));
    1092 
    1093     AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);
    1094     AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    1095 
    1096     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1097 
    1098     uint32_t uFileID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
    1099 #ifdef DEBUG
    1100     LogFlowFunc(("uFileID=%RU32 (%zu total)\n",
    1101                  uFileID, mData.mFiles.size()));
    1102 #endif
    1103     int rc;
    1104     SessionFiles::const_iterator itFile
    1105         = mData.mFiles.find(uFileID);
    1106     if (itFile != mData.mFiles.end())
    1107     {
    1108         ComObjPtr<GuestFile> pFile(itFile->second);
    1109         Assert(!pFile.isNull());
    1110 
    1111         alock.release();
    1112 
    1113         rc = pFile->i_callbackDispatcher(pCtxCb, pSvcCb);
    1114     }
    1115     else
    1116         rc = VERR_NOT_FOUND;
    1117 
    1118     LogFlowFuncLeaveRC(rc);
    1119     return rc;
    1120 }
    1121 
    1122 int GuestSession::i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
    1123 {
    1124     LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));
    1125 
    1126     AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);
    1127     AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    1128 
    1129     int rc;
    1130     uint32_t uObjectID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
    1131 
    1132     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1133 
    1134     /* Since we don't know which type the object is, we need to through all
    1135      * all objects. */
    1136     /** @todo Speed this up by adding an object type to the callback context! */
    1137     SessionProcesses::const_iterator itProc = mData.mProcesses.find(uObjectID);
    1138     if (itProc == mData.mProcesses.end())
    1139     {
    1140         SessionFiles::const_iterator itFile = mData.mFiles.find(uObjectID);
    1141         if (itFile != mData.mFiles.end())
     1052    const uint32_t uObjectID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
     1053
     1054    int rc = VERR_NOT_FOUND;
     1055
     1056    SessionObjects::const_iterator itObjs = mData.mObjects.find(uObjectID);
     1057
     1058    if (itObjs == mData.mObjects.end())
     1059        return rc;
     1060
     1061    /* Set protocol version so that pSvcCb can be interpreted right. */
     1062    pCtxCb->uProtocol = mData.mProtocolVersion;
     1063
     1064    switch (itObjs->second.enmType)
     1065    {
     1066        case SESSIONOBJECTTYPE_ANONYMOUS:
     1067            rc = VERR_NOT_SUPPORTED;
     1068            break;
     1069
     1070        case SESSIONOBJECTTYPE_SESSION:
    11421071        {
    11431072            alock.release();
    11441073
    1145             rc = i_dispatchToFile(pCtxCb, pSvcCb);
    1146         }
    1147         else
     1074            rc = i_dispatchToThis(pCtxCb, pSvcCb);
     1075            break;
     1076        }
     1077        case SESSIONOBJECTTYPE_DIRECTORY:
    11481078        {
    11491079            SessionDirectories::const_iterator itDir = mData.mDirectories.find(uObjectID);
    11501080            if (itDir != mData.mDirectories.end())
    11511081            {
     1082                ComObjPtr<GuestDirectory> pDirectory(itDir->second);
     1083                Assert(!pDirectory.isNull());
     1084
    11521085                alock.release();
    11531086
    1154                 rc = i_dispatchToDirectory(pCtxCb, pSvcCb);
     1087                rc = pDirectory->i_callbackDispatcher(pCtxCb, pSvcCb);
    11551088            }
    1156             else
    1157                 rc = VERR_NOT_FOUND;
    1158         }
    1159     }
    1160     else
    1161     {
    1162         alock.release();
    1163 
    1164         rc = i_dispatchToProcess(pCtxCb, pSvcCb);
     1089            break;
     1090        }
     1091        case SESSIONOBJECTTYPE_FILE:
     1092        {
     1093            SessionFiles::const_iterator itFile = mData.mFiles.find(uObjectID);
     1094            if (itFile != mData.mFiles.end())
     1095            {
     1096                ComObjPtr<GuestFile> pFile(itFile->second);
     1097                Assert(!pFile.isNull());
     1098
     1099                alock.release();
     1100
     1101                rc = pFile->i_callbackDispatcher(pCtxCb, pSvcCb);
     1102            }
     1103            break;
     1104        }
     1105        case SESSIONOBJECTTYPE_PROCESS:
     1106        {
     1107            SessionProcesses::const_iterator itProc = mData.mProcesses.find(uObjectID);
     1108            if (itProc != mData.mProcesses.end())
     1109            {
     1110                ComObjPtr<GuestProcess> pProcess(itProc->second);
     1111                Assert(!pProcess.isNull());
     1112
     1113                alock.release();
     1114
     1115                rc = pProcess->i_callbackDispatcher(pCtxCb, pSvcCb);
     1116            }
     1117            break;
     1118        }
     1119        default:
     1120            AssertFailed();
     1121            break;
    11651122    }
    11661123
     
    11691126}
    11701127
    1171 int GuestSession::i_dispatchToProcess(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
    1172 {
    1173     LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));
    1174 
    1175     AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);
    1176     AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
    1177 
    1178     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1179 
    1180     uint32_t uProcessID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCtxCb->uContextID);
    1181 #ifdef DEBUG
    1182     LogFlowFunc(("uProcessID=%RU32 (%zu total)\n",
    1183                  uProcessID, mData.mProcesses.size()));
    1184 #endif
    1185     int rc;
    1186     SessionProcesses::const_iterator itProc
    1187         = mData.mProcesses.find(uProcessID);
    1188     if (itProc != mData.mProcesses.end())
    1189     {
    1190 #ifdef DEBUG_andy
    1191         ULONG cRefs = itProc->second->AddRef();
    1192         Assert(cRefs >= 2);
    1193         LogFlowFunc(("pProcess=%p, cRefs=%RU32\n", &itProc->second, cRefs - 1));
    1194         itProc->second->Release();
    1195 #endif
    1196         ComObjPtr<GuestProcess> pProcess(itProc->second);
    1197         Assert(!pProcess.isNull());
    1198 
    1199         /* Set protocol version so that pSvcCb can
    1200          * be interpreted right. */
    1201         pCtxCb->uProtocol = mData.mProtocolVersion;
    1202 
    1203         alock.release();
    1204         rc = pProcess->i_callbackDispatcher(pCtxCb, pSvcCb);
    1205     }
    1206     else
    1207         rc = VERR_NOT_FOUND;
    1208 
    1209     LogFlowFuncLeaveRC(rc);
    1210     return rc;
    1211 }
    1212 
    12131128int GuestSession::i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
    12141129{
     
    12181133    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    12191134
    1220 #ifdef DEBUG
    12211135    LogFlowThisFunc(("sessionID=%RU32, CID=%RU32, uFunction=%RU32, pSvcCb=%p\n",
    12221136                     mData.mSession.mID, pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
    1223 #endif
    1224 
    12251137    int rc;
    12261138    switch (pCbCtx->uFunction)
     
    12381150
    12391151        default:
    1240             /* Silently skip unknown callbacks. */
    1241             rc = VERR_NOT_SUPPORTED;
     1152            rc = dispatchGeneric(pCbCtx, pSvcCb);
    12421153            break;
    12431154    }
     
    12591170}
    12601171
    1261 int GuestSession::i_fileRemoveFromList(GuestFile *pFile)
    1262 {
     1172/**
     1173 * Unregisters a file object from a session.
     1174 *
     1175 * @return VBox status code. VERR_NOT_FOUND if the file is not registered (anymore).
     1176 * @param  pFile                File object to unregister from session.
     1177 */
     1178int GuestSession::i_fileUnregister(GuestFile *pFile)
     1179{
     1180    AssertPtrReturn(pFile, VERR_INVALID_POINTER);
     1181
     1182    LogFlowThisFunc(("pFile=%p\n", pFile));
     1183
    12631184    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    12641185
    1265     int rc = VERR_NOT_FOUND;
    1266 
    1267     SessionFiles::iterator itFiles = mData.mFiles.begin();
    1268     while (itFiles != mData.mFiles.end())
    1269     {
    1270         if (pFile == itFiles->second)
    1271         {
    1272             /* Make sure to consume the pointer before the one of thfe
    1273              * iterator gets released. */
    1274             ComObjPtr<GuestFile> pCurFile = pFile;
    1275 
    1276             Bstr strName;
    1277             HRESULT hr = pCurFile->COMGETTER(FileName)(strName.asOutParam());
    1278             ComAssertComRC(hr);
    1279 
    1280             Assert(mData.mNumObjects);
    1281             LogFlowThisFunc(("Removing guest file \"%s\" (Session: %RU32) (now total %zu files, %RU32 objects)\n",
    1282                              Utf8Str(strName).c_str(), mData.mSession.mID, mData.mFiles.size() - 1, mData.mNumObjects - 1));
    1283 
    1284             rc = pFile->i_onRemove();
    1285             mData.mFiles.erase(itFiles);
    1286             mData.mNumObjects--;
    1287 
    1288             alock.release(); /* Release lock before firing off event. */
    1289 
    1290             fireGuestFileRegisteredEvent(mEventSource, this, pCurFile,
    1291                                          false /* Unregistered */);
    1292             pCurFile.setNull();
    1293             break;
    1294         }
    1295 
    1296         ++itFiles;
    1297     }
     1186    const uint32_t uObjectID = pFile->getObjectID();
     1187
     1188    LogFlowFunc(("Removing file (objectID=%RU32) ...\n", uObjectID));
     1189
     1190    int rc = i_objectUnregister(uObjectID);
     1191    if (RT_FAILURE(rc))
     1192        return rc;
     1193
     1194    SessionFiles::iterator itFiles = mData.mFiles.find(uObjectID);
     1195    AssertReturn(itFiles != mData.mFiles.end(), VERR_NOT_FOUND);
     1196
     1197    /* Make sure to consume the pointer before the one of the iterator gets released. */
     1198    ComObjPtr<GuestFile> pFileConsumed = pFile;
     1199
     1200    LogFlowFunc(("Removing file ID=%RU32 (session %RU32, now total %zu files)\n",
     1201                 pFileConsumed->getObjectID(), mData.mSession.mID, mData.mFiles.size()));
     1202
     1203    rc = pFileConsumed->i_onRemove();
     1204    AssertRCReturn(rc, rc);
     1205
     1206    mData.mFiles.erase(itFiles);
     1207
     1208    alock.release(); /* Release lock before firing off event. */
     1209
     1210    fireGuestFileRegisteredEvent(mEventSource, this, pFileConsumed, false /* Unregistered */);
     1211
     1212    pFileConsumed.setNull();
    12981213
    12991214    LogFlowFuncLeaveRC(rc);
     
    13411256    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    13421257
    1343     /* Guest Additions < 4.3 don't support handling
    1344        guest files, skip. */
     1258    /* Guest Additions < 4.3 don't support handling guest files, skip. */
    13451259    if (mData.mProtocolVersion < 2)
    13461260    {
    1347         LogFlowThisFunc(("Installed Guest Additions don't support handling guest files, skipping\n"));
    1348         return VERR_NOT_SUPPORTED;
    1349     }
    1350 
    1351     int rc = VERR_GSTCTL_MAX_OBJECTS_REACHED;
    1352     if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS)
    1353         return rc;
    1354 
    1355     /* Create a new (host-based) file ID and assign it. */
    1356     uint32_t uNewFileID = 0;
    1357     ULONG uTries = 0;
    1358 
    1359     for (;;)
    1360     {
    1361         /* Is the file ID already used? */
    1362         if (!i_fileExists(uNewFileID, NULL /* pFile */))
    1363         {
    1364             /* Callback with context ID was not found. This means
    1365              * we can use this context ID for our new callback we want
    1366              * to add below. */
    1367             rc = VINF_SUCCESS;
    1368             break;
    1369         }
    1370         uNewFileID++;
    1371         if (uNewFileID == VBOX_GUESTCTRL_MAX_OBJECTS)
    1372             uNewFileID = 0;
    1373 
    1374         if (++uTries == UINT32_MAX)
    1375             break; /* Don't try too hard. */
    1376     }
    1377 
     1261        if (prcGuest)
     1262            *prcGuest = VERR_NOT_SUPPORTED;
     1263        return VERR_GSTCTL_GUEST_ERROR;
     1264    }
     1265
     1266    /* Register a new object ID. */
     1267    uint32_t uObjectID;
     1268    int rc = i_objectRegister(SESSIONOBJECTTYPE_FILE, &uObjectID);
    13781269    if (RT_FAILURE(rc))
    13791270        return rc;
     
    13871278    AssertPtr(pConsole);
    13881279
    1389     rc = pFile->init(pConsole, this /* GuestSession */,
    1390                      uNewFileID, openInfo);
     1280    rc = pFile->init(pConsole, this /* GuestSession */, uObjectID, openInfo);
    13911281    if (RT_FAILURE(rc))
    13921282        return rc;
     
    14021292    {
    14031293        /* Add the created file to our vector. */
    1404         mData.mFiles[uNewFileID] = pFile;
    1405         mData.mNumObjects++;
    1406         Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS);
    1407 
    1408         LogFlowFunc(("Added new guest file \"%s\" (Session: %RU32) (now total %zu files, %RU32 objects)\n",
    1409                      openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size(), mData.mNumObjects));
     1294        mData.mFiles[uObjectID] = pFile;
     1295
     1296        LogFlowFunc(("Added new guest file \"%s\" (Session: %RU32) (now total %zu files)\n",
     1297                     openInfo.mFileName.c_str(), mData.mSession.mID, mData.mFiles.size()));
    14101298
    14111299        alock.release(); /* Release lock before firing off event. */
    14121300
    1413         fireGuestFileRegisteredEvent(mEventSource, this, pFile,
    1414                                      true /* Registered */);
     1301        fireGuestFileRegisteredEvent(mEventSource, this, pFile, true /* Registered */);
    14151302    }
    14161303    catch (std::bad_alloc &)
     
    17561643        eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged);
    17571644
    1758         vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */,
    1759                                 eventTypes, &pEvent);
     1645        vrc = registerWaitEventEx(mData.mSession.mID, mData.mObjectID, eventTypes, &pEvent);
    17601646    }
    17611647    catch (std::bad_alloc)
     
    18691755}
    18701756
     1757/**
     1758 * Registers an object to a session.
     1759 *
     1760 * @return VBox status code.
     1761 * @param  enmType              Session object type to register.
     1762 * @param  puObjectID           Returns registered object ID on success. Optional.
     1763 */
     1764int GuestSession::i_objectRegister(SESSIONOBJECTTYPE enmType, uint32_t *puObjectID)
     1765{
     1766    return i_objectRegisterEx(enmType, 0 /* fFlags */, puObjectID);
     1767}
     1768
     1769/**
     1770 * Registers an object to a session, extended version.
     1771 *
     1772 * @return VBox status code. VERR_GSTCTL_MAX_OBJECTS_REACHED if the maximum of concurrent objects is reached.
     1773 * @param  enmType              Session object type to register.
     1774 * @param  fFlags               Registration flags. Not used yet and must be 0.
     1775 * @param  puObjectID           Returns registered object ID on success. Optional.
     1776 */
     1777int GuestSession::i_objectRegisterEx(SESSIONOBJECTTYPE enmType, uint32_t fFlags, uint32_t *puObjectID)
     1778{
     1779    RT_NOREF(fFlags);
     1780    AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER);
     1781
     1782    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1783
     1784    int rc = VINF_SUCCESS;
     1785
     1786    uint32_t uObjectID;
     1787
     1788    if (mData.mObjects.size() < VBOX_GUESTCTRL_MAX_OBJECTS - 1 /* Minus 1 for the session itself */)
     1789    {
     1790        SessionObjects::reverse_iterator itRend = mData.mObjects.rbegin();
     1791        if (itRend != mData.mObjects.rend())
     1792            uObjectID = itRend->first + 1; /* Last key plus 1. */
     1793        else
     1794            uObjectID = 0;
     1795    }
     1796    else
     1797    {
     1798        /* Utilize our "free list" to get the next free object ID in the map. */
     1799        if (mData.mObjectsFree.size())
     1800        {
     1801            /* Always re-use the oldest object ID to avoid trouble. */
     1802            uObjectID = mData.mObjectsFree.front();
     1803            mData.mObjectsFree.pop_front();
     1804        }
     1805        else
     1806            rc = VERR_GSTCTL_MAX_OBJECTS_REACHED;
     1807    }
     1808
     1809    Log2Func(("enmType=%RU32, fFlags=%RU32 -> uObjectID=%RU32 (%zu objects, %zu on free list), rc=%Rrc\n",
     1810              enmType, fFlags, uObjectID, mData.mObjects.size(), mData.mObjectsFree.size(), rc));
     1811
     1812    if (RT_SUCCESS(rc))
     1813    {
     1814        mData.mObjects[uObjectID].enmType     = enmType;
     1815        mData.mObjects[uObjectID].tsCreatedMs = RTTimeMilliTS();
     1816
     1817        if (puObjectID)
     1818            *puObjectID = uObjectID;
     1819    }
     1820
     1821    return rc;
     1822}
     1823
     1824/**
     1825 * Unregisters a formerly registered object from a session.
     1826 *
     1827 * @return VBox status code. VERR_NOT_FOUND if object to unregister was not found.
     1828 * @param  uObjectID            Object ID to unregister.
     1829 */
     1830int GuestSession::i_objectUnregister(uint32_t uObjectID)
     1831{
     1832    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1833
     1834    SessionObjects::const_iterator itObj = mData.mObjects.find(uObjectID);
     1835    if (itObj != mData.mObjects.end())
     1836    {
     1837        Log2Func(("uObjectID=%RU32 (now %zu objects in free list)\n", uObjectID, mData.mObjectsFree.size()));
     1838
     1839        /* Note: Do not remove object from object list (mData.mObjects) here, as we continue operating
     1840         *       on the free list (mData.mObjectsFree) if we reached the object list's maximum. */
     1841
     1842        mData.mObjectsFree.push_back(uObjectID);
     1843        Assert(mData.mObjectsFree.size() <= VBOX_GUESTCTRL_MAX_OBJECTS);
     1844        return VINF_SUCCESS;
     1845    }
     1846
     1847    AssertFailed();
     1848    return VERR_NOT_FOUND;
     1849}
     1850
    18711851int GuestSession::i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *prcGuest)
    18721852{
     
    18791859
    18801860    GuestWaitEvent *pEvent = NULL;
    1881     int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */,
    1882                                 &pEvent);
     1861    int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
    18831862    if (RT_FAILURE(vrc))
    18841863        return vrc;
     
    19261905
    19271906    GuestWaitEvent *pEvent = NULL;
    1928     int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, &pEvent);
     1907    int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
    19291908    if (RT_FAILURE(vrc))
    19301909        return vrc;
     
    19761955
    19771956    GuestWaitEvent *pEvent = NULL;
    1978     int vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */, &pEvent);
     1957    int vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
    19791958    if (RT_FAILURE(vrc))
    19801959        return vrc;
     
    20111990}
    20121991
    2013 int GuestSession::i_processRemoveFromList(GuestProcess *pProcess)
     1992/**
     1993 * Unregisters a process object from a session.
     1994 *
     1995 * @return VBox status code. VERR_NOT_FOUND if the process is not registered (anymore).
     1996 * @param  pProcess             Process object to unregister from session.
     1997 */
     1998int GuestSession::i_processUnregister(GuestProcess *pProcess)
    20141999{
    20152000    AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
     
    20192004    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    20202005
    2021     int rc = VERR_NOT_FOUND;
    2022 
    2023     ULONG uPID;
    2024     HRESULT hr = pProcess->COMGETTER(PID)(&uPID);
     2006    const uint32_t uObjectID = pProcess->getObjectID();
     2007
     2008    LogFlowFunc(("Removing process (objectID=%RU32) ...\n", uObjectID));
     2009
     2010    int rc = i_objectUnregister(uObjectID);
     2011    if (RT_FAILURE(rc))
     2012        return rc;
     2013
     2014    SessionProcesses::iterator itProcs = mData.mProcesses.find(uObjectID);
     2015    AssertReturn(itProcs != mData.mProcesses.end(), VERR_NOT_FOUND);
     2016
     2017    /* Make sure to consume the pointer before the one of the iterator gets released. */
     2018    ComObjPtr<GuestProcess> pProc = pProcess;
     2019
     2020    uint32_t uPID;
     2021    HRESULT hr = pProc->COMGETTER(PID)(&uPID);
    20252022    ComAssertComRC(hr);
    20262023
    2027     LogFlowFunc(("Removing process (PID=%RU32) ...\n", uPID));
    2028 
    2029     SessionProcesses::iterator itProcs = mData.mProcesses.begin();
    2030     while (itProcs != mData.mProcesses.end())
    2031     {
    2032         if (pProcess == itProcs->second)
    2033         {
    2034 #ifdef DEBUG_andy
    2035             ULONG cRefs = pProcess->AddRef();
    2036             Assert(cRefs >= 2);
    2037             LogFlowFunc(("pProcess=%p, cRefs=%RU32\n", pProcess, cRefs - 1));
    2038             pProcess->Release();
    2039 #endif
    2040             /* Make sure to consume the pointer before the one of the
    2041              * iterator gets released. */
    2042             ComObjPtr<GuestProcess> pProc = pProcess;
    2043 
    2044             hr = pProc->COMGETTER(PID)(&uPID);
    2045             ComAssertComRC(hr);
    2046 
    2047             Assert(mData.mProcesses.size());
    2048             Assert(mData.mNumObjects);
    2049             LogFlowFunc(("Removing process ID=%RU32 (Session: %RU32), guest PID=%RU32 (now total %zu processes, %RU32 objects)\n",
    2050                          pProcess->getObjectID(), mData.mSession.mID, uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1));
    2051 
    2052             rc = pProcess->i_onRemove();
    2053             mData.mProcesses.erase(itProcs);
    2054             mData.mNumObjects--;
    2055 
    2056             alock.release(); /* Release lock before firing off event. */
    2057 
    2058             fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProc,
    2059                                             uPID, false /* Process unregistered */);
    2060             pProc.setNull();
    2061             break;
    2062         }
    2063 
    2064         ++itProcs;
    2065     }
     2024    LogFlowFunc(("Removing process ID=%RU32 (session %RU32, guest PID %RU32, now total %zu processes)\n",
     2025                 uObjectID, mData.mSession.mID, uPID, mData.mProcesses.size()));
     2026
     2027    rc = pProcess->i_onRemove();
     2028    AssertRCReturn(rc, rc);
     2029
     2030    mData.mProcesses.erase(itProcs);
     2031
     2032    alock.release(); /* Release lock before firing off event. */
     2033
     2034    fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProc, uPID, false /* Process unregistered */);
     2035
     2036    pProc.setNull();
    20662037
    20672038    LogFlowFuncLeaveRC(rc);
     
    21292100    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    21302101
    2131     int rc = VERR_GSTCTL_MAX_OBJECTS_REACHED;
    2132     if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS)
    2133         return rc;
    2134 
    2135     /* Create a new (host-based) process ID and assign it. */
    2136     uint32_t uNewProcessID = 0;
    2137     ULONG uTries = 0;
    2138 
    2139     for (;;)
    2140     {
    2141         /* Is the context ID already used? */
    2142         if (!i_processExists(uNewProcessID, NULL /* pProcess */))
    2143         {
    2144             /* Callback with context ID was not found. This means
    2145              * we can use this context ID for our new callback we want
    2146              * to add below. */
    2147             rc = VINF_SUCCESS;
    2148             break;
    2149         }
    2150         uNewProcessID++;
    2151         if (uNewProcessID == VBOX_GUESTCTRL_MAX_OBJECTS)
    2152             uNewProcessID = 0;
    2153 
    2154         if (++uTries == VBOX_GUESTCTRL_MAX_OBJECTS)
    2155             break; /* Don't try too hard. */
    2156     }
    2157 
     2102    /* Register a new object ID. */
     2103    uint32_t uObjectID;
     2104    int rc = i_objectRegister(SESSIONOBJECTTYPE_PROCESS, &uObjectID);
    21582105    if (RT_FAILURE(rc))
    21592106        return rc;
     
    21642111        return VERR_COM_UNEXPECTED;
    21652112
    2166     rc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */,
    2167                         uNewProcessID, procInfo, mData.mpBaseEnvironment);
     2113    rc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */, uObjectID,
     2114                        procInfo, mData.mpBaseEnvironment);
    21682115    if (RT_FAILURE(rc))
    21692116        return rc;
     
    21722119    try
    21732120    {
    2174         mData.mProcesses[uNewProcessID] = pProcess;
    2175         mData.mNumObjects++;
    2176         Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS);
    2177 
    2178         LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %zu processes, %RU32 objects)\n",
    2179                      mData.mSession.mID, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects));
     2121        mData.mProcesses[uObjectID] = pProcess;
     2122
     2123        LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %zu processes)\n",
     2124                     mData.mSession.mID, uObjectID, mData.mProcesses.size()));
    21802125
    21812126        alock.release(); /* Release lock before firing off event. */
    21822127
    2183         fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProcess,
    2184                                         0 /* PID */, true /* Process registered */);
     2128        fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, pProcess, 0 /* PID */, true /* Process registered */);
    21852129    }
    21862130    catch (std::bad_alloc &)
     
    24742418        eventTypes.push_back(VBoxEventType_OnGuestSessionStateChanged);
    24752419
    2476         vrc = registerWaitEvent(mData.mSession.mID, 0 /* Object ID */,
    2477                                 eventTypes, &pEvent);
     2420        vrc = registerWaitEventEx(mData.mSession.mID, mData.mObjectID, eventTypes, &pEvent);
    24782421    }
    24792422    catch (std::bad_alloc)
     
    29992942
    30002943    int rcGuest;
    3001     int rc = i_objectCreateTemp(aTemplateName, aPath, true /* Directory */, aDirectory, &rcGuest);
     2944    int rc = i_fsCreateTemp(aTemplateName, aPath, true /* Directory */, aDirectory, &rcGuest);
    30022945    if (!RT_SUCCESS(rc))
    30032946    {
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