Index: /trunk/include/VBox/GuestHost/DragAndDrop.h
===================================================================
--- /trunk/include/VBox/GuestHost/DragAndDrop.h	(revision 57653)
+++ /trunk/include/VBox/GuestHost/DragAndDrop.h	(revision 57654)
@@ -61,7 +61,8 @@
 int DnDDirDroppedAddFile(PDNDDIRDROPPEDFILES pDir, const char *pszFile);
 int DnDDirDroppedAddDir(PDNDDIRDROPPEDFILES pDir, const char *pszDir);
-int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, PDNDDIRDROPPEDFILES pDir);
-int DnDDirDroppedFilesCreateAndOpenTemp(PDNDDIRDROPPEDFILES pDir);
+int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, uint32_t fFlags, PDNDDIRDROPPEDFILES *ppDir);
+int DnDDirDroppedFilesCreateAndOpenTemp(uint32_t fFlags, PDNDDIRDROPPEDFILES *ppDir);
 int DnDDirDroppedFilesClose(PDNDDIRDROPPEDFILES pDir, bool fRemove);
+void DnDDirDroppedFilesDestroy(PDNDDIRDROPPEDFILES pDir);
 const char *DnDDirDroppedFilesGetDirAbs(PDNDDIRDROPPEDFILES pDir);
 int DnDDirDroppedFilesRollback(PDNDDIRDROPPEDFILES pDir);
Index: /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp	(revision 57653)
+++ /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp	(revision 57654)
@@ -373,9 +373,9 @@
      * Create and query the (unique) drop target directory in the user's temporary directory.
      */
-    DNDDIRDROPPEDFILES dirDroppedFiles;
+    PDNDDIRDROPPEDFILES pDroppedFiles;
     const char *pszDropDir = NULL;
-    int rc = DnDDirDroppedFilesCreateAndOpenTemp(&dirDroppedFiles);
-    if (RT_SUCCESS(rc))
-        pszDropDir = DnDDirDroppedFilesGetDirAbs(&dirDroppedFiles);
+    int rc = DnDDirDroppedFilesCreateAndOpenTemp(0 /* fFlags */, &pDroppedFiles);
+    if (RT_SUCCESS(rc))
+        pszDropDir = DnDDirDroppedFilesGetDirAbs(pDroppedFiles);
 
     /*
@@ -421,5 +421,5 @@
                         rc = RTDirCreate(pszPathAbs, fCreationMode, 0);
                         if (RT_SUCCESS(rc))
-                            rc = DnDDirDroppedAddDir(&dirDroppedFiles, pszPathAbs);
+                            rc = DnDDirDroppedAddDir(pDroppedFiles, pszPathAbs);
 
                         RTStrFree(pszPathAbs);
@@ -488,5 +488,5 @@
                                 if (RT_SUCCESS(rc))
                                 {
-                                    rc = DnDDirDroppedAddFile(&dirDroppedFiles, strPathAbs.c_str());
+                                    rc = DnDDirDroppedAddFile(pDroppedFiles, strPathAbs.c_str());
                                     if (RT_SUCCESS(rc))
                                     {
@@ -571,5 +571,5 @@
     if (RT_FAILURE(rc))
     {
-        int rc2 = DnDDirDroppedFilesRollback(&dirDroppedFiles);
+        int rc2 = DnDDirDroppedFilesRollback(pDroppedFiles);
         AssertRC(rc2); /* Not fatal, don't report back to host. */
     }
@@ -620,7 +620,9 @@
      * by the client's drag'n drop operation lateron.
      */
-    int rc2 = DnDDirDroppedFilesClose(&dirDroppedFiles, false);
+    int rc2 = DnDDirDroppedFilesClose(pDroppedFiles, false);
     if (RT_FAILURE(rc2)) /* Not fatal, don't report back to host. */
         LogFlowFunc(("Closing dropped files directory failed with %Rrc\n", rc2));
+
+    DnDDirDroppedFilesDestroy(pDroppedFiles);
 
     LogFlowFuncLeaveRC(rc);
Index: /trunk/src/VBox/GuestHost/DragAndDrop/DnDDir.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/DragAndDrop/DnDDir.cpp	(revision 57653)
+++ /trunk/src/VBox/GuestHost/DragAndDrop/DnDDir.cpp	(revision 57654)
@@ -48,66 +48,108 @@
 }
 
-int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, PDNDDIRDROPPEDFILES pDir)
+static int dndDirDroppedFilesCreate(uint32_t fFlags, PDNDDIRDROPPEDFILES *ppDir)
+{
+    AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); /* Flags not supported yet. */
+    AssertPtrReturn(ppDir, VERR_INVALID_POINTER);
+
+    PDNDDIRDROPPEDFILES pDir = (PDNDDIRDROPPEDFILES)RTMemAlloc(sizeof(DNDDIRDROPPEDFILES));
+    if (pDir)
+    {
+        pDir->hDir  = NULL;
+        pDir->fOpen = false;
+
+        *ppDir = pDir;
+        return VINF_SUCCESS;
+    }
+
+    return VERR_NO_MEMORY;
+}
+
+int DnDDirDroppedFilesCreateAndOpenEx(const char *pszPath, uint32_t fFlags, PDNDDIRDROPPEDFILES *ppDir)
 {
     AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
-    AssertPtrReturn(pDir, VERR_INVALID_POINTER);
-
-    char pszDropDir[RTPATH_MAX];
-    if (RTStrPrintf(pszDropDir, sizeof(pszDropDir), "%s", pszPath) <= 0)
-        return VERR_NO_MEMORY;
-
-    /** @todo On Windows we also could use the registry to override
-     *        this path, on Posix a dotfile and/or a guest property
-     *        can be used. */
-
-    /* Append our base drop directory. */
-    int rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), "VirtualBox Dropped Files"); /** @todo Make this tag configurable? */
+    AssertPtrReturn(ppDir, VERR_INVALID_POINTER);
+
+    PDNDDIRDROPPEDFILES pDir;
+    int rc = dndDirDroppedFilesCreate(fFlags, &pDir);
     if (RT_FAILURE(rc))
         return rc;
 
-    /* Create it when necessary. */
-    if (!RTDirExists(pszDropDir))
-    {
-        rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU);
+    do
+    {
+        char pszDropDir[RTPATH_MAX];
+        if (RTStrPrintf(pszDropDir, sizeof(pszDropDir), "%s", pszPath) <= 0)
+        {
+            rc = VERR_NO_MEMORY;
+            break;
+        }
+
+        /** @todo On Windows we also could use the registry to override
+         *        this path, on Posix a dotfile and/or a guest property
+         *        can be used. */
+
+        /* Append our base drop directory. */
+        int rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), "VirtualBox Dropped Files"); /** @todo Make this tag configurable? */
         if (RT_FAILURE(rc))
-            return rc;
-    }
-
-    /* The actually drop directory consist of the current time stamp and a
-     * unique number when necessary. */
-    char pszTime[64];
-    RTTIMESPEC time;
-    if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
-        return VERR_BUFFER_OVERFLOW;
-    rc = DnDPathSanitizeFilename(pszTime, sizeof(pszTime));
-    if (RT_FAILURE(rc))
-        return rc;
-
-    rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), pszTime);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    /* Create it (only accessible by the current user) */
-    rc = RTDirCreateUniqueNumbered(pszDropDir, sizeof(pszDropDir), RTFS_UNIX_IRWXU, 3, '-');
-    if (RT_SUCCESS(rc))
-    {
-        PRTDIR phDir;
-        rc = RTDirOpen(&phDir, pszDropDir);
-        if (RT_SUCCESS(rc))
-        {
-            pDir->hDir       = phDir;
-            pDir->strPathAbs = pszDropDir;
-            pDir->fOpen      = true;
-        }
-    }
-
-    return rc;
-}
-
-int DnDDirDroppedFilesCreateAndOpenTemp(PDNDDIRDROPPEDFILES pDir)
-{
-    AssertPtrReturn(pDir, VERR_INVALID_POINTER);
-
-    char szTemp[RTPATH_MAX];
+            break;
+
+        /* Create it when necessary. */
+        if (!RTDirExists(pszDropDir))
+        {
+            rc = RTDirCreateFullPath(pszDropDir, RTFS_UNIX_IRWXU);
+            if (RT_FAILURE(rc))
+                break;
+        }
+
+        /* The actually drop directory consist of the current time stamp and a
+         * unique number when necessary. */
+        char pszTime[64];
+        RTTIMESPEC time;
+        if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
+        {
+            rc = VERR_BUFFER_OVERFLOW;
+            break;
+        }
+
+        rc = DnDPathSanitizeFilename(pszTime, sizeof(pszTime));
+        if (RT_FAILURE(rc))
+            break;
+
+        rc = RTPathAppend(pszDropDir, sizeof(pszDropDir), pszTime);
+        if (RT_FAILURE(rc))
+            break;
+
+        /* Create it (only accessible by the current user) */
+        rc = RTDirCreateUniqueNumbered(pszDropDir, sizeof(pszDropDir), RTFS_UNIX_IRWXU, 3, '-');
+        if (RT_SUCCESS(rc))
+        {
+            PRTDIR phDir;
+            rc = RTDirOpen(&phDir, pszDropDir);
+            if (RT_SUCCESS(rc))
+            {
+                pDir->hDir       = phDir;
+                pDir->strPathAbs = pszDropDir;
+                pDir->fOpen      = true;
+            }
+        }
+
+    } while (0);
+
+    if (RT_SUCCESS(rc))
+    {
+        *ppDir = pDir;
+    }
+    else
+        DnDDirDroppedFilesDestroy(pDir);
+
+    return rc;
+}
+
+int DnDDirDroppedFilesCreateAndOpenTemp(uint32_t fFlags, PDNDDIRDROPPEDFILES *ppDir)
+{
+    AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); /* Flags not supported yet. */
+    AssertPtrReturn(ppDir, VERR_INVALID_POINTER);
+
+    PDNDDIRDROPPEDFILES pDir;
 
     /*
@@ -116,9 +158,24 @@
      * be kept after the guest OS used it.
      */
+    char szTemp[RTPATH_MAX];
     int rc = RTPathTemp(szTemp, sizeof(szTemp));
-    if (RT_FAILURE(rc))
-        return rc;
-
-    return DnDDirDroppedFilesCreateAndOpenEx(szTemp, pDir);
+    if (RT_SUCCESS(rc))
+        rc = DnDDirDroppedFilesCreateAndOpenEx(szTemp, fFlags, &pDir);
+
+    if (RT_SUCCESS(rc))
+    {
+        *ppDir = pDir;
+    }
+    else
+        DnDDirDroppedFilesDestroy(pDir);
+
+    return rc;
+}
+
+void DnDDirDroppedFilesDestroy(PDNDDIRDROPPEDFILES pDir)
+{
+    AssertPtrReturnVoid(pDir);
+
+    RTMemFree(pDir);
 }
 
@@ -132,5 +189,8 @@
         rc = RTDirClose(pDir->hDir);
         if (RT_SUCCESS(rc))
+        {
             pDir->fOpen = false;
+            pDir->hDir  = NULL;
+        }
     }
     if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/Main/include/GuestDnDPrivate.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestDnDPrivate.h	(revision 57653)
+++ /trunk/src/VBox/Main/include/GuestDnDPrivate.h	(revision 57654)
@@ -138,9 +138,7 @@
 {
     GuestDnDURIData(void)
-        : pvScratchBuf(NULL)
-        , cbScratchBuf(0)
-    {
-        RT_ZERO(mDropDir);
-    }
+        : pDropDir(NULL)
+        , pvScratchBuf(NULL)
+        , cbScratchBuf(0) { }
 
     virtual ~GuestDnDURIData(void)
@@ -170,6 +168,14 @@
         objCtx.Reset();
 
-        DnDDirDroppedFilesRollback(&mDropDir);
-        DnDDirDroppedFilesClose(&mDropDir, true /* fRemove */);
+        if (pDropDir)
+        {
+            int rc2 = DnDDirDroppedFilesRollback(pDropDir);
+            AssertRC(rc2);
+            rc2 = DnDDirDroppedFilesClose(pDropDir, true /* fRemove */);
+            AssertRC(rc2);
+
+            DnDDirDroppedFilesDestroy(pDropDir);
+            pDropDir = NULL;
+        }
 
         if (pvScratchBuf)
@@ -182,5 +188,6 @@
     }
 
-    DNDDIRDROPPEDFILES              mDropDir;
+    /** Pointer to dropped files object. */
+    PDNDDIRDROPPEDFILES             pDropDir;
     /** (Non-recursive) List of URI objects to handle. */
     DnDURIList                      lstURI;
Index: /trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp	(revision 57653)
+++ /trunk/src/VBox/Main/src-client/GuestDnDSourceImpl.cpp	(revision 57654)
@@ -419,5 +419,5 @@
         if (fHasURIList)
         {
-            Utf8Str strURIs = pCtx->mURI.lstURI.RootToString(RTCString(DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir)));
+            Utf8Str strURIs = pCtx->mURI.lstURI.RootToString(RTCString(DnDDirDroppedFilesGetDirAbs(pCtx->mURI.pDropDir)));
             cbData = strURIs.length();
 
@@ -604,5 +604,5 @@
 
     int rc;
-    char *pszDir = RTPathJoinA(DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir), pszPath);
+    char *pszDir = RTPathJoinA(DnDDirDroppedFilesGetDirAbs(pCtx->mURI.pDropDir), pszPath);
     if (pszDir)
     {
@@ -663,5 +663,5 @@
 
         char pszPathAbs[RTPATH_MAX];
-        rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir), pszPath);
+        rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), DnDDirDroppedFilesGetDirAbs(pCtx->mURI.pDropDir), pszPath);
         if (RT_FAILURE(rc))
         {
@@ -1036,8 +1036,8 @@
     do
     {
-        rc = DnDDirDroppedFilesCreateAndOpenTemp(&pCtx->mURI.mDropDir);
+        rc = DnDDirDroppedFilesCreateAndOpenTemp(0 /* fFlags */, &pCtx->mURI.pDropDir);
         if (RT_FAILURE(rc))
             break;
-        LogFlowFunc(("rc=%Rrc, strDropDir=%s\n", rc, DnDDirDroppedFilesGetDirAbs(&pCtx->mURI.mDropDir)));
+        LogFlowFunc(("rc=%Rrc, strDropDir=%s\n", rc, DnDDirDroppedFilesGetDirAbs(pCtx->mURI.pDropDir)));
         if (RT_FAILURE(rc))
             break;
@@ -1100,13 +1100,19 @@
     }
 
-    if (RT_FAILURE(rc))
-    {
-        rc2 = DnDDirDroppedFilesRollback(&pCtx->mURI.mDropDir); /** @todo Inform user on rollback failure? */
-        LogFlowFunc(("Rolling back ended with rc=%Rrc\n", rc2));
-    }
-
-    rc2 = DnDDirDroppedFilesClose(&pCtx->mURI.mDropDir, RT_FAILURE(rc) ? true : false /* fRemove */);
-    if (RT_SUCCESS(rc))
-        rc = rc2;
+    if (pCtx->mURI.pDropDir)
+    {
+        if (RT_FAILURE(rc))
+        {
+            rc2 = DnDDirDroppedFilesRollback(pCtx->mURI.pDropDir); /** @todo Inform user on rollback failure? */
+            LogFlowFunc(("Rolling back ended with rc=%Rrc\n", rc2));
+        }
+
+        rc2 = DnDDirDroppedFilesClose(pCtx->mURI.pDropDir, RT_FAILURE(rc) ? true : false /* fRemove */);
+        if (RT_SUCCESS(rc))
+            rc = rc2;
+
+        DnDDirDroppedFilesDestroy(pCtx->mURI.pDropDir);
+        pCtx->mURI.pDropDir = NULL;
+    }
 
     LogFlowFuncLeaveRC(rc);
