VirtualBox

Changeset 42749 in vbox for trunk


Ignore:
Timestamp:
Aug 10, 2012 10:19:57 AM (12 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42702 r42749  
    2828#include "GuestFsObjInfoImpl.h"
    2929
     30#include <iprt/isofs.h> /* For UpdateAdditions. */
     31
    3032class Guest;
    3133
     
    136138
    137139protected:
     140
     141    int copyFileToGuest(GuestSession *pSession, PRTISOFSFILE pISO,
     142                        Utf8Str const &strFileSource, const Utf8Str &strFileDest,
     143                        bool fOptional, uint32_t *pcbSize);
     144    int runFile(GuestSession *pSession, GuestProcessStartupInfo &procInfo);
    138145
    139146    /** The (optionally) specified Guest Additions .ISO on the host
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42716 r42749  
    3333#include <iprt/env.h>
    3434#include <iprt/file.h> /* For CopyTo/From. */
    35 #include <iprt/isofs.h> /* For UpdateAdditions. */
    3635
    3736#include <VBox/com/array.h>
    3837#include <VBox/version.h>
    3938
     39
     40#define VBOX_SERVICE_ENVARG_BUG
    4041
    4142// constructor / destructor
     
    678679}
    679680
     681int SessionTaskUpdateAdditions::copyFileToGuest(GuestSession *pSession, PRTISOFSFILE pISO,
     682                                                Utf8Str const &strFileSource, const Utf8Str &strFileDest,
     683                                                bool fOptional, uint32_t *pcbSize)
     684{
     685    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     686    AssertPtrReturn(pISO, VERR_INVALID_POINTER);
     687    /* pcbSize is optional. */
     688
     689    uint32_t cbOffset;
     690    size_t cbSize;
     691
     692    int rc = RTIsoFsGetFileInfo(pISO, strFileSource.c_str(), &cbOffset, &cbSize);
     693    if (RT_FAILURE(rc))
     694    {
     695        if (fOptional)
     696            return VINF_SUCCESS;
     697
     698        return rc;
     699    }
     700
     701    Assert(cbOffset);
     702    Assert(cbSize);
     703    rc = RTFileSeek(pISO->file, cbOffset, RTFILE_SEEK_BEGIN, NULL);
     704
     705    /* Copy over the Guest Additions file to the guest. */
     706    if (RT_SUCCESS(rc))
     707    {
     708        LogRel(("Copying Guest Additions installer file \"%s\" to \"%s\" on guest ...\n",
     709                strFileSource.c_str(), strFileDest.c_str()));
     710
     711        if (RT_SUCCESS(rc))
     712        {
     713            SessionTaskCopyTo *pTask = new SessionTaskCopyTo(pSession /* GuestSession */,
     714                                                             &pISO->file, cbOffset, cbSize,
     715                                                             strFileDest, CopyFileFlag_None);
     716            AssertPtrReturn(pTask, VERR_NO_MEMORY);
     717
     718            ComObjPtr<Progress> pProgressCopyTo;
     719            rc = pSession->startTaskAsync(Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer file \"%s\" to \"%s\" on guest"),
     720                                                     mSource.c_str(), strFileDest.c_str()),
     721                                          pTask, pProgressCopyTo);
     722            if (RT_SUCCESS(rc))
     723            {
     724                BOOL fCanceled = FALSE;
     725                HRESULT hr = pProgressCopyTo->WaitForCompletion(-1);
     726                if (   SUCCEEDED(pProgressCopyTo->COMGETTER(Canceled)(&fCanceled))
     727                    && fCanceled)
     728                {
     729                    rc = VERR_GENERAL_FAILURE; /* Fudge. */
     730                }
     731                else if (FAILED(hr))
     732                {
     733                    Assert(FAILED(hr));
     734                    rc = VERR_GENERAL_FAILURE; /* Fudge. */
     735                }
     736            }
     737        }
     738    }
     739
     740    /** @todo Note: Since there is no file locking involved at the moment, there can be modifications
     741     *              between finished copying, the verification and the actual execution. */
     742
     743    /* Determine where the installer image ended up and if it has the correct size. */
     744    if (RT_SUCCESS(rc))
     745    {
     746        LogRel(("Verifying Guest Additions installer file \"%s\" ...\n", strFileDest.c_str()));
     747
     748        GuestFsObjData objData;
     749        int64_t cbSizeOnGuest;
     750        rc = pSession->fileQuerySizeInternal(strFileDest, &cbSizeOnGuest);
     751#ifdef VBOX_SERVICE_ENVARG_BUG
     752        if (RT_FAILURE(rc))
     753        {
     754            /* Ugly hack: Because older Guest Additions have problems with environment variable
     755                          expansion in parameters we have to check an alternative location on Windows.
     756                          So check for "%TEMP%\" being "C:\\Windows\\system32\\EMP" actually. */
     757            if (strFileDest.startsWith("%TEMP%\\", RTCString::CaseSensitive))
     758            {
     759                Utf8Str strFileDestBug = "C:\\Windows\\system32\\EMP" + strFileDest.substr(sizeof("%TEMP%\\") - sizeof(char));
     760                rc = pSession->fileQuerySizeInternal(strFileDestBug, &cbSizeOnGuest);
     761            }
     762        }
     763#endif
     764        if (   RT_SUCCESS(rc)
     765            && cbSize == (uint64_t)cbSizeOnGuest)
     766        {
     767            LogRel(("Guest Additions installer file \"%s\" successfully verified\n",
     768                    strFileDest.c_str()));
     769        }
     770        else
     771        {
     772            if (RT_SUCCESS(rc)) /* Size does not match. */
     773                rc = VERR_BROKEN_PIPE; /** @todo FInd a better error. */
     774        }
     775
     776        if (RT_SUCCESS(rc))
     777        {
     778            if (pcbSize)
     779                *pcbSize = cbSizeOnGuest;
     780        }
     781    }
     782
     783    return rc;
     784}
     785
     786int SessionTaskUpdateAdditions::runFile(GuestSession *pSession, GuestProcessStartupInfo &procInfo)
     787{
     788    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     789
     790#ifdef VBOX_SERVICE_ENVARG_BUG
     791    GuestFsObjData objData;
     792    int rc = pSession->fileQueryInfoInternal(procInfo.mCommand, objData);
     793    if (RT_FAILURE(rc))
     794        procInfo.mCommand = "C:\\Windows\\system32\\EMP" + procInfo.mCommand.substr(sizeof("%TEMP%\\") - sizeof(char));
     795#endif
     796
     797    ComObjPtr<GuestProcess> pProcess;
     798    rc = pSession->processCreateExInteral(procInfo, pProcess);
     799    if (RT_SUCCESS(rc))
     800        rc = pProcess->startProcess();
     801
     802    if (RT_SUCCESS(rc))
     803    {
     804        LogRel(("Running %s ...\n", procInfo.mName.c_str()));
     805
     806        GuestProcessWaitResult waitRes;
     807        rc = pProcess->waitFor(ProcessWaitForFlag_Terminate,
     808                               10 * 60 * 1000 /* 10 mins Timeout */, waitRes);
     809        if (waitRes.mResult == ProcessWaitResult_Terminate)
     810        {
     811            ProcessStatus_T procStatus;
     812            LONG exitCode;
     813            if (   (   SUCCEEDED(pProcess->COMGETTER(Status(&procStatus)))
     814                    && procStatus != ProcessStatus_TerminatedNormally)
     815                || (   SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode)))
     816                    && exitCode != 0)
     817               )
     818            {
     819                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     820                                    Utf8StrFmt(GuestSession::tr("Running %s failed with status %ld, exit code %ld"),
     821                                               procInfo.mName.c_str(), procStatus, exitCode));
     822                rc = VERR_GENERAL_FAILURE; /* Fudge. */
     823            }
     824            else /* Yay, success! */
     825            {
     826                LogRel(("%s successfully completed\n", procInfo.mName.c_str()));
     827            }
     828        }
     829        else
     830        {
     831            if (RT_FAILURE(rc))
     832                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     833                                    Utf8StrFmt(GuestSession::tr("Error while waiting running %s: %Rrc"),
     834                                               procInfo.mName.c_str(), rc));
     835            else
     836            {
     837                setProgressErrorMsg(VBOX_E_IPRT_ERROR, pProcess->errorMsg());
     838                rc = VERR_GENERAL_FAILURE; /* Fudge. */
     839            }
     840        }
     841    }
     842
     843    if (!pProcess.isNull())
     844        pProcess->close();
     845
     846    return rc;
     847}
     848
    680849int SessionTaskUpdateAdditions::Run(void)
    681850{
     
    734903
    735904    RTISOFSFILE iso;
    736     uint32_t cbOffset;
    737     size_t cbSize;
    738 
    739905    if (RT_SUCCESS(rc))
    740906    {
     
    753919        else
    754920        {
    755             rc = RTIsoFsGetFileInfo(&iso, strInstallerImage.c_str(), &cbOffset, &cbSize);
    756             if (   RT_SUCCESS(rc)
    757                 && cbOffset
    758                 && cbSize)
    759             {
    760                 rc = RTFileSeek(iso.file, cbOffset, RTFILE_SEEK_BEGIN, NULL);
    761                 if (RT_FAILURE(rc))
    762                     hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    763                                              Utf8StrFmt(GuestSession::tr("Unable to retrievev setup file \"%s\" information on \"%s\": %Rrc"),
    764                                              strInstallerImage.c_str(), mSource.c_str(), rc));
    765             }
    766             else
    767             {
    768                 switch (rc)
    769                 {
    770                     case VERR_FILE_NOT_FOUND:
    771                         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    772                                                  Utf8StrFmt(GuestSession::tr("Installer \"%s\" was not found on \"%s\""),
    773                                                  strInstallerImage.c_str(), mSource.c_str()));
    774                         break;
    775 
    776                     default:
    777                         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    778                                                  Utf8StrFmt(GuestSession::tr("Error while retrieving information for installer \"%s\" on \"%s\": %Rrc"),
    779                                                  strInstallerImage.c_str(), mSource.c_str(), rc));
    780                         break;
    781                 }
    782             }
    783 
    784             /* Specify the ouput path on the guest side. */
     921            rc = setProgress(5);
     922
    785923            /** @todo Add support for non-Windows as well! */
    786924            Utf8Str strInstallerDest = "%TEMP%\\VBoxWindowsAdditions.exe";
    787 
    788             /* Copy over the Guest Additions installer to the guest. */
    789             if (RT_SUCCESS(rc))
    790             {
    791                 LogRel(("Copying Guest Additions installer \"%s\" to \"%s\" on guest ...\n",
    792                         strInstallerImage.c_str(), strInstallerDest.c_str()));
    793 
    794                 rc = setProgress(15);
    795                 if (RT_SUCCESS(rc))
    796                 {
    797                     SessionTaskCopyTo *pTask = new SessionTaskCopyTo(pSession /* GuestSession */,
    798                                                                      &iso.file, cbOffset, cbSize,
    799                                                                      strInstallerDest, CopyFileFlag_None);
    800                     AssertPtrReturn(pTask, VERR_NO_MEMORY);
    801 
    802                     ComObjPtr<Progress> pProgressCopyTo;
    803                     rc = pSession->startTaskAsync(Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer from \"%s\" to \"%s\" on the guest"),
    804                                                              mSource.c_str(), strInstallerDest.c_str()),
    805                                                   pTask, pProgressCopyTo);
    806                     if (RT_FAILURE(rc))
    807                     {
    808                         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    809                                                  Utf8StrFmt(GuestSession::tr("Unable to start copying Guest Additions installer \"%s\" to \"%s\": %Rrc"),
    810                                                  mSource.c_str(), strInstallerDest.c_str(), rc));
    811                     }
    812                     else
    813                     {
    814                         BOOL fCanceled = FALSE;
    815                         hr = pProgressCopyTo->WaitForCompletion(-1);
    816                         if (SUCCEEDED(hr))
    817                         {
    818                             rc = setProgress(20);
    819                         }
    820                         else if (   SUCCEEDED(pProgressCopyTo->COMGETTER(Canceled)(&fCanceled))
    821                                  && fCanceled)
    822                         {
    823                             hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    824                                                      Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer \"%s\" to \"%s\" was canceled"),
    825                                                      mSource.c_str(), strInstallerDest.c_str(), hr));
    826                             rc = VERR_GENERAL_FAILURE; /* Fudge. */
    827                         }
    828                         else
    829                         {
    830                             Assert(FAILED(hr));
    831                             hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    832                                                      Utf8StrFmt(GuestSession::tr("Error while copying Guest Additions installer \"%s\" to \"%s\": %Rhrc"),
    833                                                      mSource.c_str(), strInstallerDest.c_str(), hr));
    834                             rc = VERR_GENERAL_FAILURE; /* Fudge. */
    835                         }
    836                     }
    837                 }
    838             }
    839 
    840             if (RT_SUCCESS(rc))
    841             {
    842                 /* Install needed certificates for the WHQL crap. */
    843                 /** @todo Copy over VBoxCertUtil? */
    844                 rc = setProgress(25);
    845             }
     925            bool fInstallCertificates = false;
    846926
    847927            if (RT_SUCCESS(rc))
    848928            {
    849929                /*
    850                  * Installer was transferred successfully, so let's start it
    851                  * (with system rights).
     930                 * Copy over main installer to the guest.
    852931                 */
    853                 LogRel(("Verifying Guest Additions installer ...\n"));
     932                rc = copyFileToGuest(pSession, &iso, strInstallerImage, strInstallerDest,
     933                                     false /* File is not optional */, NULL /* cbSize */);
     934                if (RT_SUCCESS(rc))
     935                    rc = setProgress(20);
     936
     937                /*
     938                 * Install needed certificates for the WHQL crap.
     939                 ** @todo Only for Windows!
     940                 */
     941                if (RT_SUCCESS(rc))
     942                {
     943                    rc = copyFileToGuest(pSession, &iso, "CERT/ORACLE_VBOX.CER", "%TEMP%\\oracle-vbox.cer",
     944                                         true /* File is optional */, NULL /* cbSize */);
     945                    if (RT_SUCCESS(rc))
     946                    {
     947                        rc = setProgress(30);
     948                        if (RT_SUCCESS(rc))
     949                        {
     950                            rc = copyFileToGuest(pSession, &iso, "CERT/VBOXCERTUTIL.EXE", "%TEMP%\\VBoxCertUtil.exe",
     951                                                 true /* File is optional */, NULL /* cbSize */);
     952                            if (RT_SUCCESS(rc))
     953                            {
     954                                fInstallCertificates = true;
     955                                rc = setProgress(40);
     956                            }
     957                            else
     958                                hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     959                                                         Utf8StrFmt(GuestSession::tr("Error while copying certificate installation tool to the guest: %Rrc"), rc));
     960                        }
     961                    }
     962                    else
     963                        hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     964                                                 Utf8StrFmt(GuestSession::tr("Error while copying certificate to the guest: %Rrc"), rc));
     965                }
     966            }
     967
     968            /*
     969             * Run VBoxCertUtil.exe to install the Oracle certificate.
     970             */
     971            if (   RT_SUCCESS(rc)
     972                && fInstallCertificates)
     973            {
     974                LogRel(("Installing certificates on the guest ...\n"));
     975
     976                GuestProcessStartupInfo procInfo;
     977                procInfo.mName    = Utf8StrFmt(GuestSession::tr("VirtualBox Guest Additions Certificate Utility"));
     978                procInfo.mCommand = Utf8Str("%TEMP%\\VBoxCertUtil.exe");
     979                procInfo.mFlags   = ProcessCreateFlag_Hidden;
     980
     981                /* Construct arguments. */
     982                /** @todo Remove hardcoded paths. */
     983                procInfo.mArguments.push_back(Utf8Str("add-trusted-publisher"));
     984                /* Ugly hack: Because older Guest Additions have problems with environment variable
     985                          expansion in parameters we have to check an alternative location on Windows.
     986                          So check for "%TEMP%\VBoxWindowsAdditions.exe" in a screwed up way. */
     987#ifdef VBOX_SERVICE_ENVARG_BUG
     988                GuestFsObjData objData;
     989                rc = pSession->fileQueryInfoInternal("%TEMP%\\oracle-vbox.cer", objData);
     990                if (RT_SUCCESS(rc))
     991#endif
     992                    procInfo.mArguments.push_back(Utf8Str("%TEMP%\\oracle-vbox.cer"));
     993#ifdef VBOX_SERVICE_ENVARG_BUG
     994                else
     995                    procInfo.mArguments.push_back(Utf8Str("C:\\Windows\\system32\\EMPoracle-vbox.cer"));
     996#endif
     997                /* Overwrite rc in any case. */
     998                rc = runFile(pSession, procInfo);
     999            }
     1000
     1001            if (RT_SUCCESS(rc))
    8541002                rc = setProgress(60);
    855             }
    8561003
    8571004            if (RT_SUCCESS(rc))
    8581005            {
    859                 /* Determine where the installer image ended up and if it has the
    860                  * correct size. */
    861                 GuestFsObjData objData;
    862                 int64_t cbSizeOnGuest;
    863                 rc = pSession->fileQuerySizeInternal(strInstallerDest, &cbSizeOnGuest);
    864                 if (RT_FAILURE(rc))
    865                 {
    866                     /** @todo Windows only! */
    867 
    868                     /* Because older Guest Additions have problems with environment variable
    869                      * expansion in parameters we have to check an alternative location on Windows.
    870                      * So check for "%TEMP%\VBoxWindowsAdditions.exe" in a screwed up way. */
    871                     rc = pSession->fileQuerySizeInternal("C:\\Windows\\system32\\EMPVBoxWindowsAdditions.exe", &cbSizeOnGuest);
    872                     if (RT_SUCCESS(rc))
    873                         strInstallerDest = "C:\\Windows\\system32\\EMPVBoxWindowsAdditions.exe";
    874                 }
    875 
    876                 if (   RT_SUCCESS(rc)
    877                     && cbSize == (uint64_t)cbSizeOnGuest)
    878                 {
    879                     LogRel(("Guest Additions installer successfully verified\n"));
    880                     rc = setProgress(65);
    881                 }
    882                 else
    883                 {
    884                     if (RT_FAILURE(rc))
    885                     {
    886                         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    887                                                  Utf8StrFmt(GuestSession::tr("Unable to find Guest Additions installer on guest: %Rrc"), rc));
    888                     }
    889                     else
    890                     {
    891                         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    892                                                  Utf8StrFmt(GuestSession::tr("Guest Additions installer was not transfered fully (%RI64/%RU64)"),
    893                                                             cbSizeOnGuest, cbSize));
    894                         rc = VERR_GENERAL_FAILURE; /* Fudge. */
    895                     }
    896                 }
    897             }
    898 
    899             if (RT_SUCCESS(rc))
    900             {
     1006                LogRel(("Updating Guest Additions ...\n"));
     1007
    9011008                GuestProcessStartupInfo procInfo;
    902                 procInfo.mName    = Utf8StrFmt(GuestSession::tr("Guest Additions Setup"));
     1009                procInfo.mName    = Utf8StrFmt(GuestSession::tr("VirtualBox Guest Additions Setup"));
    9031010                procInfo.mCommand = Utf8Str(strInstallerDest);
    9041011                procInfo.mFlags   = ProcessCreateFlag_Hidden;
     
    9191026                procInfo.mArguments.push_back(Utf8Str("/post_installstatus"));
    9201027
    921                 ComObjPtr<GuestProcess> pProcess;
    922                 rc = pSession->processCreateExInteral(procInfo, pProcess);
     1028                rc = runFile(pSession, procInfo);
    9231029                if (RT_SUCCESS(rc))
    924                     rc = pProcess->startProcess();
    925                 if (RT_SUCCESS(rc))
    926                     rc = setProgress(65);
    927                 if (RT_SUCCESS(rc))
    928                 {
    929                     LogRel(("Updating Guest Additions in progress ...\n"));
    930 
    931                     GuestProcessWaitResult waitRes;
    932                     rc = pProcess->waitFor(ProcessWaitForFlag_Terminate,
    933                                            10 * 60 * 1000 /* 10 mins Timeout */, waitRes);
    934                     if (waitRes.mResult == ProcessWaitResult_Terminate)
    935                     {
    936                         ProcessStatus_T procStatus;
    937                         LONG exitCode;
    938                         if (   (   SUCCEEDED(pProcess->COMGETTER(Status(&procStatus)))
    939                                 && procStatus != ProcessStatus_TerminatedNormally)
    940                             || (   SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode)))
    941                                 && exitCode != 0)
    942                            )
    943                         {
    944                             hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    945                                                      Utf8StrFmt(GuestSession::tr("Updating Guest Additions failed with status %ld, exit code %d"),
    946                                                                 procStatus, exitCode)); /**@todo Add stringify methods! */
    947                             rc = VERR_GENERAL_FAILURE; /* Fudge. */
    948                         }
    949                         else /* Yay, success! */
    950                         {
    951                             /** @todo Add code for verifying the update. */
    952                             LogRel(("Updating Guest Additions successful\n"));
    953                             hr = setProgressSuccess();
    954                         }
    955                     }
    956                     else
    957                     {
    958                         if (RT_FAILURE(rc))
    959                             hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    960                                                      Utf8StrFmt(GuestSession::tr("Error while waiting for Guest Additions update: %Rrc"), rc));
    961                         else
    962                         {
    963                             hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, pProcess->errorMsg());
    964                             rc = VERR_GENERAL_FAILURE; /* Fudge. */
    965                         }
    966                     }
    967                 }
    968                 if (!pProcess.isNull())
    969                     pProcess->close();
     1030                    hr = setProgressSuccess();
    9701031            }
    9711032            RTIsoFsClose(&iso);
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