diff options
Diffstat (limited to 'browser/installer/windows/nsis')
-rw-r--r-- | browser/installer/windows/nsis/defines.nsi.in | 110 | ||||
-rwxr-xr-x | browser/installer/windows/nsis/installer.nsi | 1332 | ||||
-rw-r--r-- | browser/installer/windows/nsis/maintenanceservice_installer.nsi | 335 | ||||
-rw-r--r-- | browser/installer/windows/nsis/oneoff_en-US.nsh | 12 | ||||
-rwxr-xr-x | browser/installer/windows/nsis/shared.nsh | 1410 | ||||
-rw-r--r-- | browser/installer/windows/nsis/stub.nsi | 2093 | ||||
-rwxr-xr-x | browser/installer/windows/nsis/uninstaller.nsi | 627 | ||||
-rw-r--r-- | browser/installer/windows/nsis/updater_append.ini | 12 |
8 files changed, 5931 insertions, 0 deletions
diff --git a/browser/installer/windows/nsis/defines.nsi.in b/browser/installer/windows/nsis/defines.nsi.in new file mode 100644 index 000000000..ffb23ff1c --- /dev/null +++ b/browser/installer/windows/nsis/defines.nsi.in @@ -0,0 +1,110 @@ +#filter substitution +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Defining FunnelcakeVersion will append the value of StubURLVersionAppend to +# StubURLVersion, append the value of URLManualDownloadAppend to +# URLManualDownload, and append the value of URLStubDownloadAppend to +# URLStubDownload. The value of FunnelcakeVersion should not be defined when it +# is not used and when it is defined its value should never be empty. +# !define FunnelcakeVersion "999" + +!ifdef FunnelcakeVersion +!define URLManualDownloadAppend "&f=${FunnelcakeVersion}" +!define URLStubDownloadAppend "-f${FunnelcakeVersion}" +!define StubURLVersionAppend "-${FunnelcakeVersion}" +!else +!define URLManualDownloadAppend "" +!define URLStubDownloadAppend "" +!define StubURLVersionAppend "" +!endif + +# These defines should match application.ini settings +!define AppName "Firefox" +!define AppVersion "@APP_VERSION@" +!define GREVersion @MOZILLA_VERSION@ +!define AB_CD "@AB_CD@" + +!define FileMainEXE "@MOZ_APP_NAME@.exe" +!define WindowClass "FirefoxMessageWindow" +!define DDEApplication "Firefox" +!define AppRegName "Firefox" + +!ifndef DEV_EDITION +!define BrandShortName "@MOZ_APP_DISPLAYNAME@" +!endif +!define BrandFullName "${BrandFullNameInternal}" + +!define CERTIFICATE_NAME "Mozilla Corporation" +!define CERTIFICATE_ISSUER "DigiCert SHA2 Assured ID Code Signing CA" +; Changing the name or issuer requires us to have both the old and the new +; in the registry at the same time, temporarily. +!define CERTIFICATE_NAME_PREVIOUS "Mozilla Corporation" +!define CERTIFICATE_ISSUER_PREVIOUS "DigiCert Assured ID Code Signing CA-1" + +# LSP_CATEGORIES is the permitted LSP categories for the application. Each LSP +# category value is ANDed together to set multiple permitted categories. +# See http://msdn.microsoft.com/en-us/library/ms742253%28VS.85%29.aspx +# The value below removes all LSP categories previously set. +!define LSP_CATEGORIES "0x00000000" + +!if "@MOZ_UPDATE_CHANNEL@" == "" +!define UpdateChannel "Unknown" +!else +!define UpdateChannel "@MOZ_UPDATE_CHANNEL@" +!endif + +# Due to official and beta using the same branding this is needed to +# differentiante between the url used by the stub for downloading. +!if "@MOZ_UPDATE_CHANNEL@" == "beta" +!define BETA_UPDATE_CHANNEL +!endif + +!define BaseURLStubPing "http://download-stats.mozilla.org/stub" + +# ARCH is used when it is necessary to differentiate the x64 registry keys from +# the x86 registry keys (e.g. the uninstall registry key). +#ifdef HAVE_64BIT_BUILD +!define HAVE_64BIT_BUILD +!define ARCH "x64" +!define MinSupportedVer "Microsoft Windows 7 x64" +#else +!define ARCH "x86" +!define MinSupportedVer "Microsoft Windows XP SP2" +#endif + +!define MinSupportedCPU "SSE2" + +#ifdef MOZ_MAINTENANCE_SERVICE +!define MOZ_MAINTENANCE_SERVICE +#endif + +# File details shared by both the installer and uninstaller +VIProductVersion "1.0.0.0" +VIAddVersionKey "ProductName" "${BrandShortName}" +VIAddVersionKey "CompanyName" "${CompanyName}" +#ifdef MOZ_OFFICIAL_BRANDING +VIAddVersionKey "LegalTrademarks" "${BrandShortName} is a Trademark of The Mozilla Foundation." +#endif +VIAddVersionKey "LegalCopyright" "${CompanyName}" +VIAddVersionKey "FileVersion" "${AppVersion}" +VIAddVersionKey "ProductVersion" "${AppVersion}" +# Comments is not used but left below commented out for future reference +# VIAddVersionKey "Comments" "Comments" + +# It isn't possible to get the size of the installation prior to downloading +# so the stub installer uses an estimate. The size is derived from the size of +# the complete installer, the size of the extracted complete installer, and at +# least 15 MB additional for working room. +!define APPROXIMATE_REQUIRED_SPACE_MB "145" + +# Control positions in Dialog Units so they are placed correctly with +# non-default DPI settings +!define OPTIONS_ITEM_EDGE_DU 90u +!define OPTIONS_ITEM_WIDTH_DU 356u +!define OPTIONS_SUBITEM_EDGE_DU 119u +!define OPTIONS_SUBITEM_WIDTH_DU 327u +!define INSTALL_BLURB_TOP_DU 78u +!define APPNAME_BMP_EDGE_DU 19u +!define APPNAME_BMP_TOP_DU 12u diff --git a/browser/installer/windows/nsis/installer.nsi b/browser/installer/windows/nsis/installer.nsi new file mode 100755 index 000000000..1f20c01eb --- /dev/null +++ b/browser/installer/windows/nsis/installer.nsi @@ -0,0 +1,1332 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Required Plugins: +# AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in +# ApplicationID http://nsis.sourceforge.net/ApplicationID_plug-in +# CityHash http://dxr.mozilla.org/mozilla-central/source/other-licenses/nsis/Contrib/CityHash +# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in +# UAC http://nsis.sourceforge.net/UAC_plug-in +# ServicesHelper Mozilla specific plugin that is located in /other-licenses/nsis + +; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs +!verbose 3 + +; 7-Zip provides better compression than the lzma from NSIS so we add the files +; uncompressed and use 7-Zip to create a SFX archive of it +SetDatablockOptimize on +SetCompress off +CRCCheck on + +RequestExecutionLevel user + +; The commands inside this ifdef require NSIS 3.0a2 or greater so the ifdef can +; be removed after we require NSIS 3.0a2 or greater. +!ifdef NSIS_PACKEDVERSION + Unicode true + ManifestSupportedOS all + ManifestDPIAware true +!endif + +!addplugindir ./ + +Var TmpVal +Var InstallType +Var AddStartMenuSC +Var AddTaskbarSC +Var AddQuickLaunchSC +Var AddDesktopSC +Var InstallMaintenanceService +Var PageName +Var PreventRebootRequired + +; By defining NO_STARTMENU_DIR an installer that doesn't provide an option for +; an application's Start Menu PROGRAMS directory and doesn't define the +; StartMenuDir variable can use the common InstallOnInitCommon macro. +!define NO_STARTMENU_DIR + +; On Vista and above attempt to elevate Standard Users in addition to users that +; are a member of the Administrators group. +!define NONADMIN_ELEVATE + +!define AbortSurveyURL "http://www.kampyle.com/feedback_form/ff-feedback-form.php?site_code=8166124&form_id=12116&url=" + +; Other included files may depend upon these includes! +; The following includes are provided by NSIS. +!include FileFunc.nsh +!include LogicLib.nsh +!include MUI.nsh +!include WinMessages.nsh +!include WinVer.nsh +!include WordFunc.nsh + +!insertmacro GetOptions +!insertmacro GetParameters +!insertmacro GetSize +!insertmacro StrFilter +!insertmacro WordFind +!insertmacro WordReplace + +; The following includes are custom. +!include branding.nsi +!include defines.nsi +!include common.nsh +!include locales.nsi + +VIAddVersionKey "FileDescription" "${BrandShortName} Installer" +VIAddVersionKey "OriginalFilename" "setup.exe" + +; Must be inserted before other macros that use logging +!insertmacro _LoggingCommon + +!insertmacro AddDisabledDDEHandlerValues +!insertmacro ChangeMUIHeaderImage +!insertmacro CheckForFilesInUse +!insertmacro CleanUpdateDirectories +!insertmacro CopyFilesFromDir +!insertmacro CreateRegKey +!insertmacro GetLongPath +!insertmacro GetPathFromString +!insertmacro GetParent +!insertmacro InitHashAppModelId +!insertmacro IsHandlerForInstallDir +!insertmacro IsPinnedToTaskBar +!insertmacro IsUserAdmin +!insertmacro LogDesktopShortcut +!insertmacro LogQuickLaunchShortcut +!insertmacro LogStartMenuShortcut +!insertmacro ManualCloseAppPrompt +!insertmacro PinnedToStartMenuLnkCount +!insertmacro RegCleanAppHandler +!insertmacro RegCleanMain +!insertmacro RegCleanUninstall +!insertmacro RemovePrecompleteEntries +!insertmacro SetAppLSPCategories +!insertmacro SetBrandNameVars +!insertmacro UpdateShortcutAppModelIDs +!insertmacro UnloadUAC +!insertmacro WriteRegStr2 +!insertmacro WriteRegDWORD2 + +!include shared.nsh + +; Helper macros for ui callbacks. Insert these after shared.nsh +!insertmacro CheckCustomCommon +!insertmacro InstallEndCleanupCommon +!insertmacro InstallOnInitCommon +!insertmacro InstallStartCleanupCommon +!insertmacro LeaveDirectoryCommon +!insertmacro LeaveOptionsCommon +!insertmacro OnEndCommon +!insertmacro PreDirectoryCommon + +Name "${BrandFullName}" +OutFile "setup.exe" +!ifdef HAVE_64BIT_BUILD + InstallDir "$PROGRAMFILES64\${BrandFullName}\" +!else + InstallDir "$PROGRAMFILES32\${BrandFullName}\" +!endif +ShowInstDetails nevershow + +################################################################################ +# Modern User Interface - MUI + +!define MOZ_MUI_CUSTOM_ABORT +!define MUI_CUSTOMFUNCTION_ABORT "CustomAbort" +!define MUI_ICON setup.ico +!define MUI_UNICON setup.ico +!define MUI_WELCOMEPAGE_TITLE_3LINES +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_WELCOMEFINISHPAGE_BITMAP wizWatermark.bmp + +; Use a right to left header image when the language is right to left +!ifdef ${AB_CD}_rtl +!define MUI_HEADERIMAGE_BITMAP_RTL wizHeaderRTL.bmp +!else +!define MUI_HEADERIMAGE_BITMAP wizHeader.bmp +!endif + +/** + * Installation Pages + */ +; Welcome Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE preWelcome +!insertmacro MUI_PAGE_WELCOME + +; Custom Options Page +Page custom preOptions leaveOptions + +; Select Install Directory Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE preDirectory +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE leaveDirectory +!define MUI_DIRECTORYPAGE_VERIFYONLEAVE +!insertmacro MUI_PAGE_DIRECTORY + +; Custom Components Page +!ifdef MOZ_MAINTENANCE_SERVICE +Page custom preComponents leaveComponents +!endif + +; Custom Shortcuts Page +Page custom preShortcuts leaveShortcuts + +; Custom Summary Page +Page custom preSummary leaveSummary + +; Install Files Page +!insertmacro MUI_PAGE_INSTFILES + +; Finish Page +!define MUI_FINISHPAGE_TITLE_3LINES +!define MUI_FINISHPAGE_RUN +!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp +!define MUI_FINISHPAGE_RUN_TEXT $(LAUNCH_TEXT) +!define MUI_PAGE_CUSTOMFUNCTION_PRE preFinish +!insertmacro MUI_PAGE_FINISH + +; Use the default dialog for IDD_VERIFY for a simple Banner +ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe" + +################################################################################ +# Install Sections + +; Cleanup operations to perform at the start of the installation. +Section "-InstallStartCleanup" + SetDetailsPrint both + DetailPrint $(STATUS_CLEANUP) + SetDetailsPrint none + + SetOutPath "$INSTDIR" + ${StartInstallLog} "${BrandFullName}" "${AB_CD}" "${AppVersion}" "${GREVersion}" + + StrCpy $R9 "true" + StrCpy $PreventRebootRequired "false" + ${GetParameters} $R8 + ${GetOptions} "$R8" "/INI=" $R7 + ${Unless} ${Errors} + ; The configuration file must also exist + ${If} ${FileExists} "$R7" + ReadINIStr $R9 $R7 "Install" "RemoveDistributionDir" + ReadINIStr $R8 $R7 "Install" "PreventRebootRequired" + ${If} $R8 == "true" + StrCpy $PreventRebootRequired "true" + ${EndIf} + ${EndIf} + ${EndUnless} + + ; Remove directories and files we always control before parsing the uninstall + ; log so empty directories can be removed. + ${If} ${FileExists} "$INSTDIR\updates" + RmDir /r "$INSTDIR\updates" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\updated" + RmDir /r "$INSTDIR\updated" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\defaults\shortcuts" + RmDir /r "$INSTDIR\defaults\shortcuts" + ${EndIf} + ; Only remove the distribution directory if it exists and if the installer + ; isn't launched with an ini file that has RemoveDistributionDir=false in the + ; install section. + ${If} ${FileExists} "$INSTDIR\distribution" + ${AndIf} $R9 != "false" + RmDir /r "$INSTDIR\distribution" + ${EndIf} + + ; Delete the app exe if present to prevent launching the app while we are + ; installing. + ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + ; If the user closed the application it can take several seconds for it to + ; shut down completely. If the application is being used by another user we + ; can rename the file and then delete is when the system is restarted. + Sleep 5000 + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ClearErrors + ${EndIf} + + ; setup the application model id registration value + ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" + + ; Remove the updates directory for Vista and above + ${CleanUpdateDirectories} "Mozilla\Firefox" "Mozilla\updates" + + ${RemoveDeprecatedFiles} + ${RemovePrecompleteEntries} "false" + + ${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js" + Delete "$INSTDIR\defaults\pref\channel-prefs.js" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\defaults\pref" + RmDir "$INSTDIR\defaults\pref" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\defaults" + RmDir "$INSTDIR\defaults" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\uninstall" + ; Remove the uninstall directory that we control + RmDir /r "$INSTDIR\uninstall" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\update-settings.ini" + Delete "$INSTDIR\update-settings.ini" + ${EndIf} + + ; Explictly remove empty webapprt dir in case it exists (bug 757978). + RmDir "$INSTDIR\webapprt\components" + RmDir "$INSTDIR\webapprt" + + ${InstallStartCleanupCommon} +SectionEnd + +Section "-Application" APP_IDX + ${StartUninstallLog} + + SetDetailsPrint both + DetailPrint $(STATUS_INSTALL_APP) + SetDetailsPrint none + + ${LogHeader} "Installing Main Files" + ${CopyFilesFromDir} "$EXEDIR\core" "$INSTDIR" \ + "$(ERROR_CREATE_DIRECTORY_PREFIX)" \ + "$(ERROR_CREATE_DIRECTORY_SUFFIX)" + + ; Register DLLs + ; XXXrstrong - AccessibleMarshal.dll can be used by multiple applications but + ; is only registered for the last application installed. When the last + ; application installed is uninstalled AccessibleMarshal.dll will no longer be + ; registered. bug 338878 + ${LogHeader} "DLL Registration" + ClearErrors + ${RegisterDLL} "$INSTDIR\AccessibleMarshal.dll" + ${If} ${Errors} + ${LogMsg} "** ERROR Registering: $INSTDIR\AccessibleMarshal.dll **" + ${Else} + ${LogUninstall} "DLLReg: \AccessibleMarshal.dll" + ${LogMsg} "Registered: $INSTDIR\AccessibleMarshal.dll" + ${EndIf} + + ClearErrors + + ; Default for creating Start Menu shortcut + ; (1 = create, 0 = don't create) + ${If} $AddStartMenuSC == "" + StrCpy $AddStartMenuSC "1" + ${EndIf} + + ; Default for creating Quick Launch shortcut (1 = create, 0 = don't create) + ${If} $AddQuickLaunchSC == "" + ; Don't install the quick launch shortcut on Windows 7 + ${If} ${AtLeastWin7} + StrCpy $AddQuickLaunchSC "0" + ${Else} + StrCpy $AddQuickLaunchSC "1" + ${EndIf} + ${EndIf} + + ; Default for creating Desktop shortcut (1 = create, 0 = don't create) + ${If} $AddDesktopSC == "" + StrCpy $AddDesktopSC "1" + ${EndIf} + + ${LogHeader} "Adding Registry Entries" + SetShellVarContext current ; Set SHCTX to HKCU + ${RegCleanMain} "Software\Mozilla" + ${RegCleanUninstall} + ${UpdateProtocolHandlers} + + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" + ${If} ${Errors} + StrCpy $TmpVal "HKCU" ; used primarily for logging + ${Else} + SetShellVarContext all ; Set SHCTX to HKLM + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + StrCpy $TmpVal "HKLM" ; used primarily for logging + ${RegCleanMain} "Software\Mozilla" + ${RegCleanUninstall} + ${UpdateProtocolHandlers} + + ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" + ${If} "$0" != "${GREVersion}" + WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}" + ${EndIf} + ${EndIf} + + ${RemoveDeprecatedKeys} + + ; The previous installer adds several regsitry values to both HKLM and HKCU. + ; We now try to add to HKLM and if that fails to HKCU + + ; The order that reg keys and values are added is important if you use the + ; uninstall log to remove them on uninstall. When using the uninstall log you + ; MUST add children first so they will be removed first on uninstall so they + ; will be empty when the key is deleted. This allows the uninstaller to + ; specify that only empty keys will be deleted. + ${SetAppKeys} + + ${FixClassKeys} + + ; Uninstall keys can only exist under HKLM on some versions of windows. Since + ; it doesn't cause problems always add them. + ${SetUninstallKeys} + + ; On install always add the FirefoxHTML and FirefoxURL keys. + ; An empty string is used for the 5th param because FirefoxHTML is not a + ; protocol handler. + ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8 + StrCpy $2 "$\"$8$\" -osint -url $\"%1$\"" + + ; In Win8, the delegate execute handler picks up the value in FirefoxURL and + ; FirefoxHTML to launch the desktop browser when it needs to. + ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \ + "${AppRegName} Document" "" + ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \ + "true" + + ; For pre win8, the following keys should only be set if we can write to HKLM. + ; For post win8, the keys below get set in both HKLM and HKCU. + ${If} $TmpVal == "HKLM" + ; Set the Start Menu Internet and Vista Registered App HKLM registry keys. + ${SetStartMenuInternet} "HKLM" + ${FixShellIconHandler} "HKLM" + + ; If we are writing to HKLM and create either the desktop or start menu + ; shortcuts set IconsVisible to 1 otherwise to 0. + ; Taskbar shortcuts imply having a start menu shortcut. + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo" + ${If} $AddDesktopSC == 1 + ${OrIf} $AddStartMenuSC == 1 + ${OrIf} $AddTaskbarSC == 1 + WriteRegDWORD HKLM "$0" "IconsVisible" 1 + ${Else} + WriteRegDWORD HKLM "$0" "IconsVisible" 0 + ${EndIf} + ${EndIf} + + ${If} ${AtLeastWin8} + ; Set the Start Menu Internet and Vista Registered App HKCU registry keys. + ${SetStartMenuInternet} "HKCU" + ${FixShellIconHandler} "HKCU" + + ; If we create either the desktop or start menu shortcuts, then + ; set IconsVisible to 1 otherwise to 0. + ; Taskbar shortcuts imply having a start menu shortcut. + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo" + ${If} $AddDesktopSC == 1 + ${OrIf} $AddStartMenuSC == 1 + ${OrIf} $AddTaskbarSC == 1 + WriteRegDWORD HKCU "$0" "IconsVisible" 1 + ${Else} + WriteRegDWORD HKCU "$0" "IconsVisible" 0 + ${EndIf} + ${EndIf} + +!ifdef MOZ_MAINTENANCE_SERVICE + ; If the maintenance service page was displayed then a value was already + ; explicitly selected for installing the maintenance service and + ; and so InstallMaintenanceService will already be 0 or 1. + ; If the maintenance service page was not displayed then + ; InstallMaintenanceService will be equal to "". + ${If} $InstallMaintenanceService == "" + Call IsUserAdmin + Pop $R0 + ${If} $R0 == "true" + ; Only proceed if we have HKLM write access + ${AndIf} $TmpVal == "HKLM" + ; On Windows < XP SP3 we do not install the maintenance service. + ${If} ${IsWinXP} + ${AndIf} ${AtMostServicePack} 2 + StrCpy $InstallMaintenanceService "0" + ${Else} + ; The user is an admin, so we should default to installing the service. + StrCpy $InstallMaintenanceService "1" + ${EndIf} + ${Else} + ; The user is not admin, so we can't install the service. + StrCpy $InstallMaintenanceService "0" + ${EndIf} + ${EndIf} + + ${If} $InstallMaintenanceService == "1" + ; The user wants to install the maintenance service, so execute + ; the pre-packaged maintenance service installer. + ; This option can only be turned on if the user is an admin so there + ; is no need to use ExecShell w/ verb runas to enforce elevated. + nsExec::Exec "$\"$INSTDIR\maintenanceservice_installer.exe$\"" + ${EndIf} +!endif + + ; These need special handling on uninstall since they may be overwritten by + ; an install into a different location. + StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\App Paths\${FileMainEXE}" + ${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0 + ${WriteRegStr2} $TmpVal "$0" "Path" "$INSTDIR" 0 + + StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9" + ${CreateRegKey} "$TmpVal" "$0" 0 + StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe" + ${CreateRegKey} "$TmpVal" "$0" 0 + + ${If} $TmpVal == "HKLM" + ; Set the permitted LSP Categories for WinVista and above + ${SetAppLSPCategories} ${LSP_CATEGORIES} + ${EndIf} + + ; Create shortcuts + ${LogHeader} "Adding Shortcuts" + + ; Remove the start menu shortcuts and directory if the SMPROGRAMS section + ; exists in the shortcuts_log.ini and the SMPROGRAMS. The installer's shortcut + ; creation code will create the shortcut in the root of the Start Menu + ; Programs directory. + ${RemoveStartMenuDir} + + ; Always add the application's shortcuts to the shortcuts log ini file. The + ; DeleteShortcuts macro will do the right thing on uninstall if the + ; shortcuts don't exist. + ${LogStartMenuShortcut} "${BrandFullName}.lnk" + ${LogQuickLaunchShortcut} "${BrandFullName}.lnk" + ${LogDesktopShortcut} "${BrandFullName}.lnk" + + ; Best effort to update the Win7 taskbar and start menu shortcut app model + ; id's. The possible contexts are current user / system and the user that + ; elevated the installer. + Call FixShortcutAppModelIDs + ; If the current context is all also perform Win7 taskbar and start menu link + ; maintenance for the current user context. + ${If} $TmpVal == "HKLM" + SetShellVarContext current ; Set SHCTX to HKCU + Call FixShortcutAppModelIDs + SetShellVarContext all ; Set SHCTX to HKLM + ${EndIf} + + ; If running elevated also perform Win7 taskbar and start menu link + ; maintenance for the unelevated user context in case that is different than + ; the current user. + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${Unless} ${Errors} + GetFunctionAddress $0 FixShortcutAppModelIDs + UAC::ExecCodeSegment $0 + ${EndUnless} + + ; UAC only allows elevating to an Admin account so there is no need to add + ; the Start Menu or Desktop shortcuts from the original unelevated process + ; since this will either add it for the user if unelevated or All Users if + ; elevated. + ${If} $AddStartMenuSC == 1 + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true" + ${EndIf} + ${LogMsg} "Added Shortcut: $SMPROGRAMS\${BrandFullName}.lnk" + ${Else} + ${LogMsg} "** ERROR Adding Shortcut: $SMPROGRAMS\${BrandFullName}.lnk" + ${EndIf} + ${EndIf} + + ; Update lastwritetime of the Start Menu shortcut to clear the tile cache. + ${If} ${AtLeastWin8} + ${AndIf} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + FileOpen $0 "$SMPROGRAMS\${BrandFullName}.lnk" a + FileClose $0 + ${EndIf} + + ${If} $AddDesktopSC == 1 + CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "$AppUserModelID" "true" + ${EndIf} + ${LogMsg} "Added Shortcut: $DESKTOP\${BrandFullName}.lnk" + ${Else} + ${LogMsg} "** ERROR Adding Shortcut: $DESKTOP\${BrandFullName}.lnk" + ${EndIf} + ${EndIf} + + ; If elevated the Quick Launch shortcut must be added from the unelevated + ; original process. + ${If} $AddQuickLaunchSC == 1 + ${Unless} ${AtLeastWin7} + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} + Call AddQuickLaunchShortcut + ${LogMsg} "Added Shortcut: $QUICKLAUNCH\${BrandFullName}.lnk" + ${Else} + ; It is not possible to add a log entry from the unelevated process so + ; add the log entry without the path since there is no simple way to + ; know the correct full path. + ${LogMsg} "Added Quick Launch Shortcut: ${BrandFullName}.lnk" + GetFunctionAddress $0 AddQuickLaunchShortcut + UAC::ExecCodeSegment $0 + ${EndIf} + ${EndUnless} + ${EndIf} + +!ifdef MOZ_MAINTENANCE_SERVICE + ${If} $TmpVal == "HKLM" + ; Add the registry keys for allowed certificates. + ${AddMaintCertKeys} + ${EndIf} +!endif +SectionEnd + +; Cleanup operations to perform at the end of the installation. +Section "-InstallEndCleanup" + SetDetailsPrint both + DetailPrint "$(STATUS_CLEANUP)" + SetDetailsPrint none + + ${Unless} ${Silent} + ClearErrors + ${MUI_INSTALLOPTIONS_READ} $0 "summary.ini" "Field 4" "State" + ${If} "$0" == "1" + ; NB: this code is duplicated in stub.nsi. Please keep in sync. + ; For data migration in the app, we want to know what the default browser + ; value was before we changed it. To do so, we read it here and store it + ; in our own registry key. + StrCpy $0 "" + ${If} ${AtLeastWinVista} + AppAssocReg::QueryCurrentDefault "http" "protocol" "effective" + Pop $1 + ; If the method hasn't failed, $1 will contain the progid. Check: + ${If} "$1" != "method failed" + ${AndIf} "$1" != "method not available" + ; Read the actual command from the progid + ReadRegStr $0 HKCR "$1\shell\open\command" "" + ${EndIf} + ${EndIf} + ; If using the App Association Registry didn't happen or failed, fall back + ; to the effective http default: + ${If} "$0" == "" + ReadRegStr $0 HKCR "http\shell\open\command" "" + ${EndIf} + ; If we have something other than empty string now, write the value. + ${If} "$0" != "" + ClearErrors + WriteRegStr HKCU "Software\Mozilla\Firefox" "OldDefaultBrowserCommand" "$0" + ${EndIf} + + ${LogHeader} "Setting as the default browser" + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} + Call SetAsDefaultAppUserHKCU + ${Else} + GetFunctionAddress $0 SetAsDefaultAppUserHKCU + UAC::ExecCodeSegment $0 + ${EndIf} + ${ElseIfNot} ${Errors} + ${LogHeader} "Writing default-browser opt-out" + ClearErrors + WriteRegStr HKCU "Software\Mozilla\Firefox" "DefaultBrowserOptOut" "True" + ${If} ${Errors} + ${LogMsg} "Error writing default-browser opt-out" + ${EndIf} + ${EndIf} + ${EndUnless} + + ; Adds a pinned Task Bar shortcut (see MigrateTaskBarShortcut for details). + ${MigrateTaskBarShortcut} + + ; Add the Firewall entries during install + Call AddFirewallEntries + + ; Refresh desktop icons + System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_DWORDFLUSH}, i 0, i 0)" + + ${InstallEndCleanupCommon} + + ${If} $PreventRebootRequired == "true" + SetRebootFlag false + ${EndIf} + + ${If} ${RebootFlag} + ; Admin is required to delete files on reboot so only add the moz-delete if + ; the user is an admin. After calling UAC::IsAdmin $0 will equal 1 if the + ; user is an admin. + UAC::IsAdmin + ${If} "$0" == "1" + ; When a reboot is required give SHChangeNotify time to finish the + ; refreshing the icons so the OS doesn't display the icons from helper.exe + Sleep 10000 + ${LogHeader} "Reboot Required To Finish Installation" + ; ${FileMainEXE}.moz-upgrade should never exist but just in case... + ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade" + Rename "$INSTDIR\${FileMainEXE}" "$INSTDIR\${FileMainEXE}.moz-upgrade" + ${EndUnless} + + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + ClearErrors + Rename "$INSTDIR\${FileMainEXE}" "$INSTDIR\${FileMainEXE}.moz-delete" + ${Unless} ${Errors} + Delete /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-delete" + ${EndUnless} + ${EndIf} + + ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}" + CopyFiles /SILENT "$INSTDIR\uninstall\helper.exe" "$INSTDIR" + FileOpen $0 "$INSTDIR\${FileMainEXE}" w + FileWrite $0 "Will be deleted on restart" + Rename /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}" + FileClose $0 + Delete "$INSTDIR\${FileMainEXE}" + Rename "$INSTDIR\helper.exe" "$INSTDIR\${FileMainEXE}" + ${EndUnless} + ${EndIf} + ${EndIf} +SectionEnd + +################################################################################ +# Install Abort Survey Functions + +Function CustomAbort + ${If} "${AB_CD}" == "en-US" + ${AndIf} "$PageName" != "" + ${AndIf} ${FileExists} "$EXEDIR\core\distribution\distribution.ini" + ReadINIStr $0 "$EXEDIR\core\distribution\distribution.ini" "Global" "about" + ClearErrors + ${WordFind} "$0" "Funnelcake" "E#" $1 + ${Unless} ${Errors} + ; Yes = fill out the survey and exit, No = don't fill out survey and exit, + ; Cancel = don't exit. + MessageBox MB_YESNO|MB_ICONEXCLAMATION \ + "Would you like to tell us why you are canceling this installation?" \ + IDYes +1 IDNO CustomAbort_finish + ${If} "$PageName" == "Welcome" + GetFunctionAddress $0 AbortSurveyWelcome + ${ElseIf} "$PageName" == "Options" + GetFunctionAddress $0 AbortSurveyOptions + ${ElseIf} "$PageName" == "Directory" + GetFunctionAddress $0 AbortSurveyDirectory + ${ElseIf} "$PageName" == "Shortcuts" + GetFunctionAddress $0 AbortSurveyShortcuts + ${ElseIf} "$PageName" == "Summary" + GetFunctionAddress $0 AbortSurveySummary + ${EndIf} + ClearErrors + ${GetParameters} $1 + ${GetOptions} "$1" "/UAC:" $2 + ${If} ${Errors} + Call $0 + ${Else} + UAC::ExecCodeSegment $0 + ${EndIf} + + CustomAbort_finish: + Return + ${EndUnless} + ${EndIf} + + MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(MOZ_MUI_TEXT_ABORTWARNING)" \ + IDYES +1 IDNO +2 + Return + Abort +FunctionEnd + +Function AbortSurveyWelcome + ExecShell "open" "${AbortSurveyURL}step1" +FunctionEnd + +Function AbortSurveyOptions + ExecShell "open" "${AbortSurveyURL}step2" +FunctionEnd + +Function AbortSurveyDirectory + ExecShell "open" "${AbortSurveyURL}step3" +FunctionEnd + +Function AbortSurveyShortcuts + ExecShell "open" "${AbortSurveyURL}step4" +FunctionEnd + +Function AbortSurveySummary + ExecShell "open" "${AbortSurveyURL}step5" +FunctionEnd + +################################################################################ +# Helper Functions + +Function AddQuickLaunchShortcut + CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ + "$INSTDIR" + ${EndIf} +FunctionEnd + +Function CheckExistingInstall + ; If there is a pending file copy from a previous upgrade don't allow + ; installing until after the system has rebooted. + IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4 + MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 + Reboot + Quit + + ; If there is a pending file deletion from a previous uninstall don't allow + ; installing until after the system has rebooted. + IfFileExists "$INSTDIR\${FileMainEXE}.moz-delete" +1 +4 + MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UNINSTALL)" IDNO +2 + Reboot + Quit + + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + ; Disable the next, cancel, and back buttons + GetDlgItem $0 $HWNDPARENT 1 ; Next button + EnableWindow $0 0 + GetDlgItem $0 $HWNDPARENT 2 ; Cancel button + EnableWindow $0 0 + GetDlgItem $0 $HWNDPARENT 3 ; Back button + EnableWindow $0 0 + + Banner::show /NOUNLOAD "$(BANNER_CHECK_EXISTING)" + + ${If} "$TmpVal" == "FoundMessageWindow" + Sleep 5000 + ${EndIf} + + ${PushFilesToCheck} + + ; Store the return value in $TmpVal so it is less likely to be accidentally + ; overwritten elsewhere. + ${CheckForFilesInUse} $TmpVal + + Banner::destroy + + ; Enable the next, cancel, and back buttons + GetDlgItem $0 $HWNDPARENT 1 ; Next button + EnableWindow $0 1 + GetDlgItem $0 $HWNDPARENT 2 ; Cancel button + EnableWindow $0 1 + GetDlgItem $0 $HWNDPARENT 3 ; Back button + EnableWindow $0 1 + + ${If} "$TmpVal" == "true" + StrCpy $TmpVal "FoundMessageWindow" + ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_INSTALL)" + StrCpy $TmpVal "true" + ${EndIf} + ${EndIf} +FunctionEnd + +Function LaunchApp +!ifndef DEV_EDITION + ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)" +!endif + + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $1 + ${If} ${Errors} + Exec "$\"$INSTDIR\${FileMainEXE}$\"" + ${Else} + GetFunctionAddress $0 LaunchAppFromElevatedProcess + UAC::ExecCodeSegment $0 + ${EndIf} +FunctionEnd + +Function LaunchAppFromElevatedProcess + ; Find the installation directory when launching using GetFunctionAddress + ; from an elevated installer since $INSTDIR will not be set in this installer + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" + ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $1 + ; Set our current working directory to the application's install directory + ; otherwise the 7-Zip temp directory will be in use and won't be deleted. + SetOutPath "$1" + Exec "$\"$0$\"" +FunctionEnd + +################################################################################ +# Language + +!insertmacro MOZ_MUI_LANGUAGE 'baseLocale' +!verbose push +!verbose 3 +!include "overrideLocale.nsh" +!include "customLocale.nsh" +!verbose pop + +; Set this after the locale files to override it if it is in the locale +; using " " for BrandingText will hide the "Nullsoft Install System..." branding +BrandingText " " + +################################################################################ +# Page pre, show, and leave functions + +Function preWelcome + StrCpy $PageName "Welcome" + ${If} ${FileExists} "$EXEDIR\core\distribution\modern-wizard.bmp" + Delete "$PLUGINSDIR\modern-wizard.bmp" + CopyFiles /SILENT "$EXEDIR\core\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp" + ${EndIf} +FunctionEnd + +Function preOptions + StrCpy $PageName "Options" + ${If} ${FileExists} "$EXEDIR\core\distribution\modern-header.bmp" + ${AndIf} $hHeaderBitmap == "" + Delete "$PLUGINSDIR\modern-header.bmp" + CopyFiles /SILENT "$EXEDIR\core\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp" + ${ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp" + ${EndIf} + !insertmacro MUI_HEADER_TEXT "$(OPTIONS_PAGE_TITLE)" "$(OPTIONS_PAGE_SUBTITLE)" + !insertmacro MUI_INSTALLOPTIONS_DISPLAY "options.ini" +FunctionEnd + +Function leaveOptions + ${MUI_INSTALLOPTIONS_READ} $0 "options.ini" "Settings" "State" + ${If} $0 != 0 + Abort + ${EndIf} + ${MUI_INSTALLOPTIONS_READ} $R0 "options.ini" "Field 2" "State" + StrCmp $R0 "1" +1 +2 + StrCpy $InstallType ${INSTALLTYPE_BASIC} + ${MUI_INSTALLOPTIONS_READ} $R0 "options.ini" "Field 3" "State" + StrCmp $R0 "1" +1 +2 + StrCpy $InstallType ${INSTALLTYPE_CUSTOM} + + ${LeaveOptionsCommon} + + ${If} $InstallType == ${INSTALLTYPE_BASIC} + Call CheckExistingInstall + ${EndIf} +FunctionEnd + +Function preDirectory + StrCpy $PageName "Directory" + ${PreDirectoryCommon} +FunctionEnd + +Function leaveDirectory + ${If} $InstallType == ${INSTALLTYPE_BASIC} + Call CheckExistingInstall + ${EndIf} + ${LeaveDirectoryCommon} "$(WARN_DISK_SPACE)" "$(WARN_WRITE_ACCESS)" +FunctionEnd + +Function preShortcuts + StrCpy $PageName "Shortcuts" + ${CheckCustomCommon} + !insertmacro MUI_HEADER_TEXT "$(SHORTCUTS_PAGE_TITLE)" "$(SHORTCUTS_PAGE_SUBTITLE)" + !insertmacro MUI_INSTALLOPTIONS_DISPLAY "shortcuts.ini" +FunctionEnd + +Function leaveShortcuts + ${MUI_INSTALLOPTIONS_READ} $0 "shortcuts.ini" "Settings" "State" + ${If} $0 != 0 + Abort + ${EndIf} + ${MUI_INSTALLOPTIONS_READ} $AddDesktopSC "shortcuts.ini" "Field 2" "State" + ${MUI_INSTALLOPTIONS_READ} $AddStartMenuSC "shortcuts.ini" "Field 3" "State" + + ; Don't install the quick launch shortcut on Windows 7 + ${Unless} ${AtLeastWin7} + ${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State" + ${EndUnless} + + ${If} $InstallType == ${INSTALLTYPE_CUSTOM} + Call CheckExistingInstall + ${EndIf} +FunctionEnd + +!ifdef MOZ_MAINTENANCE_SERVICE +Function preComponents + ; If the service already exists, don't show this page + ServicesHelper::IsInstalled "MozillaMaintenance" + Pop $R9 + ${If} $R9 == 1 + ; The service already exists so don't show this page. + Abort + ${EndIf} + + ; On Windows < XP SP3 we do not install the maintenance service. + ${If} ${IsWinXP} + ${AndIf} ${AtMostServicePack} 2 + Abort + ${EndIf} + + ; Don't show the custom components page if the + ; user is not an admin + Call IsUserAdmin + Pop $R9 + ${If} $R9 != "true" + Abort + ${EndIf} + + ; Only show the maintenance service page if we have write access to HKLM + ClearErrors + WriteRegStr HKLM "Software\Mozilla" \ + "${BrandShortName}InstallerTest" "Write Test" + ${If} ${Errors} + ClearErrors + Abort + ${Else} + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + ${EndIf} + + StrCpy $PageName "Components" + ${CheckCustomCommon} + !insertmacro MUI_HEADER_TEXT "$(COMPONENTS_PAGE_TITLE)" "$(COMPONENTS_PAGE_SUBTITLE)" + !insertmacro MUI_INSTALLOPTIONS_DISPLAY "components.ini" +FunctionEnd + +Function leaveComponents + ${MUI_INSTALLOPTIONS_READ} $0 "components.ini" "Settings" "State" + ${If} $0 != 0 + Abort + ${EndIf} + ${MUI_INSTALLOPTIONS_READ} $InstallMaintenanceService "components.ini" "Field 2" "State" + ${If} $InstallType == ${INSTALLTYPE_CUSTOM} + Call CheckExistingInstall + ${EndIf} +FunctionEnd +!endif + +Function preSummary + StrCpy $PageName "Summary" + ; Setup the summary.ini file for the Custom Summary Page + WriteINIStr "$PLUGINSDIR\summary.ini" "Settings" NumFields "3" + + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Type "label" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Text "$(SUMMARY_INSTALLED_TO)" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Left "0" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Right "-1" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Top "5" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Bottom "15" + + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Type "text" + ; The contents of this control must be set as follows in the pre function + ; ${MUI_INSTALLOPTIONS_READ} $1 "summary.ini" "Field 2" "HWND" + ; SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" state "" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Left "0" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Right "-1" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Top "17" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Bottom "30" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" flags "READONLY" + + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Type "label" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Left "0" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Right "-1" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Top "130" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Bottom "150" + + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Text "$(SUMMARY_UPGRADE_CLICK)" + WriteINIStr "$PLUGINSDIR\summary.ini" "Settings" NextButtonText "$(UPGRADE_BUTTON)" + ${Else} + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Text "$(SUMMARY_INSTALL_CLICK)" + DeleteINIStr "$PLUGINSDIR\summary.ini" "Settings" NextButtonText + ${EndIf} + + + ; Remove the "Field 4" ini section in case the user hits back and changes the + ; installation directory which could change whether the make default checkbox + ; should be displayed. + DeleteINISec "$PLUGINSDIR\summary.ini" "Field 4" + + ; Check if it is possible to write to HKLM + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" + ${Unless} ${Errors} + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + ; Check if Firefox is the http handler for this user. + SetShellVarContext current ; Set SHCTX to the current user + ${IsHandlerForInstallDir} "http" $R9 + ${If} $TmpVal == "HKLM" + SetShellVarContext all ; Set SHCTX to all users + ${EndIf} + ; If Firefox isn't the http handler for this user show the option to set + ; Firefox as the default browser. + ${If} "$R9" != "true" + ${AndIf} ${AtMostWin2008R2} + WriteINIStr "$PLUGINSDIR\summary.ini" "Settings" NumFields "4" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Type "checkbox" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Text "$(SUMMARY_TAKE_DEFAULTS)" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Left "0" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Right "-1" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" State "1" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Top "32" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Bottom "53" + ${EndIf} + ${EndUnless} + + ${If} "$TmpVal" == "true" + ; If there is already a Type entry in the "Field 4" section with a value of + ; checkbox then the set as the default browser checkbox is displayed and + ; this text must be moved below it. + ReadINIStr $0 "$PLUGINSDIR\summary.ini" "Field 4" "Type" + ${If} "$0" == "checkbox" + StrCpy $0 "5" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Top "53" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Bottom "68" + ${Else} + StrCpy $0 "4" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Top "35" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Bottom "50" + ${EndIf} + WriteINIStr "$PLUGINSDIR\summary.ini" "Settings" NumFields "$0" + + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Type "label" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Text "$(SUMMARY_REBOOT_REQUIRED_INSTALL)" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Left "0" + WriteINIStr "$PLUGINSDIR\summary.ini" "Field $0" Right "-1" + ${EndIf} + + !insertmacro MUI_HEADER_TEXT "$(SUMMARY_PAGE_TITLE)" "$(SUMMARY_PAGE_SUBTITLE)" + + ; The Summary custom page has a textbox that will automatically receive + ; focus. This sets the focus to the Install button instead. + !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "summary.ini" + GetDlgItem $0 $HWNDPARENT 1 + System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i" + ${MUI_INSTALLOPTIONS_READ} $1 "summary.ini" "Field 2" "HWND" + SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR" + !insertmacro MUI_INSTALLOPTIONS_SHOW +FunctionEnd + +Function leaveSummary + ; Try to delete the app executable and if we can't delete it try to find the + ; app's message window and prompt the user to close the app. This allows + ; running an instance that is located in another directory. If for whatever + ; reason there is no message window we will just rename the app's files and + ; then remove them on restart. + ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_INSTALL)" + ${EndIf} +FunctionEnd + +; When we add an optional action to the finish page the cancel button is +; enabled. This disables it and leaves the finish button as the only choice. +Function preFinish + StrCpy $PageName "" + ${EndInstallLog} "${BrandFullName}" + !insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "cancelenabled" "0" +FunctionEnd + +################################################################################ +# Initialization Functions + +Function .onInit + ; Remove the current exe directory from the search order. + ; This only effects LoadLibrary calls and not implicitly loaded DLLs. + System::Call 'kernel32::SetDllDirectoryW(w "")' + + StrCpy $PageName "" + StrCpy $LANGUAGE 0 + ${SetBrandNameVars} "$EXEDIR\core\distribution\setup.ini" + + ; Don't install on systems that don't support SSE2. The parameter value of + ; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the + ; SSE2 instruction set is available. + System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7" + +!ifdef HAVE_64BIT_BUILD + ; Restrict x64 builds from being installed on x86 and pre Win7 + ${Unless} ${RunningX64} + ${OrUnless} ${AtLeastWin7} + ${If} "$R7" == "0" + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" + ${Else} + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)" + ${EndIf} + MessageBox MB_OKCANCEL|MB_ICONSTOP "$R7" IDCANCEL +2 + ExecShell "open" "${URLSystemRequirements}" + Quit + ${EndUnless} + + SetRegView 64 +!else + StrCpy $R8 "0" + ${If} ${AtMostWin2000} + StrCpy $R8 "1" + ${EndIf} + + ${If} ${IsWinXP} + ${AndIf} ${AtMostServicePack} 1 + StrCpy $R8 "1" + ${EndIf} + + ${If} $R8 == "1" + ; XXX-rstrong - some systems failed the AtLeastWin2000 test that we + ; used to use for an unknown reason and likely fail the AtMostWin2000 + ; and possibly the IsWinXP test as well. To work around this also + ; check if the Windows NT registry Key exists and if it does if the + ; first char in CurrentVersion is equal to 3 (Windows NT 3.5 and + ; 3.5.1), 4 (Windows NT 4), or 5 (Windows 2000 and Windows XP). + StrCpy $R8 "" + ClearErrors + ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion" + StrCpy $R8 "$R8" 1 + ${If} ${Errors} + ${OrIf} "$R8" == "3" + ${OrIf} "$R8" == "4" + ${OrIf} "$R8" == "5" + ${If} "$R7" == "0" + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" + ${Else} + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)" + ${EndIf} + MessageBox MB_OKCANCEL|MB_ICONSTOP "$R7" IDCANCEL +2 + ExecShell "open" "${URLSystemRequirements}" + Quit + ${EndIf} + ${EndUnless} +!endif + + ${If} "$R7" == "0" + MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_CPU_MSG)" IDCANCEL +2 + ExecShell "open" "${URLSystemRequirements}" + Quit + ${EndIf} + + ${InstallOnInitCommon} "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" + +; The commands inside this ifndef are needed prior to NSIS 3.0a2 and can be +; removed after we require NSIS 3.0a2 or greater. +!ifndef NSIS_PACKEDVERSION + ${If} ${AtLeastWinVista} + System::Call 'user32::SetProcessDPIAware()' + ${EndIf} +!endif + + !insertmacro InitInstallOptionsFile "options.ini" + !insertmacro InitInstallOptionsFile "shortcuts.ini" + !insertmacro InitInstallOptionsFile "components.ini" + !insertmacro InitInstallOptionsFile "summary.ini" + + WriteINIStr "$PLUGINSDIR\options.ini" "Settings" NumFields "5" + + WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Type "label" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Text "$(OPTIONS_SUMMARY)" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Left "0" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Right "-1" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Top "0" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Bottom "10" + + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Type "RadioButton" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Text "$(OPTION_STANDARD_RADIO)" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Left "0" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Right "-1" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Top "25" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Bottom "35" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" State "1" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 2" Flags "GROUP" + + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" Type "RadioButton" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" Text "$(OPTION_CUSTOM_RADIO)" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" Left "0" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" Right "-1" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" Top "55" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" Bottom "65" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 3" State "0" + + WriteINIStr "$PLUGINSDIR\options.ini" "Field 4" Type "label" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 4" Text "$(OPTION_STANDARD_DESC)" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 4" Left "15" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 4" Right "-1" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 4" Top "37" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 4" Bottom "57" + + WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Type "label" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Text "$(OPTION_CUSTOM_DESC)" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Left "15" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Right "-1" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Top "67" + WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Bottom "87" + + ; Setup the shortcuts.ini file for the Custom Shortcuts Page + ; Don't offer to install the quick launch shortcut on Windows 7 + ${If} ${AtLeastWin7} + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Settings" NumFields "3" + ${Else} + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Settings" NumFields "4" + ${EndIf} + + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Type "label" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Text "$(CREATE_ICONS_DESC)" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Left "0" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Right "-1" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Top "5" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Bottom "15" + + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Type "checkbox" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Text "$(ICONS_DESKTOP)" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Left "0" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Right "-1" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Top "20" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Bottom "30" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" State "1" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 2" Flags "GROUP" + + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Type "checkbox" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Text "$(ICONS_STARTMENU)" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Left "0" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Right "-1" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Top "40" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Bottom "50" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" State "1" + + ; Don't offer to install the quick launch shortcut on Windows 7 + ${Unless} ${AtLeastWin7} + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Type "checkbox" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Text "$(ICONS_QUICKLAUNCH)" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Left "0" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Right "-1" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Top "60" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Bottom "70" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" State "1" + ${EndUnless} + + ; Setup the components.ini file for the Components Page + WriteINIStr "$PLUGINSDIR\components.ini" "Settings" NumFields "2" + + WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Type "label" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Text "$(OPTIONAL_COMPONENTS_DESC)" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Left "0" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Right "-1" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Top "5" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 1" Bottom "25" + + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Type "checkbox" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Text "$(MAINTENANCE_SERVICE_CHECKBOX_DESC)" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Left "0" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Right "-1" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Top "27" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Bottom "37" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" State "1" + WriteINIStr "$PLUGINSDIR\components.ini" "Field 2" Flags "GROUP" + + ; There must always be a core directory. + ${GetSize} "$EXEDIR\core\" "/S=0K" $R5 $R7 $R8 + SectionSetSize ${APP_IDX} $R5 + + ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if + ; the user clicks the back button + StrCpy $hHeaderBitmap "" +FunctionEnd + +Function .onGUIEnd + ${OnEndCommon} +FunctionEnd diff --git a/browser/installer/windows/nsis/maintenanceservice_installer.nsi b/browser/installer/windows/nsis/maintenanceservice_installer.nsi new file mode 100644 index 000000000..ef30c1360 --- /dev/null +++ b/browser/installer/windows/nsis/maintenanceservice_installer.nsi @@ -0,0 +1,335 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs +!verbose 3 + +; 7-Zip provides better compression than the lzma from NSIS so we add the files +; uncompressed and use 7-Zip to create a SFX archive of it +SetDatablockOptimize on +SetCompress off +CRCCheck on + +RequestExecutionLevel admin + +; The commands inside this ifdef require NSIS 3.0a2 or greater so the ifdef can +; be removed after we require NSIS 3.0a2 or greater. +!ifdef NSIS_PACKEDVERSION + Unicode true + ManifestSupportedOS all + ManifestDPIAware true +!endif + +!addplugindir ./ + +; Variables +Var TempMaintServiceName +Var BrandFullNameDA +Var BrandFullName + +; Other included files may depend upon these includes! +; The following includes are provided by NSIS. +!include FileFunc.nsh +!include LogicLib.nsh +!include MUI.nsh +!include WinMessages.nsh +!include WinVer.nsh +!include WordFunc.nsh + +!insertmacro GetOptions +!insertmacro GetParameters +!insertmacro GetSize + +; The test slaves use this fallback key to run tests. +; And anyone that wants to run tests themselves should already have +; this installed. +!define FallbackKey \ + "SOFTWARE\Mozilla\MaintenanceService\3932ecacee736d366d6436db0f55bce4" + +!define CompanyName "Mozilla Corporation" +!define BrandFullNameInternal "" + +; The following includes are custom. +!include defines.nsi +; We keep defines.nsi defined so that we get other things like +; the version number, but we redefine BrandFullName +!define MaintFullName "Mozilla Maintenance Service" +!undef BrandFullName +!define BrandFullName "${MaintFullName}" + +!include common.nsh +!include locales.nsi + +VIAddVersionKey "FileDescription" "${MaintFullName} Installer" +VIAddVersionKey "OriginalFilename" "maintenanceservice_installer.exe" + +Name "${MaintFullName}" +OutFile "maintenanceservice_installer.exe" + +; Get installation folder from registry if available +InstallDirRegKey HKLM "Software\Mozilla\MaintenanceService" "" + +SetOverwrite on + +; serviceinstall.cpp also uses this key, in case the path is changed, update +; there too. +!define MaintUninstallKey \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenanceService" + +; Always install into the 32-bit location even if we have a 64-bit build. +; This is because we use only 1 service for all Firefox channels. +; Allow either x86 and x64 builds to exist at this location, depending on +; what is the latest build. +InstallDir "$PROGRAMFILES32\${MaintFullName}\" +ShowUnInstDetails nevershow + +################################################################################ +# Modern User Interface - MUI + +!define MUI_ICON setup.ico +!define MUI_UNICON setup.ico +!define MUI_WELCOMEPAGE_TITLE_3LINES +!define MUI_UNWELCOMEFINISHPAGE_BITMAP wizWatermark.bmp + +;Interface Settings +!define MUI_ABORTWARNING + +; Uninstaller Pages +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +################################################################################ +# Language + +!insertmacro MOZ_MUI_LANGUAGE 'baseLocale' +!verbose push +!verbose 3 +!include "overrideLocale.nsh" +!include "customLocale.nsh" +!verbose pop + +; Set this after the locale files to override it if it is in the locale +; using " " for BrandingText will hide the "Nullsoft Install System..." branding +BrandingText " " + +Function .onInit + ; Remove the current exe directory from the search order. + ; This only effects LoadLibrary calls and not implicitly loaded DLLs. + System::Call 'kernel32::SetDllDirectoryW(w "")' + + SetSilent silent + + ; On Windows 2000 we do not install the maintenance service. + ; We won't run this installer from the parent installer, but just in case + ; someone tries to execute it on Windows 2000... + ${Unless} ${AtLeastWinXP} + Abort + ${EndUnless} +FunctionEnd + +Function un.onInit + ; Remove the current exe directory from the search order. + ; This only effects LoadLibrary calls and not implicitly loaded DLLs. + System::Call 'kernel32::SetDllDirectoryW(w "")' + +; The commands inside this ifndef are needed prior to NSIS 3.0a2 and can be +; removed after we require NSIS 3.0a2 or greater. +!ifndef NSIS_PACKEDVERSION + ${If} ${AtLeastWinVista} + System::Call 'user32::SetProcessDPIAware()' + ${EndIf} +!endif + + StrCpy $BrandFullNameDA "${MaintFullName}" + StrCpy $BrandFullName "${MaintFullName}" +FunctionEnd + +Section "MaintenanceService" + AllowSkipFiles off + + CreateDirectory $INSTDIR + SetOutPath $INSTDIR + + ; If the service already exists, then it will be stopped when upgrading it + ; via the maintenanceservice_tmp.exe command executed below. + ; The maintenanceservice_tmp.exe command will rename the file to + ; maintenanceservice.exe if maintenanceservice_tmp.exe is newer. + ; If the service does not exist yet, we install it and drop the file on + ; disk as maintenanceservice.exe directly. + StrCpy $TempMaintServiceName "maintenanceservice.exe" + IfFileExists "$INSTDIR\maintenanceservice.exe" 0 skipAlreadyExists + StrCpy $TempMaintServiceName "maintenanceservice_tmp.exe" + skipAlreadyExists: + + ; We always write out a copy and then decide whether to install it or + ; not via calling its 'install' cmdline which works by version comparison. + CopyFiles "$EXEDIR\maintenanceservice.exe" "$INSTDIR\$TempMaintServiceName" + + ; The updater.ini file is only used when performing an install or upgrade, + ; and only if that install or upgrade is successful. If an old updater.ini + ; happened to be copied into the maintenance service installation directory + ; but the service was not newer, the updater.ini file would be unused. + ; It is used to fill the description of the service on success. + CopyFiles "$EXEDIR\updater.ini" "$INSTDIR\updater.ini" + + ; Install the application maintenance service. + ; If a service already exists, the command line parameter will stop the + ; service and only install itself if it is newer than the already installed + ; service. If successful it will remove the old maintenanceservice.exe + ; and replace it with maintenanceservice_tmp.exe. + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/Upgrade" $0 + ${If} ${Errors} + ExecWait '"$INSTDIR\$TempMaintServiceName" install' + ${Else} + ; The upgrade cmdline is the same as install except + ; It will fail if the service isn't already installed. + ExecWait '"$INSTDIR\$TempMaintServiceName" upgrade' + ${EndIf} + + WriteUninstaller "$INSTDIR\Uninstall.exe" + WriteRegStr HKLM "${MaintUninstallKey}" "DisplayName" "${MaintFullName}" + WriteRegStr HKLM "${MaintUninstallKey}" "UninstallString" \ + '"$INSTDIR\uninstall.exe"' + WriteRegStr HKLM "${MaintUninstallKey}" "DisplayIcon" \ + "$INSTDIR\Uninstall.exe,0" + WriteRegStr HKLM "${MaintUninstallKey}" "DisplayVersion" "${AppVersion}" + WriteRegStr HKLM "${MaintUninstallKey}" "Publisher" "Mozilla" + WriteRegStr HKLM "${MaintUninstallKey}" "Comments" "${BrandFullName}" + WriteRegDWORD HKLM "${MaintUninstallKey}" "NoModify" 1 + ${GetSize} "$INSTDIR" "/S=0K" $R2 $R3 $R4 + WriteRegDWORD HKLM "${MaintUninstallKey}" "EstimatedSize" $R2 + + ; Write out that a maintenance service was attempted. + ; We do this because on upgrades we will check this value and we only + ; want to install once on the first upgrade to maintenance service. + ; Also write out that we are currently installed, preferences will check + ; this value to determine if we should show the service update pref. + ; Since the Maintenance service can be installed either x86 or x64, + ; always use the 64-bit registry for checking if an attempt was made. + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} + WriteRegDWORD HKLM "Software\Mozilla\MaintenanceService" "Attempted" 1 + WriteRegDWORD HKLM "Software\Mozilla\MaintenanceService" "Installed" 1 + DeleteRegValue HKLM "Software\Mozilla\MaintenanceService" "FFPrefetchDisabled" + + ; Included here for debug purposes only. + ; These keys are used to bypass the installation dir is a valid installation + ; check from the service so that tests can be run. + ; WriteRegStr HKLM "${FallbackKey}\0" "name" "Mozilla Corporation" + ; WriteRegStr HKLM "${FallbackKey}\0" "issuer" "DigiCert SHA2 Assured ID Code Signing CA" + ${If} ${RunningX64} + SetRegView lastused + ${EndIf} +SectionEnd + +; By renaming before deleting we improve things slightly in case +; there is a file in use error. In this case a new install can happen. +Function un.RenameDelete + Pop $9 + ; If the .moz-delete file already exists previously, delete it + ; If it doesn't exist, the call is ignored. + ; We don't need to pass /REBOOTOK here since it was already marked that way + ; if it exists. + Delete "$9.moz-delete" + Rename "$9" "$9.moz-delete" + ${If} ${Errors} + Delete /REBOOTOK "$9" + ${Else} + Delete /REBOOTOK "$9.moz-delete" + ${EndIf} + ClearErrors +FunctionEnd + +Section "Uninstall" + ; Delete the service so that no updates will be attempted + ExecWait '"$INSTDIR\maintenanceservice.exe" uninstall' + + Push "$INSTDIR\updater.ini" + Call un.RenameDelete + Push "$INSTDIR\maintenanceservice.exe" + Call un.RenameDelete + Push "$INSTDIR\maintenanceservice_tmp.exe" + Call un.RenameDelete + Push "$INSTDIR\maintenanceservice.old" + Call un.RenameDelete + Push "$INSTDIR\Uninstall.exe" + Call un.RenameDelete + Push "$INSTDIR\update\updater.ini" + Call un.RenameDelete + Push "$INSTDIR\update\updater.exe" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-1.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-2.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-3.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-4.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-5.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-6.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-7.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-8.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-9.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-10.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-install.log" + Call un.RenameDelete + Push "$INSTDIR\logs\maintenanceservice-uninstall.log" + Call un.RenameDelete + SetShellVarContext all + Push "$APPDATA\Mozilla\logs\maintenanceservice.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-1.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-2.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-3.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-4.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-5.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-6.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-7.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-8.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-9.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-10.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-install.log" + Call un.RenameDelete + Push "$APPDATA\Mozilla\logs\maintenanceservice-uninstall.log" + Call un.RenameDelete + RMDir /REBOOTOK "$APPDATA\Mozilla\logs" + RMDir /REBOOTOK "$APPDATA\Mozilla" + RMDir /REBOOTOK "$INSTDIR\logs" + RMDir /REBOOTOK "$INSTDIR\update" + RMDir /REBOOTOK "$INSTDIR" + + DeleteRegKey HKLM "${MaintUninstallKey}" + + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} + DeleteRegValue HKLM "Software\Mozilla\MaintenanceService" "Installed" + DeleteRegValue HKLM "Software\Mozilla\MaintenanceService" "FFPrefetchDisabled" + DeleteRegKey HKLM "${FallbackKey}\" + ${If} ${RunningX64} + SetRegView lastused + ${EndIf} +SectionEnd diff --git a/browser/installer/windows/nsis/oneoff_en-US.nsh b/browser/installer/windows/nsis/oneoff_en-US.nsh new file mode 100644 index 000000000..62d95ade9 --- /dev/null +++ b/browser/installer/windows/nsis/oneoff_en-US.nsh @@ -0,0 +1,12 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +; Custom strings for en-US. This is not in the locale directory so these strings +; aren't translated. +!define INDENT " " +!define INTRO_BLURB "Thanks for choosing $BrandFullName. We’re not just designed to be different, we’re different by design." +!define INSTALL_BLURB1 "You're about to enjoy the very latest in speed, flexibility and security so you're always in control." +!define INSTALL_BLURB2 "And you're joining a global community of users, contributors and developers working to make the best browser in the world." +!define INSTALL_BLURB3 "You even get a haiku:$\n${INDENT}Proudly non-profit$\n${INDENT}Free to innovate for you$\n${INDENT}And a better Web" +!undef INDENT diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh new file mode 100755 index 000000000..8d7eea618 --- /dev/null +++ b/browser/installer/windows/nsis/shared.nsh @@ -0,0 +1,1410 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +!macro PostUpdate + ; PostUpdate is called from both session 0 and from the user session + ; for service updates, make sure that we only register with the user session + ; Otherwise ApplicationID::Set can fail intermittently with a file in use error. + System::Call "kernel32::GetCurrentProcessId() i.r0" + System::Call "kernel32::ProcessIdToSessionId(i $0, *i ${NSIS_MAX_STRLEN} r9)" + + ; Determine if we're the protected UserChoice default or not. If so fix the + ; start menu tile. In case there are 2 Firefox installations, we only do + ; this if the application being updated is the default. + ReadRegStr $0 HKCU "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" "ProgId" + ${If} $0 == "FirefoxURL" + ${AndIf} $9 != 0 ; We're not running in session 0 + ReadRegStr $0 HKCU "Software\Classes\FirefoxURL\shell\open\command" "" + ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $0 + ${If} ${FileExists} "$0" + ${GetLongPath} "$0" $0 + ${EndIf} + ${EndIf} + + ${CreateShortcutsLog} + + ; Remove registry entries for non-existent apps and for apps that point to our + ; install location in the Software\Mozilla key and uninstall registry entries + ; that point to our install location for both HKCU and HKLM. + SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU) + ${RegCleanMain} "Software\Mozilla" + ${RegCleanUninstall} + ${UpdateProtocolHandlers} + + ; setup the application model id registration value + ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" + + ; Win7 taskbar and start menu link maintenance + Call FixShortcutAppModelIDs + + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" + ${If} ${Errors} + StrCpy $TmpVal "HKCU" ; used primarily for logging + ${Else} + SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM) + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + StrCpy $TmpVal "HKLM" ; used primarily for logging + ${RegCleanMain} "Software\Mozilla" + ${RegCleanUninstall} + ${UpdateProtocolHandlers} + ${FixShellIconHandler} "HKLM" + ${SetAppLSPCategories} ${LSP_CATEGORIES} + + ; Win7 taskbar and start menu link maintenance + Call FixShortcutAppModelIDs + + ; Add the Firewall entries after an update + Call AddFirewallEntries + + ; Only update the Clients\StartMenuInternet registry key values in HKLM if + ; they don't exist or this installation is the same as the one set in those + ; keys. + ${StrFilter} "${FileMainEXE}" "+" "" "" $1 + ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$1\DefaultIcon" "" + ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $0 + ${If} ${FileExists} "$0" + ${GetLongPath} "$0" $0 + ${EndIf} + ${If} "$0" == "$INSTDIR" + ${SetStartMenuInternet} "HKLM" + ${EndIf} + + ; Only update the Clients\StartMenuInternet registry key values in HKCU if + ; they don't exist or this installation is the same as the one set in those + ; keys. This is only done in Windows 8 to avoid a UAC prompt. + ${If} ${AtLeastWin8} + ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$1\DefaultIcon" "" + ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $0 + ${If} ${FileExists} "$0" + ${GetLongPath} "$0" $0 + ${EndIf} + ${If} "$0" == "$INSTDIR" + ${SetStartMenuInternet} "HKCU" + ${EndIf} + ${EndIf} + + ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" + ${If} "$0" != "${GREVersion}" + WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}" + ${EndIf} + ${EndIf} + + ; Migrate the application's Start Menu directory to a single shortcut in the + ; root of the Start Menu Programs directory. + ${MigrateStartMenuShortcut} + + ; Update lastwritetime of the Start Menu shortcut to clear the tile cache. + ${If} ${AtLeastWin8} + ${AndIf} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + FileOpen $0 "$SMPROGRAMS\${BrandFullName}.lnk" a + FileClose $0 + ${EndIf} + + ; Adds a pinned Task Bar shortcut (see MigrateTaskBarShortcut for details). + ${MigrateTaskBarShortcut} + + ${RemoveDeprecatedKeys} + + ${SetAppKeys} + ${FixClassKeys} + ${SetUninstallKeys} + + ; Remove files that may be left behind by the application in the + ; VirtualStore directory. + ${CleanVirtualStore} + + ${RemoveDeprecatedFiles} + + ; Fix the distribution.ini file if applicable + ${FixDistributionsINI} + + RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}" + +!ifdef MOZ_MAINTENANCE_SERVICE + Call IsUserAdmin + Pop $R0 + ${If} $R0 == "true" + ; Only proceed if we have HKLM write access + ${AndIf} $TmpVal == "HKLM" + ; On Windows 2000 we do not install the maintenance service. + ${AndIf} ${AtLeastWinXP} + ; We check to see if the maintenance service install was already attempted. + ; Since the Maintenance service can be installed either x86 or x64, + ; always use the 64-bit registry for checking if an attempt was made. + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} + ReadRegDWORD $5 HKLM "Software\Mozilla\MaintenanceService" "Attempted" + ClearErrors + ${If} ${RunningX64} + SetRegView lastused + ${EndIf} + + ; Add the registry keys for allowed certificates. + ${AddMaintCertKeys} + + ; If the maintenance service is already installed, do nothing. + ; The maintenance service will launch: + ; maintenanceservice_installer.exe /Upgrade to upgrade the maintenance + ; service if necessary. If the update was done from updater.exe without + ; the service (i.e. service is failing), updater.exe will do the update of + ; the service. The reasons we do not do it here is because we don't want + ; to have to prompt for limited user accounts when the service isn't used + ; and we currently call the PostUpdate twice, once for the user and once + ; for the SYSTEM account. Also, this would stop the maintenance service + ; and we need a return result back to the service when run that way. + ${If} $5 == "" + ; An install of maintenance service was never attempted. + ; We know we are an Admin and that we have write access into HKLM + ; based on the above checks, so attempt to just run the EXE. + ; In the worst case, in case there is some edge case with the + ; IsAdmin check and the permissions check, the maintenance service + ; will just fail to be attempted to be installed. + nsExec::Exec "$\"$INSTDIR\maintenanceservice_installer.exe$\"" + ${EndIf} + ${EndIf} +!endif +!macroend +!define PostUpdate "!insertmacro PostUpdate" + +!macro SetAsDefaultAppGlobal + ${RemoveDeprecatedKeys} ; Does not use SHCTX + + SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM) + ${SetHandlers} ; Uses SHCTX + ${SetStartMenuInternet} "HKLM" + ${FixShellIconHandler} "HKLM" + ${ShowShortcuts} + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + WriteRegStr HKLM "Software\Clients\StartMenuInternet" "" "$R9" +!macroend +!define SetAsDefaultAppGlobal "!insertmacro SetAsDefaultAppGlobal" + +; Removes shortcuts for this installation. This should also remove the +; application from Open With for the file types the application handles +; (bug 370480). +!macro HideShortcuts + ${StrFilter} "${FileMainEXE}" "+" "" "" $0 + StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo" + WriteRegDWORD HKLM "$R1" "IconsVisible" 0 + ${If} ${AtLeastWin8} + WriteRegDWORD HKCU "$R1" "IconsVisible" 0 + ${EndIf} + + SetShellVarContext all ; Set $DESKTOP to All Users + ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + SetShellVarContext current ; Set $DESKTOP to the current user's desktop + ${EndUnless} + + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::GetShortCutArgs "$DESKTOP\${BrandFullName}.lnk" + Pop $0 + ${If} "$0" == "" + ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk" + Pop $0 + ${GetLongPath} "$0" $0 + ${If} "$0" == "$INSTDIR\${FileMainEXE}" + Delete "$DESKTOP\${BrandFullName}.lnk" + ${EndIf} + ${EndIf} + ${EndIf} + + SetShellVarContext all ; Set $SMPROGRAMS to All Users + ${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start + ; Menu Programs directory + ${EndUnless} + + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::GetShortCutArgs "$SMPROGRAMS\${BrandFullName}.lnk" + Pop $0 + ${If} "$0" == "" + ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandFullName}.lnk" + Pop $0 + ${GetLongPath} "$0" $0 + ${If} "$0" == "$INSTDIR\${FileMainEXE}" + Delete "$SMPROGRAMS\${BrandFullName}.lnk" + ${EndIf} + ${EndIf} + ${EndIf} + + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk" + Pop $0 + ${If} "$0" == "" + ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk" + Pop $0 + ${GetLongPath} "$0" $0 + ${If} "$0" == "$INSTDIR\${FileMainEXE}" + Delete "$QUICKLAUNCH\${BrandFullName}.lnk" + ${EndIf} + ${EndIf} + ${EndIf} +!macroend +!define HideShortcuts "!insertmacro HideShortcuts" + +; Adds shortcuts for this installation. This should also add the application +; to Open With for the file types the application handles (bug 370480). +!macro ShowShortcuts + ${StrFilter} "${FileMainEXE}" "+" "" "" $0 + StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo" + WriteRegDWORD HKLM "$R1" "IconsVisible" 1 + ${If} ${AtLeastWin8} + WriteRegDWORD HKCU "$R1" "IconsVisible" 1 + ${EndIf} + + SetShellVarContext all ; Set $DESKTOP to All Users + ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "$AppUserModelID" "true" + ${EndIf} + ${Else} + SetShellVarContext current ; Set $DESKTOP to the current user's desktop + ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "$AppUserModelID" "true" + ${EndIf} + ${EndIf} + ${EndUnless} + ${EndIf} + ${EndUnless} + + SetShellVarContext all ; Set $SMPROGRAMS to All Users + ${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true" + ${EndIf} + ${Else} + SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start + ; Menu Programs directory + ${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true" + ${EndIf} + ${EndIf} + ${EndUnless} + ${EndIf} + ${EndUnless} + + ; Windows 7 doesn't use the QuickLaunch directory + ${Unless} ${AtLeastWin7} + ${AndUnless} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" \ + "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ + "$INSTDIR" + ${EndIf} + ${EndUnless} +!macroend +!define ShowShortcuts "!insertmacro ShowShortcuts" + +!macro AddAssociationIfNoneExist FILE_TYPE + ClearErrors + EnumRegKey $7 HKCR "${FILE_TYPE}" 0 + ${If} ${Errors} + WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}" "" "FirefoxHTML" + ${EndIf} + WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}\OpenWithProgids" "FirefoxHTML" "" +!macroend +!define AddAssociationIfNoneExist "!insertmacro AddAssociationIfNoneExist" + +; Adds the protocol and file handler registry entries for making Firefox the +; default handler (uses SHCTX). +!macro SetHandlers + ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8 + + StrCpy $0 "SOFTWARE\Classes" + StrCpy $2 "$\"$8$\" -osint -url $\"%1$\"" + + ; Associate the file handlers with FirefoxHTML + ReadRegStr $6 SHCTX "$0\.htm" "" + ${If} "$6" != "FirefoxHTML" + WriteRegStr SHCTX "$0\.htm" "" "FirefoxHTML" + ${EndIf} + + ReadRegStr $6 SHCTX "$0\.html" "" + ${If} "$6" != "FirefoxHTML" + WriteRegStr SHCTX "$0\.html" "" "FirefoxHTML" + ${EndIf} + + ReadRegStr $6 SHCTX "$0\.shtml" "" + ${If} "$6" != "FirefoxHTML" + WriteRegStr SHCTX "$0\.shtml" "" "FirefoxHTML" + ${EndIf} + + ReadRegStr $6 SHCTX "$0\.xht" "" + ${If} "$6" != "FirefoxHTML" + WriteRegStr SHCTX "$0\.xht" "" "FirefoxHTML" + ${EndIf} + + ReadRegStr $6 SHCTX "$0\.xhtml" "" + ${If} "$6" != "FirefoxHTML" + WriteRegStr SHCTX "$0\.xhtml" "" "FirefoxHTML" + ${EndIf} + + ${AddAssociationIfNoneExist} ".pdf" + ${AddAssociationIfNoneExist} ".oga" + ${AddAssociationIfNoneExist} ".ogg" + ${AddAssociationIfNoneExist} ".ogv" + ${AddAssociationIfNoneExist} ".pdf" + ${AddAssociationIfNoneExist} ".webm" + + ; An empty string is used for the 5th param because FirefoxHTML is not a + ; protocol handler + ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \ + "${AppRegName} HTML Document" "" + + ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \ + "true" + ; An empty string is used for the 4th & 5th params because the following + ; protocol handlers already have a display name and the additional keys + ; required for a protocol handler. + ${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" "" + ${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" "" + ${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" "" +!macroend +!define SetHandlers "!insertmacro SetHandlers" + +; Adds the HKLM\Software\Clients\StartMenuInternet\FIREFOX.EXE registry +; entries (does not use SHCTX). +; +; The values for StartMenuInternet are only valid under HKLM and there can only +; be one installation registerred under StartMenuInternet per application since +; the key name is derived from the main application executable. +; http://support.microsoft.com/kb/297878 +; +; In Windows 8 this changes slightly, you can store StartMenuInternet entries in +; HKCU. The icon in start menu for StartMenuInternet is deprecated as of Win7, +; but the subkeys are what's important. Control panel default programs looks +; for them only in HKLM pre win8. +; +; Note: we might be able to get away with using the full path to the +; application executable for the key name in order to support multiple +; installations. +!macro SetStartMenuInternet RegKey + ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8 + ${GetLongPath} "$INSTDIR\uninstall\helper.exe" $7 + + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + + StrCpy $0 "Software\Clients\StartMenuInternet\$R9" + + WriteRegStr ${RegKey} "$0" "" "${BrandFullName}" + + WriteRegStr ${RegKey} "$0\DefaultIcon" "" "$8,0" + + ; The Reinstall Command is defined at + ; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_adv/registeringapps.asp + WriteRegStr ${RegKey} "$0\InstallInfo" "HideIconsCommand" "$\"$7$\" /HideShortcuts" + WriteRegStr ${RegKey} "$0\InstallInfo" "ShowIconsCommand" "$\"$7$\" /ShowShortcuts" + WriteRegStr ${RegKey} "$0\InstallInfo" "ReinstallCommand" "$\"$7$\" /SetAsDefaultAppGlobal" + + ClearErrors + ReadRegDWORD $1 ${RegKey} "$0\InstallInfo" "IconsVisible" + ; If the IconsVisible name value pair doesn't exist add it otherwise the + ; application won't be displayed in Set Program Access and Defaults. + ${If} ${Errors} + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + WriteRegDWORD ${RegKey} "$0\InstallInfo" "IconsVisible" 1 + ${Else} + WriteRegDWORD ${RegKey} "$0\InstallInfo" "IconsVisible" 0 + ${EndIf} + ${EndIf} + + WriteRegStr ${RegKey} "$0\shell\open\command" "" "$\"$8$\"" + + WriteRegStr ${RegKey} "$0\shell\properties" "" "$(CONTEXT_OPTIONS)" + WriteRegStr ${RegKey} "$0\shell\properties\command" "" "$\"$8$\" -preferences" + + WriteRegStr ${RegKey} "$0\shell\safemode" "" "$(CONTEXT_SAFE_MODE)" + WriteRegStr ${RegKey} "$0\shell\safemode\command" "" "$\"$8$\" -safe-mode" + + ; Vista Capabilities registry keys + WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationDescription" "$(REG_APP_DESC)" + WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationIcon" "$8,0" + WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationName" "${BrandShortName}" + + WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".htm" "FirefoxHTML" + WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".html" "FirefoxHTML" + WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".shtml" "FirefoxHTML" + WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".xht" "FirefoxHTML" + WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".xhtml" "FirefoxHTML" + + WriteRegStr ${RegKey} "$0\Capabilities\StartMenu" "StartMenuInternet" "$R9" + + WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "ftp" "FirefoxURL" + WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "http" "FirefoxURL" + WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "https" "FirefoxURL" + + ; Vista Registered Application + WriteRegStr ${RegKey} "Software\RegisteredApplications" "${AppRegName}" "$0\Capabilities" +!macroend +!define SetStartMenuInternet "!insertmacro SetStartMenuInternet" + +; The IconHandler reference for FirefoxHTML can end up in an inconsistent state +; due to changes not being detected by the IconHandler for side by side +; installs (see bug 268512). The symptoms can be either an incorrect icon or no +; icon being displayed for files associated with Firefox (does not use SHCTX). +!macro FixShellIconHandler RegKey + ClearErrors + ReadRegStr $1 ${RegKey} "Software\Classes\FirefoxHTML\ShellEx\IconHandler" "" + ${Unless} ${Errors} + ReadRegStr $1 ${RegKey} "Software\Classes\FirefoxHTML\DefaultIcon" "" + ${GetLongPath} "$INSTDIR\${FileMainEXE}" $2 + ${If} "$1" != "$2,1" + WriteRegStr ${RegKey} "Software\Classes\FirefoxHTML\DefaultIcon" "" "$2,1" + ${EndIf} + ${EndUnless} +!macroend +!define FixShellIconHandler "!insertmacro FixShellIconHandler" + +; Add Software\Mozilla\ registry entries (uses SHCTX). +!macro SetAppKeys + ; Check if this is an ESR release and if so add registry values so it is + ; possible to determine that this is an ESR install (bug 726781). + ClearErrors + ${WordFind} "${UpdateChannel}" "esr" "E#" $3 + ${If} ${Errors} + StrCpy $3 "" + ${Else} + StrCpy $3 " ESR" + ${EndIf} + + ${GetLongPath} "$INSTDIR" $8 + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})\Main" + ${WriteRegStr2} $TmpVal "$0" "Install Directory" "$8" 0 + ${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0 + + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})\Uninstall" + ${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" 0 + + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})" + ${WriteRegStr2} $TmpVal "$0" "" "${AppVersion}$3 (${ARCH} ${AB_CD})" 0 + ${If} "$3" == "" + DeleteRegValue SHCTX "$0" "ESR" + ${Else} + ${WriteRegDWORD2} $TmpVal "$0" "ESR" 1 0 + ${EndIf} + + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3\bin" + ${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0 + + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3\extensions" + ${WriteRegStr2} $TmpVal "$0" "Components" "$8\components" 0 + ${WriteRegStr2} $TmpVal "$0" "Plugins" "$8\plugins" 0 + + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3" + ${WriteRegStr2} $TmpVal "$0" "GeckoVer" "${GREVersion}" 0 + ${If} "$3" == "" + DeleteRegValue SHCTX "$0" "ESR" + ${Else} + ${WriteRegDWORD2} $TmpVal "$0" "ESR" 1 0 + ${EndIf} + + StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}$3" + ${WriteRegStr2} $TmpVal "$0" "" "${GREVersion}" 0 + ${WriteRegStr2} $TmpVal "$0" "CurrentVersion" "${AppVersion}$3 (${ARCH} ${AB_CD})" 0 +!macroend +!define SetAppKeys "!insertmacro SetAppKeys" + +; Add uninstall registry entries. This macro tests for write access to determine +; if the uninstall keys should be added to HKLM or HKCU. +!macro SetUninstallKeys + ; Check if this is an ESR release and if so add registry values so it is + ; possible to determine that this is an ESR install (bug 726781). + ClearErrors + ${WordFind} "${UpdateChannel}" "esr" "E#" $3 + ${If} ${Errors} + StrCpy $3 "" + ${Else} + StrCpy $3 " ESR" + ${EndIf} + + StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" + + StrCpy $2 "" + ClearErrors + WriteRegStr HKLM "$0" "${BrandShortName}InstallerTest" "Write Test" + ${If} ${Errors} + ; If the uninstall keys already exist in HKLM don't create them in HKCU + ClearErrors + ReadRegStr $2 "HKLM" $0 "DisplayName" + ${If} $2 == "" + ; Otherwise we don't have any keys for this product in HKLM so proceeed + ; to create them in HKCU. Better handling for this will be done in: + ; Bug 711044 - Better handling for 2 uninstall icons + StrCpy $1 "HKCU" + SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU) + ${EndIf} + ClearErrors + ${Else} + StrCpy $1 "HKLM" + SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM) + DeleteRegValue HKLM "$0" "${BrandShortName}InstallerTest" + ${EndIf} + + ${If} $2 == "" + ${GetLongPath} "$INSTDIR" $8 + + ; Write the uninstall registry keys + ${WriteRegStr2} $1 "$0" "Comments" "${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" 0 + ${WriteRegStr2} $1 "$0" "DisplayIcon" "$8\${FileMainEXE},0" 0 + ${WriteRegStr2} $1 "$0" "DisplayName" "${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" 0 + ${WriteRegStr2} $1 "$0" "DisplayVersion" "${AppVersion}" 0 + ${WriteRegStr2} $1 "$0" "HelpLink" "${HelpLink}" 0 + ${WriteRegStr2} $1 "$0" "InstallLocation" "$8" 0 + ${WriteRegStr2} $1 "$0" "Publisher" "Mozilla" 0 + ${WriteRegStr2} $1 "$0" "UninstallString" "$\"$8\uninstall\helper.exe$\"" 0 + DeleteRegValue SHCTX "$0" "URLInfoAbout" +; Don't add URLUpdateInfo which is the release notes url except for the release +; and esr channels since nightly, aurora, and beta do not have release notes. +; Note: URLUpdateInfo is only defined in the official branding.nsi. +!ifdef URLUpdateInfo +!ifndef BETA_UPDATE_CHANNEL + ${WriteRegStr2} $1 "$0" "URLUpdateInfo" "${URLUpdateInfo}" 0 +!endif +!endif + ${WriteRegStr2} $1 "$0" "URLInfoAbout" "${URLInfoAbout}" 0 + ${WriteRegDWORD2} $1 "$0" "NoModify" 1 0 + ${WriteRegDWORD2} $1 "$0" "NoRepair" 1 0 + + ${GetSize} "$8" "/S=0K" $R2 $R3 $R4 + ${WriteRegDWORD2} $1 "$0" "EstimatedSize" $R2 0 + + ${If} "$TmpVal" == "HKLM" + SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM) + ${Else} + SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU) + ${EndIf} + ${EndIf} +!macroend +!define SetUninstallKeys "!insertmacro SetUninstallKeys" + +; Due to a bug when associating some file handlers, only SHCTX was checked for +; some file types such as ".pdf". SHCTX is set to HKCU or HKLM depending on +; whether the installer has write access to HKLM. The bug would happen when +; HCKU was checked and didn't exist since programs aren't required to set the +; HKCU Software\Classes keys when associating handlers. The fix uses the merged +; view in HKCR to check for existance of an existing association. This macro +; cleans affected installations by removing the HKLM and HKCU value if it is set +; to FirefoxHTML when there is a value for PersistentHandler or by removing the +; HKCU value when the HKLM value has a value other than an empty string. +!macro FixBadFileAssociation FILE_TYPE + ; Only delete the default value in case the key has values for OpenWithList, + ; OpenWithProgids, PersistentHandler, etc. + ReadRegStr $0 HKCU "Software\Classes\${FILE_TYPE}" "" + ReadRegStr $1 HKLM "Software\Classes\${FILE_TYPE}" "" + ReadRegStr $2 HKCR "${FILE_TYPE}\PersistentHandler" "" + ${If} "$2" != "" + ; Since there is a persistent handler remove FirefoxHTML as the default + ; value from both HKCU and HKLM if it set to FirefoxHTML. + ${If} "$0" == "FirefoxHTML" + DeleteRegValue HKCU "Software\Classes\${FILE_TYPE}" "" + ${EndIf} + ${If} "$1" == "FirefoxHTML" + DeleteRegValue HKLM "Software\Classes\${FILE_TYPE}" "" + ${EndIf} + ${ElseIf} "$0" == "FirefoxHTML" + ; Since KHCU is set to FirefoxHTML remove FirefoxHTML as the default value + ; from HKCU if HKLM is set to a value other than an empty string. + ${If} "$1" != "" + DeleteRegValue HKCU "Software\Classes\${FILE_TYPE}" "" + ${EndIf} + ${EndIf} +!macroend +!define FixBadFileAssociation "!insertmacro FixBadFileAssociation" + +; Add app specific handler registry entries under Software\Classes if they +; don't exist (does not use SHCTX). +!macro FixClassKeys + StrCpy $1 "SOFTWARE\Classes" + + ; File handler keys and name value pairs that may need to be created during + ; install or upgrade. + ReadRegStr $0 HKCR ".shtml" "Content Type" + ${If} "$0" == "" + StrCpy $0 "$1\.shtml" + ${WriteRegStr2} $TmpVal "$1\.shtml" "" "shtmlfile" 0 + ${WriteRegStr2} $TmpVal "$1\.shtml" "Content Type" "text/html" 0 + ${WriteRegStr2} $TmpVal "$1\.shtml" "PerceivedType" "text" 0 + ${EndIf} + + ReadRegStr $0 HKCR ".xht" "Content Type" + ${If} "$0" == "" + ${WriteRegStr2} $TmpVal "$1\.xht" "" "xhtfile" 0 + ${WriteRegStr2} $TmpVal "$1\.xht" "Content Type" "application/xhtml+xml" 0 + ${EndIf} + + ReadRegStr $0 HKCR ".xhtml" "Content Type" + ${If} "$0" == "" + ${WriteRegStr2} $TmpVal "$1\.xhtml" "" "xhtmlfile" 0 + ${WriteRegStr2} $TmpVal "$1\.xhtml" "Content Type" "application/xhtml+xml" 0 + ${EndIf} + + ; Remove possibly badly associated file types + ${FixBadFileAssociation} ".pdf" + ${FixBadFileAssociation} ".oga" + ${FixBadFileAssociation} ".ogg" + ${FixBadFileAssociation} ".ogv" + ${FixBadFileAssociation} ".pdf" + ${FixBadFileAssociation} ".webm" +!macroend +!define FixClassKeys "!insertmacro FixClassKeys" + +; Updates protocol handlers if their registry open command value is for this +; install location (uses SHCTX). +!macro UpdateProtocolHandlers + ; Store the command to open the app with an url in a register for easy access. + ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8 + StrCpy $2 "$\"$8$\" -osint -url $\"%1$\"" + + ; Only set the file and protocol handlers if the existing one under HKCR is + ; for this install location. + + ${IsHandlerForInstallDir} "FirefoxHTML" $R9 + ${If} "$R9" == "true" + ; An empty string is used for the 5th param because FirefoxHTML is not a + ; protocol handler. + ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \ + "${AppRegName} HTML Document" "" + ${EndIf} + + ${IsHandlerForInstallDir} "FirefoxURL" $R9 + ${If} "$R9" == "true" + ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" \ + "${AppRegName} URL" "true" + ${EndIf} + + ; An empty string is used for the 4th & 5th params because the following + ; protocol handlers already have a display name and the additional keys + ; required for a protocol handler. + ${IsHandlerForInstallDir} "ftp" $R9 + ${If} "$R9" == "true" + ${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" "" + ${EndIf} + + ${IsHandlerForInstallDir} "http" $R9 + ${If} "$R9" == "true" + ${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" "" + ${EndIf} + + ${IsHandlerForInstallDir} "https" $R9 + ${If} "$R9" == "true" + ${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" "" + ${EndIf} +!macroend +!define UpdateProtocolHandlers "!insertmacro UpdateProtocolHandlers" + +!ifdef MOZ_MAINTENANCE_SERVICE +; Adds maintenance service certificate keys for the install dir. +; For the cert to work, it must also be signed by a trusted cert for the user. +!macro AddMaintCertKeys + Push $R0 + ; Allow main Mozilla cert information for updates + ; This call will push the needed key on the stack + ServicesHelper::PathToUniqueRegistryPath "$INSTDIR" + Pop $R0 + ${If} $R0 != "" + ; More than one certificate can be specified in a different subfolder + ; for example: $R0\1, but each individual binary can be signed + ; with at most one certificate. A fallback certificate can only be used + ; if the binary is replaced with a different certificate. + ; We always use the 64bit registry for certs. + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} + + ; PrefetchProcessName was originally used to experiment with deleting + ; Windows prefetch as a speed optimization. It is no longer used though. + DeleteRegValue HKLM "$R0" "prefetchProcessName" + + ; Setting the Attempted value will ensure that a new Maintenance Service + ; install will never be attempted again after this from updates. The value + ; is used only to see if updates should attempt new service installs. + WriteRegDWORD HKLM "Software\Mozilla\MaintenanceService" "Attempted" 1 + + ; These values associate the allowed certificates for the current + ; installation. + WriteRegStr HKLM "$R0\0" "name" "${CERTIFICATE_NAME}" + WriteRegStr HKLM "$R0\0" "issuer" "${CERTIFICATE_ISSUER}" + ; These values associate the allowed certificates for the previous + ; installation, so that we can update from it cleanly using the + ; old updater.exe (which will still have this signature). + WriteRegStr HKLM "$R0\1" "name" "${CERTIFICATE_NAME_PREVIOUS}" + WriteRegStr HKLM "$R0\1" "issuer" "${CERTIFICATE_ISSUER_PREVIOUS}" + ${If} ${RunningX64} + SetRegView lastused + ${EndIf} + ClearErrors + ${EndIf} + ; Restore the previously used value back + Pop $R0 +!macroend +!define AddMaintCertKeys "!insertmacro AddMaintCertKeys" +!endif + +; Removes various registry entries for reasons noted below (does not use SHCTX). +!macro RemoveDeprecatedKeys + StrCpy $0 "SOFTWARE\Classes" + ; Remove support for launching gopher urls from the shell during install or + ; update if the DefaultIcon is from firefox.exe. + ${RegCleanAppHandler} "gopher" + + ; Remove support for launching chrome urls from the shell during install or + ; update if the DefaultIcon is from firefox.exe (Bug 301073). + ${RegCleanAppHandler} "chrome" + + ; Remove protocol handler registry keys added by the MS shim + DeleteRegKey HKLM "Software\Classes\Firefox.URL" + DeleteRegKey HKCU "Software\Classes\Firefox.URL" + + ; Delete gopher from Capabilities\URLAssociations if it is present. + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + StrCpy $0 "Software\Clients\StartMenuInternet\$R9" + ClearErrors + ReadRegStr $2 HKLM "$0\Capabilities\URLAssociations" "gopher" + ${Unless} ${Errors} + DeleteRegValue HKLM "$0\Capabilities\URLAssociations" "gopher" + ${EndUnless} + + ; Delete gopher from the user's UrlAssociations if it points to FirefoxURL. + StrCpy $0 "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\gopher" + ReadRegStr $2 HKCU "$0\UserChoice" "Progid" + ${If} "$2" == "FirefoxURL" + DeleteRegKey HKCU "$0" + ${EndIf} +!macroend +!define RemoveDeprecatedKeys "!insertmacro RemoveDeprecatedKeys" + +; Removes various directories and files for reasons noted below. +!macro RemoveDeprecatedFiles + ; Remove talkback if it is present (remove after bug 386760 is fixed) + ${If} ${FileExists} "$INSTDIR\extensions\talkback@mozilla.org" + RmDir /r /REBOOTOK "$INSTDIR\extensions\talkback@mozilla.org" + ${EndIf} + + ; Remove the Java Console extension (bug 1165156) + ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0031-ABCDEFFEDCBA}" + RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0031-ABCDEFFEDCBA}" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0034-ABCDEFFEDCBA}" + RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0034-ABCDEFFEDCBA}" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0039-ABCDEFFEDCBA}" + RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0039-ABCDEFFEDCBA}" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0045-ABCDEFFEDCBA}" + RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0045-ABCDEFFEDCBA}" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0017-0000-0000-ABCDEFFEDCBA}" + RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0017-0000-0000-ABCDEFFEDCBA}" + ${EndIf} +!macroend +!define RemoveDeprecatedFiles "!insertmacro RemoveDeprecatedFiles" + +; Converts specific partner distribution.ini from ansi to utf-8 (bug 882989) +!macro FixDistributionsINI + StrCpy $1 "$INSTDIR\distribution\distribution.ini" + StrCpy $2 "$INSTDIR\distribution\utf8fix" + StrCpy $0 "0" ; Default to not attempting to fix + + ; Check if the distribution.ini settings are for a partner build that needs + ; to have its distribution.ini converted from ansi to utf-8. + ${If} ${FileExists} "$1" + ${Unless} ${FileExists} "$2" + ReadINIStr $3 "$1" "Preferences" "app.distributor" + ${If} "$3" == "yahoo" + ReadINIStr $3 "$1" "Preferences" "app.distributor.channel" + ${If} "$3" == "de" + ${OrIf} "$3" == "es" + ${OrIf} "$3" == "e1" + ${OrIf} "$3" == "mx" + StrCpy $0 "1" + ${EndIf} + ${EndIf} + ; Create the utf8fix so this only runs once + FileOpen $3 "$2" w + FileClose $3 + ${EndUnless} + ${EndIf} + + ${If} "$0" == "1" + StrCpy $0 "0" + ClearErrors + ReadINIStr $3 "$1" "Global" "version" + ${Unless} ${Errors} + StrCpy $4 "$3" 2 + ${If} "$4" == "1." + StrCpy $4 "$3" "" 2 ; Everything after "1." + ${If} $4 < 23 + StrCpy $0 "1" + ${EndIf} + ${EndIf} + ${EndUnless} + ${EndIf} + + ${If} "$0" == "1" + ClearErrors + FileOpen $3 "$1" r + ${If} ${Errors} + FileClose $3 + ${Else} + StrCpy $2 "$INSTDIR\distribution\distribution.new" + ClearErrors + FileOpen $4 "$2" w + ${If} ${Errors} + FileClose $3 + FileClose $4 + ${Else} + StrCpy $0 "0" ; Default to not replacing the original distribution.ini + ${Do} + FileReadByte $3 $5 + ${If} $5 == "" + ${Break} + ${EndIf} + ${If} $5 == 233 ; ansi é + StrCpy $0 "1" + FileWriteByte $4 195 + FileWriteByte $4 169 + ${ElseIf} $5 == 241 ; ansi ñ + StrCpy $0 "1" + FileWriteByte $4 195 + FileWriteByte $4 177 + ${ElseIf} $5 == 252 ; ansi ü + StrCpy $0 "1" + FileWriteByte $4 195 + FileWriteByte $4 188 + ${ElseIf} $5 < 128 + FileWriteByte $4 $5 + ${EndIf} + ${Loop} + FileClose $3 + FileClose $4 + ${If} "$0" == "1" + ClearErrors + Rename "$1" "$1.bak" + ${Unless} ${Errors} + Rename "$2" "$1" + Delete "$1.bak" + ${EndUnless} + ${Else} + Delete "$2" + ${EndIf} + ${EndIf} + ${EndIf} + ${EndIf} +!macroend +!define FixDistributionsINI "!insertmacro FixDistributionsINI" + +; Adds a pinned shortcut to Task Bar on update for Windows 7 and above if this +; macro has never been called before and the application is default (see +; PinToTaskBar for more details). +; Since defaults handling is handled by Windows in Win8 and later, we always +; attempt to pin a taskbar on that OS. If Windows sets the defaults at +; installation time, then we don't get the opportunity to run this code at +; that time. +!macro MigrateTaskBarShortcut + ${GetShortcutsLogPath} $0 + ${If} ${FileExists} "$0" + ClearErrors + ReadINIStr $1 "$0" "TASKBAR" "Migrated" + ${If} ${Errors} + ClearErrors + WriteIniStr "$0" "TASKBAR" "Migrated" "true" + ${If} ${AtLeastWin7} + ; If we didn't run the stub installer, AddTaskbarSC will be empty. + ; We determine whether to pin based on whether we're the default + ; browser, or if we're on win8 or later, we always pin. + ${If} $AddTaskbarSC == "" + ; No need to check the default on Win8 and later + ${If} ${AtMostWin2008R2} + ; Check if the Firefox is the http handler for this user + SetShellVarContext current ; Set SHCTX to the current user + ${IsHandlerForInstallDir} "http" $R9 + ${If} $TmpVal == "HKLM" + SetShellVarContext all ; Set SHCTX to all users + ${EndIf} + ${EndIf} + ${If} "$R9" == "true" + ${OrIf} ${AtLeastWin8} + ${PinToTaskBar} + ${EndIf} + ${ElseIf} $AddTaskbarSC == "1" + ${PinToTaskBar} + ${EndIf} + ${EndIf} + ${EndIf} + ${EndIf} +!macroend +!define MigrateTaskBarShortcut "!insertmacro MigrateTaskBarShortcut" + +; Adds a pinned Task Bar shortcut on Windows 7 if there isn't one for the main +; application executable already. Existing pinned shortcuts for the same +; application model ID must be removed first to prevent breaking the pinned +; item's lists but multiple installations with the same application model ID is +; an edgecase. If removing existing pinned shortcuts with the same application +; model ID removes a pinned pinned Start Menu shortcut this will also add a +; pinned Start Menu shortcut. +!macro PinToTaskBar + ${If} ${AtLeastWin7} + StrCpy $8 "false" ; Whether a shortcut had to be created + ${IsPinnedToTaskBar} "$INSTDIR\${FileMainEXE}" $R9 + ${If} "$R9" == "false" + ; Find an existing Start Menu shortcut or create one to use for pinning + ${GetShortcutsLogPath} $0 + ${If} ${FileExists} "$0" + ClearErrors + ReadINIStr $1 "$0" "STARTMENU" "Shortcut0" + ${Unless} ${Errors} + SetShellVarContext all ; Set SHCTX to all users + ${Unless} ${FileExists} "$SMPROGRAMS\$1" + SetShellVarContext current ; Set SHCTX to the current user + ${Unless} ${FileExists} "$SMPROGRAMS\$1" + StrCpy $8 "true" + CreateShortCut "$SMPROGRAMS\$1" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\$1" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\$1" \ + "$INSTDIR" + ${If} "$AppUserModelID" != "" + ApplicationID::Set "$SMPROGRAMS\$1" "$AppUserModelID" "true" + ${EndIf} + ${EndIf} + ${EndUnless} + ${EndUnless} + + ${If} ${FileExists} "$SMPROGRAMS\$1" + ; Count of Start Menu pinned shortcuts before unpinning. + ${PinnedToStartMenuLnkCount} $R9 + + ; Having multiple shortcuts pointing to different installations with + ; the same AppUserModelID (e.g. side by side installations of the + ; same version) will make the TaskBar shortcut's lists into an bad + ; state where the lists are not shown. To prevent this first + ; uninstall the pinned item. + ApplicationID::UninstallPinnedItem "$SMPROGRAMS\$1" + + ; Count of Start Menu pinned shortcuts after unpinning. + ${PinnedToStartMenuLnkCount} $R8 + + ; If there is a change in the number of Start Menu pinned shortcuts + ; assume that unpinning unpinned a side by side installation from + ; the Start Menu and pin this installation to the Start Menu. + ${Unless} $R8 == $R9 + ; Pin the shortcut to the Start Menu. 5381 is the shell32.dll + ; resource id for the "Pin to Start Menu" string. + InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "5381" + ${EndUnless} + + ; Pin the shortcut to the TaskBar. 5386 is the shell32.dll resource + ; id for the "Pin to Taskbar" string. + InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "5386" + + ; Delete the shortcut if it was created + ${If} "$8" == "true" + Delete "$SMPROGRAMS\$1" + ${EndIf} + ${EndIf} + + ${If} $TmpVal == "HKCU" + SetShellVarContext current ; Set SHCTX to the current user + ${Else} + SetShellVarContext all ; Set SHCTX to all users + ${EndIf} + ${EndUnless} + ${EndIf} + ${EndIf} + ${EndIf} +!macroend +!define PinToTaskBar "!insertmacro PinToTaskBar" + +; Adds a shortcut to the root of the Start Menu Programs directory if the +; application's Start Menu Programs directory exists with a shortcut pointing to +; this installation directory. This will also remove the old shortcuts and the +; application's Start Menu Programs directory by calling the RemoveStartMenuDir +; macro. +!macro MigrateStartMenuShortcut + ${GetShortcutsLogPath} $0 + ${If} ${FileExists} "$0" + ClearErrors + ReadINIStr $5 "$0" "SMPROGRAMS" "RelativePathToDir" + ${Unless} ${Errors} + ClearErrors + ReadINIStr $1 "$0" "STARTMENU" "Shortcut0" + ${If} ${Errors} + ; The STARTMENU ini section doesn't exist. + ${LogStartMenuShortcut} "${BrandFullName}.lnk" + ${GetLongPath} "$SMPROGRAMS" $2 + ${GetLongPath} "$2\$5" $1 + ${If} "$1" != "" + ClearErrors + ReadINIStr $3 "$0" "SMPROGRAMS" "Shortcut0" + ${Unless} ${Errors} + ${If} ${FileExists} "$1\$3" + ShellLink::GetShortCutTarget "$1\$3" + Pop $4 + ${If} "$INSTDIR\${FileMainEXE}" == "$4" + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$AppUserModelID" "true" + ${EndIf} + ${EndIf} + ${EndIf} + ${EndIf} + ${EndUnless} + ${EndIf} + ${EndIf} + ; Remove the application's Start Menu Programs directory, shortcuts, and + ; ini section. + ${RemoveStartMenuDir} + ${EndUnless} + ${EndIf} +!macroend +!define MigrateStartMenuShortcut "!insertmacro MigrateStartMenuShortcut" + +; Removes the application's start menu directory along with its shortcuts if +; they exist and if they exist creates a start menu shortcut in the root of the +; start menu directory (bug 598779). If the application's start menu directory +; is not empty after removing the shortucts the directory will not be removed +; since these additional items were not created by the installer (uses SHCTX). +!macro RemoveStartMenuDir + ${GetShortcutsLogPath} $0 + ${If} ${FileExists} "$0" + ; Delete Start Menu Programs shortcuts, directory if it is empty, and + ; parent directories if they are empty up to but not including the start + ; menu directory. + ${GetLongPath} "$SMPROGRAMS" $1 + ClearErrors + ReadINIStr $2 "$0" "SMPROGRAMS" "RelativePathToDir" + ${Unless} ${Errors} + ${GetLongPath} "$1\$2" $2 + ${If} "$2" != "" + ; Delete shortucts in the Start Menu Programs directory. + StrCpy $3 0 + ${Do} + ClearErrors + ReadINIStr $4 "$0" "SMPROGRAMS" "Shortcut$3" + ; Stop if there are no more entries + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${If} ${FileExists} "$2\$4" + ShellLink::GetShortCutTarget "$2\$4" + Pop $5 + ${If} "$INSTDIR\${FileMainEXE}" == "$5" + Delete "$2\$4" + ${EndIf} + ${EndIf} + IntOp $3 $3 + 1 ; Increment the counter + ${Loop} + ; Delete Start Menu Programs directory and parent directories + ${Do} + ; Stop if the current directory is the start menu directory + ${If} "$1" == "$2" + ${ExitDo} + ${EndIf} + ClearErrors + RmDir "$2" + ; Stop if removing the directory failed + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${GetParent} "$2" $2 + ${Loop} + ${EndIf} + DeleteINISec "$0" "SMPROGRAMS" + ${EndUnless} + ${EndIf} +!macroend +!define RemoveStartMenuDir "!insertmacro RemoveStartMenuDir" + +; Creates the shortcuts log ini file with the appropriate entries if it doesn't +; already exist. +!macro CreateShortcutsLog + ${GetShortcutsLogPath} $0 + ${Unless} ${FileExists} "$0" + ${LogStartMenuShortcut} "${BrandFullName}.lnk" + ${LogQuickLaunchShortcut} "${BrandFullName}.lnk" + ${LogDesktopShortcut} "${BrandFullName}.lnk" + ${EndUnless} +!macroend +!define CreateShortcutsLog "!insertmacro CreateShortcutsLog" + +; The files to check if they are in use during (un)install so the restart is +; required message is displayed. All files must be located in the $INSTDIR +; directory. +!macro PushFilesToCheck + ; The first string to be pushed onto the stack MUST be "end" to indicate + ; that there are no more files to check in $INSTDIR and the last string + ; should be ${FileMainEXE} so if it is in use the CheckForFilesInUse macro + ; returns after the first check. + Push "end" + Push "AccessibleMarshal.dll" + Push "IA2Marshal.dll" + Push "freebl3.dll" + Push "nssckbi.dll" + Push "nspr4.dll" + Push "nssdbm3.dll" + Push "mozsqlite3.dll" + Push "xpcom.dll" + Push "crashreporter.exe" + Push "minidump-analyzer.exe" + Push "updater.exe" + Push "${FileMainEXE}" +!macroend +!define PushFilesToCheck "!insertmacro PushFilesToCheck" + + +; Pushes the string "true" to the top of the stack if the Firewall service is +; running and pushes the string "false" to the top of the stack if it isn't. +!define SC_MANAGER_ALL_ACCESS 0x3F +!define SERVICE_QUERY_CONFIG 0x0001 +!define SERVICE_QUERY_STATUS 0x0004 +!define SERVICE_RUNNING 0x4 + +!macro IsFirewallSvcRunning + Push $R9 + Push $R8 + Push $R7 + Push $R6 + Push "false" + + System::Call 'advapi32::OpenSCManagerW(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.R6' + ${If} $R6 != 0 + ; MpsSvc is the Firewall service on Windows Vista and above. + ; When opening the service with SERVICE_QUERY_CONFIG the return value will + ; be 0 if the service is not installed. + System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_CONFIG}) i.R7' + ${If} $R7 != 0 + System::Call 'advapi32::CloseServiceHandle(i R7) n' + ; Open the service with SERVICE_QUERY_CONFIG so its status can be queried. + System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_STATUS}) i.R7' + ${Else} + ; SharedAccess is the Firewall service on Windows XP. + ; When opening the service with SERVICE_QUERY_CONFIG the return value will + ; be 0 if the service is not installed. + System::Call 'advapi32::OpenServiceW(i R6, t "SharedAccess", i ${SERVICE_QUERY_CONFIG}) i.R7' + ${If} $R7 != 0 + System::Call 'advapi32::CloseServiceHandle(i R7) n' + ; Open the service with SERVICE_QUERY_CONFIG so its status can be + ; queried. + System::Call 'advapi32::OpenServiceW(i R6, t "SharedAccess", i ${SERVICE_QUERY_STATUS}) i.R7' + ${EndIf} + ${EndIf} + ; Did the calls to OpenServiceW succeed? + ${If} $R7 != 0 + System::Call '*(i,i,i,i,i,i,i) i.R9' + ; Query the current status of the service. + System::Call 'advapi32::QueryServiceStatus(i R7, i $R9) i' + System::Call '*$R9(i, i.R8)' + System::Free $R9 + System::Call 'advapi32::CloseServiceHandle(i R7) n' + IntFmt $R8 "0x%X" $R8 + ${If} $R8 == ${SERVICE_RUNNING} + Pop $R9 + Push "true" + ${EndIf} + ${EndIf} + System::Call 'advapi32::CloseServiceHandle(i R6) n' + ${EndIf} + + Exch 1 + Pop $R6 + Exch 1 + Pop $R7 + Exch 1 + Pop $R8 + Exch 1 + Pop $R9 +!macroend +!define IsFirewallSvcRunning "!insertmacro IsFirewallSvcRunning" +!define un.IsFirewallSvcRunning "!insertmacro IsFirewallSvcRunning" + +; Sets this installation as the default browser by setting the registry keys +; under HKEY_CURRENT_USER via registry calls and using the AppAssocReg NSIS +; plugin for Vista and above. This is a function instead of a macro so it is +; easily called from an elevated instance of the binary. Since this can be +; called by an elevated instance logging is not performed in this function. +Function SetAsDefaultAppUserHKCU + ; Only set as the user's StartMenuInternet browser if the StartMenuInternet + ; registry keys are for this install. + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + ClearErrors + ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" + ${If} ${Errors} + ${OrIf} ${AtMostWin2008R2} + ClearErrors + ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" + ${EndIf} + ${Unless} ${Errors} + ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $0 + ${If} ${FileExists} "$0" + ${GetLongPath} "$0" $0 + ${If} "$0" == "$INSTDIR" + WriteRegStr HKCU "Software\Clients\StartMenuInternet" "" "$R9" + ${EndIf} + ${EndIf} + ${EndUnless} + + SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU) + + ${If} ${AtLeastWin8} + ${SetStartMenuInternet} "HKCU" + ${FixShellIconHandler} "HKCU" + ${FixClassKeys} ; Does not use SHCTX + ${EndIf} + + ${SetHandlers} + + ${If} ${AtLeastWinVista} + ; Only register as the handler on Vista and above if the app registry name + ; exists under the RegisteredApplications registry key. The protocol and + ; file handlers set previously at the user level will associate this install + ; as the default browser. + ClearErrors + ReadRegStr $0 HKLM "Software\RegisteredApplications" "${AppRegName}" + ${Unless} ${Errors} + ; This is all protected by a user choice hash in Windows 8 so it won't + ; help, but it also won't hurt. + AppAssocReg::SetAppAsDefaultAll "${AppRegName}" + ${EndUnless} + ${EndIf} + ${RemoveDeprecatedKeys} + ${MigrateTaskBarShortcut} +FunctionEnd + +; Helper for updating the shortcut application model IDs. +Function FixShortcutAppModelIDs + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "$AppUserModelID" $0 + ${EndIf} +FunctionEnd + +; Helper for adding Firewall exceptions during install and after app update. +Function AddFirewallEntries + ${IsFirewallSvcRunning} + Pop $0 + ${If} "$0" == "true" + liteFirewallW::AddRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)" + ${EndIf} +FunctionEnd + +; The !ifdef NO_LOG prevents warnings when compiling the installer.nsi due to +; this function only being used by the uninstaller.nsi. +!ifdef NO_LOG + +Function SetAsDefaultAppUser + ; On Win8, we want to avoid having a UAC prompt since we'll already have + ; another action for control panel default browser selection popping up + ; to the user. Win8 is the first OS where the start menu keys can be + ; added into HKCU. The call to SetAsDefaultAppUserHKCU will have already + ; set the HKCU keys for SetStartMenuInternet. + ${If} ${AtLeastWin8} + ; Check if this is running in an elevated process + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} ; Not elevated + Call SetAsDefaultAppUserHKCU + ${Else} ; Elevated - execute the function in the unelevated process + GetFunctionAddress $0 SetAsDefaultAppUserHKCU + UAC::ExecCodeSegment $0 + ${EndIf} + Return ; Nothing more needs to be done + ${EndIf} + + ; Before Win8, it is only possible to set this installation of the application + ; as the StartMenuInternet handler if it was added to the HKLM + ; StartMenuInternet registry keys. + ; http://support.microsoft.com/kb/297878 + + ; Check if this install location registered as the StartMenuInternet client + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + ClearErrors + ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" + ${If} ${Errors} + ${OrIf} ${AtMostWin2008R2} + ClearErrors + ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" + ${EndIf} + + ${Unless} ${Errors} + ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $0 + ${If} ${FileExists} "$0" + ${GetLongPath} "$0" $0 + ${If} "$0" == "$INSTDIR" + ; Check if this is running in an elevated process + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} ; Not elevated + Call SetAsDefaultAppUserHKCU + ${Else} ; Elevated - execute the function in the unelevated process + GetFunctionAddress $0 SetAsDefaultAppUserHKCU + UAC::ExecCodeSegment $0 + ${EndIf} + Return ; Nothing more needs to be done + ${EndIf} + ${EndIf} + ${EndUnless} + + ; The code after ElevateUAC won't be executed on Vista and above when the + ; user: + ; a) is a member of the administrators group (e.g. elevation is required) + ; b) is not a member of the administrators group and chooses to elevate + ${ElevateUAC} + + ${SetStartMenuInternet} "HKLM" + + SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM) + + ${FixClassKeys} ; Does not use SHCTX + ${FixShellIconHandler} "HKLM" + ${RemoveDeprecatedKeys} ; Does not use SHCTX + + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} + Call SetAsDefaultAppUserHKCU + ${Else} + GetFunctionAddress $0 SetAsDefaultAppUserHKCU + UAC::ExecCodeSegment $0 + ${EndIf} +FunctionEnd +!define SetAsDefaultAppUser "Call SetAsDefaultAppUser" + +!endif ; NO_LOG diff --git a/browser/installer/windows/nsis/stub.nsi b/browser/installer/windows/nsis/stub.nsi new file mode 100644 index 000000000..176f641b3 --- /dev/null +++ b/browser/installer/windows/nsis/stub.nsi @@ -0,0 +1,2093 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Required Plugins: +# AppAssocReg +# CertCheck +# InetBgDL +# ShellLink +# UAC + +; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs +!verbose 3 + +SetDatablockOptimize on +SetCompress off +CRCCheck on + +RequestExecutionLevel user + +; The commands inside this ifdef require NSIS 3.0a2 or greater so the ifdef can +; be removed after we require NSIS 3.0a2 or greater. +!ifdef NSIS_PACKEDVERSION + Unicode true + ManifestSupportedOS all + ManifestDPIAware true +!endif + +!addplugindir ./ + +Var Dialog +Var Progressbar +Var ProgressbarMarqueeIntervalMS +Var LabelDownloading +Var LabelInstalling +Var LabelFreeSpace +Var CheckboxSetAsDefault +Var CheckboxShortcutOnBar ; Used for Quicklaunch or Taskbar as appropriate +Var CheckboxShortcutInStartMenu +Var CheckboxShortcutOnDesktop +Var CheckboxSendPing +Var CheckboxInstallMaintSvc +Var DirRequest +Var ButtonBrowse +Var LabelBlurb1 +Var LabelBlurb2 +Var LabelBlurb3 +Var BitmapBlurb1 +Var BitmapBlurb2 +Var BitmapBlurb3 +Var HwndBitmapBlurb1 +Var HwndBitmapBlurb2 +Var HWndBitmapBlurb3 + +Var FontNormal +Var FontItalic +Var FontBlurb + +Var WasOptionsButtonClicked +Var CanWriteToInstallDir +Var HasRequiredSpaceAvailable +Var IsDownloadFinished +Var DownloadSizeBytes +Var HalfOfDownload +Var DownloadReset +Var ExistingTopDir +Var SpaceAvailableBytes +Var InitialInstallDir +Var HandleDownload +Var CanSetAsDefault +Var InstallCounterStep +Var InstallStepSize +Var InstallTotalSteps +Var ProgressCompleted +Var ProgressTotal +Var TmpVal + +Var ExitCode +Var FirefoxLaunchCode + +; The first three tick counts are for the start of a phase and equate equate to +; the display of individual installer pages. +Var StartIntroPhaseTickCount +Var StartOptionsPhaseTickCount +Var StartDownloadPhaseTickCount +; Since the Intro and Options pages can be displayed multiple times the total +; seconds spent on each of these pages is reported. +Var IntroPhaseSeconds +Var OptionsPhaseSeconds +; The tick count for the last download. +Var StartLastDownloadTickCount +; The number of seconds from the start of the download phase until the first +; bytes are received. This is only recorded for first request so it is possible +; to determine connection issues for the first request. +Var DownloadFirstTransferSeconds +; The last four tick counts are for the end of a phase in the installation page. +Var EndDownloadPhaseTickCount +Var EndPreInstallPhaseTickCount +Var EndInstallPhaseTickCount +Var EndFinishPhaseTickCount + +Var InitialInstallRequirementsCode +Var ExistingProfile +Var ExistingVersion +Var ExistingBuildID +Var DownloadedBytes +Var DownloadRetryCount +Var OpenedDownloadPage +Var DownloadServerIP +Var PostSigningData + +Var ControlHeightPX +Var ControlRightPX + +; Uncomment the following to prevent pinging the metrics server when testing +; the stub installer +;!define STUB_DEBUG + +!define StubURLVersion "v7" + +; Successful install exit code +!define ERR_SUCCESS 0 + +/** + * The following errors prefixed with ERR_DOWNLOAD apply to the download phase. + */ +; The download was cancelled by the user +!define ERR_DOWNLOAD_CANCEL 10 + +; Too many attempts to download. The maximum attempts is defined in +; DownloadMaxRetries. +!define ERR_DOWNLOAD_TOO_MANY_RETRIES 11 + +/** + * The following errors prefixed with ERR_PREINSTALL apply to the pre-install + * check phase. + */ +; Unable to acquire a file handle to the downloaded file +!define ERR_PREINSTALL_INVALID_HANDLE 20 + +; The downloaded file's certificate is not trusted by the certificate store. +!define ERR_PREINSTALL_CERT_UNTRUSTED 21 + +; The downloaded file's certificate attribute values were incorrect. +!define ERR_PREINSTALL_CERT_ATTRIBUTES 22 + +; The downloaded file's certificate is not trusted by the certificate store and +; certificate attribute values were incorrect. +!define ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES 23 + +/** + * The following errors prefixed with ERR_INSTALL apply to the install phase. + */ +; The installation timed out. The installation timeout is defined by the number +; of progress steps defined in InstallTotalSteps and the install timer +; interval defined in InstallIntervalMS +!define ERR_INSTALL_TIMEOUT 30 + +; Maximum times to retry the download before displaying an error +!define DownloadMaxRetries 9 + +; Minimum size expected to download in bytes +!define DownloadMinSizeBytes 15728640 ; 15 MB + +; Maximum size expected to download in bytes +!define DownloadMaxSizeBytes 73400320 ; 70 MB + +; Interval before retrying to download. 3 seconds is used along with 10 +; attempted downloads (the first attempt along with 9 retries) to give a +; minimum of 30 seconds or retrying before giving up. +!define DownloadRetryIntervalMS 3000 + +; Interval for the download timer +!define DownloadIntervalMS 200 + +; Interval for the install timer +!define InstallIntervalMS 100 + +; The first step for the install progress bar. By starting with a large step +; immediate feedback is given to the user. +!define InstallProgressFirstStep 20 + +; The finish step size to quickly increment the progress bar after the +; installation has finished. +!define InstallProgressFinishStep 40 + +; Number of steps for the install progress. +; This might not be enough when installing on a slow network drive so it will +; fallback to downloading the full installer if it reaches this number. The size +; of the install progress step is increased when the full installer finishes +; instead of waiting. + +; Approximately 150 seconds with a 100 millisecond timer and a first step of 20 +; as defined by InstallProgressFirstStep. +!define /math InstallCleanTotalSteps ${InstallProgressFirstStep} + 1500 + +; Approximately 165 seconds (minus 0.2 seconds for each file that is removed) +; with a 100 millisecond timer and a first step of 20 as defined by +; InstallProgressFirstStep . +!define /math InstallPaveOverTotalSteps ${InstallProgressFirstStep} + 1800 + +; On Vista and above attempt to elevate Standard Users in addition to users that +; are a member of the Administrators group. +!define NONADMIN_ELEVATE + +!define CONFIG_INI "config.ini" + +!ifndef FILE_SHARE_READ + !define FILE_SHARE_READ 1 +!endif +!ifndef GENERIC_READ + !define GENERIC_READ 0x80000000 +!endif +!ifndef OPEN_EXISTING + !define OPEN_EXISTING 3 +!endif +!ifndef INVALID_HANDLE_VALUE + !define INVALID_HANDLE_VALUE -1 +!endif + +!include "nsDialogs.nsh" +!include "LogicLib.nsh" +!include "FileFunc.nsh" +!include "TextFunc.nsh" +!include "WinVer.nsh" +!include "WordFunc.nsh" + +!insertmacro GetParameters +!insertmacro GetOptions +!insertmacro LineFind +!insertmacro StrFilter + +!include "locales.nsi" +!include "branding.nsi" + +!include "defines.nsi" + +; Must be included after defines.nsi +!include "locale-fonts.nsh" + +; The OFFICIAL define is a workaround to support different urls for Release and +; Beta since they share the same branding when building with other branches that +; set the update channel to beta. +!ifdef OFFICIAL +!ifdef BETA_UPDATE_CHANNEL +!undef URLStubDownload +!define URLStubDownload "http://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-beta-latest" +!undef URLManualDownload +!define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=beta&installer_lang=${AB_CD}" +!undef Channel +!define Channel "beta" +!endif +!endif + +!include "common.nsh" + +!insertmacro ElevateUAC +!insertmacro GetLongPath +!insertmacro GetPathFromString +!insertmacro GetParent +!insertmacro GetSingleInstallPath +!insertmacro GetTextWidthHeight +!insertmacro IsUserAdmin +!insertmacro RemovePrecompleteEntries +!insertmacro SetBrandNameVars +!insertmacro ITBL3Create +!insertmacro UnloadUAC + +VIAddVersionKey "FileDescription" "${BrandShortName} Stub Installer" +VIAddVersionKey "OriginalFilename" "setup-stub.exe" + +Name "$BrandFullName" +OutFile "setup-stub.exe" +icon "setup.ico" +XPStyle on +BrandingText " " +ChangeUI all "nsisui.exe" +!ifdef HAVE_64BIT_BUILD + InstallDir "$PROGRAMFILES64\${BrandFullName}\" +!else + InstallDir "$PROGRAMFILES32\${BrandFullName}\" +!endif + +!ifdef ${AB_CD}_rtl + LoadLanguageFile "locale-rtl.nlf" +!else + LoadLanguageFile "locale.nlf" +!endif + +!include "nsisstrings.nlf" + +!if "${AB_CD}" == "en-US" + ; Custom strings for en-US. This is done here so they aren't translated. + !include oneoff_en-US.nsh +!else + !define INTRO_BLURB "$(INTRO_BLURB1)" + !define INSTALL_BLURB1 "$(INSTALL_BLURB1)" + !define INSTALL_BLURB2 "$(INSTALL_BLURB2)" + !define INSTALL_BLURB3 "$(INSTALL_BLURB3)" +!endif + +Caption "$(WIN_CAPTION)" + +Page custom createDummy ; Needed to enable the Intro page's back button +Page custom createIntro leaveIntro ; Introduction page +Page custom createOptions leaveOptions ; Options page +Page custom createInstall ; Download / Installation page + +Function .onInit + ; Remove the current exe directory from the search order. + ; This only effects LoadLibrary calls and not implicitly loaded DLLs. + System::Call 'kernel32::SetDllDirectoryW(w "")' + + StrCpy $LANGUAGE 0 + ; This macro is used to set the brand name variables but the ini file method + ; isn't supported for the stub installer. + ${SetBrandNameVars} "$PLUGINSDIR\ignored.ini" + + ; Don't install on systems that don't support SSE2. The parameter value of + ; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the + ; SSE2 instruction set is available. + System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7" + +!ifdef HAVE_64BIT_BUILD + ; Restrict x64 builds from being installed on x86 and pre Win7 + ${Unless} ${RunningX64} + ${OrUnless} ${AtLeastWin7} + ${If} "$R7" == "0" + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" + ${Else} + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)" + ${EndIf} + MessageBox MB_OKCANCEL|MB_ICONSTOP "$R7" IDCANCEL +2 + ExecShell "open" "${URLSystemRequirements}" + Quit + ${EndUnless} + + SetRegView 64 +!else + StrCpy $R8 "0" + ${If} ${AtMostWin2000} + StrCpy $R8 "1" + ${EndIf} + + ${If} ${IsWinXP} + ${AndIf} ${AtMostServicePack} 1 + StrCpy $R8 "1" + ${EndIf} + + ${If} $R8 == "1" + ; XXX-rstrong - some systems failed the AtLeastWin2000 test that we + ; used to use for an unknown reason and likely fail the AtMostWin2000 + ; and possibly the IsWinXP test as well. To work around this also + ; check if the Windows NT registry Key exists and if it does if the + ; first char in CurrentVersion is equal to 3 (Windows NT 3.5 and + ; 3.5.1), 4 (Windows NT 4), or 5 (Windows 2000 and Windows XP). + StrCpy $R8 "" + ClearErrors + ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion" + StrCpy $R8 "$R8" 1 + ${If} ${Errors} + ${OrIf} "$R8" == "3" + ${OrIf} "$R8" == "4" + ${OrIf} "$R8" == "5" + ${If} "$R7" == "0" + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" + ${Else} + strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)" + ${EndIf} + MessageBox MB_OKCANCEL|MB_ICONSTOP "$R7" IDCANCEL +2 + ExecShell "open" "${URLSystemRequirements}" + Quit + ${EndIf} + ${EndUnless} +!endif + + ${If} "$R7" == "0" + MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_CPU_MSG)" IDCANCEL +2 + ExecShell "open" "${URLSystemRequirements}" + Quit + ${EndIf} + + ; Require elevation if the user can elevate + ${ElevateUAC} + +; The commands inside this ifndef are needed prior to NSIS 3.0a2 and can be +; removed after we require NSIS 3.0a2 or greater. +!ifndef NSIS_PACKEDVERSION + ${If} ${AtLeastWinVista} + System::Call 'user32::SetProcessDPIAware()' + ${EndIf} +!endif + + SetShellVarContext all ; Set SHCTX to HKLM + ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 + + ${If} "$R9" == "false" + SetShellVarContext current ; Set SHCTX to HKCU + ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 + + ${If} ${RunningX64} + ; In HKCU there is no WOW64 redirection, which means we may have gotten + ; the path to a 32-bit install even though we're 64-bit, or vice-versa. + ; In that case, just use the default path instead of offering an upgrade. + ; But only do that override if the existing install is in Program Files, + ; because that's the only place we can be sure is specific + ; to either 32 or 64 bit applications. + ; The WordFind syntax below searches for the first occurence of the + ; "delimiter" (the Program Files path) in the install path and returns + ; anything that appears before that. If nothing appears before that, + ; then the install is under Program Files (32 or 64). +!ifdef HAVE_64BIT_BUILD + ${WordFind} $R9 $PROGRAMFILES32 "+1{" $0 +!else + ${WordFind} $R9 $PROGRAMFILES64 "+1{" $0 +!endif + ${If} $0 == "" + StrCpy $R9 "false" + ${EndIf} + ${EndIf} + ${EndIf} + + ${If} "$R9" != "false" + StrCpy $INSTDIR "$R9" + ${EndIf} + + ; Used to determine if the default installation directory was used. + StrCpy $InitialInstallDir "$INSTDIR" + + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ + "Write Test" + + ; Only display set as default when there is write access to HKLM and on Win7 + ; and below. + ${If} ${Errors} + ${OrIf} ${AtLeastWin8} + StrCpy $CanSetAsDefault "false" + StrCpy $CheckboxSetAsDefault "0" + ${Else} + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + StrCpy $CanSetAsDefault "true" + ${EndIf} + + ; The interval in MS used for the progress bars set as marquee. + ${If} ${AtLeastWinVista} + StrCpy $ProgressbarMarqueeIntervalMS "10" + ${Else} + StrCpy $ProgressbarMarqueeIntervalMS "50" + ${EndIf} + + ; Initialize the majority of variables except those that need to be reset + ; when a page is displayed. + StrCpy $IntroPhaseSeconds "0" + StrCpy $OptionsPhaseSeconds "0" + StrCpy $EndPreInstallPhaseTickCount "0" + StrCpy $EndInstallPhaseTickCount "0" + StrCpy $InitialInstallRequirementsCode "" + StrCpy $IsDownloadFinished "" + StrCpy $FirefoxLaunchCode "0" + StrCpy $CheckboxShortcutOnBar "1" + StrCpy $CheckboxShortcutInStartMenu "1" + StrCpy $CheckboxShortcutOnDesktop "1" + StrCpy $CheckboxSendPing "1" +!ifdef MOZ_MAINTENANCE_SERVICE + StrCpy $CheckboxInstallMaintSvc "1" +!else + StrCpy $CheckboxInstallMaintSvc "0" +!endif + StrCpy $WasOptionsButtonClicked "0" + + StrCpy $0 "" +!ifdef FONT_FILE1 + ${If} ${FileExists} "$FONTS\${FONT_FILE1}" + StrCpy $0 "${FONT_NAME1}" + ${EndIf} +!endif + +!ifdef FONT_FILE2 + ${If} $0 == "" + ${AndIf} ${FileExists} "$FONTS\${FONT_FILE2}" + StrCpy $0 "${FONT_NAME2}" + ${EndIf} +!endif + + ${If} $0 == "" + StrCpy $0 "$(^Font)" + ${EndIf} + + CreateFont $FontBlurb "$0" "12" "500" + CreateFont $FontNormal "$0" "11" "500" + CreateFont $FontItalic "$0" "11" "500" /ITALIC + + InitPluginsDir + File /oname=$PLUGINSDIR\bgintro.bmp "bgintro.bmp" + File /oname=$PLUGINSDIR\appname.bmp "appname.bmp" + File /oname=$PLUGINSDIR\clock.bmp "clock.bmp" + File /oname=$PLUGINSDIR\particles.bmp "particles.bmp" +!ifdef ${AB_CD}_rtl + ; The horizontally flipped pencil looks better in RTL + File /oname=$PLUGINSDIR\pencil.bmp "pencil-rtl.bmp" +!else + File /oname=$PLUGINSDIR\pencil.bmp "pencil.bmp" +!endif +FunctionEnd + +; .onGUIInit isn't needed except for RTL locales +!ifdef ${AB_CD}_rtl +Function .onGUIInit + ; Since NSIS RTL support doesn't mirror progress bars use Windows mirroring. + ${NSD_AddExStyle} $HWNDPARENT ${WS_EX_LAYOUTRTL} + ${RemoveExStyle} $HWNDPARENT ${WS_EX_RTLREADING} + ${RemoveExStyle} $HWNDPARENT ${WS_EX_RIGHT} + ${NSD_AddExStyle} $HWNDPARENT ${WS_EX_LEFT}|${WS_EX_LTRREADING} +FunctionEnd +!endif + +Function .onGUIEnd + Delete "$PLUGINSDIR\_temp" + Delete "$PLUGINSDIR\download.exe" + Delete "$PLUGINSDIR\${CONFIG_INI}" + + ${UnloadUAC} +FunctionEnd + +Function .onUserAbort + ${NSD_KillTimer} StartDownload + ${NSD_KillTimer} OnDownload + ${NSD_KillTimer} CheckInstall + ${NSD_KillTimer} FinishInstall + ${NSD_KillTimer} FinishProgressBar + ${NSD_KillTimer} DisplayDownloadError + + ${If} "$IsDownloadFinished" != "" + Call DisplayDownloadError + ; Aborting the abort will allow SendPing which is called by + ; DisplayDownloadError to hide the installer window and close the installer + ; after it sends the metrics ping. + Abort + ${EndIf} +FunctionEnd + +Function SendPing + HideWindow + ; Try to send a ping if a download was attempted + ${If} $CheckboxSendPing == 1 + ${AndIf} $IsDownloadFinished != "" + ; Get the tick count for the completion of all phases. + System::Call "kernel32::GetTickCount()l .s" + Pop $EndFinishPhaseTickCount + + ; When the value of $IsDownloadFinished is false the download was started + ; but didn't finish. In this case the tick count stored in + ; $EndFinishPhaseTickCount is used to determine how long the download was + ; in progress. + ${If} "$IsDownloadFinished" == "false" + ${OrIf} "$EndDownloadPhaseTickCount" == "" + StrCpy $EndDownloadPhaseTickCount "$EndFinishPhaseTickCount" + ; Cancel the download in progress + InetBgDL::Get /RESET /END + ${EndIf} + + + ; When $DownloadFirstTransferSeconds equals an empty string the download + ; never successfully started so set the value to 0. It will be possible to + ; determine that the download didn't successfully start from the seconds for + ; the last download. + ${If} "$DownloadFirstTransferSeconds" == "" + StrCpy $DownloadFirstTransferSeconds "0" + ${EndIf} + + ; When $StartLastDownloadTickCount equals an empty string the download never + ; successfully started so set the value to $EndDownloadPhaseTickCount to + ; compute the correct value. + ${If} $StartLastDownloadTickCount == "" + ; This could happen if the download never successfully starts + StrCpy $StartLastDownloadTickCount "$EndDownloadPhaseTickCount" + ${EndIf} + + ; When $EndPreInstallPhaseTickCount equals 0 the installation phase was + ; never completed so set its value to $EndFinishPhaseTickCount to compute + ; the correct value. + ${If} "$EndPreInstallPhaseTickCount" == "0" + StrCpy $EndPreInstallPhaseTickCount "$EndFinishPhaseTickCount" + ${EndIf} + + ; When $EndInstallPhaseTickCount equals 0 the installation phase was never + ; completed so set its value to $EndFinishPhaseTickCount to compute the + ; correct value. + ${If} "$EndInstallPhaseTickCount" == "0" + StrCpy $EndInstallPhaseTickCount "$EndFinishPhaseTickCount" + ${EndIf} + + ; Get the seconds elapsed from the start of the download phase to the end of + ; the download phase. + ${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$EndDownloadPhaseTickCount" $0 + + ; Get the seconds elapsed from the start of the last download to the end of + ; the last download. + ${GetSecondsElapsed} "$StartLastDownloadTickCount" "$EndDownloadPhaseTickCount" $1 + + ; Get the seconds elapsed from the end of the download phase to the + ; completion of the pre-installation check phase. + ${GetSecondsElapsed} "$EndDownloadPhaseTickCount" "$EndPreInstallPhaseTickCount" $2 + + ; Get the seconds elapsed from the end of the pre-installation check phase + ; to the completion of the installation phase. + ${GetSecondsElapsed} "$EndPreInstallPhaseTickCount" "$EndInstallPhaseTickCount" $3 + + ; Get the seconds elapsed from the end of the installation phase to the + ; completion of all phases. + ${GetSecondsElapsed} "$EndInstallPhaseTickCount" "$EndFinishPhaseTickCount" $4 + +!ifdef HAVE_64BIT_BUILD + StrCpy $R0 "1" +!else + StrCpy $R0 "0" +!endif + + ${If} ${RunningX64} + StrCpy $R1 "1" + ${Else} + StrCpy $R1 "0" + ${EndIf} + + ; Though these values are sometimes incorrect due to bug 444664 it happens + ; so rarely it isn't worth working around it by reading the registry values. + ${WinVerGetMajor} $5 + ${WinVerGetMinor} $6 + ${WinVerGetBuild} $7 + ${WinVerGetServicePackLevel} $8 + ${If} ${IsServerOS} + StrCpy $9 "1" + ${Else} + StrCpy $9 "0" + ${EndIf} + + ${If} "$ExitCode" == "${ERR_SUCCESS}" + ReadINIStr $R5 "$INSTDIR\application.ini" "App" "Version" + ReadINIStr $R6 "$INSTDIR\application.ini" "App" "BuildID" + ${Else} + StrCpy $R5 "0" + StrCpy $R6 "0" + ${EndIf} + + ; Whether installed into the default installation directory + ${GetLongPath} "$INSTDIR" $R7 + ${GetLongPath} "$InitialInstallDir" $R8 + ${If} "$R7" == "$R8" + StrCpy $R7 "1" + ${Else} + StrCpy $R7 "0" + ${EndIf} + + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ + "Write Test" + ${If} ${Errors} + StrCpy $R8 "0" + ${Else} + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + StrCpy $R8 "1" + ${EndIf} + + ${If} "$DownloadServerIP" == "" + StrCpy $DownloadServerIP "Unknown" + ${EndIf} + + StrCpy $R2 "" + SetShellVarContext current ; Set SHCTX to the current user + ReadRegStr $R2 HKCU "Software\Classes\http\shell\open\command" "" + ${If} $R2 != "" + ${GetPathFromString} "$R2" $R2 + ${GetParent} "$R2" $R3 + ${GetLongPath} "$R3" $R3 + ${If} $R3 == $INSTDIR + StrCpy $R2 "1" ; This Firefox install is set as default. + ${Else} + StrCpy $R2 "$R2" "" -11 # length of firefox.exe + ${If} "$R2" == "${FileMainEXE}" + StrCpy $R2 "2" ; Another Firefox install is set as default. + ${Else} + StrCpy $R2 "0" + ${EndIf} + ${EndIf} + ${Else} + StrCpy $R2 "0" ; Firefox is not set as default. + ${EndIf} + + ${If} "$R2" == "0" + ${AndIf} ${AtLeastWinVista} + ; Check to see if this install location is currently set as the default + ; browser by Default Programs which is only available on Vista and above. + ClearErrors + ReadRegStr $R3 HKLM "Software\RegisteredApplications" "${AppRegName}" + ${Unless} ${Errors} + AppAssocReg::QueryAppIsDefaultAll "${AppRegName}" "effective" + Pop $R3 + ${If} $R3 == "1" + StrCpy $R3 "" + ReadRegStr $R2 HKLM "Software\Classes\http\shell\open\command" "" + ${If} $R2 != "" + ${GetPathFromString} "$R2" $R2 + ${GetParent} "$R2" $R3 + ${GetLongPath} "$R3" $R3 + ${If} $R3 == $INSTDIR + StrCpy $R2 "1" ; This Firefox install is set as default. + ${Else} + StrCpy $R2 "$R2" "" -11 # length of firefox.exe + ${If} "$R2" == "${FileMainEXE}" + StrCpy $R2 "2" ; Another Firefox install is set as default. + ${Else} + StrCpy $R2 "0" + ${EndIf} + ${EndIf} + ${Else} + StrCpy $R2 "0" ; Firefox is not set as default. + ${EndIf} + ${EndIf} + ${EndUnless} + ${EndIf} + + ${If} $CanSetAsDefault == "true" + ${If} $CheckboxSetAsDefault == "1" + StrCpy $R3 "2" + ${Else} + StrCpy $R3 "3" + ${EndIf} + ${Else} + ${If} ${AtLeastWin8} + StrCpy $R3 "1" + ${Else} + StrCpy $R3 "0" + ${EndIf} + ${EndIf} + +!ifdef STUB_DEBUG + MessageBox MB_OK "${BaseURLStubPing} \ + $\nStub URL Version = ${StubURLVersion}${StubURLVersionAppend} \ + $\nBuild Channel = ${Channel} \ + $\nUpdate Channel = ${UpdateChannel} \ + $\nLocale = ${AB_CD} \ + $\nFirefox x64 = $R0 \ + $\nRunning x64 Windows = $R1 \ + $\nMajor = $5 \ + $\nMinor = $6 \ + $\nBuild = $7 \ + $\nServicePack = $8 \ + $\nIsServer = $9 \ + $\nExit Code = $ExitCode \ + $\nFirefox Launch Code = $FirefoxLaunchCode \ + $\nDownload Retry Count = $DownloadRetryCount \ + $\nDownloaded Bytes = $DownloadedBytes \ + $\nDownload Size Bytes = $DownloadSizeBytes \ + $\nIntroduction Phase Seconds = $IntroPhaseSeconds \ + $\nOptions Phase Seconds = $OptionsPhaseSeconds \ + $\nDownload Phase Seconds = $0 \ + $\nLast Download Seconds = $1 \ + $\nDownload First Transfer Seconds = $DownloadFirstTransferSeconds \ + $\nPreinstall Phase Seconds = $2 \ + $\nInstall Phase Seconds = $3 \ + $\nFinish Phase Seconds = $4 \ + $\nInitial Install Requirements Code = $InitialInstallRequirementsCode \ + $\nOpened Download Page = $OpenedDownloadPage \ + $\nExisting Profile = $ExistingProfile \ + $\nExisting Version = $ExistingVersion \ + $\nExisting Build ID = $ExistingBuildID \ + $\nNew Version = $R5 \ + $\nNew Build ID = $R6 \ + $\nDefault Install Dir = $R7 \ + $\nHas Admin = $R8 \ + $\nDefault Status = $R2 \ + $\nSet As Sefault Status = $R3 \ + $\nDownload Server IP = $DownloadServerIP \ + $\nPost-Signing Data = $PostSigningData" + ; The following will exit the installer + SetAutoClose true + StrCpy $R9 "2" + Call RelativeGotoPage +!else + ${NSD_CreateTimer} OnPing ${DownloadIntervalMS} + 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/$PostSigningData" \ + "$PLUGINSDIR\_temp" /END +!endif + ${Else} + ${If} "$IsDownloadFinished" == "false" + ; Cancel the download in progress + InetBgDL::Get /RESET /END + ${EndIf} + ; The following will exit the installer + SetAutoClose true + StrCpy $R9 "2" + Call RelativeGotoPage + ${EndIf} +FunctionEnd + +Function createDummy +FunctionEnd + +Function createIntro + nsDialogs::Create /NOUNLOAD 1018 + Pop $Dialog + + GetFunctionAddress $0 OnBack + nsDialogs::OnBack /NOUNLOAD $0 + +!ifdef ${AB_CD}_rtl + ; For RTL align the text with the top of the F in the Firefox bitmap + StrCpy $0 "${INTRO_BLURB_RTL_TOP_DU}" +!else + ; For LTR align the text with the top of the x in the Firefox bitmap + StrCpy $0 "${INTRO_BLURB_LTR_TOP_DU}" +!endif + ${NSD_CreateLabel} ${INTRO_BLURB_EDGE_DU} $0 ${INTRO_BLURB_WIDTH_DU} 76u "${INTRO_BLURB}" + Pop $0 + SendMessage $0 ${WM_SETFONT} $FontBlurb 0 + SetCtlColors $0 ${INTRO_BLURB_TEXT_COLOR} transparent + + SetCtlColors $HWNDPARENT ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR} + GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox + ${If} "$CanSetAsDefault" == "true" + ; The uxtheme must be disabled on checkboxes in order to override the + ; system font color. + System::Call 'uxtheme::SetWindowTheme(i $0 , w " ", w " ")' + SendMessage $0 ${WM_SETFONT} $FontNormal 0 + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(MAKE_DEFAULT)" + SendMessage $0 ${BM_SETCHECK} 1 0 + SetCtlColors $0 ${FOOTER_CONTROL_TEXT_COLOR_NORMAL} ${FOOTER_BKGRD_COLOR} + ${Else} + ShowWindow $0 ${SW_HIDE} + ${EndIf} + GetDlgItem $0 $HWNDPARENT 11 + ShowWindow $0 ${SW_HIDE} + + ${NSD_CreateBitmap} ${APPNAME_BMP_EDGE_DU} ${APPNAME_BMP_TOP_DU} \ + ${APPNAME_BMP_WIDTH_DU} ${APPNAME_BMP_HEIGHT_DU} "" + Pop $2 + ${SetStretchedTransparentImage} $2 $PLUGINSDIR\appname.bmp $0 + + ${NSD_CreateBitmap} 0 0 100% 100% "" + Pop $2 + ${NSD_SetStretchedImage} $2 $PLUGINSDIR\bgintro.bmp $1 + + GetDlgItem $0 $HWNDPARENT 1 ; Install button + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" + ${Else} + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)" + ${EndIf} + ${NSD_SetFocus} $0 + + GetDlgItem $0 $HWNDPARENT 2 ; Cancel button + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)" + + GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(OPTIONS_BUTTON)" + + System::Call "kernel32::GetTickCount()l .s" + Pop $StartIntroPhaseTickCount + + LockWindow off + nsDialogs::Show + + ${NSD_FreeImage} $0 + ${NSD_FreeImage} $1 +FunctionEnd + +Function leaveIntro + LockWindow on + + System::Call "kernel32::GetTickCount()l .s" + Pop $0 + ${GetSecondsElapsed} "$StartIntroPhaseTickCount" "$0" $IntroPhaseSeconds + ; It is possible for this value to be 0 if the user clicks fast enough so + ; increment the value by 1 if it is 0. + ${If} $IntroPhaseSeconds == 0 + IntOp $IntroPhaseSeconds $IntroPhaseSeconds + 1 + ${EndIf} + + SetShellVarContext all ; Set SHCTX to All Users + ; If the user doesn't have write access to the installation directory set + ; the installation directory to a subdirectory of the All Users application + ; directory and if the user can't write to that location set the installation + ; directory to a subdirectory of the users local application directory + ; (e.g. non-roaming). + Call CanWrite + ${If} "$CanWriteToInstallDir" == "false" + StrCpy $INSTDIR "$APPDATA\${BrandFullName}\" + Call CanWrite + ${If} "$CanWriteToInstallDir" == "false" + ; This should never happen but just in case. + StrCpy $CanWriteToInstallDir "false" + ${Else} + StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\" + Call CanWrite + ${EndIf} + ${EndIf} + + Call CheckSpace + + ${If} ${FileExists} "$INSTDIR" + ; Always display the long path if the path exists. + ${GetLongPath} "$INSTDIR" $INSTDIR + ${EndIf} + +FunctionEnd + +Function createOptions + ; Check whether the install requirements are satisfied using the default + ; values for metrics. + ${If} "$InitialInstallRequirementsCode" == "" + ${If} "$CanWriteToInstallDir" != "true" + ${AndIf} "$HasRequiredSpaceAvailable" != "true" + StrCpy $InitialInstallRequirementsCode "1" + ${ElseIf} "$CanWriteToInstallDir" != "true" + StrCpy $InitialInstallRequirementsCode "2" + ${ElseIf} "$HasRequiredSpaceAvailable" != "true" + StrCpy $InitialInstallRequirementsCode "3" + ${Else} + StrCpy $InitialInstallRequirementsCode "0" + ${EndIf} + ${EndIf} + + ; Skip the options page unless the Options button was clicked as long as the + ; installation directory can be written to and there is the minimum required + ; space available. + ${If} "$WasOptionsButtonClicked" != "1" + ${If} "$CanWriteToInstallDir" == "true" + ${AndIf} "$HasRequiredSpaceAvailable" == "true" + Abort ; Skip the options page + ${EndIf} + ${EndIf} + + StrCpy $ExistingTopDir "" + + nsDialogs::Create /NOUNLOAD 1018 + Pop $Dialog + ; Since the text color for controls is set in this Dialog the foreground and + ; background colors of the Dialog must also be hardcoded. + SetCtlColors $Dialog ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + + ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 18u ${OPTIONS_ITEM_WIDTH_DU} \ + 12u "$(CREATE_SHORTCUTS)" + Pop $0 + SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $0 ${WM_SETFONT} $FontNormal 0 + + ${If} ${AtLeastWin7} + StrCpy $0 "$(ADD_SC_TASKBAR)" + ${Else} + StrCpy $0 "$(ADD_SC_QUICKLAUNCHBAR)" + ${EndIf} + ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 38u \ + ${OPTIONS_SUBITEM_WIDTH_DU} 12u "$0" + Pop $CheckboxShortcutOnBar + ; The uxtheme must be disabled on checkboxes in order to override the system + ; font color. + System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutOnBar, w " ", w " ")' + SetCtlColors $CheckboxShortcutOnBar ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxShortcutOnBar ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxShortcutOnBar + + ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 54u ${OPTIONS_SUBITEM_WIDTH_DU} \ + 12u "$(ADD_CheckboxShortcutInStartMenu)" + Pop $CheckboxShortcutInStartMenu + ; The uxtheme must be disabled on checkboxes in order to override the system + ; font color. + System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutInStartMenu, w " ", w " ")' + SetCtlColors $CheckboxShortcutInStartMenu ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxShortcutInStartMenu ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxShortcutInStartMenu + + ${NSD_CreateCheckbox} ${OPTIONS_SUBITEM_EDGE_DU} 70u ${OPTIONS_SUBITEM_WIDTH_DU} \ + 12u "$(ADD_CheckboxShortcutOnDesktop)" + Pop $CheckboxShortcutOnDesktop + ; The uxtheme must be disabled on checkboxes in order to override the system + ; font color. + System::Call 'uxtheme::SetWindowTheme(i $CheckboxShortcutOnDesktop, w " ", w " ")' + SetCtlColors $CheckboxShortcutOnDesktop ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxShortcutOnDesktop ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxShortcutOnDesktop + + ${NSD_CreateLabel} ${OPTIONS_ITEM_EDGE_DU} 100u ${OPTIONS_ITEM_WIDTH_DU} \ + 12u "$(DEST_FOLDER)" + Pop $0 + SetCtlColors $0 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $0 ${WM_SETFONT} $FontNormal 0 + + ${NSD_CreateDirRequest} ${OPTIONS_SUBITEM_EDGE_DU} 116u 159u 14u "$INSTDIR" + Pop $DirRequest + SetCtlColors $DirRequest ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $DirRequest ${WM_SETFONT} $FontNormal 0 + System::Call shlwapi::SHAutoComplete(i $DirRequest, i ${SHACF_FILESYSTEM}) + ${NSD_OnChange} $DirRequest OnChange_DirRequest + +!ifdef ${AB_CD}_rtl + ; Remove the RTL styling from the directory request text box + ${RemoveStyle} $DirRequest ${SS_RIGHT} + ${RemoveExStyle} $DirRequest ${WS_EX_RIGHT} + ${RemoveExStyle} $DirRequest ${WS_EX_RTLREADING} + ${NSD_AddStyle} $DirRequest ${SS_LEFT} + ${NSD_AddExStyle} $DirRequest ${WS_EX_LTRREADING}|${WS_EX_LEFT} +!endif + + ${NSD_CreateBrowseButton} 280u 116u 50u 14u "$(BROWSE_BUTTON)" + Pop $ButtonBrowse + SetCtlColors $ButtonBrowse "" ${COMMON_BKGRD_COLOR} + ${NSD_OnClick} $ButtonBrowse OnClick_ButtonBrowse + + ; Get the number of pixels from the left of the Dialog to the right side of + ; the "Space Required:" and "Space Available:" labels prior to setting RTL so + ; the correct position of the controls can be set by NSIS for RTL locales. + + ; Get the width and height of both labels and use the tallest for the height + ; and the widest to calculate where to place the labels after these labels. + ${GetTextExtent} "$(SPACE_REQUIRED)" $FontItalic $0 $1 + ${GetTextExtent} "$(SPACE_AVAILABLE)" $FontItalic $2 $3 + ${If} $1 > $3 + StrCpy $ControlHeightPX "$1" + ${Else} + StrCpy $ControlHeightPX "$3" + ${EndIf} + + IntOp $0 $0 + 8 ; Add padding to the control's width + ; Make both controls the same width as the widest control + ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 134u $0 $ControlHeightPX "$(SPACE_REQUIRED)" + Pop $5 + SetCtlColors $5 ${COMMON_TEXT_COLOR_FADED} ${COMMON_BKGRD_COLOR} + SendMessage $5 ${WM_SETFONT} $FontItalic 0 + + IntOp $2 $2 + 8 ; Add padding to the control's width + ${NSD_CreateLabelCenter} ${OPTIONS_SUBITEM_EDGE_DU} 145u $2 $ControlHeightPX "$(SPACE_AVAILABLE)" + Pop $6 + SetCtlColors $6 ${COMMON_TEXT_COLOR_FADED} ${COMMON_BKGRD_COLOR} + SendMessage $6 ${WM_SETFONT} $FontItalic 0 + + ; Use the widest label for aligning the labels next to them + ${If} $0 > $2 + StrCpy $6 "$5" + ${EndIf} + FindWindow $1 "#32770" "" $HWNDPARENT + ${GetDlgItemEndPX} $6 $ControlRightPX + + IntOp $ControlRightPX $ControlRightPX + 6 + + ${NSD_CreateLabel} $ControlRightPX 134u 100% $ControlHeightPX \ + "${APPROXIMATE_REQUIRED_SPACE_MB} $(MEGA)$(BYTE)" + Pop $7 + SetCtlColors $7 ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $7 ${WM_SETFONT} $FontNormal 0 + + ; Create the free space label with an empty string and update it by calling + ; UpdateFreeSpaceLabel + ${NSD_CreateLabel} $ControlRightPX 145u 100% $ControlHeightPX " " + Pop $LabelFreeSpace + SetCtlColors $LabelFreeSpace ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $LabelFreeSpace ${WM_SETFONT} $FontNormal 0 + + Call UpdateFreeSpaceLabel + + ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 168u ${OPTIONS_SUBITEM_WIDTH_DU} \ + 12u "$(SEND_PING)" + Pop $CheckboxSendPing + ; The uxtheme must be disabled on checkboxes in order to override the system + ; font color. + System::Call 'uxtheme::SetWindowTheme(i $CheckboxSendPing, w " ", w " ")' + SetCtlColors $CheckboxSendPing ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxSendPing ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxSendPing + +!ifdef MOZ_MAINTENANCE_SERVICE + ; We can only install the maintenance service if the user is an admin. + Call IsUserAdmin + Pop $0 + + ; Only show the maintenance service checkbox if we're on XP SP3 or higher; + ; we don't ever want to install it on XP without at least SP3 installed. + ${If} $0 == "true" + ${AndIf} ${IsWinXP} + ${AndIf} ${AtMostServicePack} 2 + StrCpy $0 "false" + ${EndIf} + + ; Only show the maintenance service checkbox if we have write access to HKLM + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ + "Write Test" + ${If} ${Errors} + ${OrIf} $0 != "true" + StrCpy $CheckboxInstallMaintSvc "0" + ${Else} + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + ; Read the registry instead of using ServicesHelper::IsInstalled so the + ; plugin isn't included in the stub installer to lessen its size. + ClearErrors + ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\services\MozillaMaintenance" "ImagePath" + ${If} ${Errors} + ${NSD_CreateCheckbox} ${OPTIONS_ITEM_EDGE_DU} 184u ${OPTIONS_ITEM_WIDTH_DU} \ + 12u "$(INSTALL_MAINT_SERVICE)" + Pop $CheckboxInstallMaintSvc + System::Call 'uxtheme::SetWindowTheme(i $CheckboxInstallMaintSvc, w " ", w " ")' + SetCtlColors $CheckboxInstallMaintSvc ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + SendMessage $CheckboxInstallMaintSvc ${WM_SETFONT} $FontNormal 0 + ${NSD_Check} $CheckboxInstallMaintSvc + ${EndIf} + ${EndIf} +!endif + + GetDlgItem $0 $HWNDPARENT 1 ; Install button + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" + ${Else} + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)" + ${EndIf} + ${NSD_SetFocus} $0 + + GetDlgItem $0 $HWNDPARENT 2 ; Cancel button + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)" + + GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options + EnableWindow $0 0 + ShowWindow $0 ${SW_HIDE} + + ; If the option button was not clicked display the reason for what needs to be + ; resolved to continue the installation. + ${If} "$WasOptionsButtonClicked" != "1" + ${If} "$CanWriteToInstallDir" == "false" + MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS)" + ${ElseIf} "$HasRequiredSpaceAvailable" == "false" + MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE)" + ${EndIf} + ${EndIf} + + System::Call "kernel32::GetTickCount()l .s" + Pop $StartOptionsPhaseTickCount + + LockWindow off + nsDialogs::Show +FunctionEnd + +Function leaveOptions + LockWindow on + + ${GetRoot} "$INSTDIR" $0 + ${GetLongPath} "$INSTDIR" $INSTDIR + ${GetLongPath} "$0" $0 + ${If} "$INSTDIR" == "$0" + LockWindow off + MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_ROOT_INSTALL)" + Abort ; Stay on the page + ${EndIf} + + Call CanWrite + ${If} "$CanWriteToInstallDir" == "false" + LockWindow off + MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS)" + Abort ; Stay on the page + ${EndIf} + + Call CheckSpace + ${If} "$HasRequiredSpaceAvailable" == "false" + LockWindow off + MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE)" + Abort ; Stay on the page + ${EndIf} + + System::Call "kernel32::GetTickCount()l .s" + Pop $0 + ${GetSecondsElapsed} "$StartOptionsPhaseTickCount" "$0" $OptionsPhaseSeconds + ; It is possible for this value to be 0 if the user clicks fast enough so + ; increment the value by 1 if it is 0. + ${If} $OptionsPhaseSeconds == 0 + IntOp $OptionsPhaseSeconds $OptionsPhaseSeconds + 1 + ${EndIf} + + ${NSD_GetState} $CheckboxShortcutOnBar $CheckboxShortcutOnBar + ${NSD_GetState} $CheckboxShortcutInStartMenu $CheckboxShortcutInStartMenu + ${NSD_GetState} $CheckboxShortcutOnDesktop $CheckboxShortcutOnDesktop + ${NSD_GetState} $CheckboxSendPing $CheckboxSendPing +!ifdef MOZ_MAINTENANCE_SERVICE + ${NSD_GetState} $CheckboxInstallMaintSvc $CheckboxInstallMaintSvc +!endif + +FunctionEnd + +Function createInstall + nsDialogs::Create /NOUNLOAD 1018 + Pop $Dialog + ; Since the text color for controls is set in this Dialog the foreground and + ; background colors of the Dialog must also be hardcoded. + SetCtlColors $Dialog ${COMMON_TEXT_COLOR_NORMAL} ${COMMON_BKGRD_COLOR} + + ${NSD_CreateLabel} 0 0 49u 64u "" + Pop $0 + ${GetDlgItemWidthHeight} $0 $1 $2 + System::Call 'user32::DestroyWindow(i r0)' + + ${NSD_CreateLabel} 0 0 11u 16u "" + Pop $0 + ${GetDlgItemWidthHeight} $0 $3 $4 + System::Call 'user32::DestroyWindow(i r0)' + + FindWindow $7 "#32770" "" $HWNDPARENT + ${GetDlgItemWidthHeight} $7 $8 $9 + + ; Allow a maximum text width of half of the Dialog's width + IntOp $R0 $8 / 2 + + ${GetTextWidthHeight} "${INSTALL_BLURB1}" $FontBlurb $R0 $5 $6 + IntOp $R1 $1 + $3 + IntOp $R1 $R1 + $5 + IntOp $R1 $8 - $R1 + IntOp $R1 $R1 / 2 + ${NSD_CreateBitmap} $R1 ${INSTALL_BLURB_TOP_DU} 49u 64u "" + Pop $BitmapBlurb1 + ${SetStretchedTransparentImage} $BitmapBlurb1 $PLUGINSDIR\clock.bmp $HwndBitmapBlurb1 + IntOp $R1 $R1 + $1 + IntOp $R1 $R1 + $3 + ${NSD_CreateLabel} $R1 ${INSTALL_BLURB_TOP_DU} $5 $6 "${INSTALL_BLURB1}" + Pop $LabelBlurb1 + SendMessage $LabelBlurb1 ${WM_SETFONT} $FontBlurb 0 + SetCtlColors $LabelBlurb1 ${INSTALL_BLURB_TEXT_COLOR} transparent + + ${GetTextWidthHeight} "${INSTALL_BLURB2}" $FontBlurb $R0 $5 $6 + IntOp $R1 $1 + $3 + IntOp $R1 $R1 + $5 + IntOp $R1 $8 - $R1 + IntOp $R1 $R1 / 2 + ${NSD_CreateBitmap} $R1 ${INSTALL_BLURB_TOP_DU} 49u 64u "" + Pop $BitmapBlurb2 + ${SetStretchedTransparentImage} $BitmapBlurb2 $PLUGINSDIR\particles.bmp $HwndBitmapBlurb2 + IntOp $R1 $R1 + $1 + IntOp $R1 $R1 + $3 + ${NSD_CreateLabel} $R1 ${INSTALL_BLURB_TOP_DU} $5 $6 "${INSTALL_BLURB2}" + Pop $LabelBlurb2 + SendMessage $LabelBlurb2 ${WM_SETFONT} $FontBlurb 0 + SetCtlColors $LabelBlurb2 ${INSTALL_BLURB_TEXT_COLOR} transparent + ShowWindow $BitmapBlurb2 ${SW_HIDE} + ShowWindow $LabelBlurb2 ${SW_HIDE} + + ${GetTextWidthHeight} "${INSTALL_BLURB3}" $FontBlurb $R0 $5 $6 + IntOp $R1 $1 + $3 + IntOp $R1 $R1 + $5 + IntOp $R1 $8 - $R1 + IntOp $R1 $R1 / 2 + ${NSD_CreateBitmap} $R1 ${INSTALL_BLURB_TOP_DU} 49u 64u "" + Pop $BitmapBlurb3 + ${SetStretchedTransparentImage} $BitmapBlurb3 $PLUGINSDIR\pencil.bmp $HWndBitmapBlurb3 + IntOp $R1 $R1 + $1 + IntOp $R1 $R1 + $3 + ${NSD_CreateLabel} $R1 ${INSTALL_BLURB_TOP_DU} $5 $6 "${INSTALL_BLURB3}" + Pop $LabelBlurb3 + SendMessage $LabelBlurb3 ${WM_SETFONT} $FontBlurb 0 + SetCtlColors $LabelBlurb3 ${INSTALL_BLURB_TEXT_COLOR} transparent + ShowWindow $BitmapBlurb3 ${SW_HIDE} + ShowWindow $LabelBlurb3 ${SW_HIDE} + + ${NSD_CreateProgressBar} 103u 166u 241u 9u "" + Pop $Progressbar + ${NSD_AddStyle} $Progressbar ${PBS_MARQUEE} + SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \ + $ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N + + ${NSD_CreateLabelCenter} 103u 180u 241u 20u "$(DOWNLOADING_LABEL)" + Pop $LabelDownloading + SendMessage $LabelDownloading ${WM_SETFONT} $FontNormal 0 + SetCtlColors $LabelDownloading ${INSTALL_PROGRESS_TEXT_COLOR_NORMAL} transparent + + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + ${NSD_CreateLabelCenter} 103u 180u 241u 20u "$(UPGRADING_LABEL)" + ${Else} + ${NSD_CreateLabelCenter} 103u 180u 241u 20u "$(INSTALLING_LABEL)" + ${EndIf} + Pop $LabelInstalling + SendMessage $LabelInstalling ${WM_SETFONT} $FontNormal 0 + SetCtlColors $LabelInstalling ${INSTALL_PROGRESS_TEXT_COLOR_NORMAL} transparent + ShowWindow $LabelInstalling ${SW_HIDE} + + ${NSD_CreateBitmap} ${APPNAME_BMP_EDGE_DU} ${APPNAME_BMP_TOP_DU} \ + ${APPNAME_BMP_WIDTH_DU} ${APPNAME_BMP_HEIGHT_DU} "" + Pop $2 + ${SetStretchedTransparentImage} $2 $PLUGINSDIR\appname.bmp $0 + + GetDlgItem $0 $HWNDPARENT 1 ; Install button + EnableWindow $0 0 + ShowWindow $0 ${SW_HIDE} + + GetDlgItem $0 $HWNDPARENT 3 ; Back button used for Options + EnableWindow $0 0 + ShowWindow $0 ${SW_HIDE} + + GetDlgItem $0 $HWNDPARENT 2 ; Cancel button + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(CANCEL_BUTTON)" + ; Focus the Cancel button otherwise it isn't possible to tab to it since it is + ; the only control that can be tabbed to. + ${NSD_SetFocus} $0 + ; Kill the Cancel button's focus so pressing enter won't cancel the install. + SendMessage $0 ${WM_KILLFOCUS} 0 0 + + ${If} "$CanSetAsDefault" == "true" + GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox + SendMessage $0 ${BM_GETCHECK} 0 0 $CheckboxSetAsDefault + EnableWindow $0 0 + ShowWindow $0 ${SW_HIDE} + ${EndIf} + + GetDlgItem $0 $HWNDPARENT 11 + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(ONE_MOMENT_UPGRADE)" + ${Else} + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(ONE_MOMENT_INSTALL)" + ${EndIf} + SendMessage $0 ${WM_SETFONT} $FontNormal 0 + SetCtlColors $0 ${FOOTER_CONTROL_TEXT_COLOR_FADED} ${FOOTER_BKGRD_COLOR} + ShowWindow $0 ${SW_SHOW} + + ; Set $DownloadReset to true so the first download tick count is measured. + StrCpy $DownloadReset "true" + StrCpy $IsDownloadFinished "false" + StrCpy $DownloadRetryCount "0" + StrCpy $DownloadedBytes "0" + StrCpy $StartLastDownloadTickCount "" + StrCpy $EndDownloadPhaseTickCount "" + StrCpy $DownloadFirstTransferSeconds "" + StrCpy $ExitCode "${ERR_DOWNLOAD_CANCEL}" + StrCpy $OpenedDownloadPage "0" + + ClearErrors + ReadINIStr $ExistingVersion "$INSTDIR\application.ini" "App" "Version" + ${If} ${Errors} + StrCpy $ExistingVersion "0" + ${EndIf} + + ClearErrors + ReadINIStr $ExistingBuildID "$INSTDIR\application.ini" "App" "BuildID" + ${If} ${Errors} + StrCpy $ExistingBuildID "0" + ${EndIf} + + ${If} ${FileExists} "$LOCALAPPDATA\Mozilla\Firefox" + StrCpy $ExistingProfile "1" + ${Else} + StrCpy $ExistingProfile "0" + ${EndIf} + + StrCpy $DownloadServerIP "" + + System::Call "kernel32::GetTickCount()l .s" + Pop $StartDownloadPhaseTickCount + + ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log" + StrCpy $InstallTotalSteps ${InstallPaveOverTotalSteps} + ${Else} + StrCpy $InstallTotalSteps ${InstallCleanTotalSteps} + ${EndIf} + + ${ITBL3Create} + ${ITBL3SetProgressState} "${TBPF_INDETERMINATE}" + + ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} + + LockWindow off + nsDialogs::Show + + ${NSD_FreeImage} $0 + ${NSD_FreeImage} $HwndBitmapBlurb1 + ${NSD_FreeImage} $HwndBitmapBlurb2 + ${NSD_FreeImage} $HWndBitmapBlurb3 +FunctionEnd + +Function StartDownload + ${NSD_KillTimer} StartDownload + InetBgDL::Get "${URLStubDownload}${URLStubDownloadAppend}" "$PLUGINSDIR\download.exe" \ + /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END + StrCpy $4 "" + ${NSD_CreateTimer} OnDownload ${DownloadIntervalMS} + ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" + RmDir /r "$INSTDIR\${TO_BE_DELETED}" + ${EndIf} +FunctionEnd + +Function SetProgressBars + SendMessage $Progressbar ${PBM_SETPOS} $ProgressCompleted 0 + ${ITBL3SetProgressValue} "$ProgressCompleted" "$ProgressTotal" +FunctionEnd + +Function RemoveFileProgressCallback + IntOp $InstallCounterStep $InstallCounterStep + 2 + System::Int64Op $ProgressCompleted + $InstallStepSize + Pop $ProgressCompleted + Call SetProgressBars + System::Int64Op $ProgressCompleted + $InstallStepSize + Pop $ProgressCompleted + Call SetProgressBars +FunctionEnd + +Function OnDownload + InetBgDL::GetStats + # $0 = HTTP status code, 0=Completed + # $1 = Completed files + # $2 = Remaining files + # $3 = Number of downloaded bytes for the current file + # $4 = Size of current file (Empty string if the size is unknown) + # /RESET must be used if status $0 > 299 (e.g. failure) + # When status is $0 =< 299 it is handled by InetBgDL + StrCpy $DownloadServerIP "$5" + ${If} $0 > 299 + ${NSD_KillTimer} OnDownload + IntOp $DownloadRetryCount $DownloadRetryCount + 1 + ${If} "$DownloadReset" != "true" + StrCpy $DownloadedBytes "0" + ${NSD_AddStyle} $Progressbar ${PBS_MARQUEE} + SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \ + $ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N + ${ITBL3SetProgressState} "${TBPF_INDETERMINATE}" + ${EndIf} + InetBgDL::Get /RESET /END + StrCpy $DownloadSizeBytes "" + StrCpy $DownloadReset "true" + + ${If} $DownloadRetryCount >= ${DownloadMaxRetries} + StrCpy $ExitCode "${ERR_DOWNLOAD_TOO_MANY_RETRIES}" + ; Use a timer so the UI has a chance to update + ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} + ${Else} + ${NSD_CreateTimer} StartDownload ${DownloadRetryIntervalMS} + ${EndIf} + Return + ${EndIf} + + ${If} "$DownloadReset" == "true" + System::Call "kernel32::GetTickCount()l .s" + Pop $StartLastDownloadTickCount + StrCpy $DownloadReset "false" + ; The seconds elapsed from the start of the download phase until the first + ; bytes are received are only recorded for the first request so it is + ; possible to determine connection issues for the first request. + ${If} "$DownloadFirstTransferSeconds" == "" + ; Get the seconds elapsed from the start of the download phase until the + ; first bytes are received. + ${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$StartLastDownloadTickCount" $DownloadFirstTransferSeconds + ${EndIf} + ${EndIf} + + ${If} "$DownloadSizeBytes" == "" + ${AndIf} "$4" != "" + ; Handle the case where the size of the file to be downloaded is less than + ; the minimum expected size or greater than the maximum expected size at the + ; beginning of the download. + ${If} $4 < ${DownloadMinSizeBytes} + ${OrIf} $4 > ${DownloadMaxSizeBytes} + ${NSD_KillTimer} OnDownload + InetBgDL::Get /RESET /END + StrCpy $DownloadReset "true" + + ${If} $DownloadRetryCount >= ${DownloadMaxRetries} + ; Use a timer so the UI has a chance to update + ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} + ${Else} + ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} + ${EndIf} + Return + ${EndIf} + + StrCpy $DownloadSizeBytes "$4" + System::Int64Op $4 / 2 + Pop $HalfOfDownload + System::Int64Op $HalfOfDownload / $InstallTotalSteps + Pop $InstallStepSize + SendMessage $Progressbar ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N + ${RemoveStyle} $Progressbar ${PBS_MARQUEE} + System::Int64Op $HalfOfDownload + $DownloadSizeBytes + Pop $ProgressTotal + StrCpy $ProgressCompleted 0 + SendMessage $Progressbar ${PBM_SETRANGE32} $ProgressCompleted $ProgressTotal + ${EndIf} + + ; Don't update the status until after the download starts + ${If} $2 != 0 + ${AndIf} "$4" == "" + Return + ${EndIf} + + ; Handle the case where the downloaded size is greater than the maximum + ; expected size during the download. + ${If} $DownloadedBytes > ${DownloadMaxSizeBytes} + InetBgDL::Get /RESET /END + StrCpy $DownloadReset "true" + + ${If} $DownloadRetryCount >= ${DownloadMaxRetries} + ; Use a timer so the UI has a chance to update + ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} + ${Else} + ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} + ${EndIf} + Return + ${EndIf} + + ${If} $IsDownloadFinished != "true" + ${If} $2 == 0 + ${NSD_KillTimer} OnDownload + StrCpy $IsDownloadFinished "true" + ; The first step of the install progress bar is determined by the + ; InstallProgressFirstStep define and provides the user with immediate + ; feedback. + StrCpy $InstallCounterStep "${InstallProgressFirstStep}" + System::Call "kernel32::GetTickCount()l .s" + Pop $EndDownloadPhaseTickCount + + StrCpy $DownloadedBytes "$DownloadSizeBytes" + + ; When a download has finished handle the case where the downloaded size + ; is less than the minimum expected size or greater than the maximum + ; expected size during the download. + ${If} $DownloadedBytes < ${DownloadMinSizeBytes} + ${OrIf} $DownloadedBytes > ${DownloadMaxSizeBytes} + InetBgDL::Get /RESET /END + StrCpy $DownloadReset "true" + + ${If} $DownloadRetryCount >= ${DownloadMaxRetries} + ; Use a timer so the UI has a chance to update + ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} + ${Else} + ${NSD_CreateTimer} StartDownload ${DownloadIntervalMS} + ${EndIf} + Return + ${EndIf} + + LockWindow on + ; Update the progress bars first in the UI change so they take affect + ; before other UI changes. + StrCpy $ProgressCompleted "$DownloadSizeBytes" + Call SetProgressBars + System::Int64Op $InstallStepSize * ${InstallProgressFirstStep} + Pop $R9 + System::Int64Op $ProgressCompleted + $R9 + Pop $ProgressCompleted + Call SetProgressBars + ShowWindow $LabelDownloading ${SW_HIDE} + ShowWindow $LabelInstalling ${SW_SHOW} + ShowWindow $LabelBlurb2 ${SW_HIDE} + ShowWindow $BitmapBlurb2 ${SW_HIDE} + ShowWindow $LabelBlurb3 ${SW_SHOW} + ShowWindow $BitmapBlurb3 ${SW_SHOW} + ; Disable the Cancel button during the install + GetDlgItem $5 $HWNDPARENT 2 + EnableWindow $5 0 + LockWindow off + + ; Open a handle to prevent modification of the full installer + StrCpy $R9 "${INVALID_HANDLE_VALUE}" + System::Call 'kernel32::CreateFileW(w "$PLUGINSDIR\download.exe", \ + i ${GENERIC_READ}, \ + i ${FILE_SHARE_READ}, i 0, \ + i ${OPEN_EXISTING}, i 0, i 0) i .R9' + StrCpy $HandleDownload "$R9" + + ${If} $HandleDownload == ${INVALID_HANDLE_VALUE} + StrCpy $ExitCode "${ERR_PREINSTALL_INVALID_HANDLE}" + StrCpy $0 "0" + StrCpy $1 "0" + ${Else} + CertCheck::VerifyCertTrust "$PLUGINSDIR\download.exe" + Pop $0 + CertCheck::VerifyCertNameIssuer "$PLUGINSDIR\download.exe" \ + "${CertNameDownload}" "${CertIssuerDownload}" + Pop $1 + ${If} $0 == 0 + ${AndIf} $1 == 0 + StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES}" + ${ElseIf} $0 == 0 + StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED}" + ${ElseIf} $1 == 0 + StrCpy $ExitCode "${ERR_PREINSTALL_CERT_ATTRIBUTES}" + ${EndIf} + ${EndIf} + + System::Call "kernel32::GetTickCount()l .s" + Pop $EndPreInstallPhaseTickCount + + ${If} $0 == 0 + ${OrIf} $1 == 0 + ; Use a timer so the UI has a chance to update + ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} + Return + ${EndIf} + + ; Instead of extracting the files we use the downloaded installer to + ; install in case it needs to perform operations that the stub doesn't + ; know about. + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "InstallDirectoryPath" "$INSTDIR" + ; Don't create the QuickLaunch or Taskbar shortcut from the launched installer + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "QuickLaunchShortcut" "false" + + ; Either avoid or force adding a taskbar pin based on the checkbox value: + ${If} $CheckboxShortcutOnBar == 0 + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "false" + ${Else} + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "true" + ${EndIf} + + ${If} $CheckboxShortcutOnDesktop == 1 + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "true" + ${Else} + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "false" + ${EndIf} + + ${If} $CheckboxShortcutInStartMenu == 1 + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "true" + ${Else} + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "false" + ${EndIf} + +!ifdef MOZ_MAINTENANCE_SERVICE + ${If} $CheckboxInstallMaintSvc == 1 + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "true" + ${Else} + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false" + ${EndIf} +!else + WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false" +!endif + + ; Delete the taskbar shortcut history to ensure we do the right thing based on + ; the config file above. + ${GetShortcutsLogPath} $0 + Delete "$0" + + GetFunctionAddress $0 RemoveFileProgressCallback + ${RemovePrecompleteEntries} $0 + + ; Delete the install.log and let the full installer create it. When the + ; installer closes it we can detect that it has completed. + Delete "$INSTDIR\install.log" + + ; Delete firefox.exe.moz-upgrade and firefox.exe.moz-delete if it exists + ; since it being present will require an OS restart for the full + ; installer. + Delete "$INSTDIR\${FileMainEXE}.moz-upgrade" + Delete "$INSTDIR\${FileMainEXE}.moz-delete" + + System::Call "kernel32::GetTickCount()l .s" + Pop $EndPreInstallPhaseTickCount + + Exec "$\"$PLUGINSDIR\download.exe$\" /INI=$PLUGINSDIR\${CONFIG_INI}" + ${NSD_CreateTimer} CheckInstall ${InstallIntervalMS} + ${Else} + ${If} $HalfOfDownload != "true" + ${AndIf} $3 > $HalfOfDownload + StrCpy $HalfOfDownload "true" + LockWindow on + ShowWindow $LabelBlurb1 ${SW_HIDE} + ShowWindow $BitmapBlurb1 ${SW_HIDE} + ShowWindow $LabelBlurb2 ${SW_SHOW} + ShowWindow $BitmapBlurb2 ${SW_SHOW} + LockWindow off + ${EndIf} + StrCpy $DownloadedBytes "$3" + StrCpy $ProgressCompleted "$DownloadedBytes" + Call SetProgressBars + ${EndIf} + ${EndIf} +FunctionEnd + +Function OnPing + InetBgDL::GetStats + # $0 = HTTP status code, 0=Completed + # $1 = Completed files + # $2 = Remaining files + # $3 = Number of downloaded bytes for the current file + # $4 = Size of current file (Empty string if the size is unknown) + # /RESET must be used if status $0 > 299 (e.g. failure) + # When status is $0 =< 299 it is handled by InetBgDL + ${If} $2 == 0 + ${OrIf} $0 > 299 + ${NSD_KillTimer} OnPing + ${If} $0 > 299 + InetBgDL::Get /RESET /END + ${EndIf} + ; The following will exit the installer + SetAutoClose true + StrCpy $R9 "2" + Call RelativeGotoPage + ${EndIf} +FunctionEnd + +Function CheckInstall + IntOp $InstallCounterStep $InstallCounterStep + 1 + ${If} $InstallCounterStep >= $InstallTotalSteps + ${NSD_KillTimer} CheckInstall + ; Close the handle that prevents modification of the full installer + System::Call 'kernel32::CloseHandle(i $HandleDownload)' + StrCpy $ExitCode "${ERR_INSTALL_TIMEOUT}" + ; Use a timer so the UI has a chance to update + ${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS} + Return + ${EndIf} + + System::Int64Op $ProgressCompleted + $InstallStepSize + Pop $ProgressCompleted + Call SetProgressBars + + ${If} ${FileExists} "$INSTDIR\install.log" + Delete "$INSTDIR\install.tmp" + CopyFiles /SILENT "$INSTDIR\install.log" "$INSTDIR\install.tmp" + + ; The unfocus and refocus that happens approximately here is caused by the + ; installer calling SHChangeNotify to refresh the shortcut icons. + + ; When the full installer completes the installation the install.log will no + ; longer be in use. + ClearErrors + Delete "$INSTDIR\install.log" + ${Unless} ${Errors} + ${NSD_KillTimer} CheckInstall + ; Close the handle that prevents modification of the full installer + System::Call 'kernel32::CloseHandle(i $HandleDownload)' + Rename "$INSTDIR\install.tmp" "$INSTDIR\install.log" + Delete "$PLUGINSDIR\download.exe" + Delete "$PLUGINSDIR\${CONFIG_INI}" + System::Call "kernel32::GetTickCount()l .s" + Pop $EndInstallPhaseTickCount + System::Int64Op $InstallStepSize * ${InstallProgressFinishStep} + Pop $InstallStepSize + ${NSD_CreateTimer} FinishInstall ${InstallIntervalMS} + ${EndUnless} + ${EndIf} +FunctionEnd + +Function FinishInstall + ; The full installer has completed but the progress bar still needs to finish + ; so increase the size of the step. + IntOp $InstallCounterStep $InstallCounterStep + ${InstallProgressFinishStep} + ${If} $InstallTotalSteps < $InstallCounterStep + StrCpy $InstallCounterStep "$InstallTotalSteps" + ${EndIf} + + ${If} $InstallTotalSteps != $InstallCounterStep + System::Int64Op $ProgressCompleted + $InstallStepSize + Pop $ProgressCompleted + Call SetProgressBars + Return + ${EndIf} + + ${NSD_KillTimer} FinishInstall + + StrCpy $ProgressCompleted "$ProgressTotal" + Call SetProgressBars + + ${If} "$CheckboxSetAsDefault" == "1" + ; NB: this code is duplicated in installer.nsi. Please keep in sync. + ; For data migration in the app, we want to know what the default browser + ; value was before we changed it. To do so, we read it here and store it + ; in our own registry key. + StrCpy $0 "" + ${If} ${AtLeastWinVista} + AppAssocReg::QueryCurrentDefault "http" "protocol" "effective" + Pop $1 + ; If the method hasn't failed, $1 will contain the progid. Check: + ${If} "$1" != "method failed" + ${AndIf} "$1" != "method not available" + ; Read the actual command from the progid + ReadRegStr $0 HKCR "$1\shell\open\command" "" + ${EndIf} + ${EndIf} + ; If using the App Association Registry didn't happen or failed, fall back + ; to the effective http default: + ${If} "$0" == "" + ReadRegStr $0 HKCR "http\shell\open\command" "" + ${EndIf} + ; If we have something other than empty string now, write the value. + ${If} "$0" != "" + ClearErrors + WriteRegStr HKCU "Software\Mozilla\Firefox" "OldDefaultBrowserCommand" "$0" + ${EndIf} + + ${GetParameters} $0 + ClearErrors + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} ; Not elevated + Call ExecSetAsDefaultAppUser + ${Else} ; Elevated - execute the function in the unelevated process + GetFunctionAddress $0 ExecSetAsDefaultAppUser + UAC::ExecCodeSegment $0 + ${EndIf} + ${EndIf} + + ${If} $CheckboxShortcutOnBar == 1 + ${If} ${AtMostWinVista} + ClearErrors + ${GetParameters} $0 + ClearErrors + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} + Call AddQuickLaunchShortcut + ${Else} + GetFunctionAddress $0 AddQuickLaunchShortcut + UAC::ExecCodeSegment $0 + ${EndIf} + ${EndIf} + ${EndIf} + + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade" + Delete "$INSTDIR\${FileMainEXE}" + Rename "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}" + ${EndIf} + + StrCpy $ExitCode "${ERR_SUCCESS}" + + StrCpy $InstallCounterStep 0 + ${NSD_CreateTimer} FinishProgressBar ${InstallIntervalMS} +FunctionEnd + +Function FinishProgressBar + IntOp $InstallCounterStep $InstallCounterStep + 1 + + ${If} $InstallCounterStep < 10 + Return + ${EndIf} + + ${NSD_KillTimer} FinishProgressBar + + Call CopyPostSigningData + Call LaunchApp + Call SendPing +FunctionEnd + +Function OnBack + StrCpy $WasOptionsButtonClicked "1" + StrCpy $R9 "1" ; Goto the next page + Call RelativeGotoPage + ; The call to Abort prevents NSIS from trying to move to the previous or the + ; next page. + Abort +FunctionEnd + +Function RelativeGotoPage + IntCmp $R9 0 0 Move Move + StrCmp $R9 "X" 0 Move + StrCpy $R9 "120" + + Move: + SendMessage $HWNDPARENT "0x408" "$R9" "" +FunctionEnd + +Function UpdateFreeSpaceLabel + ; Only update when $ExistingTopDir isn't set + ${If} "$ExistingTopDir" != "" + StrLen $5 "$ExistingTopDir" + StrLen $6 "$INSTDIR" + ${If} $5 <= $6 + StrCpy $7 "$INSTDIR" $5 + ${If} "$7" == "$ExistingTopDir" + Return + ${EndIf} + ${EndIf} + ${EndIf} + + Call CheckSpace + + StrCpy $0 "$SpaceAvailableBytes" + + StrCpy $1 "$(BYTE)" + + ${If} $0 > 1024 + ${OrIf} $0 < 0 + System::Int64Op $0 / 1024 + Pop $0 + StrCpy $1 "$(KILO)$(BYTE)" + ${If} $0 > 1024 + ${OrIf} $0 < 0 + System::Int64Op $0 / 1024 + Pop $0 + StrCpy $1 "$(MEGA)$(BYTE)" + ${If} $0 > 1024 + ${OrIf} $0 < 0 + System::Int64Op $0 / 1024 + Pop $0 + StrCpy $1 "$(GIGA)$(BYTE)" + ${EndIf} + ${EndIf} + ${EndIf} + + SendMessage $LabelFreeSpace ${WM_SETTEXT} 0 "STR:$0 $1" +FunctionEnd + +Function OnChange_DirRequest + Pop $0 + System::Call 'user32::GetWindowTextW(i $DirRequest, w .r0, i ${NSIS_MAX_STRLEN})' + StrCpy $1 "$0" 1 ; the first character + ${If} "$1" == "$\"" + StrCpy $1 "$0" "" -1 ; the last character + ${If} "$1" == "$\"" + StrCpy $0 "$0" "" 1 ; all but the first character + StrCpy $0 "$0" -1 ; all but the last character + ${EndIf} + ${EndIf} + + StrCpy $INSTDIR "$0" + Call UpdateFreeSpaceLabel + + GetDlgItem $0 $HWNDPARENT 1 ; Install button + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(UPGRADE_BUTTON)" + ${Else} + SendMessage $0 ${WM_SETTEXT} 0 "STR:$(INSTALL_BUTTON)" + ${EndIf} +FunctionEnd + +Function OnClick_ButtonBrowse + StrCpy $0 "$INSTDIR" + nsDialogs::SelectFolderDialog /NOUNLOAD "$(SELECT_FOLDER_TEXT)" $0 + Pop $0 + ${If} $0 == "error" ; returns 'error' if 'cancel' was pressed? + Return + ${EndIf} + + ${If} $0 != "" + StrCpy $INSTDIR "$0" + System::Call 'user32::SetWindowTextW(i $DirRequest, w "$INSTDIR")' + ${EndIf} +FunctionEnd + +Function CheckSpace + ${If} "$ExistingTopDir" != "" + StrLen $0 "$ExistingTopDir" + StrLen $1 "$INSTDIR" + ${If} $0 <= $1 + StrCpy $2 "$INSTDIR" $3 + ${If} "$2" == "$ExistingTopDir" + Return + ${EndIf} + ${EndIf} + ${EndIf} + + StrCpy $ExistingTopDir "$INSTDIR" + ${DoUntil} ${FileExists} "$ExistingTopDir" + ${GetParent} "$ExistingTopDir" $ExistingTopDir + ${If} "$ExistingTopDir" == "" + StrCpy $SpaceAvailableBytes "0" + StrCpy $HasRequiredSpaceAvailable "false" + Return + ${EndIf} + ${Loop} + + ${GetLongPath} "$ExistingTopDir" $ExistingTopDir + + ; GetDiskFreeSpaceExW requires a backslash. + StrCpy $0 "$ExistingTopDir" "" -1 ; the last character + ${If} "$0" != "\" + StrCpy $0 "\" + ${Else} + StrCpy $0 "" + ${EndIf} + + System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i("$ExistingTopDir$0", .r1, .r2, .r3) .' + StrCpy $SpaceAvailableBytes "$1" + + System::Int64Op $SpaceAvailableBytes / 1048576 + Pop $1 + System::Int64Op $1 > ${APPROXIMATE_REQUIRED_SPACE_MB} + Pop $1 + ${If} $1 == 1 + StrCpy $HasRequiredSpaceAvailable "true" + ${Else} + StrCpy $HasRequiredSpaceAvailable "false" + ${EndIf} +FunctionEnd + +Function CanWrite + StrCpy $CanWriteToInstallDir "false" + + StrCpy $0 "$INSTDIR" + ; Use the existing directory when it exists + ${Unless} ${FileExists} "$INSTDIR" + ; Get the topmost directory that exists for new installs + ${DoUntil} ${FileExists} "$0" + ${GetParent} "$0" $0 + ${If} "$0" == "" + Return + ${EndIf} + ${Loop} + ${EndUnless} + + GetTempFileName $2 "$0" + Delete $2 + CreateDirectory "$2" + ${If} ${FileExists} "$2" + ${If} ${FileExists} "$INSTDIR" + GetTempFileName $3 "$INSTDIR" + ${Else} + GetTempFileName $3 "$2" + ${EndIf} + ${If} ${FileExists} "$3" + Delete "$3" + StrCpy $CanWriteToInstallDir "true" + ${EndIf} + RmDir "$2" + ${EndIf} +FunctionEnd + +Function AddQuickLaunchShortcut + CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ + "$INSTDIR" + ${EndIf} +FunctionEnd + +Function ExecSetAsDefaultAppUser + ; Using the helper.exe lessens the stub installer size. + ; This could ask for elevatation when the user doesn't install as admin. + Exec "$\"$INSTDIR\uninstall\helper.exe$\" /SetAsDefaultAppUser" +FunctionEnd + +Function LaunchApp +!ifndef DEV_EDITION + FindWindow $0 "${WindowClass}" + ${If} $0 <> 0 ; integer comparison + StrCpy $FirefoxLaunchCode "1" + MessageBox MB_OK|MB_ICONQUESTION "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)" + Return + ${EndIf} +!endif + + StrCpy $FirefoxLaunchCode "2" + + ; Set the current working directory to the installation directory + SetOutPath "$INSTDIR" + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $1 + ${If} ${Errors} + Exec "$\"$INSTDIR\${FileMainEXE}$\"" + ${Else} + GetFunctionAddress $0 LaunchAppFromElevatedProcess + UAC::ExecCodeSegment $0 + ${EndIf} +FunctionEnd + +Function LaunchAppFromElevatedProcess + ; Find the installation directory when launching using GetFunctionAddress + ; from an elevated installer since $INSTDIR will not be set in this installer + ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 + ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" + ${GetPathFromString} "$0" $0 + ; Set the current working directory to the installation directory + ${GetParent} "$0" $1 + SetOutPath "$1" + Exec "$\"$0$\"" +FunctionEnd + +Function CopyPostSigningData + ${LineRead} "$EXEDIR\postSigningData" "1" $PostSigningData + ${If} ${Errors} + ClearErrors + StrCpy $PostSigningData "0" + ${Else} + CreateDirectory "$LOCALAPPDATA\Mozilla\Firefox" + CopyFiles /SILENT "$EXEDIR\postSigningData" "$LOCALAPPDATA\Mozilla\Firefox" + ${Endif} +FunctionEnd + +Function DisplayDownloadError + ${NSD_KillTimer} DisplayDownloadError + ; To better display the error state on the taskbar set the progress completed + ; value to the total value. + ${ITBL3SetProgressValue} "100" "100" + ${ITBL3SetProgressState} "${TBPF_ERROR}" + MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK +1 + StrCpy $OpenedDownloadPage "1" ; Already initialized to 0 + + ${If} "$OpenedDownloadPage" == "1" + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $1 + ${If} ${Errors} + Call OpenManualDownloadURL + ${Else} + GetFunctionAddress $0 OpenManualDownloadURL + UAC::ExecCodeSegment $0 + ${EndIf} + ${EndIf} + + Call SendPing +FunctionEnd + +Function OpenManualDownloadURL + ExecShell "open" "${URLManualDownload}${URLManualDownloadAppend}" +FunctionEnd + +Section +SectionEnd diff --git a/browser/installer/windows/nsis/uninstaller.nsi b/browser/installer/windows/nsis/uninstaller.nsi new file mode 100755 index 000000000..c97728b47 --- /dev/null +++ b/browser/installer/windows/nsis/uninstaller.nsi @@ -0,0 +1,627 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Required Plugins: +# AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in +# CityHash http://dxr.mozilla.org/mozilla-central/source/other-licenses/nsis/Contrib/CityHash +# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in +# UAC http://nsis.sourceforge.net/UAC_plug-in + +; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs +!verbose 3 + +; 7-Zip provides better compression than the lzma from NSIS so we add the files +; uncompressed and use 7-Zip to create a SFX archive of it +SetDatablockOptimize on +SetCompress off +CRCCheck on + +RequestExecutionLevel user + +; The commands inside this ifdef require NSIS 3.0a2 or greater so the ifdef can +; be removed after we require NSIS 3.0a2 or greater. +!ifdef NSIS_PACKEDVERSION + Unicode true + ManifestSupportedOS all + ManifestDPIAware true +!endif + +!addplugindir ./ + +; On Vista and above attempt to elevate Standard Users in addition to users that +; are a member of the Administrators group. +!define NONADMIN_ELEVATE + +; prevents compiling of the reg write logging. +!define NO_LOG + +!define MaintUninstallKey \ + "Software\Microsoft\Windows\CurrentVersion\Uninstall\MozillaMaintenanceService" + +Var TmpVal +Var MaintCertKey + +; Other included files may depend upon these includes! +; The following includes are provided by NSIS. +!include FileFunc.nsh +!include LogicLib.nsh +!include MUI.nsh +!include WinMessages.nsh +!include WinVer.nsh +!include WordFunc.nsh + +!insertmacro GetSize +!insertmacro StrFilter +!insertmacro WordReplace + +!insertmacro un.GetParent + +; The following includes are custom. +!include branding.nsi +!include defines.nsi +!include common.nsh +!include locales.nsi + +; This is named BrandShortName helper because we use this for software update +; post update cleanup. +VIAddVersionKey "FileDescription" "${BrandShortName} Helper" +VIAddVersionKey "OriginalFilename" "helper.exe" + +!insertmacro AddDisabledDDEHandlerValues +!insertmacro CleanVirtualStore +!insertmacro ElevateUAC +!insertmacro GetLongPath +!insertmacro GetPathFromString +!insertmacro InitHashAppModelId +!insertmacro IsHandlerForInstallDir +!insertmacro IsPinnedToTaskBar +!insertmacro IsUserAdmin +!insertmacro LogDesktopShortcut +!insertmacro LogQuickLaunchShortcut +!insertmacro LogStartMenuShortcut +!insertmacro PinnedToStartMenuLnkCount +!insertmacro RegCleanAppHandler +!insertmacro RegCleanMain +!insertmacro RegCleanUninstall +!insertmacro SetAppLSPCategories +!insertmacro SetBrandNameVars +!insertmacro UpdateShortcutAppModelIDs +!insertmacro UnloadUAC +!insertmacro WriteRegDWORD2 +!insertmacro WriteRegStr2 + +!insertmacro un.ChangeMUIHeaderImage +!insertmacro un.CheckForFilesInUse +!insertmacro un.CleanUpdateDirectories +!insertmacro un.CleanVirtualStore +!insertmacro un.DeleteShortcuts +!insertmacro un.GetLongPath +!insertmacro un.GetSecondInstallPath +!insertmacro un.InitHashAppModelId +!insertmacro un.ManualCloseAppPrompt +!insertmacro un.RegCleanAppHandler +!insertmacro un.RegCleanFileHandler +!insertmacro un.RegCleanMain +!insertmacro un.RegCleanUninstall +!insertmacro un.RegCleanProtocolHandler +!insertmacro un.RemoveQuotesFromPath +!insertmacro un.RemovePrecompleteEntries +!insertmacro un.SetAppLSPCategories +!insertmacro un.SetBrandNameVars + +!include shared.nsh + +; Helper macros for ui callbacks. Insert these after shared.nsh +!insertmacro OnEndCommon +!insertmacro UninstallOnInitCommon + +!insertmacro un.OnEndCommon +!insertmacro un.UninstallUnOnInitCommon + +Name "${BrandFullName}" +OutFile "helper.exe" +!ifdef HAVE_64BIT_BUILD + InstallDir "$PROGRAMFILES64\${BrandFullName}\" +!else + InstallDir "$PROGRAMFILES32\${BrandFullName}\" +!endif +ShowUnInstDetails nevershow + +################################################################################ +# Modern User Interface - MUI + +!define MUI_ABORTWARNING +!define MUI_ICON setup.ico +!define MUI_UNICON setup.ico +!define MUI_WELCOMEPAGE_TITLE_3LINES +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_UNWELCOMEFINISHPAGE_BITMAP wizWatermark.bmp + +; Use a right to left header image when the language is right to left +!ifdef ${AB_CD}_rtl +!define MUI_HEADERIMAGE_BITMAP_RTL wizHeaderRTL.bmp +!else +!define MUI_HEADERIMAGE_BITMAP wizHeader.bmp +!endif + +/** + * Uninstall Pages + */ +; Welcome Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE un.preWelcome +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.leaveWelcome +!insertmacro MUI_UNPAGE_WELCOME + +; Custom Uninstall Confirm Page +UninstPage custom un.preConfirm + +; Remove Files Page +!insertmacro MUI_UNPAGE_INSTFILES + +; Finish Page + +!insertmacro MUI_UNPAGE_FINISH + +; Use the default dialog for IDD_VERIFY for a simple Banner +ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe" + +################################################################################ +# Helper Functions + +; This function is used to uninstall the maintenance service if the +; application currently being uninstalled is the last application to use the +; maintenance service. +Function un.UninstallServiceIfNotUsed + ; $0 will store if a subkey exists + ; $1 will store the first subkey if it exists or an empty string if it doesn't + ; Backup the old values + Push $0 + Push $1 + + ; The maintenance service always uses the 64-bit registry on x64 systems + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} + + ; Figure out the number of subkeys + StrCpy $0 0 + ${Do} + EnumRegKey $1 HKLM "Software\Mozilla\MaintenanceService" $0 + ${If} "$1" == "" + ${ExitDo} + ${EndIf} + IntOp $0 $0 + 1 + ${Loop} + + ; Restore back the registry view + ${If} ${RunningX64} + SetRegView lastUsed + ${EndIf} + ${If} $0 == 0 + ; Get the path of the maintenance service uninstaller + ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString" + + ; If the uninstall string does not exist, skip executing it + StrCmp $1 "" doneUninstall + + ; $1 is already a quoted string pointing to the install path + ; so we're already protected against paths with spaces + nsExec::Exec "$1 /S" +doneUninstall: + ${EndIf} + + ; Restore the old value of $1 and $0 + Pop $1 + Pop $0 +FunctionEnd + +################################################################################ +# Install Sections +; Empty section required for the installer to compile as an uninstaller +Section "" +SectionEnd + +################################################################################ +# Uninstall Sections + +Section "Uninstall" + SetDetailsPrint textonly + DetailPrint $(STATUS_UNINSTALL_MAIN) + SetDetailsPrint none + + ; Delete the app exe to prevent launching the app while we are uninstalling. + ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + ; If the user closed the application it can take several seconds for it to + ; shut down completely. If the application is being used by another user we + ; can still delete the files when the system is restarted. + Sleep 5000 + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ClearErrors + ${EndIf} + + ; setup the application model id registration value + ${un.InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" + + SetShellVarContext current ; Set SHCTX to HKCU + ${un.RegCleanMain} "Software\Mozilla" + ${un.RegCleanUninstall} + ${un.DeleteShortcuts} + + ; Unregister resources associated with Win7 taskbar jump lists. + ${If} ${AtLeastWin7} + ${AndIf} "$AppUserModelID" != "" + ApplicationID::UninstallJumpLists "$AppUserModelID" + ${EndIf} + + ; Remove the updates directory for Vista and above + ${un.CleanUpdateDirectories} "Mozilla\Firefox" "Mozilla\updates" + + ; Remove any app model id's stored in the registry for this install path + DeleteRegValue HKCU "Software\Mozilla\${AppName}\TaskBarIDs" "$INSTDIR" + DeleteRegValue HKLM "Software\Mozilla\${AppName}\TaskBarIDs" "$INSTDIR" + + ClearErrors + WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" + ${If} ${Errors} + StrCpy $TmpVal "HKCU" ; used primarily for logging + ${Else} + SetShellVarContext all ; Set SHCTX to HKLM + DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" + StrCpy $TmpVal "HKLM" ; used primarily for logging + ${un.RegCleanMain} "Software\Mozilla" + ${un.RegCleanUninstall} + ${un.DeleteShortcuts} + ${un.SetAppLSPCategories} + ${EndIf} + + ${un.RegCleanAppHandler} "FirefoxURL" + ${un.RegCleanAppHandler} "FirefoxHTML" + ${un.RegCleanProtocolHandler} "ftp" + ${un.RegCleanProtocolHandler} "http" + ${un.RegCleanProtocolHandler} "https" + + ClearErrors + ReadRegStr $R9 HKCR "FirefoxHTML" "" + ; Don't clean up the file handlers if the FirefoxHTML key still exists since + ; there should be a second installation that may be the default file handler + ${If} ${Errors} + ${un.RegCleanFileHandler} ".htm" "FirefoxHTML" + ${un.RegCleanFileHandler} ".html" "FirefoxHTML" + ${un.RegCleanFileHandler} ".shtml" "FirefoxHTML" + ${un.RegCleanFileHandler} ".xht" "FirefoxHTML" + ${un.RegCleanFileHandler} ".xhtml" "FirefoxHTML" + ${un.RegCleanFileHandler} ".oga" "FirefoxHTML" + ${un.RegCleanFileHandler} ".ogg" "FirefoxHTML" + ${un.RegCleanFileHandler} ".ogv" "FirefoxHTML" + ${un.RegCleanFileHandler} ".pdf" "FirefoxHTML" + ${un.RegCleanFileHandler} ".webm" "FirefoxHTML" + ${EndIf} + + SetShellVarContext all ; Set SHCTX to HKLM + ${un.GetSecondInstallPath} "Software\Mozilla" $R9 + ${If} $R9 == "false" + SetShellVarContext current ; Set SHCTX to HKCU + ${un.GetSecondInstallPath} "Software\Mozilla" $R9 + ${EndIf} + + StrCpy $0 "Software\Clients\StartMenuInternet\${FileMainEXE}\shell\open\command" + ReadRegStr $R1 HKLM "$0" "" + ${un.RemoveQuotesFromPath} "$R1" $R1 + ${un.GetParent} "$R1" $R1 + + ; Only remove the StartMenuInternet key if it refers to this install location. + ; The StartMenuInternet registry key is independent of the default browser + ; settings. The XPInstall base un-installer always removes this key if it is + ; uninstalling the default browser and it will always replace the keys when + ; installing even if there is another install of Firefox that is set as the + ; default browser. Now the key is always updated on install but it is only + ; removed if it refers to this install location. + ${If} "$INSTDIR" == "$R1" + DeleteRegKey HKLM "Software\Clients\StartMenuInternet\${FileMainEXE}" + DeleteRegValue HKLM "Software\RegisteredApplications" "${AppRegName}" + ${EndIf} + + ReadRegStr $R1 HKCU "$0" "" + ${un.RemoveQuotesFromPath} "$R1" $R1 + ${un.GetParent} "$R1" $R1 + + ; Only remove the StartMenuInternet key if it refers to this install location. + ; The StartMenuInternet registry key is independent of the default browser + ; settings. The XPInstall base un-installer always removes this key if it is + ; uninstalling the default browser and it will always replace the keys when + ; installing even if there is another install of Firefox that is set as the + ; default browser. Now the key is always updated on install but it is only + ; removed if it refers to this install location. + ${If} "$INSTDIR" == "$R1" + DeleteRegKey HKCU "Software\Clients\StartMenuInternet\${FileMainEXE}" + DeleteRegValue HKCU "Software\RegisteredApplications" "${AppRegName}" + ${EndIf} + + StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\App Paths\${FileMainEXE}" + ${If} $R9 == "false" + DeleteRegKey HKLM "$0" + DeleteRegKey HKCU "$0" + StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\${FileMainEXE}" + DeleteRegKey HKLM "$0" + DeleteRegKey HKCU "$0" + StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe" + DeleteRegKey HKLM "$0" + DeleteRegKey HKCU "$0" + StrCpy $0 "Software\Classes\MIME\Database\Content Type\application/x-xpinstall;app=firefox" + DeleteRegKey HKLM "$0" + DeleteRegKey HKCU "$0" + ${Else} + ReadRegStr $R1 HKLM "$0" "" + ${un.RemoveQuotesFromPath} "$R1" $R1 + ${un.GetParent} "$R1" $R1 + ${If} "$INSTDIR" == "$R1" + WriteRegStr HKLM "$0" "" "$R9" + ${un.GetParent} "$R9" $R1 + WriteRegStr HKLM "$0" "Path" "$R1" + ${EndIf} + ${EndIf} + + ; Remove directories and files we always control before parsing the uninstall + ; log so empty directories can be removed. + ${If} ${FileExists} "$INSTDIR\updates" + RmDir /r /REBOOTOK "$INSTDIR\updates" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\updated" + RmDir /r /REBOOTOK "$INSTDIR\updated" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\defaults\shortcuts" + RmDir /r /REBOOTOK "$INSTDIR\defaults\shortcuts" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\distribution" + RmDir /r /REBOOTOK "$INSTDIR\distribution" + ${EndIf} + + ; Remove files that may be left behind by the application in the + ; VirtualStore directory. + ${un.CleanVirtualStore} + + ; Only unregister the dll if the registration points to this installation + ReadRegStr $R1 HKCR "CLSID\{0D68D6D0-D93D-4D08-A30D-F00DD1F45B24}\InProcServer32" "" + ${If} "$INSTDIR\AccessibleMarshal.dll" == "$R1" + ${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll" + ${EndIf} + + ${un.RemovePrecompleteEntries} "false" + + ${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js" + Delete /REBOOTOK "$INSTDIR\defaults\pref\channel-prefs.js" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\defaults\pref" + RmDir /REBOOTOK "$INSTDIR\defaults\pref" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\defaults" + RmDir /REBOOTOK "$INSTDIR\defaults" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\uninstall" + ; Remove the uninstall directory that we control + RmDir /r /REBOOTOK "$INSTDIR\uninstall" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\install.log" + Delete /REBOOTOK "$INSTDIR\install.log" + ${EndIf} + ${If} ${FileExists} "$INSTDIR\update-settings.ini" + Delete /REBOOTOK "$INSTDIR\update-settings.ini" + ${EndIf} + + ; Explicitly remove empty webapprt dir in case it exists (bug 757978). + RmDir "$INSTDIR\webapprt\components" + RmDir "$INSTDIR\webapprt" + + ; Remove the installation directory if it is empty + RmDir "$INSTDIR" + + ; If firefox.exe was successfully deleted yet we still need to restart to + ; remove other files create a dummy firefox.exe.moz-delete to prevent the + ; installer from allowing an install without restart when it is required + ; to complete an uninstall. + ${If} ${RebootFlag} + ; Admin is required to delete files on reboot so only add the moz-delete if + ; the user is an admin. After calling UAC::IsAdmin $0 will equal 1 if the + ; user is an admin. + UAC::IsAdmin + ${If} "$0" == "1" + ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-delete" + FileOpen $0 "$INSTDIR\${FileMainEXE}.moz-delete" w + FileWrite $0 "Will be deleted on restart" + Delete /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-delete" + FileClose $0 + ${EndUnless} + ${EndIf} + ${EndIf} + + ; Refresh desktop icons otherwise the start menu internet item won't be + ; removed and other ugly things will happen like recreation of the app's + ; clients registry key by the OS under some conditions. + System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i 0, i 0, i 0)" + + ; Users who uninstall then reinstall expecting Firefox to use a clean profile + ; may be surprised during first-run. This key is checked during startup of Firefox and + ; subsequently deleted after checking. If the value is found during startup + ; the browser will offer to Reset Firefox. We use the UpdateChannel to match + ; uninstalls of Firefox-release with reinstalls of Firefox-release, for example. + WriteRegStr HKCU "Software\Mozilla\Firefox" "Uninstalled-${UpdateChannel}" "True" + +!ifdef MOZ_MAINTENANCE_SERVICE + ; Get the path the allowed cert is at and remove it + ; Keep this block of code last since it modfies the reg view + ServicesHelper::PathToUniqueRegistryPath "$INSTDIR" + Pop $MaintCertKey + ${If} $MaintCertKey != "" + ; Always use the 64bit registry for certs on 64bit systems. + ${If} ${RunningX64} + SetRegView 64 + ${EndIf} + DeleteRegKey HKLM "$MaintCertKey" + ${If} ${RunningX64} + SetRegView lastused + ${EndIf} + ${EndIf} + Call un.UninstallServiceIfNotUsed +!endif + + ${un.IsFirewallSvcRunning} + Pop $0 + ${If} "$0" == "true" + liteFirewallW::RemoveRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)" + ${EndIf} +SectionEnd + +################################################################################ +# Language + +!insertmacro MOZ_MUI_LANGUAGE 'baseLocale' +!verbose push +!verbose 3 +!include "overrideLocale.nsh" +!include "customLocale.nsh" +!verbose pop + +; Set this after the locale files to override it if it is in the locale. Using +; " " for BrandingText will hide the "Nullsoft Install System..." branding. +BrandingText " " + +################################################################################ +# Page pre, show, and leave functions + +Function un.preWelcome + ${If} ${FileExists} "$INSTDIR\distribution\modern-wizard.bmp" + Delete "$PLUGINSDIR\modern-wizard.bmp" + CopyFiles /SILENT "$INSTDIR\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp" + ${EndIf} +FunctionEnd + +Function un.leaveWelcome + ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" + Banner::show /NOUNLOAD "$(BANNER_CHECK_EXISTING)" + + ; If the message window has been found previously give the app an additional + ; five seconds to close. + ${If} "$TmpVal" == "FoundMessageWindow" + Sleep 5000 + ${EndIf} + + ${PushFilesToCheck} + + ${un.CheckForFilesInUse} $TmpVal + + Banner::destroy + + ; If there are files in use $TmpVal will be "true" + ${If} "$TmpVal" == "true" + ; If the message window is found the call to ManualCloseAppPrompt will + ; abort leaving the value of $TmpVal set to "FoundMessageWindow". + StrCpy $TmpVal "FoundMessageWindow" + ${un.ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_UNINSTALL)" + ; If the message window is not found set $TmpVal to "true" so the restart + ; required message is displayed. + StrCpy $TmpVal "true" + ${EndIf} + ${EndIf} +FunctionEnd + +Function un.preConfirm + ${If} ${FileExists} "$INSTDIR\distribution\modern-header.bmp" + ${AndIf} $hHeaderBitmap == "" + Delete "$PLUGINSDIR\modern-header.bmp" + CopyFiles /SILENT "$INSTDIR\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp" + ${un.ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp" + ${EndIf} + + ; Setup the unconfirm.ini file for the Custom Uninstall Confirm Page + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "3" + + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Type "label" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Text "$(UN_CONFIRM_UNINSTALLED_FROM)" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Left "0" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Right "-1" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Top "5" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Bottom "15" + + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Type "text" + ; The contents of this control must be set as follows in the pre function + ; ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND" + ; SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" State "" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Left "0" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Right "-1" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Top "17" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Bottom "30" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" flags "READONLY" + + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Type "label" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Text "$(UN_CONFIRM_CLICK)" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Left "0" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Right "-1" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Top "130" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Bottom "150" + + ${If} "$TmpVal" == "true" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Type "label" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Text "$(SUMMARY_REBOOT_REQUIRED_UNINSTALL)" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Left "0" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Right "-1" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Top "35" + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Bottom "45" + + WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "4" + ${EndIf} + + !insertmacro MUI_HEADER_TEXT "$(UN_CONFIRM_PAGE_TITLE)" "$(UN_CONFIRM_PAGE_SUBTITLE)" + ; The Summary custom page has a textbox that will automatically receive + ; focus. This sets the focus to the Install button instead. + !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini" + GetDlgItem $0 $HWNDPARENT 1 + System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i" + ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND" + SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR" + !insertmacro MUI_INSTALLOPTIONS_SHOW +FunctionEnd + +################################################################################ +# Initialization Functions + +Function .onInit + ; Remove the current exe directory from the search order. + ; This only effects LoadLibrary calls and not implicitly loaded DLLs. + System::Call 'kernel32::SetDllDirectoryW(w "")' + + ; We need this set up for most of the helper.exe operations. + ${UninstallOnInitCommon} +FunctionEnd + +Function un.onInit + ; Remove the current exe directory from the search order. + ; This only effects LoadLibrary calls and not implicitly loaded DLLs. + System::Call 'kernel32::SetDllDirectoryW(w "")' + + StrCpy $LANGUAGE 0 + + ${un.UninstallUnOnInitCommon} + +; The commands inside this ifndef are needed prior to NSIS 3.0a2 and can be +; removed after we require NSIS 3.0a2 or greater. +!ifndef NSIS_PACKEDVERSION + ${If} ${AtLeastWinVista} + System::Call 'user32::SetProcessDPIAware()' + ${EndIf} +!endif + + !insertmacro InitInstallOptionsFile "unconfirm.ini" +FunctionEnd + +Function .onGUIEnd + ${OnEndCommon} +FunctionEnd + +Function un.onGUIEnd + ${un.OnEndCommon} +FunctionEnd diff --git a/browser/installer/windows/nsis/updater_append.ini b/browser/installer/windows/nsis/updater_append.ini new file mode 100644 index 000000000..af7742c12 --- /dev/null +++ b/browser/installer/windows/nsis/updater_append.ini @@ -0,0 +1,12 @@ + +; IMPORTANT: This file should always start with a newline in case a locale +; provided updater.ini does not end with a newline. +; Application to launch after an update has been successfully applied. This +; must be in the same directory or a sub-directory of the directory of the +; application executable that initiated the software update. +[PostUpdateWin] +; ExeRelPath is the path to the PostUpdateWin executable relative to the +; application executable. +ExeRelPath=uninstall\helper.exe +; ExeArg is the argument to pass to the PostUpdateWin exe +ExeArg=/PostUpdate |