Index: trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp	(revision 58257)
+++ trunk/src/VBox/Main/src-client/GuestDnDTargetImpl.cpp	(revision 58329)
@@ -866,5 +866,5 @@
     AssertPtrReturn(pMsg,    VERR_INVALID_POINTER);
 
-    DnDURIObject *pObj = pObjCtx->pObjURI;
+    DnDURIObject *pObj = pObjCtx->getObj();
     AssertPtr(pObj);
 
@@ -893,5 +893,5 @@
     AssertPtrReturn(pMsg,    VERR_INVALID_POINTER);
 
-    DnDURIObject *pObj = pObjCtx->pObjURI;
+    DnDURIObject *pObj = pObjCtx->getObj();
     AssertPtr(pObj);
 
@@ -920,5 +920,6 @@
         if (mDataBase.m_uProtocolVersion >= 2)
         {
-            if (!pObjCtx->fHeaderSent)
+            uint32_t fState = pObjCtx->getState();
+            if (!(fState & DND_OBJCTX_STATE_HAS_HDR))
             {
                 /*
@@ -941,5 +942,5 @@
                 /** @todo Set progress object title to current file being transferred? */
 
-                pObjCtx->fHeaderSent = true;
+                pObjCtx->setState(fState | DND_OBJCTX_STATE_HAS_HDR);
             }
             else
@@ -972,5 +973,5 @@
     AssertPtrReturn(pMsg,    VERR_INVALID_POINTER);
 
-    DnDURIObject *pObj = pObjCtx->pObjURI;
+    DnDURIObject *pObj = pObjCtx->getObj();
     AssertPtr(pObj);
 
@@ -1058,4 +1059,12 @@
     switch (uMsg)
     {
+        case GUEST_DND_CONNECT:
+            /* Nothing to do here (yet). */
+            break;
+
+        case GUEST_DND_DISCONNECT:
+            rc = VERR_CANCELLED;
+            break;
+
         case GUEST_DND_GET_NEXT_HOST_MSG:
         {
@@ -1252,5 +1261,5 @@
     rc = pCtx->mpResp->setCallback(x, i_sendURIDataCallback, pCtx); \
     if (RT_FAILURE(rc))                                             \
-        break;
+        return rc;
 
 #define UNREGISTER_CALLBACK(x)                        \
@@ -1267,4 +1276,18 @@
     if (RT_FAILURE(rc))
         return rc;
+
+    /*
+     * Register callbacks.
+     */
+    /* Guest callbacks. */
+    REGISTER_CALLBACK(GUEST_DND_CONNECT);
+    REGISTER_CALLBACK(GUEST_DND_DISCONNECT);
+    REGISTER_CALLBACK(GUEST_DND_GET_NEXT_HOST_MSG);
+    REGISTER_CALLBACK(GUEST_DND_GH_EVT_ERROR);
+    /* Host callbacks. */
+    REGISTER_CALLBACK(HOST_DND_HG_SND_DIR);
+    if (mDataBase.m_uProtocolVersion >= 2)
+        REGISTER_CALLBACK(HOST_DND_HG_SND_FILE_HDR);
+    REGISTER_CALLBACK(HOST_DND_HG_SND_FILE_DATA);
 
     do
@@ -1276,5 +1299,5 @@
         GuestDnDURIData *pURI  = &pCtx->mURI;
 
-        rc = pURI->fromMetaData(pData->getMeta());
+        rc = pURI->fromLocalMetaData(pData->getMeta());
         if (RT_FAILURE(rc))
             break;
@@ -1291,9 +1314,14 @@
 
         /*
-         * Set the additional size we are going to send after the meta data header + meta data.
-         * This additional data will contain the actual file data we want to transfer.
+         * Set the estimated data sizes we are going to send.
+         * The total size also contains the meta data size.
          */
-        pData->setAdditionalSize(pURI->getURIList().TotalBytes());
-
+        const uint32_t cbMeta = pData->getMeta().getSize();
+        pData->setEstimatedSize(pURI->getURIList().TotalBytes() + cbMeta /* cbTotal */,
+                                                                  cbMeta /* cbMeta  */);
+
+        /*
+         * Set the meta format.
+         */
         void    *pvFmt = (void *)pCtx->mFmtReq.c_str();
         uint32_t cbFmt = pCtx->mFmtReq.length() + 1;        /* Include terminating zero. */
@@ -1326,45 +1354,36 @@
         if (RT_SUCCESS(rc))
         {
-            /*
-             * Register callbacks.
-             */
-            /* Guest callbacks. */
-            REGISTER_CALLBACK(GUEST_DND_GET_NEXT_HOST_MSG);
-            REGISTER_CALLBACK(GUEST_DND_GH_EVT_ERROR);
-            /* Host callbacks. */
-            REGISTER_CALLBACK(HOST_DND_HG_SND_DIR);
-            if (mDataBase.m_uProtocolVersion >= 2)
-                REGISTER_CALLBACK(HOST_DND_HG_SND_FILE_HDR);
-            REGISTER_CALLBACK(HOST_DND_HG_SND_FILE_DATA);
-
             rc = waitForEvent(&pCtx->mCBEvent, pCtx->mpResp, msTimeout);
-            if (RT_FAILURE(rc))
-            {
-                if (rc == VERR_CANCELLED)
-                    rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED, VINF_SUCCESS);
-                else if (rc != VERR_GSTDND_GUEST_ERROR) /* Guest-side error are already handled in the callback. */
-                    rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_ERROR, rc,
-                                                   GuestDnDTarget::i_hostErrorToString(rc));
-            }
-            else
-                rc = pCtx->mpResp->setProgress(100, DND_PROGRESS_COMPLETE, VINF_SUCCESS);
-
-            /*
-             * Unregister callbacks.
-             */
-            /* Guest callbacks. */
-            UNREGISTER_CALLBACK(GUEST_DND_GET_NEXT_HOST_MSG);
-            UNREGISTER_CALLBACK(GUEST_DND_GH_EVT_ERROR);
-            /* Host callbacks. */
-            UNREGISTER_CALLBACK(HOST_DND_HG_SND_DIR);
-            if (mDataBase.m_uProtocolVersion >= 2)
-                UNREGISTER_CALLBACK(HOST_DND_HG_SND_FILE_HDR);
-            UNREGISTER_CALLBACK(HOST_DND_HG_SND_FILE_DATA);
+            if (RT_SUCCESS(rc))
+                pCtx->mpResp->setProgress(100, DND_PROGRESS_COMPLETE, VINF_SUCCESS);
         }
 
     } while (0);
+
+    /*
+     * Unregister callbacks.
+     */
+    /* Guest callbacks. */
+    UNREGISTER_CALLBACK(GUEST_DND_CONNECT);
+    UNREGISTER_CALLBACK(GUEST_DND_DISCONNECT);
+    UNREGISTER_CALLBACK(GUEST_DND_GET_NEXT_HOST_MSG);
+    UNREGISTER_CALLBACK(GUEST_DND_GH_EVT_ERROR);
+    /* Host callbacks. */
+    UNREGISTER_CALLBACK(HOST_DND_HG_SND_DIR);
+    if (mDataBase.m_uProtocolVersion >= 2)
+        UNREGISTER_CALLBACK(HOST_DND_HG_SND_FILE_HDR);
+    UNREGISTER_CALLBACK(HOST_DND_HG_SND_FILE_DATA);
 
 #undef REGISTER_CALLBACK
 #undef UNREGISTER_CALLBACK
+
+    if (RT_FAILURE(rc))
+    {
+        if (rc == VERR_CANCELLED)
+            pCtx->mpResp->setProgress(100, DND_PROGRESS_CANCELLED, VINF_SUCCESS);
+        else if (rc != VERR_GSTDND_GUEST_ERROR) /* Guest-side error are already handled in the callback. */
+            pCtx->mpResp->setProgress(100, DND_PROGRESS_ERROR, rc,
+                                      GuestDnDTarget::i_hostErrorToString(rc));
+    }
 
     /*
@@ -1401,5 +1420,5 @@
         return VERR_WRONG_ORDER;
 
-    DnDURIObject *pCurObj = objCtx.pObjURI;
+    DnDURIObject *pCurObj = objCtx.getObj();
     AssertPtr(pCurObj);
 
