Index: /trunk/include/VBox/VBoxGuestLib.h
===================================================================
--- /trunk/include/VBox/VBoxGuestLib.h	(revision 86868)
+++ /trunk/include/VBox/VBoxGuestLib.h	(revision 86869)
@@ -1232,4 +1232,6 @@
     VBGLR3DNDEVENTTYPE_GH_DROP        = 102,
 # endif
+    /** Tells the caller that it has to quit operation. */
+    VBGLR3DNDEVENTTYPE_QUIT           = 200,
     /** Blow the type up to 32-bit. */
     VBGLR3DNDEVENTTYPE_32BIT_HACK = 0x7fffffff
Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp	(revision 86868)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp	(revision 86869)
@@ -610,4 +610,10 @@
                 }
 
+                case VBGLR3DNDEVENTTYPE_QUIT:
+                {
+                    LogRel(("DnD: Received quit message, shutting down ...\n"));
+                    PostQuitMessage(0);
+                }
+
 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
                 case VBGLR3DNDEVENTTYPE_GH_ERROR:
@@ -1877,10 +1883,4 @@
                 LogRel(("DnD: Processing proxy window event %RU32 failed with %Rrc\n", pVbglR3Event->enmType, rc));
         }
-        else if (rc == VERR_INTERRUPTED) /* Disconnected from service. */
-        {
-            LogRel(("DnD: Received quit message, shutting down ...\n"));
-            pWnd->PostMessage(WM_QUIT, 0 /* wParm */, 0 /* lParm */);
-            rc = VINF_SUCCESS;
-        }
 
         if (RT_FAILURE(rc))
Index: /trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp	(revision 86868)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibDragAndDrop.cpp	(revision 86869)
@@ -61,4 +61,5 @@
  *
  * @returns IPRT status code.
+ *          Will return VERR_CANCELLED (implemented by the host service) if we need to bail out.
  * @param   pCtx                DnD context to use.
  * @param   puMsg               Where to store the message type.
@@ -72,16 +73,22 @@
     AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
 
-    HGCMMsgGetNext Msg;
-    VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_FN_GET_NEXT_HOST_MSG, 3);
-    Msg.uMsg.SetUInt32(0);
-    Msg.cParms.SetUInt32(0);
-    Msg.fBlock.SetUInt32(fWait ? 1 : 0);
-
-    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
-    if (RT_SUCCESS(rc))
-    {
-        rc = Msg.uMsg.GetUInt32(puMsg);     AssertRC(rc);
-        rc = Msg.cParms.GetUInt32(pcParms); AssertRC(rc);
-    }
+    int rc;
+
+    do
+    {
+        HGCMMsgGetNext Msg;
+        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, GUEST_DND_FN_GET_NEXT_HOST_MSG, 3);
+        Msg.uMsg.SetUInt32(0);
+        Msg.cParms.SetUInt32(0);
+        Msg.fBlock.SetUInt32(fWait ? 1 : 0);
+
+        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
+        if (RT_SUCCESS(rc))
+        {
+            rc = Msg.uMsg.GetUInt32(puMsg);     AssertRC(rc);
+            rc = Msg.cParms.GetUInt32(pcParms); AssertRC(rc);
+        }
+
+    } while (rc == VERR_INTERRUPTED);
 
     return rc;
@@ -1078,7 +1085,12 @@
 {
     AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
+
+    if (!pCtx->uClientID) /* Already disconnected? Bail out early. */
+        return VINF_SUCCESS;
+
     int rc = VbglR3HGCMDisconnect(pCtx->uClientID);
     if (RT_SUCCESS(rc))
         pCtx->uClientID = 0;
+
     return rc;
 }
@@ -1162,4 +1174,13 @@
                 rc = VbglR3DnDConnect(pCtx);
         }
+    }
+
+    if (rc == VERR_CANCELLED) /* Host service told us that we have to bail out. */
+    {
+        pEvent->enmType = VBGLR3DNDEVENTTYPE_QUIT;
+
+        *ppEvent = pEvent;
+
+        return VINF_SUCCESS;
     }
 
Index: /trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp
===================================================================
--- /trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp	(revision 86868)
+++ /trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp	(revision 86869)
@@ -147,8 +147,13 @@
 void DragAndDropClient::disconnect(void) RT_NOEXCEPT
 {
-    LogFlowThisFunc(("uClient=%RU32\n", m_idClient));
-
+    LogFlowThisFunc(("uClient=%RU32, fDeferred=%RTbool\n", m_idClient, IsDeferred()));
+
+    /*
+     * If the client still is waiting for a message (i.e in deferred mode),
+     * complete the call with a VERR_CANCELED status so that the client (VBoxTray / VBoxClient) knows
+     * it should bail out.
+     */
     if (IsDeferred())
-        CompleteDeferred(VERR_INTERRUPTED);
+        CompleteDeferred(VERR_CANCELLED);
 
     /*
@@ -471,8 +476,4 @@
             break;
     }
-
-#ifdef DEBUG_andy
-    LogFlowFunc(("Mode (%RU32) check rc=%Rrc\n", modeGet(), rc));
-#endif
 
 #define DO_HOST_CALLBACK();                                                                   \
@@ -1028,4 +1029,6 @@
     if (rc == VINF_HGCM_ASYNC_EXECUTE)
     {
+        LogFlowFunc(("Deferring client %RU32\n", idClient));
+
         try
         {
