VirtualBox

Changeset 97344 in vbox


Ignore:
Timestamp:
Oct 31, 2022 10:17:50 AM (2 years ago)
Author:
vboxsync
Message:

Guest Control/Main: Fixes for copying to/from guests with mixed OSes. bugref:10286

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestSessionImplTasks.h

    r97152 r97344  
    139139    /** File system filter / options to use for this task. */
    140140    GuestSessionFsSourceSpec mSourceSpec;
    141     /** The source' root path.
     141    /** The source' root path. Always in the source's path style!
     142     *
    142143     *  For a single file list this is the full (absolute) path to a file,
    143144     *  for a directory list this is the source root directory. */
    144145    Utf8Str                 mSrcRootAbs;
    145     /** The destinations's root path.
     146    /** The destinations's root path. Always in the destination's path style!
     147     *
    146148     *  For a single file list this is the full (absolute) path to a file,
    147149     *  for a directory list this is the destination root directory. */
     
    256258     *  asynchronously. Optional. */
    257259    ComObjPtr<Progress>     mProgress;
    258     /** The guest's path style (depending on the guest OS type set). */
    259     uint32_t                mfPathStyle;
    260     /** The guest's path style as string representation (depending on the guest OS type set). */
    261     Utf8Str                 mPathStyle;
     260    /** The guest's path style as char representation (depending on the guest OS type set). */
     261    Utf8Str                 mstrGuestPathStyle;
    262262};
    263263
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r97306 r97344  
    7575
    7676
     77/** Returns the path separator based on \a a_enmPathStyle as a C-string. */
     78#define PATH_STYLE_SEP_STR(a_enmPathStyle) a_enmPathStyle == PathStyle_DOS ? "\\" : "/"
     79#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     80# define PATH_STYLE_NATIVE               PathStyle_DOS
     81#else
     82# define PATH_STYLE_NATIVE               PathStyle_UNIX
     83#endif
     84
    7785// session task classes
    7886/////////////////////////////////////////////////////////////////////////////
     
    8694    {
    8795        case PathStyle_DOS:
    88             mfPathStyle = RTPATH_STR_F_STYLE_DOS;
    89             mPathStyle  = "\\";
     96            mstrGuestPathStyle = "\\";
    9097            break;
    9198
    9299        default:
    93             mfPathStyle = RTPATH_STR_F_STYLE_UNIX;
    94             mPathStyle  = "/";
     100            mstrGuestPathStyle = "/";
    95101            break;
    96102    }
     
    598604        else
    599605        {
    600             if (vrc != VERR_FILE_NOT_FOUND) /* Destination file does not exist (yet)? */
     606            if (vrc == VERR_PATH_NOT_FOUND)       /* Destination file does not exist (yet)? */
     607                vrc = VERR_FILE_NOT_FOUND;        /* Needed in next block further down. */
     608            else if (vrc != VERR_FILE_NOT_FOUND)  /* Ditto. */
    601609                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    602                                     Utf8StrFmt(tr("Host file lookup for \"%s\" failed: %Rrc"),
    603                                                strDst.c_str(), vrc));
     610                                    Utf8StrFmt(tr("Host destination file lookup for \"%s\" failed: %Rrc"), strDst.c_str(), vrc));
    604611        }
    605612    }
     
    634641            if (RT_SUCCESS(vrc))
    635642            {
    636                 vrc = RTPathAppend(szDstPath, sizeof(szDstPath), RTPathFilenameEx(strSrc.c_str(), mfPathStyle));
     643                vrc = RTPathAppend(szDstPath, sizeof(szDstPath), RTPathFilename(strSrc.c_str()));
    637644                if (RT_SUCCESS(vrc))
    638645                    pszDstFile = RTStrDup(szDstPath);
     
    910917            {
    911918                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    912                                     Utf8StrFmt(tr("Host file lookup for \"%s\" failed: %Rrc"),
     919                                    Utf8StrFmt(tr("Host source file lookup for \"%s\" failed: %Rrc"),
    913920                                               szSrcReal, vrc));
    914921            }
     
    10771084{
    10781085    Utf8Str strPathAbs = strPath;
    1079     if (   !strPathAbs.endsWith("/")
    1080         && !strPathAbs.endsWith("\\"))
    1081         strPathAbs += "/";
     1086    if (!strPathAbs.endsWith(PATH_STYLE_SEP_STR(mSourceSpec.enmPathStyle)))
     1087        strPathAbs += PATH_STYLE_SEP_STR(mSourceSpec.enmPathStyle);
    10821088
    10831089    Utf8Str strPathSub = strSubDir;
    10841090    if (   strPathSub.isNotEmpty()
    1085         && !strPathSub.endsWith("/")
    1086         && !strPathSub.endsWith("\\"))
    1087         strPathSub += "/";
     1091        && !strPathSub.endsWith(PATH_STYLE_SEP_STR(mSourceSpec.enmPathStyle)))
     1092        strPathSub += PATH_STYLE_SEP_STR(mSourceSpec.enmPathStyle);
    10881093
    10891094    strPathAbs += strPathSub;
     
    12171222{
    12181223    Utf8Str strPathAbs = strPath;
    1219     if (   !strPathAbs.endsWith("/")
    1220         && !strPathAbs.endsWith("\\"))
    1221         strPathAbs += "/";
     1224    if (!strPathAbs.endsWith(RTPATH_SLASH_STR))
     1225        strPathAbs += RTPATH_SLASH_STR;
    12221226
    12231227    Utf8Str strPathSub = strSubDir;
    12241228    if (   strPathSub.isNotEmpty()
    1225         && !strPathSub.endsWith("/")
    1226         && !strPathSub.endsWith("\\"))
    1227         strPathSub += "/";
     1229        && !strPathSub.endsWith(RTPATH_SLASH_STR))
     1230        strPathSub += RTPATH_SLASH_STR;
    12281231
    12291232    strPathAbs += strPathSub;
     
    14741477                /* If the source does not end with a slash, copy over the entire directory
    14751478                 * (and not just its contents). */
    1476                 /** @todo r=bird: Try get the path style stuff right and stop assuming all guest are windows guests.  */
    1477                 if (   !strSrc.endsWith("/")
    1478                     && !strSrc.endsWith("\\"))
     1479                if (!strSrc.endsWith(mstrGuestPathStyle))
    14791480                {
    14801481                    if (!RTPATH_IS_SLASH(strDst[strDst.length() - 1]))
    1481                         strDst += "/";
    1482 
    1483                     strDst += Utf8Str(RTPathFilenameEx(strSrc.c_str(), mfPathStyle));
     1482                        strDst += RTPATH_SLASH_STR;
     1483
     1484                    strDst += Utf8Str(RTPathFilename(strSrc.c_str()));
    14841485                }
    14851486
     
    16021603        AssertPtr(pList);
    16031604
     1605        LogFlowFunc(("List: srcRootAbs=%s, dstRootAbs=%s\n", pList->mSrcRootAbs.c_str(), pList->mDstRootAbs.c_str()));
     1606
     1607        Utf8Str strSrcRootAbs = pList->mSrcRootAbs;
     1608        Utf8Str strDstRootAbs = pList->mDstRootAbs;
     1609
    16041610        const bool     fCopyIntoExisting = pList->mSourceSpec.Type.Dir.fCopyFlags & DirectoryCopyFlag_CopyIntoExisting;
    16051611        const bool     fFollowSymlinks   = true; /** @todo */
     
    16101616            fDirCreate |= RTDIRCREATE_FLAGS_NO_SYMLINKS;
    16111617
    1612         LogFlowFunc(("List: srcRootAbs=%s, dstRootAbs=%s\n", pList->mSrcRootAbs.c_str(), pList->mDstRootAbs.c_str()));
    1613 
    1614         /* Create the root directory. */
     1618        RTFSOBJINFO ObjInfo;
     1619        RT_ZERO(ObjInfo);
     1620        vrc = RTPathQueryInfo(strDstRootAbs.c_str(), &ObjInfo, RTFSOBJATTRADD_NOTHING);
     1621        if (   RT_FAILURE(vrc)
     1622            && vrc != VERR_FILE_NOT_FOUND
     1623            && vrc != VERR_PATH_NOT_FOUND)
     1624        {
     1625            setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     1626                                Utf8StrFmt(tr("Host path lookup for \"%s\" failed: %Rrc"), strDstRootAbs.c_str(), vrc));
     1627            break;
     1628        }
     1629        else
     1630            vrc = VINF_SUCCESS; /* Reset rc. */
     1631
     1632        bool const fDstIsDir        = RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode);
     1633        bool const fDstDirMustExist = strDstRootAbs.endsWith(PATH_STYLE_SEP_STR(PATH_STYLE_NATIVE)); /* Copy into existing dir? */
     1634
     1635        /* Copy source(s) into an existing directory on the host (path ends with a slash)? */
     1636        if (fDstDirMustExist)
     1637        {
     1638            if (   !RTDirExists(strDstRootAbs.c_str())
     1639                || !fDstIsDir)
     1640            {
     1641                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     1642                                    Utf8StrFmt(tr("Host directory \"%s\" does not exist"), strDstRootAbs.c_str()));
     1643                vrc = VERR_PATH_NOT_FOUND;
     1644                break;
     1645            }
     1646        }
     1647        /* else Copy source(s) into a file on the host. */
     1648
     1649        /* Create the destination directory if required. */
    16151650        if (   pList->mSourceSpec.enmType == FsObjType_Directory
    16161651            && pList->mSourceSpec.fDryRun == false)
    16171652        {
    1618             vrc = directoryCreateOnHost(pList->mDstRootAbs, fDirCreate, fDirMode, fCopyIntoExisting);
     1653            vrc = directoryCreateOnHost(strDstRootAbs, fDirCreate, fDirMode, fCopyIntoExisting);
    16191654            if (RT_FAILURE(vrc))
    16201655                break;
     
    16271662            AssertPtr(pEntry);
    16281663
    1629             Utf8Str strSrcAbs = pList->mSrcRootAbs;
    1630             Utf8Str strDstAbs = pList->mDstRootAbs;
    1631 
    1632             LogFlowFunc(("Entry: srcRootAbs=%s, dstRootAbs=%s\n", pList->mSrcRootAbs.c_str(), pList->mDstRootAbs.c_str()));
     1664            Utf8Str strSrcAbs = strSrcRootAbs;
     1665            Utf8Str strDstAbs = strDstRootAbs;
    16331666
    16341667            if (pList->mSourceSpec.enmType == FsObjType_Directory)
    16351668            {
    1636                 char szPath[RTPATH_MAX];
    1637 
    1638                 /* Build the source path on the guest. */
    1639                 vrc = RTStrCopy(szPath, sizeof(szPath), pList->mSrcRootAbs.c_str());
    1640                 if (RT_SUCCESS(vrc))
    1641                 {
    1642                     vrc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
    1643                     if (RT_SUCCESS(vrc))
    1644                         strSrcAbs = szPath;
    1645                 }
    1646 
    1647                 /* Build the destination path on the host. */
    1648                 vrc = RTStrCopy(szPath, sizeof(szPath), pList->mDstRootAbs.c_str());
    1649                 if (RT_SUCCESS(vrc))
    1650                 {
    1651                     vrc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
    1652                     if (RT_SUCCESS(vrc))
    1653                         strDstAbs = szPath;
    1654                 }
    1655             }
    1656 
    1657             if (pList->mSourceSpec.enmPathStyle == PathStyle_DOS)
    1658                 strDstAbs.findReplace('\\', '/');
     1669                strSrcAbs += PATH_STYLE_SEP_STR(pList->mSourceSpec.enmPathStyle);
     1670                strSrcAbs += pEntry->strPath;
     1671            }
     1672
     1673            if (fDstIsDir)
     1674            {
     1675                strDstAbs += PATH_STYLE_SEP_STR(PATH_STYLE_NATIVE);
     1676                strDstAbs += pEntry->strPath;
     1677            }
     1678
     1679            /* Translate the final guest source path (for cleaning up mixed path separators). */
     1680            vrc = GuestPath::Translate(strSrcAbs, pList->mSourceSpec.enmPathStyle /* Source */, pList->mSourceSpec.enmPathStyle /* Dest */,
     1681                                       true /* fForce */);
     1682            if (RT_FAILURE(vrc))
     1683                break;
     1684
     1685            /* Translate the final host destination path (for cleaning up mixed path separators). */
     1686            vrc = GuestPath::Translate(strDstAbs, PATH_STYLE_NATIVE, PATH_STYLE_NATIVE /* Dest */, true /* fForce */);
     1687            if (RT_FAILURE(vrc))
     1688                break;
    16591689
    16601690            mProgress->SetNextOperation(Bstr(strSrcAbs).raw(), 1);
     
    16651695            {
    16661696                case RTFS_TYPE_DIRECTORY:
    1667                     LogFlowFunc(("Directory '%s': %s -> %s\n", pEntry->strPath.c_str(), strSrcAbs.c_str(), strDstAbs.c_str()));
     1697                    LogRel2(("Guest Control: Copying directory '%s' from guest to '%s' on host ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
    16681698                    if (!pList->mSourceSpec.fDryRun)
    16691699                        vrc = directoryCreateOnHost(strDstAbs, fDirCreate, fDirMode, fCopyIntoExisting);
     
    16731703                    RT_FALL_THROUGH();
    16741704                case RTFS_TYPE_SYMLINK:
    1675                     LogFlowFunc(("%s '%s': %s -> %s\n", pEntry->strPath.c_str(),
    1676                                  (pEntry->fMode & RTFS_TYPE_MASK) == RTFS_TYPE_SYMLINK ? "Symlink" : "File",
    1677                                   strSrcAbs.c_str(), strDstAbs.c_str()));
     1705                    LogRel2(("Guest Control: Copying %s '%s' from guest to '%s' on host ...\n",
     1706                             (pEntry->fMode & RTFS_TYPE_MASK) == RTFS_TYPE_SYMLINK ? "symlink" : "file", strSrcAbs.c_str(), strDstAbs.c_str()));
    16781707                    if (!pList->mSourceSpec.fDryRun)
    16791708                        vrc = fileCopyFromGuest(strSrcAbs, strDstAbs, FileCopyFlag_None);
     
    18811910        AssertPtr(pList);
    18821911
     1912        LogFlowFunc(("List: srcRootAbs=%s, dstRootAbs=%s\n", pList->mSrcRootAbs.c_str(), pList->mDstRootAbs.c_str()));
     1913
    18831914        Utf8Str strSrcRootAbs = pList->mSrcRootAbs;
    18841915        Utf8Str strDstRootAbs = pList->mDstRootAbs;
     1916
     1917        /* Translate the destination path from the host to a path compatible with the guest. */
     1918        vrc = GuestPath::Translate(strDstRootAbs, PATH_STYLE_NATIVE /* Source */, mSession->i_getGuestPathStyle() /* Dest */);
     1919        if (RT_FAILURE(vrc))
     1920            break;
    18851921
    18861922        bool     fCopyIntoExisting = false;
     
    19201956        }
    19211957
    1922         char szPath[RTPATH_MAX];
    1923 
    19241958        LogFlowFunc(("List inital: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s\n",
    19251959                     vrc, strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
     
    19451979                    {
    19461980                        /* Build the destination path on the guest. */
    1947                         vrc = RTStrCopy(szPath, sizeof(szPath), strDstRootAbs.c_str());
    1948                         if (RT_SUCCESS(vrc))
    1949                         {
    1950                             vrc = RTPathAppend(szPath, sizeof(szPath), RTPathFilenameEx(strSrcRootAbs.c_str(), mfPathStyle));
    1951                             if (RT_SUCCESS(vrc))
    1952                                 strDstRootAbs = szPath;
    1953                         }
     1981                        strDstRootAbs += PATH_STYLE_SEP_STR(mSession->i_getGuestPathStyle()) + Utf8Str(RTPathFilename(strSrcRootAbs.c_str()));
    19541982                    }
    19551983                    else
     
    20202048            if (pList->mSourceSpec.enmType == FsObjType_Directory)
    20212049            {
    2022                 /* Build the final (absolute) source path (on the host). */
    2023                 vrc = RTStrCopy(szPath, sizeof(szPath), strSrcAbs.c_str());
    2024                 if (RT_SUCCESS(vrc))
    2025                 {
    2026                     vrc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
    2027                     if (RT_SUCCESS(vrc))
    2028                         strSrcAbs = szPath;
    2029                 }
    2030 
    2031                 if (RT_FAILURE(vrc))
    2032                     setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    2033                                         Utf8StrFmt(tr("Building source host path for entry \"%s\" failed (%Rrc)"),
    2034                                                    pEntry->strPath.c_str(), vrc));
     2050                strSrcAbs += PATH_STYLE_SEP_STR(PATH_STYLE_NATIVE);
     2051                strSrcAbs += pEntry->strPath;
    20352052            }
    20362053
     
    20382055            if (dstObjData.mType == FsObjType_Directory)
    20392056            {
    2040                 /* Build the final (absolute) destination path (on the guest). */
    2041                 vrc = RTStrCopy(szPath, sizeof(szPath), strDstAbs.c_str());
    2042                 if (RT_SUCCESS(vrc))
    2043                 {
    2044                     vrc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
    2045                     if (RT_SUCCESS(vrc))
    2046                         strDstAbs = szPath;
    2047                 }
    2048 
    2049                 if (RT_FAILURE(vrc))
    2050                     setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    2051                                         Utf8StrFmt(tr("Building destination guest path for entry \"%s\" failed (%Rrc)"),
    2052                                                    pEntry->strPath.c_str(), vrc));
    2053             }
     2057                strDstAbs += PATH_STYLE_SEP_STR(mSession->i_getGuestPathStyle());
     2058                strDstAbs += pEntry->strPath;
     2059            }
     2060
     2061            /* Translate the final source host path (for cleaning up mixed path separators). */
     2062            vrc = GuestPath::Translate(strSrcAbs, PATH_STYLE_NATIVE /* Source */, PATH_STYLE_NATIVE /* Dest */, true /* fForce */);
     2063            if (RT_FAILURE(vrc))
     2064                break;
     2065
     2066            /* Translate the final destination path from the host to a path compatible with the guest. */
     2067            vrc = GuestPath::Translate(strDstAbs, PATH_STYLE_NATIVE /* Source */, mSession->i_getGuestPathStyle() /* Dest */);
     2068            if (RT_FAILURE(vrc))
     2069                break;
    20542070
    20552071            mProgress->SetNextOperation(Bstr(strSrcAbs).raw(), 1);
    20562072
    2057             LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
    2058 
    20592073            switch (pEntry->fMode & RTFS_TYPE_MASK)
    20602074            {
    20612075                case RTFS_TYPE_DIRECTORY:
    20622076                {
     2077                    LogRel2(("Guest Control: Copying directory '%s' from host to '%s' on guest ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
    20632078                    if (!pList->mSourceSpec.fDryRun)
    20642079                        vrc = directoryCreateOnGuest(strDstAbs, DirectoryCreateFlag_None, fDirMode,
     
    20692084                case RTFS_TYPE_FILE:
    20702085                {
     2086                    LogRel2(("Guest Control: Copying file '%s' from host to '%s' on guest ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
    20712087                    if (!pList->mSourceSpec.fDryRun)
    20722088                        vrc = fileCopyToGuest(strSrcAbs, strDstAbs, fFileCopyFlags);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette