VirtualBox

Changeset 33492 in vbox for trunk


Ignore:
Timestamp:
Oct 27, 2010 11:05:14 AM (14 years ago)
Author:
vboxsync
Message:

Guest Copy/Guest Additions: Update.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/HostServices/GuestControlSvc.h

    r33247 r33492  
    6969
    7070/**
    71  * Input flags, set by the host.
     71 * Input flags, set by the host. This is needed for
     72 * handling flags on the guest side.
    7273 * Note: Has to match Main's ProcessInputFlag_* flags!
    7374 */
  • trunk/include/iprt/isofs.h

    r33464 r33492  
    4444#define RTISOFS_MAX_PREPARER_ID    128
    4545#define RTISOFS_MAX_APPLICATION_ID 128
     46#define RTISOFS_MAX_STRING_LEN     256
    4647
    4748/** Standard ID of volume descriptors. */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp

    r33464 r33492  
    11401140        if (RT_SUCCESS(rc) && pszCmdTool)
    11411141        {
     1142            /* Disable service flag bit, because we're executing the internal
     1143             * tool with the profile which was used to start VBoxService. */
     1144            fFlags &= ~RTPROC_FLAGS_SERVICE;
     1145
    11421146            rc = RTProcCreateEx(pszCmdTool, papszArgsTool ? papszArgsTool : papszArgs,
    11431147                                hEnv, fFlags,
    1144                                 phStdIn, phStdOut, phStdErr, pszAsUser,
    1145                                 pszPassword, phProcess);
     1148                                phStdIn, phStdOut, phStdErr,
     1149                                strlen(pszAsUser) ? pszAsUser : NULL,
     1150                                strlen(pszPassword) ? pszPassword : NULL,
     1151                                phProcess);
    11461152            if (papszArgsTool)
    11471153                RTGetOptArgvFree(papszArgsTool);
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.cpp

    r32334 r33492  
    23812381}
    23822382
    2383 void VBoxProblemReporter::warnAboutIncorrectPort(QWidget *pParent) const
     2383void VBoxProblemReporter::cannotUpdateGuestAdditions (const CProgress &aProgress, QWidget *aParent /* = NULL */) const
     2384{
     2385    AssertWrapperOk (aProgress);
     2386
     2387    message (aParent ? aParent : mainWindowShown(),
     2388             Error,
     2389             tr ("Failed to update Guest Additions."),
     2390             formatErrorInfo (aProgress.GetErrorInfo()));
     2391}
     2392
     2393void VBoxProblemReporter::warnAboutIncorrectPort (QWidget *pParent) const
    23842394{
    23852395    message(pParent, Error,
     
    23882398}
    23892399
    2390 bool VBoxProblemReporter::confirmCancelingPortForwardingDialog(QWidget *pParent) const
     2400bool VBoxProblemReporter::confirmCancelingPortForwardingDialog (QWidget *pParent) const
    23912401{
    23922402    return messageOkCancel(pParent, Question,
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxProblemReporter.h

    r32296 r33492  
    372372    void cannotExportAppliance (const CProgress &aProgress, CAppliance *aAppliance, QWidget *aParent = NULL) const;
    373373
     374    void cannotUpdateGuestAdditions (const CProgress &aProgress, QWidget *aParent /* = NULL */) const;
     375
    374376    void warnAboutIncorrectPort(QWidget *pParent) const;
    375377    bool confirmCancelingPortForwardingDialog(QWidget *pParent) const;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r33386 r33492  
    355355    CMachine machine = session().GetMachine();
    356356    CVirtualBox vbox = vboxGlobal().virtualBox();
    357     QString strUuid;
    358 
    359     CMedium image = vbox.FindMedium(strSource, KDeviceType_DVD);
    360     if (image.isNull())
    361     {
    362         image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite);
    363         if (vbox.isOk())
     357
     358#ifdef DEBUG_andy
     359    /*
     360     * If the already installed Guest Additions indicate a
     361     * high enough run level (at the moment this is level "Desktop",
     362     * which means that a user has to be logged in to acknowledge
     363     * WHQL popups), try an automatic Guest Additions update.
     364     */
     365    CGuest guest = session().GetConsole().GetGuest();
     366    QString osType = guest.GetOSTypeId();
     367    ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
     368    if (   ulGuestAdditionsRunLevel >= AdditionsRunLevelType_System // Desktop
     369#if 1  /* Only Windows is supported at the moment! */
     370        && (   osType.contains("Microsoft", Qt::CaseInsensitive)
     371            || osType.contains("Windows", Qt::CaseInsensitive)
     372           )
     373#endif
     374       )
     375    {
     376#ifdef DEBUG_andy
     377        CProgress progressInstall = guest.UpdateGuestAdditions("c:\\Downloads\\VBoxGuestAdditions_3.2.8.iso");
     378#else
     379        CProgress progressInstall = guest.UpdateGuestAdditions(strSource);
     380#endif
     381#if 0
     382        bool fResult = guest.isOk();
     383        if (fResult)
     384        {
     385            vboxProblem().showModalProgressDialog(progressInstall, tr("Updating Guest Additions ..."), mainMachineWindow());
     386            if (progressInstall.GetCanceled())
     387                return;
     388            if (!progressInstall.isOk() || progressInstall.GetResultCode() != 0)
     389            {
     390                vboxProblem().cannotUpdateGuestAdditions(progressInstall, mainMachineWindow());
     391                return;
     392            }
     393        }
     394#endif
     395    }
     396    else /* Fallback to only mounting the .ISO file. */
     397    {
     398#endif /* DEBUG_andy */
     399        QString strUuid;
     400        CMedium image = vbox.FindMedium(strSource, KDeviceType_DVD);
     401        if (image.isNull())
     402        {
     403            image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite);
     404            if (vbox.isOk())
     405                strUuid = image.GetId();
     406        }
     407        else
    364408            strUuid = image.GetId();
    365     }
    366     else
    367         strUuid = image.GetId();
    368 
    369     if (!vbox.isOk())
    370     {
    371         vboxProblem().cannotOpenMedium(0, vbox, VBoxDefs::MediumType_DVD, strSource);
    372         return;
    373     }
    374 
    375     AssertMsg(!strUuid.isNull(), ("Guest Additions image UUID should be valid!\n"));
    376 
    377     QString strCntName;
    378     LONG iCntPort = -1, iCntDevice = -1;
    379     /* Searching for the first suitable slot */
    380     {
    381         CStorageControllerVector controllers = machine.GetStorageControllers();
    382         int i = 0;
    383         while (i < controllers.size() && strCntName.isNull())
    384         {
    385             CStorageController controller = controllers[i];
    386             CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
    387             int j = 0;
    388             while (j < attachments.size() && strCntName.isNull())
     409
     410        if (!vbox.isOk())
     411        {
     412            vboxProblem().cannotOpenMedium(0, vbox, VBoxDefs::MediumType_DVD, strSource);
     413            return;
     414        }
     415
     416        AssertMsg(!strUuid.isNull(), ("Guest Additions image UUID should be valid!\n"));
     417
     418        QString strCntName;
     419        LONG iCntPort = -1, iCntDevice = -1;
     420        /* Searching for the first suitable slot */
     421        {
     422            CStorageControllerVector controllers = machine.GetStorageControllers();
     423            int i = 0;
     424            while (i < controllers.size() && strCntName.isNull())
    389425            {
    390                 CMediumAttachment attachment = attachments[j];
    391                 if (attachment.GetType() == KDeviceType_DVD)
     426                CStorageController controller = controllers[i];
     427                CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
     428                int j = 0;
     429                while (j < attachments.size() && strCntName.isNull())
    392430                {
    393                     strCntName = controller.GetName();
    394                     iCntPort = attachment.GetPort();
    395                     iCntDevice = attachment.GetDevice();
     431                    CMediumAttachment attachment = attachments[j];
     432                    if (attachment.GetType() == KDeviceType_DVD)
     433                    {
     434                        strCntName = controller.GetName();
     435                        iCntPort = attachment.GetPort();
     436                        iCntDevice = attachment.GetDevice();
     437                    }
     438                    ++ j;
    396439                }
    397                 ++ j;
     440                ++ i;
    398441            }
    399             ++ i;
    400         }
    401     }
    402 
    403     if (!strCntName.isNull())
    404     {
    405         bool fIsMounted = false;
    406 
    407         VBoxMedium vmedium = vboxGlobal().findMedium(strUuid);
    408         CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    409 
    410         /* Mount medium to the predefined port/device */
    411         machine.MountMedium(strCntName, iCntPort, iCntDevice, medium, false /* force */);
    412         if (machine.isOk())
    413             fIsMounted = true;
     442        }
     443
     444        if (!strCntName.isNull())
     445        {
     446            bool fIsMounted = false;
     447
     448            VBoxMedium vmedium = vboxGlobal().findMedium(strUuid);
     449            CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
     450
     451            /* Mount medium to the predefined port/device */
     452            machine.MountMedium(strCntName, iCntPort, iCntDevice, medium, false /* force */);
     453            if (machine.isOk())
     454                fIsMounted = true;
     455            else
     456            {
     457                /* Ask for force mounting */
     458                if (vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
     459                                                      true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
     460                {
     461                    /* Force mount medium to the predefined port/device */
     462                    machine.MountMedium(strCntName, iCntPort, iCntDevice, medium, true /* force */);
     463                    if (machine.isOk())
     464                        fIsMounted = true;
     465                    else
     466                        vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
     467                                                          true /* mount? */, false /* retry? */);
     468                }
     469            }
     470        }
    414471        else
    415         {
    416             /* Ask for force mounting */
    417             if (vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
    418                                                   true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
    419             {
    420                 /* Force mount medium to the predefined port/device */
    421                 machine.MountMedium(strCntName, iCntPort, iCntDevice, medium, true /* force */);
    422                 if (machine.isOk())
    423                     fIsMounted = true;
    424                 else
    425                     vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
    426                                                       true /* mount? */, false /* retry? */);
    427             }
    428         }
    429     }
    430     else
    431         vboxProblem().cannotMountGuestAdditions(machine.GetName());
     472            vboxProblem().cannotMountGuestAdditions(machine.GetName());
     473#ifdef DEBUG_andy
     474    }
     475#endif /* DEBUG_andy */
    432476}
    433477
  • trunk/src/VBox/Main/GuestImpl.cpp

    r33464 r33492  
    3535#include <iprt/file.h>
    3636#include <iprt/getopt.h>
     37#include <iprt/isofs.h>
    3738#include <iprt/list.h>
    3839#include <iprt/path.h>
     
    4748DEFINE_EMPTY_CTOR_DTOR (Guest)
    4849
     50struct Guest::TaskGuest
     51{
     52    enum TaskType
     53    {
     54        UpdateGuestAdditions = 100
     55    };
     56
     57    TaskGuest(TaskType aTaskType, Guest *aThat, Progress *aProgress)
     58        : taskType(aTaskType),
     59          pGuest(aThat),
     60          progress(aProgress),
     61          rc(S_OK)
     62    {}
     63    ~TaskGuest() {}
     64
     65    int startThread();
     66    static int taskThread(RTTHREAD aThread, void *pvUser);
     67    static int uploadProgress(unsigned uPercent, void *pvUser);
     68
     69    TaskType taskType;
     70    Guest *pGuest;
     71    ComObjPtr<Progress> progress;
     72    HRESULT rc;
     73
     74    /* Task data. */
     75    Utf8Str strSource;
     76};
     77
     78int Guest::TaskGuest::startThread()
     79{
     80    int vrc = RTThreadCreate(NULL, Guest::TaskGuest::taskThread, this,
     81                             0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,
     82                             "Guest::Task");
     83
     84    if (RT_FAILURE(vrc))
     85        return Guest::setErrorStatic(E_FAIL, Utf8StrFmt("Could not create taskThreadGuest (%Rrc)\n", vrc));
     86
     87    return vrc;
     88}
     89
     90/* static */
     91DECLCALLBACK(int) Guest::TaskGuest::taskThread(RTTHREAD /* aThread */, void *pvUser)
     92{
     93    std::auto_ptr<TaskGuest> task(static_cast<TaskGuest*>(pvUser));
     94    AssertReturn(task.get(), VERR_GENERAL_FAILURE);
     95
     96    Guest *pGuest = task->pGuest;
     97
     98    LogFlowFuncEnter();
     99    LogFlowFunc(("Guest %p\n", pGuest));
     100
     101    HRESULT rc = S_OK;
     102
     103    switch (task->taskType)
     104    {
     105#ifdef VBOX_WITH_GUEST_CONTROL
     106        case TaskGuest::UpdateGuestAdditions:
     107        {
     108            rc = pGuest->taskUpdateGuestAdditions(task.get());
     109            break;
     110        }
     111#endif
     112        default:
     113            AssertMsgFailed(("Invalid task type %u specified!\n", task->taskType));
     114            break;
     115    }
     116
     117    LogFlowFunc(("rc=%Rhrc\n", rc));
     118    LogFlowFuncLeave();
     119
     120    return VINF_SUCCESS;
     121}
     122
     123/* static */
     124int Guest::TaskGuest::uploadProgress(unsigned uPercent, void *pvUser)
     125{
     126    Guest::TaskGuest *pTask = *(Guest::TaskGuest**)pvUser;
     127
     128    if (pTask &&
     129        !pTask->progress.isNull())
     130    {
     131        BOOL fCanceled;
     132        pTask->progress->COMGETTER(Canceled)(&fCanceled);
     133        if (fCanceled)
     134            return -1;
     135        pTask->progress->SetCurrentOperationProgress(uPercent);
     136    }
     137    return VINF_SUCCESS;
     138}
     139
     140#ifdef VBOX_WITH_GUEST_CONTROL
     141HRESULT Guest::taskUpdateGuestAdditions(TaskGuest *aTask)
     142{
     143    LogFlowFuncEnter();
     144
     145    AutoCaller autoCaller(this);
     146    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     147
     148    AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS);
     149
     150    HRESULT rc = S_OK;
     151
     152    try
     153    {
     154        Guest *pGuest = aTask->pGuest;
     155        AssertPtr(pGuest);
     156        /*Console *pConsole = pGuest->mParent;
     157        AssertPtr(pConsole);
     158        Console *pMachine = pConsole->machine();
     159        AssertPtr(pMachine);*/
     160
     161        if (aTask->progress)
     162            aTask->progress->SetCurrentOperationProgress(10);
     163
     164        /*
     165         * Determine guest type to know which installer stuff
     166         * we need. At the moment only Windows guests are supported.
     167         */
     168        Utf8Str installerImage;
     169        Utf8Str osType = pGuest->mData.mOSTypeId;
     170        if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
     171            || osType.contains("Windows", Utf8Str::CaseInsensitive))
     172        {
     173            if (osType.contains("64", Utf8Str::CaseInsensitive))
     174                installerImage = "VBOXWINDOWSADDITIONS_AMD64.EXE";
     175            else
     176                installerImage = "VBOXWINDOWSADDITIONS_X86.EXE";
     177            /* Since the installers are located in the root directory,
     178             * no further path processing needs to be done (yet). */
     179        }
     180
     181        /* No (suited) installer found? Bail out. */
     182        if (installerImage.isEmpty())
     183            throw setError(VBOX_E_FILE_ERROR, tr("Guest OS not supported for automatic Guest Additions updating yet"));
     184
     185        /*
     186         * Try to open the .ISO file and locate the specified installer.
     187         */
     188        RTISOFSFILE iso;
     189        int vrc = RTIsoFsOpen(&iso, aTask->strSource.c_str());
     190        if (RT_SUCCESS(vrc))
     191        {
     192            uint32_t cbOffset;
     193            size_t cbLength;
     194            vrc = RTIsoFsGetFileInfo(&iso, installerImage.c_str(), &cbOffset, &cbLength);
     195            if (   RT_SUCCESS(vrc)
     196                && cbOffset
     197                && cbLength)
     198            {
     199                vrc = RTFileSeek(iso.file, cbOffset, RTFILE_SEEK_BEGIN, NULL);
     200            }
     201
     202            /** @todo Only Windows! */
     203            Utf8Str strInstallerPath = "C:\\Windows\\VBoxWindowsAdditions.exe";
     204
     205            if (RT_FAILURE(vrc))
     206            {
     207                switch (vrc)
     208                {
     209                    case VERR_FILE_NOT_FOUND:
     210                        rc = setError(VBOX_E_IPRT_ERROR, tr("Installer file was not found on medium"));
     211                        break;
     212
     213                    default:
     214                        rc = setError(VBOX_E_IPRT_ERROR, tr("An unknown error occured, rc=%Rrc"), vrc);
     215                        break;
     216                }
     217            }
     218            else
     219            {
     220                /* Okay, we're ready to transfer the bits! */
     221                if (aTask->progress)
     222                    aTask->progress->SetCurrentOperationProgress(15);
     223
     224                /* Prepare command line args. */
     225                com::SafeArray<IN_BSTR> args;
     226                com::SafeArray<IN_BSTR> env;
     227
     228                char szOutput[RTPATH_MAX];
     229                if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", strInstallerPath.c_str()))
     230                {
     231                    args.push_back(Bstr("vbox_cat").raw()); /* The actual (internal) tool to use (as argv[0]). */
     232                    args.push_back(Bstr(szOutput).raw());   /* We want to write a file ... */
     233                }
     234                else
     235                    rc = setError(VBOX_E_IPRT_ERROR, tr("Error preparing command line fopr copy operation"));
     236
     237                if (SUCCEEDED(rc))
     238                {
     239                    ComPtr<IProgress> progressCopy;
     240                    ULONG uPID;
     241
     242                    /*
     243                     * Start built-in "vbox_cat" tool (inside VBoxService) to
     244                     * copy over/pipe the data into a file on the guest (with
     245                     * system rights, no username/password specified).
     246                     */
     247                    rc = pGuest->executeProcessInternal(Bstr("vbox_cat").raw(),
     248                                                        ExecuteProcessFlag_WaitForProcessStartOnly,
     249                                                        ComSafeArrayAsInParam(args),
     250                                                        ComSafeArrayAsInParam(env),
     251                                                        Bstr("admin")  /* Username */,
     252                                                        Bstr("password")  /* Password */,
     253                                                        10 * 1000 /* Wait 10s for getting the process started */,
     254                                                        &uPID, progressCopy.asOutParam());
     255                    if (SUCCEEDED(rc))
     256                    {
     257                        if (aTask->progress)
     258                            aTask->progress->SetCurrentOperationProgress(20);
     259
     260                        /* Wait for process to exit ... */
     261                        BOOL fCompleted = FALSE;
     262                        BOOL fCanceled = FALSE;
     263
     264                        size_t cbRead;
     265                        size_t cbToRead;
     266                        SafeArray<BYTE> aInputData(_64K);
     267                        while (   SUCCEEDED(progressCopy->COMGETTER(Completed(&fCompleted)))
     268                               && !fCompleted)
     269                        {
     270                            cbToRead = RT_MIN(cbLength, _64K);
     271                            vrc = RTFileRead(iso.file, (uint8_t*)aInputData.raw(), cbToRead, &cbRead);
     272                            if (   cbRead
     273                                && RT_SUCCESS(vrc))
     274                            {
     275                                aInputData.resize(cbRead);
     276
     277                                /* Did we reach the end of the content
     278                                 * we want to transfer (last chunk)? */
     279                                ULONG uFlags = ProcessInputFlag_None;
     280                                if (cbRead < _64K)
     281                                    uFlags |= ProcessInputFlag_EndOfFile;
     282
     283                                /* Transfer the current chunk ... */
     284                                ULONG uBytesWritten;
     285                                rc = SetProcessInput(uPID, uFlags,
     286                                                     ComSafeArrayAsInParam(aInputData), &uBytesWritten);
     287                                if (FAILED(rc))
     288                                {
     289                                    break;
     290                                }
     291                                else
     292                                {
     293                                    cbLength -= uBytesWritten;
     294                                }
     295
     296                                /* Progress canceled by Main API? */
     297                                if (   SUCCEEDED(progressCopy->COMGETTER(Canceled(&fCanceled)))
     298                                    && fCanceled)
     299                                {
     300                                    break;
     301                                }
     302                            }
     303                        }
     304                    }
     305                }
     306            }
     307            RTIsoFsClose(&iso);
     308
     309            if (SUCCEEDED(rc))
     310            {
     311                /*
     312                 * Installer was transferred successfully, so let's start it
     313                 * (with system rights).
     314                 */
     315                if (aTask->progress)
     316                    aTask->progress->SetCurrentOperationProgress(66);
     317
     318                /* Prepare command line args for installer. */
     319                com::SafeArray<IN_BSTR> installerArgs;
     320                com::SafeArray<IN_BSTR> installerEnv;
     321
     322                /** @todo Only Windows! */
     323                installerArgs.push_back(Bstr(strInstallerPath).raw()); /* The actual (internal) installer image (as argv[0]). */
     324                installerArgs.push_back(Bstr("/S").raw());             /* We want to install in silent mode. */
     325                installerArgs.push_back(Bstr("/l").raw());             /* ... and logging enabled. */
     326
     327                /*
     328                 * Start built-in "vbox_cat" tool (inside VBoxService) to
     329                 * copy over/pipe the data into a file on the guest (with
     330                 * system rights, no username/password specified).
     331                 */
     332                ComPtr<IProgress> progressInstaller;
     333                ULONG uPID;
     334                rc = pGuest->executeProcessInternal(Bstr(strInstallerPath).raw(), 0 /* Flags */,
     335                                                    ComSafeArrayAsInParam(installerArgs),
     336                                                    ComSafeArrayAsInParam(installerEnv),
     337                                                    Bstr("") /* Username */,
     338                                                    Bstr("") /* Password */,
     339                                                    0 /* Timeout */,
     340                                                    &uPID, progressInstaller.asOutParam());
     341                if (SUCCEEDED(rc))
     342                {
     343                    /* Nothing yet. */
     344                }
     345            }
     346        }
     347    }
     348    catch(HRESULT aRC)
     349    {
     350        rc = aRC;
     351    }
     352
     353    /* Clean up */
     354    if (aTask->progress)
     355        aTask->progress->SetCurrentOperationProgress(99);
     356
     357    /* Assign data. */
     358    if (rc == S_OK)
     359    {
     360    }
     361
     362    aTask->rc = rc;
     363
     364    if (!aTask->progress.isNull())
     365        aTask->progress->notifyComplete(rc);
     366
     367    LogFlowFunc(("rc=%Rhrc\n", rc));
     368    LogFlowFuncLeave();
     369
     370    return VINF_SUCCESS;
     371}
     372#endif
     373
    49374HRESULT Guest::FinalConstruct()
    50375{
     
    63388 * Initializes the guest object.
    64389 */
    65 HRESULT Guest::init (Console *aParent)
     390HRESULT Guest::init(Console *aParent)
    66391{
    67392    LogFlowThisFunc(("aParent=%p\n", aParent));
     
    11011426        return setError(E_INVALIDARG, tr("No user name specified"));
    11021427
     1428    LogRel(("Executing guest process \"%s\" as user \"%s\" ...\n",
     1429            Utf8Str(aCommand).c_str(), Utf8Str(aUserName).c_str()));
     1430
     1431    return executeProcessInternal(aCommand, aFlags,aArguments, aEnvironment,
     1432                                  aUserName, aPassword, aTimeoutMS, aPID, aProgress);
     1433#endif
     1434}
     1435
     1436HRESULT Guest::executeProcessInternal(Bstr aCommand, ULONG aFlags,
     1437                                      ComSafeArrayIn(Bstr, aArguments), ComSafeArrayIn(Bstr, aEnvironment),
     1438                                      Bstr aUserName, Bstr aPassword,
     1439                                      ULONG aTimeoutMS, ULONG *aPID, IProgress **aProgress)
     1440{
     1441/** @todo r=bird: Eventually we should clean up all the timeout parameters
     1442 *        in the API and have the same way of specifying infinite waits!  */
     1443#ifndef VBOX_WITH_GUEST_CONTROL
     1444    ReturnComNotImplemented();
     1445#else  /* VBOX_WITH_GUEST_CONTROL */
     1446    using namespace guestControl;
     1447
    11031448    AutoCaller autoCaller(this);
    11041449    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    11071452    if (aFlags)
    11081453    {
    1109         if (!(aFlags & ExecuteProcessFlag_IgnoreOrphanedProcesses))
    1110             return E_INVALIDARG;
     1454        if (   !(aFlags & ExecuteProcessFlag_IgnoreOrphanedProcesses)
     1455            && !(aFlags & ExecuteProcessFlag_WaitForProcessStartOnly))
     1456        {
     1457            return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags);
     1458        }
    11111459    }
    11121460
     
    11891537                }
    11901538
    1191                 LogRel(("Executing guest process \"%s\" as user \"%s\" ...\n",
    1192                         Utf8Command.c_str(), Utf8UserName.c_str()));
    1193 
    11941539                if (RT_SUCCESS(vrc))
    11951540                {
     
    12131558                    paParms[i++].setPointer((void*)Utf8UserName.c_str(), (uint32_t)Utf8UserName.length() + 1);
    12141559                    paParms[i++].setPointer((void*)Utf8Password.c_str(), (uint32_t)Utf8Password.length() + 1);
    1215                     paParms[i++].setUInt32(aTimeoutMS);
     1560
     1561                    /*
     1562                     * If the WaitForProcessStartOnly flag is set, we only want to define and wait for a timeout
     1563                     * until the process was started - the process itself then gets an infinit timeout for execution.
     1564                     * This is handy when we want to start a process inside a worker thread within a certain timeout
     1565                     * but let the started process perform lengthly operations then.
     1566                     */
     1567                    if (aFlags & ExecuteProcessFlag_WaitForProcessStartOnly)
     1568                        paParms[i++].setUInt32(UINT32_MAX /* Infinite timeout */);
     1569                    else
     1570                        paParms[i++].setUInt32(aTimeoutMS);
    12161571
    12171572                    VMMDev *vmmDev;
     
    13831738
    13841739        if (RT_FAILURE(vrc))
    1385             LogRel(("Executing guest process \"%s\" as user \"%s\" failed with %Rrc\n",
    1386                     Utf8Command.c_str(), Utf8UserName.c_str(), vrc));
     1740        {
     1741            if (!Utf8UserName.isEmpty()) /* Skip logging internal calls. */
     1742                LogRel(("Executing guest process \"%s\" as user \"%s\" failed with %Rrc\n",
     1743                        Utf8Command.c_str(), Utf8UserName.c_str(), vrc));
     1744        }
    13871745    }
    13881746    catch (std::bad_alloc &)
     
    18342192#ifndef VBOX_WITH_GUEST_CONTROL
    18352193    ReturnComNotImplemented();
    1836 #else  /* VBOX_WITH_GUEST_CONTROL */
     2194#else /* VBOX_WITH_GUEST_CONTROL */
    18372195    using namespace guestControl;
    18382196
     
    19142272                        LogRel(("Copying file \"%s\" to guest \"%s\" ...\n",
    19152273                                Utf8Source.c_str(), Utf8Dest.c_str()));
    1916 
    19172274                        /*
    19182275                         * Okay, since we gathered all stuff we need until now to start the
    19192276                         * actual copying, start the guest part now.
    19202277                         */
    1921                         rc = ExecuteProcess(Bstr("vbox_cat").raw(), 0 /* Flags */,
     2278                        rc = ExecuteProcess(Bstr("vbox_cat").raw(),
     2279                                            ExecuteProcessFlag_WaitForProcessStartOnly,
    19222280                                            ComSafeArrayAsInParam(args),
    19232281                                            ComSafeArrayAsInParam(env),
    19242282                                            Bstr(Utf8UserName).raw(),
    1925                                             Bstr(Utf8Password).raw(), 0 /* Timeout */,
     2283                                            Bstr(Utf8Password).raw(),
     2284                                            10 * 1000 /* Wait 10s for getting the process started */,
    19262285                                            &uPID, execProgress.asOutParam());
    19272286                    }
     
    19852344}
    19862345
     2346STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, IProgress **aProgress)
     2347{
     2348#ifndef VBOX_WITH_GUEST_CONTROL
     2349    ReturnComNotImplemented();
     2350#else /* VBOX_WITH_GUEST_CONTROL */
     2351    CheckComArgStrNotEmptyOrNull(aSource);
     2352    CheckComArgOutPointerValid(aProgress);
     2353
     2354    AutoCaller autoCaller(this);
     2355    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     2356
     2357    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     2358
     2359    HRESULT rc = S_OK;
     2360
     2361    ComObjPtr<Progress> progress;
     2362    try
     2363    {
     2364        /* Create the progress object. */
     2365        progress.createObject();
     2366
     2367        rc = progress->init(static_cast<IGuest*>(this),
     2368                            Bstr(tr("Updating Guest Additions")).raw(),
     2369                            TRUE /* aCancelable */);
     2370        if (FAILED(rc)) throw rc;
     2371
     2372        /* Initialize our worker task. */
     2373        std::auto_ptr<TaskGuest> task(new TaskGuest(TaskGuest::UpdateGuestAdditions, this, progress));
     2374
     2375        /* Assign data. */
     2376        task->strSource = (Utf8Str(aSource));
     2377
     2378        rc = task->startThread();
     2379        if (FAILED(rc)) throw rc;
     2380
     2381        /* Don't destruct on success. */
     2382        task.release();
     2383    }
     2384    catch (HRESULT aRC)
     2385    {
     2386        rc = aRC;
     2387    }
     2388
     2389    if (SUCCEEDED(rc))
     2390        /* Return progress to the caller. */
     2391        progress.queryInterfaceTo(aProgress);
     2392
     2393    return rc;
     2394#endif /* VBOX_WITH_GUEST_CONTROL */
     2395}
     2396
    19872397// public methods only for internal purposes
    19882398/////////////////////////////////////////////////////////////////////////////
     
    19992409{
    20002410    AutoCaller autoCaller(this);
    2001     AssertComRCReturnVoid (autoCaller.rc());
     2411    AssertComRCReturnVoid(autoCaller.rc());
    20022412
    20032413    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    20572467{
    20582468    AutoCaller autoCaller(this);
    2059     AssertComRCReturnVoid (autoCaller.rc());
     2469    AssertComRCReturnVoid(autoCaller.rc());
    20602470
    20612471    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    20822492{
    20832493    AutoCaller autoCaller(this);
    2084     AssertComRCReturnVoid (autoCaller.rc());
     2494    AssertComRCReturnVoid(autoCaller.rc());
    20852495
    20862496    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    21252535{
    21262536    AutoCaller autoCaller(this);
    2127     AssertComRCReturnVoid (autoCaller.rc());
     2537    AssertComRCReturnVoid(autoCaller.rc());
    21282538
    21292539    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r33474 r33492  
    76187618    </const>
    76197619    <const name="System"   value="1">
    7620         <desc>Guest drivers are loaded.</desc>
     7620      <desc>Guest drivers are loaded.</desc>
    76217621    </const>
    76227622    <const name="Userland" value="2">
    7623         <desc>Common components (such as application services) are loaded.</desc>
     7623      <desc>Common components (such as application services) are loaded.</desc>
    76247624    </const>
    76257625    <const name="Desktop"  value="3">
    7626         <desc>Per-user desktop components are loaded.</desc>
     7626      <desc>Per-user desktop components are loaded.</desc>
    76277627    </const>
    76287628  </enum>
     
    76307630  <enum
    76317631    name="ExecuteProcessFlag"
    7632     uuid="9a24c17d-bd46-4207-b247-517fdd6d6b8f"
     7632    uuid="3258e8a5-ba0c-43d5-86b5-cf91405fddc0"
    76337633  >
    76347634    <desc>
     
    76387638    <const name="None"                    value="0">
    76397639      <desc>No flag set.</desc>
     7640    </const>
     7641
     7642    <const name="WaitForProcessStartOnly" value="1">
     7643      <desc>Only use the specified timeout value to wait for starting the guest process - the guest
     7644        process itself then uses an infinite timeout.</desc>
    76407645    </const>
    76417646
     
    76887693  <interface
    76897694     name="IGuest" extends="$unknown"
    7690      uuid="ed69cdce-2905-4275-872b-3c743a85c584"
     7695     uuid="5a4f265c-0c0e-495a-8ff6-7d68682e276b"
    76917696     wsmap="managed"
    76927697     >
     
    79887993      <param name="source" type="wstring" dir="in">
    79897994        <desc>
    7990           Foo.
     7995          Source file on the host to copy.
    79917996        </desc>
    79927997      </param>
    79937998      <param name="dest" type="wstring" dir="in">
    79947999        <desc>
    7995           Bar.
     8000          Destination path on the guest.
    79968001        </desc>
    79978002      </param>
     
    80468051          Number of bytes written.
    80478052        </desc>
     8053      </param>
     8054    </method>
     8055
     8056    <method name="updateGuestAdditions">
     8057      <desc>
     8058        Updates already installed Guest Additions in a VM
     8059        (Windows guests only).
     8060
     8061        <result name="VBOX_E_IPRT_ERROR">
     8062          Error while updating.
     8063        </result>
     8064
     8065      </desc>
     8066      <param name="source" type="wstring" dir="in">
     8067        <desc>
     8068          Path to the Guest Additions .ISO file to use for the upate.
     8069        </desc>
     8070      </param>
     8071      <param name="progress" type="IProgress" dir="return">
     8072        <desc>Progress object to track the operation completion.</desc>
    80488073      </param>
    80498074    </method>
  • trunk/src/VBox/Main/include/GuestImpl.h

    r33411 r33492  
    105105                                     ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache,
    106106                                     ULONG *aPageTotal, ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal);
     107    STDMETHOD(UpdateGuestAdditions)(IN_BSTR aSource, IProgress **aProgress);
    107108
    108109    // Public methods that are not in IDL (only called internally).
     110    HRESULT executeProcessInternal(Bstr aCommand, ULONG aFlags,
     111                                   ComSafeArrayIn(Bstr, aArguments), ComSafeArrayIn(Bstr, aEnvironment),
     112                                   Bstr aUserName, Bstr aPassword,
     113                                   ULONG aTimeoutMS, ULONG *aPID, IProgress **aProgress);
    109114    void setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType);
    110115    void setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision);
     
    113118    HRESULT setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal);
    114119    BOOL isPageFusionEnabled();
    115 
    116120# ifdef VBOX_WITH_GUEST_CONTROL
    117121    /** Static callback for handling guest notifications. */
    118122    static DECLCALLBACK(int) doGuestCtrlNotification(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms);
    119123# endif
     124    static HRESULT setErrorStatic(HRESULT aResultCode,
     125                                  const Utf8Str &aText)
     126    {
     127        return setErrorInternal(aResultCode, getStaticClassIID(), getStaticComponentName(), aText, false, true);
     128    }
    120129
    121130private:
    122131
    123 # ifdef VBOX_WITH_GUEST_CONTROL
     132    // Internal tasks
     133    struct TaskGuest; /* Worker thread helper. */
     134#ifdef VBOX_WITH_GUEST_CONTROL
     135    HRESULT taskUpdateGuestAdditions(TaskGuest *aTask);
     136
    124137    struct CallbackContext
    125138    {
  • trunk/src/VBox/Runtime/r3/isofs.cpp

    r33466 r33492  
    333333                    break;
    334334
    335                 Assert(pCurRecord->name_len > 0);
     335                Assert(   pCurRecord->name_len  > 0
     336                       && pCurRecord->name_len <= RTISOFS_MAX_STRING_LEN);
    336337                char *pszName = RTStrAlloc(pCurRecord->name_len + 1);
    337338                AssertPtr(pszName);
    338339                Assert(idx + sizeof(RTISOFSDIRRECORD) < cbRead);
    339340                memcpy(pszName, &uBuffer[idx + sizeof(RTISOFSDIRRECORD)], pCurRecord->name_len);
     341                pszName[pCurRecord->name_len] = '\0'; /* Force string termination. */
    340342
    341343                if (   pCurRecord->name_len == 1
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