Source code
Revision control
Copy as Markdown
Other Tools
# 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
; Generated by DeriveCapabilitySidsFromName with the name "lpacFirefoxInstallFiles"
!define LpacFirefoxInstallFilesSid "S-1-15-3-1024-1238444810-1356253261-2257478630-1143196962-1563090664-2414759320-1282101916-4218287853"
!macro PostUpdate
${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"
ClearErrors
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test"
${If} ${Errors}
StrCpy $RegHive "HKCU"
${Else}
SetShellVarContext all ; Set SHCTX to all users (e.g. HKLM)
DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest"
StrCpy $RegHive "HKLM"
${RegCleanMain} "Software\Mozilla"
${RegCleanUninstall}
${UpdateProtocolHandlers}
${FixShellIconHandler} "HKLM"
${SetAppLSPCategories} ${LSP_CATEGORIES}
; Add the Firewall entries after an update
Call AddFirewallEntries
ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
${If} "$0" != "${GREVersion}"
WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}"
${EndIf}
${EndIf}
; Update the name/icon/AppModelID of our shortcuts as needed, then update the
; lastwritetime of the Start Menu shortcut to clear the tile icon cache.
; Do this for both shell contexts in case the user has shortcuts in multiple
; locations, then restore the previous context at the end.
SetShellVarContext all
${UpdateShortcutsBranding}
${TouchStartMenuShortcut}
Call FixShortcutAppModelIDs
SetShellVarContext current
${UpdateShortcutsBranding}
${TouchStartMenuShortcut}
Call FixShortcutAppModelIDs
${If} $RegHive == "HKLM"
SetShellVarContext all
${ElseIf} $RegHive == "HKCU"
SetShellVarContext current
${EndIf}
${RemoveDeprecatedKeys}
${Set32to64DidMigrateReg}
${SetAppKeys}
${FixClassKeys}
${SetUninstallKeys}
${If} $RegHive == "HKLM"
${SetStartMenuInternet} HKLM
${ElseIf} $RegHive == "HKCU"
${SetStartMenuInternet} HKCU
${EndIf}
; Remove files that may be left behind by the application in the
; VirtualStore directory.
${CleanVirtualStore}
${RemoveDeprecatedFiles}
; Fix the distribution.ini file if applicable
${FixDistributionsINI}
; Migrate postSigningData file if present, and if it doesn't already exist.
${GetLocalAppDataFolder} $0
${If} ${FileExists} "$INSTDIR\postSigningData"
; If it already exists, just delete the appdata one.
; It's possible this was for a different install, but it's impossible to
; know for sure, so we may as well just get rid of it.
Delete /REBOOTOK "$0\Mozilla\Firefox\postSigningData"
${Else}
${If} ${FileExists} "$0\Mozilla\Firefox\postSigningData"
Rename "$0\Mozilla\Firefox\postSigningData" "$INSTDIR\postSigningData"
${EndIf}
${EndIf}
RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}"
; Register AccessibleMarshal.dll with COM (this requires write access to HKLM)
${RegisterAccessibleMarshal}
; Record the Windows Error Reporting module
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" "$INSTDIR\mozwer.dll" 0
; Apply LPAC permissions to install directory.
Push "Marker"
AccessControl::GrantOnFile \
"$INSTDIR" "(${LpacFirefoxInstallFilesSid})" "GenericRead + GenericExecute"
Pop $TmpVal ; get "Marker" or error msg
${If} $TmpVal != "Marker"
Pop $TmpVal ; get "Marker"
${EndIf}
!ifdef MOZ_MAINTENANCE_SERVICE
Call IsUserAdmin
Pop $R0
${If} $R0 == "true"
; Only proceed if we have HKLM write access
${AndIf} $RegHive == "HKLM"
; 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}
${OrIf} ${IsNativeARM64}
SetRegView 64
${EndIf}
ReadRegDWORD $5 HKLM "Software\Mozilla\MaintenanceService" "Attempted"
ClearErrors
${If} ${RunningX64}
${OrIf} ${IsNativeARM64}
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
!ifdef MOZ_LAUNCHER_PROCESS
${ResetLauncherProcessDefaults}
!endif
${WriteToastNotificationRegistration} $RegHive
; Make sure the scheduled task registration for the default browser agent gets
; updated, but only if we're not the instance of PostUpdate that was started
; by the service, because this needs to run as the actual user. Also, don't do
; that if the installer was told not to register the agent task at all.
; XXXbytesized - This also needs to un-register any scheduled tasks for the WDBA
; that were registered using elevation, but currently it does
; not. See Bugs 1638509 and 1902719.
!ifdef MOZ_DEFAULT_BROWSER_AGENT
${If} $RegHive == "HKCU"
ClearErrors
ReadRegDWORD $0 HKCU "Software\Mozilla\${AppName}\Installer\$AppUserModelID" \
"DidRegisterDefaultBrowserAgent"
${If} $0 != 0
${OrIf} ${Errors}
ExecWait '"$INSTDIR\default-browser-agent.exe" register-task $AppUserModelID'
${EndIf}
${EndIf}
!endif
${RemoveDefaultBrowserAgentShortcut}
!macroend
!define PostUpdate "!insertmacro PostUpdate"
; Update the last modified time on the Start Menu shortcut, so that its icon
; gets refreshed. Should be called on Win8+ after UpdateShortcutBranding.
!macro TouchStartMenuShortcut
${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
FileOpen $0 "$SMPROGRAMS\${BrandShortName}.lnk" a
${IfNot} ${Errors}
System::Call '*(i, i) p .r1'
System::Call 'kernel32::GetSystemTimeAsFileTime(p r1)'
System::Call 'kernel32::SetFileTime(p r0, i 0, i 0, p r1) i .r2'
System::Free $1
FileClose $0
${EndIf}
${EndIf}
!macroend
!define TouchStartMenuShortcut "!insertmacro TouchStartMenuShortcut"
!macro AddPrivateBrowsingShortcut
${IfNot} ${FileExists} "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk"
CreateShortcut "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$INSTDIR\${PrivateBrowsingEXE}" "" "$INSTDIR\${PrivateBrowsingEXE}" ${IDI_PBICON_PB_EXE_ZERO_BASED}
ShellLink::SetShortcutWorkingDirectory "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$INSTDIR"
ShellLink::SetShortcutDescription "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$(PRIVATE_BROWSING_SHORTCUT_TITLE)"
ApplicationID::Set "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$AppUserModelID;PrivateBrowsingAUMID" "true"
${LogStartMenuShortcut} "$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk"
${EndIf}
!macroend
!define AddPrivateBrowsingShortcut "!insertmacro AddPrivateBrowsingShortcut"
!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}
!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
!macro HideShortcuts
; Find the correct registry path to clear IconsVisible.
StrCpy $R1 "Software\Clients\StartMenuInternet\${AppRegName}-$AppUserModelID\InstallInfo"
ReadRegDWORD $0 HKLM "$R1" "ShowIconsCommand"
${If} ${Errors}
${StrFilter} "${FileMainEXE}" "+" "" "" $0
StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
${EndIf}
WriteRegDWORD HKLM "$R1" "IconsVisible" 0
WriteRegDWORD HKCU "$R1" "IconsVisible" 0
SetShellVarContext all ; Set $DESKTOP to All Users
${Unless} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
${EndUnless}
${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
ShellLink::GetShortCutArgs "$DESKTOP\${BrandShortName}.lnk"
Pop $0
${If} "$0" == ""
ShellLink::GetShortCutTarget "$DESKTOP\${BrandShortName}.lnk"
Pop $0
${GetLongPath} "$0" $0
${If} "$0" == "$INSTDIR\${FileMainEXE}"
Delete "$DESKTOP\${BrandShortName}.lnk"
${EndIf}
${EndIf}
${EndIf}
SetShellVarContext all ; Set $SMPROGRAMS to All Users
${Unless} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start
; Menu Programs directory
${EndUnless}
${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
ShellLink::GetShortCutArgs "$SMPROGRAMS\${BrandShortName}.lnk"
Pop $0
${If} "$0" == ""
ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandShortName}.lnk"
Pop $0
${GetLongPath} "$0" $0
${If} "$0" == "$INSTDIR\${FileMainEXE}"
Delete "$SMPROGRAMS\${BrandShortName}.lnk"
${EndIf}
${EndIf}
${EndIf}
${If} ${FileExists} "$QUICKLAUNCH\${BrandShortName}.lnk"
ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandShortName}.lnk"
Pop $0
${If} "$0" == ""
ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandShortName}.lnk"
Pop $0
${GetLongPath} "$0" $0
${If} "$0" == "$INSTDIR\${FileMainEXE}"
Delete "$QUICKLAUNCH\${BrandShortName}.lnk"
${EndIf}
${EndIf}
${EndIf}
!macroend
!define HideShortcuts "!insertmacro HideShortcuts"
; Adds shortcuts for this installation. This should also add the application
!macro ShowShortcuts
; Find the correct registry path to set IconsVisible.
StrCpy $R1 "Software\Clients\StartMenuInternet\${AppRegName}-$AppUserModelID\InstallInfo"
ReadRegDWORD $0 HKLM "$R1" "ShowIconsCommand"
${If} ${Errors}
${StrFilter} "${FileMainEXE}" "+" "" "" $0
StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
${EndIf}
WriteRegDWORD HKLM "$R1" "IconsVisible" 1
WriteRegDWORD HKCU "$R1" "IconsVisible" 1
SetShellVarContext all ; Set $DESKTOP to All Users
${Unless} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
CreateShortCut "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR"
${If} "$AppUserModelID" != ""
ApplicationID::Set "$DESKTOP\${BrandShortName}.lnk" "$AppUserModelID" "true"
${EndIf}
${Else}
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
${Unless} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
CreateShortCut "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandShortName}.lnk" \
"$INSTDIR"
${If} "$AppUserModelID" != ""
ApplicationID::Set "$DESKTOP\${BrandShortName}.lnk" "$AppUserModelID" "true"
${EndIf}
${EndIf}
${EndUnless}
${EndIf}
${EndUnless}
SetShellVarContext all ; Set $SMPROGRAMS to All Users
${Unless} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
CreateShortCut "$SMPROGRAMS\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandShortName}.lnk" \
"$INSTDIR"
${If} "$AppUserModelID" != ""
ApplicationID::Set "$SMPROGRAMS\${BrandShortName}.lnk" "$AppUserModelID" "true"
${EndIf}
${Else}
SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start
; Menu Programs directory
${Unless} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
CreateShortCut "$SMPROGRAMS\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandShortName}.lnk" \
"$INSTDIR"
${If} "$AppUserModelID" != ""
ApplicationID::Set "$SMPROGRAMS\${BrandShortName}.lnk" "$AppUserModelID" "true"
${EndIf}
${EndIf}
${EndUnless}
${EndIf}
${EndUnless}
!macroend
!define ShowShortcuts "!insertmacro ShowShortcuts"
; Update the branding name on all shortcuts our installer created
; to convert from BrandFullName (which is what we used to name shortcuts)
; to BrandShortName (which is what we now name shortcuts). We only rename
; desktop and start menu shortcuts, because touching taskbar pins often
; (but inconsistently) triggers various broken behaviors in the shell.
; This assumes SHCTX is set correctly.
!macro UpdateShortcutsBranding
${UpdateOneShortcutBranding} "STARTMENU" "$SMPROGRAMS"
${UpdateOneShortcutBranding} "DESKTOP" "$DESKTOP"
!macroend
!define UpdateShortcutsBranding "!insertmacro UpdateShortcutsBranding"
!macro UpdateOneShortcutBranding LOG_SECTION SHORTCUT_DIR
; Only try to rename the shortcuts found in the shortcuts log, to avoid
; blowing away a name that the user created.
${GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9
${If} ${FileExists} "$R9"
ClearErrors
; The shortcuts log contains a numbered list of entries for each section,
; but we never actually create more than one.
ReadINIStr $R8 "$R9" "${LOG_SECTION}" "Shortcut0"
${IfNot} ${Errors}
${If} ${FileExists} "${SHORTCUT_DIR}\$R8"
; If the shortcut does not have a description, add one. See https://nsis.sourceforge.io/ShellLink_plug-in#Get_Shortcut_Description
ShellLink::GetShortCutDescription "${SHORTCUT_DIR}\$R8"
; Let's use R7 to store the result, since it's going to be reused in the next check
Pop $R7
${If} $R7 == ""
; Looks like there is no description. Let's add one. See https://nsis.sourceforge.io/ShellLink_plug-in#Set_Shortcut_Description
ShellLink::SetShortCutDescription "${SHORTCUT_DIR}\$R8" "$(BRIEF_APP_DESC)"
${EndIf}
ShellLink::GetShortCutTarget "${SHORTCUT_DIR}\$R8"
Pop $R7
${GetLongPath} "$R7" $R7
${If} $R7 == "$INSTDIR\${FileMainEXE}"
${AndIf} $R8 != "${BrandShortName}.lnk"
${AndIfNot} ${FileExists} "${SHORTCUT_DIR}\${BrandShortName}.lnk"
ClearErrors
Rename "${SHORTCUT_DIR}\$R8" "${SHORTCUT_DIR}\${BrandShortName}.lnk"
${IfNot} ${Errors}
; Update the shortcut log manually instead of calling LogShortcut
; because it would add a Shortcut1 entry, and we really do want to
; overwrite the existing entry 0, since we just renamed the file.
WriteINIStr "$R9" "${LOG_SECTION}" "Shortcut0" \
"${BrandShortName}.lnk"
${EndIf}
${EndIf}
${EndIf}
${EndIf}
${EndIf}
!macroend
!define UpdateOneShortcutBranding "!insertmacro UpdateOneShortcutBranding"
!macro RemoveDefaultBrowserAgentShortcut
Push $0
Push $1
Push $2
Push $3
; Get the current user's Start Menu Programs.
${GetProgramsFolder} $1
; The shortcut would have been named MOZ_BASE_NAME regardless of branding.
; According to defines.nsi.in AppName should match application.ini, and application.ini.in sets
; [App] Name from MOZ_BASE_NAME.
StrCpy $1 "$1\${AppName}.lnk"
ShellLink::GetShortCutTarget $1
Pop $0
; ShellLink::GetShortCutTarget, and the underlying IShellLink::GetPath(), have an issue
; where "C:\Program Files" becomes "C:\Program Files (x86)" in some cases.
; It should be OK to remove the shortcut (which matches our app name) even if it isn't from this
; install, as long as the file name portion of the target path matches.
StrCpy $2 "\default-browser-agent.exe"
StrLen $3 $2
; Select the substring to match from the end of the target path.
StrCpy $0 $0 $3 -$3
${If} $0 == $2
Delete $1
${EndIf}
Pop $3
Pop $2
Pop $1
Pop $0
!macroend
!define RemoveDefaultBrowserAgentShortcut "!insertmacro RemoveDefaultBrowserAgentShortcut"
!macro AddAssociationIfNoneExist FILE_TYPE KEY
ClearErrors
EnumRegKey $7 HKCR "${FILE_TYPE}" 0
${If} ${Errors}
WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}" "" ${KEY}
${EndIf}
WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}\OpenWithProgids" ${KEY} ""
!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
; See if we're using path hash suffixed registry keys for this install.
StrCpy $5 ""
${StrFilter} "${FileMainEXE}" "+" "" "" $2
ReadRegStr $0 SHCTX "Software\Clients\StartMenuInternet\$2\DefaultIcon" ""
StrCpy $0 $0 -2
${If} $0 != $8
StrCpy $5 "-$AppUserModelID"
${EndIf}
StrCpy $0 "SOFTWARE\Classes"
StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
; Associate the file handlers with FirefoxHTML, if they aren't already.
ReadRegStr $6 SHCTX "$0\.htm" ""
${WordFind} "$6" "-" "+1{" $6
${If} "$6" != "FirefoxHTML"
WriteRegStr SHCTX "$0\.htm" "" "FirefoxHTML$5"
${EndIf}
ReadRegStr $6 SHCTX "$0\.html" ""
${WordFind} "$6" "-" "+1{" $6
${If} "$6" != "FirefoxHTML"
WriteRegStr SHCTX "$0\.html" "" "FirefoxHTML$5"
${EndIf}
ReadRegStr $6 SHCTX "$0\.shtml" ""
${WordFind} "$6" "-" "+1{" $6
${If} "$6" != "FirefoxHTML"
WriteRegStr SHCTX "$0\.shtml" "" "FirefoxHTML$5"
${EndIf}
ReadRegStr $6 SHCTX "$0\.xht" ""
${WordFind} "$6" "-" "+1{" $6
${If} "$6" != "FirefoxHTML"
WriteRegStr SHCTX "$0\.xht" "" "FirefoxHTML$5"
${EndIf}
ReadRegStr $6 SHCTX "$0\.xhtml" ""
${WordFind} "$6" "-" "+1{" $6
${If} "$6" != "FirefoxHTML"
WriteRegStr SHCTX "$0\.xhtml" "" "FirefoxHTML$5"
${EndIf}
; Keep this list synchronized with
; and `os.environment.launched_to_handle` and `os.environment.invoked_to_handle` telemetry in
${AddAssociationIfNoneExist} ".oga" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".ogg" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".ogv" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".webm" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".svg" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".webp" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".avif" "FirefoxHTML$5"
${AddAssociationIfNoneExist} ".pdf" "FirefoxPDF$5"
; An empty string is used for the 5th param because FirefoxHTML- is not a
; protocol handler. Ditto for FirefoxPDF-.
${AddDisabledDDEHandlerValues} "FirefoxHTML$5" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
"${AppRegName} HTML Document" ""
${AddDisabledDDEHandlerValues} "FirefoxPDF$5" "$2" "$8,${IDI_DOCUMENT_PDF_ZERO_BASED}" \
"${AppRegName} PDF Document" ""
${AddDisabledDDEHandlerValues} "FirefoxURL$5" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "${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} "http" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
${AddDisabledDDEHandlerValues} "https" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
${AddDisabledDDEHandlerValues} "mailto" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
!macroend
!define SetHandlers "!insertmacro SetHandlers"
!macro WriteApplicationsSupportedType RegKey Type
WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\SupportedTypes" "${Type}" ""
!macroend
!define WriteApplicationsSupportedType "!insertmacro WriteApplicationsSupportedType"
; Adds the HKLM\Software\Clients\StartMenuInternet\Firefox-[pathhash] 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.
;
; 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.
;
; The StartMenuInternet key and friends are documented at
;
; This function also writes our RegisteredApplications entry, which gets us
; listed in the Settings app's default browser options on Windows 8+, and in
; Set Program Access and Defaults on earlier versions.
!macro SetStartMenuInternet RegKey
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
${GetLongPath} "$INSTDIR\uninstall\helper.exe" $7
; If we already have keys at the old FIREFOX.EXE path, then just update those.
; We have to be careful to update the existing keys in place so that we don't
; create duplicate keys for the same installation, or cause Windows to think
; something "suspicious" has happened and it should reset the default browser.
${StrFilter} "${FileMainEXE}" "+" "" "" $1
ReadRegStr $0 ${RegKey} "Software\Clients\StartMenuInternet\$1\DefaultIcon" ""
StrCpy $0 $0 -2
${If} $0 != $8
StrCpy $1 "${AppRegName}-$AppUserModelID"
StrCpy $2 "-$AppUserModelID"
${Else}
StrCpy $2 ""
${EndIf}
StrCpy $0 "Software\Clients\StartMenuInternet\$1"
WriteRegStr ${RegKey} "$0" "" "${BrandFullName}"
WriteRegStr ${RegKey} "$0\DefaultIcon" "" "$8,${IDI_APPICON_ZERO_BASED}"
; The Reinstall Command is defined at
WriteRegStr ${RegKey} "$0\InstallInfo" "HideIconsCommand" "$\"$7$\" /HideShortcuts"
WriteRegStr ${RegKey} "$0\InstallInfo" "ShowIconsCommand" "$\"$7$\" /ShowShortcuts"
WriteRegStr ${RegKey} "$0\InstallInfo" "ReinstallCommand" "$\"$7$\" /SetAsDefaultAppGlobal"
WriteRegDWORD ${RegKey} "$0\InstallInfo" "IconsVisible" 1
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"
; Capabilities registry keys
WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationDescription" "$(REG_APP_DESC)"
WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationIcon" "$8,${IDI_APPICON_ZERO_BASED}"
WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationName" "${BrandShortName}"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".htm" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".html" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".shtml" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".xht" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".xhtml" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".svg" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".webp" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".avif" "FirefoxHTML$2"
WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".pdf" "FirefoxPDF$2"
WriteRegStr ${RegKey} "$0\Capabilities\StartMenu" "StartMenuInternet" "$1"
; In the past, we supported ftp. Since we don't delete and re-create the
; entire key, we need to remove any existing registration.
DeleteRegValue ${RegKey} "$0\Capabilities\URLAssociations" "ftp"
WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "http" "FirefoxURL$2"
WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "https" "FirefoxURL$2"
WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "mailto" "FirefoxURL$2"
WriteRegStr ${RegKey} "Software\RegisteredApplications" "$1" "$0\Capabilities"
; This key would be created by the Open With dialog when a user creates an
; association for us with a file type that we haven't registered as a handler
; for. We need to preemptively create it ourselves so that we can control the
; command line that's used to launch us in that situation. If it's too late
; and one already exists, then we need to edit its command line to make sure
; it contains the -osint flag.
ReadRegStr $6 ${RegKey} "Software\Classes\Applications\${FileMainEXE}\shell\open\command" ""
${If} $6 != ""
${GetPathFromString} "$6" $6
WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\shell\open\command" \
"" "$\"$6$\" -osint -url $\"%1$\""
${Else}
WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\shell\open\command" \
"" "$\"$8$\" -osint -url $\"%1$\""
; Make sure files associated this way use the document icon instead of the
; application icon.
WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\DefaultIcon" \
"" "$8,${IDI_DOCUMENT_ZERO_BASED}"
; If we're going to create this key at all, we also need to list our supported
; file types in it, because otherwise we'll be shown as a suggestion for every
; single file type, whether we support it in any way or not.
; We take a more expansive approach to the set of file types registered
; here compared to elsewhere because this key is interpreted by the OS as
; containing every file type that we can possibly open, so if something
; isn't listed it assumes we can't open it and hides us from e.g. the Open
; With context menu, even if the user has tried to add us there manually.
; The list here was derived from the file /layout/build/components.conf,
; filtered down to only those types which make sense to open on their own
; in Firefox, basically meaning that plain text file types were left out,
; but not JSON or XML types because we have specific viewers for those.
${WriteApplicationsSupportedType} ${RegKey} ".apng"
${WriteApplicationsSupportedType} ${RegKey} ".bmp"
${WriteApplicationsSupportedType} ${RegKey} ".flac"
${WriteApplicationsSupportedType} ${RegKey} ".gif"
${WriteApplicationsSupportedType} ${RegKey} ".htm"
${WriteApplicationsSupportedType} ${RegKey} ".html"
${WriteApplicationsSupportedType} ${RegKey} ".ico"
${WriteApplicationsSupportedType} ${RegKey} ".jfif"
${WriteApplicationsSupportedType} ${RegKey} ".jpeg"
${WriteApplicationsSupportedType} ${RegKey} ".jpg"
${WriteApplicationsSupportedType} ${RegKey} ".json"
${WriteApplicationsSupportedType} ${RegKey} ".m4a"
${WriteApplicationsSupportedType} ${RegKey} ".mp3"
${WriteApplicationsSupportedType} ${RegKey} ".oga"
${WriteApplicationsSupportedType} ${RegKey} ".ogg"
${WriteApplicationsSupportedType} ${RegKey} ".ogv"
${WriteApplicationsSupportedType} ${RegKey} ".opus"
${WriteApplicationsSupportedType} ${RegKey} ".pdf"
${WriteApplicationsSupportedType} ${RegKey} ".pjpeg"
${WriteApplicationsSupportedType} ${RegKey} ".pjp"
${WriteApplicationsSupportedType} ${RegKey} ".png"
${WriteApplicationsSupportedType} ${RegKey} ".rdf"
${WriteApplicationsSupportedType} ${RegKey} ".shtml"
${WriteApplicationsSupportedType} ${RegKey} ".svg"
${WriteApplicationsSupportedType} ${RegKey} ".webm"
${WriteApplicationsSupportedType} ${RegKey} ".webp"
${WriteApplicationsSupportedType} ${RegKey} ".avif"
${WriteApplicationsSupportedType} ${RegKey} ".xht"
${WriteApplicationsSupportedType} ${RegKey} ".xhtml"
${WriteApplicationsSupportedType} ${RegKey} ".xml"
${EndIf}
!macroend
!define SetStartMenuInternet "!insertmacro SetStartMenuInternet"
; Add registry keys to support the Firefox 32 bit to 64 bit migration. These
; registry entries are not removed on uninstall at this time. After the Firefox
; 32 bit to 64 bit migration effort is completed these registry entries can be
; removed during install, post update, and uninstall.
!macro Set32to64DidMigrateReg
${GetLongPath} "$INSTDIR" $1
; These registry keys are always in the 32 bit hive since they are never
; needed by a Firefox 64 bit install unless it has been updated from Firefox
; 32 bit.
SetRegView 32
!ifdef HAVE_64BIT_BUILD
; Running Firefox 64 bit on Windows 64 bit
ClearErrors
ReadRegDWORD $2 HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
; If there were no errors then the system was updated from Firefox 32 bit to
; Firefox 64 bit and if the value is already 1 then the registry value has
; already been updated in the HKLM registry.
${IfNot} ${Errors}
${AndIf} $2 != 1
ClearErrors
WriteRegDWORD HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 1
${If} ${Errors}
; There was an error writing to HKLM so just write it to HKCU
WriteRegDWORD HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 1
${Else}
; This will delete the value from HKCU if it exists
DeleteRegValue HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
${EndIf}
${EndIf}
ClearErrors
ReadRegDWORD $2 HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
; If there were no errors then the system was updated from Firefox 32 bit to
; Firefox 64 bit and if the value is already 1 then the registry value has
; already been updated in the HKCU registry.
${IfNot} ${Errors}
${AndIf} $2 != 1
WriteRegDWORD HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 1
${EndIf}
!else
; Running Firefox 32 bit
${If} ${RunningX64}
${OrIf} ${IsNativeARM64}
; Running Firefox 32 bit on a Windows 64 bit system
ClearErrors
ReadRegDWORD $2 HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
; If there were errors the value doesn't exist yet.
${If} ${Errors}
ClearErrors
WriteRegDWORD HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 0
; If there were errors write the value in HKCU.
${If} ${Errors}
WriteRegDWORD HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 0
${EndIf}
${EndIf}
${EndIf}
!endif
ClearErrors
SetRegView lastused
!macroend
!define Set32to64DidMigrateReg "!insertmacro Set32to64DidMigrateReg"
; 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
; icon being displayed for files associated with Firefox (does not use SHCTX).
!macro FixShellIconHandler RegKey
; Find the correct key to update, either FirefoxHTML or FirefoxHTML-[PathHash]
StrCpy $3 "FirefoxHTML-$AppUserModelID"
ClearErrors
ReadRegStr $0 ${RegKey} "Software\Classes\$3\DefaultIcon" ""
${If} ${Errors}
StrCpy $3 "FirefoxHTML"
${EndIf}
ClearErrors
ReadRegStr $1 ${RegKey} "Software\Classes\$3\ShellEx\IconHandler" ""
${Unless} ${Errors}
ReadRegStr $1 ${RegKey} "Software\Classes\$3\DefaultIcon" ""
${GetLongPath} "$INSTDIR\${FileMainEXE}" $2
${If} "$1" != "$2,${IDI_DOCUMENT_ZERO_BASED}"
WriteRegStr ${RegKey} "Software\Classes\$3\DefaultIcon" "" "$2,${IDI_DOCUMENT_ZERO_BASED}"
${EndIf}
${EndUnless}
!macroend
!define FixShellIconHandler "!insertmacro FixShellIconHandler"
; Add Software\Mozilla\ registry entries (uses SHCTX).
; This expects $RegHive to already have been set correctly.
!macro SetAppKeys
; Check if this is an ESR release and if so add registry values so it is
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} $RegHive "$0" "Install Directory" "$8" 0
${WriteRegStr2} $RegHive "$0" "PathToExe" "$8\${FileMainEXE}" 0
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})\Uninstall"
${WriteRegStr2} $RegHive "$0" "Description" "${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" 0
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})"
${WriteRegStr2} $RegHive "$0" "" "${AppVersion}$3 (${ARCH} ${AB_CD})" 0
${If} "$3" == ""
DeleteRegValue SHCTX "$0" "ESR"
${Else}
${WriteRegDWORD2} $RegHive "$0" "ESR" 1 0
${EndIf}
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3\bin"
${WriteRegStr2} $RegHive "$0" "PathToExe" "$8\${FileMainEXE}" 0
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3\extensions"
${WriteRegStr2} $RegHive "$0" "Components" "$8\components" 0
${WriteRegStr2} $RegHive "$0" "Plugins" "$8\plugins" 0
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3"
${WriteRegStr2} $RegHive "$0" "GeckoVer" "${GREVersion}" 0
${If} "$3" == ""
DeleteRegValue SHCTX "$0" "ESR"
${Else}
${WriteRegDWORD2} $RegHive "$0" "ESR" 1 0
${EndIf}
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}$3"
${WriteRegStr2} $RegHive "$0" "" "${GREVersion}" 0
${WriteRegStr2} $RegHive "$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.
; This expects $RegHive to already have been set correctly.
!macro SetUninstallKeys
; Check if this is an ESR release and if so add registry values so it is
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:
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},${IDI_APPICON_ZERO_BASED}" 0
${WriteRegStr2} $1 "$0" "DisplayName" "${BrandFullNameInternal}$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} "$RegHive" == "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}" ""
${WordFind} "$0" "-" "+1{" $0
ReadRegStr $1 HKLM "Software\Classes\${FILE_TYPE}" ""
${WordFind} "$1" "-" "+1{" $1
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 HKCU 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).
; This expects $RegHive to already have been set correctly.
!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} $RegHive "$1\.shtml" "" "shtmlfile" 0
${WriteRegStr2} $RegHive "$1\.shtml" "Content Type" "text/html" 0
${WriteRegStr2} $RegHive "$1\.shtml" "PerceivedType" "text" 0
${EndIf}
ReadRegStr $0 HKCR ".xht" "Content Type"
${If} "$0" == ""
${WriteRegStr2} $RegHive "$1\.xht" "" "xhtfile" 0
${WriteRegStr2} $RegHive "$1\.xht" "Content Type" "application/xhtml+xml" 0
${EndIf}
ReadRegStr $0 HKCR ".xhtml" "Content Type"
${If} "$0" == ""
${WriteRegStr2} $RegHive "$1\.xhtml" "" "xhtmlfile" 0
${WriteRegStr2} $RegHive "$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-$AppUserModelID" $R9
${If} "$R9" == "true"
; An empty string is used for the 5th param because FirefoxHTML is not a
; protocol handler.
${AddDisabledDDEHandlerValues} "FirefoxHTML-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
"${AppRegName} HTML Document" ""
${Else}
${IsHandlerForInstallDir} "FirefoxHTML" $R9
${If} "$R9" == "true"
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
"${AppRegName} HTML Document" ""
${EndIf}
${EndIf}
; FirefoxPDF-* was added after FirefoxHTML and FirefoxURL, so we've never
; supported bare "FirefoxPDF". But we won't have it from the installer, so we
; add/update it unconditionally. `PostUpdate` is gated on `uninstall.log`
; being present, so the invocation here will only happen for installed
; directories, not unpackaged directories.
${AddDisabledDDEHandlerValues} "FirefoxPDF-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_PDF_ZERO_BASED}" \
"${AppRegName} PDF Document" ""
${IsHandlerForInstallDir} "FirefoxURL-$AppUserModelID" $R9
${If} "$R9" == "true"
${AddDisabledDDEHandlerValues} "FirefoxURL-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
"${AppRegName} URL" "true"
${Else}
${IsHandlerForInstallDir} "FirefoxURL" $R9
${If} "$R9" == "true"
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
"${AppRegName} URL" "true"
${EndIf}
${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"
; In the past, we supported ftp, so we need to delete any registration.
${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" "delete"
${EndIf}
${IsHandlerForInstallDir} "http" $R9
${If} "$R9" == "true"
${AddDisabledDDEHandlerValues} "http" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
${EndIf}
${IsHandlerForInstallDir} "https" $R9
${If} "$R9" == "true"
${AddDisabledDDEHandlerValues} "https" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
${EndIf}
${IsHandlerForInstallDir} "mailto" $R9
${If} "$R9" == "true"
${AddDisabledDDEHandlerValues} "mailto" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
${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}
${OrIf} ${IsNativeARM64}
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}
${OrIf} ${IsNativeARM64}
SetRegView lastused
${EndIf}
ClearErrors
${EndIf}
; Restore the previously used value back
Pop $R0
!macroend
!define AddMaintCertKeys "!insertmacro AddMaintCertKeys"
!endif
!macro RegisterAccessibleMarshal
${RegisterDLL} "$INSTDIR\AccessibleMarshal.dll"
!macroend
!define RegisterAccessibleMarshal "!insertmacro RegisterAccessibleMarshal"
; Removes various registry entries for reasons noted below (does not use SHCTX).
!macro RemoveDeprecatedKeys
StrCpy $0 "SOFTWARE\Classes"
; Remove support for launching chrome urls from the shell during install or
${RegCleanAppHandler} "chrome"
; Remove protocol handler registry keys added by the MS shim
DeleteRegKey HKLM "Software\Classes\Firefox.URL"
DeleteRegKey HKCU "Software\Classes\Firefox.URL"
; Unregister deprecated AccessibleHandler.dll.
${If} ${FileExists} "$INSTDIR\AccessibleHandler.dll"
${UnregisterDLL} "$INSTDIR\AccessibleHandler.dll"
${EndIf}
!macroend
!define RemoveDeprecatedKeys "!insertmacro RemoveDeprecatedKeys"
; Removes various directories and files for reasons noted below.
!macro RemoveDeprecatedFiles
${If} ${FileExists} "$INSTDIR\chrome.manifest"
Delete "$INSTDIR\chrome.manifest"
${EndIf}
${If} ${FileExists} "$INSTDIR\extensions\talkback@mozilla.org"
RmDir /r /REBOOTOK "$INSTDIR\extensions\talkback@mozilla.org"
${EndIf}
${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"
!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"
; For updates, adds a pinned shortcut to Task Bar on update for Windows 7
; and 8 if this macro has never been called before and the application
; is default (see PinToTaskBar for more details). This doesn't get called
; for Windows 10 and 11 on updates, so we will never pin on update there.
;
; For installs, adds a taskbar pin if SHOULD_PIN is 1. (Defaults to 1,
; but is controllable through the UI, ini file, and command line flags.)
!macro MigrateTaskBarShortcut SHOULD_PIN
${GetShortcutsLogPath} $0
${If} ${FileExists} "$0"
ClearErrors
ReadINIStr $1 "$0" "TASKBAR" "Migrated"
${If} ${Errors}
ClearErrors
WriteIniStr "$0" "TASKBAR" "Migrated" "true"
WriteRegDWORD HKCU \
"Software\Mozilla\${AppName}\Installer\$AppUserModelID" \
"WasPinnedToTaskbar" 1
${If} "${SHOULD_PIN}" == "1"
${PinToTaskBar}
${EndIf}
${EndIf}
${EndIf}
!macroend
!define MigrateTaskBarShortcut "!insertmacro MigrateTaskBarShortcut"
!define GetPinningSupportedByWindowsVersionWithoutSystemPopup "!insertmacro GetPinningSupportedByWindowsVersionWithoutSystemPopup "
; Starting with Windows 10 (> 10.0.19045.3996) and Windows 11 (> 10.0.22621.2361),
; the OS will show a system popup when trying to pin to the taskbar.
;
; Pass in the variable to put the output into. A '1' means pinning is supported on this
; OS without generating a popup, a '0' means pinning will generate a system popup.
;
; More info: a version of Windows was released that introduced a system popup when
; an exe (such as setup.exe) attempts to pin an app to the taskbar.
; We already handle pinning in the onboarding process once Firefox
; launches so we don't want to also attempt to pin it in the installer
; and have the OS ask the user for confirmation without the full context.
;
; The number for that version of windows is still unclear (it might be 22H2 or 23H2)
; and it's not supported by the version of WinVer.nsh we have anyways,
; so instead we are manually retrieving the major, minor, build and ubr numbers
; (Update Build Revision) and confirming that the build numbers work to do pinning
; in the installer.
;
; NOTE: there are currently running Windows where pinning fails and is a no-op. We haven't quite
; determined how to identify when that will happen, and it's so far only been reported
; on the newest versions of Windows. GetPinningSupportedByWindowsVersionWithoutSystemPopup
; will current report that pinning is not supported in these cases, due to reporting
; pinning as not supported on the newest builds of Windows.
;
!macro GetPinningSupportedByWindowsVersionWithoutSystemPopup outvar
!define pin_lbl lbl_GPSBWVWSP_${__COUNTER__}
Push $0
Push $1
Push $2
Push $3
${WinVerGetMajor} $0
${WinVerGetMinor} $1
${WinVerGetBuild} $2
; Get the UBR; only documented way I could figure out how to get this reliably
ClearErrors
ReadRegDWORD $3 HKLM \
"Software\Microsoft\Windows NT\CurrentVersion" \
"UBR"
; It's not obvious how to use LogicLib itself within a LogicLib custom
; operator, so we do everything by hand with `IntCmp`. The below lines
; translate to:
; StrCpy ${outvar} '0' ; default to false
; ${If} $0 == 10
; ${If} $1 == 0
; ${If} $2 < 19045
; StrCpy ${outvar} '1'
; ${ElseIf} $2 == 19045
; ; Test Windows 10
; ${If} $3 < 3996
; StrCpy ${outvar} '1'
; ${Endif}
; ; 22000 is the version number that splits between Win 10 and 11
; ${ElseIf} $2 >= 22000
; ; Test Windows 11
; ${If} $2 < 22621
; StrCpy ${outvar} '1'
; ${ElseIf} $2 == 22621
; ${If} $3 < 2361
; StrCpy ${outvar} '1'
; ${EndIf}
; ${EndIf}
; ${EndIf}
; ${Endif}
; ${EndIf}
StrCpy ${outvar} '0' ; default to false on pinning
; If the major version is greater than 10, no pinning in setup
IntCmp $0 10 "" "" ${pin_lbl}_bad
; If the minor version is greater than 0, no pinning in setup
IntCmp $1 0 "" "" ${pin_lbl}_bad
; If the build number equals 19045, we have to test the UBR
; If it's greater than 19045, then we have to check if
; it's a Windows 11 build or not to determine if more testing
; is needed
IntCmp $2 19045 ${pin_lbl}_test_win10 ${pin_lbl}_good ""
; If the major number is less than 22000, then we're between
; 19046 and 22000, meaning pinning will produce a popup
IntCmp $2 22000 "" ${pin_lbl}_bad ""
${pin_lbl}_test_win11:
; If the build number is less than 22621, jump to pinning; if greater than, no pinning
IntCmp $2 22621 "" ${pin_lbl}_good ${pin_lbl}_bad
; Only if the version is 10.0.22621 do we fall through to here
; If the UBR is greater than or equal to 2361, jump to no pinning
; Otherwise jump to pinning
IntCmp $3 2361 ${pin_lbl}_bad ${pin_lbl}_good ${pin_lbl}_bad
${pin_lbl}_test_win10:
; Only if the version is 10.0.19045 or greater (but not Windows 11) do we fall
; through to here.
; If the UBR is greater than or equal to 3996, jump to no pinning
IntCmp $3 3996 ${pin_lbl}_bad ${pin_lbl}_good ${pin_lbl}_bad
${pin_lbl}_good:
StrCpy ${outvar} '1'
${pin_lbl}_bad:
!undef pin_lbl
Pop $3
Pop $2
Pop $1
Pop $0
!macroend
!macro _PinningSupportedByWindowsVersionWithoutSystemPopup _ignore _ignore2 _t _f
!insertmacro _LOGICLIB_TEMP
${GetPinningSupportedByWindowsVersionWithoutSystemPopup} $_LOGICLIB_TEMP
!insertmacro _= $_LOGICLIB_TEMP "1" `${_t}` `${_f}`
!macroend
; The following is to make if statements for the functionality easier. When using an if statement,
; Use IsPinningSupportedByWindowsVersionWithoutSystemPopup like so, instead of GetPinningSupportedByWindowsVersionWithoutSystemPopup:
;
; ${If} ${IsPinningSupportedByWindowsVersionWithoutSystemPopup}
; ; do something
; ${EndIf}
;
!define IsPinningSupportedByWindowsVersionWithoutSystemPopup `"" PinningSupportedByWindowsVersionWithoutSystemPopup "" `
; 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.
; This expects $RegHive to already have been set correctly.
!macro PinToTaskBar
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}
${If} ${AtMostWaaS} 1809
; In Windows 10 the "Pin to Taskbar" resource was removed, so we
; can't access the verb that way anymore. We have to create a
; command key using the GUID that's assigned to this action and
; then invoke that as a verb. This works up until build 1809
ReadRegStr $R9 HKLM \
"Software\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Windows.taskbarpin" \
"ExplorerCommandHandler"
WriteRegStr HKCU "Software\Classes\*\shell\${AppRegName}-$AppUserModelID" "ExplorerCommandHandler" $R9
InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "${AppRegName}-$AppUserModelID"
DeleteRegKey HKCU "Software\Classes\*\shell\${AppRegName}-$AppUserModelID"
${Else}
; In Windows 10 1903 and up, and Windows 11 prior to 22H2, the above no
; longer works. We have yet another method for these versions
; which is detailed in the PinToTaskbar plugin code.
${If} ${IsPinningSupportedByWindowsVersionWithoutSystemPopup}
PinToTaskbar::Pin "$SMPROGRAMS\$1"
${EndIf}
${EndIf}
; Delete the shortcut if it was created
${If} "$8" == "true"
Delete "$SMPROGRAMS\$1"
${EndIf}
${EndIf}
${If} $RegHive == "HKCU"
SetShellVarContext current ; Set SHCTX to the current user
${Else}
SetShellVarContext all ; Set SHCTX to all users
${EndIf}
${EndUnless}
${EndIf}
${EndIf}
!macroend
!define PinToTaskBar "!insertmacro PinToTaskBar"
; 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
; 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} "${BrandShortName}.lnk"
${LogQuickLaunchShortcut} "${BrandShortName}.lnk"
${LogDesktopShortcut} "${BrandShortName}.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 "freebl3.dll"
Push "nssckbi.dll"
Push "nspr4.dll"
Push "nssdbm3.dll"
Push "mozsqlite3.dll"
Push "xpcom.dll"
Push "crashreporter.exe"
Push "default-browser-agent.exe"
Push "nmhproxy.exe"
Push "pingsender.exe"
Push "updater.exe"
Push "mozwer.dll"
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.
; 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_STATUS so its status can be queried.
System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_STATUS}) i.R7'
${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. 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
; See if we're using path hash suffixed registry keys for this install
${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
ClearErrors
ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
${If} ${Errors}
ClearErrors
ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
${EndIf}
StrCpy $0 $0 -2
${If} $0 != $8
${If} $AppUserModelID == ""
${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
${EndIf}
StrCpy $R9 "${AppRegName}-$AppUserModelID"
${EndIf}
; Set ourselves as the user's selected StartMenuInternet browser, but only
; if we have StartMenuInternet registry keys that are for this install.
ClearErrors
ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
${If} ${Errors}
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"
; This function cannot do anything to actually set the default browser,
; it can only set up the registry entries to allow the user to do so.
; Getting here means that those entries already exist for this
; installation, we just found them, so there is nothing more to be
; done.
Return
${EndIf}
${EndIf}
${EndUnless}
SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU)
; It's unlikely that we didn't find a StartMenuInternet key above, but it is
; possible; it likely would mean this copy of the application was extracted
; directly from a ZIP file and the installer was never run.
${SetStartMenuInternet} "HKCU"
${FixShellIconHandler} "HKCU"
${FixClassKeys} ; Does not use SHCTX
${SetHandlers}
; Only register as the handler 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" "$R9"
${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::SetAppAsDefault "$R9" ".htm" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" ".html" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" ".shtml" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" ".webp" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" ".avif" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" ".xht" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" ".xhtml" "file"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" "http" "protocol"
Pop $0
AppAssocReg::SetAppAsDefault "$R9" "https" "protocol"
Pop $0
${EndUnless}
${RemoveDeprecatedKeys}
${MigrateTaskBarShortcut} "$R0"
FunctionEnd
; Helper for updating the shortcut application model IDs.
Function FixShortcutAppModelIDs
${If} "$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
; AddTaskbarSC is needed by MigrateTaskBarShortcut, which is called by
; SetAsDefaultAppUserHKCU. If this is called via ExecCodeSegment,
; MigrateTaskBarShortcut will not see the value of AddTaskbarSC, so we
; send it via a register instead.
StrCpy $R0 $AddTaskbarSC
; We want to avoid having a UAC prompt since we'll already have another
; action for control panel default browser selection popping upto the user.
; The start menu keys can be added into HKCU. The call to
; SetAsDefaultAppUserHKCU will have already set the HKCU keys for
; SetStartMenuInternet.
; 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}
FunctionEnd
!define SetAsDefaultAppUser "Call SetAsDefaultAppUser"
!endif ; NO_LOG
!ifdef MOZ_LAUNCHER_PROCESS
!macro ResetLauncherProcessDefaults
# By deleting these values, we remove remnants of any force-disable settings
# that may have been set during the SHIELD study in 67. Note that this setting
# was only intended to distinguish between test and control groups for the
# purposes of the study, not as a user preference.
DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Launcher"
DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Browser"
!macroend
!define ResetLauncherProcessDefaults "!insertmacro ResetLauncherProcessDefaults"
!endif
!macro WriteToastNotificationRegistration RegKey
; Find or create a GUID to use for this installation. For simplicity, We
; always update our registration.
ClearErrors
ReadRegStr $0 SHCTX "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator"
${If} "$0" == ""
; Create a GUID.
System::Call "rpcrt4::UuidCreate(g . r0)i"
; StringFromGUID2 (which is what System::Call uses internally to stringify
; GUIDs) includes braces in its output. In this case, we want the braces.
${EndIf}
; Check if this is an ESR release.
ClearErrors
${WordFind} "${UpdateChannel}" "esr" "E#" $1
${If} ${Errors}
StrCpy $1 ""
${Else}
StrCpy $1 " ESR"
${EndIf}
; Write the following keys and values to the registry.
; HKEY_CURRENT_USER\Software\Classes\AppID\{GUID} DllSurrogate : REG_SZ = ""
; \AppUserModelId\{ToastAumidPrefix}{install hash} CustomActivator : REG_SZ = {GUID}
; DisplayName : REG_EXPAND_SZ = {display name}
; IconUri : REG_EXPAND_SZ = {icon path}
; \CLSID\{GUID} AppID : REG_SZ = {GUID}
; \InprocServer32 (Default) : REG_SZ = {notificationserver.dll path}
${WriteRegStr2} ${RegKey} "Software\Classes\AppID\$0" "DllSurrogate" "" 0
${WriteRegStr2} ${RegKey} "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator" "$0" 0
${WriteRegStr2} ${RegKey} "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "DisplayName" "${BrandFullNameInternal}$1" 0
; Sadly, we can't use embedded resources like `firefox.exe,1`.
${WriteRegStr2} ${RegKey} "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "IconUri" "$INSTDIR\browser\VisualElements\VisualElements_70.png" 0
${WriteRegStr2} ${RegKey} "Software\Classes\CLSID\$0" "AppID" "$0" 0
${WriteRegStr2} ${RegKey} "Software\Classes\CLSID\$0\InProcServer32" "" "$INSTDIR\notificationserver.dll" 0
!macroend
!define WriteToastNotificationRegistration "!insertmacro WriteToastNotificationRegistration"
/**
* Deletes the registry keys for a protocol handler but only if those registry
* keys were pointed to the installation being uninstalled.
* Does this with both the HKLM and the HKCU registry entries.
*
* @param _PROTOCOL
* The protocol to delete the registry keys for
*/
!macro DeleteProtocolRegistryIfSetToInstallation INSTALL_PATH _PROTOCOL
Push $0
; Check if there is a protocol handler registered by fetching the DefaultIcon value
; in the registry.
; If there is something registered for the icon, it will be the path to the executable,
; plus a comma and a number for the id of the resource for the icon.
; Use StrCpy with -2 to remove the comma and the resource id so that
; the whole path to the executable can be compared against what's being
; uninstalled.
; Do all of that twice, once for the local machine and once for the current user
; Remove protocol handlers
ClearErrors
ReadRegStr $0 HKLM "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
${If} $0 != ""
StrCpy $0 $0 -2
${If} $0 == '"${INSTALL_PATH}"'
DeleteRegKey HKLM "Software\Classes\${_PROTOCOL}"
${EndIf}
${EndIf}
ClearErrors
ReadRegStr $0 HKCU "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
${If} $0 != ""
StrCpy $0 $0 -2
${If} $0 == '"${INSTALL_PATH}"'
DeleteRegKey HKCU "Software\Classes\${_PROTOCOL}"
${EndIf}
${EndIf}
ClearErrors
Pop $0
!macroend
!define DeleteProtocolRegistryIfSetToInstallation '!insertmacro DeleteProtocolRegistryIfSetToInstallation'