Changeset 42923 in vbox for trunk/src/VBox/Main
- Timestamp:
- Aug 22, 2012 3:33:56 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
r42918 r42923 27 27 #include "Global.h" 28 28 #include "AutoCaller.h" 29 #include "ConsoleImpl.h" 30 #include "MachineImpl.h" 29 31 #include "ProgressImpl.h" 30 32 … … 41 43 42 44 43 /* 44 * If the following define is enabled the Guest Additions update code also 45 * checks for locations which were not supposed to happen due to not resolving 46 * environment variables in VBoxService toolbox arguments. So a file copied 47 * to "%TEMP%\foo.exe" became "C:\Windows\EMPfoo.exe". 45 /******************************************************************************* 46 * Defines * 47 *******************************************************************************/ 48 49 /** 50 * Update file flags. 48 51 */ 49 #define VBOX_SERVICE_ENVARG_BUG 52 #define UPDATEFILE_FLAG_NONE RT_BIT(0) 53 /** File is optional, does not have to be 54 * 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) 59 50 60 51 61 // session task classes … … 59 69 GuestSessionTask::~GuestSessionTask(void) 60 70 { 71 } 72 73 int GuestSessionTask::getGuestProperty(const ComObjPtr<Guest> &pGuest, 74 const Utf8Str &strPath, Utf8Str &strValue) 75 { 76 ComObjPtr<Console> pConsole = pGuest->getConsole(); 77 const ComPtr<IMachine> pMachine = pConsole->machine(); 78 79 Assert(!pMachine.isNull()); 80 Bstr strTemp, strFlags; 81 LONG64 i64Timestamp; 82 HRESULT hr = pMachine->GetGuestProperty(Bstr(strPath).raw(), 83 strTemp.asOutParam(), 84 &i64Timestamp, strFlags.asOutParam()); 85 if (SUCCEEDED(hr)) 86 { 87 strValue = strTemp; 88 return VINF_SUCCESS; 89 } 90 return VERR_NOT_FOUND; 91 92 61 93 } 62 94 … … 729 761 rc = pSession->startTaskAsync(Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer file \"%s\" to \"%s\" on guest"), 730 762 mSource.c_str(), strFileDest.c_str()), 731 pTask, pProgressCopyTo);763 pTask, pProgressCopyTo); 732 764 if (RT_SUCCESS(rc)) 733 765 { … … 759 791 int64_t cbSizeOnGuest; 760 792 rc = pSession->fileQuerySizeInternal(strFileDest, &cbSizeOnGuest); 761 #ifdef VBOX_SERVICE_ENVARG_BUG762 if (RT_FAILURE(rc))763 {764 /* Ugly hack: Because older Guest Additions have problems with environment variable765 expansion in parameters we have to check an alternative location on Windows.766 So check for "%TEMP%\" being "C:\\Windows\\system32\\EMP" actually. */767 if (strFileDest.startsWith("%TEMP%\\", RTCString::CaseSensitive))768 {769 Utf8Str strFileDestBug = "C:\\Windows\\system32\\EMP" + strFileDest.substr(sizeof("%TEMP%\\") - sizeof(char));770 rc = pSession->fileQuerySizeInternal(strFileDestBug, &cbSizeOnGuest);771 }772 }773 #endif774 793 if ( RT_SUCCESS(rc) 775 794 && cbSize == (uint64_t)cbSizeOnGuest) … … 781 800 { 782 801 if (RT_SUCCESS(rc)) /* Size does not match. */ 783 rc = VERR_BROKEN_PIPE; /** @todo FInd a better error. */ 802 { 803 LogRel(("Size of Guest Additions installer file \"%s\" does not match: %RI64bytes copied, %RU64bytes expected\n", 804 strFileDest.c_str(), cbSizeOnGuest, cbSize)); 805 rc = VERR_BROKEN_PIPE; /** @todo Find a better error. */ 806 } 807 else 808 LogRel(("Error copying Guest Additions installer file \"%s\": %Rrc\n", 809 strFileDest.c_str(), rc)); 784 810 } 785 811 … … 798 824 AssertPtrReturn(pSession, VERR_INVALID_POINTER); 799 825 800 #ifdef VBOX_SERVICE_ENVARG_BUG801 GuestFsObjData objData;802 int rc = pSession->fileQueryInfoInternal(procInfo.mCommand, objData);803 if (RT_FAILURE(rc))804 procInfo.mCommand = "C:\\Windows\\system32\\EMP" + procInfo.mCommand.substr(sizeof("%TEMP%\\") - sizeof(char));805 #endif806 807 826 ComObjPtr<GuestProcess> pProcess; 808 rc = pSession->processCreateExInteral(procInfo, pProcess);827 int rc = pSession->processCreateExInteral(procInfo, pProcess); 809 828 if (RT_SUCCESS(rc)) 810 829 rc = pProcess->startProcess(); … … 877 896 /* 878 897 * Determine guest OS type and the required installer image. 879 * At the moment only Windows guests are supported.880 898 */ 881 Utf8Str strInstallerImage;882 883 899 ComObjPtr<Guest> pGuest(mSession->getParent()); 884 Bstr osTypeId; 885 if ( SUCCEEDED(pGuest->COMGETTER(OSTypeId(osTypeId.asOutParam()))) 886 && !osTypeId.isEmpty()) 887 { 888 Utf8Str osTypeIdUtf8(osTypeId); /* Needed for .contains(). */ 889 if ( osTypeIdUtf8.contains("Microsoft", Utf8Str::CaseInsensitive) 890 || osTypeIdUtf8.contains("Windows", Utf8Str::CaseInsensitive)) 891 { 892 if (osTypeIdUtf8.contains("64", Utf8Str::CaseInsensitive)) 893 strInstallerImage = "VBOXWINDOWSADDITIONS_AMD64.EXE"; 894 else 895 strInstallerImage = "VBOXWINDOWSADDITIONS_X86.EXE"; 896 /* Since the installers are located in the root directory, 897 * no further path processing needs to be done (yet). */ 898 } 899 else /* Everything else is not supported (yet). */ 900 { 901 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 902 Utf8StrFmt(GuestSession::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"), 903 osTypeIdUtf8.c_str())); 904 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 905 } 906 } 907 else 900 901 eOSType eOSType; 902 Utf8Str strOSType; 903 rc = getGuestProperty(pGuest, "/VirtualBox/GuestInfo/OS/Product", strOSType); 904 if ( strOSType.contains("Microsoft", Utf8Str::CaseInsensitive) 905 || strOSType.contains("Windows", Utf8Str::CaseInsensitive)) 906 { 907 eOSType = eOSType_Windows; 908 } 909 else if (strOSType.contains("Solaris", Utf8Str::CaseInsensitive)) 910 { 911 eOSType = eOSType_Solaris; 912 } 913 else /* Everything else hopefully means Linux :-). */ 914 eOSType = eOSType_Linux; 915 916 #if 1 /* Only Windows is supported (and tested) at the moment. */ 917 if (eOSType != eOSType_Windows) 908 918 { 909 919 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 910 Utf8StrFmt(GuestSession::tr("Could not detected guest OS type/version, please update manually"))); 911 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 912 } 920 Utf8StrFmt(GuestSession::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"), 921 strOSType.c_str())); 922 rc = VERR_NOT_SUPPORTED; 923 } 924 #endif 913 925 914 926 RTISOFSFILE iso; 915 927 if (RT_SUCCESS(rc)) 916 928 { 917 Assert(!strInstallerImage.isEmpty());918 919 929 /* 920 * Try to open the .ISO file and locate the specified installer.930 * Try to open the .ISO file to extract all needed files. 921 931 */ 922 932 rc = RTIsoFsOpen(&iso, mSource.c_str()); … … 929 939 else 930 940 { 941 /* Set default installation directories. */ 942 Utf8Str strInstallerDir = "/tmp/"; 943 if (eOSType == eOSType_Windows) 944 strInstallerDir = "C:\\Temp\\"; 945 931 946 rc = setProgress(5); 932 947 933 /** @todo Add support for non-Windows as well! */ 934 Utf8Str strInstallerDest = "%TEMP%\\VBoxWindowsAdditions.exe"; 935 bool fInstallCertificates = false; 936 948 /* Try looking up the Guest Additions installation directory. */ 937 949 if (RT_SUCCESS(rc)) 938 950 { 939 /* 940 * Copy over main installer to the guest. 941 */ 942 rc = copyFileToGuest(pSession, &iso, strInstallerImage, strInstallerDest, 943 false /* File is not optional */, NULL /* cbSize */); 951 rc = getGuestProperty(pGuest, "/VirtualBox/GuestAdd/InstallDir", strInstallerDir); 944 952 if (RT_SUCCESS(rc)) 945 rc = setProgress(20);946 947 /*948 * Install needed certificates for the WHQL crap.949 ** @todo Only for Windows!950 */ 953 { 954 LogRel(("Guest Additions were installed to: %ls\n", 955 strInstallerDir.c_str())); 956 rc = setProgress(8); 957 } 958 951 959 if (RT_SUCCESS(rc)) 952 960 { 953 rc = copyFileToGuest(pSession, &iso, "CERT/ORACLE_VBOX.CER", "%TEMP%\\oracle-vbox.cer", 954 true /* File is optional */, NULL /* cbSize */); 955 if (RT_SUCCESS(rc)) 961 if (eOSType == eOSType_Windows) 956 962 { 957 rc = setProgress(30); 958 if (RT_SUCCESS(rc)) 959 { 960 rc = copyFileToGuest(pSession, &iso, "CERT/VBOXCERTUTIL.EXE", "%TEMP%\\VBoxCertUtil.exe", 961 true /* File is optional */, NULL /* cbSize */); 962 if (RT_SUCCESS(rc)) 963 { 964 fInstallCertificates = true; 965 rc = setProgress(40); 966 } 967 else 968 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 969 Utf8StrFmt(GuestSession::tr("Error while copying certificate installation tool to the guest: %Rrc"), rc)); 970 } 963 strInstallerDir.findReplace('/', '\\'); 964 strInstallerDir.append("\\Update\\"); 971 965 } 972 966 else 967 strInstallerDir.append("/update/"); 968 } 969 } 970 971 LogRel(("Guest Additions update will be installed to: %s\n", 972 strInstallerDir.c_str())); 973 974 /* Prepare the file(s) we want to copy over to the guest and 975 * (maybe) want to run. */ 976 switch (eOSType) 977 { 978 case eOSType_Windows: 979 { 980 /* Our certificate. */ 981 mFiles.push_back(InstallerFile("CERT/ORACLE_VBOX.CER", "Oracle_VBox.cer", 982 UPDATEFILE_FLAG_OPTIONAL)); 983 /* Our certificate installation utility. */ 984 GuestProcessStartupInfo siCertUtil; 985 siCertUtil.mArguments.push_back(Utf8Str("add-trusted-publisher")); 986 siCertUtil.mArguments.push_back(Utf8Str(strInstallerDir + "oracle-vbox.cer")); 987 mFiles.push_back(InstallerFile("CERT/VBOXCERTUTIL.EXE", "VBoxCertUtil.exe", 988 UPDATEFILE_FLAG_OPTIONAL | UPDATEFILE_FLAG_EXECUTE, siCertUtil)); 989 /* The installers in different flavors. */ 990 mFiles.push_back(InstallerFile("VBOXWINDOWSADDITIONS_X86.EXE", 991 strInstallerDir + "VBoxWindowsAdditions_x86.exe", 992 UPDATEFILE_FLAG_NONE)); 993 mFiles.push_back(InstallerFile("VBOXWINDOWSADDITIONS_AMD64.EXE", 994 strInstallerDir + "VBoxWindowsAdditions_amd64.exe", 995 UPDATEFILE_FLAG_NONE)); 996 GuestProcessStartupInfo siInstaller; 997 siInstaller.mArguments.push_back(Utf8Str("/S")); /* We want to install in silent mode. */ 998 siInstaller.mArguments.push_back(Utf8Str("/l")); /* ... and logging enabled. */ 999 /* Don't quit VBoxService during upgrade because it still is used for this 1000 * piece of code we're in right now (that is, here!) ... */ 1001 siInstaller.mArguments.push_back(Utf8Str("/no_vboxservice_exit")); 1002 /* Tell the installer to report its current installation status 1003 * using a running VBoxTray instance via balloon messages in the 1004 * Windows taskbar. */ 1005 siInstaller.mArguments.push_back(Utf8Str("/post_installstatus")); 1006 /* If the caller does not want to wait for out guest update process to end, 1007 * complete the progress object now so that the caller can do other work. */ 1008 if (mFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly) 1009 siInstaller.mFlags |= ProcessCreateFlag_WaitForProcessStartOnly; 1010 mFiles.push_back(InstallerFile("VBOXWINDOWSADDITIONS.EXE", 1011 strInstallerDir + "VBoxWindowsAdditions.exe", 1012 UPDATEFILE_FLAG_EXECUTE, siInstaller)); 1013 break; 1014 } 1015 case eOSType_Linux: 1016 /** @todo Add Linux support. */ 1017 break; 1018 case eOSType_Solaris: 1019 /** @todo Add Solaris support. */ 1020 break; 1021 default: 1022 rc = VERR_INVALID_PARAMETER; 1023 } 1024 1025 if (RT_SUCCESS(rc)) 1026 { 1027 std::vector<InstallerFile>::const_iterator itFiles = mFiles.begin(); 1028 while (itFiles != mFiles.end()) 1029 { 1030 rc = copyFileToGuest(pSession, &iso, itFiles->strSource, itFiles->strDest, 1031 (itFiles->fFlags & UPDATEFILE_FLAG_OPTIONAL), NULL /* cbSize */); 1032 if (RT_FAILURE(rc)) 1033 { 973 1034 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 974 Utf8StrFmt(GuestSession::tr("Error while copying certificate to the guest: %Rrc"), rc)); 975 } 976 } 977 978 /* 979 * Run VBoxCertUtil.exe to install the Oracle certificate. 980 */ 981 if ( RT_SUCCESS(rc) 982 && fInstallCertificates) 983 { 984 LogRel(("Installing certificates on the guest ...\n")); 985 986 GuestProcessStartupInfo procInfo; 987 procInfo.mName = Utf8StrFmt(GuestSession::tr("VirtualBox Guest Additions Certificate Utility")); 988 procInfo.mCommand = Utf8Str("%TEMP%\\VBoxCertUtil.exe"); 989 procInfo.mFlags = ProcessCreateFlag_Hidden; 990 991 /* Construct arguments. */ 992 /** @todo Remove hardcoded paths. */ 993 procInfo.mArguments.push_back(Utf8Str("add-trusted-publisher")); 994 /* Ugly hack: Because older Guest Additions have problems with environment variable 995 expansion in parameters we have to check an alternative location on Windows. 996 So check for "%TEMP%\VBoxWindowsAdditions.exe" in a screwed up way. */ 997 #ifdef VBOX_SERVICE_ENVARG_BUG 998 GuestFsObjData objData; 999 rc = pSession->fileQueryInfoInternal("%TEMP%\\oracle-vbox.cer", objData); 1000 if (RT_SUCCESS(rc)) 1001 #endif 1002 procInfo.mArguments.push_back(Utf8Str("%TEMP%\\oracle-vbox.cer")); 1003 #ifdef VBOX_SERVICE_ENVARG_BUG 1004 else 1005 procInfo.mArguments.push_back(Utf8Str("C:\\Windows\\system32\\EMPoracle-vbox.cer")); 1006 #endif 1007 /* Overwrite rc in any case. */ 1008 rc = runFile(pSession, procInfo); 1035 Utf8StrFmt(GuestSession::tr("Error while copying file \"%s\" to \"%s\" on the guest: %Rrc"), 1036 itFiles->strSource, itFiles->strDest, rc)); 1037 break; 1038 } 1039 itFiles++; 1040 } 1009 1041 } 1010 1042 1011 1043 if (RT_SUCCESS(rc)) 1012 rc = setProgress(60); 1044 { 1045 std::vector<InstallerFile>::iterator itFiles = mFiles.begin(); 1046 while (itFiles != mFiles.end()) 1047 { 1048 rc = runFile(pSession, itFiles->mProcInfo); 1049 if (RT_FAILURE(rc)) 1050 { 1051 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 1052 Utf8StrFmt(GuestSession::tr("Error while running installer file \"%s\" on the guest: %Rrc"), 1053 itFiles->strDest, rc)); 1054 break; 1055 } 1056 itFiles++; 1057 } 1058 } 1013 1059 1014 1060 if (RT_SUCCESS(rc)) 1015 { 1016 LogRel(("Updating Guest Additions ...\n")); 1017 1018 GuestProcessStartupInfo procInfo; 1019 procInfo.mName = Utf8StrFmt(GuestSession::tr("VirtualBox Guest Additions Setup")); 1020 procInfo.mCommand = Utf8Str(strInstallerDest); 1021 procInfo.mFlags = ProcessCreateFlag_Hidden; 1022 /* If the caller does not want to wait for out guest update process to end, 1023 * complete the progress object now so that the caller can do other work. */ 1024 if (mFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly) 1025 procInfo.mFlags |= ProcessCreateFlag_WaitForProcessStartOnly; 1026 1027 /* Construct arguments. */ 1028 procInfo.mArguments.push_back(Utf8Str("/S")); /* We want to install in silent mode. */ 1029 procInfo.mArguments.push_back(Utf8Str("/l")); /* ... and logging enabled. */ 1030 /* Don't quit VBoxService during upgrade because it still is used for this 1031 * piece of code we're in right now (that is, here!) ... */ 1032 procInfo.mArguments.push_back(Utf8Str("/no_vboxservice_exit")); 1033 /* Tell the installer to report its current installation status 1034 * using a running VBoxTray instance via balloon messages in the 1035 * Windows taskbar. */ 1036 procInfo.mArguments.push_back(Utf8Str("/post_installstatus")); 1037 1038 rc = runFile(pSession, procInfo); 1039 if (RT_SUCCESS(rc)) 1040 hr = setProgressSuccess(); 1041 } 1061 hr = setProgressSuccess(); 1062 1042 1063 RTIsoFsClose(&iso); 1043 1064 }
Note:
See TracChangeset
for help on using the changeset viewer.