Index: trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
===================================================================
--- trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h	(revision 42895)
+++ trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h	(revision 42897)
@@ -37,22 +37,17 @@
 #endif
 
-#ifdef LOG_GROUP
- #undef LOG_GROUP
-#endif
-#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
-#include <VBox/log.h>
-
 /** Maximum number of guest sessions a VM can have. */
 #define VBOX_GUESTCTRL_MAX_SESSIONS     255
-/** Maximum of guest processes a guest session can have. */
-#define VBOX_GUESTCTRL_MAX_PROCESSES    255
+/** Maximum number of guest objects (processes, files, ...)
+ *  a guest session can have. */
+#define VBOX_GUESTCTRL_MAX_OBJECTS      255
 /** Maximum of callback contexts a guest process can have. */
 #define VBOX_GUESTCTRL_MAX_CONTEXTS     _64K - 1
 
-/** Builds a context ID out of the session ID, process ID and an
+/** Builds a context ID out of the session ID, object ID and an
  *  increasing count. */
-#define VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession, uProcess, uCount) \
+#define VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession, uObject, uCount) \
     (  (uint32_t)((uSession) &   0xff) << 24 \
-     | (uint32_t)((uProcess) &   0xff) << 16 \
+     | (uint32_t)((uObject)  &   0xff) << 16 \
      | (uint32_t)((uCount)   & 0xffff)       \
     )
@@ -61,5 +56,5 @@
     ((uContextID) >> 24)
 /** Gets the process ID out of a context ID. */
-#define VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID) \
+#define VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID) \
     (((uContextID) >> 16) & 0xff)
 /** Gets the conext count of a process out of a context ID. */
Index: trunk/src/VBox/Main/include/GuestDirectoryImpl.h
===================================================================
--- trunk/src/VBox/Main/include/GuestDirectoryImpl.h	(revision 42895)
+++ trunk/src/VBox/Main/include/GuestDirectoryImpl.h	(revision 42897)
@@ -73,5 +73,5 @@
     struct Data
     {
-        GuestSession              *mParent;
+        GuestSession              *mSession;
         Utf8Str                    mName;
         Utf8Str                    mFilter;
@@ -83,5 +83,5 @@
         /** The guest process which is responsible for
          *  getting the stdout stream. */
-        ComObjPtr<GuestProcess>    mProcess;
+        GuestProcess              *mProcess;
     } mData;
 };
Index: trunk/src/VBox/Main/include/GuestFileImpl.h
===================================================================
--- trunk/src/VBox/Main/include/GuestFileImpl.h	(revision 42895)
+++ trunk/src/VBox/Main/include/GuestFileImpl.h	(revision 42897)
@@ -83,7 +83,5 @@
     {
         /** The associate session this file belongs to. */
-        ComObjPtr<GuestSession> mSession;
-        /** The process object this file is bound to. */
-        ComObjPtr<GuestProcess> mProcess;
+        GuestSession           *mSession;
         uint32_t                mCreationMode;
         uint32_t                mDisposition;
Index: trunk/src/VBox/Main/include/GuestImpl.h
===================================================================
--- trunk/src/VBox/Main/include/GuestImpl.h	(revision 42895)
+++ trunk/src/VBox/Main/include/GuestImpl.h	(revision 42897)
@@ -139,5 +139,5 @@
     uint32_t    getAdditionsVersion(void) { return mData.mAdditionsVersionFull; }
     Console    *getConsole(void) { return mParent; }
-    int         sessionClose(ComObjPtr<GuestSession> pSession);
+    int         sessionRemove(GuestSession *pSession);
     int         sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain,
                               const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession);
Index: trunk/src/VBox/Main/include/GuestProcessImpl.h
===================================================================
--- trunk/src/VBox/Main/include/GuestProcessImpl.h	(revision 42895)
+++ trunk/src/VBox/Main/include/GuestProcessImpl.h	(revision 42897)
@@ -75,8 +75,6 @@
     inline bool callbackExists(uint32_t uContextID);
     inline int checkPID(uint32_t uPID);
-    void close(void);
     Utf8Str errorMsg(void) { return mData.mErrorMsg; }
     bool isReady(void);
-    ULONG getPID(void) { return mData.mPID; }
     ULONG getProcessID(void) { return mData.mProcessID; }
     int rc(void) { return mData.mRC; }
@@ -113,5 +111,7 @@
     struct Data
     {
-        /** Pointer to parent session. */
+        /** Pointer to parent session. Per definition
+         *  this objects *always* lives shorter than the
+         *  parent. */
         GuestSession            *mParent;
         /** Pointer to the console object. Needed
Index: trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp	(revision 42897)
@@ -41,4 +41,11 @@
 
 #include <memory>
+
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
+
 
 // public methods only for internal purposes
@@ -84,8 +91,8 @@
 
 #ifdef DEBUG
-    LogFlowFunc(("CID=%RU32, uSession=%RU32, uProcess=%RU32, uCount=%RU32\n",
+    LogFlowFunc(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32\n",
                  pHeader->u32ContextID,
                  VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHeader->u32ContextID),
-                 VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(pHeader->u32ContextID),
+                 VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pHeader->u32ContextID),
                  VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pHeader->u32ContextID)));
 #endif
@@ -240,7 +247,13 @@
 }
 
-int Guest::sessionClose(ComObjPtr<GuestSession> pSession)
-{
+int Guest::sessionRemove(GuestSession *pSession)
+{
+    LogFlowThisFuncEnter();
+
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    int rc = VERR_NOT_FOUND;
+
+    LogFlowFunc(("Closing session (ID=%RU32) ...\n", pSession->getId()));
 
     for (GuestSessions::iterator itSessions = mData.mGuestSessions.begin();
@@ -249,10 +262,16 @@
         if (pSession == itSessions->second)
         {
+            LogFlowFunc(("Removing session (pSession=%p, ID=%RU32) (now total %ld sessions)\n",
+                         itSessions->second, itSessions->second->getId(), mData.mGuestSessions.size() - 1));
+
             mData.mGuestSessions.erase(itSessions);
-            return VINF_SUCCESS;
-        }
-    }
-
-    return VERR_NOT_FOUND;
+
+            rc = VINF_SUCCESS;
+            break;
+        }
+    }
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
 }
 
@@ -299,6 +318,6 @@
         mData.mGuestSessions[uNewSessionID] = pGuestSession;
 
-        LogFlowFunc(("Added new session with session ID=%RU32 (now %ld sessions total)\n",
-                     uNewSessionID, mData.mGuestSessions.size()));
+        LogFlowFunc(("Added new session (pSession=%p, ID=%RU32), now %ld sessions total\n",
+                     pGuestSession, uNewSessionID, mData.mGuestSessions.size()));
     }
     catch (int rc2)
Index: trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp	(revision 42897)
@@ -27,4 +27,10 @@
 # include <iprt/file.h>
 #endif /* DEBUG */
+
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
 
 /******************************************************************************
Index: trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp	(revision 42897)
@@ -30,4 +30,10 @@
 #include <VBox/com/array.h>
 
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
+
 
 // constructor / destructor
@@ -63,8 +69,8 @@
     AssertReturn(autoInitSpan.isOk(), E_FAIL);
 
-    mData.mParent = aSession;
-    mData.mName   = strPath;
-    mData.mFilter = strFilter;
-    mData.mFlags  = uFlags;
+    mData.mSession = aSession;
+    mData.mName    = strPath;
+    mData.mFilter  = strFilter;
+    mData.mFlags   = uFlags;
 
     /* Start the directory process on the guest. */
@@ -89,7 +95,8 @@
      * it later in subsequent read() calls.
      */
-    int rc = mData.mParent->processCreateExInteral(procInfo, mData.mProcess);
+    ComObjPtr<GuestProcess> pProcess;
+    int rc = mData.mSession->processCreateExInteral(procInfo, pProcess);
     if (RT_SUCCESS(rc))
-        rc = mData.mProcess->startProcessAsync();
+        rc = pProcess->startProcessAsync();
 
     LogFlowThisFunc(("rc=%Rrc\n", rc));
@@ -97,4 +104,6 @@
     if (RT_SUCCESS(rc))
     {
+        mData.mProcess = pProcess;
+
         /* Confirm a successful initialization when it's the case. */
         autoInitSpan.setSucceeded();
@@ -119,6 +128,5 @@
         return;
 
-    if (!mData.mProcess.isNull())
-        mData.mProcess->uninit();
+    LogFlowThisFuncLeave();
 }
 
@@ -181,5 +189,4 @@
 }
 
-
 // implementation of public methods
 /////////////////////////////////////////////////////////////////////////////
@@ -192,7 +199,24 @@
     LogFlowThisFuncEnter();
 
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AssertPtr(mData.mSession);
+    int rc = mData.mSession->directoryRemoveFromList(this);
+    if (mData.mProcess)
+    {
+        int rc2 = mData.mSession->processRemoveFromList(mData.mProcess);
+        if (RT_SUCCESS(rc))
+            rc = rc2;
+    }
+
+    /*
+     * Release autocaller before calling uninit.
+     */
+    autoCaller.release();
+
     uninit();
 
-    LogFlowThisFuncLeave();
+    LogFlowFuncLeaveRC(rc);
     return S_OK;
 #endif /* VBOX_WITH_GUEST_CONTROL */
Index: trunk/src/VBox/Main/src-client/GuestFileImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestFileImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestFileImpl.cpp	(revision 42897)
@@ -30,4 +30,10 @@
 #include <VBox/com/array.h>
 
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
+
 
 // constructor / destructor
@@ -36,5 +42,5 @@
 DEFINE_EMPTY_CTOR_DTOR(GuestFile)
 
-HRESULT GuestFile::FinalConstruct()
+HRESULT GuestFile::FinalConstruct(void)
 {
     LogFlowThisFunc(("\n"));
@@ -90,5 +96,5 @@
         return;
 
-    mData.mSession->fileClose(this);
+    LogFlowThisFuncLeave();
 }
 
@@ -229,7 +235,18 @@
     LogFlowThisFuncEnter();
 
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    AssertPtr(mData.mSession);
+    int rc = mData.mSession->fileRemoveFromList(this);
+
+    /*
+     * Release autocaller before calling uninit.
+     */
+    autoCaller.release();
+
     uninit();
 
-    LogFlowThisFuncLeave();
+    LogFlowFuncLeaveRC(rc);
     return S_OK;
 #endif /* VBOX_WITH_GUEST_CONTROL */
Index: trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp	(revision 42897)
@@ -29,4 +29,10 @@
 #include <VBox/com/array.h>
 
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
+
 
 // constructor / destructor
Index: trunk/src/VBox/Main/src-client/GuestImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestImpl.cpp	(revision 42897)
@@ -139,9 +139,15 @@
 
 #ifdef VBOX_WITH_GUEST_CONTROL
+    LogFlowThisFunc(("Closing sessions (%RU64 total)\n",
+                     mData.mGuestSessions.size()));
     GuestSessions::iterator itSessions = mData.mGuestSessions.begin();
     while (itSessions != mData.mGuestSessions.end())
     {
-        if (!itSessions->second.isNull())
-            itSessions->second->uninit();
+#ifdef DEBUG
+        ULONG cRefs = itSessions->second->AddRef();
+        LogFlowThisFunc(("pSession=%p, cRefs=%RU32\n", itSessions->second, cRefs > 0 ? cRefs - 1 : 0));
+        itSessions->second->Release();
+#endif
+        itSessions->second->uninit();
         itSessions++;
     }
@@ -158,4 +164,6 @@
 
     unconst(mParent) = NULL;
+
+    LogFlowFuncLeave();
 }
 
Index: trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp	(revision 42897)
@@ -45,7 +45,15 @@
 #include <VBox/com/array.h>
 
-
-struct GuestProcessTask
-{
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
+
+
+class GuestProcessTask
+{
+public:
+
     GuestProcessTask(GuestProcess *pProcess)
         : mProcess(pProcess),
@@ -55,14 +63,17 @@
 
     int rc(void) const { return mRC; }
-    bool isOk(void) const { return RT_SUCCESS(rc()); }
+    bool isOk(void) const { return RT_SUCCESS(mRC); }
+    const ComObjPtr<GuestProcess> &Process(void) const { return mProcess; }
+
+protected:
 
     const ComObjPtr<GuestProcess>    mProcess;
-
-private:
     int                              mRC;
 };
 
-struct GuestProcessStartTask : public GuestProcessTask
-{
+class GuestProcessStartTask : public GuestProcessTask
+{
+public:
+
     GuestProcessStartTask(GuestProcess *pProcess)
         : GuestProcessTask(pProcess) { }
@@ -133,5 +144,6 @@
 void GuestProcess::uninit(void)
 {
-    LogFlowThisFunc(("\n"));
+    LogFlowThisFunc(("mCmd=%s, PID=%RU32\n",
+                     mData.mProcess.mCommand.c_str(), mData.mPID));
 
     /* Enclose the state transition Ready->InUninit->NotReady. */
@@ -140,5 +152,7 @@
         return;
 
-#ifndef VBOX_WITH_GUEST_CONTROL
+    int vrc = VINF_SUCCESS;
+
+#ifdef VBOX_WITH_GUEST_CONTROL
     /*
      * Cancel all callbacks + waiters.
@@ -151,5 +165,6 @@
         AssertPtr(pCallback);
         int rc2 = pCallback->Cancel();
-        AssertRC(rc2);
+        if (RT_SUCCESS(vrc))
+            vrc = rc2;
     }
     mData.mCallbacks.clear();
@@ -158,15 +173,12 @@
     {
         int rc2 = mData.mWaitEvent->Cancel();
-        AssertRC(rc2);
+        if (RT_SUCCESS(vrc))
+            vrc = rc2;
     }
 
     mData.mStatus = ProcessStatus_Down; /** @todo Correct? */
-
-    /* Remove the reference from the session's process list. */
-    AssertPtr(mData.mParent);
-    mData.mParent->processClose(this);
 #endif
 
-    LogFlowThisFuncLeave();
+    LogFlowFuncLeaveRC(vrc);
 }
 
@@ -531,15 +543,4 @@
 
     return VINF_SUCCESS;
-}
-
-/* Do not hold any locks here because the lock validator will be unhappy
- * when being in uninit(). */
-void GuestProcess::close(void)
-{
-    LogFlowThisFuncEnter();
-
-    uninit();
-
-    LogFlowThisFuncLeave();
 }
 
@@ -1166,17 +1167,26 @@
     LogFlowThisFuncEnter();
 
-    /* Asynchronously start the process on the guest by kicking off a
-     * worker thread. */
-    std::auto_ptr<GuestProcessStartTask> pTask(new GuestProcessStartTask(this));
-    AssertReturn(pTask->isOk(), pTask->rc());
-
-    int vrc = RTThreadCreate(NULL, GuestProcess::startProcessThread,
-                            (void *)pTask.get(), 0,
-                            RTTHREADTYPE_MAIN_WORKER, 0,
-                            "gctlPrcStart");
-    if (RT_SUCCESS(vrc))
-    {
-        /* pTask is now owned by startProcessThread(), so release it. */
-        pTask.release();
+    int vrc;
+
+    try
+    {
+        /* Asynchronously start the process on the guest by kicking off a
+         * worker thread. */
+        std::auto_ptr<GuestProcessStartTask> pTask(new GuestProcessStartTask(this));
+        AssertReturn(pTask->isOk(), pTask->rc());
+
+        vrc = RTThreadCreate(NULL, GuestProcess::startProcessThread,
+                             (void *)pTask.get(), 0,
+                             RTTHREADTYPE_MAIN_WORKER, 0,
+                             "gctlPrcStart");
+        if (RT_SUCCESS(vrc))
+        {
+            /* pTask is now owned by startProcessThread(), so release it. */
+            pTask.release();
+        }
+    }
+    catch(std::bad_alloc &)
+    {
+        vrc = VERR_NO_MEMORY;
     }
 
@@ -1185,4 +1195,5 @@
 }
 
+/* static */
 DECLCALLBACK(int) GuestProcess::startProcessThread(RTTHREAD Thread, void *pvUser)
 {
@@ -1192,5 +1203,5 @@
     AssertPtr(pTask.get());
 
-    const ComObjPtr<GuestProcess> pProcess(pTask->mProcess);
+    const ComObjPtr<GuestProcess> pProcess(pTask->Process());
     Assert(!pProcess.isNull());
 
@@ -1274,5 +1285,4 @@
                 /* Filter out waits which are *not* supported using
                  * older guest control Guest Additions. */
-                AssertPtr(mData.mParent);
                 if (mData.mParent->getProtocolVersion() < 2)
                 {
@@ -1355,5 +1365,14 @@
     int vrc = mData.mWaitEvent->Wait(uTimeoutMS);
     if (RT_SUCCESS(vrc))
+    {
         waitRes = mData.mWaitEvent->GetResult();
+    }
+    else if (vrc == VERR_TIMEOUT)
+    {
+        waitRes.mRC = VINF_SUCCESS;
+        waitRes.mResult = ProcessWaitResult_Timeout;
+
+        vrc = VINF_SUCCESS;
+    }
 
     alock.acquire(); /* Get the lock again. */
@@ -1570,4 +1589,14 @@
     }
 
+    AssertPtr(mData.mParent);
+    mData.mParent->processRemoveFromList(this);
+
+    /*
+     * Release autocaller before calling uninit.
+     */
+    autoCaller.release();
+
+    uninit();
+
     LogFlowFuncLeaveRC(vrc);
     return hr;
@@ -1601,12 +1630,7 @@
     else
     {
-        if (vrc == VERR_TIMEOUT)
-            hr = setError(VBOX_E_IPRT_ERROR,
-                          tr("Process \"%s\" (PID %RU32) did not respond within time (%RU32ms)"),
-                          mData.mProcess.mCommand.c_str(), mData.mPID, aTimeoutMS);
-        else
-            hr = setError(VBOX_E_IPRT_ERROR,
-                          tr("Waiting for process \"%s\" (PID %RU32) failed with vrc=%Rrc"),
-                          mData.mProcess.mCommand.c_str(), mData.mPID, vrc);
+        hr = setError(VBOX_E_IPRT_ERROR,
+                      tr("Waiting for process \"%s\" (PID %RU32) failed with vrc=%Rrc"),
+                      mData.mProcess.mCommand.c_str(), mData.mPID, vrc);
     }
     LogFlowFuncLeaveRC(vrc);
Index: trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 42897)
@@ -37,12 +37,10 @@
 #include <VBox/version.h>
 
-
-/*
- * If the following define is enabled the Guest Additions update code also
- * checks for locations which were not supposed to happen due to not resolving
- * environment variables in VBoxService toolbox arguments. So a file copied
- * to "%TEMP%\foo.exe" became "C:\Windows\EMPfoo.exe".
- */
-#define VBOX_SERVICE_ENVARG_BUG
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
+
 
 // constructor / destructor
@@ -87,4 +85,5 @@
     mData.mCredentials.mDomain = aDomain;
     mData.mName = aName;
+    mData.mNumObjects = 0;
 
     /* Confirm a successful initialization when it's the case. */
@@ -108,39 +107,52 @@
         return;
 
-#ifdef VBOX_WITH_GUEST_CONTROL
+    int rc = VINF_SUCCESS;
+
+#ifndef VBOX_WITH_GUEST_CONTROL
+    LogFlowThisFunc(("Closing directories (%RU64 total)\n",
+                     mData.mDirectories.size()));
     for (SessionDirectories::iterator itDirs = mData.mDirectories.begin();
          itDirs != mData.mDirectories.end(); ++itDirs)
     {
+#ifdef DEBUG
+        ULONG cRefs = (*itDirs)->AddRef();
+        LogFlowThisFunc(("pFile=%p, cRefs=%RU32\n", (*itDirs), cRefs));
+        (*itDirs)->Release();
+#endif
         (*itDirs)->uninit();
-        (*itDirs).setNull();
     }
     mData.mDirectories.clear();
 
+    LogFlowThisFunc(("Closing files (%RU64 total)\n",
+                     mData.mFiles.size()));
     for (SessionFiles::iterator itFiles = mData.mFiles.begin();
          itFiles != mData.mFiles.end(); ++itFiles)
     {
+#ifdef DEBUG
+        ULONG cRefs = (*itFiles)->AddRef();
+        LogFlowThisFunc(("pFile=%p, cRefs=%RU32\n", (*itFiles), cRefs));
+        (*itFiles)->Release();
+#endif
         (*itFiles)->uninit();
-        (*itFiles).setNull();
     }
     mData.mFiles.clear();
 
+    LogFlowThisFunc(("Closing processes (%RU64 total)\n",
+                     mData.mProcesses.size()));
     for (SessionProcesses::iterator itProcs = mData.mProcesses.begin();
          itProcs != mData.mProcesses.end(); ++itProcs)
     {
-        itProcs->second->close();
-    }
-
-    for (SessionProcesses::iterator itProcs = mData.mProcesses.begin();
-         itProcs != mData.mProcesses.end(); ++itProcs)
-    {
+#ifdef DEBUG
+        ULONG cRefs = itProcs->second->AddRef();
+        LogFlowThisFunc(("pProcess=%p, cRefs=%RU32\n", itProcs->second, cRefs));
+        itProcs->second->Release();
+#endif
         itProcs->second->uninit();
-        itProcs->second.setNull();
     }
     mData.mProcesses.clear();
 
-    mData.mParent->sessionClose(this);
-
-    LogFlowThisFuncLeave();
+    LogFlowThisFunc(("mNumObjects=%RU32\n", mData.mNumObjects));
 #endif
+    LogFlowFuncLeaveRC(rc);
 }
 
@@ -399,5 +411,5 @@
 /////////////////////////////////////////////////////////////////////////////
 
-int GuestSession::directoryClose(ComObjPtr<GuestDirectory> pDirectory)
+int GuestSession::directoryRemoveFromList(GuestDirectory *pDirectory)
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -408,4 +420,12 @@
         if (pDirectory == (*itDirs))
         {
+            Bstr strName;
+            HRESULT hr = (*itDirs)->COMGETTER(DirectoryName)(strName.asOutParam());
+            ComAssertComRC(hr);
+
+            Assert(mData.mDirectories.size());
+            LogFlowFunc(("Removing directory \"%s\" (Session: %RU32) (now total %ld directories)\n",
+                         Utf8Str(strName).c_str(), mData.mNumObjects - 1));
+
             mData.mDirectories.erase(itDirs);
             return VINF_SUCCESS;
@@ -629,5 +649,5 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    uint32_t uProcessID = VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID);
+    uint32_t uProcessID = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID);
 #ifdef DEBUG
     LogFlowFunc(("uProcessID=%RU32 (%RU32 total)\n",
@@ -652,5 +672,5 @@
 }
 
-int GuestSession::fileClose(ComObjPtr<GuestFile> pFile)
+int GuestSession::fileRemoveFromList(GuestFile *pFile)
 {
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -661,5 +681,18 @@
         if (pFile == (*itFiles))
         {
+            Bstr strName;
+            HRESULT hr = (*itFiles)->COMGETTER(FileName)(strName.asOutParam());
+            ComAssertComRC(hr);
+
+            Assert(mData.mNumObjects);
+            LogFlowThisFunc(("Removing file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n",
+                             Utf8Str(strName).c_str(), mData.mId, mData.mFiles.size() - 1, mData.mNumObjects - 1));
+#ifdef DEBUG
+            ULONG cRefs = pFile->AddRef();
+            LogFlowThisFunc(("pObject=%p, cRefs=%RU32\n", pFile, cRefs));
+            pFile->Release();
+#endif
             mData.mFiles.erase(itFiles);
+            mData.mNumObjects--;
             return VINF_SUCCESS;
         }
@@ -772,7 +805,9 @@
     /* Add the created directory to our vector. */
     mData.mFiles.push_back(pFile);
-
-    LogFlowFunc(("Added new file \"%s\" (Session: %RU32\n",
-                 strPath.c_str(), mData.mId));
+    mData.mNumObjects++;
+    Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS);
+
+    LogFlowFunc(("Added new file \"%s\" (Session: %RU32) (now total %ld files, %ld objects)\n",
+                 strPath.c_str(), mData.mId, mData.mProcesses.size(), mData.mNumObjects));
 
     LogFlowFuncLeaveRC(rc);
@@ -900,7 +935,16 @@
 }
 
-int GuestSession::processClose(ComObjPtr<GuestProcess> pProcess)
-{
+int GuestSession::processRemoveFromList(GuestProcess *pProcess)
+{
+    LogFlowThisFuncEnter();
+
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    int rc = VERR_NOT_FOUND;
+
+    ULONG uPID;
+    HRESULT hr = pProcess->COMGETTER(PID)(&uPID);
+
+    LogFlowFunc(("Closing process (PID=%RU32) ...\n", uPID));
 
     for (SessionProcesses::iterator itProcs = mData.mProcesses.begin();
@@ -909,13 +953,24 @@
         if (pProcess == itProcs->second)
         {
-            LogFlowFunc(("Removing process (Session: %RU32) with process ID=%RU32, guest PID=%RU32 (now total %ld processes)\n",
-                         mData.mId, itProcs->second->getProcessID(), itProcs->second->getPID(), mData.mProcesses.size() - 1));
+            GuestProcess *pCurProc = itProcs->second;
+            AssertPtr(pCurProc);
+
+            hr = pCurProc->COMGETTER(PID)(&uPID);
+            ComAssertComRC(hr);
+
+            Assert(mData.mNumObjects);
+            LogFlowFunc(("Removing process (Session: %RU32) with process ID=%RU32, guest PID=%RU32 (now total %ld processes, %ld objects)\n",
+                         mData.mId, pCurProc->getProcessID(), uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1));
 
             mData.mProcesses.erase(itProcs);
-            return VINF_SUCCESS;
-        }
-    }
-
-    return VERR_NOT_FOUND;
+            mData.mNumObjects--;
+
+            rc = VINF_SUCCESS;
+            break;
+        }
+    }
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
 }
 
@@ -970,5 +1025,5 @@
 
     int rc = VERR_MAX_PROCS_REACHED;
-    if (mData.mProcesses.size() >= VBOX_GUESTCTRL_MAX_PROCESSES)
+    if (mData.mNumObjects >= VBOX_GUESTCTRL_MAX_OBJECTS)
         return rc;
 
@@ -989,5 +1044,5 @@
         }
         uNewProcessID++;
-        if (uNewProcessID == VBOX_GUESTCTRL_MAX_PROCESSES)
+        if (uNewProcessID == VBOX_GUESTCTRL_MAX_OBJECTS)
             uNewProcessID = 0;
 
@@ -1011,7 +1066,9 @@
     /* Add the created process to our map. */
     mData.mProcesses[uNewProcessID] = pProcess;
-
-    LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes)\n",
-                 mData.mId, uNewProcessID, mData.mProcesses.size()));
+    mData.mNumObjects++;
+    Assert(mData.mNumObjects <= VBOX_GUESTCTRL_MAX_OBJECTS);
+
+    LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes, %ld objects)\n",
+                 mData.mId, uNewProcessID, mData.mProcesses.size(), mData.mNumObjects));
 
     return rc;
@@ -1035,13 +1092,17 @@
     /* pProcess is optional. */
 
-    SessionProcesses::iterator it = mData.mProcesses.begin();
-    for (; it != mData.mProcesses.end(); it++)
-    {
-        ComObjPtr<GuestProcess> pCurProc = it->second;
+    SessionProcesses::iterator itProcs = mData.mProcesses.begin();
+    for (; itProcs != mData.mProcesses.end(); itProcs++)
+    {
+        ComObjPtr<GuestProcess> pCurProc = itProcs->second;
         AutoCaller procCaller(pCurProc);
         if (procCaller.rc())
             return VERR_COM_INVALID_OBJECT_STATE;
 
-        if (it->second->getPID() == uPID)
+        ULONG uCurPID;
+        HRESULT hr = pCurProc->COMGETTER(PID)(&uCurPID);
+        ComAssertComRC(hr);
+
+        if (uCurPID == uPID)
         {
             if (pProcess)
@@ -1132,7 +1193,18 @@
     LogFlowThisFuncEnter();
 
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    /* Remove ourselves from the session list. */
+    mData.mParent->sessionRemove(this);
+
+    /*
+     * Release autocaller before calling uninit.
+     */
+    autoCaller.release();
+
     uninit();
 
-    LogFlowFuncLeaveRC(S_OK);
+    LogFlowFuncLeave();
     return S_OK;
 #endif /* VBOX_WITH_GUEST_CONTROL */
@@ -1351,5 +1423,5 @@
 
     GuestFsObjData objData;
-    int rc = fileQueryInfoInternal(Utf8Str(aPath), objData);
+    int rc = directoryQueryInfoInternal(Utf8Str(aPath), objData);
     if (RT_SUCCESS(rc))
     {
@@ -1413,5 +1485,5 @@
         else
         {
-            rc = directoryClose(pDirectory);
+            rc = directoryRemoveFromList(pDirectory);
             if (RT_FAILURE(rc))
                 hr = setError(VBOX_E_IPRT_ERROR, tr("Unable to close directory object, rc=%Rrc"), rc);
@@ -1987,6 +2059,6 @@
         {
             case VERR_MAX_PROCS_REACHED:
-                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest processes per session (%ld) reached"),
-                              VBOX_GUESTCTRL_MAX_PROCESSES);
+                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest objects per session (%ld) reached"),
+                                                    VBOX_GUESTCTRL_MAX_OBJECTS);
                 break;
 
Index: trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 42895)
+++ trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 42897)
@@ -33,4 +33,10 @@
 #include <iprt/env.h>
 #include <iprt/file.h> /* For CopyTo/From. */
+
+#ifdef LOG_GROUP
+ #undef LOG_GROUP
+#endif
+#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
+#include <VBox/log.h>
 
 
@@ -400,5 +406,6 @@
         }
 
-        pProcess->close();
+        if (!pProcess.isNull())
+            pProcess->uninit();
     } /* processCreateExInteral */
 
@@ -632,5 +639,6 @@
                 }
 
-                pProcess->close();
+                if (!pProcess.isNull())
+                    pProcess->uninit();
             }
 
@@ -844,5 +852,5 @@
 
     if (!pProcess.isNull())
-        pProcess->close();
+        pProcess->uninit();
 
     return rc;
Index: trunk/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp
===================================================================
--- trunk/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp	(revision 42895)
+++ trunk/src/VBox/Main/testcase/tstGuestCtrlContextID.cpp	(revision 42897)
@@ -59,5 +59,5 @@
     {
         uint32_t s = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_SESSIONS);
-        uint32_t p = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_PROCESSES);
+        uint32_t p = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_OBJECTS);
         uint32_t c = RTRandU32Ex(0, VBOX_GUESTCTRL_MAX_CONTEXTS);
 
@@ -69,8 +69,8 @@
                          s, p, c, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID), s, uContextID);
         }
-        else if (p != VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID))
+        else if (p != VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID))
         {
-            RTTestFailed(hTest, "%d,%d,%d: Process is %d, expected %d -> %RU64\n",
-                         s, p, c, VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID), p, uContextID);
+            RTTestFailed(hTest, "%d,%d,%d: Object is %d, expected %d -> %RU64\n",
+                         s, p, c, VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID), p, uContextID);
         }
         if (c != VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID))
