VirtualBox

Changeset 34831 in vbox


Ignore:
Timestamp:
Dec 8, 2010 1:37:55 PM (14 years ago)
Author:
vboxsync
Message:

GuestControl/Copy: Use a thread (guest task) for displaying real progress and fixes for proper cancellation. Raised send buffers to _1M.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

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

    r34769 r34831  
    201201static int ctrlPrintProgressError(ComPtr<IProgress> progress)
    202202{
    203     com::ProgressErrorInfo ErrInfo(progress);
    204     return ctrlPrintError(ErrInfo);
     203    int rc;
     204    BOOL fCanceled;
     205    if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
     206        && fCanceled)
     207    {
     208        rc = VERR_CANCELLED;
     209    }
     210    else
     211    {
     212        com::ProgressErrorInfo ErrInfo(progress);
     213        rc = ctrlPrintError(ErrInfo);
     214    }
     215    return rc;
    205216}
    206217
     
    954965 * @return  IPRT status code.
    955966 * @param   pGuest          IGuest interface pointer.
     967 * @param   fVerbose        Verbose flag.
    956968 * @param   pszSource       Source path of existing host file to copy.
    957969 * @param   pszDest         Destination path on guest to copy the file to.
     
    960972 * @param   uFlags          Copy flags.
    961973 */
    962 static int ctrlCopyFileToGuest(IGuest *pGuest, const char *pszSource, const char *pszDest,
     974static int ctrlCopyFileToGuest(IGuest *pGuest, bool fVerbose, const char *pszSource, const char *pszDest,
    963975                               const char *pszUserName, const char *pszPassword,
    964976                               uint32_t uFlags)
     
    978990    else
    979991    {
    980         /* Setup signal handling if cancelable. */
    981         ASSERT(progress);
    982         bool fCanceledAlready = false;
    983         BOOL fCancelable = FALSE;
    984         HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);
    985         if (fCancelable)
    986             ctrlSignalHandlerInstall();
    987 
    988         /* Wait for process to exit ... */
    989         BOOL fCompleted = FALSE;
    990         BOOL fCanceled = FALSE;
    991         while (   SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))
    992                && !fCompleted)
    993         {
    994             /* Process async cancelation */
    995             if (g_fGuestCtrlCanceled && !fCanceledAlready)
    996             {
    997                 hrc = progress->Cancel();
    998                 if (SUCCEEDED(hrc))
    999                     fCanceledAlready = TRUE;
    1000                 else
    1001                     g_fGuestCtrlCanceled = false;
    1002             }
    1003 
    1004             /* Progress canceled by Main API? */
    1005             if (   SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled)))
    1006                 && fCanceled)
    1007             {
    1008                 break;
    1009             }
    1010         }
    1011 
    1012         /* Undo signal handling. */
    1013         if (fCancelable)
    1014             ctrlSignalHandlerUninstall();
    1015 
    1016         if (fCanceled)
    1017         {
    1018             /* Nothing to do here right now. */
    1019         }
    1020         else if (   fCompleted
    1021                  && SUCCEEDED(rc))
    1022         {
    1023             LONG iRc;
    1024             CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    1025             if (FAILED(iRc))
    1026                 vrc = ctrlPrintProgressError(progress);
    1027         }
     992        rc = showProgress(progress);
     993        if (FAILED(rc))
     994            vrc = ctrlPrintProgressError(progress);
    1028995    }
    1029996    return vrc;
     
    12081175                        /* Finally copy the desired file (if no dry run selected). */
    12091176                        if (!fDryRun)
    1210                             vrc = ctrlCopyFileToGuest(guest, pNode->pszSourcePath, pNode->pszDestPath,
     1177                            vrc = ctrlCopyFileToGuest(guest, fVerbose, pNode->pszSourcePath, pNode->pszDestPath,
    12111178                                                      Utf8UserName.c_str(), Utf8Password.c_str(), uFlags);
    12121179                    }
  • trunk/src/VBox/Main/GuestImpl.cpp

    r34760 r34831  
    3131#ifdef VBOX_WITH_GUEST_CONTROL
    3232# include <VBox/com/array.h>
     33# include <VBox/com/ErrorInfo.h>
    3334#endif
    3435#include <iprt/cpp/utils.h>
     
    5455    enum TaskType
    5556    {
     57        /** Copies a file to the guest. */
     58        CopyFile = 50,
     59
    5660        /** Update Guest Additions by directly copying the required installer
    5761         *  off the .ISO file, transfer it to the guest and execute the installer
     
    7276    static int uploadProgress(unsigned uPercent, void *pvUser);
    7377
     78    static HRESULT setProgressErrorInfo(HRESULT hr, ComObjPtr<Progress> pProgress, const char * pszText, ...);
     79    static HRESULT setProgressErrorInfo(HRESULT hr, ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest);
     80
    7481    TaskType taskType;
    7582    Guest *pGuest;
     
    7986    /* Task data. */
    8087    Utf8Str strSource;
    81     ULONG uFlags;
     88    Utf8Str strDest;
     89    Utf8Str strUserName;
     90    Utf8Str strPassword;
     91    ULONG   uFlags;
    8292};
    8393
     
    110120    {
    111121#ifdef VBOX_WITH_GUEST_CONTROL
     122        case TaskGuest::CopyFile:
     123        {
     124            rc = pGuest->taskCopyFile(task.get());
     125            break;
     126        }
    112127        case TaskGuest::UpdateGuestAdditions:
    113128        {
     
    144159}
    145160
     161/* static */
     162HRESULT Guest::TaskGuest::setProgressErrorInfo(HRESULT hr, ComObjPtr<Progress> pProgress, const char *pszText, ...)
     163{
     164    BOOL fCanceled;
     165    BOOL fCompleted;
     166    if (   SUCCEEDED(pProgress->COMGETTER(Canceled(&fCanceled)))
     167        && !fCanceled
     168        && SUCCEEDED(pProgress->COMGETTER(Completed(&fCompleted)))
     169        && !fCompleted)
     170    {
     171        va_list va;
     172        va_start(va, pszText);
     173        HRESULT hr2 = pProgress->notifyComplete(hr,
     174                                                COM_IIDOF(IGuest),
     175                                                Guest::getStaticComponentName(),
     176                                                va);
     177        va_end(va);
     178        if (hr2 == S_OK) /* If unable to retrieve error, return input error. */
     179            hr2 = hr;
     180        return hr2;
     181    }
     182    return S_OK;
     183}
     184
     185/* static */
     186HRESULT Guest::TaskGuest::setProgressErrorInfo(HRESULT hr, ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest)
     187{
     188    return setProgressErrorInfo(hr, pProgress,
     189                                Utf8Str(com::ErrorInfo((IGuest*)pGuest, COM_IIDOF(IGuest)).getText()).c_str());
     190}
     191
    146192#ifdef VBOX_WITH_GUEST_CONTROL
     193HRESULT Guest::taskCopyFile(TaskGuest *aTask)
     194{
     195    LogFlowFuncEnter();
     196
     197    AutoCaller autoCaller(this);
     198    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     199
     200    /*
     201     * Do *not* take a write lock here since we don't (and won't)
     202     * touch any class-specific data (of IGuest) here - only the member functions
     203     * which get called here can do that.
     204     */
     205
     206    HRESULT rc = S_OK;
     207
     208    try
     209    {
     210        Guest *pGuest = aTask->pGuest;
     211        AssertPtr(pGuest);
     212
     213        /* Does our source file exist? */
     214        if (!RTFileExists(aTask->strSource.c_str()))
     215        {
     216            /* Since this task runs in another thread than the main Guest object
     217             * we cannot rely on notifyComplete's internal lookup - so do this ourselves. */
     218            rc = VBOX_E_IPRT_ERROR;
     219            aTask->progress->notifyComplete(rc,
     220                                            COM_IIDOF(IGuest),
     221                                            Guest::getStaticComponentName(),
     222                                            Guest::tr("Source file \"%s\" does not exist"), aTask->strSource.c_str());
     223        }
     224        else
     225        {
     226            RTFILE fileSource;
     227            int vrc = RTFileOpen(&fileSource, aTask->strSource.c_str(),
     228                                 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
     229            if (RT_FAILURE(vrc))
     230            {
     231                rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
     232                                                     Guest::tr("Could not open source file \"%s\" for reading (%Rrc)"),
     233                                                     aTask->strSource.c_str(),  vrc);
     234            }
     235            else
     236            {
     237                uint64_t cbSize;
     238                vrc = RTFileGetSize(fileSource, &cbSize);
     239                if (RT_FAILURE(vrc))
     240                {
     241                    rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
     242                                                         Guest::tr("Could not query file size of \"%s\" (%Rrc)"),
     243                                                         aTask->strSource.c_str(), vrc);
     244                }
     245                else
     246                {
     247                    com::SafeArray<IN_BSTR> args;
     248                    com::SafeArray<IN_BSTR> env;
     249
     250                    /*
     251                     * Prepare tool command line.
     252                     */
     253                    char szOutput[RTPATH_MAX];
     254                    if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", aTask->strDest.c_str()) <= sizeof(szOutput) - 1)
     255                    {
     256                        /*
     257                         * Normalize path slashes, based on the detected guest.
     258                         */
     259                        Utf8Str osType = mData.mOSTypeId;
     260                        if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
     261                            || osType.contains("Windows", Utf8Str::CaseInsensitive))
     262                        {
     263                            /* We have a Windows guest. */
     264                            RTPathChangeToDosSlashes(szOutput, true /* Force conversion. */);
     265                        }
     266                        else /* ... or something which isn't from Redmond ... */
     267                        {
     268                            RTPathChangeToUnixSlashes(szOutput, true /* Force conversion. */);
     269                        }
     270
     271                        args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */
     272                        args.push_back(Bstr(szOutput).raw());             /* We want to write a file ... */
     273                    }
     274                    else
     275                    {
     276                        rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
     277                                                             Guest::tr("Error preparing command line"));
     278                    }
     279
     280                    ComPtr<IProgress> execProgress;
     281                    ULONG uPID;
     282                    if (SUCCEEDED(rc))
     283                    {
     284                        LogRel(("Copying file \"%s\" to guest \"%s\" (%u bytes) ...\n",
     285                                aTask->strSource.c_str(), aTask->strDest.c_str(), cbSize));
     286                        /*
     287                         * Okay, since we gathered all stuff we need until now to start the
     288                         * actual copying, start the guest part now.
     289                         */
     290                        rc = pGuest->ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
     291                                                      ExecuteProcessFlag_Hidden
     292                                                    | ExecuteProcessFlag_WaitForProcessStartOnly,
     293                                                    ComSafeArrayAsInParam(args),
     294                                                    ComSafeArrayAsInParam(env),
     295                                                    Bstr(aTask->strUserName).raw(),
     296                                                    Bstr(aTask->strPassword).raw(),
     297                                                    5 * 1000 /* Wait 5s for getting the process started. */,
     298                                                    &uPID, execProgress.asOutParam());
     299                        if (FAILED(rc))
     300                            rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest);
     301                    }
     302
     303                    if (SUCCEEDED(rc))
     304                    {
     305                        BOOL fCompleted = FALSE;
     306                        BOOL fCanceled = FALSE;
     307
     308                        size_t cbToRead = cbSize;
     309                        size_t cbTransfered = 0;
     310                        size_t cbRead;
     311                        SafeArray<BYTE> aInputData(_1M);
     312                        while (   SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted)))
     313                               && !fCompleted)
     314                        {
     315                            vrc = RTFileRead(fileSource, (uint8_t*)aInputData.raw(), RT_MIN(cbToRead, _1M), &cbRead);
     316                            /*
     317                             * Some other error occured? There might be a chance that RTFileRead
     318                             * could not resolve/map the native error code to an IPRT code, so just
     319                             * print a generic error.
     320                             */
     321                            if (RT_FAILURE(vrc))
     322                            {
     323                                rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
     324                                                                     Guest::tr("Could not read from file \"%s\" (%Rrc)"),
     325                                                                     aTask->strSource.c_str(), vrc);
     326                                break;
     327                            }
     328
     329                            /* Resize buffer to reflect amount we just have read. */
     330                            aInputData.resize(cbRead);
     331
     332                            ULONG uFlags = ProcessInputFlag_None;
     333                            /* Did we reach the end of the content we want to transfer (last chunk)? */
     334                            if (   (cbRead < _1M)
     335                                /* ... or does the user want to cancel? */
     336                                || (   SUCCEEDED(aTask->progress->COMGETTER(Canceled(&fCanceled)))
     337                                    && fCanceled)
     338                               )
     339                            {
     340                                uFlags |= ProcessInputFlag_EndOfFile;
     341                            }
     342
     343                            /* Transfer the current chunk ... */
     344                            ULONG uBytesWritten;
     345                            rc = pGuest->SetProcessInput(uPID, uFlags,
     346                                                         ComSafeArrayAsInParam(aInputData), &uBytesWritten);
     347                            if (FAILED(rc))
     348                            {
     349                                rc = TaskGuest::setProgressErrorInfo(rc, aTask->progress, pGuest);
     350                                break;
     351                            }
     352
     353                            Assert(cbRead <= cbToRead);
     354                            cbToRead -= cbRead;
     355                            Assert(cbToRead >= 0);
     356
     357                            cbTransfered += uBytesWritten;
     358                            Assert(cbTransfered <= cbSize);
     359                            aTask->progress->SetCurrentOperationProgress(cbTransfered / (cbSize / 100));
     360
     361                            /* End of file reached? */
     362                            if (cbToRead == 0)
     363                                break;
     364
     365                            /* Progress canceled by Main API? */
     366                            if (   SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled)))
     367                                && fCanceled)
     368                            {
     369                                rc = TaskGuest::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->progress,
     370                                                                     Guest::tr("Copy operation of file \"%s\" was canceled on guest side"),
     371                                                                     aTask->strSource.c_str());
     372                                break;
     373                            }
     374                        }
     375
     376                        if (SUCCEEDED(rc))
     377                            aTask->progress->notifyComplete(S_OK);
     378                    }
     379                }
     380                RTFileClose(fileSource);
     381            }
     382        }
     383    }
     384    catch (HRESULT aRC)
     385    {
     386        rc = aRC;
     387    }
     388
     389    /* Clean up */
     390    aTask->rc = rc;
     391
     392    LogFlowFunc(("rc=%Rhrc\n", rc));
     393    LogFlowFuncLeave();
     394
     395    return VINF_SUCCESS;
     396}
     397
    147398HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask)
    148399{
     
    307558
    308559                        /* Wait for process to exit ... */
    309                         SafeArray<BYTE> aInputData(_64K);
     560                        SafeArray<BYTE> aInputData(_1M);
    310561                        while (   SUCCEEDED(progressCat->COMGETTER(Completed(&fCompleted)))
    311562                               && !fCompleted)
     
    314565                            /* cbLength contains remaining bytes of our installer file
    315566                             * opened above to read. */
    316                             size_t cbToRead = RT_MIN(cbLength, _64K);
     567                            size_t cbToRead = RT_MIN(cbLength, _1M);
    317568                            if (cbToRead)
    318569                            {
     
    324575                                     * we want to transfer (last chunk)? */
    325576                                    ULONG uFlags = ProcessInputFlag_None;
    326                                     if (cbRead < _64K)
     577                                    if (cbRead < _1M)
    327578                                    {
    328579                                        uFlags |= ProcessInputFlag_EndOfFile;
     
    21462397        Assert(uContextID > 0);
    21472398
    2148         size_t cbData = (size_t)RT_MIN(aSize, _64K);
    2149         com::SafeArray<BYTE> outputData(cbData);
     2399        com::SafeArray<BYTE> outputData((size_t)aSize);
    21502400
    21512401        VBOXHGCMSVCPARM paParms[5];
     
    22172467                        {
    22182468                            /* Do we need to resize the array? */
    2219                             if (pData->cbData > cbData)
     2469                            if (pData->cbData > aSize)
    22202470                                outputData.resize(pData->cbData);
    22212471
     
    23312581}
    23322582
    2333 /** @todo For having a progress object which actually reports something,
    2334   *       the actual copy loop (see below) needs to go to some worker thread
    2335   *       so that this routine can return to the caller (and the caller then
    2336   *       can do display a progress). */
    23372583STDMETHODIMP Guest::CopyToGuest(IN_BSTR aSource, IN_BSTR aDest,
    23382584                                IN_BSTR aUserName, IN_BSTR aPassword,
     
    23422588    ReturnComNotImplemented();
    23432589#else /* VBOX_WITH_GUEST_CONTROL */
    2344     using namespace guestControl;
    2345 
    23462590    CheckComArgStrNotEmptyOrNull(aSource);
    23472591    CheckComArgStrNotEmptyOrNull(aDest);
     2592    CheckComArgStrNotEmptyOrNull(aUserName);
     2593    CheckComArgStrNotEmptyOrNull(aPassword);
    23482594    CheckComArgOutPointerValid(aProgress);
    23492595
     
    23512597    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    23522598
     2599    /* Validate flags. */
    23532600    if (aFlags != 0) /* Flags are not supported at the moment. */
    23542601        return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags);
    23552602
     2603    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     2604
    23562605    HRESULT rc = S_OK;
    23572606
     2607    ComObjPtr<Progress> progress;
    23582608    try
    23592609    {
    2360         Utf8Str Utf8Source(aSource);
    2361         Utf8Str Utf8Dest(aDest);
    2362         Utf8Str Utf8UserName(aUserName);
    2363         Utf8Str Utf8Password(aPassword);
    2364 
    2365         /* Does our source file exist? */
    2366         if (!RTFileExists(Utf8Source.c_str()))
    2367         {
    2368             rc = setError(VBOX_E_FILE_ERROR,
    2369                           tr("Source file \"%s\" does not exist"), Utf8Source.c_str());
    2370         }
    2371         else
    2372         {
    2373             RTFILE fileSource;
    2374             int vrc = RTFileOpen(&fileSource, Utf8Source.c_str(),
    2375                                  RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
    2376             if (RT_FAILURE(vrc))
    2377             {
    2378                 rc = setError(VBOX_E_IPRT_ERROR,
    2379                               tr("Could not open source file \"%s\" for reading, rc=%Rrc"),
    2380                               Utf8Source.c_str(),  vrc);
    2381             }
    2382             else
    2383             {
    2384                 uint64_t cbSize;
    2385                 vrc = RTFileGetSize(fileSource, &cbSize);
    2386                 if (RT_FAILURE(vrc))
    2387                 {
    2388                     rc = setError(VBOX_E_IPRT_ERROR,
    2389                                   tr("Could not query file size of \"%s\", rc=%Rrc"),
    2390                                   Utf8Source.c_str(),  vrc);
    2391                 }
    2392                 else
    2393                 {
    2394                     com::SafeArray<IN_BSTR> args;
    2395                     com::SafeArray<IN_BSTR> env;
    2396 
    2397                     /*
    2398                      * Prepare tool command line.
    2399                      */
    2400                     char szOutput[RTPATH_MAX];
    2401                     if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", Utf8Dest.c_str()) <= sizeof(szOutput) - 1)
    2402                     {
    2403                         /*
    2404                          * Normalize path slashes, based on the detected guest.
    2405                          */
    2406                         Utf8Str osType = mData.mOSTypeId;
    2407                         if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
    2408                             || osType.contains("Windows", Utf8Str::CaseInsensitive))
    2409                         {
    2410                             /* We have a Windows guest. */
    2411                             RTPathChangeToDosSlashes(szOutput, true /* Force conversion. */);
    2412                         }
    2413                         else /* ... or something which isn't from Redmond ... */
    2414                         {
    2415                             RTPathChangeToUnixSlashes(szOutput, true /* Force conversion. */);
    2416                         }
    2417 
    2418                         args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */
    2419                         args.push_back(Bstr(szOutput).raw());             /* We want to write a file ... */
    2420                     }
    2421                     else
    2422                         rc = setError(VBOX_E_IPRT_ERROR, tr("Error preparing command line"));
    2423 
    2424                     ComPtr<IProgress> execProgress;
    2425                     ULONG uPID;
    2426                     if (SUCCEEDED(rc))
    2427                     {
    2428                         LogRel(("Copying file \"%s\" to guest \"%s\" (%u bytes) ...\n",
    2429                                 Utf8Source.c_str(), Utf8Dest.c_str(), cbSize));
    2430                         /*
    2431                          * Okay, since we gathered all stuff we need until now to start the
    2432                          * actual copying, start the guest part now.
    2433                          */
    2434                         rc = ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
    2435                                               ExecuteProcessFlag_Hidden
    2436                                             | ExecuteProcessFlag_WaitForProcessStartOnly,
    2437                                             ComSafeArrayAsInParam(args),
    2438                                             ComSafeArrayAsInParam(env),
    2439                                             Bstr(Utf8UserName).raw(),
    2440                                             Bstr(Utf8Password).raw(),
    2441                                             5 * 1000 /* Wait 5s for getting the process started. */,
    2442                                             &uPID, execProgress.asOutParam());
    2443                     }
    2444 
    2445                     if (SUCCEEDED(rc))
    2446                     {
    2447                         /* Wait for process to exit ... */
    2448                         BOOL fCompleted = FALSE;
    2449                         BOOL fCanceled = FALSE;
    2450 
    2451                         size_t cbRead;
    2452                         SafeArray<BYTE> aInputData(_64K);
    2453                         while (   SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted)))
    2454                                && !fCompleted)
    2455                         {
    2456                             vrc = RTFileRead(fileSource, (uint8_t*)aInputData.raw(), _64K, &cbRead);
    2457                             if (   cbRead == 0
    2458                                 || vrc == VERR_EOF)
    2459                                 break;
    2460 
    2461                             aInputData.resize(cbRead);
    2462 
    2463                             /* Did we reach the end of the content
    2464                              * we want to transfer (last chunk)? */
    2465                             ULONG uFlags = ProcessInputFlag_None;
    2466                             if (cbRead < _64K)
    2467                                 uFlags |= ProcessInputFlag_EndOfFile;
    2468 
    2469                             /* Transfer the current chunk ... */
    2470                             ULONG uBytesWritten;
    2471                             rc = SetProcessInput(uPID, uFlags,
    2472                                                  ComSafeArrayAsInParam(aInputData), &uBytesWritten);
    2473                             if (FAILED(rc))
    2474                                 break;
    2475 
    2476                             /* Progress canceled by Main API? */
    2477                             if (   SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled)))
    2478                                 && fCanceled)
    2479                             {
    2480                                 break;
    2481                             }
    2482                         }
    2483 
    2484                         if (SUCCEEDED(rc))
    2485                         {
    2486                             /* Return the progress to the caller. */
    2487                             execProgress.queryInterfaceTo(aProgress);
    2488                         }
    2489                     }
    2490                 }
    2491                 RTFileClose(fileSource);
    2492             }
    2493         }
    2494     }
    2495     catch (std::bad_alloc &)
    2496     {
    2497         rc = E_OUTOFMEMORY;
     2610        /* Create the progress object. */
     2611        progress.createObject();
     2612
     2613        rc = progress->init(static_cast<IGuest*>(this),
     2614                            Bstr(tr("Copying file")).raw(),
     2615                            TRUE /* aCancelable */);
     2616        if (FAILED(rc)) throw rc;
     2617
     2618        /* Initialize our worker task. */
     2619        TaskGuest *pTask = new TaskGuest(TaskGuest::CopyFile, this, progress);
     2620        AssertPtr(pTask);
     2621        std::auto_ptr<TaskGuest> task(pTask);
     2622
     2623        /* Assign data - in that case aSource is the full path
     2624         * to the Guest Additions .ISO we want to mount. */
     2625        task->strSource   = (Utf8Str(aSource));
     2626        task->strDest     = (Utf8Str(aDest));
     2627        task->strUserName = (Utf8Str(aUserName));
     2628        task->strPassword = (Utf8Str(aPassword));
     2629        task->uFlags      = aFlags;
     2630
     2631        rc = task->startThread();
     2632        if (FAILED(rc)) throw rc;
     2633
     2634        /* Don't destruct on success. */
     2635        task.release();
     2636    }
     2637    catch (HRESULT aRC)
     2638    {
     2639        rc = aRC;
     2640    }
     2641
     2642    if (SUCCEEDED(rc))
     2643    {
     2644        /* Return progress to the caller. */
     2645        progress.queryInterfaceTo(aProgress);
    24982646    }
    24992647    return rc;
  • trunk/src/VBox/Main/include/GuestImpl.h

    r33898 r34831  
    136136    struct TaskGuest; /* Worker thread helper. */
    137137#ifdef VBOX_WITH_GUEST_CONTROL
     138    HRESULT taskCopyFile(TaskGuest *aTask);
    138139    HRESULT taskUpdateGuestAdditions(TaskGuest *aTask);
    139140
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