Index: /trunk/src/VBox/HostServices/GuestControl/service.cpp
===================================================================
--- /trunk/src/VBox/HostServices/GuestControl/service.cpp	(revision 75893)
+++ /trunk/src/VBox/HostServices/GuestControl/service.cpp	(revision 75894)
@@ -134,4 +134,6 @@
     /** Array of HGCM parameters. */
     PVBOXHGCMSVCPARM mpParms;
+    /** Set if we detected the message skipping hack from r121400. */
+    bool m_f60BetaHackInPlay;
 
     HostCommand()
@@ -140,4 +142,5 @@
         , mParmCount(0)
         , mpParms(NULL)
+        , m_f60BetaHackInPlay(false)
     {
         RTListInit(&m_ListEntry);
@@ -472,4 +475,6 @@
     /** Set if master. */
     bool                    m_fIsMaster;
+    /** Set if restored (needed for shutting legacy mode assert on non-masters). */
+    bool                    m_fRestored;
 
     /** Set if we've got a pending wait cancel. */
@@ -489,4 +494,5 @@
         , m_idSession(UINT32_MAX)
         , m_fIsMaster(false)
+        , m_fRestored(false)
         , m_fPendingCancel(false)
         , m_enmIsPending((guestControl::eGuestFn)0)
@@ -503,4 +509,5 @@
         , m_idSession(UINT32_MAX)
         , m_fIsMaster(false)
+        , m_fRestored(false)
         , m_fPendingCancel(false)
         , m_enmIsPending((guestControl::eGuestFn)0)
@@ -652,4 +659,5 @@
         Assert(pFirstCmd);
         RTListNodeRemove(&pFirstCmd->m_ListEntry);
+        pFirstCmd->Delete();
 
         /* Reset state else. */
@@ -896,5 +904,5 @@
                                          uint32_t fRequestor, bool fRestoring);
     static DECLCALLBACK(int)  svcDisconnect(void *pvService, uint32_t idClient, void *pvClient);
-    static DECLCALLBACK(void) svcCall(void *pvService, VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, void *pvClient,
+    static DECLCALLBACK(void) svcCall(void *pvService, VBOXHGCMCALLHANDLE hCall, uint32_t idClient, void *pvClient,
                                       uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival);
     static DECLCALLBACK(int)  svcHostCall(void *pvService, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
@@ -915,7 +923,7 @@
     int clientToMain(ClientState *pClient, uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
 
-    int clientMsgOldGet(ClientState *pClient, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
+    int clientMsgOldGet(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     int clientMsgOldFilterSet(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
-    int clientMsgOldSkip(ClientState *pClient, uint32_t cParms);
+    int clientMsgOldSkip(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms);
 
     int hostCallback(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
@@ -1088,5 +1096,5 @@
 int GstCtrlService::clientMsgOldGet(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
 {
-    ASSERT_GUEST(pClient->m_idSession != UINT32_MAX || pClient->m_fIsMaster);
+    ASSERT_GUEST(pClient->m_idSession != UINT32_MAX || pClient->m_fIsMaster || pClient->m_fRestored);
 
     /* Use the current (inbound) connection. */
@@ -1781,5 +1789,5 @@
     uint32_t const fFlags = paParms[1].u.uint32;
 
-    ASSERT_GUEST_RETURN(pClient->m_fIsMaster, VERR_ACCESS_DENIED);
+    ASSERT_GUEST_RETURN(pClient->m_fIsMaster || (m_fLegacyMode && pClient->m_idSession == UINT32_MAX), VERR_ACCESS_DENIED);
 
     /*
@@ -1877,7 +1885,8 @@
  * @return  VBox status code.
  * @param   pClient     The client state.
+ * @param   hCall       The call handle for completing it.
  * @param   cParms      Number of parameters.
  */
-int GstCtrlService::clientMsgOldSkip(ClientState *pClient, uint32_t cParms)
+int GstCtrlService::clientMsgOldSkip(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms)
 {
     /*
@@ -1888,9 +1897,41 @@
     /*
      * Execute the request.
-     */
-    if (!RTListIsEmpty(&pClient->m_HostCmdList))
-        pClient->OldDitchFirstHostCmd();
-
-    LogFlowFunc(("[Client %RU32] Skipped current message - leagcy function\n", pClient->m_idClient));
+     *
+     * Note! As it turns out the old and new skip should be mostly the same.  The
+     *       pre-6.0 GAs (up to BETA3) has a hack which tries to issue a
+     *       VERR_NOT_SUPPORTED reply to unknown host requests, however the 5.2.x
+     *       and earlier GAs doesn't.  We need old skip behavior only for the 6.0
+     *       beta GAs, nothing else.
+     *       So, we have to track whether they issued a MSG_REPLY or not.  Wonderful.
+     */
+    HostCommand *pFirstCmd = RTListGetFirstCpp(&pClient->m_HostCmdList, HostCommand, m_ListEntry);
+    if (pFirstCmd)
+    {
+        uint32_t const idMsg             = pFirstCmd->mMsgType;
+        bool const     f60BetaHackInPlay = pFirstCmd->m_f60BetaHackInPlay;
+        int            rc;
+        if (!f60BetaHackInPlay)
+            rc = clientMsgSkip(pClient, hCall, 0, NULL);
+        else
+        {
+            RTListNodeRemove(&pFirstCmd->m_ListEntry);
+            pFirstCmd->Delete();
+            rc = VINF_SUCCESS;
+        }
+
+        /* Reset legacy message wait/get state: */
+        if (RT_SUCCESS(rc))
+        {
+            pClient->mHostCmdRc    = VINF_SUCCESS;
+            pClient->mHostCmdTries = 0;
+            pClient->mPeekCount    = 0;
+        }
+
+        LogFlowFunc(("[Client %RU32] Legacy message skipping: Skipped %u (%s)%s!\n",
+                     pClient->m_idClient, idMsg, GstCtrlHostFnName((eHostFn)idMsg), f60BetaHackInPlay ? " hack style" : ""));
+        NOREF(idMsg);
+        return rc;
+    }
+    LogFlowFunc(("[Client %RU32] Legacy message skipping: No messages pending!\n", pClient->m_idClient));
     return VINF_SUCCESS;
 }
@@ -2012,4 +2053,11 @@
          */
         case GUEST_MSG_REPLY:
+            if (cParms >= 3 && paParms[2].u.uint32 == (uint32_t)VERR_NOT_SUPPORTED)
+            {
+                HostCommand *pFirstCmd = RTListGetFirstCpp(&pClient->m_HostCmdList, HostCommand, m_ListEntry);
+                if (pFirstCmd && pFirstCmd->m_idContext == paParms[0].u.uint32)
+                    pFirstCmd->m_f60BetaHackInPlay = true;
+            }
+            RT_FALL_THROUGH();
         case GUEST_MSG_PROGRESS_UPDATE:
         case GUEST_SESSION_NOTIFY:
@@ -2036,5 +2084,5 @@
         case GUEST_MSG_SKIP_OLD:
             LogFlowFunc(("[Client %RU32] GUEST_MSG_SKIP_OLD\n", idClient));
-            rc = pThis->clientMsgOldSkip(pClient, cParms);
+            rc = pThis->clientMsgOldSkip(pClient, hCall, cParms);
             break;
 
@@ -2315,4 +2363,5 @@
          */
     }
+    pClient->m_fRestored = true;
     return VINF_SUCCESS;
 }
