VirtualBox

Ignore:
Timestamp:
Oct 28, 2010 1:37:37 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67164
Message:

Guest Copy/Guest Additions: First working version of host-triggered Guest Additions updates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/GuestImpl.cpp

    r33540 r33558  
    5454    enum TaskType
    5555    {
     56        /** Update Guest Additions by directly copying the required installer
     57         *  off the .ISO file, transfer it to the guest and execute the installer
     58         *  with system priviledges. */
    5659        UpdateGuestAdditions = 100
    5760    };
     
    148151    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    149152
    150     AutoWriteLock appLock(this COMMA_LOCKVAL_SRC_POS);
     153    /*
     154     * Do *not* take a write lock here since we don't (and won't)
     155     * touch any class-specific data (of IGuest) here - only the member functions
     156     * which get called here can do that.
     157     */
    151158
    152159    HRESULT rc = S_OK;
     
    202209            }
    203210
    204             /** @todo Only Windows! */
     211            /** @todo Only Windows! Don't use percent (like %TEMP%) env vars -- Windows
     212             *        will quote it like "%TEMP%" which results in a *not* working command
     213             *        line! */
    205214            Utf8Str strInstallerPath = "C:\\Windows\\VBoxWindowsAdditions.exe";
    206215
     
    214223
    215224                    default:
    216                         rc = setError(VBOX_E_IPRT_ERROR, tr("An unknown error occured, rc=%Rrc"), vrc);
     225                        rc = setError(VBOX_E_IPRT_ERROR, tr("An unknown error occured (%Rrc)"), vrc);
    217226                        break;
    218227                }
     
    220229            else
    221230            {
    222                 /* Okay, we're ready to transfer the bits! */
     231                /* Okay, we're ready to start our copy routine on the guest! */
    223232                if (aTask->progress)
    224233                    aTask->progress->SetCurrentOperationProgress(15);
     
    231240                if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", strInstallerPath.c_str()))
    232241                {
    233                     args.push_back(Bstr("vbox_cat").raw()); /* The actual (internal) tool to use (as argv[0]). */
    234                     args.push_back(Bstr(szOutput).raw());   /* We want to write a file ... */
     242                    args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */
     243                    args.push_back(Bstr(szOutput).raw());             /* We want to write a file ... */
    235244                }
    236245                else
     
    247256                     * system rights, no username/password specified).
    248257                     */
    249                     rc = pGuest->executeProcessInternal(Bstr("vbox_cat").raw(),
     258                    rc = pGuest->executeProcessInternal(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
    250259                                                        ExecuteProcessFlag_WaitForProcessStartOnly,
    251260                                                        ComSafeArrayAsInParam(args),
     
    270279                               && !fCompleted)
    271280                        {
     281                            /* cbLength contains remaining bytes of our installer file
     282                             * opened above to read. */
    272283                            cbToRead = RT_MIN(cbLength, _64K);
    273                             vrc = RTFileRead(iso.file, (uint8_t*)aInputData.raw(), cbToRead, &cbRead);
    274                             if (   cbRead
    275                                 && RT_SUCCESS(vrc))
     284                            if (cbToRead)
    276285                            {
    277                                 aInputData.resize(cbRead);
    278 
    279                                 /* Did we reach the end of the content
    280                                  * we want to transfer (last chunk)? */
    281                                 ULONG uFlags = ProcessInputFlag_None;
    282                                 if (cbRead < _64K)
    283                                     uFlags |= ProcessInputFlag_EndOfFile;
    284 
    285                                 /* Transfer the current chunk ... */
    286                                 ULONG uBytesWritten;
    287                                 rc = SetProcessInput(uPID, uFlags,
    288                                                      ComSafeArrayAsInParam(aInputData), &uBytesWritten);
    289                                 if (FAILED(rc))
     286                                vrc = RTFileRead(iso.file, (uint8_t*)aInputData.raw(), cbToRead, &cbRead);
     287                                if (   cbRead
     288                                    && RT_SUCCESS(vrc))
    290289                                {
    291                                     break;
    292                                 }
    293                                 else
    294                                 {
     290                                    /* Did we reach the end of the content
     291                                     * we want to transfer (last chunk)? */
     292                                    ULONG uFlags = ProcessInputFlag_None;
     293                                    if (cbRead < _64K)
     294                                    {
     295                                        uFlags |= ProcessInputFlag_EndOfFile;
     296                                        if (cbRead > 0) /* Don't allow an empty array! */
     297                                            aInputData.resize(cbRead); /* Adjust array size (less than 64K read). */
     298                                    }
     299
     300                                    /* Transfer the current chunk ... */
     301                                    ULONG uBytesWritten;
     302                                    rc = SetProcessInput(uPID, uFlags,
     303                                                         ComSafeArrayAsInParam(aInputData), &uBytesWritten);
     304                                    if (FAILED(rc))
     305                                        break;
     306
     307                                    Assert(cbLength >= uBytesWritten);
    295308                                    cbLength -= uBytesWritten;
    296                                 }
    297 
    298                                 /* Progress canceled by Main API? */
    299                                 if (   SUCCEEDED(progressCopy->COMGETTER(Canceled(&fCanceled)))
    300                                     && fCanceled)
    301                                 {
    302                                     break;
     309
     310                                    /* Progress canceled by Main API? */
     311                                    if (   SUCCEEDED(progressCopy->COMGETTER(Canceled(&fCanceled)))
     312                                        && fCanceled)
     313                                    {
     314                                        break;
     315                                    }
    303316                                }
    304317                            }
     
    324337                /** @todo Only Windows! */
    325338                installerArgs.push_back(Bstr(strInstallerPath).raw()); /* The actual (internal) installer image (as argv[0]). */
    326                 installerArgs.push_back(Bstr("/S").raw());             /* We want to install in silent mode. */
    327                 installerArgs.push_back(Bstr("/l").raw());             /* ... and logging enabled. */
     339                /* Note that starting at Windows Vista the lovely session 0 separation applies:
     340                 * This means that if we run an application with the profile/security context
     341                 * of VBoxService (system rights!) we're not able to show any UI. */
     342                installerArgs.push_back(Bstr("/S").raw());      /* We want to install in silent mode. */
     343                installerArgs.push_back(Bstr("/l").raw());      /* ... and logging enabled. */
     344                /* Don't quit VBoxService during upgrade because it still is used for this
     345                 * piece of code we're in right now (that is, here!) ... */
     346                installerArgs.push_back(Bstr("/no_vboxservice_exit").raw());
    328347
    329348                /*
    330                  * Start built-in "vbox_cat" tool (inside VBoxService) to
    331                  * copy over/pipe the data into a file on the guest (with
    332                  * system rights, no username/password specified).
     349                 * Start the just copied over installer with system rights
     350                 * in silent mode on the guest.
    333351                 */
    334352                ComPtr<IProgress> progressInstaller;
     
    22642282                    if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", Utf8Dest.c_str()))
    22652283                    {
    2266                         args.push_back(Bstr("vbox_cat").raw()); /* The actual (internal) tool to use (as argv[0]). */
    2267                         args.push_back(Bstr(szOutput).raw());   /* We want to write a file ... */
     2284                        args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */
     2285                        args.push_back(Bstr(szOutput).raw());             /* We want to write a file ... */
    22682286                    }
    22692287                    else
     
    22802298                         * actual copying, start the guest part now.
    22812299                         */
    2282                         rc = ExecuteProcess(Bstr("vbox_cat").raw(),
     2300                        rc = ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(),
    22832301                                            ExecuteProcessFlag_WaitForProcessStartOnly,
    22842302                                            ComSafeArrayAsInParam(args),
     
    23772395        std::auto_ptr<TaskGuest> task(new TaskGuest(TaskGuest::UpdateGuestAdditions, this, progress));
    23782396
    2379         /* Assign data. */
     2397        /* Assign data - in that case aSource is the full path
     2398         * to the Guest Additions .ISO we want to mount. */
    23802399        task->strSource = (Utf8Str(aSource));
    23812400
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette