Index: /trunk/src/VBox/Main/include/GuestSessionImplTasks.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 71846)
+++ /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 71847)
@@ -116,4 +116,6 @@
      *  asynchronously. Optional. */
     ComObjPtr<Progress>     mProgress;
+    /** The guest's path style (depending on the guest OS type set). */
+    uint32_t                mfPathStyle;
 };
 
@@ -144,5 +146,8 @@
 
     GuestSessionCopyTask(GuestSession *pSession)
-        : GuestSessionTask(pSession) { RT_ZERO(u); }
+        : GuestSessionTask(pSession)
+    {
+        RT_ZERO(u);
+    }
 
     virtual ~GuestSessionCopyTask() { }
@@ -151,9 +156,9 @@
 
     /** Source to copy from. */
-    Utf8Str mSource;
+    Utf8Str  mSource;
     /** Destination to copy to. */
-    Utf8Str mDest;
+    Utf8Str  mDest;
     /** Filter (wildcard-style) when copying directories. */
-    Utf8Str mFilter;
+    Utf8Str  mFilter;
 
     union
Index: /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 71846)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 71847)
@@ -71,4 +71,7 @@
 {
     mSession = pSession;
+
+    mfPathStyle = mSession->i_getPathStyle() == PathStyle_DOS
+                ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX;
 }
 
@@ -516,22 +519,15 @@
         else if (RTFS_IS_DIRECTORY(dstObjInfo.Attr.fMode))
         {
-            if (   strDest.endsWith("\\")
-                || strDest.endsWith("/"))
-            {
-                /* Build the final file name with destination path (on the host). */
-                char szDstPath[RTPATH_MAX];
-                RTStrPrintf2(szDstPath, sizeof(szDstPath), "%s", strDest.c_str());
-
-                RTPathAppend(szDstPath, sizeof(szDstPath), RTPathFilename(strSource.c_str()));
-
-                pszDstFile = RTStrDup(szDstPath);
-            }
-            else
-            {
-                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
-                                    Utf8StrFmt(GuestSession::tr("Destination directory \"%s\" already exists"),
-                                               strDest.c_str(), rc));
-                rc = VERR_ALREADY_EXISTS;
-            }
+            /* Build the final file name with destination path (on the host). */
+            char szDstPath[RTPATH_MAX];
+            RTStrPrintf2(szDstPath, sizeof(szDstPath), "%s", strDest.c_str());
+
+            if (   !strDest.endsWith("\\")
+                && !strDest.endsWith("/"))
+                RTPathAppend(szDstPath, sizeof(szDstPath), "/"); /* IPRT can handle / on all hosts. */
+
+            RTPathAppend(szDstPath, sizeof(szDstPath), RTPathFilenameEx(strSource.c_str(), mfPathStyle));
+
+            pszDstFile = RTStrDup(szDstPath);
         }
         else if (RTFS_IS_SYMLINK(dstObjInfo.Attr.fMode))
@@ -992,5 +988,6 @@
     Utf8Str strSrcCur = strSrcDir + strSrcSubDir;
 
-    LogFlowFunc(("Entering '%s'\n", strSrcCur.c_str()));
+    LogFlowFunc(("strSrcDir=%s, strDstDir=%s, strFilter=%s, strSubDir=%s\n",
+                 strSrcDir.c_str(), strDstDir.c_str(), strFilter.c_str(), strSubDir.c_str()));
 
     int rc;
@@ -1124,28 +1121,44 @@
     int rc = VINF_SUCCESS;
 
-    /* Figure out if we need to copy the entire source directory or just its contents. */
     Utf8Str strSrcDir = mSource;
     Utf8Str strDstDir = mDest;
+
+    bool fDstExists = RTDirExists(strDstDir.c_str());
+    if (fDstExists)
+    {
+        if (!(u.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
+        {
+            setProgressErrorMsg(VBOX_E_IPRT_ERROR,
+                                Utf8StrFmt(GuestSession::tr("Destination directory \"%s\" exists when it must not"), strDstDir.c_str()));
+            rc = VERR_ALREADY_EXISTS;
+        }
+    }
+
+    if (RT_FAILURE(rc))
+        return rc;
+
     if (   !strSrcDir.endsWith("/")
         && !strSrcDir.endsWith("\\"))
     {
-        if (   strDstDir.endsWith("/")
-            || strDstDir.endsWith("\\"))
-        {
-            strDstDir += Utf8StrFmt("%s", RTPathFilename(strSrcDir.c_str()));
-        }
-    }
-
-    /* Create the root target directory on the host.
+        if (   !strDstDir.endsWith("/")
+            && !strDstDir.endsWith("\\"))
+                strDstDir += "/"; /* IPRT can handle / on all hosts. */
+
+        strDstDir += Utf8StrFmt("%s", RTPathFilenameEx(strSrcDir.c_str(), mfPathStyle));
+    }
+
+    /* Create the final target directory on the host.
      * The target directory might already exist on the host (based on u.Dir.fCopyFlags). */
-    const bool fExists = RTDirExists(strDstDir.c_str());
-    if (   fExists
-        && !(u.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
-    {
-        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
-                            Utf8StrFmt(GuestSession::tr("Destination directory \"%s\" exists when it must not"), strDstDir.c_str()));
-        rc = VERR_ALREADY_EXISTS;
-    }
-    else if (!fExists)
+    fDstExists = RTDirExists(strDstDir.c_str());
+    if (fDstExists)
+    {
+        if (!(u.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
+        {
+            setProgressErrorMsg(VBOX_E_IPRT_ERROR,
+                                Utf8StrFmt(GuestSession::tr("Destination directory \"%s\" exists when it must not"), strDstDir.c_str()));
+            rc = VERR_ALREADY_EXISTS;
+        }
+    }
+    else
     {
         rc = RTDirCreate(strDstDir.c_str(), fDirMode, 0);
@@ -1168,4 +1181,7 @@
         return rc;
     }
+
+    LogFlowFunc(("Source: %s -> %s\n", mSource.c_str(), strSrcDir.c_str()));
+    LogFlowFunc(("Destination: %s -> %s\n", mDest.c_str(), strDstDir.c_str()));
 
     /* At this point the directory on the host was created and (hopefully) is ready
Index: /trunk/src/VBox/ValidationKit/tests/additions/tdAddGuestCtrl.py
===================================================================
--- /trunk/src/VBox/ValidationKit/tests/additions/tdAddGuestCtrl.py	(revision 71846)
+++ /trunk/src/VBox/ValidationKit/tests/additions/tdAddGuestCtrl.py	(revision 71847)
@@ -3370,8 +3370,12 @@
                                      sDst = sScratchHst + "/"),
                       tdTestResult(fRc = True) ],
-                    # Destination is a directory (should fail).
+                    # Destination is a directory (without a trailing slash, should also work).
                     # See "cp" syntax.
                     [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
                                      sDst = sScratchHst),
+                      tdTestResult(fRc = True) ],
+                    # Destination is a non-existing directory.
+                    [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\system32\\ole32.dll',
+                                     sDst = sScratchHst + "/non-existing-directory/"),
                       tdTestResult(fRc = False) ]
                 ]);
@@ -3384,18 +3388,25 @@
                     # Copying entire directories (destination is "<sScratch>", which exists, which should fail).
                     [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web',
-                                    sDst = sScratchHst),
+                                     sDst = sScratchHst),
                       tdTestResult(fRc = False) ],
-                    # Copying entire directories (destination is "<sScratch>\Web").
-                    # Should fail, as the corresponding flag is missing.
+                    # Ditto, with trailing slash.
                     [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web',
-                                    sDst = sScratchHst + "/"),
+                                     sDst = sScratchHst + "/"),
                       tdTestResult(fRc = False) ],
-                    # Next try with correct flag being set.
+                    # Next try with the DirectoryCopyFlag_CopyIntoExisting flag being set.
                     [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web',
-                                    sDst = sScratchHst + "/", aFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
+                                     sDst = sScratchHst, aFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
                       tdTestResult(fRc = True) ],
-                    # Copying contents of directories (destination is "<sScratch>/").
+                    # Ditto, with trailing slash.
+                    [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web',
+                                     sDst = sScratchHst + "/", aFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
+                      tdTestResult(fRc = True) ],
+                    # Copying contents of directories into a non-existing directory chain on the host which fail.
                     [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web\\',
-                                    sDst = sScratchHst + "/", aFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
+                                     sDst = sScratchHst + "/not/existing/", aFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
+                      tdTestResult(fRc = False) ],
+                    # Copying contents of directories into a non-existing directory on the host, which should succeed.
+                    [ tdTestCopyFrom(sUser = sUser, sPassword = sPassword, sSrc = 'C:\\Windows\\Web\\',
+                                     sDst = sScratchHst + "/no-existing/", aFlags = [ vboxcon.DirectoryCopyFlag_CopyIntoExisting ]),
                       tdTestResult(fRc = True) ]
                 ]);
