Index: trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp	(revision 47694)
+++ trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp	(revision 47695)
@@ -138,9 +138,10 @@
  * @return  IPRT status code.
  * @param   uClientId       The client ID returned by VbglR3GuestCtrlConnect().
- * @param   uFilterAdd      Context ID filter mask to add.
- * @param   uFilterRemove   Context ID filter mask to remove.
- */
-VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t uClientId,
-                                            uint32_t uFilterAdd, uint32_t uFilterRemove)
+ * @param   uValue          The value to filter messages for.
+ * @param   uMaskAdd        Filter mask to add.
+ * @param   uMaskRemove     Filter mask to remove.
+ */
+VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t uClientId, uint32_t uValue,
+                                            uint32_t uMaskAdd, uint32_t uMaskRemove)
 {
     HGCMMsgCmdFilterSet Msg;
@@ -149,8 +150,9 @@
     Msg.hdr.u32ClientID = uClientId;
     Msg.hdr.u32Function = GUEST_MSG_FILTER_SET; /* Tell the host we want to set a filter. */
-    Msg.hdr.cParms      = 3;
-
-    VbglHGCMParmUInt32Set(&Msg.add, uFilterAdd);
-    VbglHGCMParmUInt32Set(&Msg.remove, uFilterRemove);
+    Msg.hdr.cParms      = 4;
+
+    VbglHGCMParmUInt32Set(&Msg.value, uValue);
+    VbglHGCMParmUInt32Set(&Msg.mask_add, uMaskAdd);
+    VbglHGCMParmUInt32Set(&Msg.mask_remove, uMaskRemove);
     VbglHGCMParmUInt32Set(&Msg.flags, 0 /* Flags, unused */);
 
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp	(revision 47694)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp	(revision 47695)
@@ -1442,5 +1442,6 @@
     /* The process thread is not interested in receiving any commands;
      * tell the host service. */
-    rc = VbglR3GuestCtrlMsgFilterSet(pProcess->uClientID, 0 /* Skip all */, 0);
+    rc = VbglR3GuestCtrlMsgFilterSet(pProcess->uClientID, 0 /* Skip all */,
+                                     0 /* Filter mask to add */, 0 /* Filter mask to remove */);
     if (RT_FAILURE(rc))
     {
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp	(revision 47694)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp	(revision 47695)
@@ -911,6 +911,6 @@
 
 /**
- * Thread main routine for a forked guest session. This
- * thread runs in the main executable to control the forked
+ * Thread main routine for a forked guest session process.
+ * This thread runs in the main executable to control the forked
  * session process.
  *
@@ -936,19 +936,23 @@
         /* The session thread is not interested in receiving any commands;
          * tell the host service. */
-        rc = VbglR3GuestCtrlMsgFilterSet(uClientID, 0 /* Skip all */, 0);
+        rc = VbglR3GuestCtrlMsgFilterSet(uClientID, 0 /* Skip all */,
+                                         0 /* Filter mask to add */, 0 /* Filter mask to remove */);
         if (RT_FAILURE(rc))
         {
             VBoxServiceError("Unable to set message filter, rc=%Rrc\n", rc);
             /* Non-critical. */
+            rc = VINF_SUCCESS;
         }
     }
     else
-    {
         VBoxServiceError("Error connecting to guest control service, rc=%Rrc\n", rc);
-        return rc;
-    }
-
-    /* Let caller know that we're done initializing. */
-    rc = RTThreadUserSignal(RTThreadSelf());
+
+    if (RT_FAILURE(rc))
+        pThread->fShutdown = true;
+
+    /* Let caller know that we're done initializing, regardless of the result. */
+    int rc2 = RTThreadUserSignal(RTThreadSelf());
+    AssertRC(rc2);
+
     if (RT_FAILURE(rc))
         return rc;
@@ -1069,6 +1073,6 @@
     Assert(uSessionStatus != GUEST_SESSION_NOTIFYTYPE_UNDEFINED);
     VBGLR3GUESTCTRLCMDCTX ctx = { uClientID, VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSessionID) };
-    int rc2 = VbglR3GuestCtrlSessionNotify(&ctx,
-                                           uSessionStatus, uSessionRc);
+    rc2 = VbglR3GuestCtrlSessionNotify(&ctx,
+                                       uSessionStatus, uSessionRc);
     if (RT_FAILURE(rc2))
         VBoxServiceError("Reporting session ID=%RU32 final status failed with rc=%Rrc\n",
@@ -1100,8 +1104,8 @@
          * session we don't want to handle. */
         uint32_t uFilterAdd =
-            VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID);
-        uFilterAdd |= 0x7FFFFFF; /* We only want to filter for session IDs. */
-
-        rc = VbglR3GuestCtrlMsgFilterSet(uClientID, uFilterAdd, 0 /* Filter remove */);
+            VBOX_GUESTCTRL_FILTER_BY_SESSION(pSession->StartupInfo.uSessionID);
+        rc = VbglR3GuestCtrlMsgFilterSet(uClientID,
+                                         VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(pSession->StartupInfo.uSessionID),
+                                         uFilterAdd, 0 /* Filter remove */);
         VBoxServiceVerbose(3, "Setting message filterAdd=0x%x returned %Rrc\n",
                            uFilterAdd, rc);
@@ -1930,9 +1934,10 @@
     int rc = GstCntlSessionThreadWait(pThread,
                                       5 * 60 * 1000 /* 5 minutes timeout */, uFlags);
-    /** @todo Kill session process if still around? */
 
     /* Remove session from list and destroy object. */
     RTListNodeRemove(&pThread->Node);
+
     RTMemFree(pThread);
+    pThread = NULL;
 
     return rc;
Index: trunk/src/VBox/HostServices/GuestControl/service.cpp
===================================================================
--- trunk/src/VBox/HostServices/GuestControl/service.cpp	(revision 47694)
+++ trunk/src/VBox/HostServices/GuestControl/service.cpp	(revision 47695)
@@ -287,6 +287,6 @@
     int CopyTo(VBOXHGCMSVCPARM paDstParms[], uint32_t cDstParms) const
     {
-        LogFlowFunc(("pHostCmd=%p, mMsgType=%RU32, mParmCount=%RU32, mContextID=%RU32\n",
-                     this, mMsgType, mParmCount, mContextID));
+        LogFlowFunc(("pHostCmd=%p, mMsgType=%RU32, mParmCount=%RU32, mContextID=%RU32 (Session %RU32)\n",
+                     this, mMsgType, mParmCount, mContextID, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(mContextID)));
 
         int rc = VINF_SUCCESS;
@@ -478,5 +478,6 @@
         : mSvcHelpers(NULL),
           mID(0),
-          mFlags(0), mContextFilter(0),
+          mFlags(0),
+          mFilterMask(0), mFilterValue(0),
           mHostCmdRc(VINF_SUCCESS), mHostCmdTries(0),
           mHostCmdTS(0),
@@ -487,5 +488,6 @@
         : mSvcHelpers(pSvcHelpers),
           mID(uClientID),
-          mFlags(0), mContextFilter(0),
+          mFlags(0),
+          mFilterMask(0), mFilterValue(0),
           mHostCmdRc(VINF_SUCCESS), mHostCmdTries(0),
           mHostCmdTS(0),
@@ -571,14 +573,13 @@
         if (mFlags & CLIENTSTATE_FLAG_CONTEXTFILTER)
         {
-            fWant =
-                (pHostCmd->mContextID & mContextFilter) == pHostCmd->mContextID;
+            fWant = (pHostCmd->mContextID & mFilterMask) == mFilterValue;
         }
         else /* Client is interested in all commands. */
             fWant = true;
 
-        LogFlowFunc(("[Client %RU32] mFlags=0x%x, mContextID=%RU32 (session %RU32), mContextFilter=0x%x, fWant=%RTbool\n",
+        LogFlowFunc(("[Client %RU32] mFlags=0x%x, mContextID=%RU32 (session %RU32), mFilterMask=0x%x, mFilterValue=%RU32, fWant=%RTbool\n",
                      mID, mFlags, pHostCmd->mContextID,
                      VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCmd->mContextID),
-                     mContextFilter, fWant));
+                     mFilterMask, mFilterValue, fWant));
 
         return fWant;
@@ -831,6 +832,8 @@
     /** Client flags. @sa CLIENTSTATE_FLAG_ flags. */
     uint32_t mFlags;
-    /** The context ID filter, based on the flags set. */
-    uint32_t mContextFilter;
+    /** The context ID filter mask, if any. */
+    uint32_t mFilterMask;
+    /** The context ID filter value, if any. */
+    uint32_t mFilterValue;
     /** Host command list to process. */
     HostCmdList mHostCmdList;
@@ -1152,11 +1155,14 @@
         return VERR_NOT_FOUND; /* Should never happen. */
 
-    if (cParms != 3)
+    if (cParms != 4)
         return VERR_INVALID_PARAMETER;
 
-    uint32_t uMaskAdd, uMaskRemove;
-    int rc = paParms[0].getUInt32(&uMaskAdd);
+    uint32_t uValue, uMaskAdd, uMaskRemove;
+    int rc = paParms[0].getUInt32(&uValue);
     if (RT_SUCCESS(rc))
-        rc = paParms[1].getUInt32(&uMaskRemove);
+        rc = paParms[1].getUInt32(&uMaskAdd);
+    if (RT_SUCCESS(rc))
+        rc = paParms[2].getUInt32(&uMaskRemove);
+    /** @todo paParm[3] (flags) not used yet. */
     if (RT_SUCCESS(rc))
     {
@@ -1165,11 +1171,13 @@
         clientState.mFlags |= CLIENTSTATE_FLAG_CONTEXTFILTER;
         if (uMaskAdd)
-            clientState.mContextFilter |= uMaskAdd;
+            clientState.mFilterMask |= uMaskAdd;
         if (uMaskRemove)
-            clientState.mContextFilter &= ~uMaskRemove;
-
-        LogFlowFunc(("[Client %RU32] Setting message filter=0x%x set (flags=0x%x, maskAdd=0x%x, maskRemove=0x%x)\n",
-                     u32ClientID, clientState.mContextFilter, clientState.mFlags,
-                     uMaskAdd, uMaskRemove));
+            clientState.mFilterMask &= ~uMaskRemove;
+
+        clientState.mFilterValue = uValue;
+
+        LogFlowFunc(("[Client %RU32] Setting message filterMask=0x%x, filterVal=%RU32 set (flags=0x%x, maskAdd=0x%x, maskRemove=0x%x)\n",
+                     u32ClientID, clientState.mFilterMask, clientState.mFilterValue,
+                     clientState.mFlags, uMaskAdd, uMaskRemove));
     }
 
@@ -1196,5 +1204,6 @@
 
     clientState.mFlags &= ~CLIENTSTATE_FLAG_CONTEXTFILTER;
-    clientState.mContextFilter = 0;
+    clientState.mFilterMask = 0;
+    clientState.mFilterValue = 0;
 
     LogFlowFunc(("[Client %RU32} Unset message filter\n", u32ClientID));
