Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h	(revision 59839)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h	(revision 59840)
@@ -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
@@ -112,7 +112,11 @@
 protected:
 
+    /** Reference count of this object. */
     LONG                  mRefCount;
+    /** Pointer to parent proxy window. */
     VBoxDnDWnd           *mpWndParent;
+    /** Current drag effect. */
     DWORD                 mdwCurEffect;
+    /** Current action to perform on the host. */
     uint32_t              muCurAction;
 };
@@ -140,4 +144,5 @@
 protected:
 
+    static void DumpFormats(IDataObject *pDataObject);
     static DWORD GetDropEffect(DWORD grfKeyState, DWORD dwAllowedEffects);
     void reset(void);
@@ -145,21 +150,29 @@
 public:
 
-    void *DataMutableRaw(void) { return mpvData; }
-    uint32_t DataSize(void) { return mcbData; }
-    RTCString Formats(void);
+    void *DataMutableRaw(void) const { return mpvData; }
+    size_t DataSize(void) const { return mcbData; }
+    RTCString Formats(void) const;
     int WaitForDrop(RTMSINTERVAL msTimeout);
 
 protected:
 
+    /** Reference count of this object. */
     LONG                  mRefCount;
+    /** Pointer to parent proxy window. */
     VBoxDnDWnd           *mpWndParent;
+    /** Current drop effect. */
     DWORD                 mdwCurEffect;
-    /** Copy of the data object's FORMATETC struct.
+    /** Copy of the data object's current FORMATETC struct.
      *  Note: We don't keep the pointer of the DVTARGETDEVICE here! */
     FORMATETC             mFormatEtc;
-    RTCString             mFormats;
+    /** Stringified data object's formats string.  */
+    RTCString             mstrFormats;
+    /** Pointer to actual format data. */
     void                 *mpvData;
-    uint32_t              mcbData;
+    /** Size (in bytes) of format data. */
+    size_t                mcbData;
+    /** Event for waiting on the "drop" event. */
     RTSEMEVENT            hEventDrop;
+    /** Result of the drop event. */
     int                   mDroppedRc;
 };
Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp	(revision 59839)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp	(revision 59840)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2014-2015 Oracle Corporation
+ * Copyright (C) 2014-2016 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -93,4 +93,36 @@
 }
 
+/* static */
+void VBoxDnDDropTarget::DumpFormats(IDataObject *pDataObject)
+{
+    AssertPtrReturnVoid(pDataObject);
+
+    /* Enumerate supported source formats. This shouldn't happen too often
+     * on day to day use, but still keep it in here. */
+    IEnumFORMATETC *pEnumFormats;
+    HRESULT hr2 = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormats);
+    if (SUCCEEDED(hr2))
+    {
+        LogRel(("DnD: The following formats were offered to us:\n"));
+
+        FORMATETC curFormatEtc;
+        while (pEnumFormats->Next(1, &curFormatEtc,
+                                  NULL /* pceltFetched */) == S_OK)
+        {
+            WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */
+            hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName,
+                                          sizeof(wszCfName) / sizeof(WCHAR));
+            LogRel(("\tcfFormat=%RI16 (%s), tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",
+                    curFormatEtc.cfFormat,
+                    VBoxDnDDataObject::ClipboardFormatToString(curFormatEtc.cfFormat),
+                    curFormatEtc.tymed,
+                    curFormatEtc.dwAspect,
+                    wszCfName, hr2));
+        }
+
+        pEnumFormats->Release();
+    }
+}
+
 /*
  * IDropTarget methods.
@@ -110,11 +142,15 @@
     /** @todo At the moment we only support one DnD format at a time. */
 
-    /* Try different formats. CF_HDROP is the most common one, so start
-     * with this. */
+#ifdef DEBUG
+    VBoxDnDDropTarget::DumpFormats(pDataObject);
+#endif
+
+    /* Try different formats.
+     * CF_HDROP is the most common one, so start with this. */
     FORMATETC fmtEtc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
     HRESULT hr = pDataObject->QueryGetData(&fmtEtc);
     if (hr == S_OK)
     {
-        mFormats = "text/uri-list";
+        mstrFormats = "text/uri-list";
     }
     else
@@ -128,5 +164,5 @@
         if (hr == S_OK)
         {
-            mFormats = "text/plain;charset=utf-8";
+            mstrFormats = "text/plain;charset=utf-8";
         }
         else
@@ -138,10 +174,13 @@
             if (hr == S_OK)
             {
-                mFormats = "text/plain;charset=utf-8";
+                mstrFormats = "text/plain;charset=utf-8";
             }
             else
             {
                 LogFlowFunc(("CF_TEXT not wanted, hr=%Rhrc\n", hr));
-                fmtEtc.cfFormat = 0; /* Mark it to not supported. */
+                fmtEtc.cfFormat = 0; /* Set it to non-supported. */
+
+                /* Clean up. */
+                reset();
             }
         }
@@ -156,5 +195,5 @@
         /* Make a copy of the FORMATETC structure so that we later can
          * use this for comparrison and stuff. */
-        /** Note: The DVTARGETDEVICE member only is a shallow copy for now! */
+        /** @todo The DVTARGETDEVICE member only is a shallow copy for now! */
         memcpy(&mFormatEtc, &fmtEtc, sizeof(FORMATETC));
 
@@ -174,31 +213,5 @@
             {
                 LogRel(("DnD: Drag and drop format is not supported by VBoxTray\n"));
-
-                /* Enumerate supported source formats. This shouldn't happen too often
-                 * on day to day use, but still keep it in here. */
-                IEnumFORMATETC *pEnumFormats;
-                HRESULT hr2 = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormats);
-                if (SUCCEEDED(hr2))
-                {
-                    LogRel(("DnD: The following formats were offered to us:\n"));
-
-                    FORMATETC curFormatEtc;
-                    while (pEnumFormats->Next(1, &curFormatEtc,
-                                              NULL /* pceltFetched */) == S_OK)
-                    {
-                        WCHAR wszCfName[128]; /* 128 chars should be enough, rest will be truncated. */
-                        hr2 = GetClipboardFormatNameW(curFormatEtc.cfFormat, wszCfName,
-                                                      sizeof(wszCfName) / sizeof(WCHAR));
-                        LogRel(("\tcfFormat=%RI16 (%s), tyMed=%RI32, dwAspect=%RI32, strCustomName=%ls, hr=%Rhrc\n",
-                                curFormatEtc.cfFormat,
-                                VBoxDnDDataObject::ClipboardFormatToString(curFormatEtc.cfFormat),
-                                curFormatEtc.tymed,
-                                curFormatEtc.dwAspect,
-                                wszCfName, hr2));
-                    }
-
-                    pEnumFormats->Release();
-                }
-
+                VBoxDnDDropTarget::DumpFormats(pDataObject);
                 break;
             }
@@ -209,6 +222,6 @@
     }
 
-    LogFlowFunc(("Returning cfFormat=%RI16, pdwEffect=%ld, hr=%Rhrc\n",
-                 fmtEtc.cfFormat, *pdwEffect, hr));
+    LogFlowFunc(("Returning mstrFormats=%s, cfFormat=%RI16, pdwEffect=%ld, hr=%Rhrc\n",
+                 mstrFormats.c_str(), fmtEtc.cfFormat, *pdwEffect, hr));
     return hr;
 }
@@ -256,22 +269,19 @@
 {
     AssertPtrReturn(pDataObject, E_INVALIDARG);
-    AssertPtrReturn(pdwEffect, E_INVALIDARG);
-
-#ifdef DEBUG
+    AssertPtrReturn(pdwEffect,   E_INVALIDARG);
+
     LogFlowFunc(("mFormatEtc.cfFormat=%RI16 (%s), pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n",
                  mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
                  pDataObject, grfKeyState, pt.x, pt.y));
-#endif
+
     HRESULT hr = S_OK;
 
     if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */
     {
-        /* Make sure the data object's data format is still the same
-         * as we got it in DragEnter(). */
+        /* Make sure the data object's data format is still valid. */
         hr = pDataObject->QueryGetData(&mFormatEtc);
         AssertMsg(SUCCEEDED(hr),
-                  ("Data format changed between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n",
-                  mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
-                  hr));
+                  ("Data format changed to invalid between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n",
+                  mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), hr));
     }
 
@@ -313,44 +323,38 @@
             if (RT_SUCCESS(rc))
             {
-                /* Second stage: Do the actual copying of the data object's data,
-                                 based on the storage medium type. */
+                /*
+                 * Second stage: Do the actual copying of the data object's data,
+                 *               based on the storage medium type.
+                 */
                 switch (mFormatEtc.cfFormat)
                 {
+                    case CF_TEXT:
+                    /* Fall through is intentional. */
                     case CF_UNICODETEXT:
                     {
                         AssertPtr(pvData);
                         size_t cbSize = GlobalSize(pvData);
-                        LogFlowFunc(("CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
+                        LogFlowFunc(("CF_TEXT/CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
                         if (cbSize)
                         {
                             char *pszText = NULL;
-                            rc = RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);
+
+                            rc = mFormatEtc.cfFormat == CF_TEXT
+                               /* ANSI codepage -> UTF-8 */
+                               ? RTStrCurrentCPToUtf8(&pszText, (char *)pvData)
+                               /* Unicode  -> UTF-8 */
+                               : RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);
+
                             if (RT_SUCCESS(rc))
                             {
-                                mpvData = (void *)pszText;
-                                mcbData = strlen(pszText) + 1; /* Include termination. */
-
-                                /* Note: Don't free data of pszText, mpvData now owns it. */
-                            }
-                        }
-
-                        break;
-                    }
-
-                    case CF_TEXT:
-                    {
-                        AssertPtr(pvData);
-                        size_t cbSize = GlobalSize(pvData);
-                        LogFlowFunc(("CF_TEXT 0x%p got %zu bytes\n", pvData, cbSize));
-                        if (cbSize)
-                        {
-                            char *pszText = NULL;
-                            rc = RTStrCurrentCPToUtf8(&pszText, (char *)pvData);
-                            if (RT_SUCCESS(rc))
-                            {
-                                mpvData = (void *)pszText;
-                                mcbData = strlen(pszText) + 1; /* Include termination. */
-
-                                /* Note: Don't free data of pszText, mpvData now owns it. */
+                                AssertPtr(pszText);
+
+                                size_t cbText = strlen(pszText) + 1; /* Include termination. */
+
+                                mpvData = RTMemDup((void *)pszText, cbText);
+                                mcbData = cbText;
+
+                                RTStrFree(pszText);
+                                pszText = NULL;
                             }
                         }
@@ -429,7 +433,5 @@
                             if (RT_SUCCESS(rc))
                             {
-                                LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n",
-                                             pszFile, cchFile));
-
+                                LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n", pszFile, cchFile));
                                 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
                                                      pszFile, cchFile);
@@ -491,6 +493,5 @@
                         /* Note: Should not happen due to the checks done in DragEnter(). */
                         AssertMsgFailed(("Format of type %RI16 (%s) not supported\n",
-                                         mFormatEtc.cfFormat,
-                                         VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat)));
+                                         mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat)));
                         hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */
                         break;
@@ -580,11 +581,12 @@
 
     mcbData = 0;
+
     RT_ZERO(mFormatEtc);
-    mFormats = "";
-}
-
-RTCString VBoxDnDDropTarget::Formats(void)
-{
-    return mFormats;
+    mstrFormats = "";
+}
+
+RTCString VBoxDnDDropTarget::Formats(void) const
+{
+    return mstrFormats;
 }
 
