270 lines
7.3 KiB
Plaintext
270 lines
7.3 KiB
Plaintext
!define IsRunOnce `"" HasFlag "/runonce"`
|
|
!define IsPostInstall `"" HasFlag "/postinstall"`
|
|
!define NoRestart `"" HasFlag "/norestart"`
|
|
|
|
!macro PromptReboot
|
|
!insertmacro InhibitSleep 0
|
|
SetErrorLevel ${ERROR_SUCCESS_REBOOT_REQUIRED}
|
|
|
|
${If} ${NoRestart}
|
|
; Prompt for reboot
|
|
${IfNot} ${Silent}
|
|
${AndIfNot} ${IsPassive}
|
|
System::Call '${RestartDialog}($HWNDPARENT, "", ${EWX_REBOOT})'
|
|
${EndIf}
|
|
Quit
|
|
${Else}
|
|
; Reboot immediately
|
|
System::Call '${GetUserName}(.r0, ${NSIS_MAX_STRLEN}) .r1'
|
|
${If} ${IsRunOnce}
|
|
${AndIf} $0 == "SYSTEM"
|
|
; Running in setup mode
|
|
SetErrorLevel ${ERROR_SUCCESS}
|
|
Quit
|
|
${Else}
|
|
; Regular reboot.
|
|
Reboot
|
|
${EndIf}
|
|
${EndIf}
|
|
!macroend
|
|
|
|
!macro RunOnceOverwriteReg type root subkey name value
|
|
ClearErrors
|
|
ReadReg${type} $0 ${root} "${subkey}" "${name}"
|
|
${IfNot} ${Errors}
|
|
WriteReg${type} ${root} "${subkey}" "${name}_LegacyUpdateTemp" $0
|
|
${EndIf}
|
|
WriteReg${type} ${root} "${subkey}" "${name}" `${value}`
|
|
!macroend
|
|
|
|
!macro RunOnceRestoreReg type root subkey name fallback
|
|
ClearErrors
|
|
ReadReg${type} $0 ${root} "${subkey}" "${name}_LegacyUpdateTemp"
|
|
${If} ${Errors}
|
|
!if "${fallback}" == "-"
|
|
DeleteRegValue ${root} "${subkey}" "${name}"
|
|
!else
|
|
WriteReg${type} ${root} "${subkey}" "${name}" `${fallback}`
|
|
!endif
|
|
${Else}
|
|
WriteReg${type} ${root} "${subkey}" "${name}" $0
|
|
DeleteRegValue ${root} "${subkey}" "${name}_LegacyUpdateTemp"
|
|
${EndIf}
|
|
!macroend
|
|
|
|
Function CleanUpRunOnce
|
|
; Restore setup keys
|
|
; Be careful here. Doing this wrong can cause SYSTEM_LICENSE_VIOLATION bootloops!
|
|
!insertmacro RunOnceRestoreReg Str HKLM "${REGPATH_SETUP}" "CmdLine" ""
|
|
!insertmacro RunOnceRestoreReg Dword HKLM "${REGPATH_SETUP}" "SetupType" ${SETUP_TYPE_NORMAL}
|
|
DeleteRegValue HKLM "${REGPATH_SETUP}" "SetupShutdownRequired"
|
|
|
|
${If} ${Abort}
|
|
Call CleanUpRunOnceFinal
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
Function CleanUpRunOnceFinal
|
|
; Enable keys we disabled if needed
|
|
${If} ${IsWinXP2002}
|
|
!insertmacro RunOnceRestoreReg Dword HKLM "${REGPATH_SECURITYCENTER}" "FirstRunDisabled" "-"
|
|
${EndIf}
|
|
|
|
${If} ${AtLeastWin8}
|
|
!insertmacro RunOnceRestoreReg Dword HKLM "${REGPATH_POLICIES_SYSTEM}" "EnableFirstLogonAnimation" "-"
|
|
${EndIf}
|
|
|
|
; Delete runonce stuff
|
|
RMDir /r /REBOOTOK "${RUNONCEDIR}"
|
|
|
|
; Delete IE6 temp files
|
|
RMDir /r /REBOOTOK "$WINDIR\Windows Update Setup Files"
|
|
FunctionEnd
|
|
|
|
Function CopyLauncher
|
|
${If} ${IsNativeAMD64}
|
|
File /ONAME=LegacyUpdate.exe "..\launcher\obj\LegacyUpdate64.exe"
|
|
${Else}
|
|
File /ONAME=LegacyUpdate.exe "..\launcher\obj\LegacyUpdate32.exe"
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
Var /GLOBAL RunOnce.UseFallback
|
|
|
|
Function PrepareRunOnce
|
|
${If} ${RebootFlag}
|
|
${IfNot} ${IsRunOnce}
|
|
; Copy to runonce path to ensure installer is accessible by the temp user
|
|
CreateDirectory "${RUNONCEDIR}"
|
|
SetOutPath "${RUNONCEDIR}"
|
|
CopyFiles /SILENT "$EXEPATH" "${RUNONCEDIR}\LegacyUpdateSetup.exe"
|
|
Call CopyLauncher
|
|
|
|
; Remove mark of the web to prevent "Open File - Security Warning" dialog
|
|
Delete "${RUNONCEDIR}\LegacyUpdateSetup.exe:Zone.Identifier"
|
|
${EndIf}
|
|
|
|
${If} $RunOnce.UseFallback == 1
|
|
WriteRegStr HKLM "${REGPATH_RUNONCE}" "LegacyUpdateRunOnce" '"${RUNONCEDIR}\LegacyUpdateSetup.exe" /runonce'
|
|
${Else}
|
|
; Somewhat documented in KB939857:
|
|
; https://web.archive.org/web/20090723061647/http://support.microsoft.com/kb/939857
|
|
; See also Wine winternl.h
|
|
!insertmacro RunOnceOverwriteReg Str HKLM "${REGPATH_SETUP}" "CmdLine" '"${RUNONCEDIR}\LegacyUpdate.exe" /runonce'
|
|
!insertmacro RunOnceOverwriteReg Dword HKLM "${REGPATH_SETUP}" "SetupType" ${SETUP_TYPE_NOREBOOT}
|
|
WriteRegDword HKLM "${REGPATH_SETUP}" "SetupShutdownRequired" ${SETUP_SHUTDOWN_REBOOT}
|
|
${EndIf}
|
|
|
|
; Temporarily disable Security Center first run if needed
|
|
${If} ${IsWinXP2002}
|
|
${AndIfNot} ${AtLeastServicePack} 2
|
|
${VerbosePrint} "Disabling Security Center first run"
|
|
!insertmacro RunOnceOverwriteReg Dword HKLM "${REGPATH_SECURITYCENTER}" "FirstRunDisabled" 1
|
|
${EndIf}
|
|
|
|
; Temporarily disable logon animation if needed
|
|
${If} ${AtLeastWin8}
|
|
${VerbosePrint} "Disabling first logon animation"
|
|
!insertmacro RunOnceOverwriteReg Dword HKLM "${REGPATH_POLICIES_SYSTEM}" "EnableFirstLogonAnimation" 0
|
|
${EndIf}
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
Function RebootIfRequired
|
|
${MementoSectionSave}
|
|
${If} ${RebootFlag}
|
|
; Give the user a moment to understand we're rebooting
|
|
${DetailPrint} "$(StatusRestarting)"
|
|
Sleep 2000
|
|
|
|
; Now reboot
|
|
Call PrepareRunOnce
|
|
!insertmacro PromptReboot
|
|
${Else}
|
|
; Restore setup keys
|
|
Call CleanUpRunOnce
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
Function OnRunOnceLogon
|
|
; To be safe in case we crash, immediately restore setup keys. We'll set them again if needed.
|
|
Call CleanUpRunOnce
|
|
|
|
; If we're in the middle of installing a service pack, the system will reboot without notice. Be prepared for that
|
|
; to happen.
|
|
ClearErrors
|
|
EnumRegKey $1 HKLM "${REGPATH_CBS_REBOOTINPROGRESS}" 0
|
|
${IfNot} ${Errors}
|
|
; System will reboot without notice. Be prepared for that to happen.
|
|
${VerbosePrint} "CBS reboot is pending"
|
|
Call PrepareRunOnce
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
!macro SetMarquee state
|
|
Push $0
|
|
FindWindow $0 "#32770" "" $HWNDPARENT
|
|
FindWindow $0 "msctls_progress32" "" $0
|
|
!if ${state} == 1
|
|
${NSD_AddStyle} $0 ${PBS_MARQUEE}
|
|
SendMessage $0 ${PBM_SETMARQUEE} 1 100
|
|
!else
|
|
${NSD_RemoveStyle} $0 ${PBS_MARQUEE}
|
|
!endif
|
|
Pop $0
|
|
!macroend
|
|
|
|
Function PollCbsInstall
|
|
${IfNot} ${AtLeastWinVista}
|
|
Return
|
|
${EndIf}
|
|
|
|
ReadRegDWORD $0 HKLM "${REGPATH_CBS}" "ExecuteState"
|
|
${If} $0 == ${CBS_EXECUTE_STATE_NONE}
|
|
${OrIf} $0 == ${CBS_EXECUTE_STATE_NONE2}
|
|
Return
|
|
${EndIf}
|
|
|
|
${VerbosePrint} "Packages are still installing [$0]"
|
|
${DetailPrint} "$(StatusCbsInstalling)"
|
|
|
|
; Set marquee progress bar
|
|
!insertmacro SetMarquee 1
|
|
|
|
${While} 1 == 1
|
|
; Are we in a RebootInProgress phase?
|
|
ClearErrors
|
|
EnumRegKey $1 HKLM "${REGPATH_CBS_REBOOTINPROGRESS}" 0
|
|
${IfNot} ${Errors}
|
|
; Spin forever. TrustedInstaller will reboot on its own.
|
|
${While} 1 == 1
|
|
Sleep 10000
|
|
${EndWhile}
|
|
${EndIf}
|
|
|
|
; Poll ExecuteState, waiting for TrustedInstaller to be done.
|
|
ReadRegDWORD $0 HKLM "${REGPATH_CBS}" "ExecuteState"
|
|
${If} $0 == ${CBS_EXECUTE_STATE_NONE}
|
|
${OrIf} $0 == ${CBS_EXECUTE_STATE_NONE2}
|
|
${Break}
|
|
${EndIf}
|
|
|
|
Sleep 1000
|
|
${EndWhile}
|
|
|
|
; Revert progress bar
|
|
!insertmacro SetMarquee 0
|
|
FunctionEnd
|
|
|
|
Function RebootIfCbsRebootPending
|
|
${IfNot} ${AtLeastWinVista}
|
|
Return
|
|
${EndIf}
|
|
|
|
StrCpy $1 0
|
|
|
|
ReadRegDWORD $0 HKLM "${REGPATH_CBS}" "ExecuteState"
|
|
${If} $0 != ${CBS_EXECUTE_STATE_NONE}
|
|
${AndIf} $0 != ${CBS_EXECUTE_STATE_NONE2}
|
|
StrCpy $1 1
|
|
${EndIf}
|
|
|
|
ClearErrors
|
|
EnumRegKey $0 HKLM "${REGPATH_CBS_REBOOTPENDING}" 0
|
|
${IfNot} ${Errors}
|
|
StrCpy $1 1
|
|
${EndIf}
|
|
|
|
EnumRegKey $0 HKLM "${REGPATH_CBS_PACKAGESPENDING}" 0
|
|
${IfNot} ${Errors}
|
|
StrCpy $1 1
|
|
${EndIf}
|
|
|
|
${If} $1 == 1
|
|
${VerbosePrint} "Restarting to install previously pending packages"
|
|
SetRebootFlag true
|
|
Call RebootIfRequired
|
|
${EndIf}
|
|
FunctionEnd
|
|
|
|
Function OnRunOnceDone
|
|
${If} ${IsRunOnce}
|
|
${AndIfNot} ${Abort}
|
|
; Set up postinstall runonce
|
|
${VerbosePrint} "Preparing postinstall"
|
|
WriteRegStr HKLM "${REGPATH_RUNONCE}" "LegacyUpdatePostInstall" '"${RUNONCEDIR}\LegacyUpdateSetup.exe" /postinstall'
|
|
|
|
System::Call '${GetUserName}(.r0, ${NSIS_MAX_STRLEN}) .r1'
|
|
${If} $0 == "SYSTEM"
|
|
; Configure winlogon to proceed to the logon dialog
|
|
Call CleanUpRunOnce
|
|
; Reboot
|
|
${DetailPrint} "$(StatusRestarting)"
|
|
Sleep 2000
|
|
Reboot
|
|
; Just to be sure
|
|
Sleep 10000
|
|
${EndIf}
|
|
${EndIf}
|
|
FunctionEnd
|