Index: /trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerGuestTable.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerGuestTable.cpp	(revision 92543)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerGuestTable.cpp	(revision 92544)
@@ -37,4 +37,6 @@
 #include "CGuestDirectory.h"
 #include "CProgress.h"
+
+#include <iprt/path.h>
 
 
@@ -323,11 +325,11 @@
 
 void UIFileManagerGuestTable::copyHostToGuest(const QStringList &hostSourcePathList,
-                                        const QString &strDestination /* = QString() */)
+                                              const QString &strDestination /* = QString() */)
 {
     if (!checkGuestSession())
         return;
     QVector<QString> sourcePaths = hostSourcePathList.toVector();
-    QVector<QString>  aFilters;
-    QVector<QString>  aFlags;
+    QVector<QString> aFilters;
+    QVector<QString> aFlags;
     QString strDestinationPath = strDestination;
     if (strDestinationPath.isEmpty())
@@ -345,4 +347,22 @@
     }
 
+    foreach (const QString &strSource, sourcePaths)
+    {
+        RTFSOBJINFO ObjInfo;
+        int vrc = RTPathQueryInfo(strSource.toStdString().c_str(), &ObjInfo, RTFSOBJATTRADD_NOTHING);
+        if (RT_SUCCESS(vrc))
+        {
+            /* If the source is an directory, make sure to add the appropriate flag to make copying work
+             * into existing directories on the guest. This otherwise would fail (default). */
+            if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
+                aFlags.append("CopyIntoExisting");
+            else /* Make sure to keep the vector in sync with the number of source items by adding an empty entry. */
+                aFlags.append("");
+        }
+        else
+            emit sigLogOutput(QString("Querying information for host item \"%s\" failed with %Rrc").arg(strSource.toStdString().c_str(), vrc),
+                              FileManagerLogType_Error);
+    }
+
     CProgress progress = m_comGuestSession.CopyToGuest(sourcePaths, aFilters, aFlags, strDestinationPath);
     if (!checkGuestSession())
@@ -356,6 +376,6 @@
         return;
     QVector<QString> sourcePaths = selectedItemPathList().toVector();
-    QVector<QString>  aFilters;
-    QVector<QString>  aFlags;
+    QVector<QString> aFilters;
+    QVector<QString> aFlags;
 
     if (hostDestinationPath.isEmpty())
@@ -368,4 +388,24 @@
         emit sigLogOutput("No source for copy operation", FileManagerLogType_Error);
         return;
+    }
+
+    foreach (const QString &strSource, sourcePaths)
+    {
+        /** @todo Cache this info and use the item directly, which has this info already? */
+
+        /* If the source is an directory, make sure to add the appropriate flag to make copying work
+         * into existing directories on the guest. This otherwise would fail (default). */
+        CGuestFsObjInfo fileInfo = m_comGuestSession.FsObjQueryInfo(strSource, true);
+        if (!m_comGuestSession.isOk())
+        {
+            emit sigLogOutput(UIErrorString::formatErrorInfo(m_comGuestSession), FileManagerLogType_Error);
+            return;
+        }
+
+        KFsObjType eType = fileType(fileInfo);
+        if (eType == KFsObjType_Directory)
+            aFlags.append("CopyIntoExisting");
+        else /* Make sure to keep the vector in sync with the number of source items by adding an empty entry. */
+            aFlags.append("");
     }
 
Index: /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 92543)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 92544)
@@ -1001,26 +1001,10 @@
     mSourceSpec = SourceSpec;
 
-    /* If the source is a directory, make sure the path is properly terminated already. */
-    if (mSourceSpec.enmType == FsObjType_Directory)
-    {
-        LogFlowFunc(("Directory: mSrcRootAbs=%s, mDstRootAbs=%s, fCopyFlags=%#x, fFollowSymlinks=%RTbool, fRecursive=%RTbool\n",
-                     mSrcRootAbs.c_str(), mDstRootAbs.c_str(), mSourceSpec.Type.Dir.fCopyFlags,
-                     mSourceSpec.Type.Dir.fFollowSymlinks, mSourceSpec.Type.Dir.fRecursive));
-
-        if (   !mSrcRootAbs.endsWith("/")
-            && !mSrcRootAbs.endsWith("\\"))
-            mSrcRootAbs += "/";
-
-        if (   !mDstRootAbs.endsWith("/")
-            && !mDstRootAbs.endsWith("\\"))
-            mDstRootAbs += "/";
-    }
-    else if (mSourceSpec.enmType == FsObjType_File)
-    {
-        LogFlowFunc(("File: mSrcRootAbs=%s, mDstRootAbs=%s, fCopyFlags=%#x\n",
-                     mSrcRootAbs.c_str(), mDstRootAbs.c_str(), mSourceSpec.Type.File.fCopyFlags));
-    }
-    else
-        AssertFailedReturn(VERR_NOT_IMPLEMENTED);
+    /* Note: Leave the source and dest roots unmodified -- how paths will be treated
+     *       will be done directly when working on those. See @bugref{10139}. */
+
+    LogFlowFunc(("mSrcRootAbs=%s, mDstRootAbs=%s, fCopyFlags=%#x, fFollowSymlinks=%RTbool, fRecursive=%RTbool\n",
+                 mSrcRootAbs.c_str(), mDstRootAbs.c_str(), mSourceSpec.Type.Dir.fCopyFlags,
+                 mSourceSpec.Type.Dir.fFollowSymlinks, mSourceSpec.Type.Dir.fRecursive));
 
     return VINF_SUCCESS;
@@ -1579,4 +1563,6 @@
         }
 
+        char szPath[RTPATH_MAX];
+
         FsEntries::const_iterator itEntry = pList->mVecEntries.begin();
         while (itEntry != pList->mVecEntries.end())
@@ -1587,14 +1573,34 @@
             Utf8Str strSrcAbs = pList->mSrcRootAbs;
             Utf8Str strDstAbs = pList->mDstRootAbs;
+
+            LogFlowFunc(("Entry: srcRootAbs=%s, dstRootAbs=%s\n", pList->mSrcRootAbs.c_str(), pList->mDstRootAbs.c_str()));
+
             if (pList->mSourceSpec.enmType == FsObjType_Directory)
             {
-                strSrcAbs += pEntry->strPath;
-                strDstAbs += pEntry->strPath;
-
-                if (pList->mSourceSpec.enmPathStyle == PathStyle_DOS)
-                    strDstAbs.findReplace('\\', '/');
-            }
+                /* Build the source path on the guest. */
+                rc = RTStrCopy(szPath, sizeof(szPath), pList->mSrcRootAbs.c_str());
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
+                    if (RT_SUCCESS(rc))
+                        strSrcAbs = szPath;
+                }
+
+                /* Build the destination path on the host. */
+                rc = RTStrCopy(szPath, sizeof(szPath), pList->mDstRootAbs.c_str());
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
+                    if (RT_SUCCESS(rc))
+                        strDstAbs = szPath;
+                }
+            }
+
+            if (pList->mSourceSpec.enmPathStyle == PathStyle_DOS)
+                strDstAbs.findReplace('\\', '/');
 
             mProgress->SetNextOperation(Bstr(strSrcAbs).raw(), 1);
+
+            LogRel2(("Guest Control: Copying '%s' from guest to '%s' on host ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
 
             switch (pEntry->fMode & RTFS_TYPE_MASK)
@@ -1827,5 +1833,5 @@
                     default:
                         setProgressErrorMsg(VBOX_E_IPRT_ERROR,
-                                            Utf8StrFmt(tr("Querying information on for '%s' failed: %Rrc"),
+                                            Utf8StrFmt(tr("Querying information on guest for '%s' failed: %Rrc"),
                                             strDstRootAbs.c_str(), rcGuest));
                         break;
@@ -1841,4 +1847,6 @@
         }
 
+        char szPath[RTPATH_MAX];
+
         LogFlowFunc(("List inital: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s\n",
                      rc, strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
@@ -1857,20 +1865,39 @@
 
             /* If the directory on the guest already exists, append the name of the root source directory to it. */
-            if (dstObjData.mType == FsObjType_Directory)
-            {
-                if (fCopyIntoExisting)
-                {
-                    if (   !strDstRootAbs.endsWith("/")
-                        && !strDstRootAbs.endsWith("\\"))
-                        strDstRootAbs += "/";
-                    strDstRootAbs += Utf8Str(RTPathFilenameEx(strSrcRootAbs.c_str(), mfPathStyle));
-                }
-                else
-                {
+            switch (dstObjData.mType)
+            {
+                case FsObjType_Directory:
+                {
+                    if (fCopyIntoExisting)
+                    {
+                        /* Build the destination path on the guest. */
+                        rc = RTStrCopy(szPath, sizeof(szPath), strDstRootAbs.c_str());
+                        if (RT_SUCCESS(rc))
+                        {
+                            rc = RTPathAppend(szPath, sizeof(szPath), RTPathFilenameEx(strSrcRootAbs.c_str(), mfPathStyle));
+                            if (RT_SUCCESS(rc))
+                                strDstRootAbs = szPath;
+                        }
+                    }
+                    else
+                    {
+                        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
+                                            Utf8StrFmt(tr("Guest directory \"%s\" already exists"),
+                                                       strDstRootAbs.c_str()));
+                        rc = VERR_ALREADY_EXISTS;
+                    }
+                    break;
+                }
+
+                case FsObjType_File:
+                    /* Nothing to do. */
+                    break;
+
+                default:
                     setProgressErrorMsg(VBOX_E_IPRT_ERROR,
-                                        Utf8StrFmt(tr("Guest directory \"%s\" already exists"),
+                                        Utf8StrFmt(tr("Unknown object type on guest for \"%s\""),
                                                    strDstRootAbs.c_str()));
-                    rc = VERR_ALREADY_EXISTS;
-                }
+                    rc = VERR_NOT_SUPPORTED;
+                    break;
             }
 
@@ -1898,11 +1925,11 @@
             AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
 
+        LogFlowFunc(("List final: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s, fFileCopyFlags=%#x\n",
+                     rc, strSrcRootAbs.c_str(), strDstRootAbs.c_str(), fFileCopyFlags));
+
+        LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
+
         if (RT_FAILURE(rc))
             break;
-
-        LogFlowFunc(("List final: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s, fFileCopyFlags=%#x\n",
-                     rc, strSrcRootAbs.c_str(), strDstRootAbs.c_str(), fFileCopyFlags));
-
-        LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
 
         FsEntries::const_iterator itEntry = pList->mVecEntries.begin();
@@ -1918,8 +1945,17 @@
             if (pList->mSourceSpec.enmType == FsObjType_Directory)
             {
-                if (   !strSrcAbs.endsWith("/")
-                    && !strSrcAbs.endsWith("\\"))
-                    strSrcAbs += "/";
-                strSrcAbs += pEntry->strPath;
+                /* Build the final (absolute) source path (on the host). */
+                rc = RTStrCopy(szPath, sizeof(szPath), strSrcAbs.c_str());
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
+                    if (RT_SUCCESS(rc))
+                        strSrcAbs = szPath;
+                }
+
+                if (RT_FAILURE(rc))
+                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
+                                        Utf8StrFmt(tr("Building source host path for entry \"%s\" failed (%Rrc)"),
+                                                   pEntry->strPath.c_str(), rc));
             }
 
@@ -1927,15 +1963,22 @@
             if (dstObjData.mType == FsObjType_Directory)
             {
-                if (   !strDstAbs.endsWith("/")
-                    && !strDstAbs.endsWith("\\"))
-                    strDstAbs += "/";
-                strDstAbs += pEntry->strPath;
+                /* Build the final (absolute) destination path (on the guest). */
+                rc = RTStrCopy(szPath, sizeof(szPath), strDstAbs.c_str());
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
+                    if (RT_SUCCESS(rc))
+                        strDstAbs = szPath;
+                }
+
+                if (RT_FAILURE(rc))
+                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
+                                        Utf8StrFmt(tr("Building destination guest path for entry \"%s\" failed (%Rrc)"),
+                                                   pEntry->strPath.c_str(), rc));
             }
 
             mProgress->SetNextOperation(Bstr(strSrcAbs).raw(), 1);
 
-            LogFlowFunc(("strEntry='%s'\n", pEntry->strPath.c_str()));
-            LogFlowFunc(("\tsrcAbs='%s'\n", strSrcAbs.c_str()));
-            LogFlowFunc(("\tdstAbs='%s'\n", strDstAbs.c_str()));
+            LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
 
             switch (pEntry->fMode & RTFS_TYPE_MASK)
