VirtualBox

Ignore:
Timestamp:
Dec 1, 2010 10:13:08 AM (14 years ago)
Author:
vboxsync
Message:

Guest Copy/CreateDirectory: Bugfixes, improved error handling.

File:
1 edited

Legend:

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

    r34465 r34552  
    172172}
    173173
    174 static int ctrlPrintError(ComPtr<IUnknown> object, const GUID &aIID)
    175 {
    176     com::ErrorInfo info(object, aIID);
    177     if (   info.isFullAvailable()
    178         || info.isBasicAvailable())
     174static int ctrlPrintError(com::ErrorInfo &errorInfo)
     175{
     176    if (   errorInfo.isFullAvailable()
     177        || errorInfo.isBasicAvailable())
    179178    {
    180179        /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
    181180         * because it contains more accurate info about what went wrong. */
    182         if (info.getResultCode() == VBOX_E_IPRT_ERROR)
    183             RTMsgError("%ls.", info.getText().raw());
     181        if (errorInfo.getResultCode() == VBOX_E_IPRT_ERROR)
     182            RTMsgError("%ls.", errorInfo.getText().raw());
    184183        else
    185184        {
    186185            RTMsgError("Error details:");
    187             GluePrintErrorInfo(info);
     186            GluePrintErrorInfo(errorInfo);
    188187        }
    189188        return VERR_GENERAL_FAILURE; /** @todo */
     
    191190    AssertMsgFailedReturn(("Object has indicated no error!?\n"),
    192191                          VERR_INVALID_PARAMETER);
     192}
     193
     194static int ctrlPrintProgressError(ComPtr<IProgress> progress)
     195{
     196    return ctrlPrintError(com::ProgressErrorInfo(progress));
    193197}
    194198
     
    430434        if (FAILED(rc))
    431435        {
    432             vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
     436            vrc = ctrlPrintError(com::ErrorInfo(guest, COM_IIDOF(IGuest)));
    433437        }
    434438        else
     
    486490                        if (FAILED(rc))
    487491                        {
    488                             vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
     492                            vrc = ctrlPrintError(com::ErrorInfo(guest, COM_IIDOF(IGuest)));
    489493
    490494                            cbOutputData = 0;
     
    560564                         && SUCCEEDED(rc))
    561565                {
    562                     LONG iRc = false;
     566                    LONG iRc;
    563567                    CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    564568                    if (FAILED(iRc))
    565569                    {
    566                         vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
     570                        vrc = ctrlPrintProgressError(progress);
    567571                    }
    568572                    else if (fVerbose)
     
    590594
    591595/**
    592  * Appends a new to-copy object to a copy list.
     596 * Appends a new file/directory entry to a given list.
    593597 *
    594598 * @return  IPRT status code.
    595  * @param   pszFileSource       Full qualified source path of file to copy.
    596  * @param   pszFileDest         Full qualified destination path.
     599 * @param   pszFileSource       Full qualified source path of file to copy (optional).
     600 * @param   pszFileDest         Full qualified destination path (optional).
    597601 * @param   pList               Copy list used for insertion.
    598602 */
    599 static int ctrlCopyDirectoryEntryAppend(const char *pszFileSource, const char *pszFileDest,
    600                                         PRTLISTNODE pList)
    601 {
    602     AssertPtrReturn(pszFileSource, VERR_INVALID_POINTER);
    603     AssertPtrReturn(pszFileDest, VERR_INVALID_POINTER);
     603static int ctrlDirectoryEntryAppend(const char *pszFileSource, const char *pszFileDest,
     604                                    PRTLISTNODE pList)
     605{
    604606    AssertPtrReturn(pList, VERR_INVALID_POINTER);
     607    AssertReturn(pszFileSource || pszFileDest, VERR_INVALID_PARAMETER);
    605608
    606609    PDIRECTORYENTRY pNode = (PDIRECTORYENTRY)RTMemAlloc(sizeof(DIRECTORYENTRY));
     
    608611        return VERR_NO_MEMORY;
    609612
    610     pNode->pszSourcePath = RTStrDup(pszFileSource);
    611     pNode->pszDestPath = RTStrDup(pszFileDest);
    612     if (   !pNode->pszSourcePath
    613         || !pNode->pszDestPath)
    614     {
    615         return VERR_NO_MEMORY;
     613    pNode->pszSourcePath = NULL;
     614    pNode->pszDestPath = NULL;
     615
     616    if (pszFileSource)
     617    {
     618        pNode->pszSourcePath = RTStrDup(pszFileSource);
     619        AssertPtrReturn(pNode->pszSourcePath, VERR_NO_MEMORY);
     620    }
     621    if (pszFileDest)
     622    {
     623        pNode->pszDestPath = RTStrDup(pszFileDest);
     624        AssertPtrReturn(pNode->pszDestPath, VERR_NO_MEMORY);
    616625    }
    617626
     
    621630    return VINF_SUCCESS;
    622631}
     632
     633/**
     634 * Destroys a directory list.
     635 *
     636 * @param   pList               Pointer to list to destroy.
     637 */
     638static void ctrlDirectoryListDestroy(PRTLISTNODE pList)
     639{
     640    AssertPtr(pList);
     641
     642    /* Destroy file list. */
     643    PDIRECTORYENTRY pNode = RTListGetFirst(pList, DIRECTORYENTRY, Node);
     644    while (pNode)
     645    {
     646        PDIRECTORYENTRY pNext = RTListNodeGetNext(&pNode->Node, DIRECTORYENTRY, Node);
     647        bool fLast = RTListNodeIsLast(pList, &pNode->Node);
     648
     649        if (pNode->pszSourcePath)
     650            RTStrFree(pNode->pszSourcePath);
     651        if (pNode->pszDestPath)
     652            RTStrFree(pNode->pszDestPath);
     653        RTListNodeRemove(&pNode->Node);
     654        RTMemFree(pNode);
     655
     656        if (fLast)
     657            break;
     658
     659        pNode = pNext;
     660    }
     661}
     662
    623663
    624664/**
     
    743783                        if (RT_SUCCESS(rc))
    744784                        {
    745                             rc = ctrlCopyDirectoryEntryAppend(pszFileSource, pszFileDest, pList);
     785                            rc = ctrlDirectoryEntryAppend(pszFileSource, pszFileDest, pList);
    746786                            if (RT_SUCCESS(rc))
    747787                                *pcObjects = *pcObjects + 1;
     
    819859                {
    820860                    RTListInit(pList);
    821                     rc = ctrlCopyDirectoryEntryAppend(pszSourceAbs, pszDestAbs, pList);
     861                    rc = ctrlDirectoryEntryAppend(pszSourceAbs, pszDestAbs, pList);
    822862                    *pcObjects = 1;
    823863                }
     
    900940        rc = VERR_NO_MEMORY;
    901941    return rc;
    902 }
    903 
    904 /**
    905  * Destroys a copy list.
    906  */
    907 static void ctrlCopyDestroy(PRTLISTNODE pList)
    908 {
    909     AssertPtr(pList);
    910 
    911     /* Destroy file list. */
    912     PDIRECTORYENTRY pNode = RTListGetFirst(pList, DIRECTORYENTRY, Node);
    913     while (pNode)
    914     {
    915         PDIRECTORYENTRY pNext = RTListNodeGetNext(&pNode->Node, DIRECTORYENTRY, Node);
    916         bool fLast = RTListNodeIsLast(pList, &pNode->Node);
    917 
    918         if (pNode->pszSourcePath)
    919             RTStrFree(pNode->pszSourcePath);
    920         if (pNode->pszDestPath)
    921             RTStrFree(pNode->pszDestPath);
    922         RTListNodeRemove(&pNode->Node);
    923         RTMemFree(pNode);
    924 
    925         if (fLast)
    926             break;
    927 
    928         pNode = pNext;
    929     }
    930942}
    931943
     
    957969    if (FAILED(rc))
    958970    {
    959         vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest));
     971        vrc = ctrlPrintError(com::ErrorInfo(pGuest, COM_IIDOF(IGuest)));
    960972    }
    961973    else
     
    10041016                 && SUCCEEDED(rc))
    10051017        {
    1006             LONG iRc = false;
     1018            LONG iRc;
    10071019            CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    10081020            if (FAILED(iRc))
    1009                 vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
     1021                vrc = ctrlPrintProgressError(progress);
    10101022        }
    10111023    }
     
    11061118                }
    11071119                uNoOptionIdx++;
     1120                if (uNoOptionIdx == UINT32_MAX)
     1121                {
     1122                    RTMsgError("Too many files specified! Aborting.\n");
     1123                    vrc = VERR_TOO_MUCH_DATA;
     1124                }
    11081125                break;
    11091126            }
     
    11941211                    RTStrFree(pszDestPath);
    11951212                    if (FAILED(rc))
    1196                         vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
     1213                        vrc = ctrlPrintError(com::ErrorInfo(guest, COM_IIDOF(IGuest)));
    11971214                    else
    11981215                    {
     
    12171234                    RTPrintf("Copy operation successful!\n");
    12181235            }
    1219             ctrlCopyDestroy(&listToCopy);
     1236            ctrlDirectoryListDestroy(&listToCopy);
    12201237        }
    12211238        ctrlUninitVM(a);
     
    12511268    RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
    12521269
    1253     Utf8Str Utf8Directory(a->argv[1]);
    12541270    Utf8Str Utf8UserName;
    12551271    Utf8Str Utf8Password;
     
    12581274    bool fVerbose = false;
    12591275
     1276    RTLISTNODE listDirs;
     1277    uint32_t uNumDirs = 0;
     1278    RTListInit(&listDirs);
     1279
    12601280    int vrc = VINF_SUCCESS;
    12611281    bool fUsageOK = true;
     
    12921312            case VINF_GETOPT_NOT_OPTION:
    12931313            {
    1294                 Utf8Directory = ValueUnion.psz;
     1314                vrc = ctrlDirectoryEntryAppend(NULL,              /* No source given */
     1315                                               ValueUnion.psz,    /* Destination */
     1316                                               &listDirs);
     1317                if (RT_SUCCESS(vrc))
     1318                {
     1319                    uNumDirs++;
     1320                    if (uNumDirs == UINT32_MAX)
     1321                    {
     1322                        RTMsgError("Too many directories specified! Aborting.\n");
     1323                        vrc = VERR_TOO_MUCH_DATA;
     1324                    }
     1325                }
    12951326                break;
    12961327            }
     
    13041335        return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters");
    13051336
    1306     if (Utf8Directory.isEmpty())
     1337    if (!uNumDirs)
    13071338        return errorSyntax(USAGE_GUESTCONTROL,
    13081339                           "No directory to create specified!");
     
    13171348    if (RT_SUCCESS(vrc))
    13181349    {
    1319         ComPtr<IProgress> progress;
    1320         rc = guest->CreateDirectory(Bstr(Utf8Directory).raw(),
    1321                                     Bstr(Utf8UserName).raw(), Bstr(Utf8Password).raw(),
    1322                                     uMode, uFlags, progress.asOutParam());
    1323         if (FAILED(rc))
    1324             vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
    1325         else
    1326         {
    1327             /* Setup signal handling if cancelable. */
    1328             ASSERT(progress);
    1329             bool fCanceledAlready = false;
    1330             BOOL fCancelable;
    1331             rc = progress->COMGETTER(Cancelable)(&fCancelable);
     1350        if (fVerbose && uNumDirs > 1)
     1351            RTPrintf("Creating %ld directories ...\n", uNumDirs);
     1352
     1353        PDIRECTORYENTRY pNode;
     1354        RTListForEach(&listDirs, pNode, DIRECTORYENTRY, Node)
     1355        {
     1356            if (fVerbose)
     1357                RTPrintf("Creating directory \"%s\" ...\n", pNode->pszDestPath);
     1358
     1359            ComPtr<IProgress> progress;
     1360            rc = guest->CreateDirectory(Bstr(pNode->pszDestPath).raw(),
     1361                                        Bstr(Utf8UserName).raw(), Bstr(Utf8Password).raw(),
     1362                                        uMode, uFlags, progress.asOutParam());
    13321363            if (FAILED(rc))
    1333                 fCancelable = FALSE;
    1334             if (fCancelable)
    1335                 ctrlSignalHandlerInstall();
    1336 
    1337             /* Wait for process to exit ... */
    1338             BOOL fCompleted = FALSE;
    1339             BOOL fCanceled = FALSE;
    1340             while (   SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))
    1341                    && !fCompleted)
    1342             {
    1343                 /* Process async cancelation */
    1344                 if (g_fGuestCtrlCanceled && !fCanceledAlready)
    1345                 {
    1346                     rc = progress->Cancel();
    1347                     if (SUCCEEDED(rc))
    1348                         fCanceledAlready = TRUE;
    1349                     else
    1350                         g_fGuestCtrlCanceled = false;
    1351                 }
    1352 
    1353                 /* Progress canceled by Main API? */
    1354                 if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
    1355                     && fCanceled)
    1356                 {
    1357                     break;
    1358                 }
    1359             }
    1360 
    1361             /* Undo signal handling. */
    1362             if (fCancelable)
    1363                 ctrlSignalHandlerUninstall();
    1364 
    1365             if (fCanceled)
    1366             {
    1367                 //RTPrintf("Copy operation canceled!\n");
    1368             }
    1369             else if (   fCompleted
    1370                      && SUCCEEDED(rc))
    1371             {
    1372                 LONG iRc = false;
     1364                vrc = ctrlPrintError(com::ErrorInfo(guest, COM_IIDOF(IGuest)));
     1365            else
     1366            {
     1367                LONG iRc;
    13731368                CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    13741369                if (FAILED(iRc))
    1375                     vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
     1370                {
     1371                      vrc = ctrlPrintProgressError(progress);
     1372                      break;
     1373                }
     1374                else if (fVerbose)
     1375                    RTPrintf("Directory created: %s\n", pNode->pszDestPath);
    13761376            }
    13771377        }
    13781378        ctrlUninitVM(a);
    13791379    }
     1380    ctrlDirectoryListDestroy(&listDirs);
    13801381
    13811382    if (RT_FAILURE(vrc))
     
    14721473                                                    progress.asOutParam()));
    14731474            if (FAILED(rc))
    1474                 vrc = ctrlPrintError(guest, COM_IIDOF(IGuest));
     1475                vrc = ctrlPrintError(com::ErrorInfo(guest, COM_IIDOF(IGuest)));
    14751476            else
    14761477            {
    14771478                rc = showProgress(progress);
    14781479                if (FAILED(rc))
    1479                     vrc = ctrlPrintError(progress, COM_IIDOF(IProgress));
     1480                    vrc = ctrlPrintProgressError(progress);
    14801481                else if (fVerbose)
    14811482                    RTPrintf("Guest Additions installer successfully copied and started.\n");
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