VirtualBox

Changeset 33411 in vbox


Ignore:
Timestamp:
Oct 25, 2010 11:32:26 AM (14 years ago)
Author:
vboxsync
Message:

Guest Copy/VBoxManage+Main: Enabled code by default (VBoxManage "copyto"), added batch copy support.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

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

    r33302 r33411  
    3636
    3737#include <iprt/asm.h>
     38#include <iprt/dir.h>
    3839#include <iprt/isofs.h>
    3940#include <iprt/getopt.h>
     41#include <iprt/list.h>
     42#include <iprt/path.h>
    4043
    4144#ifdef USE_XPCOM_QUEUE
     
    6164static volatile bool    g_fExecCanceled = false;
    6265static volatile bool    g_fCopyCanceled = false;
     66
     67/*
     68 * Structure holding a directory entry.
     69 */
     70typedef struct DIRECTORYENTRY
     71{
     72    char       *pszPath;
     73    RTLISTNODE  Node;
     74} DIRECTORYENTRY, *PDIRECTORYENTRY;
    6375
    6476#endif /* VBOX_ONLY_DOCS */
     
    7688                 /** @todo Add a "--" parameter (has to be last parameter) to directly execute
    7789                  *        stuff, e.g. "VBoxManage guestcontrol execute <VMName> --username <> ... -- /bin/rm -Rf /foo". */
    78 #ifdef VBOX_WITH_COPYTOGUEST
    7990                 "\n"
    8091                 "                            copyto <vmname>|<uuid>\n"
     
    8293                 "                            --username <name> --password <password>\n"
    8394                 "                            [--recursive] [--verbose] [--flags <flags>]\n"
    84 #endif
    8595                 "\n");
    8696}
     
    603613}
    604614
    605 #ifdef VBOX_WITH_COPYTOGUEST
    606615/**
    607616 * Signal handler that sets g_fCopyCanceled.
     
    617626}
    618627
     628/**
     629 * TODO
     630 *
     631 * @return  IPRT status code.
     632 * @return  int
     633 * @param   pszPath
     634 * @param   pList
     635 */
     636int ctrlCopyDirectoryEntryAppend(const char *pszPath, PRTLISTNODE pList)
     637{
     638    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     639    AssertPtrReturn(pList, VERR_INVALID_POINTER);
     640
     641    LogFlowFunc(("Appending to pList=%p: %s\n", pList, pszPath));
     642
     643    PDIRECTORYENTRY pNode = (PDIRECTORYENTRY)RTMemAlloc(sizeof(DIRECTORYENTRY));
     644    if (pNode == NULL)
     645        return VERR_NO_MEMORY;
     646
     647    pNode->pszPath = NULL;
     648    if (RT_SUCCESS(RTStrAAppend(&pNode->pszPath, pszPath)))
     649    {
     650        pNode->Node.pPrev = NULL;
     651        pNode->Node.pNext = NULL;
     652        RTListAppend(pList, &pNode->Node);
     653        return VINF_SUCCESS;
     654    }
     655    return VERR_NO_MEMORY;
     656}
     657
     658/**
     659 * TODO
     660 *
     661 * @return  IPRT status code.
     662 * @return  int
     663 * @param   pszDirectory
     664 * @param   pszFilter
     665 * @param   uFlags
     666 * @param   pcObjects
     667 * @param   pList
     668 */
     669int ctrlCopyDirectoryRead(const char *pszDirectory, const char *pszFilter,
     670                          uint32_t uFlags, uint32_t *pcObjects, PRTLISTNODE pList)
     671{
     672    AssertPtrReturn(pszDirectory, VERR_INVALID_POINTER);
     673    /* Filter is optional. */
     674    AssertPtrReturn(pcObjects, VERR_INVALID_POINTER);
     675    AssertPtrReturn(pList, VERR_INVALID_POINTER);
     676
     677    LogFlowFunc(("Reading directory: %s, filter: %s\n",
     678                 pszDirectory, pszFilter ? pszFilter : "<None>"));
     679
     680    PRTDIR pDir = NULL;
     681    int rc = RTDirOpenFiltered(&pDir, pszDirectory,
     682#ifdef RT_OS_WINDOWS
     683                               RTDIRFILTER_WINNT);
     684#else
     685                               RTDIRFILTER_UNIX);
     686#endif
     687    char *pszDirectoryStrip = RTStrDup(pszDirectory);
     688    if (!pszDirectoryStrip)
     689        rc = VERR_NO_MEMORY;
     690
     691    if (RT_SUCCESS(rc))
     692    {
     693        RTPathStripFilename(pszDirectoryStrip);
     694        for (;;)
     695        {
     696            RTDIRENTRY DirEntry;
     697            rc = RTDirRead(pDir, &DirEntry, NULL);
     698            if (RT_FAILURE(rc))
     699            {
     700                if (rc == VERR_NO_MORE_FILES)
     701                    rc = VINF_SUCCESS;
     702                break;
     703            }
     704            switch (DirEntry.enmType)
     705            {
     706                case RTDIRENTRYTYPE_DIRECTORY:
     707                    /* Skip "." and ".." entrires. */
     708                    if (   !strcmp(DirEntry.szName, ".")
     709                        || !strcmp(DirEntry.szName, ".."))
     710                    {
     711                        break;
     712                    }
     713                    if (uFlags & CopyFileFlag_Recursive)
     714                        rc = ctrlCopyDirectoryRead(DirEntry.szName, pszFilter,
     715                                                   uFlags, pcObjects, pList);
     716                    break;
     717
     718                case RTDIRENTRYTYPE_FILE:
     719                {
     720                    char *pszFile;
     721                    if (RTStrAPrintf(&pszFile, "%s%c%s",
     722                                     pszDirectoryStrip, RTPATH_SLASH, DirEntry.szName))
     723                    {
     724                        rc = ctrlCopyDirectoryEntryAppend(pszFile, pList);
     725                        if (RT_SUCCESS(rc))
     726                            *pcObjects = *pcObjects + 1;
     727                        RTStrFree(pszFile);
     728                    }
     729                    break;
     730                }
     731
     732                case RTDIRENTRYTYPE_SYMLINK:
     733                    if (   (uFlags & CopyFileFlag_Recursive)
     734                        && (uFlags & CopyFileFlag_FollowLinks))
     735                    {
     736                        rc = ctrlCopyDirectoryRead(DirEntry.szName, pszFilter,
     737                                                   uFlags, pcObjects, pList);
     738                    }
     739                    break;
     740
     741                default:
     742                    break;
     743            }
     744            if (RT_FAILURE(rc))
     745                break;
     746        }
     747        RTStrFree(pszDirectoryStrip);
     748    }
     749
     750    if (pDir)
     751        RTDirClose(pDir);
     752    return rc;
     753}
     754
     755/**
     756 * TODO
     757 *
     758 * @return  IPRT status code.
     759 * @param   pszSource
     760 * @param   pszDest
     761 * @param   uFlags
     762 */
     763int ctrlCopyInit(const char *pszSource, const char *pszDest, uint32_t uFlags,
     764                 uint32_t *pcObjects, PRTLISTNODE pList)
     765{
     766    AssertPtrReturn(pszSource, VERR_INVALID_PARAMETER);
     767    AssertPtrReturn(pszDest, VERR_INVALID_PARAMETER);
     768    AssertPtrReturn(pcObjects, VERR_INVALID_PARAMETER);
     769    AssertPtrReturn(pList, VERR_INVALID_PARAMETER);
     770
     771    int rc;
     772    char *pszSourceAbs = RTPathAbsDup(pszSource);
     773    if (pszSourceAbs)
     774    {
     775        if (   RTPathFilename(pszSourceAbs)
     776            && RTFileExists(pszSourceAbs)) /* We have a single file ... */
     777        {
     778            RTListInit(pList);
     779            rc = ctrlCopyDirectoryEntryAppend(pszSourceAbs, pList);
     780            *pcObjects = 1;
     781        }
     782        else /* ... or a directory. */
     783        {
     784            RTListInit(pList);
     785            rc = ctrlCopyDirectoryRead(pszSourceAbs, NULL /* Filter */,
     786                                       uFlags, pcObjects, pList);
     787            if (*pcObjects == 0)
     788                rc = VERR_NOT_FOUND;
     789        }
     790        RTStrFree(pszSourceAbs);
     791    }
     792    else
     793        rc = VERR_NO_MEMORY;
     794    return rc;
     795}
     796
     797/**
     798 * TODO
     799 *
     800 * @return  IPRT status code.
     801 */
     802void ctrlCopyDestroy(PRTLISTNODE pList)
     803{
     804    AssertPtr(pList);
     805
     806    /* Destroy file list. */
     807    PDIRECTORYENTRY pNode = RTListNodeGetFirst(pList, DIRECTORYENTRY, Node);
     808    while (pNode)
     809    {
     810        PDIRECTORYENTRY pNext = RTListNodeGetNext(&pNode->Node, DIRECTORYENTRY, Node);
     811        bool fLast = RTListNodeIsLast(pList, &pNode->Node);
     812
     813        if (pNode->pszPath)
     814            RTStrFree(pNode->pszPath);
     815        RTListNodeRemove(&pNode->Node);
     816        RTMemFree(pNode);
     817
     818        if (fLast)
     819            break;
     820
     821        pNode = pNext;
     822    }
     823}
     824
     825/**
     826 * TODO
     827 *
     828 * @return  IPRT status code.
     829 * @return  int
     830 * @param   pGuest
     831 * @param   pszSource
     832 * @param   pszDest
     833 * @param   pszUserName
     834 * @param   pszPassword
     835 * @param   uFlags
     836 */
     837int ctrlCopyFile(IGuest *pGuest, const char *pszSource, const char *pszDest,
     838                 const char *pszUserName, const char *pszPassword,
     839                 uint32_t uFlags)
     840{
     841    AssertPtrReturn(pszSource, VERR_INVALID_PARAMETER);
     842    AssertPtrReturn(pszDest, VERR_INVALID_PARAMETER);
     843    AssertPtrReturn(pszUserName, VERR_INVALID_PARAMETER);
     844    AssertPtrReturn(pszPassword, VERR_INVALID_PARAMETER);
     845
     846    int vrc = VINF_SUCCESS;
     847    ComPtr<IProgress> progress;
     848    HRESULT rc = pGuest->CopyToGuest(Bstr(pszSource).raw(), Bstr(pszDest).raw(),
     849                                     Bstr(pszUserName).raw(), Bstr(pszPassword).raw(),
     850                                     uFlags, progress.asOutParam());
     851    if (FAILED(rc))
     852    {
     853        /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
     854         * because it contains more accurate info about what went wrong. */
     855        ErrorInfo info(pGuest, COM_IIDOF(IGuest));
     856        if (info.isFullAvailable())
     857        {
     858            if (rc == VBOX_E_IPRT_ERROR)
     859                RTMsgError("%ls.", info.getText().raw());
     860            else
     861                RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode());
     862        }
     863        vrc = VERR_GENERAL_FAILURE;
     864    }
     865    else
     866    {
     867        /* Setup signal handling if cancelable. */
     868        ASSERT(progress);
     869        bool fCanceledAlready = false;
     870        BOOL fCancelable;
     871        HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
     872        if (FAILED(hrc))
     873            fCancelable = FALSE;
     874        if (fCancelable)
     875        {
     876            signal(SIGINT,   ctrlCopySignalHandler);
     877    #ifdef SIGBREAK
     878            signal(SIGBREAK, ctrlCopySignalHandler);
     879    #endif
     880        }
     881
     882        /* Wait for process to exit ... */
     883        BOOL fCompleted = FALSE;
     884        BOOL fCanceled = FALSE;
     885        while (   SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))
     886               && !fCompleted)
     887        {
     888            /* Process async cancelation */
     889            if (g_fCopyCanceled && !fCanceledAlready)
     890            {
     891                hrc = progress->Cancel();
     892                if (SUCCEEDED(hrc))
     893                    fCanceledAlready = TRUE;
     894                else
     895                    g_fCopyCanceled = false;
     896            }
     897
     898            /* Progress canceled by Main API? */
     899            if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
     900                && fCanceled)
     901            {
     902                break;
     903            }
     904        }
     905
     906        /* Undo signal handling */
     907        if (fCancelable)
     908        {
     909            signal(SIGINT,   SIG_DFL);
     910    #ifdef SIGBREAK
     911            signal(SIGBREAK, SIG_DFL);
     912    #endif
     913        }
     914
     915        if (fCanceled)
     916        {
     917            //RTPrintf("Copy operation canceled!\n");
     918        }
     919        else if (   fCompleted
     920                 && SUCCEEDED(rc))
     921        {
     922            LONG iRc = false;
     923            CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
     924            if (FAILED(iRc))
     925            {
     926                com::ProgressErrorInfo info(progress);
     927                if (   info.isFullAvailable()
     928                    || info.isBasicAvailable())
     929                {
     930                    /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
     931                     * because it contains more accurate info about what went wrong. */
     932                    if (info.getResultCode() == VBOX_E_IPRT_ERROR)
     933                        RTMsgError("%ls.", info.getText().raw());
     934                    else
     935                    {
     936                        RTMsgError("Copy operation error details:");
     937                        GluePrintErrorInfo(info);
     938                    }
     939                }
     940                else
     941                {
     942                    if (RT_FAILURE(rc))
     943                        RTMsgError("Error while looking up error code, rc=%Rrc", rc);
     944                    else
     945                        com::GluePrintRCMessage(iRc);
     946                }
     947                vrc = VERR_GENERAL_FAILURE;
     948            }
     949        }
     950    }
     951    return vrc;
     952}
     953
    619954static int handleCtrlCopyTo(HandlerArg *a)
    620955{
     
    7351070            ULONG uPID = 0;
    7361071
    737             if (fVerbose)
    738             {
    739                 if (fCopyRecursive)
    740                     RTPrintf("Recursively copying \"%s\" to \"%s\" ...\n", Utf8Source, Utf8Dest);
    741                 else
    742                     RTPrintf("Copying \"%s\" to \"%s\" ...\n", Utf8Source, Utf8Dest);
    743             }
    744 
    745             /* Do the copy. */
    746             rc = guest->CopyToGuest(Bstr(Utf8Source).raw(), Bstr(Utf8Dest).raw(),
    747                                     Bstr(Utf8UserName).raw(), Bstr(Utf8Password).raw(),
    748                                     uFlags, progress.asOutParam());
    749             if (FAILED(rc))
    750             {
    751                 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    752                  * because it contains more accurate info about what went wrong. */
    753                 ErrorInfo info(guest, COM_IIDOF(IGuest));
    754                 if (info.isFullAvailable())
    755                 {
    756                     if (rc == VBOX_E_IPRT_ERROR)
    757                         RTMsgError("%ls.", info.getText().raw());
     1072            RTLISTNODE listToCopy;
     1073            uint32_t cObjects = 0;
     1074            int vrc = ctrlCopyInit(Utf8Source.c_str(), Utf8Dest.c_str(), uFlags,
     1075                                   &cObjects, &listToCopy);
     1076            if (RT_FAILURE(vrc))
     1077            {
     1078                switch (vrc)
     1079                {
     1080                    case VERR_NOT_FOUND:
     1081                        RTMsgError("No files to copy found!\n");
     1082                        break;
     1083
     1084                    case VERR_PATH_NOT_FOUND:
     1085                        RTMsgError("Source path \"%s\" not found!\n", Utf8Source.c_str());
     1086                        break;
     1087
     1088                    default:
     1089                        RTMsgError("Failed to initialize, rc=%Rrc\n", vrc);
     1090                        break;
     1091                }
     1092            }
     1093            else
     1094            {
     1095                if (fVerbose)
     1096                {
     1097                    if (fCopyRecursive)
     1098                        RTPrintf("Recursively copying \"%s\" to \"%s\" (%u file(s)) ...\n",
     1099                                 Utf8Source.c_str(), Utf8Dest.c_str(), cObjects);
    7581100                    else
    759                         RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode());
    760                 }
    761                 break;
    762             }
    763             else
    764             {
    765                 /* Setup signal handling if cancelable. */
    766                 ASSERT(progress);
    767                 bool fCanceledAlready = false;
    768                 BOOL fCancelable;
    769                 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
    770                 if (FAILED(hrc))
    771                     fCancelable = FALSE;
    772                 if (fCancelable)
    773                 {
    774                     signal(SIGINT,   ctrlCopySignalHandler);
    775             #ifdef SIGBREAK
    776                     signal(SIGBREAK, ctrlCopySignalHandler);
    777             #endif
    778                 }
    779 
    780                 /* Wait for process to exit ... */
    781                 BOOL fCompleted = FALSE;
    782                 BOOL fCanceled = FALSE;
    783                 while (   SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))
    784                        && !fCompleted)
    785                 {
    786                     /* Process async cancelation */
    787                     if (g_fCopyCanceled && !fCanceledAlready)
    788                     {
    789                         hrc = progress->Cancel();
    790                         if (SUCCEEDED(hrc))
    791                             fCanceledAlready = TRUE;
    792                         else
    793                             g_fCopyCanceled = false;
    794                     }
    795 
    796                     /* Progress canceled by Main API? */
    797                     if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
    798                         && fCanceled)
    799                     {
    800                         break;
    801                     }
    802                 }
    803 
    804                 /* Undo signal handling */
    805                 if (fCancelable)
    806                 {
    807                     signal(SIGINT,   SIG_DFL);
    808             #ifdef SIGBREAK
    809                     signal(SIGBREAK, SIG_DFL);
    810             #endif
    811                 }
    812 
    813                 if (fCanceled)
    814                 {
    815                     if (fVerbose)
    816                         RTPrintf("Copy operation canceled!\n");
    817                 }
    818                 else if (   fCompleted
    819                          && SUCCEEDED(rc))
    820                 {
    821                     LONG iRc = false;
    822                     CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    823                     if (FAILED(iRc))
    824                     {
    825                         com::ProgressErrorInfo info(progress);
    826                         if (   info.isFullAvailable()
    827                             || info.isBasicAvailable())
    828                         {
    829                             /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    830                              * because it contains more accurate info about what went wrong. */
    831                             if (info.getResultCode() == VBOX_E_IPRT_ERROR)
    832                                 RTMsgError("%ls.", info.getText().raw());
    833                             else
    834                             {
    835                                 RTMsgError("Copy operation error details:");
    836                                 GluePrintErrorInfo(info);
    837                             }
    838                         }
    839                         else
    840                         {
    841                             if (RT_FAILURE(rc))
    842                                 RTMsgError("Error while looking up error code, rc=%Rrc", rc);
    843                             else
    844                                 com::GluePrintRCMessage(iRc);
    845                         }
    846                     }
    847                     else if (fVerbose)
    848                     {
     1101                        RTPrintf("Copying \"%s\" to \"%s\" (%u file(s)) ...\n",
     1102                                 Utf8Source.c_str(), Utf8Dest.c_str(), cObjects);
     1103                }
     1104
     1105                if (RT_SUCCESS(vrc))
     1106                {
     1107                    PDIRECTORYENTRY pNode;
     1108                    uint32_t uCurObject = 0;
     1109                    RTListForEach(&listToCopy, pNode, DIRECTORYENTRY, Node)
     1110                    {
     1111                        if (fVerbose)
     1112                            RTPrintf("Copying \"%s\" (%u/%u) ...\n",
     1113                                     pNode->pszPath, uCurObject + 1, cObjects + 1);
     1114                        vrc = ctrlCopyFile(guest, pNode->pszPath, Utf8Dest.c_str(),
     1115                                           Utf8UserName.c_str(), Utf8Password.c_str(), uFlags);
     1116                        if (RT_FAILURE(vrc))
     1117                            break;
     1118                    }
     1119                    if (RT_SUCCESS(vrc) && fVerbose)
    8491120                        RTPrintf("Copy operation successful!\n");
    850                     }
    851                 }
    852                 else
    853                 {
    854                     if (fVerbose)
    855                         RTPrintf("Copy operation aborted!\n");
    856                 }
     1121                }
     1122                ctrlCopyDestroy(&listToCopy);
    8571123            }
    8581124            a->session->UnlockMachine();
     
    8611127    return SUCCEEDED(rc) ? 0 : 1;
    8621128}
    863 #endif
    8641129
    8651130/**
     
    8841149        return handleCtrlExecProgram(&arg);
    8851150    }
    886 #ifdef VBOX_WITH_COPYTOGUEST
    8871151    else if (   strcmp(a->argv[0], "copyto")  == 0
    8881152             || strcmp(a->argv[0], "copy_to") == 0)
     
    8901154        return handleCtrlCopyTo(&arg);
    8911155    }
    892 #endif
    8931156
    8941157    /* default: */
  • trunk/src/VBox/Main/GuestImpl.cpp

    r33301 r33411  
    3333#endif
    3434#include <iprt/cpp/utils.h>
    35 #include <iprt/dir.h>
    3635#include <iprt/file.h>
    3736#include <iprt/getopt.h>
     
    18171816}
    18181817
    1819 #ifdef VBOX_WITH_COPYTOGUEST
    1820 int Guest::directoryEntryAppend(const char *pszPath, PRTLISTNODE pList)
    1821 {
    1822     using namespace guestControl;
    1823 
    1824     AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
    1825     AssertPtrReturn(pList, VERR_INVALID_POINTER);
    1826 
    1827     LogFlowFunc(("Appending to pList=%p: %s\n", pList, pszPath));
    1828 
    1829     VBoxGuestDirEntry *pNode = (VBoxGuestDirEntry*)RTMemAlloc(sizeof(VBoxGuestDirEntry));
    1830     if (pNode == NULL)
    1831         return VERR_NO_MEMORY;
    1832 
    1833     pNode->pszPath = NULL;
    1834     if (RT_SUCCESS(RTStrAAppend(&pNode->pszPath, pszPath)))
    1835     {
    1836         pNode->Node.pPrev = NULL;
    1837         pNode->Node.pNext = NULL;
    1838         RTListAppend(pList, &pNode->Node);
    1839         return VINF_SUCCESS;
    1840     }
    1841     return VERR_NO_MEMORY;
    1842 }
    1843 
    1844 int Guest::directoryRead(const char *pszDirectory, const char *pszFilter,
    1845                          ULONG uFlags, ULONG *pcObjects, PRTLISTNODE pList)
    1846 {
    1847     using namespace guestControl;
    1848 
    1849     AssertPtrReturn(pszDirectory, VERR_INVALID_POINTER);
    1850     /* Filter is optional. */
    1851     AssertPtrReturn(pcObjects, VERR_INVALID_POINTER);
    1852     AssertPtrReturn(pList, VERR_INVALID_POINTER);
    1853 
    1854     LogFlowFunc(("Reading directory: %s, filter: %s\n",
    1855                  pszDirectory, pszFilter ? pszFilter : "<None>"));
    1856 
    1857     PRTDIR pDir = NULL;
    1858     int rc = RTDirOpenFiltered(&pDir, pszDirectory,
    1859 #ifdef RT_OS_WINDOWS
    1860                                RTDIRFILTER_WINNT);
    1861 #else
    1862                                RTDIRFILTER_UNIX);
    1863 #endif
    1864     char *pszDirectoryStrip = RTStrDup(pszDirectory);
    1865     if (!pszDirectoryStrip)
    1866         rc = VERR_NO_MEMORY;
    1867 
    1868     if (RT_SUCCESS(rc))
    1869     {
    1870         RTPathStripFilename(pszDirectoryStrip);
    1871         for (;;)
    1872         {
    1873             RTDIRENTRY DirEntry;
    1874             rc = RTDirRead(pDir, &DirEntry, NULL);
    1875             if (RT_FAILURE(rc))
    1876             {
    1877                 if (rc == VERR_NO_MORE_FILES)
    1878                     rc = VINF_SUCCESS;
    1879                 break;
    1880             }
    1881             switch (DirEntry.enmType)
    1882             {
    1883                 case RTDIRENTRYTYPE_DIRECTORY:
    1884                     /* Skip "." and ".." entrires. */
    1885                     if (   !strcmp(DirEntry.szName, ".")
    1886                         || !strcmp(DirEntry.szName, ".."))
    1887                     {
    1888                         break;
    1889                     }
    1890                     if (uFlags & CopyFileFlag_Recursive)
    1891                         rc = directoryRead(DirEntry.szName, pszFilter,
    1892                                            uFlags, pcObjects, pList);
    1893                     break;
    1894 
    1895                 case RTDIRENTRYTYPE_FILE:
    1896                 {
    1897                     char *pszFile;
    1898                     if (RTStrAPrintf(&pszFile, "%s%c%s",
    1899                                      pszDirectoryStrip, RTPATH_SLASH, DirEntry.szName))
    1900                     {
    1901                         rc = directoryEntryAppend(pszFile, pList);
    1902                         if (RT_SUCCESS(rc))
    1903                             *pcObjects = *pcObjects + 1;
    1904                         RTStrFree(pszFile);
    1905                     }
    1906                     break;
    1907                 }
    1908 
    1909                 case RTDIRENTRYTYPE_SYMLINK:
    1910                     if (   (uFlags & CopyFileFlag_Recursive)
    1911                         && (uFlags & CopyFileFlag_FollowLinks))
    1912                     {
    1913                         rc = directoryRead(DirEntry.szName, pszFilter,
    1914                                            uFlags, pcObjects, pList);
    1915                     }
    1916                     break;
    1917 
    1918                 default:
    1919                     break;
    1920             }
    1921             if (RT_FAILURE(rc))
    1922                 break;
    1923         }
    1924         RTStrFree(pszDirectoryStrip);
    1925     }
    1926 
    1927     if (pDir)
    1928         RTDirClose(pDir);
    1929     return rc;
    1930 }
    1931 #endif
    1932 
    19331818/** @todo For having a progress object which actually reports something,
    19341819  *       the actual copy loop (see below) needs to go to some worker thread
     
    19421827    ReturnComNotImplemented();
    19431828#else  /* VBOX_WITH_GUEST_CONTROL */
    1944 #ifndef VBOX_WITH_COPYTOGUEST
    1945     ReturnComNotImplemented();
    1946 #else
    19471829    using namespace guestControl;
    19481830
     
    22652147    }
    22662148    return rc;
    2267 #endif /* VBOX_WITH_COPYTOGUEST */
    22682149#endif /* VBOX_WITH_GUEST_CONTROL */
    22692150}
  • trunk/src/VBox/Main/include/GuestImpl.h

    r33301 r33411  
    152152    typedef std::map< uint32_t, GuestProcess >::const_iterator GuestProcessMapIterConst;
    153153
    154 #ifdef VBOX_WITH_COPYTOGUEST
    155     /*
    156      * Structure holding a directory entry.
    157      */
    158     struct VBoxGuestDirEntry
    159     {
    160         char       *pszPath;
    161         RTLISTNODE  Node;
    162     };
    163 
    164154    int directoryEntryAppend(const char *pszPath, PRTLISTNODE pList);
    165155    int directoryRead(const char *pszDirectory, const char *pszFilter, ULONG uFlags, ULONG *pcObjects, PRTLISTNODE pList);
    166 #endif
    167156
    168157    int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv);
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