Index: /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp	(revision 59847)
+++ /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp	(revision 59848)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2011-2015 Oracle Corporation
+ * Copyright (C) 2011-2016 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -640,5 +640,8 @@
                             }
                             else
+                            {
+                                AssertMsgFailed(("ObjType=%RU32, Proto=%RU32\n", objFile.GetType(), pCtx->uProtocol));
                                 rc = VERR_WRONG_ORDER;
+                            }
 
                             RTStrFree(pszPathAbs);
@@ -651,6 +654,4 @@
                         && uNextMsg == HOST_DND_HG_SND_FILE_DATA)
                     {
-                        bool fClose = false;
-
                         uint32_t cbChunkWritten;
                         rc = objFile.Write(pvChunk, cbChunkRead, &cbChunkWritten);
@@ -661,36 +662,38 @@
                                          cbChunkRead, cbChunkWritten, cbFileWritten + cbChunkWritten, cbFileSize));
 
-                            if (pCtx->uProtocol >= 2)
+                            cbFileWritten += cbChunkWritten;
+
+                            if (fDoAccounting)
                             {
-                                /* Data transfer complete? Close the file. */
-                                fClose = objFile.IsComplete();
-                                if (   fClose
-                                    && fDoAccounting)
-                                {
-                                    Assert(cToRecvObjs);
-                                    cToRecvObjs--;
-                                }
-
-                                /* Only since protocol v2 we know the file size upfront. */
-                                Assert(cbFileWritten <= cbFileSize);
-                            }
-                            else
-                                fClose = true; /* Always close the file after each chunk. */
-
-                            cbFileWritten += cbChunkWritten;
-
-                            if (pCtx->uProtocol >= 3)
-                            {
-                                Assert(cbToRecvBytes >= cbChunkRead);
+                                Assert(cbChunkRead <= cbToRecvBytes);
                                 cbToRecvBytes -= cbChunkRead;
                             }
                         }
-
-                        if (fClose)
+                    }
+
+                    bool fClose = false;
+                    if (pCtx->uProtocol >= 2)
+                    {
+                        /* Data transfer complete? Close the file. */
+                        fClose = objFile.IsComplete();
+                        if (   fClose
+                            && fDoAccounting)
                         {
-                            LogFlowFunc(("Closing file\n"));
-                            objFile.Close();
+                            Assert(cToRecvObjs);
+                            cToRecvObjs--;
                         }
+
+                        /* Only since protocol v2 we know the file size upfront. */
+                        Assert(cbFileWritten <= cbFileSize);
                     }
+                    else
+                        fClose = true; /* Always close the file after each chunk. */
+
+                    if (fClose)
+                    {
+                        LogFlowFunc(("Closing file\n"));
+                        objFile.Close();
+                    }
+
                     break;
                 }
@@ -741,7 +744,5 @@
     {
         objFile.Close();
-
-        int rc2 = pDroppedFiles->Rollback();
-        AssertRC(rc2); /* Not fatal, don't report back to host. */
+        pDroppedFiles->Rollback();
     }
     else
@@ -1201,5 +1202,6 @@
 
         int rc2 = VbglR3DnDHGSendProgress(pCtx, DND_PROGRESS_ERROR, 100 /* Percent */, rc);
-        AssertRC(rc2);
+        if (RT_FAILURE(rc2))
+            LogFlowFunc(("Unable to send progress error %Rrc to host: %Rrc\n", rc, rc2));
     }
     else if (RT_SUCCESS(rc))
@@ -1419,5 +1421,5 @@
             Msg.hdr.cParms = 3;
 
-             /** @todo Context ID not used yet. */
+            /** @todo Context ID not used yet. */
             Msg.u.v3.uContext.SetUInt32(0);
             Msg.u.v3.uProtocol.SetUInt32(pCtx->uProtocol);
@@ -1711,5 +1713,5 @@
 
     if (!RTStrIsValidEncoding(pcszFormats))
-        return VERR_INVALID_PARAMETER;
+        return VERR_INVALID_UTF8_ENCODING;
 
     VBOXDNDGHACKPENDINGMSG Msg;
@@ -1786,5 +1788,5 @@
             rc = Msg.hdr.result;
 
-        LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU64, cObjects=%RU64, rc=%Rrc\n",
+        LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU64, rc=%Rrc\n",
                      pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects, rc));
     }
@@ -1839,9 +1841,12 @@
         }
 
+        LogFlowFunc(("cbMaxChunk=%RU32, cbData=%RU64, cbSent=%RU32, rc=%Rrc\n",
+                     cbMaxChunk, cbData, cbSent, rc));
+
         if (RT_SUCCESS(rc))
             Assert(cbSent == cbData);
     }
 
-    LogFlowFunc(("Returning rc=%Rrc, cbData=%RU64\n", rc, cbData));
+    LogFlowFuncLeaveRC(rc);
     return rc;
 }
@@ -2073,6 +2078,20 @@
 }
 
-static int vbglR3DnDGHSendURIData(PVBGLR3GUESTDNDCMDCTX pCtx,
-                                  const void *pvData, uint32_t cbData)
+static int vbglR3DnDGHSendRawData(PVBGLR3GUESTDNDCMDCTX pCtx, void *pvData, size_t cbData)
+{
+    AssertPtrReturn(pCtx,   VERR_INVALID_POINTER);
+    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
+    /* cbData can be 0. */
+
+    VBOXDNDDATAHDR dataHdr;
+    RT_ZERO(dataHdr);
+
+    /* For raw data only the total size is required to be specified. */
+    dataHdr.cbTotal = cbData;
+
+    return vbglR3DnDGHSendDataInternal(pCtx, pvData, cbData, &dataHdr);
+}
+
+static int vbglR3DnDGHSendURIData(PVBGLR3GUESTDNDCMDCTX pCtx, const void *pvData, size_t cbData)
 {
     AssertPtrReturn(pCtx,   VERR_INVALID_POINTER);
@@ -2109,14 +2128,14 @@
             const uint32_t cbMetaFmt   = (uint32_t)strlen(szMetaFmt) + 1; /* Include termination. */
 
-            VBOXDNDDATAHDR dataHeader;
-            dataHeader.uFlags    = 0; /* Flags not used yet. */
-            dataHeader.cbTotal   = cbTotal;
-            dataHeader.cbMeta    = cbURLIist;
-            dataHeader.pvMetaFmt = (void *)szMetaFmt;
-            dataHeader.cbMetaFmt = cbMetaFmt;
-            dataHeader.cObjects  = lstURI.TotalCount();
+            VBOXDNDDATAHDR dataHdr;
+            dataHdr.uFlags    = 0; /* Flags not used yet. */
+            dataHdr.cbTotal   = cbTotal;
+            dataHdr.cbMeta    = cbURLIist;
+            dataHdr.pvMetaFmt = (void *)szMetaFmt;
+            dataHdr.cbMetaFmt = cbMetaFmt;
+            dataHdr.cObjects  = lstURI.TotalCount();
 
             rc = vbglR3DnDGHSendDataInternal(pCtx,
-                                             pvURIList, cbURLIist, &dataHeader);
+                                             pvURIList, cbURLIist, &dataHdr);
         }
         else
@@ -2153,10 +2172,9 @@
     if (DnDMIMEHasFileURLs(pszFormat, strlen(pszFormat)))
     {
+        /* Send file data. */
         rc = vbglR3DnDGHSendURIData(pCtx, pvData, cbData);
     }
-    else /* Send raw data. */
-    {
-        rc = vbglR3DnDGHSendDataInternal(pCtx, pvData, cbData, NULL /* pDataHdr */);
-    }
+    else
+        rc = vbglR3DnDGHSendRawData(pCtx, pvData, cbData);
 
     if (RT_FAILURE(rc))
@@ -2197,8 +2215,16 @@
     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     if (RT_SUCCESS(rc))
-        rc = Msg.hdr.result;
-
-    if (RT_FAILURE(rc))
-        LogFlowFunc(("Sending error %Rrc failed with rc=%Rrc\n", rcErr, rc));
+    {
+        if (RT_FAILURE(Msg.hdr.result))
+        {
+            LogFlowFunc(("Sending error %Rrc failed with rc=%Rrc\n", rcErr, Msg.hdr.result));
+
+            /* Never return an error if the host did not accept the error at
+             * the current time. This can be due to the host not having any appropriate
+             * callbacks set which would handle that error. */
+            rc = VINF_SUCCESS;
+        }
+    }
+
     return rc;
 }
