Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 72066)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 72067)
@@ -11145,32 +11145,4 @@
 
   <enum
-    name="GuestCopyFlag"
-    uuid="84d6430f-dfe6-4415-a26d-3cdde1c3205a"
-    >
-    <desc>
-      Flags for use when copying elements from or to the guest, see
-      <link to="IGuestSession::copyFromGuest"/> and
-      <link to="IGuestSession::copyToGuest"/>.
-    </desc>
-
-    <const name="NoReplace"             value="0">
-      <desc>Do not replace any destination object.</desc>
-    </const>
-    <const name="Replace"               value="1">
-      <desc>This will attempt to replace any destination object other except
-        directories. (The default is to fail if the destination exists.)</desc>
-    </const>
-    <const name="CopyIntoExisting"      value="2">
-      <desc>Allow copying into an existing destination directory.</desc>
-    </const>
-    <const name="Recursive"             value="4">
-      <desc>Copies directories recursively.</desc>
-    </const>
-    <const name="FollowSymlinks"        value="8">
-      <desc>Follows (and handles) symbolic links.</desc>
-    </const>
-  </enum>
-
-  <enum
     name="ProcessCreateFlag"
     uuid="C544CD2B-F02D-4886-9901-71C523DB8DC5"
@@ -11898,5 +11870,5 @@
   <interface
     name="IGuestSession" extends="$unknown"
-    uuid="a71fcf9a-a45e-440a-886a-5b4c664195ef"
+    uuid="9880f6e3-c4c1-4031-8ec2-28ee088370e4"
     wsmap="managed"
     reservedMethods="8" reservedAttributes="8"
@@ -12074,14 +12046,41 @@
       </param>
       <param name="filters" type="wstring" dir="in" safearray="yes">
-        <desc>Array of filters corresponding to the sources. This uses the
+        <desc>Array of source filters. This uses the
           DOS/NT style wildcard characters '?' and '*'.</desc>
       </param>
       <param name="types" type="FsObjType" dir="in" safearray="yes">
-        <desc>Array of <link to="FsObjType"/> types which define the type of
-          source entries.</desc>
-      </param>
-      <param name="flags" type="GuestCopyFlag" dir="in" safearray="yes">
-        <desc>Array of <link to="GuestCopyFlag"/> flags corresponding to the
-          sources.</desc>
+        <desc>Array of source <link to="FsObjType"/> types.</desc>
+      </param>
+      <param name="flags" type="wstring" dir="in" safearray="yes">
+        <desc>Array of comma-separated list of source flags.
+
+          The following flags are available for directory sources:
+
+          <table>
+            <tr>
+              <td>CopyIntoExisting</td>
+              <td>Allow copying into an existing destination directory.</td>
+            </tr>
+          </table>
+
+          The following flags are available for file sources:
+
+          <table>
+            <tr>
+              <td>NoReplace</td>
+              <td>Do not replace any destination object.</td>
+            </tr>
+            <tr>
+              <td>FollowLinks</td>
+              <td>Follows (and handles) (symbolic) links.</td>
+            </tr>
+            <tr>
+              <td>Update</td>
+              <td>Only copy when the source file is newer than the destination
+               file or when the destination file is missing.</td>
+            </tr>
+          </table>
+
+        </desc>
       </param>
       <param name="destination" type="wstring" dir="in">
@@ -12105,14 +12104,41 @@
       </param>
       <param name="filters" type="wstring" dir="in" safearray="yes">
-        <desc>Array of filters corresponding to the sources. This uses the
+        <desc>Array of source filters. This uses the
           DOS/NT style wildcard characters '?' and '*'.</desc>
       </param>
       <param name="types" type="FsObjType" dir="in" safearray="yes">
-        <desc>Array of <link to="FsObjType"/> types which define the type of
-          source entries.</desc>
-      </param>
-      <param name="flags" type="GuestCopyFlag" dir="in" safearray="yes">
-        <desc>Array of <link to="GuestCopyFlag"/> flags corresponding to the
-          sources.</desc>
+        <desc>Array of source <link to="FsObjType"/> types.</desc>
+      </param>
+      <param name="flags" type="wstring" dir="in" safearray="yes">
+        <desc>Array of comma-separated list of source flags.
+
+          The following flags are available for directory sources:
+
+          <table>
+            <tr>
+              <td>CopyIntoExisting</td>
+              <td>Allow copying into an existing destination directory.</td>
+            </tr>
+          </table>
+
+          The following flags are available for file sources:
+
+          <table>
+            <tr>
+              <td>NoReplace</td>
+              <td>Do not replace any destination object.</td>
+            </tr>
+            <tr>
+              <td>FollowLinks</td>
+              <td>Follows (and handles) (symbolic) links.</td>
+            </tr>
+            <tr>
+              <td>Update</td>
+              <td>Only copy when the source file is newer than the destination
+               file or when the destination file is missing.</td>
+            </tr>
+          </table>
+
+        </desc>
       </param>
       <param name="destination" type="wstring" dir="in">
Index: /trunk/src/VBox/Main/include/GuestSessionImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImpl.h	(revision 72066)
+++ /trunk/src/VBox/Main/include/GuestSessionImpl.h	(revision 72067)
@@ -84,5 +84,5 @@
                           const std::vector<com::Utf8Str> &aFilters,
                           const std::vector<FsObjType_T> &aTypes,
-                          const std::vector<GuestCopyFlag_T> &aFlags,
+                          const std::vector<com::Utf8Str> &aFlags,
                           const com::Utf8Str &aDestination,
                           ComPtr<IProgress> &aProgress);
@@ -90,5 +90,5 @@
                         const std::vector<com::Utf8Str> &aFilters,
                         const std::vector<FsObjType_T> &aTypes,
-                        const std::vector<GuestCopyFlag_T> &aFlags,
+                        const std::vector<com::Utf8Str> &aFlags,
                         const com::Utf8Str &aDestination,
                         ComPtr<IProgress> &aProgress);
@@ -267,4 +267,5 @@
                                           ComPtr<IProgress> &pProgress);
     int                     i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
+    static int              i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags);
     inline bool             i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
     int                     i_directoryUnregister(GuestDirectory *pDirectory);
@@ -276,4 +277,5 @@
     int                     i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
     int                     i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
+    static int              i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags);
     inline bool             i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
     int                     i_fileUnregister(GuestFile *pFile);
Index: /trunk/src/VBox/Main/include/GuestSessionImplTasks.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 72066)
+++ /trunk/src/VBox/Main/include/GuestSessionImplTasks.h	(revision 72067)
@@ -42,4 +42,10 @@
 struct GuestSessionFsSourceSpec
 {
+    GuestSessionFsSourceSpec()
+        : enmType(FsObjType_Unknown)
+        , enmPathStyle(PathStyle_Unknown)
+        , fDryRun(false)
+        , fFollowSymlinks(false) { }
+
     Utf8Str     strSource;
     Utf8Str     strFilter;
Index: /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 72066)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 72067)
@@ -748,33 +748,4 @@
         return setError(E_INVALIDARG, tr("No destination specified"));
 
-    GuestSessionFsSourceSet::const_iterator itSource = SourceSet.begin();
-    while (itSource != SourceSet.end())
-    {
-        if (itSource->enmType == FsObjType_Directory)
-        {
-            if (itSource->Type.Dir.fCopyFlags)
-            {
-                if (!(itSource->Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
-                    return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
-            }
-        }
-        else if (itSource->enmType == FsObjType_File)
-        {
-            if (itSource->Type.File.fCopyFlags)
-            {
-                if (   !(itSource->Type.File.fCopyFlags & FileCopyFlag_NoReplace)
-                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_FollowLinks)
-                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_Update))
-                {
-                    return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
-                }
-            }
-        }
-        else
-            return setError(E_NOTIMPL, tr("Source type %RU32 not implemented"), itSource->enmType);
-
-        itSource++;
-    }
-
     try
     {
@@ -849,33 +820,4 @@
         return setError(E_INVALIDARG, tr("No destination specified"));
 
-    GuestSessionFsSourceSet::const_iterator itSource = SourceSet.begin();
-    while (itSource != SourceSet.end())
-    {
-        if (itSource->enmType == FsObjType_Directory)
-        {
-            if (itSource->Type.Dir.fCopyFlags)
-            {
-                if (!(itSource->Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting))
-                    return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
-            }
-        }
-        else if (itSource->enmType == FsObjType_File)
-        {
-            if (itSource->Type.File.fCopyFlags)
-            {
-                if (   !(itSource->Type.File.fCopyFlags & FileCopyFlag_NoReplace)
-                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_FollowLinks)
-                    && !(itSource->Type.File.fCopyFlags & FileCopyFlag_Update))
-                {
-                    return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
-                }
-            }
-        }
-        else
-            return setError(E_NOTIMPL, tr("Source type %RU32 not implemented"), itSource->enmType);
-
-        itSource++;
-    }
-
     try
     {
@@ -924,4 +866,61 @@
     LogFlowFunc(("Returning %Rhrc\n", hrc));
     return hrc;
+}
+
+/**
+ * Validates and extracts directory copy flags from a comma-separated string.
+ *
+ * @return VBox status code.
+ * @param  strFlags             String to extract flags from.
+ * @param  pfFlags              Where to store the extracted (and validated) flags.
+ */
+/* static */
+int GuestSession::i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags)
+{
+    DirectoryCopyFlag_T fFlags = DirectoryCopyFlag_None;
+
+    /* Validate and set flags. */
+    if (strFlags.isEmpty())
+    {
+        *pfFlags = fFlags;
+        return VINF_SUCCESS;
+    }
+
+    const char *pcszNext = strFlags.c_str();
+    while (*pcszNext != '\0')
+    {
+        Utf8Str strFlag;
+        const char *pcszComma = RTStrStr(pcszNext, ",");
+        if (!pcszComma)
+            strFlag = pcszNext;
+        else
+            strFlag = Utf8Str(pcszNext, pcszComma - pcszNext);
+
+        const char *pcszEqual = RTStrStr(strFlag.c_str(), "=");
+        if (   pcszEqual
+            && pcszEqual != strFlag.c_str())
+        {
+            Utf8Str strKey(strFlag.c_str(), pcszEqual - strFlag.c_str());
+            Utf8Str strValue(strFlag.c_str() + (pcszEqual - strFlag.c_str() + 1));
+            RT_NOREF(strKey, strValue); /* We don't have any key=value pairs yet. */
+        }
+        else
+        {
+           if (strFlag == "CopyIntoExisting")
+               fFlags |= DirectoryCopyFlag_CopyIntoExisting;
+           else
+               return VERR_INVALID_PARAMETER;
+        }
+
+        if (!pcszComma)
+            pcszNext += strFlag.length();
+        else
+            pcszNext += strFlag.length() + 1;
+    }
+
+    if (pfFlags)
+        *pfFlags = fFlags;
+
+    return VINF_SUCCESS;
 }
 
@@ -1344,4 +1343,65 @@
     LogFlowFuncLeaveRC(rc);
     return rc;
+}
+
+/**
+ * Validates and extracts file copy flags from a comma-separated string.
+ *
+ * @return VBox status code.
+ * @param  strFlags             String to extract flags from.
+ * @param  pfFlags              Where to store the extracted (and validated) flags.
+ */
+/* static */
+int GuestSession::i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags)
+{
+    FileCopyFlag_T fFlags = FileCopyFlag_None;
+
+    /* Validate and set flags. */
+    if (strFlags.isEmpty())
+    {
+        *pfFlags = fFlags;
+        return VINF_SUCCESS;
+    }
+
+    const char *pcszNext = strFlags.c_str();
+    while (*pcszNext != '\0')
+    {
+        Utf8Str strFlag;
+        const char *pcszComma = RTStrStr(pcszNext, ",");
+        if (!pcszComma)
+            strFlag = pcszNext;
+        else
+            strFlag = Utf8Str(pcszNext, pcszComma - pcszNext);
+
+        const char *pcszEqual = RTStrStr(strFlag.c_str(), "=");
+        if (   pcszEqual
+            && pcszEqual != strFlag.c_str())
+        {
+            Utf8Str strKey(strFlag.c_str(), pcszEqual - strFlag.c_str());
+            Utf8Str strValue(strFlag.c_str() + (pcszEqual - strFlag.c_str() + 1));
+            RT_NOREF(strKey, strValue); /* We don't have any key=value pairs yet. */
+        }
+        else
+        {
+            if (strFlag == "NoReplace")
+                fFlags |= FileCopyFlag_NoReplace;
+            else if (strFlag == "FollowLinks")
+                fFlags |= FileCopyFlag_FollowLinks;
+            else if (strFlag == "Update")
+                fFlags |= FileCopyFlag_Update;
+            else
+                return VERR_INVALID_PARAMETER;
+        }
+
+        if (!pcszComma)
+            pcszNext += strFlag.length();
+        else
+            pcszNext += strFlag.length() + 1;
+    }
+
+    if (pfFlags)
+        *pfFlags = fFlags;
+
+    return VINF_SUCCESS;
 }
 
@@ -2851,5 +2911,5 @@
 
 HRESULT GuestSession::copyFromGuest(const std::vector<com::Utf8Str> &aSources, const std::vector<com::Utf8Str> &aFilters,
-                                    const std::vector<FsObjType_T> &aTypes, const std::vector<GuestCopyFlag_T> &aFlags,
+                                    const std::vector<FsObjType_T> &aTypes, const std::vector<com::Utf8Str> &aFlags,
                                     const com::Utf8Str &aDestination, ComPtr<IProgress> &aProgress)
 {
@@ -2867,8 +2927,8 @@
     GuestSessionFsSourceSet SourceSet;
 
-    std::vector<com::Utf8Str>::const_iterator itSource  = aSources.begin();
-    std::vector<com::Utf8Str>::const_iterator itFilter  = aFilters.begin();
-    std::vector<FsObjType_T>::const_iterator itType     = aTypes.begin();
-    std::vector<GuestCopyFlag_T>::const_iterator itFlag = aFlags.begin();
+    std::vector<com::Utf8Str>::const_iterator itSource = aSources.begin();
+    std::vector<com::Utf8Str>::const_iterator itFilter = aFilters.begin();
+    std::vector<FsObjType_T>::const_iterator  itType   = aTypes.begin();
+    std::vector<com::Utf8Str>::const_iterator itFlags  = aFlags.begin();
 
     while (itSource != aSources.end())
@@ -2880,13 +2940,20 @@
         source.enmPathStyle = i_getPathStyle();
 
-        if (*itType == FsObjType_Directory)
-        {
-            source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)*itFlag;
+        if (source.enmType == FsObjType_Directory)
+        {
+            int rc2 = GuestSession::i_directoryCopyFlagFromStr(*itFlags, &source.Type.Dir.fCopyFlags);
+            if (RT_FAILURE(rc2))
+                return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
+
             source.Type.Dir.fRecursive = true; /* Implicit. */
         }
+        else if (source.enmType == FsObjType_File)
+        {
+            int rc2 = GuestSession::i_fileCopyFlagFromStr(*itFlags, &source.Type.File.fCopyFlags);
+            if (RT_FAILURE(rc2))
+                return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
+        }
         else
-        {
-            source.Type.File.fCopyFlags = (FileCopyFlag_T)*itFlag;
-        }
+            return setError(E_INVALIDARG, tr("Source type %d invalid / not supported"), source.enmType);
 
         SourceSet.push_back(source);
@@ -2895,5 +2962,5 @@
         ++itFilter;
         ++itType;
-        ++itFlag;
+        ++itFlags;
     }
 
@@ -2902,5 +2969,5 @@
 
 HRESULT GuestSession::copyToGuest(const std::vector<com::Utf8Str> &aSources, const std::vector<com::Utf8Str> &aFilters,
-                                  const std::vector<FsObjType_T> &aTypes, const std::vector<GuestCopyFlag_T> &aFlags,
+                                  const std::vector<FsObjType_T> &aTypes, const std::vector<com::Utf8Str> &aFlags,
                                   const com::Utf8Str &aDestination, ComPtr<IProgress> &aProgress)
 {
@@ -2918,12 +2985,11 @@
     GuestSessionFsSourceSet SourceSet;
 
-    std::vector<com::Utf8Str>::const_iterator itSource  = aSources.begin();
-    std::vector<com::Utf8Str>::const_iterator itFilter  = aFilters.begin();
-    std::vector<FsObjType_T>::const_iterator itType     = aTypes.begin();
-    std::vector<GuestCopyFlag_T>::const_iterator itFlag = aFlags.begin();
+    std::vector<com::Utf8Str>::const_iterator itSource = aSources.begin();
+    std::vector<com::Utf8Str>::const_iterator itFilter = aFilters.begin();
+    std::vector<FsObjType_T>::const_iterator  itType   = aTypes.begin();
+    std::vector<com::Utf8Str>::const_iterator itFlags  = aFlags.begin();
 
     while (itSource != aSources.end())
     {
-
         GuestSessionFsSourceSpec source;
         source.strSource    = *itSource;
@@ -2932,11 +2998,20 @@
         source.enmPathStyle = i_getPathStyle();
 
-        if (*itType == FsObjType_Directory)
-        {
-            source.Type.Dir.fCopyFlags = (DirectoryCopyFlag_T)*itFlag;
+        if (source.enmType == FsObjType_Directory)
+        {
+            int rc2 = GuestSession::i_directoryCopyFlagFromStr(*itFlags, &source.Type.Dir.fCopyFlags);
+            if (RT_FAILURE(rc2))
+                return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
+
             source.Type.Dir.fRecursive = true; /* Implicit. */
         }
+        else if (source.enmType == FsObjType_File)
+        {
+            int rc2 = GuestSession::i_fileCopyFlagFromStr(*itFlags, &source.Type.File.fCopyFlags);
+            if (RT_FAILURE(rc2))
+                return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
+        }
         else
-            source.Type.File.fCopyFlags = (FileCopyFlag_T)*itFlag;
+            return setError(E_INVALIDARG, tr("Source type %d invalid / not supported"), source.enmType);
 
         SourceSet.push_back(source);
@@ -2945,5 +3020,5 @@
         ++itFilter;
         ++itType;
-        ++itFlag;
+        ++itFlags;
     }
 
