diff options
Diffstat (limited to 'src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh')
-rw-r--r-- | src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh | 358 |
1 files changed, 215 insertions, 143 deletions
diff --git a/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh b/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh index 6e377ddc..61615221 100644 --- a/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh +++ b/src/VBox/Additions/WINNT/Installer/VBoxGuestAdditionsCommon.nsh @@ -4,7 +4,7 @@ ; ; -; Copyright (C) 2006-2012 Oracle Corporation +; Copyright (C) 2006-2014 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -136,7 +136,7 @@ Function ExtractFiles FILE "$%PATH_OUT%\bin\additions\wined3dwddm-x86.dll" !endif ; $%VBOX_WITH_CROGL% == "1" !endif ; $%BUILD_TARGET_ARCH% == "amd64" - + !if $%VBOX_WITH_WDDM_W8% == "1" ; WDDM Video driver for Win8 SetOutPath "$0\VBoxVideoW8" @@ -246,83 +246,6 @@ Function ExtractFiles FunctionEnd !endif ; UNINSTALLER_ONLY -!macro EnableLog un -Function ${un}EnableLog - -!ifdef _DEBUG - Goto log -!endif - - StrCmp $g_bLogEnable "true" log - Goto exit - -log: - - LogSet on - LogText "Start logging." - -exit: - -FunctionEnd -!macroend -!insertmacro EnableLog "" -!insertmacro EnableLog "un." - -!macro WriteLogUI un -Function ${un}WriteLogUI - - IfSilent exit - -!ifdef _DEBUG - Goto log -!endif - - StrCmp $g_bLogEnable "true" log - Goto exit - -log: - - ; Dump log to see what happened - StrCpy $0 "$INSTDIR\${un}install_ui.log" - Push $0 - Call ${un}DumpLog - -exit: - -FunctionEnd -!macroend -!insertmacro WriteLogUI "" -!insertmacro WriteLogUI "un." - -!macro WriteLogVBoxTray un -Function ${un}WriteLogVBoxTray - - ; Pop function parameters off the stack - ; in reverse order - Exch $1 ; Message type (0=Info, 1=Warning, 2=Error) - Exch - Exch $0 ; Body string - - ; @todo Add more paramters here! -!if $%VBOX_WITH_GUEST_INSTALL_HELPER% == "1" - ${If} $g_bPostInstallStatus == "true" - ; Parameters: - ; - String: Description / Body - ; - String: Title / Name of application - ; - Integer: Type of message: 0 (Info), 1 (Warning), 2 (Error) - ; - Integer: Time (in msec) to show the notification - VBoxGuestInstallHelper::VBoxTrayShowBallonMsg "$0" "VirtualBox Guest Additions Setup" $1 5000 - Pop $0 ; Get return value (ignored for now) - ${EndIf} -!endif - Pop $0 - Pop $1 - -FunctionEnd -!macroend -!insertmacro WriteLogVBoxTray "" -!insertmacro WriteLogVBoxTray "un." - !macro CheckArchitecture un Function ${un}CheckArchitecture @@ -353,43 +276,51 @@ FunctionEnd !insertmacro CheckArchitecture "" !insertmacro CheckArchitecture "un." -!macro GetWindowsVer un -Function ${un}GetWindowsVer +; +; Macro for retrieving the Windows version this installer is running on. +; +; @return Stack: Windows version string. Empty on error / +; if not able to identify. +; +!macro GetWindowsVersionEx un +Function ${un}GetWindowsVersionEx - ; Check if we are running on w2k or above - ; For other windows versions (>XP) it may be necessary to change winver.nsh - Call ${un}GetWindowsVersion - Pop $R3 ; Windows Version + Push $0 + Push $1 - Push $R3 ; The windows version string - Push "NT" ; String to search for. Win 2k family returns no string containing 'NT' - Call ${un}StrStr - Pop $R0 - StrCmp $R0 '' nt5plus ; Not NT 3.XX or 4.XX + ; Check if we are running on Windows 2000 or above + ; For other windows versions (> XP) it may be necessary to change winver.nsh + Call ${un}GetWindowsVersion + Pop $0 ; Windows Version - ; Ok we know it is NT. Must be a string like NT X.XX - Push $R3 ; The windows version string - Push "4." ; String to search for + Push $0 ; The windows version string + Push "NT" ; String to search for. W2K+ returns no string containing "NT" Call ${un}StrStr - Pop $R0 - StrCmp $R0 "" nt5plus nt4 ; If empty -> not NT 4 - -nt5plus: ; Windows 2000+ (XP, Vista, ...) - - StrCpy $g_strWinVersion $R3 - goto exit - -nt4: ; NT 4.0 + Pop $1 - StrCpy $g_strWinVersion "NT4" - goto exit + ${If} $1 == "" ; If empty -> not NT 3.XX or 4.XX + ; $0 contains the original version string + ${Else} + ; Ok we know it is NT. Must be a string like NT X.XX + Push $0 ; The windows version string + Push "4." ; String to search for + Call ${un}StrStr + Pop $1 + ${If} $1 == "" ; If empty -> not NT 4 + ;; @todo NT <= 3.x ? + ; $0 contains the original version string + ${Else} + StrCpy $0 "NT4" + ${EndIf} + ${EndIf} -exit: + Pop $1 + Exch $0 FunctionEnd !macroend -!insertmacro GetWindowsVer "" -!insertmacro GetWindowsVer "un." +!insertmacro GetWindowsVersionEx "" +!insertmacro GetWindowsVersionEx "un." !macro GetAdditionsVersion un Function ${un}GetAdditionsVersion @@ -465,22 +396,22 @@ Function ${un}StopVBoxService Push $3 ; Safety counter StrCpy $3 "0" ; Init counter - DetailPrint "Stopping VBoxService ..." + ${LogVerbose} "Stopping VBoxService ..." svc_stop: - LogText "Stopping VBoxService (as service) ..." + ${LogVerbose} "Stopping VBoxService via SCM ..." ${If} $g_strWinVersion == "NT4" - nsExec::Exec '"$SYSDIR\net.exe" stop VBoxService' + nsExec::Exec '"$SYSDIR\net.exe" stop VBoxService' ${Else} - nsExec::Exec '"$SYSDIR\SC.exe" stop VBoxService' + nsExec::Exec '"$SYSDIR\SC.exe" stop VBoxService' ${EndIf} Sleep "1000" ; Wait a bit exe_stop: !ifdef _DEBUG - DetailPrint "Stopping VBoxService (as exe) ..." + ${LogVerbose} "Stopping VBoxService (as exe) ..." !endif exe_stop_loop: @@ -488,7 +419,9 @@ exe_stop_loop: IntCmp $3 10 exit ; Only try this loop 10 times max IntOp $3 $3 + 1 ; Increment - LogText "Try: $3" +!ifdef _DEBUG + ${LogVerbose} "Stopping attempt #$3" +!endif ${If} $g_strWinVersion == "NT4" StrCpy $2 "VBoxServiceNT.exe" @@ -500,12 +433,12 @@ exe_stop_loop: StrCmp $0 0 0 exit ${nsProcess::KillProcess} $2 $0 - Sleep "1000" ; Wait a bit + Sleep "1000" ; Wait a bit Goto exe_stop_loop exit: - DetailPrint "Stopping VBoxService done." + ${LogVerbose} "Stopping VBoxService done" Pop $3 Pop $2 @@ -524,7 +457,7 @@ Function ${un}StopVBoxTray Push $1 ; Safety counter StrCpy $1 "0" ; Init counter - DetailPrint "Stopping VBoxTray ..." + ${LogVerbose} "Stopping VBoxTray ..." exe_stop: @@ -540,7 +473,7 @@ exe_stop: exit: - DetailPrint "Stopping VBoxTray done." + ${LogVerbose} "Stopping VBoxTray done" Pop $1 Pop $0 @@ -590,12 +523,12 @@ FunctionEnd !macro AbortShutdown un Function ${un}AbortShutdown - Push $0 - - ; Try to abort the shutdown - nsExec::ExecToLog '"$g_strSystemDir\shutdown.exe" -a' $0 - - Pop $0 + ${If} ${FileExists} "$g_strSystemDir\shutdown.exe" + ; Try to abort the shutdown + ${CmdExecute} "$\"$g_strSystemDir\shutdown.exe$\" -a" "true" + ${Else} + ${LogVerbose} "Shutting down not supported: Binary $\"$g_strSystemDir\shutdown.exe$\" not found" + ${EndIf} FunctionEnd !macroend @@ -607,15 +540,19 @@ Function ${un}CheckForWDDMCapability !if $%VBOX_WITH_WDDM% == "1" ; If we're on a 32-bit Windows Vista / 7 / 8 we can use the WDDM driver - ${If} $g_strWinVersion == "Vista" + ${If} $g_strWinVersion == "Vista" ${OrIf} $g_strWinVersion == "7" ${OrIf} $g_strWinVersion == "8" + ${OrIf} $g_strWinVersion == "8_1" StrCpy $g_bCapWDDM "true" + ${LogVerbose} "OS is WDDM driver capable" ${EndIf} ; If we're on Windows 8 we *have* to use the WDDM driver, so select it ; by default - ${If} $g_strWinVersion == "8" + ${If} $g_strWinVersion == "8" + ${OrIf} $g_strWinVersion == "8_1" StrCpy $g_bWithWDDM "true" + ${LogVerbose} "OS needs WDDM driver by default" ${EndIf} !endif @@ -634,10 +571,12 @@ Function ${un}CheckForCapabilities StrCpy $g_iSystemMode $0 ; Does the guest have a DLL cache? - ${If} $g_strWinVersion == "Vista" + ${If} $g_strWinVersion == "Vista" ${OrIf} $g_strWinVersion == "7" ${OrIf} $g_strWinVersion == "8" + ${OrIf} $g_strWinVersion == "8_1" StrCpy $g_bCapDllCache "true" + ${LogVerbose} "OS has a DLL cache" ${EndIf} ; Check whether this OS is capable of handling WDDM drivers @@ -836,15 +775,15 @@ FunctionEnd Push "${Architecture}" Push "${Vendor}" Push "${File}" - DetailPrint "Verifying file $\"${File}$\" ..." + ${LogVerbose} "Verifying file $\"${File}$\" ..." Call ${un}VerifyFile Pop $0 ${If} $0 == "0" - DetailPrint "Verification of file $\"${File}$\" successful (Vendor: ${Vendor}, Architecture: ${Architecture})" + ${LogVerbose} "Verification of file $\"${File}$\" successful (Vendor: ${Vendor}, Architecture: ${Architecture})" ${ElseIf} $0 == "1" - DetailPrint "Verification of file $\"${File}$\" failed (not Vendor: ${Vendor}, and/or not Architecture: ${Architecture})" + ${LogVerbose} "Verification of file $\"${File}$\" failed (not Vendor: ${Vendor}, and/or not Architecture: ${Architecture})" ${Else} - DetailPrint "Skipping to file $\"${File}$\"; not found" + ${LogVerbose} "Skipping to file $\"${File}$\"; not found" ${EndIf} ; Push result popped off the stack to stack again Push $0 @@ -852,7 +791,7 @@ FunctionEnd !define VerifyFileEx "!insertmacro VerifyFileEx" ; -; Macro for copying a file only if the source file is verified +; Macro for copying a file only if the source file is verified ; to be from a certain vendor and architecture. ; @return Stack: "0" if copied, "1" if not, "2" on error / not found. ; @param Un/Installer prefix; either "" or "un". @@ -865,14 +804,24 @@ FunctionEnd Push $0 Push "${Architecture}" Push "${Vendor}" - Push "${FileSrc}" + Push "${FileSrc}" Call ${un}VerifyFile Pop $0 ${If} $0 == "0" - DetailPrint "Copying verified file $\"${FileSrc}$\" to $\"${FileDest}$\" ..." + ${LogVerbose} "Copying verified file $\"${FileSrc}$\" to $\"${FileDest}$\" ..." + ClearErrors + SetOverwrite on CopyFiles /SILENT "${FileSrc}" "${FileDest}" + ${If} ${Errors} + CreateDirectory "$TEMP\${PRODUCT_NAME}" + ${GetFileName} "${FileSrc}" $0 ; Get the base name + CopyFiles /SILENT "${FileSrc}" "$TEMP\${PRODUCT_NAME}\$0" + ${LogVerbose} "Immediate installation failed, postponing to next reboot (temporary location is: $\"$TEMP\${PRODUCT_NAME}\$0$\") ..." + ;${InstallFileEx} "${un}" "${FileSrc}" "${FileDest}" "$TEMP" ; Only works with compile time files! + System::Call "kernel32::MoveFileEx(t '$TEMP\${PRODUCT_NAME}\$0', t '${FileDest}', i 5)" + ${EndIf} ${Else} - DetailPrint "Skipping to copy file $\"${FileSrc}$\" to $\"${FileDest}$\" (not Vendor: ${Vendor}, Architecture: ${Architecture})" + ${LogVerbose} "Skipping to copy file $\"${FileSrc}$\" to $\"${FileDest}$\" (not Vendor: ${Vendor}, Architecture: ${Architecture})" ${EndIf} ; Push result popped off the stack to stack again Push $0 @@ -883,12 +832,12 @@ FunctionEnd ; Macro for installing a library/DLL. ; @return Stack: "0" if copied, "1" if not, "2" on error / not found. ; @param Un/Installer prefix; either "" or "un". -; @param Name of lib/DLL to verify and copy to destination. -; @param Destination name to copy verified file to. +; @param Name of lib/DLL to copy to destination. +; @param Destination name to copy the source file to. ; @param Temporary folder used for exchanging the (locked) lib/DLL after a reboot. ; !macro InstallFileEx un FileSrc FileDest DirTemp - DetailPrint "Installing library $\"${FileSrc}$\" to $\"${FileDest}$\" ..." + ${LogVerbose} "Installing library $\"${FileSrc}$\" to $\"${FileDest}$\" ..." ; Try the gentle way and replace the file instantly !insertmacro InstallLib DLL NOTSHARED NOREBOOT_NOTPROTECTED "${FileSrc}" "${FileDest}" "${DirTemp}" ; If the above call didn't help, use a (later) reboot to replace the file @@ -911,19 +860,75 @@ FunctionEnd Push "${Architecture}" Push "${Vendor}" Push "${FileSrc}" - DetailPrint "Verifying library $\"${FileSrc}$\" ..." + ${LogVerbose} "Verifying library $\"${FileSrc}$\" ..." Call ${un}VerifyFile Pop $0 ${If} $0 == "0" ${InstallFileEx} ${un} ${FileSrc} ${FileDest} ${DirTemp} ${Else} - DetailPrint "File $\"${FileSrc}$\" did not pass verification (Vendor: ${Vendor}, Architecture: ${Architecture})" + ${LogVerbose} "File $\"${FileSrc}$\" did not pass verification (Vendor: ${Vendor}, Architecture: ${Architecture})" ${EndIf} ; Push result popped off the stack to stack again. Push $0 !macroend !define InstallFileVerify "!insertmacro InstallFileVerify" +; Prepares the access rights for replacing +; a WRP (Windows Resource Protection) protected file +!macro PrepareWRPFile un +Function ${un}PrepareWRPFile + + Pop $0 + Push $1 + + ${IfNot} ${FileExists} "$0" + ${LogVerbose} "WRP: File $\"$0$\" does not exist, skipping" + Return + ${EndIf} + + ${If} ${FileExists} "$g_strSystemDir\takeown.exe" + ${CmdExecute} "$\"$g_strSystemDir\takeown.exe$\" /F $\"$0$\"" "true" + ${Else} + ${LogVerbose} "WRP: Warning: takeown.exe not found, skipping" + ${EndIf} + + AccessControl::SetFileOwner "$0" "(S-1-5-32-545)" + Pop $1 + ${LogVerbose} "WRP: Setting file owner for $\"$0$\" returned: $1" + + AccessControl::GrantOnFile "$0" "(S-1-5-32-545)" "FullAccess" + Pop $1 + ${LogVerbose} "WRP: Setting access rights for $\"$0$\" returned: $1" + +!if $%VBOX_WITH_GUEST_INSTALL_HELPER% == "1" + !ifdef WFP_FILE_EXCEPTION + VBoxGuestInstallHelper::DisableWFP "$0" + Pop $1 ; Get return value (ignored for now) + ${LogVerbose} "WRP: Setting WFP exception for $\"$0$\" returned: $1" + !endif +!endif + + Pop $1 + +FunctionEnd +!macroend +!insertmacro PrepareWRPFile "" +!insertmacro PrepareWRPFile "un." + +; +; Macro for preparing the access rights for replacing +; a WRP (Windows Resource Protection) protected file. +; @return None. +; @param Path of file to prepare. +; +!macro PrepareWRPFileEx un FileSrc + Push $0 + Push "${FileSrc}" + Call ${un}PrepareWRPFile + Pop $0 +!macroend +!define PrepareWRPFileEx "!insertmacro PrepareWRPFileEx" + ; ; Validates backed up and replaced Direct3D files; either the d3d*.dll have ; to be from Microsoft or the (already) backed up msd3d*.dll files. If both @@ -936,13 +941,13 @@ Function ${un}ValidateD3DFiles Push $0 ; We need to switch to 64-bit app mode to handle the "real" 64-bit files in - ; ""system32" on a 64-bit guest + ; "system32" on a 64-bit guest Call ${un}SetAppMode64 ; Note: Not finding a file (like *d3d8.dll) on Windows Vista/7 is fine; ; it simply is not present there. - - ; Note 2: On 64-bit systems there are no 64-bit *d3d8 DLLs, only 32-bit ones + + ; Note 2: On 64-bit systems there are no 64-bit *d3d8 DLLs, only 32-bit ones ; in SysWOW64 (or in system32 on 32-bit systems). !if $%BUILD_TARGET_ARCH% == "x86" @@ -952,7 +957,7 @@ Function ${un}ValidateD3DFiles Goto verify_msd3d ${EndIf} !endif - + ${VerifyFileEx} "${un}" "$SYSDIR\d3d9.dll" "Microsoft Corporation" "$%BUILD_TARGET_ARCH%" Pop $0 ${If} $0 == "1" @@ -1079,3 +1084,70 @@ FunctionEnd !macroend !insertmacro ValidateFilesDirect3D "" !insertmacro ValidateFilesDirect3D "un." + +; +; Restores formerly backed up Direct3D original files, which were replaced by +; a VBox XPDM driver installation before. This might be necessary for upgrading a +; XPDM installation to a WDDM one. +; @return Stack: "0" if files were restored successfully; otherwise "1". +; +!macro RestoreFilesDirect3D un +Function ${un}RestoreFilesDirect3D + + Push $0 + + ; We need to switch to 64-bit app mode to handle the "real" 64-bit files in + ; "system32" on a 64-bit guest + Call ${un}SetAppMode64 + + ; Note: Not finding a file (like *d3d8.dll) on Windows Vista/7 is fine; + ; it simply is not present there. + + ; Note 2: On 64-bit systems there are no 64-bit *d3d8 DLLs, only 32-bit ones + ; in SysWOW64 (or in system32 on 32-bit systems). + + ${LogVerbose} "Restoring original D3D files ..." +!if $%BUILD_TARGET_ARCH% == "x86" + ${PrepareWRPFileEx} "${un}" "$SYSDIR\d3d8.dll" + ${CopyFileEx} "${un}" "$SYSDIR\msd3d8.dll" "$SYSDIR\d3d8.dll" "Microsoft Corporation" "$%BUILD_TARGET_ARCH%" +!endif + ${PrepareWRPFileEx} "${un}" "$SYSDIR\d3d9.dll" + ${CopyFileEx} "${un}" "$SYSDIR\msd3d9.dll" "$SYSDIR\d3d9.dll" "Microsoft Corporation" "$%BUILD_TARGET_ARCH%" + + ${If} $g_bCapDllCache == "true" +!if $%BUILD_TARGET_ARCH% == "x86" + ${PrepareWRPFileEx} "${un}" "$SYSDIR\dllcache\d3d8.dll" + ${CopyFileEx} "${un}" "$SYSDIR\dllcache\msd3d8.dll" "$SYSDIR\dllcache\d3d8.dll" "Microsoft Corporation" "$%BUILD_TARGET_ARCH%" +!endif + ${PrepareWRPFileEx} "${un}" "$SYSDIR\dllcache\d3d9.dll" + ${CopyFileEx} "${un}" "$SYSDIR\dllcache\msd3d9.dll" "$SYSDIR\dllcache\d3d9.dll" "Microsoft Corporation" "$%BUILD_TARGET_ARCH%" + ${EndIf} + +!if $%BUILD_TARGET_ARCH% == "amd64" + ${PrepareWRPFileEx} "${un}" "$g_strSysWow64\d3d8.dll" + ${CopyFileEx} "${un}" "$g_strSysWow64\msd3d8.dll" "$g_strSysWow64\d3d8.dll" "Microsoft Corporation" "x86" + ${PrepareWRPFileEx} "${un}" "$g_strSysWow64\d3d9.dll" + ${CopyFileEx} "${un}" "$g_strSysWow64\msd3d9.dll" "$g_strSysWow64\d3d9.dll" "Microsoft Corporation" "x86" + + ${If} $g_bCapDllCache == "true" + ${PrepareWRPFileEx} "${un}" "$g_strSysWow64\dllcache\d3d8.dll" + ${CopyFileEx} "${un}" "$g_strSysWow64\dllcache\msd3d8.dll" "$g_strSysWow64\dllcache\d3d8.dll" "Microsoft Corporation" "x86" + ${PrepareWRPFileEx} "${un}" "$g_strSysWow64\dllcache\d3d9.dll" + ${CopyFileEx} "${un}" "$g_strSysWow64\dllcache\msd3d9.dll" "$g_strSysWow64\dllcache\d3d9.dll" "Microsoft Corporation" "x86" + ${EndIf} +!endif + + ; Do a re-validation afterwards. + Call ${un}ValidateD3DFiles + Pop $0 + ${If} $0 == "1" ; D3D files are invalid + ${LogVerbose} $(VBOX_UNINST_UNABLE_TO_RESTORE_D3D) + MessageBox MB_ICONSTOP|MB_OK $(VBOX_UNINST_UNABLE_TO_RESTORE_D3D) /SD IDOK + ${EndIf} + + Exch $0 + +FunctionEnd +!macroend +!insertmacro RestoreFilesDirect3D "" +!insertmacro RestoreFilesDirect3D "un." |