VirtualBox

Changeset 97343 in vbox


Ignore:
Timestamp:
Oct 31, 2022 9:47:06 AM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154341
Message:

Guest Control/FE/VBoxManage: Use the same APIs (GuestSession::CopyToGuest() + GuestSession::CopyFromGuest()) as in FE/Qt's file manager to match testing / validating things. Also simplifies the code in VBoxManage, as most of the magic now is done under the hood by Main. bugref:10286

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r97308 r97343  
    16861686    HRESULT hrc = S_OK;
    16871687
    1688     bool fDstIsDir = false;
    1689 
    1690     if (!fHostToGuest)
    1691     {
    1692         RTFSOBJINFO ObjInfo;
    1693         vrc = RTPathQueryInfo(szAbsDst, &ObjInfo, RTFSOBJATTRADD_NOTHING);
    1694         if (RT_SUCCESS(vrc))
    1695         {
    1696             fDstIsDir = RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode);
    1697         }
    1698         else if (   RT_FAILURE(vrc)
    1699                  && vrc != VERR_FILE_NOT_FOUND) /* Destination file on the host might not exist yet, which is fine. */
    1700                 return RTMsgErrorExitFailure(GuestCtrl::tr("RTPathQueryInfo failed on '%s': %Rrc"), szAbsDst, vrc);
    1701     }
    1702     else
    1703     {
    1704         BOOL fDirExists = FALSE;
    1705         hrc = pCtx->pGuestSession->DirectoryExists(Bstr(pszDst).raw(), TRUE /* fFollowSymlinks */, &fDirExists);
    1706         if (SUCCEEDED(hrc))
    1707             fDstIsDir = RT_BOOL(fDirExists);
    1708     }
    1709 
    1710     /* If multiple sources are specified, the destination must be a directory. */
    1711     fDstMustBeDir = cSources > 1;
    1712 
    1713     /* If destination must be a directory, check this first before everything else. */
    1714     if (    fDstMustBeDir
    1715         && !fDstIsDir)
    1716     {
    1717         return RTMsgErrorExitFailure(GuestCtrl::tr("Destination must be a directory!"));
    1718     }
    1719 
    1720     for (size_t iSrc = 0; iSrc < cSources; iSrc++)
    1721     {
    1722         /*
    1723          * Note: Having a dedicated progress object on every single source being copied can be very slow.
    1724          *       We implement IGuestSession::Copy[From|To]Guest() since quite a while which does most of the below
    1725          *       under the hood in Main using a multi-staged progress object. However, leave this like it is for now
    1726          *       to (also) have a different method of API testing.
    1727          */
    1728         ComPtr<IProgress> pProgress;
    1729         const char       *pszSource = papszSources[iSrc];
    1730 
    1731         /* Note: Wildcards have to be processed by the calling process (i.e. via globbing, if available). */
    1732 
     1688    com::SafeArray<IN_BSTR> aSources;
     1689    com::SafeArray<IN_BSTR> aFilters; /** @todo Populate those? For now we use caller-based globbing. */
     1690    com::SafeArray<IN_BSTR> aCopyFlags;
     1691
     1692    size_t iSrc = 0;
     1693    for (; iSrc < cSources; iSrc++)
     1694    {
     1695        aSources.push_back(Bstr(papszSources[iSrc]).raw());
     1696        aFilters.push_back(Bstr("").raw()); /* Empty for now. See @todo above. */
     1697
     1698        /* Compile the comma-separated list of flags.
     1699         * Certain flags are only available for specific file system objects, e.g. directories. */
     1700        bool fIsDir = false;
    17331701        if (fHostToGuest)
    17341702        {
    1735             /*
    1736              * Source is host, destination guest.
    1737              */
    1738             char szAbsSrc[RTPATH_MAX];
    1739             vrc = RTPathAbs(pszSource, szAbsSrc, sizeof(szAbsSrc));
     1703            RTFSOBJINFO ObjInfo;
     1704            vrc = RTPathQueryInfo(papszSources[iSrc], &ObjInfo, RTFSOBJATTRADD_NOTHING);
    17401705            if (RT_SUCCESS(vrc))
    1741             {
    1742                 RTFSOBJINFO ObjInfo;
    1743                 vrc = RTPathQueryInfo(szAbsSrc, &ObjInfo, RTFSOBJATTRADD_NOTHING);
    1744                 if (RT_SUCCESS(vrc))
    1745                 {
    1746                     if (RTFS_IS_FILE(ObjInfo.Attr.fMode))
    1747                     {
    1748                         if (pCtx->cVerbose)
    1749                             RTPrintf(GuestCtrl::tr("File '%s' -> '%s'\n"), szAbsSrc, pszDst);
    1750 
    1751                         SafeArray<FileCopyFlag_T> aCopyFlags;
    1752                         hrc = pCtx->pGuestSession->FileCopyToGuest(Bstr(szAbsSrc).raw(), Bstr(pszDst).raw(),
    1753                                                                    ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam());
    1754                     }
    1755                     else if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
    1756                     {
    1757                         if (pCtx->cVerbose)
    1758                             RTPrintf(GuestCtrl::tr("Directory '%s' -> '%s'\n"), szAbsSrc, pszDst);
    1759 
    1760                         SafeArray<DirectoryCopyFlag_T> aCopyFlags;
    1761                         aCopyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting);
    1762                         if (fRecursive)
    1763                             aCopyFlags.push_back(DirectoryCopyFlag_Recursive);
    1764                         if (fFollow)
    1765                             aCopyFlags.push_back(DirectoryCopyFlag_FollowLinks);
    1766                         hrc = pCtx->pGuestSession->DirectoryCopyToGuest(Bstr(szAbsSrc).raw(), Bstr(pszDst).raw(),
    1767                                                                         ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam());
    1768                     }
    1769                     else
    1770                         rcExit = RTMsgErrorExitFailure(GuestCtrl::tr("Not a file or directory: %s\n"), szAbsSrc);
    1771                 }
    1772                 else
    1773                     rcExit = RTMsgErrorExitFailure(GuestCtrl::tr("RTPathQueryInfo failed on '%s': %Rrc"), szAbsSrc, vrc);
    1774             }
    1775             else
    1776                 rcExit = RTMsgErrorExitFailure(GuestCtrl::tr("RTPathAbs failed on '%s': %Rrc"), pszSource, vrc);
    1777         }
    1778         else
    1779         {
    1780             /*
    1781              * Source guest, destination host.
    1782              */
    1783             /* We need to query the source type on the guest first in order to know which copy flavor we need. */
     1706                fIsDir = RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode);
     1707
     1708            if (RT_FAILURE(vrc))
     1709                break;
     1710        }
     1711        else /* Guest to host. */
     1712        {
    17841713            ComPtr<IGuestFsObjInfo> pFsObjInfo;
    1785             hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(pszSource).raw(), TRUE  /* fFollowSymlinks */, pFsObjInfo.asOutParam());
     1714            hrc = pCtx->pGuestSession->FsObjQueryInfo(Bstr(papszSources[iSrc]).raw(), RT_BOOL(fFollow) /* fFollowSymlinks */,
     1715                                                      pFsObjInfo.asOutParam());
    17861716            if (SUCCEEDED(hrc))
    17871717            {
     
    17911721                {
    17921722                    /* Take action according to source file. */
    1793                     if (enmObjType == FsObjType_Directory)
    1794                     {
    1795                         if (pCtx->cVerbose)
    1796                             RTPrintf(GuestCtrl::tr("Directory '%s' -> '%s'\n"), pszSource, pszDst);
    1797 
    1798                         SafeArray<DirectoryCopyFlag_T> aCopyFlags;
    1799                         aCopyFlags.push_back(DirectoryCopyFlag_CopyIntoExisting);
    1800                         if (fRecursive)
    1801                             aCopyFlags.push_back(DirectoryCopyFlag_Recursive);
    1802                         if (fFollow)
    1803                             aCopyFlags.push_back(DirectoryCopyFlag_FollowLinks);
    1804                         hrc = pCtx->pGuestSession->DirectoryCopyFromGuest(Bstr(pszSource).raw(), Bstr(pszDst).raw(),
    1805                                                                           ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam());
    1806                     }
    1807                     else if (enmObjType == FsObjType_File)
    1808                     {
    1809                         if (pCtx->cVerbose)
    1810                             RTPrintf(GuestCtrl::tr("File '%s' -> '%s'\n"), pszSource, pszDst);
    1811 
    1812                         SafeArray<FileCopyFlag_T> aCopyFlags;
    1813                         if (fFollow)
    1814                             aCopyFlags.push_back(FileCopyFlag_FollowLinks);
    1815                         hrc = pCtx->pGuestSession->FileCopyFromGuest(Bstr(pszSource).raw(), Bstr(pszDst).raw(),
    1816                                                                      ComSafeArrayAsInParam(aCopyFlags), pProgress.asOutParam());
    1817                     }
    1818                     else
    1819                         rcExit = RTMsgErrorExitFailure(GuestCtrl::tr("Not a file or directory: %s\n"), pszSource);
     1723                    fIsDir = enmObjType == FsObjType_Directory;
    18201724                }
    1821                 else
    1822                     rcExit = RTEXITCODE_FAILURE;
    18231725            }
    1824             else
    1825                 rcExit = RTMsgErrorExitFailure(GuestCtrl::tr("FsObjQueryInfo failed on '%s': %Rhrc"), pszSource, hrc);
    1826         }
    1827 
    1828         if (FAILED(hrc))
    1829         {
    1830             vrc = gctlPrintError(pCtx->pGuestSession, COM_IIDOF(IGuestSession));
    1831         }
    1832         else if (pProgress.isNotNull())
    1833         {
    1834             if (pCtx->cVerbose)
    1835                 hrc = showProgress(pProgress);
    1836             else
    1837                 hrc = pProgress->WaitForCompletion(-1 /* No timeout */);
    1838             if (SUCCEEDED(hrc))
    1839                 CHECK_PROGRESS_ERROR(pProgress, (GuestCtrl::tr("File copy failed")));
    1840             vrc = gctlPrintProgressError(pProgress);
    1841         }
    1842 
    1843         /* Keep going. */
     1726
     1727            if (FAILED(hrc))
     1728            {
     1729                vrc = gctlPrintError(pCtx->pGuestSession, COM_IIDOF(IGuestSession));
     1730                break;
     1731            }
     1732        }
     1733
     1734        if (pCtx->cVerbose)
     1735            RTPrintf(GuestCtrl::tr("Source '%s' is a %s\n"), papszSources[iSrc], fIsDir ? "directory" : "file");
     1736
     1737        Utf8Str strCopyFlags;
     1738        if (fRecursive && fIsDir) /* Only available for directories. Just ignore otherwise. */
     1739            strCopyFlags += "Recursive,";
     1740        if (fIsDir)
     1741            strCopyFlags += "CopyIntoExisting,"; /* Implicit. */
     1742        if (fFollow)
     1743            strCopyFlags += "FollowLinks,";
     1744       aCopyFlags.push_back(Bstr(strCopyFlags).raw());
     1745    }
     1746
     1747    if (RT_FAILURE(vrc))
     1748        return RTMsgErrorExitFailure(GuestCtrl::tr("Error looking file system information for source '%s', rc=%Rrc"),
     1749                                     papszSources[iSrc], vrc);
     1750
     1751    ComPtr<IProgress> pProgress;
     1752    if (fHostToGuest)
     1753    {
     1754        hrc = pCtx->pGuestSession->CopyToGuest(ComSafeArrayAsInParam(aSources),
     1755                                               ComSafeArrayAsInParam(aFilters), ComSafeArrayAsInParam(aCopyFlags),
     1756                                               Bstr(pszDst).raw(), pProgress.asOutParam());
     1757    }
     1758    else /* Guest to host. */
     1759    {
     1760        hrc = pCtx->pGuestSession->CopyFromGuest(ComSafeArrayAsInParam(aSources),
     1761                                                 ComSafeArrayAsInParam(aFilters), ComSafeArrayAsInParam(aCopyFlags),
     1762                                                 Bstr(pszDst).raw(), pProgress.asOutParam());
     1763    }
     1764
     1765    if (FAILED(hrc))
     1766    {
     1767        vrc = gctlPrintError(pCtx->pGuestSession, COM_IIDOF(IGuestSession));
     1768    }
     1769    else if (pProgress.isNotNull())
     1770    {
     1771        if (pCtx->cVerbose)
     1772            hrc = showProgress(pProgress);
     1773        else
     1774            hrc = pProgress->WaitForCompletion(-1 /* No timeout */);
     1775        if (SUCCEEDED(hrc))
     1776            CHECK_PROGRESS_ERROR(pProgress, (GuestCtrl::tr("File copy failed")));
     1777        vrc = gctlPrintProgressError(pProgress);
    18441778    }
    18451779
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