Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp	(revision 59843)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp	(revision 59844)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2013-2015 Oracle Corporation
+ * Copyright (C) 2013-2016 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -799,5 +799,5 @@
          */
         size_t cFormatsSup    = this->lstFmtSup.size();
-        size_t cFormatsActive = 0;
+        ULONG  cFormatsActive = 0;
 
         LPFORMATETC pFormatEtc = new FORMATETC[cFormatsSup];
@@ -1220,8 +1220,8 @@
         uAllActions = uDefAction;
 
-        rc = VbglR3DnDGHSendAckPending(&mDnDCtx,
-                                       uDefAction, uAllActions,
-                                       strFormats.c_str(), strFormats.length() + 1 /* Include termination */);
-        if (RT_FAILURE(rc))
+        int rc2 = VbglR3DnDGHSendAckPending(&mDnDCtx,
+                                            uDefAction, uAllActions,
+                                            strFormats.c_str(), strFormats.length() + 1 /* Include termination */);
+        if (RT_FAILURE(rc2))
         {
             char szMsg[256]; /* Sizes according to MSDN. */
@@ -1233,7 +1233,8 @@
                                               "Please enable Guest to Host or Bidirectional drag and drop mode "
                                               "or re-install the VirtualBox Guest Additions.");
-            switch (rc)
+            switch (rc2)
             {
                 case VERR_ACCESS_DENIED:
+                {
                     rc = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON,
                                            szMsg, szTitle,
@@ -1241,8 +1242,12 @@
                     AssertRC(rc);
                     break;
+                }
 
                 default:
                     break;
             }
+
+            LogRel2(("DnD: Host refuses drag and drop operation from guest: %Rrc\n", rc2));
+            reset();
         }
     }
@@ -1269,5 +1274,5 @@
 {
     AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
-    AssertReturn(cbFormat, VERR_INVALID_PARAMETER);
+    AssertReturn(cbFormat,     VERR_INVALID_PARAMETER);
 
     LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, pszFormat=%s, uDefAction=0x%x\n",
@@ -1279,5 +1284,5 @@
         {
             AssertPtr(pDropTarget);
-            rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
+            rc = pDropTarget->WaitForDrop(5 * 1000 /* 5s timeout */);
 
             reset();
@@ -1293,15 +1298,30 @@
         {
             /** @todo Respect uDefAction. */
-            void *pvData = pDropTarget->DataMutableRaw();
-            AssertPtr(pvData);
+            void *pvData    = pDropTarget->DataMutableRaw();
             uint32_t cbData = pDropTarget->DataSize();
-            Assert(cbData);
-
-            rc = VbglR3DnDGHSendData(&mDnDCtx, pszFormat, pvData, cbData);
-            LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n", pvData, cbData, rc));
+
+            if (   pvData
+                && cbData)
+            {
+                rc = VbglR3DnDGHSendData(&mDnDCtx, pszFormat, pvData, cbData);
+                LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n", pvData, cbData, rc));
+            }
+            else
+                rc = VERR_NO_DATA;
         }
     }
     else
         rc = VERR_WRONG_ORDER;
+
+    if (RT_FAILURE(rc))
+    {
+        /*
+         * If an error occurred or the guest is in a wrong DnD mode,
+         * send an error to the host in any case so that the host does
+         * not wait for the data it expects from the guest.
+         */
+        int rc2 = VbglR3DnDGHSendError(&mDnDCtx, rc);
+        AssertRC(rc2);
+    }
 
     LogFlowFuncLeaveRC(rc);
@@ -1499,7 +1519,6 @@
 int VBoxDnDWnd::mouseRelease(void)
 {
-#ifdef DEBUG_andy
-    LogFlowFunc(("\n"));
-#endif
+    LogFlowFuncEnter();
+
     int rc;
 
@@ -1786,13 +1805,15 @@
             }
             else
-                LogFlowFunc(("Processing event failed with rc=%Rrc\n", rc));
+                LogRel(("DnD: Processing proxy window event %RU32 on screen %RU32 failed with %Rrc\n",
+                        pEvent->Event.uType, pEvent->Event.uScreenId, rc));
         }
         else if (rc == VERR_INTERRUPTED) /* Disconnected from service. */
         {
-            LogFlowFunc(("Posting quit message ...\n"));
+            LogRel(("DnD: Received quit message, shutting down ...\n"));
             pWnd->PostMessage(WM_QUIT, 0 /* wParm */, 0 /* lParm */);
             rc = VINF_SUCCESS;
         }
-        else
+
+        if (RT_FAILURE(rc))
         {
             LogFlowFunc(("Processing next message failed with rc=%Rrc\n", rc));
@@ -1809,6 +1830,18 @@
             }
 
+            /* Make sure our proxy window is hidden when an error occured to
+             * not block the guest's UI. */
+            pWnd->hide();
+
             int rc2 = VbglR3DnDGHSendError(&pCtx->cmdCtx, rc);
-            AssertRC(rc2);
+            if (RT_FAILURE(rc2))
+            {
+                /* Ignore the following errors reported back from the host. */
+                if (   rc2 != VERR_NOT_SUPPORTED
+                    && rc2 != VERR_NOT_IMPLEMENTED)
+                {
+                    LogRel(("DnD: Could not report error %Rrc back to host: %Rrc\n", rc, rc2));
+                }
+            }
         }
 
@@ -1826,7 +1859,7 @@
     }
 
-    LogFlowFunc(("Shutting down ...\n"));
-
     VbglR3DnDDisconnect(&pCtx->cmdCtx);
+
+    LogRel(("DnD: Ended\n"));
 
     LogFlowFuncLeaveRC(rc);
