michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: # file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: # Required Plugins: michael@0: # AppAssocReg michael@0: # CertCheck michael@0: # InetBgDL michael@0: # ShellLink michael@0: # UAC michael@0: michael@0: ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs michael@0: !verbose 3 michael@0: michael@0: SetDatablockOptimize on michael@0: SetCompress off michael@0: CRCCheck on michael@0: michael@0: RequestExecutionLevel user michael@0: michael@0: ; The commands inside this ifdef require NSIS 3.0a2 or greater so the ifdef can michael@0: ; be removed after we require NSIS 3.0a2 or greater. michael@0: !ifdef NSIS_PACKEDVERSION michael@0: Unicode true michael@0: ManifestSupportedOS all michael@0: ManifestDPIAware true michael@0: !endif michael@0: michael@0: !addplugindir ./ michael@0: michael@0: Var Dialog michael@0: Var Progressbar michael@0: Var ProgressbarMarqueeIntervalMS michael@0: Var LabelDownloading michael@0: Var LabelInstalling michael@0: Var LabelFreeSpace michael@0: Var CheckboxSetAsDefault michael@0: Var CheckboxShortcutOnBar ; Used for Quicklaunch or Taskbar as appropriate michael@0: Var CheckboxShortcutInStartMenu michael@0: Var CheckboxShortcutOnDesktop michael@0: Var CheckboxSendPing michael@0: Var CheckboxInstallMaintSvc michael@0: Var DirRequest michael@0: Var ButtonBrowse michael@0: Var LabelBlurb1 michael@0: Var LabelBlurb2 michael@0: Var LabelBlurb3 michael@0: Var BitmapBlurb1 michael@0: Var BitmapBlurb2 michael@0: Var BitmapBlurb3 michael@0: Var HwndBitmapBlurb1 michael@0: Var HwndBitmapBlurb2 michael@0: Var HWndBitmapBlurb3 michael@0: michael@0: Var FontNormal michael@0: Var FontItalic michael@0: Var FontBlurb michael@0: michael@0: Var WasOptionsButtonClicked michael@0: Var CanWriteToInstallDir michael@0: Var HasRequiredSpaceAvailable michael@0: Var IsDownloadFinished michael@0: Var DownloadSizeBytes michael@0: Var HalfOfDownload michael@0: Var DownloadReset michael@0: Var ExistingTopDir michael@0: Var SpaceAvailableBytes michael@0: Var InitialInstallDir michael@0: Var HandleDownload michael@0: Var CanSetAsDefault michael@0: Var InstallCounterStep michael@0: Var InstallStepSize michael@0: Var InstallTotalSteps michael@0: Var TmpVal michael@0: michael@0: Var ExitCode michael@0: Var FirefoxLaunchCode michael@0: michael@0: ; The first three tick counts are for the start of a phase and equate equate to michael@0: ; the display of individual installer pages. michael@0: Var StartIntroPhaseTickCount michael@0: Var StartOptionsPhaseTickCount michael@0: Var StartDownloadPhaseTickCount michael@0: ; Since the Intro and Options pages can be displayed multiple times the total michael@0: ; seconds spent on each of these pages is reported. michael@0: Var IntroPhaseSeconds michael@0: Var OptionsPhaseSeconds michael@0: ; The tick count for the last download. michael@0: Var StartLastDownloadTickCount michael@0: ; The number of seconds from the start of the download phase until the first michael@0: ; bytes are received. This is only recorded for first request so it is possible michael@0: ; to determine connection issues for the first request. michael@0: Var DownloadFirstTransferSeconds michael@0: ; The last four tick counts are for the end of a phase in the installation page. michael@0: Var EndDownloadPhaseTickCount michael@0: Var EndPreInstallPhaseTickCount michael@0: Var EndInstallPhaseTickCount michael@0: Var EndFinishPhaseTickCount michael@0: michael@0: Var InitialInstallRequirementsCode michael@0: Var ExistingProfile michael@0: Var ExistingVersion michael@0: Var ExistingBuildID michael@0: Var DownloadedBytes michael@0: Var DownloadRetryCount michael@0: Var OpenedDownloadPage michael@0: Var DownloadServerIP michael@0: michael@0: Var ControlHeightPX michael@0: Var ControlRightPX michael@0: michael@0: ; Uncomment the following to prevent pinging the metrics server when testing michael@0: ; the stub installer michael@0: ;!define STUB_DEBUG michael@0: michael@0: !define StubURLVersion "v6" michael@0: michael@0: ; Successful install exit code michael@0: !define ERR_SUCCESS 0 michael@0: michael@0: /** michael@0: * The following errors prefixed with ERR_DOWNLOAD apply to the download phase. michael@0: */ michael@0: ; The download was cancelled by the user michael@0: !define ERR_DOWNLOAD_CANCEL 10 michael@0: michael@0: ; Too many attempts to download. The maximum attempts is defined in michael@0: ; DownloadMaxRetries. michael@0: !define ERR_DOWNLOAD_TOO_MANY_RETRIES 11 michael@0: michael@0: /** michael@0: * The following errors prefixed with ERR_PREINSTALL apply to the pre-install michael@0: * check phase. michael@0: */ michael@0: ; Unable to acquire a file handle to the downloaded file michael@0: !define ERR_PREINSTALL_INVALID_HANDLE 20 michael@0: michael@0: ; The downloaded file's certificate is not trusted by the certificate store. michael@0: !define ERR_PREINSTALL_CERT_UNTRUSTED 21 michael@0: michael@0: ; The downloaded file's certificate attribute values were incorrect. michael@0: !define ERR_PREINSTALL_CERT_ATTRIBUTES 22 michael@0: michael@0: ; The downloaded file's certificate is not trusted by the certificate store and michael@0: ; certificate attribute values were incorrect. michael@0: !define ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES 23 michael@0: michael@0: /** michael@0: * The following errors prefixed with ERR_INSTALL apply to the install phase. michael@0: */ michael@0: ; The installation timed out. The installation timeout is defined by the number michael@0: ; of progress steps defined in InstallTotalSteps and the install timer michael@0: ; interval defined in InstallIntervalMS michael@0: !define ERR_INSTALL_TIMEOUT 30 michael@0: michael@0: ; Maximum times to retry the download before displaying an error michael@0: !define DownloadMaxRetries 9 michael@0: michael@0: ; Minimum size expected to download in bytes michael@0: !define DownloadMinSizeBytes 15728640 ; 15 MB michael@0: michael@0: ; Maximum size expected to download in bytes michael@0: !define DownloadMaxSizeBytes 36700160 ; 35 MB michael@0: michael@0: ; Interval before retrying to download. 3 seconds is used along with 10 michael@0: ; attempted downloads (the first attempt along with 9 retries) to give a michael@0: ; minimum of 30 seconds or retrying before giving up. michael@0: !define DownloadRetryIntervalMS 3000 michael@0: michael@0: ; Interval for the download timer michael@0: !define DownloadIntervalMS 200 michael@0: michael@0: ; Interval for the install timer michael@0: !define InstallIntervalMS 100 michael@0: michael@0: ; The first step for the install progress bar. By starting with a large step michael@0: ; immediate feedback is given to the user. michael@0: !define InstallProgressFirstStep 20 michael@0: michael@0: ; The finish step size to quickly increment the progress bar after the michael@0: ; installation has finished. michael@0: !define InstallProgressFinishStep 40 michael@0: michael@0: ; Number of steps for the install progress. michael@0: ; This might not be enough when installing on a slow network drive so it will michael@0: ; fallback to downloading the full installer if it reaches this number. The size michael@0: ; of the install progress step is increased when the full installer finishes michael@0: ; instead of waiting. michael@0: michael@0: ; Approximately 150 seconds with a 100 millisecond timer and a first step of 20 michael@0: ; as defined by InstallProgressFirstStep. michael@0: !define /math InstallCleanTotalSteps ${InstallProgressFirstStep} + 1500 michael@0: michael@0: ; Approximately 165 seconds (minus 0.2 seconds for each file that is removed) michael@0: ; with a 100 millisecond timer and a first step of 20 as defined by michael@0: ; InstallProgressFirstStep . michael@0: !define /math InstallPaveOverTotalSteps ${InstallProgressFirstStep} + 1800 michael@0: michael@0: ; On Vista and above attempt to elevate Standard Users in addition to users that michael@0: ; are a member of the Administrators group. michael@0: !define NONADMIN_ELEVATE michael@0: michael@0: !define CONFIG_INI "config.ini" michael@0: michael@0: !ifndef FILE_SHARE_READ michael@0: !define FILE_SHARE_READ 1 michael@0: !endif michael@0: !ifndef GENERIC_READ michael@0: !define GENERIC_READ 0x80000000 michael@0: !endif michael@0: !ifndef OPEN_EXISTING michael@0: !define OPEN_EXISTING 3 michael@0: !endif michael@0: !ifndef INVALID_HANDLE_VALUE michael@0: !define INVALID_HANDLE_VALUE -1 michael@0: !endif michael@0: michael@0: !include "nsDialogs.nsh" michael@0: !include "LogicLib.nsh" michael@0: !include "FileFunc.nsh" michael@0: !include "WinVer.nsh" michael@0: !include "WordFunc.nsh" michael@0: michael@0: !insertmacro GetParameters michael@0: !insertmacro GetOptions michael@0: !insertmacro StrFilter michael@0: michael@0: !include "locales.nsi" michael@0: !include "branding.nsi" michael@0: michael@0: !include "defines.nsi" michael@0: michael@0: ; Must be included after defines.nsi michael@0: !include "locale-fonts.nsh" michael@0: michael@0: ; The OFFICIAL define is a workaround to support different urls for Release and michael@0: ; Beta since they share the same branding when building with other branches that michael@0: ; set the update channel to beta. michael@0: !ifdef OFFICIAL michael@0: !ifdef BETA_UPDATE_CHANNEL michael@0: !undef URLStubDownload michael@0: !define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-beta-latest" michael@0: !undef URLManualDownload michael@0: !define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=beta&installer_lang=${AB_CD}" michael@0: !undef Channel michael@0: !define Channel "beta" michael@0: !endif michael@0: !endif michael@0: michael@0: !include "common.nsh" michael@0: michael@0: !insertmacro ElevateUAC michael@0: !insertmacro GetLongPath michael@0: !insertmacro GetPathFromString michael@0: !insertmacro GetParent michael@0: !insertmacro GetSingleInstallPath michael@0: !insertmacro GetTextWidthHeight michael@0: !insertmacro IsUserAdmin michael@0: !insertmacro OnStubInstallUninstall michael@0: !insertmacro SetBrandNameVars michael@0: !insertmacro UnloadUAC michael@0: michael@0: VIAddVersionKey "FileDescription" "${BrandShortName} Stub Installer" michael@0: VIAddVersionKey "OriginalFilename" "setup-stub.exe" michael@0: michael@0: Name "$BrandFullName" michael@0: OutFile "setup-stub.exe" michael@0: icon "setup.ico" michael@0: XPStyle on michael@0: BrandingText " " michael@0: ChangeUI all "nsisui.exe" michael@0: !ifdef HAVE_64BIT_OS michael@0: InstallDir "$PROGRAMFILES64\${BrandFullName}\" michael@0: !else michael@0: InstallDir "$PROGRAMFILES32\${BrandFullName}\" michael@0: !endif michael@0: michael@0: !ifdef ${AB_CD}_rtl michael@0: LoadLanguageFile "locale-rtl.nlf" michael@0: !else michael@0: LoadLanguageFile "locale.nlf" michael@0: !endif michael@0: michael@0: !include "nsisstrings.nlf" michael@0: michael@0: !if "${AB_CD}" == "en-US" michael@0: ; Custom strings for en-US. This is done here so they aren't translated. michael@0: !include oneoff_en-US.nsh michael@0: !else michael@0: !define INTRO_BLURB "$(INTRO_BLURB1)" michael@0: !define INSTALL_BLURB1 "$(INSTALL_BLURB1)" michael@0: !define INSTALL_BLURB2 "$(INSTALL_BLURB2)" michael@0: !define INSTALL_BLURB3 "$(INSTALL_BLURB3)" michael@0: !endif michael@0: michael@0: Caption "$(WIN_CAPTION)" michael@0: michael@0: Page custom createDummy ; Needed to enable the Intro page's back button michael@0: Page custom createIntro leaveIntro ; Introduction page michael@0: Page custom createOptions leaveOptions ; Options page michael@0: Page custom createInstall ; Download / Installation page michael@0: michael@0: Function .onInit michael@0: ; Remove the current exe directory from the search order. michael@0: ; This only effects LoadLibrary calls and not implicitly loaded DLLs. michael@0: System::Call 'kernel32::SetDllDirectoryW(w "")' michael@0: michael@0: StrCpy $LANGUAGE 0 michael@0: ; This macro is used to set the brand name variables but the ini file method michael@0: ; isn't supported for the stub installer. michael@0: ${SetBrandNameVars} "$PLUGINSDIR\ignored.ini" michael@0: michael@0: !ifdef HAVE_64BIT_OS michael@0: ; Restrict x64 builds from being installed on x86 and pre Vista michael@0: ${Unless} ${RunningX64} michael@0: ${OrUnless} ${AtLeastWinVista} michael@0: MessageBox MB_OK|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OS_MSG)" michael@0: Quit michael@0: ${EndUnless} michael@0: michael@0: SetRegView 64 michael@0: !else michael@0: StrCpy $R8 "0" michael@0: ${If} ${AtMostWin2000} michael@0: StrCpy $R8 "1" michael@0: ${EndIf} michael@0: michael@0: ${If} ${IsWinXP} michael@0: ${AndIf} ${AtMostServicePack} 1 michael@0: StrCpy $R8 "1" michael@0: ${EndIf} michael@0: michael@0: ${If} $R8 == "1" michael@0: ; XXX-rstrong - some systems failed the AtLeastWin2000 test that we michael@0: ; used to use for an unknown reason and likely fail the AtMostWin2000 michael@0: ; and possibly the IsWinXP test as well. To work around this also michael@0: ; check if the Windows NT registry Key exists and if it does if the michael@0: ; first char in CurrentVersion is equal to 3 (Windows NT 3.5 and michael@0: ; 3.5.1), 4 (Windows NT 4), or 5 (Windows 2000 and Windows XP). michael@0: StrCpy $R8 "" michael@0: ClearErrors michael@0: ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion" michael@0: StrCpy $R8 "$R8" 1 michael@0: ${If} ${Errors} michael@0: ${OrIf} "$R8" == "3" michael@0: ${OrIf} "$R8" == "4" michael@0: ${OrIf} "$R8" == "5" michael@0: MessageBox MB_OK|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OS_MSG)" michael@0: Quit michael@0: ${EndIf} michael@0: ${EndUnless} michael@0: !endif michael@0: michael@0: ; Require elevation if the user can elevate michael@0: ${ElevateUAC} michael@0: michael@0: ; The commands inside this ifndef are needed prior to NSIS 3.0a2 and can be michael@0: ; removed after we require NSIS 3.0a2 or greater. michael@0: !ifndef NSIS_PACKEDVERSION michael@0: ${If} ${AtLeastWinVista} michael@0: System::Call 'user32::SetProcessDPIAware()' michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: SetShellVarContext all ; Set SHCTX to HKLM michael@0: ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 michael@0: michael@0: ${If} "$R9" == "false" michael@0: SetShellVarContext current ; Set SHCTX to HKCU michael@0: ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 michael@0: ${EndIf} michael@0: michael@0: ${If} "$R9" != "false" michael@0: StrCpy $INSTDIR "$R9" michael@0: ${EndIf} michael@0: michael@0: ; Used to determine if the default installation directory was used. michael@0: StrCpy $InitialInstallDir "$INSTDIR" michael@0: michael@0: ClearErrors michael@0: WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ michael@0: "Write Test" michael@0: michael@0: ; Only display set as default when there is write access to HKLM and on Win7 michael@0: ; and below. michael@0: ${If} ${Errors} michael@0: ${OrIf} ${AtLeastWin8} michael@0: StrCpy $CanSetAsDefault "false" michael@0: StrCpy $CheckboxSetAsDefault "0" michael@0: ${Else} michael@0: DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" michael@0: StrCpy $CanSetAsDefault "true" michael@0: ${EndIf} michael@0: michael@0: ; The interval in MS used for the progress bars set as marquee. michael@0: ${If} ${AtLeastWinVista} michael@0: StrCpy $ProgressbarMarqueeIntervalMS "10" michael@0: ${Else} michael@0: StrCpy $ProgressbarMarqueeIntervalMS "50" michael@0: ${EndIf} michael@0: michael@0: ; Initialize the majority of variables except those that need to be reset michael@0: ; when a page is displayed. michael@0: StrCpy $IntroPhaseSeconds "0" michael@0: StrCpy $OptionsPhaseSeconds "0" michael@0: StrCpy $EndPreInstallPhaseTickCount "0" michael@0: StrCpy $EndInstallPhaseTickCount "0" michael@0: StrCpy $InitialInstallRequirementsCode "" michael@0: StrCpy $IsDownloadFinished "" michael@0: StrCpy $FirefoxLaunchCode "0" michael@0: StrCpy $CheckboxShortcutOnBar "1" michael@0: StrCpy $CheckboxShortcutInStartMenu "1" michael@0: StrCpy $CheckboxShortcutOnDesktop "1" michael@0: StrCpy $CheckboxSendPing "1" michael@0: !ifdef MOZ_MAINTENANCE_SERVICE michael@0: StrCpy $CheckboxInstallMaintSvc "1" michael@0: !else michael@0: StrCpy $CheckboxInstallMaintSvc "0" michael@0: !endif michael@0: StrCpy $WasOptionsButtonClicked "0" michael@0: michael@0: StrCpy $0 "" michael@0: !ifdef FONT_FILE1 michael@0: ${If} ${FileExists} "$FONTS\${FONT_FILE1}" michael@0: StrCpy $0 "${FONT_NAME1}" michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: !ifdef FONT_FILE2 michael@0: ${If} $0 == "" michael@0: ${AndIf} ${FileExists} "$FONTS\${FONT_FILE2}" michael@0: StrCpy $0 "${FONT_NAME2}" michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: ${If} $0 == "" michael@0: StrCpy $0 "$(^Font)" michael@0: ${EndIf} michael@0: michael@0: CreateFont $FontBlurb "$0" "12" "500" michael@0: CreateFont $FontNormal "$0" "11" "500" michael@0: CreateFont $FontItalic "$0" "11" "500" /ITALIC michael@0: michael@0: InitPluginsDir michael@0: File /oname=$PLUGINSDIR\bgintro.bmp "bgintro.bmp" michael@0: File /oname=$PLUGINSDIR\appname.bmp "appname.bmp" michael@0: File /oname=$PLUGINSDIR\clock.bmp "clock.bmp" michael@0: File /oname=$PLUGINSDIR\particles.bmp "particles.bmp" michael@0: !ifdef ${AB_CD}_rtl michael@0: ; The horizontally flipped pencil looks better in RTL michael@0: File /oname=$PLUGINSDIR\pencil.bmp "pencil-rtl.bmp" michael@0: !else michael@0: File /oname=$PLUGINSDIR\pencil.bmp "pencil.bmp" michael@0: !endif michael@0: FunctionEnd michael@0: michael@0: ; .onGUIInit isn't needed except for RTL locales michael@0: !ifdef ${AB_CD}_rtl michael@0: Function .onGUIInit michael@0: ; Since NSIS RTL support doesn't mirror progress bars use Windows mirroring. michael@0: ${NSD_AddExStyle} $HWNDPARENT ${WS_EX_LAYOUTRTL} michael@0: ${RemoveExStyle} $HWNDPARENT ${WS_EX_RTLREADING} michael@0: ${RemoveExStyle} $HWNDPARENT ${WS_EX_RIGHT} michael@0: ${NSD_AddExStyle} $HWNDPARENT ${WS_EX_LEFT}|${WS_EX_LTRREADING} michael@0: FunctionEnd michael@0: !endif michael@0: michael@0: Function .onGUIEnd michael@0: Delete "$PLUGINSDIR\_temp" michael@0: Delete "$PLUGINSDIR\download.exe" michael@0: Delete "$PLUGINSDIR\${CONFIG_INI}" michael@0: michael@0: ${UnloadUAC} michael@0: FunctionEnd michael@0: michael@0: Function .onUserAbort michael@0: ${NSD_KillTimer} StartDownload michael@0: ${NSD_KillTimer} OnDownload michael@0: ${NSD_KillTimer} CheckInstall michael@0: ${NSD_KillTimer} FinishInstall michael@0: ${NSD_KillTimer} FinishProgressBar michael@0: ${NSD_KillTimer} DisplayDownloadError michael@0: michael@0: ${If} "$IsDownloadFinished" != "" michael@0: Call DisplayDownloadError michael@0: ; Aborting the abort will allow SendPing which is called by michael@0: ; DisplayDownloadError to hide the installer window and close the installer michael@0: ; after it sends the metrics ping. michael@0: Abort michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function SendPing michael@0: HideWindow michael@0: ; Try to send a ping if a download was attempted michael@0: ${If} $CheckboxSendPing == 1 michael@0: ${AndIf} $IsDownloadFinished != "" michael@0: ; Get the tick count for the completion of all phases. michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $EndFinishPhaseTickCount michael@0: michael@0: ; When the value of $IsDownloadFinished is false the download was started michael@0: ; but didn't finish. In this case the tick count stored in michael@0: ; $EndFinishPhaseTickCount is used to determine how long the download was michael@0: ; in progress. michael@0: ${If} "$IsDownloadFinished" == "false" michael@0: ${OrIf} "$EndDownloadPhaseTickCount" == "" michael@0: StrCpy $EndDownloadPhaseTickCount "$EndFinishPhaseTickCount" michael@0: ; Cancel the download in progress michael@0: InetBgDL::Get /RESET /END michael@0: ${EndIf} michael@0: michael@0: michael@0: ; When $DownloadFirstTransferSeconds equals an empty string the download michael@0: ; never successfully started so set the value to 0. It will be possible to michael@0: ; determine that the download didn't successfully start from the seconds for michael@0: ; the last download. michael@0: ${If} "$DownloadFirstTransferSeconds" == "" michael@0: StrCpy $DownloadFirstTransferSeconds "0" michael@0: ${EndIf} michael@0: michael@0: ; When $StartLastDownloadTickCount equals an empty string the download never michael@0: ; successfully started so set the value to $EndDownloadPhaseTickCount to michael@0: ; compute the correct value. michael@0: ${If} $StartLastDownloadTickCount == "" michael@0: ; This could happen if the download never successfully starts michael@0: StrCpy $StartLastDownloadTickCount "$EndDownloadPhaseTickCount" michael@0: ${EndIf} michael@0: michael@0: ; When $EndPreInstallPhaseTickCount equals 0 the installation phase was michael@0: ; never completed so set its value to $EndFinishPhaseTickCount to compute michael@0: ; the correct value. michael@0: ${If} "$EndPreInstallPhaseTickCount" == "0" michael@0: StrCpy $EndPreInstallPhaseTickCount "$EndFinishPhaseTickCount" michael@0: ${EndIf} michael@0: michael@0: ; When $EndInstallPhaseTickCount equals 0 the installation phase was never michael@0: ; completed so set its value to $EndFinishPhaseTickCount to compute the michael@0: ; correct value. michael@0: ${If} "$EndInstallPhaseTickCount" == "0" michael@0: StrCpy $EndInstallPhaseTickCount "$EndFinishPhaseTickCount" michael@0: ${EndIf} michael@0: michael@0: ; Get the seconds elapsed from the start of the download phase to the end of michael@0: ; the download phase. michael@0: ${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$EndDownloadPhaseTickCount" $0 michael@0: michael@0: ; Get the seconds elapsed from the start of the last download to the end of michael@0: ; the last download. michael@0: ${GetSecondsElapsed} "$StartLastDownloadTickCount" "$EndDownloadPhaseTickCount" $1 michael@0: michael@0: ; Get the seconds elapsed from the end of the download phase to the michael@0: ; completion of the pre-installation check phase. michael@0: ${GetSecondsElapsed} "$EndDownloadPhaseTickCount" "$EndPreInstallPhaseTickCount" $2 michael@0: michael@0: ; Get the seconds elapsed from the end of the pre-installation check phase michael@0: ; to the completion of the installation phase. michael@0: ${GetSecondsElapsed} "$EndPreInstallPhaseTickCount" "$EndInstallPhaseTickCount" $3 michael@0: michael@0: ; Get the seconds elapsed from the end of the installation phase to the michael@0: ; completion of all phases. michael@0: ${GetSecondsElapsed} "$EndInstallPhaseTickCount" "$EndFinishPhaseTickCount" $4 michael@0: michael@0: !ifdef HAVE_64BIT_OS michael@0: StrCpy $R0 "1" michael@0: !else michael@0: StrCpy $R0 "0" michael@0: !endif michael@0: michael@0: ${If} ${RunningX64} michael@0: StrCpy $R1 "1" michael@0: ${Else} michael@0: StrCpy $R1 "0" michael@0: ${EndIf} michael@0: michael@0: ; Though these values are sometimes incorrect due to bug 444664 it happens michael@0: ; so rarely it isn't worth working around it by reading the registry values. michael@0: ${WinVerGetMajor} $5 michael@0: ${WinVerGetMinor} $6 michael@0: ${WinVerGetBuild} $7 michael@0: ${WinVerGetServicePackLevel} $8 michael@0: ${If} ${IsServerOS} michael@0: StrCpy $9 "1" michael@0: ${Else} michael@0: StrCpy $9 "0" michael@0: ${EndIf} michael@0: michael@0: ${If} "$ExitCode" == "${ERR_SUCCESS}" michael@0: ReadINIStr $R5 "$INSTDIR\application.ini" "App" "Version" michael@0: ReadINIStr $R6 "$INSTDIR\application.ini" "App" "BuildID" michael@0: ${Else} michael@0: StrCpy $R5 "0" michael@0: StrCpy $R6 "0" michael@0: ${EndIf} michael@0: michael@0: ; Whether installed into the default installation directory michael@0: ${GetLongPath} "$INSTDIR" $R7 michael@0: ${GetLongPath} "$InitialInstallDir" $R8 michael@0: ${If} "$R7" == "$R8" michael@0: StrCpy $R7 "1" michael@0: ${Else} michael@0: StrCpy $R7 "0" michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ michael@0: "Write Test" michael@0: ${If} ${Errors} michael@0: StrCpy $R8 "0" michael@0: ${Else} michael@0: DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" michael@0: StrCpy $R8 "1" michael@0: ${EndIf} michael@0: michael@0: ${If} "$DownloadServerIP" == "" michael@0: StrCpy $DownloadServerIP "Unknown" michael@0: ${EndIf} michael@0: michael@0: StrCpy $R2 "" michael@0: SetShellVarContext current ; Set SHCTX to the current user michael@0: ReadRegStr $R2 HKCU "Software\Classes\http\shell\open\command" "" michael@0: ${If} $R2 != "" michael@0: ${GetPathFromString} "$R2" $R2 michael@0: ${GetParent} "$R2" $R3 michael@0: ${GetLongPath} "$R3" $R3 michael@0: ${If} $R3 == $INSTDIR michael@0: StrCpy $R2 "1" ; This Firefox install is set as default. michael@0: ${Else} michael@0: StrCpy $R2 "$R2" "" -11 # length of firefox.exe michael@0: ${If} "$R2" == "${FileMainEXE}" michael@0: StrCpy $R2 "2" ; Another Firefox install is set as default. michael@0: ${Else} michael@0: StrCpy $R2 "0" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Else} michael@0: StrCpy $R2 "0" ; Firefox is not set as default. michael@0: ${EndIf} michael@0: michael@0: ${If} "$R2" == "0" michael@0: ${AndIf} ${AtLeastWinVista} michael@0: ; Check to see if this install location is currently set as the default michael@0: ; browser by Default Programs which is only available on Vista and above. michael@0: ClearErrors michael@0: ReadRegStr $R3 HKLM "Software\RegisteredApplications" "${AppRegName}" michael@0: ${Unless} ${Errors} michael@0: AppAssocReg::QueryAppIsDefaultAll "${AppRegName}" "effective" michael@0: Pop $R3 michael@0: ${If} $R3 == "1" michael@0: StrCpy $R3 "" michael@0: ReadRegStr $R2 HKLM "Software\Classes\http\shell\open\command" "" michael@0: ${If} $R2 != "" michael@0: ${GetPathFromString} "$R2" $R2 michael@0: ${GetParent} "$R2" $R3 michael@0: ${GetLongPath} "$R3" $R3 michael@0: ${If} $R3 == $INSTDIR michael@0: StrCpy $R2 "1" ; This Firefox install is set as default. michael@0: ${Else} michael@0: StrCpy $R2 "$R2" "" -11 # length of firefox.exe michael@0: ${If} "$R2" == "${FileMainEXE}" michael@0: StrCpy $R2 "2" ; Another Firefox install is set as default. michael@0: ${Else} michael@0: StrCpy $R2 "0" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Else} michael@0: StrCpy $R2 "0" ; Firefox is not set as default. michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: michael@0: ${If} $CanSetAsDefault == "true" michael@0: ${If} $CheckboxSetAsDefault == "1" michael@0: StrCpy $R3 "2" michael@0: ${Else} michael@0: StrCpy $R3 "3" michael@0: ${EndIf} michael@0: ${Else} michael@0: ${If} ${AtLeastWin8} michael@0: StrCpy $R3 "1" michael@0: ${Else} michael@0: StrCpy $R3 "0" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: !ifdef STUB_DEBUG michael@0: MessageBox MB_OK "${BaseURLStubPing} \ michael@0: $\nStub URL Version = ${StubURLVersion}${StubURLVersionAppend} \ michael@0: $\nBuild Channel = ${Channel} \ michael@0: $\nUpdate Channel = ${UpdateChannel} \ michael@0: $\nLocale = ${AB_CD} \ michael@0: $\nFirefox x64 = $R0 \ michael@0: $\nRunning x64 Windows = $R1 \ michael@0: $\nMajor = $5 \ michael@0: $\nMinor = $6 \ michael@0: $\nBuild = $7 \ michael@0: $\nServicePack = $8 \ michael@0: $\nIsServer = $9 \ michael@0: $\nExit Code = $ExitCode \ michael@0: $\nFirefox Launch Code = $FirefoxLaunchCode \ michael@0: $\nDownload Retry Count = $DownloadRetryCount \ michael@0: $\nDownloaded Bytes = $DownloadedBytes \ michael@0: $\nDownload Size Bytes = $DownloadSizeBytes \ michael@0: $\nIntroduction Phase Seconds = $IntroPhaseSeconds \ michael@0: $\nOptions Phase Seconds = $OptionsPhaseSeconds \ michael@0: $\nDownload Phase Seconds = $0 \ michael@0: $\nLast Download Seconds = $1 \ michael@0: $\nDownload First Transfer Seconds = $DownloadFirstTransferSeconds \ michael@0: $\nPreinstall Phase Seconds = $2 \ michael@0: $\nInstall Phase Seconds = $3 \ michael@0: $\nFinish Phase Seconds = $4 \ michael@0: $\nInitial Install Requirements Code = $InitialInstallRequirementsCode \ michael@0: $\nOpened Download Page = $OpenedDownloadPage \ michael@0: $\nExisting Profile = $ExistingProfile \ michael@0: $\nExisting Version = $ExistingVersion \ michael@0: $\nExisting Build ID = $ExistingBuildID \ michael@0: $\nNew Version = $R5 \ michael@0: $\nNew Build ID = $R6 \ michael@0: $\nDefault Install Dir = $R7 \ michael@0: $\nHas Admin = $R8 \ michael@0: $\nDefault Status = $R2 \ michael@0: $\nSet As Sefault Status = $R3 \ michael@0: $\nDownload Server IP = $DownloadServerIP" michael@0: ; The following will exit the installer michael@0: SetAutoClose true michael@0: StrCpy $R9 "2" michael@0: Call RelativeGotoPage michael@0: !else michael@0: ${NSD_CreateTimer} OnPing ${DownloadIntervalMS} michael@0: InetBgDL::Get "${BaseURLStubPing}/${StubURLVersion}${StubURLVersionAppend}/${Channel}/${UpdateChannel}/${AB_CD}/$R0/$R1/$5/$6/$7/$8/$9/$ExitCode/$FirefoxLaunchCode/$DownloadRetryCount/$DownloadedBytes/$DownloadSizeBytes/$IntroPhaseSeconds/$OptionsPhaseSeconds/$0/$1/$DownloadFirstTransferSeconds/$2/$3/$4/$InitialInstallRequirementsCode/$OpenedDownloadPage/$ExistingProfile/$ExistingVersion/$ExistingBuildID/$R5/$R6/$R7/$R8/$R2/$R3/$DownloadServerIP" \ michael@0: "$PLUGINSDIR\_temp" /END michael@0: !endif michael@0: ${Else} michael@0: ${If} "$IsDownloadFinished" == "false" michael@0: ; Cancel the download in progress michael@0: InetBgDL::Get /RESET /END michael@0: ${EndIf} michael@0: ; The following will exit the installer michael@0: SetAutoClose true michael@0: StrCpy $R9 "2" michael@0: Call RelativeGotoPage michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function createDummy michael@0: FunctionEnd michael@0: michael@0: Function createIntro michael@0: nsDialogs::Create /NOUNLOAD 1018 michael@0: Pop $Dialog michael@0: michael@0: GetFunctionAddress $0 OnBack michael@0: nsDialogs::OnBack /NOUNLOAD $0 michael@0: michael@0: !ifdef ${AB_CD}_rtl michael@0: ; For RTL align the text with the top of the F in the Firefox bitmap michael@0: StrCpy $0 "${INTRO_BLURB_RTL_TOP_DU}" michael@0: !else michael@0: ; For LTR align the text with the top of the x in the Firefox bitmap michael@0: StrCpy $0 "${INTRO_BLURB_LTR_TOP_DU}" michael@0: !endif michael@0: ${NSD_CreateLabel} ${INTRO_BLURB_EDGE_DU} $0 ${INTRO_BLURB_WIDTH_DU} 76u "${INTRO_BLURB}" michael@0: Pop $0 michael@0: SendMessage $0 ${WM_SETFONT} $FontBlurb 0 michael@0: SetCtlColors $0 ${INTRO_BLURB_TEXT_COLOR} transparent michael@0: michael@0: SetCtlColors $HWNDPARENT ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR} michael@0: GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox michael@0: ${If} "$CanSetAsDefault" == "true" michael@0: ; The uxtheme must be disabled on checkboxes in order to override the michael@0: ; system font color. michael@0: System::Call 'uxtheme::SetWindowTheme(i $0 , w " ", w " ")' michael@0: SendMessage $0 ${WM_SETFONT} $FontNormal 0 michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(MAKE_DEFAULT)" michael@0: SendMessage $0 ${BM_SETCHECK} 1 0 michael@0: SetCtlColors $0 ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR} michael@0: ${Else} michael@0: ShowWindow $0 ${SW_HIDE} michael@0: ${EndIf} michael@0: GetDlgItem $0 $HWNDPARENT 11 michael@0: ShowWindow $0 ${SW_HIDE} michael@0: michael@0: ${NSD_CreateBitmap} ${APPNAME_BMP_EDGE_DU} ${APPNAME_BMP_TOP_DU} \ michael@0: ${APPNAME_BMP_WIDTH_DU} ${APPNAME_BMP_HEIGHT_DU} "" michael@0: Pop $2 michael@0: ${SetStretchedTransparentImage} $2 $PLUGINSDIR\appname.bmp $0 michael@0: michael@0: ${NSD_CreateBitmap} 0 0 100% 100% "" michael@0: Pop $2 michael@0: ${NSD_SetStretchedImage} $2 $PLUGINSDIR\bgintro.bmp $1 michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 1 ; Install button michael@0: ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" michael@0: ${Else} michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)" michael@0: ${EndIf} michael@0: ${NSD_SetFocus} $0 michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 2 ; Cancel button michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)" michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(OPTIONS_BUTTON)" michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $StartIntroPhaseTickCount michael@0: michael@0: LockWindow off michael@0: nsDialogs::Show michael@0: michael@0: ${NSD_FreeImage} $0 michael@0: ${NSD_FreeImage} $1 michael@0: FunctionEnd michael@0: michael@0: Function leaveIntro michael@0: LockWindow on michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $0 michael@0: ${GetSecondsElapsed} "$StartIntroPhaseTickCount" "$0" $IntroPhaseSeconds michael@0: ; It is possible for this value to be 0 if the user clicks fast enough so michael@0: ; increment the value by 1 if it is 0. michael@0: ${If} $IntroPhaseSeconds == 0 michael@0: IntOp $IntroPhaseSeconds $IntroPhaseSeconds + 1 michael@0: ${EndIf} michael@0: michael@0: SetShellVarContext all ; Set SHCTX to All Users michael@0: ; If the user doesn't have write access to the installation directory set michael@0: ; the installation directory to a subdirectory of the All Users application michael@0: ; directory and if the user can't write to that location set the installation michael@0: ; directory to a subdirectory of the users local application directory michael@0: ; (e.g. non-roaming). michael@0: Call CanWrite michael@0: ${If} "$CanWriteToInstallDir" == "false" michael@0: StrCpy $INSTDIR "$APPDATA\${BrandFullName}\" michael@0: Call CanWrite michael@0: ${If} "$CanWriteToInstallDir" == "false" michael@0: ; This should never happen but just in case. michael@0: StrCpy $CanWriteToInstallDir "false" michael@0: ${Else} michael@0: StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\" michael@0: Call CanWrite michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: Call CheckSpace michael@0: michael@0: ${If} ${FileExists} "$INSTDIR" michael@0: ; Always display the long path if the path exists. michael@0: ${GetLongPath} "$INSTDIR" $INSTDIR michael@0: ${EndIf} michael@0: michael@0: FunctionEnd michael@0: michael@0: Function createOptions michael@0: ; Check whether the install requirements are satisfied using the default michael@0: ; values for metrics. michael@0: ${If} "$InitialInstallRequirementsCode" == "" michael@0: ${If} "$CanWriteToInstallDir" != "true" michael@0: ${AndIf} "$HasRequiredSpaceAvailable" != "true" michael@0: StrCpy $InitialInstallRequirementsCode "1" michael@0: ${ElseIf} "$CanWriteToInstallDir" != "true" michael@0: StrCpy $InitialInstallRequirementsCode "2" michael@0: ${ElseIf} "$HasRequiredSpaceAvailable" != "true" michael@0: StrCpy $InitialInstallRequirementsCode "3" michael@0: ${Else} michael@0: StrCpy $InitialInstallRequirementsCode "0" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ; Skip the options page unless the Options button was clicked as long as the michael@0: ; installation directory can be written to and there is the minimum required michael@0: ; space available. michael@0: ${If} "$WasOptionsButtonClicked" != "1" michael@0: ${If} "$CanWriteToInstallDir" == "true" michael@0: ${AndIf} "$HasRequiredSpaceAvailable" == "true" michael@0: Abort ; Skip the options page michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: StrCpy $ExistingTopDir "" michael@0: michael@0: nsDialogs::Create /NOUNLOAD 1018 michael@0: Pop $Dialog michael@0: ; Since the text color for controls is set in this Dialog the foreground and michael@0: ; background colors of the Dialog must also be hardcoded. michael@0: SetCtlColors $Dialog ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: michael@0: ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 18u ${OPTIONS_ITEM_WIDTH_DU} \ michael@0: 12u "$(CREATE_SHORTCUTS)" michael@0: Pop $0 michael@0: SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $0 ${WM_SETFONT} $FontNormal 0 michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: StrCpy $0 "$(ADD_SC_TASKBAR)" michael@0: ${Else} michael@0: StrCpy $0 "$(ADD_SC_QUICKLAUNCHBAR)" michael@0: ${EndIf} michael@0: ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 38u \ michael@0: ${OPTIONS_SUBITEM_WIDTH_DU} 12u "$0" michael@0: Pop $CheckboxShortcutOnBar michael@0: ; The uxtheme must be disabled on checkboxes in order to override the system michael@0: ; font color. michael@0: System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutOnBar, w " ", w " ")' michael@0: SetCtlColors $CheckboxShortcutOnBar ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $CheckboxShortcutOnBar ${WM_SETFONT} $FontNormal 0 michael@0: ${NSD_Check} $CheckboxShortcutOnBar michael@0: michael@0: ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 54u ${OPTIONS_SUBITEM_WIDTH_DU} \ michael@0: 12u "$(ADD_CheckboxShortcutInStartMenu)" michael@0: Pop $CheckboxShortcutInStartMenu michael@0: ; The uxtheme must be disabled on checkboxes in order to override the system michael@0: ; font color. michael@0: System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutInStartMenu, w " ", w " ")' michael@0: SetCtlColors $CheckboxShortcutInStartMenu ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $CheckboxShortcutInStartMenu ${WM_SETFONT} $FontNormal 0 michael@0: ${NSD_Check} $CheckboxShortcutInStartMenu michael@0: michael@0: ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 70u ${OPTIONS_SUBITEM_WIDTH_DU} \ michael@0: 12u "$(ADD_CheckboxShortcutOnDesktop)" michael@0: Pop $CheckboxShortcutOnDesktop michael@0: ; The uxtheme must be disabled on checkboxes in order to override the system michael@0: ; font color. michael@0: System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutOnDesktop, w " ", w " ")' michael@0: SetCtlColors $CheckboxShortcutOnDesktop ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $CheckboxShortcutOnDesktop ${WM_SETFONT} $FontNormal 0 michael@0: ${NSD_Check} $CheckboxShortcutOnDesktop michael@0: michael@0: ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 100u ${OPTIONS_ITEM_WIDTH_DU} \ michael@0: 12u "$(DEST_FOLDER)" michael@0: Pop $0 michael@0: SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $0 ${WM_SETFONT} $FontNormal 0 michael@0: michael@0: ${NSD_CreateDirRequest} ${OPTIONS_SUBITEM_EDGE_DU} 116u 159u 14u "$INSTDIR" michael@0: Pop $DirRequest michael@0: SetCtlColors $DirRequest ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $DirRequest ${WM_SETFONT} $FontNormal 0 michael@0: System::Call shlwapi::SHAutoComplete(i $DirRequest, i ${SHACF_FILESYSTEM}) michael@0: ${NSD_OnChange} $DirRequest OnChange_DirRequest michael@0: michael@0: !ifdef ${AB_CD}_rtl michael@0: ; Remove the RTL styling from the directory request text box michael@0: ${RemoveStyle} $DirRequest ${SS_RIGHT} michael@0: ${RemoveExStyle} $DirRequest ${WS_EX_RIGHT} michael@0: ${RemoveExStyle} $DirRequest ${WS_EX_RTLREADING} michael@0: ${NSD_AddStyle} $DirRequest ${SS_LEFT} michael@0: ${NSD_AddExStyle} $DirRequest ${WS_EX_LTRREADING}|${WS_EX_LEFT} michael@0: !endif michael@0: michael@0: ${NSD_CreateBrowseButton} 280u 116u 50u 14u "$(BROWSE_BUTTON)" michael@0: Pop $ButtonBrowse michael@0: SetCtlColors $ButtonBrowse "" ${COMMON_BKGRD_COLOR} michael@0: ${NSD_OnClick} $ButtonBrowse OnClick_ButtonBrowse michael@0: michael@0: ; Get the number of pixels from the left of the Dialog to the right side of michael@0: ; the "Space Required:" and "Space Available:" labels prior to setting RTL so michael@0: ; the correct position of the controls can be set by NSIS for RTL locales. michael@0: michael@0: ; Get the width and height of both labels and use the tallest for the height michael@0: ; and the widest to calculate where to place the labels after these labels. michael@0: ${GetTextExtent} "$(SPACE_REQUIRED)" $FontItalic $0 $1 michael@0: ${GetTextExtent} "$(SPACE_AVAILABLE)" $FontItalic $2 $3 michael@0: ${If} $1 > $3 michael@0: StrCpy $ControlHeightPX "$1" michael@0: ${Else} michael@0: StrCpy $ControlHeightPX "$3" michael@0: ${EndIf} michael@0: michael@0: IntOp $0 $0 + 8 ; Add padding to the control's width michael@0: ; Make both controls the same width as the widest control michael@0: ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 134u $0 $ControlHeightPX "$(SPACE_REQUIRED)" michael@0: Pop $5 michael@0: SetCtlColors $5 ${COMMON_TEXT_COLOR_FADED} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $5 ${WM_SETFONT} $FontItalic 0 michael@0: michael@0: IntOp $2 $2 + 8 ; Add padding to the control's width michael@0: ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 145u $2 $ControlHeightPX "$(SPACE_AVAILABLE)" michael@0: Pop $6 michael@0: SetCtlColors $6 ${COMMON_TEXT_COLOR_FADED} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $6 ${WM_SETFONT} $FontItalic 0 michael@0: michael@0: ; Use the widest label for aligning the labels next to them michael@0: ${If} $0 > $2 michael@0: StrCpy $6 "$5" michael@0: ${EndIf} michael@0: FindWindow $1 "#32770" "" $HWNDPARENT michael@0: ${GetDlgItemEndPX} $6 $ControlRightPX michael@0: michael@0: IntOp $ControlRightPX $ControlRightPX + 6 michael@0: michael@0: ${NSD_CreateLabel} $ControlRightPX 134u 100% $ControlHeightPX \ michael@0: "${APPROXIMATE_REQUIRED_SPACE_MB} $(MEGA)$(BYTE)" michael@0: Pop $7 michael@0: SetCtlColors $7 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $7 ${WM_SETFONT} $FontNormal 0 michael@0: michael@0: ; Create the free space label with an empty string and update it by calling michael@0: ; UpdateFreeSpaceLabel michael@0: ${NSD_CreateLabel} $ControlRightPX 145u 100% $ControlHeightPX " " michael@0: Pop $LabelFreeSpace michael@0: SetCtlColors $LabelFreeSpace ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $LabelFreeSpace ${WM_SETFONT} $FontNormal 0 michael@0: michael@0: Call UpdateFreeSpaceLabel michael@0: michael@0: ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 168u ${OPTIONS_SUBITEM_WIDTH_DU} \ michael@0: 12u "$(SEND_PING)" michael@0: Pop $CheckboxSendPing michael@0: ; The uxtheme must be disabled on checkboxes in order to override the system michael@0: ; font color. michael@0: System::Call 'uxtheme::SetWindowTheme(i $CheckboxSendPing, w " ", w " ")' michael@0: SetCtlColors $CheckboxSendPing ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $CheckboxSendPing ${WM_SETFONT} $FontNormal 0 michael@0: ${NSD_Check} $CheckboxSendPing michael@0: michael@0: !ifdef MOZ_MAINTENANCE_SERVICE michael@0: ; Only show the maintenance service checkbox if we have write access to HKLM michael@0: Call IsUserAdmin michael@0: Pop $0 michael@0: ClearErrors michael@0: WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ michael@0: "Write Test" michael@0: ${If} ${Errors} michael@0: ${OrIf} $0 != "true" michael@0: StrCpy $CheckboxInstallMaintSvc "0" michael@0: ${Else} michael@0: DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" michael@0: ; Read the registry instead of using ServicesHelper::IsInstalled so the michael@0: ; plugin isn't included in the stub installer to lessen its size. michael@0: ClearErrors michael@0: ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\services\MozillaMaintenance" "ImagePath" michael@0: ${If} ${Errors} michael@0: ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 184u ${OPTIONS_ITEM_WIDTH_DU} \ michael@0: 12u "$(INSTALL_MAINT_SERVICE)" michael@0: Pop $CheckboxInstallMaintSvc michael@0: System::Call 'uxtheme::SetWindowTheme(i $CheckboxInstallMaintSvc, w " ", w " ")' michael@0: SetCtlColors $CheckboxInstallMaintSvc ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: SendMessage $CheckboxInstallMaintSvc ${WM_SETFONT} $FontNormal 0 michael@0: ${NSD_Check} $CheckboxInstallMaintSvc michael@0: ${EndIf} michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 1 ; Install button michael@0: ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" michael@0: ${Else} michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)" michael@0: ${EndIf} michael@0: ${NSD_SetFocus} $0 michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 2 ; Cancel button michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)" michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options michael@0: EnableWindow $0 0 michael@0: ShowWindow $0 ${SW_HIDE} michael@0: michael@0: ; If the option button was not clicked display the reason for what needs to be michael@0: ; resolved to continue the installation. michael@0: ${If} "$WasOptionsButtonClicked" != "1" michael@0: ${If} "$CanWriteToInstallDir" == "false" michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS)" michael@0: ${ElseIf} "$HasRequiredSpaceAvailable" == "false" michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE)" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $StartOptionsPhaseTickCount michael@0: michael@0: LockWindow off michael@0: nsDialogs::Show michael@0: FunctionEnd michael@0: michael@0: Function leaveOptions michael@0: LockWindow on michael@0: michael@0: ${GetRoot} "$INSTDIR" $0 michael@0: ${GetLongPath} "$INSTDIR" $INSTDIR michael@0: ${GetLongPath} "$0" $0 michael@0: ${If} "$INSTDIR" == "$0" michael@0: LockWindow off michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_ROOT_INSTALL)" michael@0: Abort ; Stay on the page michael@0: ${EndIf} michael@0: michael@0: Call CanWrite michael@0: ${If} "$CanWriteToInstallDir" == "false" michael@0: LockWindow off michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS)" michael@0: Abort ; Stay on the page michael@0: ${EndIf} michael@0: michael@0: Call CheckSpace michael@0: ${If} "$HasRequiredSpaceAvailable" == "false" michael@0: LockWindow off michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE)" michael@0: Abort ; Stay on the page michael@0: ${EndIf} michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $0 michael@0: ${GetSecondsElapsed} "$StartOptionsPhaseTickCount" "$0" $OptionsPhaseSeconds michael@0: ; It is possible for this value to be 0 if the user clicks fast enough so michael@0: ; increment the value by 1 if it is 0. michael@0: ${If} $OptionsPhaseSeconds == 0 michael@0: IntOp $OptionsPhaseSeconds $OptionsPhaseSeconds + 1 michael@0: ${EndIf} michael@0: michael@0: ${NSD_GetState} $CheckboxShortcutOnBar $CheckboxShortcutOnBar michael@0: ${NSD_GetState} $CheckboxShortcutInStartMenu $CheckboxShortcutInStartMenu michael@0: ${NSD_GetState} $CheckboxShortcutOnDesktop $CheckboxShortcutOnDesktop michael@0: ${NSD_GetState} $CheckboxSendPing $CheckboxSendPing michael@0: !ifdef MOZ_MAINTENANCE_SERVICE michael@0: ${NSD_GetState} $CheckboxInstallMaintSvc $CheckboxInstallMaintSvc michael@0: !endif michael@0: michael@0: FunctionEnd michael@0: michael@0: Function createInstall michael@0: nsDialogs::Create /NOUNLOAD 1018 michael@0: Pop $Dialog michael@0: ; Since the text color for controls is set in this Dialog the foreground and michael@0: ; background colors of the Dialog must also be hardcoded. michael@0: SetCtlColors $Dialog ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} michael@0: michael@0: ${NSD_CreateLabel} 0 0 49u 64u "" michael@0: Pop $0 michael@0: ${GetDlgItemWidthHeight} $0 $1 $2 michael@0: System::Call 'user32::DestroyWindow(i r0)' michael@0: michael@0: ${NSD_CreateLabel} 0 0 11u 16u "" michael@0: Pop $0 michael@0: ${GetDlgItemWidthHeight} $0 $3 $4 michael@0: System::Call 'user32::DestroyWindow(i r0)' michael@0: michael@0: FindWindow $7 "#32770" "" $HWNDPARENT michael@0: ${GetDlgItemWidthHeight} $7 $8 $9 michael@0: michael@0: ; Allow a maximum text width of half of the Dialog's width michael@0: IntOp $R0 $8 / 2 michael@0: michael@0: ${GetTextWidthHeight} "${INSTALL_BLURB1}" $FontBlurb $R0 $5 $6 michael@0: IntOp $R1 $1 + $3 michael@0: IntOp $R1 $R1 + $5 michael@0: IntOp $R1 $8 - $R1 michael@0: IntOp $R1 $R1 / 2 michael@0: ${NSD_CreateBitmap} $R1 ${INSTALL_BLURB_TOP_DU} 49u 64u "" michael@0: Pop $BitmapBlurb1 michael@0: ${SetStretchedTransparentImage} $BitmapBlurb1 $PLUGINSDIR\clock.bmp $HwndBitmapBlurb1 michael@0: IntOp $R1 $R1 + $1 michael@0: IntOp $R1 $R1 + $3 michael@0: ${NSD_CreateLabel} $R1 ${INSTALL_BLURB_TOP_DU} $5 $6 "${INSTALL_BLURB1}" michael@0: Pop $LabelBlurb1 michael@0: SendMessage $LabelBlurb1 ${WM_SETFONT} $FontBlurb 0 michael@0: SetCtlColors $LabelBlurb1 ${INSTALL_BLURB_TEXT_COLOR} transparent michael@0: michael@0: ${GetTextWidthHeight} "${INSTALL_BLURB2}" $FontBlurb $R0 $5 $6 michael@0: IntOp $R1 $1 + $3 michael@0: IntOp $R1 $R1 + $5 michael@0: IntOp $R1 $8 - $R1 michael@0: IntOp $R1 $R1 / 2 michael@0: ${NSD_CreateBitmap} $R1 ${INSTALL_BLURB_TOP_DU} 49u 64u "" michael@0: Pop $BitmapBlurb2 michael@0: ${SetStretchedTransparentImage} $BitmapBlurb2 $PLUGINSDIR\particles.bmp $HwndBitmapBlurb2 michael@0: IntOp $R1 $R1 + $1 michael@0: IntOp $R1 $R1 + $3 michael@0: ${NSD_CreateLabel} $R1 ${INSTALL_BLURB_TOP_DU} $5 $6 "${INSTALL_BLURB2}" michael@0: Pop $LabelBlurb2 michael@0: SendMessage $LabelBlurb2 ${WM_SETFONT} $FontBlurb 0 michael@0: SetCtlColors $LabelBlurb2 ${INSTALL_BLURB_TEXT_COLOR} transparent michael@0: ShowWindow $BitmapBlurb2 ${SW_HIDE} michael@0: ShowWindow $LabelBlurb2 ${SW_HIDE} michael@0: michael@0: ${GetTextWidthHeight} "${INSTALL_BLURB3}" $FontBlurb $R0 $5 $6 michael@0: IntOp $R1 $1 + $3 michael@0: IntOp $R1 $R1 + $5 michael@0: IntOp $R1 $8 - $R1 michael@0: IntOp $R1 $R1 / 2 michael@0: ${NSD_CreateBitmap} $R1 ${INSTALL_BLURB_TOP_DU} 49u 64u "" michael@0: Pop $BitmapBlurb3 michael@0: ${SetStretchedTransparentImage} $BitmapBlurb3 $PLUGINSDIR\pencil.bmp $HWndBitmapBlurb3 michael@0: IntOp $R1 $R1 + $1 michael@0: IntOp $R1 $R1 + $3 michael@0: ${NSD_CreateLabel} $R1 ${INSTALL_BLURB_TOP_DU} $5 $6 "${INSTALL_BLURB3}" michael@0: Pop $LabelBlurb3 michael@0: SendMessage $LabelBlurb3 ${WM_SETFONT} $FontBlurb 0 michael@0: SetCtlColors $LabelBlurb3 ${INSTALL_BLURB_TEXT_COLOR} transparent michael@0: ShowWindow $BitmapBlurb3 ${SW_HIDE} michael@0: ShowWindow $LabelBlurb3 ${SW_HIDE} michael@0: michael@0: ${NSD_CreateProgressBar} 103u 166u 241u 9u "" michael@0: Pop $Progressbar michael@0: ${NSD_AddStyle} $Progressbar ${PBS_MARQUEE} michael@0: SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \ michael@0: $ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N michael@0: michael@0: ${NSD_CreateLabelCenter} 103u 180u 241u 20u "$(DOWNLOADING_LABEL)" michael@0: Pop $LabelDownloading michael@0: SendMessage $LabelDownloading ${WM_SETFONT} $FontNormal 0 michael@0: SetCtlColors $LabelDownloading ${INSTALL_PROGRESS_TEXT_COLOR_NORMAL} transparent michael@0: michael@0: ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" michael@0: ${NSD_CreateLabelCenter} 103u 180u 241u 20u "$(UPGRADING_LABEL)" michael@0: ${Else} michael@0: ${NSD_CreateLabelCenter} 103u 180u 241u 20u "$(INSTALLING_LABEL)" michael@0: ${EndIf} michael@0: Pop $LabelInstalling michael@0: SendMessage $LabelInstalling ${WM_SETFONT} $FontNormal 0 michael@0: SetCtlColors $LabelInstalling ${INSTALL_PROGRESS_TEXT_COLOR_NORMAL} transparent michael@0: ShowWindow $LabelInstalling ${SW_HIDE} michael@0: michael@0: ${NSD_CreateBitmap} ${APPNAME_BMP_EDGE_DU} ${APPNAME_BMP_TOP_DU} \ michael@0: ${APPNAME_BMP_WIDTH_DU} ${APPNAME_BMP_HEIGHT_DU} "" michael@0: Pop $2 michael@0: ${SetStretchedTransparentImage} $2 $PLUGINSDIR\appname.bmp $0 michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 1 ; Install button michael@0: EnableWindow $0 0 michael@0: ShowWindow $0 ${SW_HIDE} michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options michael@0: EnableWindow $0 0 michael@0: ShowWindow $0 ${SW_HIDE} michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 2 ; Cancel button michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)" michael@0: ; Focus the Cancel button otherwise it isn't possible to tab to it since it is michael@0: ; the only control that can be tabbed to. michael@0: ${NSD_SetFocus} $0 michael@0: ; Kill the Cancel button's focus so pressing enter won't cancel the install. michael@0: SendMessage $0 ${WM_KILLFOCUS} 0 0 michael@0: michael@0: ${If} "$CanSetAsDefault" == "true" michael@0: GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox michael@0: SendMessage $0 ${BM_GETCHECK} 0 0 $CheckboxSetAsDefault michael@0: EnableWindow $0 0 michael@0: ShowWindow $0 ${SW_HIDE} michael@0: ${EndIf} michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 11 michael@0: ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(ONE_MOMENT_UPGRADE)" michael@0: ${Else} michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(ONE_MOMENT_INSTALL)" michael@0: ${EndIf} michael@0: SendMessage $0 ${WM_SETFONT} $FontNormal 0 michael@0: SetCtlColors $0 ${FOOTER_CONTROL_TEXT_COLOR_FADED} ${FOOTER_BKGRD_COLOR} michael@0: ShowWindow $0 ${SW_SHOW} michael@0: michael@0: ; Set $DownloadReset to true so the first download tick count is measured. michael@0: StrCpy $DownloadReset "true" michael@0: StrCpy $IsDownloadFinished "false" michael@0: StrCpy $DownloadRetryCount "0" michael@0: StrCpy $DownloadedBytes "0" michael@0: StrCpy $StartLastDownloadTickCount "" michael@0: StrCpy $EndDownloadPhaseTickCount "" michael@0: StrCpy $DownloadFirstTransferSeconds "" michael@0: StrCpy $ExitCode "${ERR_DOWNLOAD_CANCEL}" michael@0: StrCpy $OpenedDownloadPage "0" michael@0: michael@0: ClearErrors michael@0: ReadINIStr $ExistingVersion "$INSTDIR\application.ini" "App" "Version" michael@0: ${If} ${Errors} michael@0: StrCpy $ExistingVersion "0" michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: ReadINIStr $ExistingBuildID "$INSTDIR\application.ini" "App" "BuildID" michael@0: ${If} ${Errors} michael@0: StrCpy $ExistingBuildID "0" michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$LOCALAPPDATA\Mozilla\Firefox" michael@0: StrCpy $ExistingProfile "1" michael@0: ${Else} michael@0: StrCpy $ExistingProfile "0" michael@0: ${EndIf} michael@0: michael@0: StrCpy $DownloadServerIP "" michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $StartDownloadPhaseTickCount michael@0: michael@0: ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log" michael@0: StrCpy $InstallTotalSteps ${InstallPaveOverTotalSteps} michael@0: ${Else} michael@0: StrCpy $InstallTotalSteps ${InstallCleanTotalSteps} michael@0: ${EndIf} michael@0: michael@0: ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} michael@0: michael@0: LockWindow off michael@0: nsDialogs::Show michael@0: michael@0: ${NSD_FreeImage} $0 michael@0: ${NSD_FreeImage} $HwndBitmapBlurb1 michael@0: ${NSD_FreeImage} $HwndBitmapBlurb2 michael@0: ${NSD_FreeImage} $HWndBitmapBlurb3 michael@0: FunctionEnd michael@0: michael@0: Function StartDownload michael@0: ${NSD_KillTimer} StartDownload michael@0: InetBgDL::Get "${URLStubDownload}${URLStubDownloadAppend}" "$PLUGINSDIR\download.exe" \ michael@0: /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END michael@0: StrCpy $4 "" michael@0: ${NSD_CreateTimer} OnDownload ${DownloadIntervalMS} michael@0: ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" michael@0: RmDir /r "$INSTDIR\${TO_BE_DELETED}" michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function OnDownload michael@0: InetBgDL::GetStats michael@0: # $0 = HTTP status code, 0=Completed michael@0: # $1 = Completed files michael@0: # $2 = Remaining files michael@0: # $3 = Number of downloaded bytes for the current file michael@0: # $4 = Size of current file (Empty string if the size is unknown) michael@0: # /RESET must be used if status $0 > 299 (e.g. failure) michael@0: # When status is $0 =< 299 it is handled by InetBgDL michael@0: StrCpy $DownloadServerIP "$5" michael@0: ${If} $0 > 299 michael@0: ${NSD_KillTimer} OnDownload michael@0: IntOp $DownloadRetryCount $DownloadRetryCount + 1 michael@0: ${If} "$DownloadReset" != "true" michael@0: StrCpy $DownloadedBytes "0" michael@0: ${NSD_AddStyle} $Progressbar ${PBS_MARQUEE} michael@0: SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \ michael@0: $ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N michael@0: ${EndIf} michael@0: InetBgDL::Get /RESET /END michael@0: StrCpy $DownloadSizeBytes "" michael@0: StrCpy $DownloadReset "true" michael@0: michael@0: ${If} $DownloadRetryCount >= ${DownloadMaxRetries} michael@0: StrCpy $ExitCode "${ERR_DOWNLOAD_TOO_MANY_RETRIES}" michael@0: ; Use a timer so the UI has a chance to update michael@0: ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} michael@0: ${Else} michael@0: ${NSD_CreateTimer} StartDownload ${DownloadRetryIntervalMS} michael@0: ${EndIf} michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ${If} "$DownloadReset" == "true" michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $StartLastDownloadTickCount michael@0: StrCpy $DownloadReset "false" michael@0: ; The seconds elapsed from the start of the download phase until the first michael@0: ; bytes are received are only recorded for the first request so it is michael@0: ; possible to determine connection issues for the first request. michael@0: ${If} "$DownloadFirstTransferSeconds" == "" michael@0: ; Get the seconds elapsed from the start of the download phase until the michael@0: ; first bytes are received. michael@0: ${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$StartLastDownloadTickCount" $DownloadFirstTransferSeconds michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ${If} "$DownloadSizeBytes" == "" michael@0: ${AndIf} "$4" != "" michael@0: ; Handle the case where the size of the file to be downloaded is less than michael@0: ; the minimum expected size or greater than the maximum expected size at the michael@0: ; beginning of the download. michael@0: ${If} $4 < ${DownloadMinSizeBytes} michael@0: ${OrIf} $4 > ${DownloadMaxSizeBytes} michael@0: ${NSD_KillTimer} OnDownload michael@0: InetBgDL::Get /RESET /END michael@0: StrCpy $DownloadReset "true" michael@0: michael@0: ${If} $DownloadRetryCount >= ${DownloadMaxRetries} michael@0: ; Use a timer so the UI has a chance to update michael@0: ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} michael@0: ${Else} michael@0: ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} michael@0: ${EndIf} michael@0: Return michael@0: ${EndIf} michael@0: michael@0: StrCpy $DownloadSizeBytes "$4" michael@0: System::Int64Op $4 / 2 michael@0: Pop $HalfOfDownload michael@0: System::Int64Op $HalfOfDownload / $InstallTotalSteps michael@0: Pop $InstallStepSize michael@0: SendMessage $Progressbar ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N michael@0: ${RemoveStyle} $Progressbar ${PBS_MARQUEE} michael@0: System::Int64Op $HalfOfDownload + $DownloadSizeBytes michael@0: Pop $R9 michael@0: SendMessage $Progressbar ${PBM_SETRANGE32} 0 $R9 michael@0: ${EndIf} michael@0: michael@0: ; Don't update the status until after the download starts michael@0: ${If} $2 != 0 michael@0: ${AndIf} "$4" == "" michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ; Handle the case where the downloaded size is greater than the maximum michael@0: ; expected size during the download. michael@0: ${If} $DownloadedBytes > ${DownloadMaxSizeBytes} michael@0: InetBgDL::Get /RESET /END michael@0: StrCpy $DownloadReset "true" michael@0: michael@0: ${If} $DownloadRetryCount >= ${DownloadMaxRetries} michael@0: ; Use a timer so the UI has a chance to update michael@0: ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} michael@0: ${Else} michael@0: ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} michael@0: ${EndIf} michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ${If} $IsDownloadFinished != "true" michael@0: ${If} $2 == 0 michael@0: ${NSD_KillTimer} OnDownload michael@0: StrCpy $IsDownloadFinished "true" michael@0: ; The first step of the install progress bar is determined by the michael@0: ; InstallProgressFirstStep define and provides the user with immediate michael@0: ; feedback. michael@0: StrCpy $InstallCounterStep "${InstallProgressFirstStep}" michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $EndDownloadPhaseTickCount michael@0: michael@0: StrCpy $DownloadedBytes "$DownloadSizeBytes" michael@0: michael@0: ; When a download has finished handle the case where the downloaded size michael@0: ; is less than the minimum expected size or greater than the maximum michael@0: ; expected size during the download. michael@0: ${If} $DownloadedBytes < ${DownloadMinSizeBytes} michael@0: ${OrIf} $DownloadedBytes > ${DownloadMaxSizeBytes} michael@0: InetBgDL::Get /RESET /END michael@0: StrCpy $DownloadReset "true" michael@0: michael@0: ${If} $DownloadRetryCount >= ${DownloadMaxRetries} michael@0: ; Use a timer so the UI has a chance to update michael@0: ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} michael@0: ${Else} michael@0: ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} michael@0: ${EndIf} michael@0: Return michael@0: ${EndIf} michael@0: michael@0: LockWindow on michael@0: ; Update the progress bars first in the UI change so they take affect michael@0: ; before other UI changes. michael@0: SendMessage $Progressbar ${PBM_SETPOS} $DownloadSizeBytes 0 michael@0: System::Int64Op $InstallStepSize * ${InstallProgressFirstStep} michael@0: Pop $R9 michael@0: SendMessage $Progressbar ${PBM_SETSTEP} $R9 0 michael@0: SendMessage $Progressbar ${PBM_STEPIT} 0 0 michael@0: SendMessage $Progressbar ${PBM_SETSTEP} $InstallStepSize 0 michael@0: ShowWindow $LabelDownloading ${SW_HIDE} michael@0: ShowWindow $LabelInstalling ${SW_SHOW} michael@0: ShowWindow $LabelBlurb2 ${SW_HIDE} michael@0: ShowWindow $BitmapBlurb2 ${SW_HIDE} michael@0: ShowWindow $LabelBlurb3 ${SW_SHOW} michael@0: ShowWindow $BitmapBlurb3 ${SW_SHOW} michael@0: ; Disable the Cancel button during the install michael@0: GetDlgItem $5 $HWNDPARENT 2 michael@0: EnableWindow $5 0 michael@0: LockWindow off michael@0: michael@0: ; Open a handle to prevent modification of the full installer michael@0: StrCpy $R9 "${INVALID_HANDLE_VALUE}" michael@0: System::Call 'kernel32::CreateFileW(w "$PLUGINSDIR\download.exe", \ michael@0: i ${GENERIC_READ}, \ michael@0: i ${FILE_SHARE_READ}, i 0, \ michael@0: i ${OPEN_EXISTING}, i 0, i 0) i .R9' michael@0: StrCpy $HandleDownload "$R9" michael@0: michael@0: ${If} $HandleDownload == ${INVALID_HANDLE_VALUE} michael@0: StrCpy $ExitCode "${ERR_PREINSTALL_INVALID_HANDLE}" michael@0: StrCpy $0 "0" michael@0: StrCpy $1 "0" michael@0: ${Else} michael@0: CertCheck::VerifyCertTrust "$PLUGINSDIR\download.exe" michael@0: Pop $0 michael@0: CertCheck::VerifyCertNameIssuer "$PLUGINSDIR\download.exe" \ michael@0: "${CertNameDownload}" "${CertIssuerDownload}" michael@0: Pop $1 michael@0: ${If} $0 == 0 michael@0: ${AndIf} $1 == 0 michael@0: StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES}" michael@0: ${ElseIf} $0 == 0 michael@0: StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED}" michael@0: ${ElseIf} $1 == 0 michael@0: StrCpy $ExitCode "${ERR_PREINSTALL_CERT_ATTRIBUTES}" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $EndPreInstallPhaseTickCount michael@0: michael@0: ${If} $0 == 0 michael@0: ${OrIf} $1 == 0 michael@0: ; Use a timer so the UI has a chance to update michael@0: ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ; Instead of extracting the files we use the downloaded installer to michael@0: ; install in case it needs to perform operations that the stub doesn't michael@0: ; know about. michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "InstallDirectoryPath" "$INSTDIR" michael@0: ; Don't create the QuickLaunch or Taskbar shortcut from the launched installer michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "QuickLaunchShortcut" "false" michael@0: ${If} $CheckboxShortcutOnDesktop == 1 michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "true" michael@0: ${Else} michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "false" michael@0: ${EndIf} michael@0: michael@0: ${If} $CheckboxShortcutInStartMenu == 1 michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "true" michael@0: ${Else} michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "false" michael@0: ${EndIf} michael@0: michael@0: !ifdef MOZ_MAINTENANCE_SERVICE michael@0: ${If} $CheckboxInstallMaintSvc == 1 michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "true" michael@0: ${Else} michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false" michael@0: ${EndIf} michael@0: !else michael@0: WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false" michael@0: !endif michael@0: michael@0: ; Write migrated to the shortcuts.ini file to prevent the installer michael@0: ; from creating a taskbar shortcut (Bug 791613). michael@0: ${GetShortcutsLogPath} $0 michael@0: Delete "$0" michael@0: ; Workaround to prevent pinning to the taskbar. michael@0: ${If} $CheckboxShortcutOnBar == 0 michael@0: WriteIniStr "$0" "TASKBAR" "Migrated" "true" michael@0: ${EndIf} michael@0: michael@0: ${OnStubInstallUninstall} $Progressbar $InstallCounterStep michael@0: michael@0: ; Delete the install.log and let the full installer create it. When the michael@0: ; installer closes it we can detect that it has completed. michael@0: Delete "$INSTDIR\install.log" michael@0: michael@0: ; Delete firefox.exe.moz-upgrade if it exists since it being present will michael@0: ; require an OS restart for the full installer. michael@0: Delete "$INSTDIR\${FileMainEXE}.moz-upgrade" michael@0: michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $EndPreInstallPhaseTickCount michael@0: michael@0: Exec "$\"$PLUGINSDIR\download.exe$\" /INI=$PLUGINSDIR\${CONFIG_INI}" michael@0: ${NSD_CreateTimer} CheckInstall ${InstallIntervalMS} michael@0: ${Else} michael@0: ${If} $HalfOfDownload != "true" michael@0: ${AndIf} $3 > $HalfOfDownload michael@0: StrCpy $HalfOfDownload "true" michael@0: LockWindow on michael@0: ShowWindow $LabelBlurb1 ${SW_HIDE} michael@0: ShowWindow $BitmapBlurb1 ${SW_HIDE} michael@0: ShowWindow $LabelBlurb2 ${SW_SHOW} michael@0: ShowWindow $BitmapBlurb2 ${SW_SHOW} michael@0: LockWindow off michael@0: ${EndIf} michael@0: StrCpy $DownloadedBytes "$3" michael@0: SendMessage $Progressbar ${PBM_SETPOS} $3 0 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function OnPing michael@0: InetBgDL::GetStats michael@0: # $0 = HTTP status code, 0=Completed michael@0: # $1 = Completed files michael@0: # $2 = Remaining files michael@0: # $3 = Number of downloaded bytes for the current file michael@0: # $4 = Size of current file (Empty string if the size is unknown) michael@0: # /RESET must be used if status $0 > 299 (e.g. failure) michael@0: # When status is $0 =< 299 it is handled by InetBgDL michael@0: ${If} $2 == 0 michael@0: ${OrIf} $0 > 299 michael@0: ${NSD_KillTimer} OnPing michael@0: ${If} $0 > 299 michael@0: InetBgDL::Get /RESET /END michael@0: ${EndIf} michael@0: ; The following will exit the installer michael@0: SetAutoClose true michael@0: StrCpy $R9 "2" michael@0: Call RelativeGotoPage michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function CheckInstall michael@0: IntOp $InstallCounterStep $InstallCounterStep + 1 michael@0: ${If} $InstallCounterStep >= $InstallTotalSteps michael@0: ${NSD_KillTimer} CheckInstall michael@0: ; Close the handle that prevents modification of the full installer michael@0: System::Call 'kernel32::CloseHandle(i $HandleDownload)' michael@0: StrCpy $ExitCode "${ERR_INSTALL_TIMEOUT}" michael@0: ; Use a timer so the UI has a chance to update michael@0: ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} michael@0: Return michael@0: ${EndIf} michael@0: michael@0: SendMessage $Progressbar ${PBM_STEPIT} 0 0 michael@0: michael@0: ${If} ${FileExists} "$INSTDIR\install.log" michael@0: Delete "$INSTDIR\install.tmp" michael@0: CopyFiles /SILENT "$INSTDIR\install.log" "$INSTDIR\install.tmp" michael@0: michael@0: ; The unfocus and refocus that happens approximately here is caused by the michael@0: ; installer calling SHChangeNotify to refresh the shortcut icons. michael@0: michael@0: ; When the full installer completes the installation the install.log will no michael@0: ; longer be in use. michael@0: ClearErrors michael@0: Delete "$INSTDIR\install.log" michael@0: ${Unless} ${Errors} michael@0: ${NSD_KillTimer} CheckInstall michael@0: ; Close the handle that prevents modification of the full installer michael@0: System::Call 'kernel32::CloseHandle(i $HandleDownload)' michael@0: Rename "$INSTDIR\install.tmp" "$INSTDIR\install.log" michael@0: Delete "$PLUGINSDIR\download.exe" michael@0: Delete "$PLUGINSDIR\${CONFIG_INI}" michael@0: System::Call "kernel32::GetTickCount()l .s" michael@0: Pop $EndInstallPhaseTickCount michael@0: System::Int64Op $InstallStepSize * ${InstallProgressFinishStep} michael@0: Pop $InstallStepSize michael@0: SendMessage $Progressbar ${PBM_SETSTEP} $InstallStepSize 0 michael@0: ${NSD_CreateTimer} FinishInstall ${InstallIntervalMS} michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function FinishInstall michael@0: ; The full installer has completed but the progress bar still needs to finish michael@0: ; so increase the size of the step. michael@0: IntOp $InstallCounterStep $InstallCounterStep + ${InstallProgressFinishStep} michael@0: ${If} $InstallTotalSteps < $InstallCounterStep michael@0: StrCpy $InstallCounterStep "$InstallTotalSteps" michael@0: ${EndIf} michael@0: michael@0: ${If} $InstallTotalSteps != $InstallCounterStep michael@0: SendMessage $Progressbar ${PBM_STEPIT} 0 0 michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ${NSD_KillTimer} FinishInstall michael@0: michael@0: SendMessage $Progressbar ${PBM_GETRANGE} 0 0 $R9 michael@0: SendMessage $Progressbar ${PBM_SETPOS} $R9 0 michael@0: michael@0: ${If} "$CheckboxSetAsDefault" == "1" michael@0: ${GetParameters} $0 michael@0: ClearErrors michael@0: ${GetOptions} "$0" "/UAC:" $0 michael@0: ${If} ${Errors} ; Not elevated michael@0: Call ExecSetAsDefaultAppUser michael@0: ${Else} ; Elevated - execute the function in the unelevated process michael@0: GetFunctionAddress $0 ExecSetAsDefaultAppUser michael@0: UAC::ExecCodeSegment $0 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ${If} $CheckboxShortcutOnBar == 1 michael@0: ${If} ${AtMostWinVista} michael@0: ClearErrors michael@0: ${GetParameters} $0 michael@0: ClearErrors michael@0: ${GetOptions} "$0" "/UAC:" $0 michael@0: ${If} ${Errors} michael@0: Call AddQuickLaunchShortcut michael@0: ${Else} michael@0: GetFunctionAddress $0 AddQuickLaunchShortcut michael@0: UAC::ExecCodeSegment $0 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade" michael@0: Delete "$INSTDIR\${FileMainEXE}" michael@0: Rename "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}" michael@0: ${EndIf} michael@0: michael@0: StrCpy $ExitCode "${ERR_SUCCESS}" michael@0: michael@0: StrCpy $InstallCounterStep 0 michael@0: ${NSD_CreateTimer} FinishProgressBar ${InstallIntervalMS} michael@0: FunctionEnd michael@0: michael@0: Function FinishProgressBar michael@0: IntOp $InstallCounterStep $InstallCounterStep + 1 michael@0: michael@0: ${If} $InstallCounterStep < 10 michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ${NSD_KillTimer} FinishProgressBar michael@0: michael@0: Call LaunchApp michael@0: michael@0: Call SendPing michael@0: FunctionEnd michael@0: michael@0: Function OnBack michael@0: StrCpy $WasOptionsButtonClicked "1" michael@0: StrCpy $R9 "1" ; Goto the next page michael@0: Call RelativeGotoPage michael@0: ; The call to Abort prevents NSIS from trying to move to the previous or the michael@0: ; next page. michael@0: Abort michael@0: FunctionEnd michael@0: michael@0: Function RelativeGotoPage michael@0: IntCmp $R9 0 0 Move Move michael@0: StrCmp $R9 "X" 0 Move michael@0: StrCpy $R9 "120" michael@0: michael@0: Move: michael@0: SendMessage $HWNDPARENT "0x408" "$R9" "" michael@0: FunctionEnd michael@0: michael@0: Function UpdateFreeSpaceLabel michael@0: ; Only update when $ExistingTopDir isn't set michael@0: ${If} "$ExistingTopDir" != "" michael@0: StrLen $5 "$ExistingTopDir" michael@0: StrLen $6 "$INSTDIR" michael@0: ${If} $5 <= $6 michael@0: StrCpy $7 "$INSTDIR" $5 michael@0: ${If} "$7" == "$ExistingTopDir" michael@0: Return michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: Call CheckSpace michael@0: michael@0: StrCpy $0 "$SpaceAvailableBytes" michael@0: michael@0: StrCpy $1 "$(BYTE)" michael@0: michael@0: ${If} $0 > 1024 michael@0: ${OrIf} $0 < 0 michael@0: ; Multiply by 10 so it is possible to display a decimal in the size michael@0: System::Int64Op $0 * 10 michael@0: Pop $0 michael@0: System::Int64Op $0 / 1024 michael@0: Pop $0 michael@0: StrCpy $1 "$(KILO)$(BYTE)" michael@0: ${If} $0 > 10240 michael@0: ${OrIf} $0 < 0 michael@0: System::Int64Op $0 / 1024 michael@0: Pop $0 michael@0: StrCpy $1 "$(MEGA)$(BYTE)" michael@0: ${If} $0 > 10240 michael@0: ${OrIf} $0 < 0 michael@0: System::Int64Op $0 / 1024 michael@0: Pop $0 michael@0: StrCpy $1 "$(GIGA)$(BYTE)" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: StrLen $3 "$0" michael@0: ${If} $3 > 1 michael@0: StrCpy $2 "$0" -1 ; All characters except the last one michael@0: StrCpy $0 "$0" "" -1 ; The last character michael@0: ${If} "$0" == "0" michael@0: StrCpy $0 "$2" ; Don't display the decimal if it is 0 michael@0: ${Else} michael@0: StrCpy $0 "$2.$0" michael@0: ${EndIf} michael@0: ${ElseIf} $3 == 1 michael@0: StrCpy $0 "0.$0" michael@0: ${Else} michael@0: ; This should never happen michael@0: System::Int64Op $0 / 10 michael@0: Pop $0 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: SendMessage $LabelFreeSpace ${WM_SETTEXT} 0 "STR:$0 $1" michael@0: michael@0: FunctionEnd michael@0: michael@0: Function OnChange_DirRequest michael@0: Pop $0 michael@0: System::Call 'user32::GetWindowTextW(i $DirRequest, w .r0, i ${NSIS_MAX_STRLEN})' michael@0: StrCpy $1 "$0" 1 ; the first character michael@0: ${If} "$1" == "$\"" michael@0: StrCpy $1 "$0" "" -1 ; the last character michael@0: ${If} "$1" == "$\"" michael@0: StrCpy $0 "$0" "" 1 ; all but the first character michael@0: StrCpy $0 "$0" -1 ; all but the last character michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: StrCpy $INSTDIR "$0" michael@0: Call UpdateFreeSpaceLabel michael@0: michael@0: GetDlgItem $0 $HWNDPARENT 1 ; Install button michael@0: ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" michael@0: ${Else} michael@0: SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)" michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function OnClick_ButtonBrowse michael@0: StrCpy $0 "$INSTDIR" michael@0: nsDialogs::SelectFolderDialog /NOUNLOAD "$(SELECT_FOLDER_TEXT)" $0 michael@0: Pop $0 michael@0: ${If} $0 == "error" ; returns 'error' if 'cancel' was pressed? michael@0: Return michael@0: ${EndIf} michael@0: michael@0: ${If} $0 != "" michael@0: StrCpy $INSTDIR "$0" michael@0: System::Call 'user32::SetWindowTextW(i $DirRequest, w "$INSTDIR")' michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function CheckSpace michael@0: ${If} "$ExistingTopDir" != "" michael@0: StrLen $0 "$ExistingTopDir" michael@0: StrLen $1 "$INSTDIR" michael@0: ${If} $0 <= $1 michael@0: StrCpy $2 "$INSTDIR" $3 michael@0: ${If} "$2" == "$ExistingTopDir" michael@0: Return michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: StrCpy $ExistingTopDir "$INSTDIR" michael@0: ${DoUntil} ${FileExists} "$ExistingTopDir" michael@0: ${GetParent} "$ExistingTopDir" $ExistingTopDir michael@0: ${If} "$ExistingTopDir" == "" michael@0: StrCpy $SpaceAvailableBytes "0" michael@0: StrCpy $HasRequiredSpaceAvailable "false" michael@0: Return michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ${GetLongPath} "$ExistingTopDir" $ExistingTopDir michael@0: michael@0: ; GetDiskFreeSpaceExW requires a backslash. michael@0: StrCpy $0 "$ExistingTopDir" "" -1 ; the last character michael@0: ${If} "$0" != "\" michael@0: StrCpy $0 "\" michael@0: ${Else} michael@0: StrCpy $0 "" michael@0: ${EndIf} michael@0: michael@0: System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i("$ExistingTopDir$0", .r1, .r2, .r3) .' michael@0: StrCpy $SpaceAvailableBytes "$1" michael@0: michael@0: System::Int64Op $SpaceAvailableBytes / 1048576 michael@0: Pop $1 michael@0: System::Int64Op $1 > ${APPROXIMATE_REQUIRED_SPACE_MB} michael@0: Pop $1 michael@0: ${If} $1 == 1 michael@0: StrCpy $HasRequiredSpaceAvailable "true" michael@0: ${Else} michael@0: StrCpy $HasRequiredSpaceAvailable "false" michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function CanWrite michael@0: StrCpy $CanWriteToInstallDir "false" michael@0: michael@0: StrCpy $0 "$INSTDIR" michael@0: ; Use the existing directory when it exists michael@0: ${Unless} ${FileExists} "$INSTDIR" michael@0: ; Get the topmost directory that exists for new installs michael@0: ${DoUntil} ${FileExists} "$0" michael@0: ${GetParent} "$0" $0 michael@0: ${If} "$0" == "" michael@0: Return michael@0: ${EndIf} michael@0: ${Loop} michael@0: ${EndUnless} michael@0: michael@0: GetTempFileName $2 "$0" michael@0: Delete $2 michael@0: CreateDirectory "$2" michael@0: ${If} ${FileExists} "$2" michael@0: ${If} ${FileExists} "$INSTDIR" michael@0: GetTempFileName $3 "$INSTDIR" michael@0: ${Else} michael@0: GetTempFileName $3 "$2" michael@0: ${EndIf} michael@0: ${If} ${FileExists} "$3" michael@0: Delete "$3" michael@0: StrCpy $CanWriteToInstallDir "true" michael@0: ${EndIf} michael@0: RmDir "$2" michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function AddQuickLaunchShortcut michael@0: CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" michael@0: ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" michael@0: ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ michael@0: "$INSTDIR" michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function ExecSetAsDefaultAppUser michael@0: ; Using the helper.exe lessens the stub installer size. michael@0: ; This could ask for elevatation when the user doesn't install as admin. michael@0: Exec "$\"$INSTDIR\uninstall\helper.exe$\" /SetAsDefaultAppUser" michael@0: FunctionEnd michael@0: michael@0: Function LaunchApp michael@0: FindWindow $0 "${WindowClass}" michael@0: ${If} $0 <> 0 ; integer comparison michael@0: StrCpy $FirefoxLaunchCode "1" michael@0: MessageBox MB_OK|MB_ICONQUESTION "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)" michael@0: Return michael@0: ${EndIf} michael@0: michael@0: StrCpy $FirefoxLaunchCode "2" michael@0: michael@0: ; Set the current working directory to the installation directory michael@0: SetOutPath "$INSTDIR" michael@0: ClearErrors michael@0: ${GetParameters} $0 michael@0: ${GetOptions} "$0" "/UAC:" $1 michael@0: ${If} ${Errors} michael@0: Exec "$\"$INSTDIR\${FileMainEXE}$\"" michael@0: ${Else} michael@0: GetFunctionAddress $0 LaunchAppFromElevatedProcess michael@0: UAC::ExecCodeSegment $0 michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: Function LaunchAppFromElevatedProcess michael@0: ; Find the installation directory when launching using GetFunctionAddress michael@0: ; from an elevated installer since $INSTDIR will not be set in this installer michael@0: ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 michael@0: ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" michael@0: ${GetPathFromString} "$0" $0 michael@0: ; Set the current working directory to the installation directory michael@0: ${GetParent} "$0" $1 michael@0: SetOutPath "$1" michael@0: Exec "$\"$0$\"" michael@0: FunctionEnd michael@0: michael@0: Function DisplayDownloadError michael@0: ${NSD_KillTimer} DisplayDownloadError michael@0: MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK +1 michael@0: StrCpy $OpenedDownloadPage "1" ; Already initialized to 0 michael@0: michael@0: ${If} "$OpenedDownloadPage" == "1" michael@0: ClearErrors michael@0: ${GetParameters} $0 michael@0: ${GetOptions} "$0" "/UAC:" $1 michael@0: ${If} ${Errors} michael@0: Call OpenManualDownloadURL michael@0: ${Else} michael@0: GetFunctionAddress $0 OpenManualDownloadURL michael@0: UAC::ExecCodeSegment $0 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: Call SendPing michael@0: FunctionEnd michael@0: michael@0: Function OpenManualDownloadURL michael@0: ExecShell "open" "${URLManualDownload}${URLManualDownloadAppend}" michael@0: FunctionEnd michael@0: michael@0: Section michael@0: SectionEnd