VirtualBox

Changeset 92544 in vbox


Ignore:
Timestamp:
Nov 22, 2021 10:31:09 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148419
Message:

Guest Control/Main + FE/Qt: Fixes for host -> guest and guest -> host copy operations using GuestSession::copyFromGuest() and GuestSession::copyToGuest(). bugref:10139

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerGuestTable.cpp

    r86233 r92544  
    3737#include "CGuestDirectory.h"
    3838#include "CProgress.h"
     39
     40#include <iprt/path.h>
    3941
    4042
     
    323325
    324326void UIFileManagerGuestTable::copyHostToGuest(const QStringList &hostSourcePathList,
    325                                         const QString &strDestination /* = QString() */)
     327                                              const QString &strDestination /* = QString() */)
    326328{
    327329    if (!checkGuestSession())
    328330        return;
    329331    QVector<QString> sourcePaths = hostSourcePathList.toVector();
    330     QVector<QString>  aFilters;
    331     QVector<QString>  aFlags;
     332    QVector<QString> aFilters;
     333    QVector<QString> aFlags;
    332334    QString strDestinationPath = strDestination;
    333335    if (strDestinationPath.isEmpty())
     
    345347    }
    346348
     349    foreach (const QString &strSource, sourcePaths)
     350    {
     351        RTFSOBJINFO ObjInfo;
     352        int vrc = RTPathQueryInfo(strSource.toStdString().c_str(), &ObjInfo, RTFSOBJATTRADD_NOTHING);
     353        if (RT_SUCCESS(vrc))
     354        {
     355            /* If the source is an directory, make sure to add the appropriate flag to make copying work
     356             * into existing directories on the guest. This otherwise would fail (default). */
     357            if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
     358                aFlags.append("CopyIntoExisting");
     359            else /* Make sure to keep the vector in sync with the number of source items by adding an empty entry. */
     360                aFlags.append("");
     361        }
     362        else
     363            emit sigLogOutput(QString("Querying information for host item \"%s\" failed with %Rrc").arg(strSource.toStdString().c_str(), vrc),
     364                              FileManagerLogType_Error);
     365    }
     366
    347367    CProgress progress = m_comGuestSession.CopyToGuest(sourcePaths, aFilters, aFlags, strDestinationPath);
    348368    if (!checkGuestSession())
     
    356376        return;
    357377    QVector<QString> sourcePaths = selectedItemPathList().toVector();
    358     QVector<QString>  aFilters;
    359     QVector<QString>  aFlags;
     378    QVector<QString> aFilters;
     379    QVector<QString> aFlags;
    360380
    361381    if (hostDestinationPath.isEmpty())
     
    368388        emit sigLogOutput("No source for copy operation", FileManagerLogType_Error);
    369389        return;
     390    }
     391
     392    foreach (const QString &strSource, sourcePaths)
     393    {
     394        /** @todo Cache this info and use the item directly, which has this info already? */
     395
     396        /* If the source is an directory, make sure to add the appropriate flag to make copying work
     397         * into existing directories on the guest. This otherwise would fail (default). */
     398        CGuestFsObjInfo fileInfo = m_comGuestSession.FsObjQueryInfo(strSource, true);
     399        if (!m_comGuestSession.isOk())
     400        {
     401            emit sigLogOutput(UIErrorString::formatErrorInfo(m_comGuestSession), FileManagerLogType_Error);
     402            return;
     403        }
     404
     405        KFsObjType eType = fileType(fileInfo);
     406        if (eType == KFsObjType_Directory)
     407            aFlags.append("CopyIntoExisting");
     408        else /* Make sure to keep the vector in sync with the number of source items by adding an empty entry. */
     409            aFlags.append("");
    370410    }
    371411
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r91745 r92544  
    10011001    mSourceSpec = SourceSpec;
    10021002
    1003     /* If the source is a directory, make sure the path is properly terminated already. */
    1004     if (mSourceSpec.enmType == FsObjType_Directory)
    1005     {
    1006         LogFlowFunc(("Directory: mSrcRootAbs=%s, mDstRootAbs=%s, fCopyFlags=%#x, fFollowSymlinks=%RTbool, fRecursive=%RTbool\n",
    1007                      mSrcRootAbs.c_str(), mDstRootAbs.c_str(), mSourceSpec.Type.Dir.fCopyFlags,
    1008                      mSourceSpec.Type.Dir.fFollowSymlinks, mSourceSpec.Type.Dir.fRecursive));
    1009 
    1010         if (   !mSrcRootAbs.endsWith("/")
    1011             && !mSrcRootAbs.endsWith("\\"))
    1012             mSrcRootAbs += "/";
    1013 
    1014         if (   !mDstRootAbs.endsWith("/")
    1015             && !mDstRootAbs.endsWith("\\"))
    1016             mDstRootAbs += "/";
    1017     }
    1018     else if (mSourceSpec.enmType == FsObjType_File)
    1019     {
    1020         LogFlowFunc(("File: mSrcRootAbs=%s, mDstRootAbs=%s, fCopyFlags=%#x\n",
    1021                      mSrcRootAbs.c_str(), mDstRootAbs.c_str(), mSourceSpec.Type.File.fCopyFlags));
    1022     }
    1023     else
    1024         AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     1003    /* Note: Leave the source and dest roots unmodified -- how paths will be treated
     1004     *       will be done directly when working on those. See @bugref{10139}. */
     1005
     1006    LogFlowFunc(("mSrcRootAbs=%s, mDstRootAbs=%s, fCopyFlags=%#x, fFollowSymlinks=%RTbool, fRecursive=%RTbool\n",
     1007                 mSrcRootAbs.c_str(), mDstRootAbs.c_str(), mSourceSpec.Type.Dir.fCopyFlags,
     1008                 mSourceSpec.Type.Dir.fFollowSymlinks, mSourceSpec.Type.Dir.fRecursive));
    10251009
    10261010    return VINF_SUCCESS;
     
    15791563        }
    15801564
     1565        char szPath[RTPATH_MAX];
     1566
    15811567        FsEntries::const_iterator itEntry = pList->mVecEntries.begin();
    15821568        while (itEntry != pList->mVecEntries.end())
     
    15871573            Utf8Str strSrcAbs = pList->mSrcRootAbs;
    15881574            Utf8Str strDstAbs = pList->mDstRootAbs;
     1575
     1576            LogFlowFunc(("Entry: srcRootAbs=%s, dstRootAbs=%s\n", pList->mSrcRootAbs.c_str(), pList->mDstRootAbs.c_str()));
     1577
    15891578            if (pList->mSourceSpec.enmType == FsObjType_Directory)
    15901579            {
    1591                 strSrcAbs += pEntry->strPath;
    1592                 strDstAbs += pEntry->strPath;
    1593 
    1594                 if (pList->mSourceSpec.enmPathStyle == PathStyle_DOS)
    1595                     strDstAbs.findReplace('\\', '/');
    1596             }
     1580                /* Build the source path on the guest. */
     1581                rc = RTStrCopy(szPath, sizeof(szPath), pList->mSrcRootAbs.c_str());
     1582                if (RT_SUCCESS(rc))
     1583                {
     1584                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
     1585                    if (RT_SUCCESS(rc))
     1586                        strSrcAbs = szPath;
     1587                }
     1588
     1589                /* Build the destination path on the host. */
     1590                rc = RTStrCopy(szPath, sizeof(szPath), pList->mDstRootAbs.c_str());
     1591                if (RT_SUCCESS(rc))
     1592                {
     1593                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
     1594                    if (RT_SUCCESS(rc))
     1595                        strDstAbs = szPath;
     1596                }
     1597            }
     1598
     1599            if (pList->mSourceSpec.enmPathStyle == PathStyle_DOS)
     1600                strDstAbs.findReplace('\\', '/');
    15971601
    15981602            mProgress->SetNextOperation(Bstr(strSrcAbs).raw(), 1);
     1603
     1604            LogRel2(("Guest Control: Copying '%s' from guest to '%s' on host ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
    15991605
    16001606            switch (pEntry->fMode & RTFS_TYPE_MASK)
     
    18271833                    default:
    18281834                        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    1829                                             Utf8StrFmt(tr("Querying information on for '%s' failed: %Rrc"),
     1835                                            Utf8StrFmt(tr("Querying information on guest for '%s' failed: %Rrc"),
    18301836                                            strDstRootAbs.c_str(), rcGuest));
    18311837                        break;
     
    18411847        }
    18421848
     1849        char szPath[RTPATH_MAX];
     1850
    18431851        LogFlowFunc(("List inital: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s\n",
    18441852                     rc, strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
     
    18571865
    18581866            /* If the directory on the guest already exists, append the name of the root source directory to it. */
    1859             if (dstObjData.mType == FsObjType_Directory)
    1860             {
    1861                 if (fCopyIntoExisting)
    1862                 {
    1863                     if (   !strDstRootAbs.endsWith("/")
    1864                         && !strDstRootAbs.endsWith("\\"))
    1865                         strDstRootAbs += "/";
    1866                     strDstRootAbs += Utf8Str(RTPathFilenameEx(strSrcRootAbs.c_str(), mfPathStyle));
    1867                 }
    1868                 else
    1869                 {
     1867            switch (dstObjData.mType)
     1868            {
     1869                case FsObjType_Directory:
     1870                {
     1871                    if (fCopyIntoExisting)
     1872                    {
     1873                        /* Build the destination path on the guest. */
     1874                        rc = RTStrCopy(szPath, sizeof(szPath), strDstRootAbs.c_str());
     1875                        if (RT_SUCCESS(rc))
     1876                        {
     1877                            rc = RTPathAppend(szPath, sizeof(szPath), RTPathFilenameEx(strSrcRootAbs.c_str(), mfPathStyle));
     1878                            if (RT_SUCCESS(rc))
     1879                                strDstRootAbs = szPath;
     1880                        }
     1881                    }
     1882                    else
     1883                    {
     1884                        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     1885                                            Utf8StrFmt(tr("Guest directory \"%s\" already exists"),
     1886                                                       strDstRootAbs.c_str()));
     1887                        rc = VERR_ALREADY_EXISTS;
     1888                    }
     1889                    break;
     1890                }
     1891
     1892                case FsObjType_File:
     1893                    /* Nothing to do. */
     1894                    break;
     1895
     1896                default:
    18701897                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    1871                                         Utf8StrFmt(tr("Guest directory \"%s\" already exists"),
     1898                                        Utf8StrFmt(tr("Unknown object type on guest for \"%s\""),
    18721899                                                   strDstRootAbs.c_str()));
    1873                     rc = VERR_ALREADY_EXISTS;
    1874                 }
     1900                    rc = VERR_NOT_SUPPORTED;
     1901                    break;
    18751902            }
    18761903
     
    18981925            AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
    18991926
     1927        LogFlowFunc(("List final: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s, fFileCopyFlags=%#x\n",
     1928                     rc, strSrcRootAbs.c_str(), strDstRootAbs.c_str(), fFileCopyFlags));
     1929
     1930        LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
     1931
    19001932        if (RT_FAILURE(rc))
    19011933            break;
    1902 
    1903         LogFlowFunc(("List final: rc=%Rrc, srcRootAbs=%s, dstRootAbs=%s, fFileCopyFlags=%#x\n",
    1904                      rc, strSrcRootAbs.c_str(), strDstRootAbs.c_str(), fFileCopyFlags));
    1905 
    1906         LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcRootAbs.c_str(), strDstRootAbs.c_str()));
    19071934
    19081935        FsEntries::const_iterator itEntry = pList->mVecEntries.begin();
     
    19181945            if (pList->mSourceSpec.enmType == FsObjType_Directory)
    19191946            {
    1920                 if (   !strSrcAbs.endsWith("/")
    1921                     && !strSrcAbs.endsWith("\\"))
    1922                     strSrcAbs += "/";
    1923                 strSrcAbs += pEntry->strPath;
     1947                /* Build the final (absolute) source path (on the host). */
     1948                rc = RTStrCopy(szPath, sizeof(szPath), strSrcAbs.c_str());
     1949                if (RT_SUCCESS(rc))
     1950                {
     1951                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
     1952                    if (RT_SUCCESS(rc))
     1953                        strSrcAbs = szPath;
     1954                }
     1955
     1956                if (RT_FAILURE(rc))
     1957                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     1958                                        Utf8StrFmt(tr("Building source host path for entry \"%s\" failed (%Rrc)"),
     1959                                                   pEntry->strPath.c_str(), rc));
    19241960            }
    19251961
     
    19271963            if (dstObjData.mType == FsObjType_Directory)
    19281964            {
    1929                 if (   !strDstAbs.endsWith("/")
    1930                     && !strDstAbs.endsWith("\\"))
    1931                     strDstAbs += "/";
    1932                 strDstAbs += pEntry->strPath;
     1965                /* Build the final (absolute) destination path (on the guest). */
     1966                rc = RTStrCopy(szPath, sizeof(szPath), strDstAbs.c_str());
     1967                if (RT_SUCCESS(rc))
     1968                {
     1969                    rc = RTPathAppend(szPath, sizeof(szPath), pEntry->strPath.c_str());
     1970                    if (RT_SUCCESS(rc))
     1971                        strDstAbs = szPath;
     1972                }
     1973
     1974                if (RT_FAILURE(rc))
     1975                    setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     1976                                        Utf8StrFmt(tr("Building destination guest path for entry \"%s\" failed (%Rrc)"),
     1977                                                   pEntry->strPath.c_str(), rc));
    19331978            }
    19341979
    19351980            mProgress->SetNextOperation(Bstr(strSrcAbs).raw(), 1);
    19361981
    1937             LogFlowFunc(("strEntry='%s'\n", pEntry->strPath.c_str()));
    1938             LogFlowFunc(("\tsrcAbs='%s'\n", strSrcAbs.c_str()));
    1939             LogFlowFunc(("\tdstAbs='%s'\n", strDstAbs.c_str()));
     1982            LogRel2(("Guest Control: Copying '%s' from host to '%s' on guest ...\n", strSrcAbs.c_str(), strDstAbs.c_str()));
    19401983
    19411984            switch (pEntry->fMode & RTFS_TYPE_MASK)
Note: See TracChangeset for help on using the changeset viewer.

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