Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp	(revision 50398)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp	(revision 50399)
@@ -46,4 +46,11 @@
 #define WM_VBOXTRAY_DND_MESSAGE       WM_APP + 401
 
+/** Function pointer for SendInput(). This only is available starting
+ *  at NT4 SP3+. */
+typedef BOOL (WINAPI *PFNSENDINPUT)(UINT, LPINPUT, int);
+
+/** Static pointer to SendInput() function. */
+static PFNSENDINPUT s_pfnSendInput = NULL;
+
 static LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 static LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -335,5 +342,5 @@
                     HRESULT hr = DoDragDrop(startupInfo.pDataObject, startupInfo.pDropSource,
                                             startupInfo.dwOKEffects, &dwEffect);
-                    LogFlowThisFunc(("rc=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
+                    LogFlowThisFunc(("hr=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
                     switch (hr)
                     {
@@ -773,24 +780,9 @@
                      u32xPos, u32yPos, uAction));
 
-    /** @todo Put this block into a function! */
-    /** @todo Multi-monitor setups? */
-    int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
-    int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
-
-    INPUT Input[1] = { 0 };
-    Input[0].type       = INPUT_MOUSE;
-    Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE;
-    Input[0].mi.dx      = u32xPos * (65535 / iScreenX);
-    Input[0].mi.dy      = u32yPos * (65535 / iScreenY);
-    SendInput(1, Input, sizeof(INPUT));
-
-#ifdef DEBUG_andy
-    POINT p;
-    GetCursorPos(&p);
-    LogFlowThisFunc(("curX=%d, curY=%d\n", p.x, p.y));
-#endif
+    int rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
 
     uint32_t uActionNotify = DND_IGNORE_ACTION;
-    int rc = RTCritSectEnter(&mCritSect);
+    if (RT_SUCCESS(rc))
+        rc = RTCritSectEnter(&mCritSect);
     if (RT_SUCCESS(rc))
     {
@@ -889,5 +881,5 @@
     }
 
-    int rc2 = dragRelease();
+    int rc2 = mouseRelease();
     if (RT_SUCCESS(rc))
         rc = rc2;
@@ -908,5 +900,5 @@
     }
 
-    int rc2 = dragRelease();
+    int rc2 = mouseRelease();
     if (RT_SUCCESS(rc))
         rc = rc2;
@@ -936,5 +928,5 @@
              * get into our (invisible) proxy window.
              */
-            dragRelease();
+            mouseRelease();
 
             /*
@@ -980,23 +972,198 @@
         if (py <= 0)
             py = 1;
-        //px++; py++;
-        LogFlowThisFunc(("px=%ld, py=%ld\n", px, py));
-
-        INPUT Input[1] = { 0 };
-        Input[0].type       = INPUT_MOUSE;
-        Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | /*MOUSEEVENTF_LEFTDOWN |*/ MOUSEEVENTF_ABSOLUTE;
-        Input[0].mi.dx      = px * (65535 / iScreenX);
-        Input[0].mi.dy      = py * (65535 / iScreenY);
-        UINT uiProcessed = SendInput(1, Input, sizeof(INPUT));
-        if (uiProcessed)
-        {
+
+        rc = mouseMove(px, py, 0 /* dwMouseInputFlags */);
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        uint32_t uDefAction = DND_IGNORE_ACTION;
+
+        AssertPtr(pDropTarget);
+        RTCString strFormats = pDropTarget->Formats();
+        if (!strFormats.isEmpty())
+        {
+            uDefAction = DND_COPY_ACTION;
+            uAllActions = uDefAction;
+
+            LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n",
+                         pDropTarget, uDefAction, uAllActions, strFormats.c_str()));
+            rc = VbglR3DnDGHAcknowledgePending(mClientID,
+                                               uDefAction, uAllActions, strFormats.c_str());
+        }
+        else
+            LogFlowFunc(("No format data available yet\n"));
+    }
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+int VBoxDnDWnd::OnGhDropped(const char *pszFormat, uint32_t cbFormats,
+                            uint32_t uDefAction)
+{
+    AssertPtrReturn(pszFormat, VERR_INVALID_POINTER);
+    AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
+
+    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, uDefAction=0x%x\n",
+                     mMode, mState, pDropTarget, uDefAction));
+
+    int rc;
+    if (mState == Dragging)
+    {
+        AssertPtr(pDropTarget);
+        rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
+        if (RT_SUCCESS(rc))
+        {
+            /** @todo Respect uDefAction. */
+            /** @todo Do data checking / conversion based on pszFormats. */
+
+            void *pvData = pDropTarget->DataMutableRaw();
+            AssertPtr(pvData);
+            uint32_t cbData = pDropTarget->DataSize();
+            Assert(cbData);
+
+            rc = VbglR3DnDGHSendData(mClientID, pvData, cbData);
+            LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
+                         pvData, cbData, rc));
+        }
+
+        reset();
+    }
+    else
+        rc = VERR_WRONG_ORDER;
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,
+                            uint32_t uDefAction)
+{
+    int rc = 0;
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
+                             uint32_t uDefAction)
+{
+    int rc = 0;
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
+
+int VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
+{
+    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
+
+    PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
+                0 /* wParm */, (LPARAM)pEvent /* lParm */);
+
+    return VINF_SUCCESS;
+}
+
+int VBoxDnDWnd::hide(void)
+{
 #ifdef DEBUG_andy
-            LogFlowFunc(("Sent %RU16 mouse input(s), x=%ld, y=%ld, flags=0x%x\n",
-                         uiProcessed, Input[0].mi.dx, Input[0].mi.dy, Input[0].mi.dwFlags));
-#endif
+    LogFlowFunc(("\n"));
+#endif
+    ShowWindow(hWnd, SW_HIDE);
+
+    return VINF_SUCCESS;
+}
+
+int VBoxDnDWnd::makeFullscreen(void)
+{
+    int rc = VINF_SUCCESS;
+
+    RECT r;
+    RT_ZERO(r);
+
+    BOOL fRc;
+    HDC hDC = GetDC(NULL /* Entire screen */);
+    if (hDC)
+    {
+        fRc = EnumDisplayMonitors(hDC, NULL, VBoxDnDWnd::MonitorEnumProc,
+                                  (LPARAM)&r);
+        if (!fRc)
+            rc = VERR_NOT_FOUND;
+        ReleaseDC(NULL, hDC);
+    }
+    else
+        rc = VERR_ACCESS_DENIED;
+
+    if (RT_FAILURE(rc))
+    {
+        /* If multi-monitor enumeration failed above, try getting at least the
+         * primary monitor as a fallback. */
+        MONITORINFO monitor_info;
+        monitor_info.cbSize = sizeof(monitor_info);
+        if (GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
+                           &monitor_info))
+        {
+
+            r = monitor_info.rcMonitor;
+            rc = VINF_SUCCESS;
+        }
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
+        SetWindowLong(hWnd, GWL_STYLE,
+                      lStyle & ~(WS_CAPTION | WS_THICKFRAME));
+        LONG lExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
+        SetWindowLong(hWnd, GWL_EXSTYLE,
+                      lExStyle & ~(  WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
+                                   | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
+
+        fRc = SetWindowPos(hWnd, HWND_TOPMOST,
+                           r.left,
+                           r.top,
+                           r.right  - r.left,
+                           r.bottom - r.top,
+#ifdef VBOX_DND_DEBUG_WND
+                           SWP_SHOWWINDOW | SWP_FRAMECHANGED);
+#else
+                           SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
+#endif
+        if (fRc)
+        {
+            LogFlowFunc(("Virtual screen is %ld,%ld,%ld,%ld (%ld x %ld)\n",
+                         r.left, r.top, r.right, r.bottom,
+                         r.right - r.left, r.bottom - r.top));
         }
         else
-            LogFlowFunc(("Unable to send input, error=0x%x\n", GetLastError()));
-
+        {
+            DWORD dwErr = GetLastError();
+            LogRel(("DnD: Failed to set proxy window position, rc=%Rrc\n",
+                    RTErrConvertFromWin32(dwErr)));
+        }
+    }
+    else
+        LogRel(("DnD: Failed to determine virtual screen size, rc=%Rrc\n", rc));
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
+int VBoxDnDWnd::mouseMove(int x, int y, DWORD dwMouseInputFlags)
+{
+    int iScreenX = GetSystemMetrics(SM_CXSCREEN) - 1;
+    int iScreenY = GetSystemMetrics(SM_CYSCREEN) - 1;
+
+    INPUT Input[1] = { 0 };
+    Input[0].type       = INPUT_MOUSE;
+    Input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE
+                        | dwMouseInputFlags;
+    Input[0].mi.dx      = x * (65535 / iScreenX);
+    Input[0].mi.dy      = y * (65535 / iScreenY);
+
+    int rc;
+    if (s_pfnSendInput(1 /* Number of inputs */,
+                       Input, sizeof(INPUT)))
+    {
 #ifdef DEBUG_andy
         CURSORINFO ci;
@@ -1009,109 +1176,23 @@
                              ci.hCursor, ci.ptScreenPos.x, ci.ptScreenPos.y));
 #endif
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        uint32_t uDefAction = DND_IGNORE_ACTION;
-
-        AssertPtr(pDropTarget);
-        RTCString strFormats = pDropTarget->Formats();
-        if (!strFormats.isEmpty())
-        {
-            uDefAction = DND_COPY_ACTION;
-            uAllActions = uDefAction;
-
-            LogFlowFunc(("Acknowledging pDropTarget=0x%p, uDefAction=0x%x, uAllActions=0x%x, strFormats=%s\n",
-                         pDropTarget, uDefAction, uAllActions, strFormats.c_str()));
-            rc = VbglR3DnDGHAcknowledgePending(mClientID,
-                                               uDefAction, uAllActions, strFormats.c_str());
-        }
-        else
-            LogFlowFunc(("No format data available yet\n"));
-    }
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-int VBoxDnDWnd::OnGhDropped(const char *pszFormats, uint32_t cbFormats,
-                            uint32_t uDefAction)
-{
-    AssertPtrReturn(pszFormats, VERR_INVALID_POINTER);
-    AssertReturn(cbFormats, VERR_INVALID_PARAMETER);
-
-    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, uDefAction=0x%x\n",
-                     mMode, mState, pDropTarget, uDefAction));
-#ifdef DEBUG
-    RTCList<RTCString> lstFormats =
-        RTCString(pszFormats, cbFormats - 1).split("\r\n");
-
-    LogFlow(("cbFormats=%RU32: ", cbFormats));
-    for (size_t i = 0; i < lstFormats.size(); i++)
-        LogFlow(("'%s' ", lstFormats.at(i).c_str()));
-    LogFlow(("\n"));
-#endif
-
-    int rc;
-    if (mState == Dragging)
-    {
-        AssertPtr(pDropTarget);
-        rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
-        if (RT_SUCCESS(rc))
-        {
-            /** @todo Respect uDefAction. */
-            /** @todo Do data checking / conversion based on pszFormats. */
-
-            void *pvData = pDropTarget->DataMutableRaw();
-            AssertPtr(pvData);
-            uint32_t cbData = pDropTarget->DataSize();
-            Assert(cbData);
-
-            rc = VbglR3DnDGHSendData(mClientID, pvData, cbData);
-            LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
-                         pvData, cbData, rc));
-        }
-
-        reset();
+        rc = VINF_SUCCESS;
     }
     else
-        rc = VERR_WRONG_ORDER;
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,
-                            uint32_t uDefAction)
-{
-    int rc = 0;
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
-                             uint32_t uDefAction)
-{
-    int rc = 0;
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
-
-int VBoxDnDWnd::ProcessEvent(PVBOXDNDEVENT pEvent)
-{
-    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
-
-    PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
-                0 /* wParm */, (LPARAM)pEvent /* lParm */);
-
-    return VINF_SUCCESS;
-}
-
-int VBoxDnDWnd::dragRelease(void)
+    {
+        DWORD dwErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwErr);
+        LogFlowFunc(("SendInput failed with rc=%Rrc\n", rc));
+    }
+
+    return rc;
+}
+
+int VBoxDnDWnd::mouseRelease(void)
 {
 #ifdef DEBUG_andy
     LogFlowFunc(("\n"));
 #endif
+    int rc;
+
     /* Release mouse button in the guest to start the "drop"
      * action at the current mouse cursor position. */
@@ -1119,91 +1200,13 @@
     Input[0].type       = INPUT_MOUSE;
     Input[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;
-    SendInput(1, Input, sizeof(INPUT));
-
-    return VINF_SUCCESS;
-}
-
-int VBoxDnDWnd::hide(void)
-{
-#ifdef DEBUG_andy
-    LogFlowFunc(("\n"));
-#endif
-    ShowWindow(hWnd, SW_HIDE);
-
-    return VINF_SUCCESS;
-}
-
-int VBoxDnDWnd::makeFullscreen(void)
-{
-    int rc = VINF_SUCCESS;
-
-    RECT r;
-    RT_ZERO(r);
-
-    BOOL fRc;
-    HDC hDC = GetDC(NULL /* Entire screen */);
-    if (hDC)
-    {
-        fRc = EnumDisplayMonitors(hDC, NULL, VBoxDnDWnd::MonitorEnumProc,
-                                  (LPARAM)&r);
-        if (!fRc)
-            rc = VERR_NOT_FOUND;
-        ReleaseDC(NULL, hDC);
+    if (!s_pfnSendInput(1, Input, sizeof(INPUT)))
+    {
+        DWORD dwErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwErr);
+        LogFlowFunc(("SendInput failed with rc=%Rrc\n", rc));
     }
     else
-        rc = VERR_ACCESS_DENIED;
-
-    if (RT_FAILURE(rc))
-    {
-        /* If multi-monitor enumeration failed above, try getting at least the
-         * primary monitor as a fallback. */
-        MONITORINFO monitor_info;
-        monitor_info.cbSize = sizeof(monitor_info);
-        if (GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
-                           &monitor_info))
-        {
-
-            r = monitor_info.rcMonitor;
-            rc = VINF_SUCCESS;
-        }
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
-        SetWindowLong(hWnd, GWL_STYLE,
-                      lStyle & ~(WS_CAPTION | WS_THICKFRAME));
-        LONG lExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
-        SetWindowLong(hWnd, GWL_EXSTYLE,
-                      lExStyle & ~(  WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE
-                                   | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
-
-        fRc = SetWindowPos(hWnd, HWND_TOPMOST,
-                           r.left,
-                           r.top,
-                           r.right  - r.left,
-                           r.bottom - r.top,
-#ifdef VBOX_DND_DEBUG_WND
-                           SWP_SHOWWINDOW | SWP_FRAMECHANGED);
-#else
-                           SWP_SHOWWINDOW | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
-#endif
-        if (fRc)
-        {
-            LogFlowFunc(("Virtual screen is %ld,%ld,%ld,%ld (%ld x %ld)\n",
-                         r.left, r.top, r.right, r.bottom,
-                         r.right - r.left, r.bottom - r.top));
-        }
-        else
-        {
-            DWORD dwErr = GetLastError();
-            LogRel(("DnD: Failed to set proxy window position, rc=%Rrc\n",
-                    RTErrConvertFromWin32(dwErr)));
-        }
-    }
-    else
-        LogRel(("DnD: Failed to determine virtual screen size, rc=%Rrc\n", rc));
-
-    LogFlowFuncLeaveRC(rc);
+        rc = VINF_SUCCESS;
+
     return rc;
 }
@@ -1272,20 +1275,36 @@
 
     int rc;
-
-    /* Create the proxy window. At the moment we
-     * only support one window at a time. */
-    VBoxDnDWnd *pWnd = NULL;
-    try
-    {
-        pWnd = new VBoxDnDWnd();
-        rc = pWnd->Initialize(pCtx);
-
-        /* Add proxy window to our proxy windows list. */
-        if (RT_SUCCESS(rc))
-            pCtx->lstWnd.append(pWnd);
-    }
-    catch (std::bad_alloc)
-    {
-        rc = VERR_NO_MEMORY;
+    bool fSupportedOS = true;
+
+    s_pfnSendInput = (PFNSENDINPUT)
+        RTLdrGetSystemSymbol("User32.dll", "SendInput");
+    fSupportedOS = !RT_BOOL(s_pfnSendInput == NULL);
+
+    if (!fSupportedOS)
+    {
+        LogRel(("DnD: Not supported Windows version, disabling drag'n drop support\n"));
+        rc = VERR_NOT_SUPPORTED;
+    }
+    else
+        rc = VINF_SUCCESS;
+
+    if (RT_SUCCESS(rc))
+    {
+        /* Create the proxy window. At the moment we
+         * only support one window at a time. */
+        VBoxDnDWnd *pWnd = NULL;
+        try
+        {
+            pWnd = new VBoxDnDWnd();
+            rc = pWnd->Initialize(pCtx);
+
+            /* Add proxy window to our proxy windows list. */
+            if (RT_SUCCESS(rc))
+                pCtx->lstWnd.append(pWnd);
+        }
+        catch (std::bad_alloc)
+        {
+            rc = VERR_NO_MEMORY;
+        }
     }
 
@@ -1338,4 +1357,13 @@
 
     int rc = VINF_SUCCESS;
+
+    /** @todo At the moment we only have one DnD proxy window. */
+    Assert(pCtx->lstWnd.size() == 1);
+    VBoxDnDWnd *pWnd = pCtx->lstWnd.first();
+    if (pWnd)
+        delete pWnd;
+
+    if (pCtx->hEvtQueueSem != NIL_RTSEMEVENT)
+        RTSemEventDestroy(pCtx->hEvtQueueSem);
 
     LogFunc(("Destroyed pInstance=%p, rc=%Rrc\n",
Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h	(revision 50398)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h	(revision 50399)
@@ -174,4 +174,5 @@
     uint32_t mcbData;
     RTSEMEVENT hEventDrop;
+    int mDroppedRc;
 };
 
@@ -338,5 +339,5 @@
     /* G->H */
     int OnGhIsDnDPending(uint32_t uScreenID);
-    int OnGhDropped(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
+    int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
     int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
     int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
@@ -351,7 +352,8 @@
 protected:
 
-    int dragRelease(void);
     int makeFullscreen(void);
     void reset(void);
+    int mouseMove(int x, int y, DWORD dwMouseInputFlags);
+    int mouseRelease(void);
 
 public: /** @todo Make protected! */
@@ -386,5 +388,5 @@
 #else
     /** @todo Implement me. */
-#endif
+#endif /* RT_OS_WINDOWS */
 
     /** The window's own HGCM client ID. */
Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp	(revision 50398)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp	(revision 50399)
@@ -254,5 +254,4 @@
     HRESULT hr = S_OK;
 
-    bool fCanDrop = false;
     if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */
     {
@@ -368,5 +367,5 @@
 
                             if (RT_FAILURE(rc))
-                                return rc;
+                                break;
 
                             char *pszFile = NULL; /* UTF-8 version. */
@@ -405,13 +404,12 @@
                             if (RT_SUCCESS(rc))
                             {
-                                LogFlowFunc(("\tFile: %s (%RU32 characters)\n",
+                                LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n",
                                              pszFile, cchFile));
 
                                 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
                                                      pszFile, cchFile);
+                                if (RT_SUCCESS(rc))
+                                    cchFiles += cchFile;
                             }
-
-                            /* Termination. */
-                            pszFiles[cchFiles] = '\0';
 
                             if (pszFile)
@@ -428,5 +426,10 @@
 
                             mpvData = RTMemDup(pszFiles, cbSize);
-                            mcbData = cbSize;
+                            if (mpvData)
+                            {
+                                mcbData = cbSize;
+                            }
+                            else
+                                rc = VERR_NO_MEMORY;
                         }
 
@@ -440,40 +443,37 @@
 
                     default:
+                        /* 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)));
-                        hr = ERROR_NOT_SUPPORTED;
                         hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */
                         break;
                 }
+
+                /*
+                 * Third stage: Release access to the storage medium again.
+                 */
+                switch (mFormatEtc.tymed)
+                {
+                    case TYMED_HGLOBAL:
+                        GlobalUnlock(stgMed.hGlobal);
+                        break;
+
+                    default:
+                        AssertMsgFailed(("Really should not happen -- see init stage!\n"));
+                        break;
+                }
             }
 
-            /*
-             * Third stage: Release access to the storage medium again.
-             */
-            switch (mFormatEtc.tymed)
-            {
-                case TYMED_HGLOBAL:
-                    GlobalUnlock(stgMed.hGlobal);
-                    break;
-
-                default:
-                    AssertMsgFailed(("Really should not happen -- see init stage!\n"));
-                    break;
-            }
+            /* Signal waiters. */
+            mDroppedRc = rc;
+            RTSemEventSignal(hEventDrop);
 
             /* Release storage medium again. */
             ReleaseStgMedium(&stgMed);
-
-            /** @todo Signal in any case to avoid hangs/timeouts? */
-            if (RT_SUCCESS(rc))
-            {
-                RTSemEventSignal(hEventDrop);
-                fCanDrop = true;
-            }
         }
     }
 
-    if (fCanDrop)
+    if (RT_SUCCESS(rc))
     {
         /* Note: pt is not used since we don't need to differentiate within our
@@ -487,7 +487,7 @@
         mpWndParent->hide();
 
-    LogFlowFunc(("Returning with rc=%Rrc, mFormatEtc.cfFormat=%RI16 (%s), fCanDrop=%RTbool, *pdwEffect=%RI32\n",
-                 rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
-                 fCanDrop, *pdwEffect));
+    LogFlowFunc(("Returning with hr=%Rhrc (%Rrc), mFormatEtc.cfFormat=%RI16 (%s), *pdwEffect=%RI32\n",
+                 hr, rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
+                 *pdwEffect));
 
     return hr;
@@ -546,5 +546,9 @@
 {
     LogFlowFunc(("msTimeout=%RU32\n", msTimeout));
+
     int rc = RTSemEventWait(hEventDrop, msTimeout);
+    if (RT_SUCCESS(rc))
+        rc = mDroppedRc;
+
     LogFlowFuncLeaveRC(rc);
     return rc;
