VirtualBox

Changeset 43001 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Aug 27, 2012 3:42:00 PM (12 years ago)
Author:
vboxsync
Message:

Main/GuestSessionImplTasks: More code for updating Guest Additions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r42937 r43001  
    5050 * Update file flags.
    5151 */
    52 #define UPDATEFILE_FLAG_NONE        RT_BIT(0)
     52#define UPDATEFILE_FLAG_NONE                RT_BIT(0)
     53/** Copy over the file from host to the
     54 *  guest. */
     55#define UPDATEFILE_FLAG_COPY_FROM_ISO       RT_BIT(1)
     56/** Execute file on the guest after it has
     57 *  been successfully transfered. */
     58#define UPDATEFILE_FLAG_EXECUTE             RT_BIT(7)
    5359/** File is optional, does not have to be
    5460 *  existent on the .ISO. */
    55 #define UPDATEFILE_FLAG_OPTIONAL    RT_BIT(1)
    56 /** Execute file on the guest after it has
    57  *  been successfully transfered. */
    58 #define UPDATEFILE_FLAG_EXECUTE     RT_BIT(2)
     61#define UPDATEFILE_FLAG_OPTIONAL            RT_BIT(8)
    5962
    6063
     
    8992    }
    9093    return VERR_NOT_FOUND;
    91 
    92 
    9394}
    9495
     
    824825}
    825826
    826 int SessionTaskUpdateAdditions::runFile(GuestSession *pSession, GuestProcessStartupInfo &procInfo)
     827int SessionTaskUpdateAdditions::runFileOnGuest(GuestSession *pSession, GuestProcessStartupInfo &procInfo)
    827828{
    828829    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     
    835836    if (RT_SUCCESS(rc))
    836837    {
    837         LogFlowThisFunc(("Running %s ...\n", procInfo.mName.c_str()));
     838        LogRel(("Running %s ...\n", procInfo.mName.c_str()));
    838839
    839840        GuestProcessWaitResult waitRes;
     
    898899    LogRel(("Automatic update of Guest Additions started, using \"%s\"\n", mSource.c_str()));
    899900
     901    ComObjPtr<Guest> pGuest(mSession->getParent());
    900902    /*
    901      * Determine guest OS type and the required installer image.
     903     * Wait for the guest being ready within 30 seconds.
    902904     */
    903     ComObjPtr<Guest> pGuest(mSession->getParent());
     905    AdditionsRunLevelType_T addsRunLevel;
     906    uint64_t tsStart = RTTimeSystemMilliTS();
     907    while (   SUCCEEDED(hr = pGuest->COMGETTER(AdditionsRunLevel)(&addsRunLevel))
     908           && (    addsRunLevel != AdditionsRunLevelType_Userland
     909                && addsRunLevel != AdditionsRunLevelType_Desktop))
     910    {
     911        if ((RTTimeSystemMilliTS() - tsStart) > 30 * 1000)
     912        {
     913            rc = VERR_TIMEOUT;
     914            break;
     915        }
     916
     917        RTThreadSleep(100); /* Wait a bit. */
     918    }
     919
     920    if (FAILED(hr)) rc = VERR_TIMEOUT;
     921    if (rc == VERR_TIMEOUT)
     922        hr = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
     923                                 Utf8StrFmt(GuestSession::tr("Guest Additions were not ready within time, giving up")));
    904924
    905925    eOSType eOSType;
    906     Utf8Str strOSType;
    907     rc = getGuestProperty(pGuest, "/VirtualBox/GuestInfo/OS/Product", strOSType);
    908     if (   strOSType.contains("Microsoft", Utf8Str::CaseInsensitive)
    909         || strOSType.contains("Windows", Utf8Str::CaseInsensitive))
    910     {
    911         eOSType = eOSType_Windows;
    912     }
    913     else if (strOSType.contains("Solaris", Utf8Str::CaseInsensitive))
    914     {
    915         eOSType = eOSType_Solaris;
    916     }
    917     else /* Everything else hopefully means Linux :-). */
    918         eOSType = eOSType_Linux;
     926    if (RT_SUCCESS(rc))
     927    {
     928        /*
     929         * Determine if we are able to update automatically. This only works
     930         * if there are recent Guest Additions installed already.
     931         */
     932        Utf8Str strAddsVer;
     933        rc = getGuestProperty(pGuest, "/VirtualBox/GuestAdd/Version", strAddsVer);
     934        if (   RT_SUCCESS(rc)
     935            && RTStrVersionCompare(strAddsVer.c_str(), "4.1") < 0)
     936        {
     937            hr = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
     938                                     Utf8StrFmt(GuestSession::tr("Guest has too old Guest Additions (%s) installed for automatic updating, please update manually"),
     939                                                strAddsVer.c_str()));
     940            rc = VERR_NOT_SUPPORTED;
     941        }
     942
     943        /*
     944         * Determine guest OS type and the required installer image.
     945         */
     946        Utf8Str strOSType;
     947        rc = getGuestProperty(pGuest, "/VirtualBox/GuestInfo/OS/Product", strOSType);
     948        if (RT_SUCCESS(rc))
     949        {
     950            if (   strOSType.contains("Microsoft", Utf8Str::CaseInsensitive)
     951                || strOSType.contains("Windows", Utf8Str::CaseInsensitive))
     952            {
     953                eOSType = eOSType_Windows;
     954            }
     955            else if (strOSType.contains("Solaris", Utf8Str::CaseInsensitive))
     956            {
     957                eOSType = eOSType_Solaris;
     958            }
     959            else /* Everything else hopefully means Linux :-). */
     960                eOSType = eOSType_Linux;
    919961
    920962#if 1 /* Only Windows is supported (and tested) at the moment. */
    921     if (eOSType != eOSType_Windows)
    922     {
    923         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    924                                  Utf8StrFmt(GuestSession::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
    925                                             strOSType.c_str()));
    926         rc = VERR_NOT_SUPPORTED;
    927     }
     963            if (eOSType != eOSType_Windows)
     964            {
     965                hr = setProgressErrorMsg(VBOX_E_NOT_SUPPORTED,
     966                                         Utf8StrFmt(GuestSession::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"),
     967                                                    strOSType.c_str()));
     968                rc = VERR_NOT_SUPPORTED;
     969            }
    928970#endif
     971        }
     972    }
    929973
    930974    RTISOFSFILE iso;
     
    944988        {
    945989            /* Set default installation directories. */
    946             Utf8Str strInstallerDir = "/tmp/";
     990            Utf8Str strUpdateDir = "/tmp/";
    947991            if (eOSType == eOSType_Windows)
    948                  strInstallerDir = "C:\\Temp\\";
     992                 strUpdateDir = "C:\\Temp\\";
    949993
    950994            rc = setProgress(5);
     
    953997            if (RT_SUCCESS(rc))
    954998            {
    955                 rc = getGuestProperty(pGuest, "/VirtualBox/GuestAdd/InstallDir", strInstallerDir);
    956                 if (RT_SUCCESS(rc))
    957                 {
    958                     if (eOSType == eOSType_Windows)
     999                /* Try getting the installed Guest Additions version to know whether we
     1000                 * can install our temporary Guest Addition data into the original installation
     1001                 * directory.
     1002                 *
     1003                 * Because versions prior to 4.2 had bugs wrt spaces in paths we have to choose
     1004                 * a different location then.
     1005                 */
     1006                bool fUseInstallDir = false;
     1007
     1008                Utf8Str strAddsVer;
     1009                rc = getGuestProperty(pGuest, "/VirtualBox/GuestAdd/Version", strAddsVer);
     1010                if (   RT_SUCCESS(rc)
     1011                    && RTStrVersionCompare(strAddsVer.c_str(), "4.2") >= 0)
     1012                {
     1013                    fUseInstallDir = true;
     1014                }
     1015
     1016                if (fUseInstallDir)
     1017                {
     1018                    if (RT_SUCCESS(rc))
     1019                        rc = getGuestProperty(pGuest, "/VirtualBox/GuestAdd/InstallDir", strUpdateDir);
     1020                    if (RT_SUCCESS(rc))
    9591021                    {
    960                         strInstallerDir.findReplace('/', '\\');
    961                         strInstallerDir.append("\\Update\\");
     1022                        if (eOSType == eOSType_Windows)
     1023                        {
     1024                            strUpdateDir.findReplace('/', '\\');
     1025                            strUpdateDir.append("\\Update\\");
     1026                        }
     1027                        else
     1028                            strUpdateDir.append("/update/");
    9621029                    }
    963                     else
    964                         strInstallerDir.append("/update/");
    965                 }
    966             }
    967 
    968             LogRel(("Guest Additions update directory is: %s\n",
    969                     strInstallerDir.c_str()));
     1030                }
     1031            }
     1032
     1033            if (RT_SUCCESS(rc))
     1034                LogRel(("Guest Additions update directory is: %s\n",
     1035                        strUpdateDir.c_str()));
    9701036
    9711037            /* Create the installation directory. */
    972             rc = pSession->directoryCreateInternal(strInstallerDir,
     1038            rc = pSession->directoryCreateInternal(strUpdateDir,
    9731039                                                   755 /* Mode */, DirectoryCreateFlag_Parents);
    9741040            if (RT_FAILURE(rc))
    9751041                hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    9761042                                         Utf8StrFmt(GuestSession::tr("Error creating installation directory \"%s\" on the guest: %Rrc"),
    977                                                     strInstallerDir.c_str(), rc));
     1043                                                    strUpdateDir.c_str(), rc));
    9781044            if (RT_SUCCESS(rc))
    9791045                rc = setProgress(10);
     
    9871053                    case eOSType_Windows:
    9881054                    {
    989                 #if 0 /* VBoxCertUtil.exe does not work yet, disabled. */
    990                         /* Our certificate. */
    991                         mFiles.push_back(InstallerFile("CERT/ORACLE_VBOX.CER",
    992                                                        strInstallerDir + "Oracle_VBox.cer",
    993                                                        UPDATEFILE_FLAG_OPTIONAL));
    994                         /* Our certificate installation utility. */
    995                         GuestProcessStartupInfo siCertUtil;
    996                         siCertUtil.mArguments.push_back(Utf8Str("add-trusted-publisher"));
    997                         siCertUtil.mArguments.push_back(Utf8Str(strInstallerDir + "oracle-vbox.cer"));
    998                         mFiles.push_back(InstallerFile("CERT/VBOXCERTUTIL.EXE",
    999                                                        strInstallerDir + "VBoxCertUtil.exe",
    1000                                                        UPDATEFILE_FLAG_OPTIONAL | UPDATEFILE_FLAG_EXECUTE, siCertUtil));
    1001                 #endif
    1002                         /* The installers in different flavors. */
     1055                        /* Do we need to install our certificates? We do this for W2K and up. */
     1056                        bool fInstallCert = false;
     1057
     1058                        Utf8Str strOSVer;
     1059                        rc = getGuestProperty(pGuest, "/VirtualBox/GuestInfo/OS/Release", strOSVer);
     1060                        if (   RT_SUCCESS(rc)
     1061                            && RTStrVersionCompare(strOSVer.c_str(), "5.0") >= 0) /* Only W2K an up. */
     1062                        {
     1063                            fInstallCert = true;
     1064                            LogRel(("Certificates for auto updating WHQL drivers will be installed\n"));
     1065                        }
     1066                        else if (RT_FAILURE(rc))
     1067                        {
     1068                            /* Unknown (or unhandled) Windows OS. */
     1069                            fInstallCert = true;
     1070                            LogRel(("Unknown guest Windows version detected (%s), installing certificates for WHQL drivers\n",
     1071                                    strOSVer.c_str()));
     1072                        }
     1073                        else
     1074                            LogRel(("Skipping installation of certificates for WHQL drivers\n"));
     1075
     1076                        if (fInstallCert)
     1077                        {
     1078                            /* Our certificate. */
     1079                            mFiles.push_back(InstallerFile("CERT/ORACLE_VBOX.CER",
     1080                                                           strUpdateDir + "oracle-vbox.cer",
     1081                                                           UPDATEFILE_FLAG_COPY_FROM_ISO | UPDATEFILE_FLAG_OPTIONAL));
     1082                            /* Our certificate installation utility. */
     1083                            /* First pass: Copy over the file + execute it to remove any existing
     1084                             *             VBox certificates. */
     1085                            GuestProcessStartupInfo siCertUtilRem;
     1086                            siCertUtilRem.mName = "VirtualBox Certificate Utility";
     1087                            siCertUtilRem.mArguments.push_back(Utf8Str("remove-trusted-publisher"));
     1088                            siCertUtilRem.mArguments.push_back(Utf8Str("--root")); /* Add root certificate as well. */
     1089                            siCertUtilRem.mArguments.push_back(Utf8Str(strUpdateDir + "oracle-vbox.cer"));
     1090                            siCertUtilRem.mArguments.push_back(Utf8Str(strUpdateDir + "oracle-vbox.cer"));
     1091                            mFiles.push_back(InstallerFile("CERT/VBOXCERTUTIL.EXE",
     1092                                                           strUpdateDir + "VBoxCertUtil.exe",
     1093                                                           UPDATEFILE_FLAG_COPY_FROM_ISO | UPDATEFILE_FLAG_EXECUTE | UPDATEFILE_FLAG_OPTIONAL,
     1094                                                           siCertUtilRem));
     1095                            /* Second pass: Only execute (but don't copy) again, this time installng the
     1096                             *              recent certificates just copied over. */
     1097                            GuestProcessStartupInfo siCertUtilAdd;
     1098                            siCertUtilAdd.mName = "VirtualBox Certificate Utility";
     1099                            siCertUtilAdd.mArguments.push_back(Utf8Str("add-trusted-publisher"));
     1100                            siCertUtilAdd.mArguments.push_back(Utf8Str("--root")); /* Add root certificate as well. */
     1101                            siCertUtilAdd.mArguments.push_back(Utf8Str(strUpdateDir + "oracle-vbox.cer"));
     1102                            siCertUtilAdd.mArguments.push_back(Utf8Str(strUpdateDir + "oracle-vbox.cer"));
     1103                            mFiles.push_back(InstallerFile("CERT/VBOXCERTUTIL.EXE",
     1104                                                           strUpdateDir + "VBoxCertUtil.exe",
     1105                                                           UPDATEFILE_FLAG_EXECUTE | UPDATEFILE_FLAG_OPTIONAL,
     1106                                                           siCertUtilAdd));
     1107                        }
     1108                        /* The installers in different flavors, as we don't know (and can't assume)
     1109                         * the guest's bitness. */
    10031110                        mFiles.push_back(InstallerFile("VBOXWINDOWSADDITIONS_X86.EXE",
    1004                                                        strInstallerDir + "VBoxWindowsAdditions-x86.exe",
    1005                                                        UPDATEFILE_FLAG_NONE));
     1111                                                       strUpdateDir + "VBoxWindowsAdditions-x86.exe",
     1112                                                       UPDATEFILE_FLAG_COPY_FROM_ISO));
    10061113                        mFiles.push_back(InstallerFile("VBOXWINDOWSADDITIONS_AMD64.EXE",
    1007                                                        strInstallerDir + "VBoxWindowsAdditions-amd64.exe",
    1008                                                        UPDATEFILE_FLAG_NONE));
     1114                                                       strUpdateDir + "VBoxWindowsAdditions-amd64.exe",
     1115                                                       UPDATEFILE_FLAG_COPY_FROM_ISO));
     1116                        /* The stub loader which decides which flavor to run. */
    10091117                        GuestProcessStartupInfo siInstaller;
     1118                        siInstaller.mName = "VirtualBox Windows Guest Additions Installer";
    10101119                        siInstaller.mArguments.push_back(Utf8Str("/S")); /* We want to install in silent mode. */
    10111120                        siInstaller.mArguments.push_back(Utf8Str("/l")); /* ... and logging enabled. */
     
    10221131                            siInstaller.mFlags |= ProcessCreateFlag_WaitForProcessStartOnly;
    10231132                        mFiles.push_back(InstallerFile("VBOXWINDOWSADDITIONS.EXE",
    1024                                                        strInstallerDir + "VBoxWindowsAdditions.exe",
    1025                                                        UPDATEFILE_FLAG_EXECUTE, siInstaller));
     1133                                                       strUpdateDir + "VBoxWindowsAdditions.exe",
     1134                                                       UPDATEFILE_FLAG_COPY_FROM_ISO | UPDATEFILE_FLAG_EXECUTE, siInstaller));
    10261135                        break;
    10271136                    }
     
    10501159                while (itFiles != mFiles.end())
    10511160                {
    1052                     rc = copyFileToGuest(pSession, &iso, itFiles->strSource, itFiles->strDest,
    1053                                          (itFiles->fFlags & UPDATEFILE_FLAG_OPTIONAL), NULL /* cbSize */);
    1054                     if (RT_FAILURE(rc))
     1161                    if (itFiles->fFlags & UPDATEFILE_FLAG_COPY_FROM_ISO)
    10551162                    {
    1056                         hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    1057                                                   Utf8StrFmt(GuestSession::tr("Error while copying file \"%s\" to \"%s\" on the guest: %Rrc"),
    1058                                                              itFiles->strSource.c_str(), itFiles->strDest.c_str(), rc));
    1059                         break;
     1163                        bool fOptional = false;
     1164                        if (itFiles->fFlags & UPDATEFILE_FLAG_OPTIONAL)
     1165                            fOptional = true;
     1166                        rc = copyFileToGuest(pSession, &iso, itFiles->strSource, itFiles->strDest,
     1167                                             fOptional, NULL /* cbSize */);
     1168                        if (RT_FAILURE(rc))
     1169                        {
     1170                            hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     1171                                                      Utf8StrFmt(GuestSession::tr("Error while copying file \"%s\" to \"%s\" on the guest: %Rrc"),
     1172                                                                 itFiles->strSource.c_str(), itFiles->strDest.c_str(), rc));
     1173                            break;
     1174                        }
    10601175                    }
    10611176
     
    10691184            }
    10701185
     1186            /* Done copying, close .ISO file. */
     1187            RTIsoFsClose(&iso);
     1188
    10711189            if (RT_SUCCESS(rc))
    10721190            {
     
    10831201                    if (itFiles->fFlags & UPDATEFILE_FLAG_EXECUTE)
    10841202                    {
    1085                         rc = runFile(pSession, itFiles->mProcInfo);
     1203                        rc = runFileOnGuest(pSession, itFiles->mProcInfo);
    10861204                        if (RT_FAILURE(rc))
    10871205                        {
     
    11301248
    11311249                LogRel(("Automatic update of Guest Additions failed: %s\n", strError.c_str()));
    1132             }
    1133 
    1134             RTIsoFsClose(&iso);
     1250                LogRel(("Please install Guest Additions manually\n"));
     1251            }
    11351252        }
    11361253    }
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