tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

shared.nsh (83120B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 ; Generated by DeriveCapabilitySidsFromName with the name "lpacFirefoxInstallFiles"
      6 !define LpacFirefoxInstallFilesSid "S-1-15-3-1024-1238444810-1356253261-2257478630-1143196962-1563090664-2414759320-1282101916-4218287853"
      7 
      8 !include WinVer.nsh
      9 !include postupdate_helper.nsh
     10 !include control_utils.nsh
     11 
     12 !macro PostUpdate
     13  ${CreateShortcutsLog}
     14 
     15  ; Remove registry entries for non-existent apps and for apps that point to our
     16  ; install location in the Software\Mozilla key and uninstall registry entries
     17  ; that point to our install location for both HKCU and HKLM.
     18  SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
     19  ${RegCleanMain} "Software\Mozilla"
     20  ${RegCleanUninstall}
     21  ${UpdateProtocolHandlers}
     22 
     23  ; setup the application model id registration value
     24  ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
     25 
     26  ClearErrors
     27  WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test"
     28  ${If} ${Errors}
     29    StrCpy $RegHive "HKCU"
     30  ${Else}
     31    SetShellVarContext all    ; Set SHCTX to all users (e.g. HKLM)
     32    DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest"
     33    StrCpy $RegHive "HKLM"
     34    ${RegCleanMain} "Software\Mozilla"
     35    ${RegCleanUninstall}
     36    ${UpdateProtocolHandlers}
     37    ${FixShellIconHandler} "HKLM"
     38    ${SetAppLSPCategories} ${LSP_CATEGORIES}
     39 
     40    ; Add the Firewall entries after an update
     41    Call AddFirewallEntries
     42 
     43    ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
     44    ${If} "$0" != "${GREVersion}"
     45      WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}"
     46    ${EndIf}
     47  ${EndIf}
     48 
     49  !ifdef DESKTOP_LAUNCHER_ENABLED
     50    Call OnUpdateDesktopLauncherHandler
     51  !endif
     52 
     53  ; Update the name/icon/AppModelID of our shortcuts as needed, then update the
     54  ; lastwritetime of the Start Menu shortcut to clear the tile icon cache.
     55  ; Do this for both shell contexts in case the user has shortcuts in multiple
     56  ; locations, then restore the previous context at the end.
     57  SetShellVarContext all
     58  ${UpdateShortcutsBranding}
     59  ${TouchStartMenuShortcut}
     60  Call FixShortcutAppModelIDs
     61  SetShellVarContext current
     62  ${UpdateShortcutsBranding}
     63  ${TouchStartMenuShortcut}
     64  Call FixShortcutAppModelIDs
     65  ${If} $RegHive == "HKLM"
     66    SetShellVarContext all
     67  ${ElseIf} $RegHive == "HKCU"
     68    SetShellVarContext current
     69  ${EndIf}
     70 
     71  ${RemoveDeprecatedKeys}
     72  ${Set32to64DidMigrateReg}
     73 
     74  ${SetAppKeys}
     75  ${FixClassKeys}
     76  ${SetUninstallKeys}
     77  ${If} $RegHive == "HKLM"
     78    ${SetStartMenuInternet} HKLM
     79  ${ElseIf} $RegHive == "HKCU"
     80    ${SetStartMenuInternet} HKCU
     81  ${EndIf}
     82 
     83  ; Remove files that may be left behind by the application in the
     84  ; VirtualStore directory.
     85  ${CleanVirtualStore}
     86 
     87  ${RemoveDeprecatedFiles}
     88 
     89  ; Fix the distribution.ini file if applicable
     90  ${FixDistributionsINI}
     91 
     92  ; https://bugzilla.mozilla.org/show_bug.cgi?id=1616355
     93  ; Migrate postSigningData file if present, and if it doesn't already exist.
     94  ${GetLocalAppDataFolder} $0
     95  ${If} ${FileExists} "$INSTDIR\postSigningData"
     96    ; If it already exists, just delete the appdata one.
     97    ; It's possible this was for a different install, but it's impossible to
     98    ; know for sure, so we may as well just get rid of it.
     99    Delete /REBOOTOK "$0\Mozilla\Firefox\postSigningData"
    100  ${Else}
    101    ${If} ${FileExists} "$0\Mozilla\Firefox\postSigningData"
    102      Rename "$0\Mozilla\Firefox\postSigningData" "$INSTDIR\postSigningData"
    103    ${EndIf}
    104  ${EndIf}
    105 
    106  RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}"
    107 
    108  ; Register AccessibleMarshal.dll with COM (this requires write access to HKLM)
    109  ${RegisterAccessibleMarshal}
    110 
    111  ; Record the Windows Error Reporting module
    112  WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" "$INSTDIR\mozwer.dll" 0
    113 
    114  ; Apply LPAC permissions to install directory.
    115  Push "Marker"
    116  AccessControl::GrantOnFile \
    117    "$INSTDIR" "(${LpacFirefoxInstallFilesSid})" "GenericRead + GenericExecute"
    118  Pop $TmpVal ; get "Marker" or error msg
    119  ${If} $TmpVal != "Marker"
    120    Pop $TmpVal ; get "Marker"
    121  ${EndIf}
    122 
    123 !ifdef MOZ_MAINTENANCE_SERVICE
    124  Call IsUserAdmin
    125  Pop $R0
    126  ${If} $R0 == "true"
    127  ; Only proceed if we have HKLM write access
    128  ${AndIf} $RegHive == "HKLM"
    129    ; We check to see if the maintenance service install was already attempted.
    130    ; Since the Maintenance service can be installed either x86 or x64,
    131    ; always use the 64-bit registry for checking if an attempt was made.
    132    ${If} ${RunningX64}
    133    ${OrIf} ${IsNativeARM64}
    134      SetRegView 64
    135    ${EndIf}
    136    ReadRegDWORD $5 HKLM "Software\Mozilla\MaintenanceService" "Attempted"
    137    ClearErrors
    138    ${If} ${RunningX64}
    139    ${OrIf} ${IsNativeARM64}
    140      SetRegView lastused
    141    ${EndIf}
    142 
    143    ; Add the registry keys for allowed certificates.
    144    ${AddMaintCertKeys}
    145 
    146    ; If the maintenance service is already installed, do nothing.
    147    ; The maintenance service will launch:
    148    ; maintenanceservice_installer.exe /Upgrade to upgrade the maintenance
    149    ; service if necessary.   If the update was done from updater.exe without
    150    ; the service (i.e. service is failing), updater.exe will do the update of
    151    ; the service.  The reasons we do not do it here is because we don't want
    152    ; to have to prompt for limited user accounts when the service isn't used
    153    ; and we currently call the PostUpdate twice, once for the user and once
    154    ; for the SYSTEM account.  Also, this would stop the maintenance service
    155    ; and we need a return result back to the service when run that way.
    156    ${If} $5 == ""
    157      ; An install of maintenance service was never attempted.
    158      ; We know we are an Admin and that we have write access into HKLM
    159      ; based on the above checks, so attempt to just run the EXE.
    160      ; In the worst case, in case there is some edge case with the
    161      ; IsAdmin check and the permissions check, the maintenance service
    162      ; will just fail to be attempted to be installed.
    163      nsExec::Exec "$\"$INSTDIR\maintenanceservice_installer.exe$\""
    164    ${EndIf}
    165  ${EndIf}
    166 !endif
    167 
    168 !ifdef MOZ_LAUNCHER_PROCESS
    169  ${ResetLauncherProcessDefaults}
    170 !endif
    171 
    172  ${WriteToastNotificationRegistration} $RegHive
    173 
    174 ; Make sure the scheduled task registration for the default browser agent gets
    175 ; updated, but only if we're not the instance of PostUpdate that was started
    176 ; by the service, because this needs to run as the actual user. Also, don't do
    177 ; that if the installer was told not to register the agent task at all.
    178 ; XXXbytesized - This also needs to un-register any scheduled tasks for the WDBA
    179 ;                that were registered using elevation, but currently it does
    180 ;                not. See Bugs 1638509 and 1902719.
    181 !ifdef MOZ_DEFAULT_BROWSER_AGENT
    182 ${If} $RegHive == "HKCU"
    183  ClearErrors
    184  ReadRegDWORD $0 HKCU "Software\Mozilla\${AppName}\Installer\$AppUserModelID" \
    185                    "DidRegisterDefaultBrowserAgent"
    186  ${If} $0 != 0
    187  ${OrIf} ${Errors}
    188    ExecWait '"$INSTDIR\default-browser-agent.exe" register-task $AppUserModelID'
    189  ${EndIf}
    190 ${EndIf}
    191 !endif
    192 
    193 ${RemoveDefaultBrowserAgentShortcut}
    194 !macroend
    195 !define PostUpdate "!insertmacro PostUpdate"
    196 
    197 ; Update the last modified time on the Start Menu shortcut, so that its icon
    198 ; gets refreshed. Should be called on Win8+ after UpdateShortcutBranding.
    199 !macro TouchStartMenuShortcut
    200  ${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    201    FileOpen $0 "$SMPROGRAMS\${BrandShortName}.lnk" a
    202    ${IfNot} ${Errors}
    203      System::Call '*(i, i) p .r1'
    204      System::Call 'kernel32::GetSystemTimeAsFileTime(p r1)'
    205      System::Call 'kernel32::SetFileTime(p r0, i 0, i 0, p r1) i .r2'
    206      System::Free $1
    207      FileClose $0
    208    ${EndIf}
    209  ${EndIf}
    210 !macroend
    211 !define TouchStartMenuShortcut "!insertmacro TouchStartMenuShortcut"
    212 
    213 !macro AddPrivateBrowsingShortcut
    214  ${IfNot} ${FileExists} "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk"
    215    CreateShortcut "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$INSTDIR\${PrivateBrowsingEXE}" "" "$INSTDIR\${PrivateBrowsingEXE}" ${IDI_PBICON_PB_EXE_ZERO_BASED}
    216    ShellLink::SetShortcutWorkingDirectory "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$INSTDIR"
    217    ShellLink::SetShortcutDescription "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$(PRIVATE_BROWSING_SHORTCUT_TITLE)"
    218    ApplicationID::Set "$SMPROGRAMS\$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk" "$AppUserModelID;PrivateBrowsingAUMID" "true"
    219    ${LogStartMenuShortcut} "$(PRIVATE_BROWSING_SHORTCUT_TITLE).lnk"
    220  ${EndIf}
    221 !macroend
    222 !define AddPrivateBrowsingShortcut "!insertmacro AddPrivateBrowsingShortcut"
    223 
    224 !macro SetAsDefaultAppGlobal
    225  ${RemoveDeprecatedKeys} ; Does not use SHCTX
    226 
    227  SetShellVarContext all      ; Set SHCTX to all users (e.g. HKLM)
    228  ${SetHandlers} ; Uses SHCTX
    229  ${SetStartMenuInternet} "HKLM"
    230  ${FixShellIconHandler} "HKLM"
    231  ${ShowShortcuts}
    232 !macroend
    233 !define SetAsDefaultAppGlobal "!insertmacro SetAsDefaultAppGlobal"
    234 
    235 ; Removes shortcuts for this installation. This should also remove the
    236 ; application from Open With for the file types the application handles
    237 ; (bug 370480).
    238 !macro HideShortcuts
    239  ; Find the correct registry path to clear IconsVisible.
    240  StrCpy $R1 "Software\Clients\StartMenuInternet\${AppRegName}-$AppUserModelID\InstallInfo"
    241  ReadRegDWORD $0 HKLM "$R1" "ShowIconsCommand"
    242  ${If} ${Errors}
    243    ${StrFilter} "${FileMainEXE}" "+" "" "" $0
    244    StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
    245  ${EndIf}
    246  WriteRegDWORD HKLM "$R1" "IconsVisible" 0
    247  WriteRegDWORD HKCU "$R1" "IconsVisible" 0
    248 
    249  SetShellVarContext all  ; Set $DESKTOP to All Users
    250  ${Unless} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    251    SetShellVarContext current  ; Set $DESKTOP to the current user's desktop
    252  ${EndUnless}
    253 
    254  ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    255    ShellLink::GetShortCutArgs "$DESKTOP\${BrandShortName}.lnk"
    256    Pop $0
    257    ${If} "$0" == ""
    258      ShellLink::GetShortCutTarget "$DESKTOP\${BrandShortName}.lnk"
    259      Pop $0
    260      ${GetLongPath} "$0" $0
    261      ${If} "$0" == "$INSTDIR\${FileMainEXE}"
    262        Delete "$DESKTOP\${BrandShortName}.lnk"
    263      ${EndIf}
    264    ${EndIf}
    265  ${EndIf}
    266 
    267  SetShellVarContext all  ; Set $SMPROGRAMS to All Users
    268  ${Unless} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    269    SetShellVarContext current  ; Set $SMPROGRAMS to the current user's Start
    270                                ; Menu Programs directory
    271  ${EndUnless}
    272 
    273  ${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    274    ShellLink::GetShortCutArgs "$SMPROGRAMS\${BrandShortName}.lnk"
    275    Pop $0
    276    ${If} "$0" == ""
    277      ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandShortName}.lnk"
    278      Pop $0
    279      ${GetLongPath} "$0" $0
    280      ${If} "$0" == "$INSTDIR\${FileMainEXE}"
    281        Delete "$SMPROGRAMS\${BrandShortName}.lnk"
    282      ${EndIf}
    283    ${EndIf}
    284  ${EndIf}
    285 
    286  ${If} ${FileExists} "$QUICKLAUNCH\${BrandShortName}.lnk"
    287    ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandShortName}.lnk"
    288    Pop $0
    289    ${If} "$0" == ""
    290      ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandShortName}.lnk"
    291      Pop $0
    292      ${GetLongPath} "$0" $0
    293      ${If} "$0" == "$INSTDIR\${FileMainEXE}"
    294        Delete "$QUICKLAUNCH\${BrandShortName}.lnk"
    295      ${EndIf}
    296    ${EndIf}
    297  ${EndIf}
    298 !macroend
    299 !define HideShortcuts "!insertmacro HideShortcuts"
    300 
    301 ; Looks for the desktop shortcut (.lnk) in the $DESKTOP directory
    302 ; relative to the shell var context. Caller is expected to call
    303 ; SetShellVarContext to set the shell var context.
    304 ; Args: none
    305 ; Return value is pushed onto the stack: "1" if the shortcut
    306 ;    is found, "0" otherwise
    307 Function IsDesktopShortcutPresent
    308  Push $0 ; will be used to store the result
    309  Push $1 ; will be used as a temp variable
    310  StrCpy $0 "0"
    311 
    312  ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    313    ShellLink::GetShortCutArgs "$DESKTOP\${BrandShortName}.lnk"
    314    Pop $1
    315    ${If} "$1" == ""
    316      ; Let's see if we can find out anything about the shortcut
    317      ShellLink::GetShortCutTarget "$DESKTOP\${BrandShortName}.lnk"
    318      Pop $1
    319      ${GetLongPath} "$1" $1
    320      ${If} "$1" == "$INSTDIR\${FileMainEXE}"
    321        ; We had permission to look at the shortcut properties and its target was the Firefox executable
    322        StrCpy $0 "1" ; set the result to 1
    323      ${ElseIf} "$1" == ""
    324        ; Most likely case is that we don't have permission to read the shortcut properties, so just report that it exists
    325        StrCpy $0 "1" ; set the result to 1
    326      ${EndIf}
    327    ${EndIf}
    328  ${EndIf}
    329  Pop $1 ; restore the register
    330  Exch $0 ; restore the register and place result on the stack
    331 FunctionEnd
    332 
    333 
    334 ; Installs the desktop launcher and sets a registry key to show that we did it.
    335 Function InstallDesktopLauncher
    336  ClearErrors
    337  ; Copy the launcher into the user's Desktop with an appropriate name
    338  CopyFiles /SILENT /FILESONLY "$INSTDIR\desktop-launcher\desktop-launcher.exe" "$DESKTOP\${BrandShortName}.exe"
    339  ${If} ${FileExists} "$DESKTOP\${BrandShortName}.exe"
    340    WriteRegDWORD HKCU "Software\Mozilla\${BrandFullNameInternal}" DesktopLauncherAppInstalled 1
    341  ${EndIf}
    342 FunctionEnd
    343 
    344 
    345 Function OnUpdateDesktopLauncher_HKLM
    346  ; This is elevated. In this instance, we won't be installing  the desktop launcher, but we may be deleting the shared shortcut
    347  Push $0
    348  Push $1
    349  ; Have we deleted the shared shortcut before?
    350  StrCpy $0 "0"
    351  ReadRegDWORD $0 HKLM "Software\Mozilla\${BrandFullNameInternal}" "UpdaterDeletedShortcut"
    352  Call IsDesktopShortcutPresent
    353  Pop $1
    354  ${If} $0 != "1"
    355  ${AndIf} $1 != "0"
    356    ; shared shortcut exists, and we haven't deleted it before. So let's delete it now.
    357    Delete "$DESKTOP\${BrandShortName}.lnk"
    358    WriteRegDWORD HKLM "Software\Mozilla\${BrandFullNameInternal}" "UpdaterDeletedShortcut" "1"
    359  ${EndIf}
    360  Pop $1
    361  Pop $0
    362 FunctionEnd
    363 
    364 Function OnUpdateDesktopLauncher_HKCU
    365  ; If there is a desktop launcher installed, call InstallDesktopLauncher (this is how the launcher gets updated)
    366  ${If} ${FileExists} "$DESKTOP\${BrandShortName}.exe"
    367    Call InstallDesktopLauncher
    368    ; Early return
    369    Return
    370  ${EndIf}
    371 
    372  Push $0
    373  Push $1
    374  Push $2
    375  Push $3
    376 
    377  ; $0 is 1 if a shortcut is found in user's desktop or 0 otherwise
    378  StrCpy $0 "0"
    379  ; $1 is 1 if there was a "recently deleted" shortcut or 0 otherwise
    380  StrCpy $1 "0"
    381  ; $2 is 1 if the desktop launcher was ever installed or 0 otherwise
    382  StrCpy $2 "0"
    383  ; $3 is 1 if a shortcut is found in shared desktop or 0 otherwise
    384  StrCpy $3 "0"
    385 
    386  ; see if there is a shortcut on the user's own desktop
    387  Call IsDesktopShortcutPresent
    388  Pop $0
    389 
    390  ; see if there is a shortcut in the shared desktop folder
    391  SetShellVarContext all
    392  Call IsDesktopShortcutPresent
    393  Pop $3
    394  SetShellVarContext current
    395 
    396  ReadRegDWORD $1 HKLM "Software\Mozilla\${BrandFullNameInternal}" "UpdaterDeletedShortcut"
    397  ReadRegDWORD $2 HKCU "Software\Mozilla\${BrandFullNameInternal}" "DesktopLauncherAppInstalled"
    398 
    399  ${If} $2 == "1"
    400    ; We previously installed desktop launcher. Don't reinstall
    401  ${ElseIf} $0 == "1"
    402    ; There was a shortcut on the user's desktop. Delete it and install launcher
    403    Delete "$DESKTOP\${BrandShortName}.lnk"
    404    Call InstallDesktopLauncher
    405  ${ElseIf} $1 == "1"
    406  ${OrIf} $3 == "1"
    407    ; This block covers these two cases:
    408    ; - If the elevated post-update script runs before the unelevated one, then it will have deleted the shortcut and set the UpdaterDeletedShortcut regkey.
    409    ; - Or, if the unelevated script is running now befor the elevated one, then there will still be a shortcut in the shared location.
    410    ; In either case, we need to install the desktop launcher now. It's the responsibility of the elevated post-update script to delete
    411    ; the shared shortcut, and that is implemented in OnUpdateDesktopLauncher_HKLM
    412    Call InstallDesktopLauncher
    413  ${EndIf}
    414  Pop $3
    415  Pop $2
    416  Pop $1
    417  Pop $0
    418 FunctionEnd
    419 
    420 Function OnUpdateDesktopLauncherHandler
    421  Push $0
    422  Push "$INSTDIR\installation_telemetry.json"
    423  Call GetInstallationType
    424  ; Pop the result from the stack into $0
    425  Pop $0
    426  ${If} $0 == "stub"
    427    ${If} $RegHive == "HKLM"
    428      SetShellVarContext all
    429      Call OnUpdateDesktopLauncher_HKLM
    430    ${Else}
    431      SetShellVarContext current
    432      Call OnUpdateDesktopLauncher_HKCU
    433    ${EndIf}
    434  ${EndIf}
    435  ; Restore $0 to its original value
    436  Pop $0
    437 FunctionEnd
    438 
    439 ; For new installs, install desktop launcher
    440 ; TODO: This case needs more nuance. To be fixed as part of Bug 1981597
    441 Function OnInstallDesktopLauncherHandler
    442  Push $0
    443  ${SwapShellVarContext} current $0
    444  Call InstallDesktopLauncher
    445  ${SetShellVarContextToValue} $0
    446  Pop $0
    447 FunctionEnd
    448 
    449 Function CreateDesktopShortcuts
    450  SetShellVarContext all  ; Set $DESKTOP to All Users
    451  ${Unless} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    452    CreateShortCut "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
    453    ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    454      ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR"
    455      ${If} "$AppUserModelID" != ""
    456        ApplicationID::Set "$DESKTOP\${BrandShortName}.lnk" "$AppUserModelID" "true"
    457      ${EndIf}
    458    ${Else}
    459      SetShellVarContext current  ; Set $DESKTOP to the current user's desktop
    460      ${Unless} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    461        CreateShortCut "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
    462        ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    463          ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandShortName}.lnk" \
    464                                                 "$INSTDIR"
    465          ${If} "$AppUserModelID" != ""
    466            ApplicationID::Set "$DESKTOP\${BrandShortName}.lnk" "$AppUserModelID" "true"
    467          ${EndIf}
    468        ${EndIf}
    469      ${EndUnless}
    470    ${EndIf}
    471  ${EndUnless}
    472 FunctionEnd
    473 
    474 Function DeleteDesktopShortcut
    475  ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
    476    Delete "$DESKTOP\${BrandShortName}.lnk"
    477  ${EndIf}
    478 FunctionEnd
    479 
    480 ; Adds shortcuts for this installation. This should also add the application
    481 ; to Open With for the file types the application handles (bug 370480).
    482 !macro ShowShortcuts
    483  ; Find the correct registry path to set IconsVisible.
    484  StrCpy $R1 "Software\Clients\StartMenuInternet\${AppRegName}-$AppUserModelID\InstallInfo"
    485  ReadRegDWORD $0 HKLM "$R1" "ShowIconsCommand"
    486  ${If} ${Errors}
    487    ${StrFilter} "${FileMainEXE}" "+" "" "" $0
    488    StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
    489  ${EndIf}
    490  WriteRegDWORD HKLM "$R1" "IconsVisible" 1
    491  WriteRegDWORD HKCU "$R1" "IconsVisible" 1
    492 
    493  SetShellVarContext all  ; Set $SMPROGRAMS to All Users
    494  ${Unless} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    495    CreateShortCut "$SMPROGRAMS\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
    496    ${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    497      ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandShortName}.lnk" \
    498                                             "$INSTDIR"
    499      ${If} "$AppUserModelID" != ""
    500        ApplicationID::Set "$SMPROGRAMS\${BrandShortName}.lnk" "$AppUserModelID" "true"
    501      ${EndIf}
    502    ${Else}
    503      SetShellVarContext current  ; Set $SMPROGRAMS to the current user's Start
    504                                  ; Menu Programs directory
    505      ${Unless} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    506        CreateShortCut "$SMPROGRAMS\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
    507        ${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
    508          ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandShortName}.lnk" \
    509                                                 "$INSTDIR"
    510          ${If} "$AppUserModelID" != ""
    511            ApplicationID::Set "$SMPROGRAMS\${BrandShortName}.lnk" "$AppUserModelID" "true"
    512          ${EndIf}
    513        ${EndIf}
    514      ${EndUnless}
    515    ${EndIf}
    516  ${EndUnless}
    517 !macroend
    518 !define ShowShortcuts "!insertmacro ShowShortcuts"
    519 
    520 ; Update the branding name on all shortcuts our installer created
    521 ; to convert from BrandFullName (which is what we used to name shortcuts)
    522 ; to BrandShortName (which is what we now name shortcuts). We only rename
    523 ; desktop and start menu shortcuts, because touching taskbar pins often
    524 ; (but inconsistently) triggers various broken behaviors in the shell.
    525 ; This assumes SHCTX is set correctly.
    526 !macro UpdateShortcutsBranding
    527  ${UpdateOneShortcutBranding} "STARTMENU" "$SMPROGRAMS"
    528  ${UpdateOneShortcutBranding} "DESKTOP" "$DESKTOP"
    529 !macroend
    530 !define UpdateShortcutsBranding "!insertmacro UpdateShortcutsBranding"
    531 
    532 !macro UpdateOneShortcutBranding LOG_SECTION SHORTCUT_DIR
    533  ; Only try to rename the shortcuts found in the shortcuts log, to avoid
    534  ; blowing away a name that the user created.
    535  ${GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9
    536  ${If} ${FileExists} "$R9"
    537    ClearErrors
    538    ; The shortcuts log contains a numbered list of entries for each section,
    539    ; but we never actually create more than one.
    540    ReadINIStr $R8 "$R9" "${LOG_SECTION}" "Shortcut0"
    541    ${IfNot} ${Errors}
    542      ${If} ${FileExists} "${SHORTCUT_DIR}\$R8"
    543 
    544        ; If the shortcut does not have a description, add one. See https://nsis.sourceforge.io/ShellLink_plug-in#Get_Shortcut_Description
    545        ShellLink::GetShortCutDescription "${SHORTCUT_DIR}\$R8"
    546        ; Let's use R7 to store the result, since it's going to be reused in the next check
    547        Pop $R7
    548        ${If} $R7 == ""
    549          ; Looks like there is no description. Let's add one. See https://nsis.sourceforge.io/ShellLink_plug-in#Set_Shortcut_Description
    550          ShellLink::SetShortCutDescription "${SHORTCUT_DIR}\$R8" "$(BRIEF_APP_DESC)"
    551        ${EndIf}
    552        ShellLink::GetShortCutTarget "${SHORTCUT_DIR}\$R8"
    553        Pop $R7
    554        ${GetLongPath} "$R7" $R7
    555        ${If} $R7 == "$INSTDIR\${FileMainEXE}"
    556        ${AndIf} $R8 != "${BrandShortName}.lnk"
    557        ${AndIfNot} ${FileExists} "${SHORTCUT_DIR}\${BrandShortName}.lnk"
    558          ClearErrors
    559          Rename "${SHORTCUT_DIR}\$R8" "${SHORTCUT_DIR}\${BrandShortName}.lnk"
    560          ${IfNot} ${Errors}
    561            ; Update the shortcut log manually instead of calling LogShortcut
    562            ; because it would add a Shortcut1 entry, and we really do want to
    563            ; overwrite the existing entry 0, since we just renamed the file.
    564            WriteINIStr "$R9" "${LOG_SECTION}" "Shortcut0" \
    565                        "${BrandShortName}.lnk"
    566          ${EndIf}
    567        ${EndIf}
    568      ${EndIf}
    569    ${EndIf}
    570  ${EndIf}
    571 !macroend
    572 !define UpdateOneShortcutBranding "!insertmacro UpdateOneShortcutBranding"
    573 
    574 ; Remove a shortcut unintentionally added by the default browser agent (bug 1672957, 1681207)
    575 !macro RemoveDefaultBrowserAgentShortcut
    576  Push $0
    577  Push $1
    578  Push $2
    579  Push $3
    580 
    581  ; Get the current user's Start Menu Programs.
    582  ${GetProgramsFolder} $1
    583 
    584  ; The shortcut would have been named MOZ_BASE_NAME regardless of branding.
    585  ; According to defines.nsi.in AppName should match application.ini, and application.ini.in sets
    586  ; [App] Name from MOZ_BASE_NAME.
    587  StrCpy $1 "$1\${AppName}.lnk"
    588  ShellLink::GetShortCutTarget $1
    589  Pop $0
    590 
    591  ; ShellLink::GetShortCutTarget, and the underlying IShellLink::GetPath(), have an issue
    592  ; where "C:\Program Files" becomes "C:\Program Files (x86)" in some cases.
    593  ; It should be OK to remove the shortcut (which matches our app name) even if it isn't from this
    594  ; install, as long as the file name portion of the target path matches.
    595  StrCpy $2 "\default-browser-agent.exe"
    596  StrLen $3 $2
    597  ; Select the substring to match from the end of the target path.
    598  StrCpy $0 $0 $3 -$3
    599  ${If} $0 == $2
    600    Delete $1
    601  ${EndIf}
    602 
    603  Pop $3
    604  Pop $2
    605  Pop $1
    606  Pop $0
    607 !macroend
    608 !define RemoveDefaultBrowserAgentShortcut "!insertmacro RemoveDefaultBrowserAgentShortcut"
    609 
    610 !macro AddAssociationIfNoneExist FILE_TYPE KEY
    611  ClearErrors
    612  EnumRegKey $7 HKCR "${FILE_TYPE}" 0
    613  ${If} ${Errors}
    614    WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}"  "" ${KEY}
    615  ${EndIf}
    616  WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}\OpenWithProgids" ${KEY} ""
    617 !macroend
    618 !define AddAssociationIfNoneExist "!insertmacro AddAssociationIfNoneExist"
    619 
    620 ; Adds the protocol and file handler registry entries for making Firefox the
    621 ; default handler (uses SHCTX).
    622 !macro SetHandlers
    623  ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
    624 
    625  ; See if we're using path hash suffixed registry keys for this install.
    626  StrCpy $5 ""
    627  ${StrFilter} "${FileMainEXE}" "+" "" "" $2
    628  ReadRegStr $0 SHCTX "Software\Clients\StartMenuInternet\$2\DefaultIcon" ""
    629  StrCpy $0 $0 -2
    630  ${If} $0 != $8
    631    StrCpy $5 "-$AppUserModelID"
    632  ${EndIf}
    633 
    634  StrCpy $0 "SOFTWARE\Classes"
    635  StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
    636 
    637  ; Associate the file handlers with FirefoxHTML, if they aren't already.
    638  ReadRegStr $6 SHCTX "$0\.htm" ""
    639  ${WordFind} "$6" "-" "+1{" $6
    640  ${If} "$6" != "FirefoxHTML"
    641    WriteRegStr SHCTX "$0\.htm"   "" "FirefoxHTML$5"
    642  ${EndIf}
    643 
    644  ReadRegStr $6 SHCTX "$0\.html" ""
    645  ${WordFind} "$6" "-" "+1{" $6
    646  ${If} "$6" != "FirefoxHTML"
    647    WriteRegStr SHCTX "$0\.html"  "" "FirefoxHTML$5"
    648  ${EndIf}
    649 
    650  ReadRegStr $6 SHCTX "$0\.shtml" ""
    651  ${WordFind} "$6" "-" "+1{" $6
    652  ${If} "$6" != "FirefoxHTML"
    653    WriteRegStr SHCTX "$0\.shtml" "" "FirefoxHTML$5"
    654  ${EndIf}
    655 
    656  ReadRegStr $6 SHCTX "$0\.xht" ""
    657  ${WordFind} "$6" "-" "+1{" $6
    658  ${If} "$6" != "FirefoxHTML"
    659    WriteRegStr SHCTX "$0\.xht"   "" "FirefoxHTML$5"
    660  ${EndIf}
    661 
    662  ReadRegStr $6 SHCTX "$0\.xhtml" ""
    663  ${WordFind} "$6" "-" "+1{" $6
    664  ${If} "$6" != "FirefoxHTML"
    665    WriteRegStr SHCTX "$0\.xhtml" "" "FirefoxHTML$5"
    666  ${EndIf}
    667 
    668 
    669  ; Keep this list synchronized with
    670  ; https://searchfox.org/mozilla-central/source/browser/installer/windows/msix/AppxManifest.xml.in.
    671  ; and `os.environment.launched_to_handle` and `os.environment.invoked_to_handle` telemetry in
    672  ; https://searchfox.org/mozilla-central/source/browser/components/BrowserContentHandler.sys.mjs.
    673  ${AddAssociationIfNoneExist} ".oga" "FirefoxHTML$5"
    674  ${AddAssociationIfNoneExist} ".ogg" "FirefoxHTML$5"
    675  ${AddAssociationIfNoneExist} ".ogv" "FirefoxHTML$5"
    676  ${AddAssociationIfNoneExist} ".webm" "FirefoxHTML$5"
    677  ${AddAssociationIfNoneExist} ".svg" "FirefoxHTML$5"
    678  ${AddAssociationIfNoneExist} ".webp"  "FirefoxHTML$5"
    679  ${AddAssociationIfNoneExist} ".avif" "FirefoxHTML$5"
    680 
    681  ${AddAssociationIfNoneExist} ".pdf" "FirefoxPDF$5"
    682 
    683  ; An empty string is used for the 5th param because FirefoxHTML- is not a
    684  ; protocol handler.  Ditto for FirefoxPDF-.
    685  ${AddDisabledDDEHandlerValues} "FirefoxHTML$5" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
    686                                 "${AppRegName} HTML Document" ""
    687 
    688  ${AddDisabledDDEHandlerValues} "FirefoxPDF$5" "$2" "$8,${IDI_DOCUMENT_PDF_ZERO_BASED}" \
    689                                 "${AppRegName} PDF Document" ""
    690 
    691  ${AddDisabledDDEHandlerValues} "FirefoxURL$5" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "${AppRegName} URL" \
    692                                 "true"
    693  ; An empty string is used for the 4th & 5th params because the following
    694  ; protocol handlers already have a display name and the additional keys
    695  ; required for a protocol handler.
    696  ${AddDisabledDDEHandlerValues} "http" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
    697  ${AddDisabledDDEHandlerValues} "https" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
    698  ${AddDisabledDDEHandlerValues} "mailto" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
    699 !macroend
    700 !define SetHandlers "!insertmacro SetHandlers"
    701 
    702 !macro WriteApplicationsSupportedType RegKey Type
    703  WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\SupportedTypes" "${Type}" ""
    704 !macroend
    705 !define WriteApplicationsSupportedType "!insertmacro WriteApplicationsSupportedType"
    706 
    707 ; Adds the HKLM\Software\Clients\StartMenuInternet\Firefox-[pathhash] registry
    708 ; entries (does not use SHCTX).
    709 ;
    710 ; The values for StartMenuInternet are only valid under HKLM and there can only
    711 ; be one installation registerred under StartMenuInternet per application since
    712 ; the key name is derived from the main application executable.
    713 ;
    714 ; In Windows 8 this changes slightly, you can store StartMenuInternet entries in
    715 ; HKCU.  The icon in start menu for StartMenuInternet is deprecated as of Win7,
    716 ; but the subkeys are what's important.  Control panel default programs looks
    717 ; for them only in HKLM pre win8.
    718 ;
    719 ; The StartMenuInternet key and friends are documented at
    720 ; https://msdn.microsoft.com/en-us/library/windows/desktop/cc144109(v=vs.85).aspx
    721 ;
    722 ; This function also writes our RegisteredApplications entry, which gets us
    723 ; listed in the Settings app's default browser options on Windows 8+, and in
    724 ; Set Program Access and Defaults on earlier versions.
    725 !macro SetStartMenuInternet RegKey
    726  ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
    727  ${GetLongPath} "$INSTDIR\uninstall\helper.exe" $7
    728 
    729  ; If we already have keys at the old FIREFOX.EXE path, then just update those.
    730  ; We have to be careful to update the existing keys in place so that we don't
    731  ; create duplicate keys for the same installation, or cause Windows to think
    732  ; something "suspicious" has happened and it should reset the default browser.
    733  ${StrFilter} "${FileMainEXE}" "+" "" "" $1
    734  ReadRegStr $0 ${RegKey} "Software\Clients\StartMenuInternet\$1\DefaultIcon" ""
    735  StrCpy $0 $0 -2
    736  ${If} $0 != $8
    737    StrCpy $1 "${AppRegName}-$AppUserModelID"
    738    StrCpy $2 "-$AppUserModelID"
    739  ${Else}
    740    StrCpy $2 ""
    741  ${EndIf}
    742  StrCpy $0 "Software\Clients\StartMenuInternet\$1"
    743 
    744  WriteRegStr ${RegKey} "$0" "" "${BrandFullName}"
    745 
    746  WriteRegStr ${RegKey} "$0\DefaultIcon" "" "$8,${IDI_APPICON_ZERO_BASED}"
    747 
    748  ; The Reinstall Command is defined at
    749  ; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_adv/registeringapps.asp
    750  WriteRegStr ${RegKey} "$0\InstallInfo" "HideIconsCommand" "$\"$7$\" /HideShortcuts"
    751  WriteRegStr ${RegKey} "$0\InstallInfo" "ShowIconsCommand" "$\"$7$\" /ShowShortcuts"
    752  WriteRegStr ${RegKey} "$0\InstallInfo" "ReinstallCommand" "$\"$7$\" /SetAsDefaultAppGlobal"
    753  WriteRegDWORD ${RegKey} "$0\InstallInfo" "IconsVisible" 1
    754 
    755  WriteRegStr ${RegKey} "$0\shell\open\command" "" "$\"$8$\""
    756 
    757  WriteRegStr ${RegKey} "$0\shell\properties" "" "$(CONTEXT_OPTIONS)"
    758  WriteRegStr ${RegKey} "$0\shell\properties\command" "" "$\"$8$\" -preferences"
    759 
    760  WriteRegStr ${RegKey} "$0\shell\safemode" "" "$(CONTEXT_SAFE_MODE)"
    761  WriteRegStr ${RegKey} "$0\shell\safemode\command" "" "$\"$8$\" -safe-mode"
    762 
    763  ; Capabilities registry keys
    764  WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationDescription" "$(REG_APP_DESC)"
    765  WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationIcon" "$8,${IDI_APPICON_ZERO_BASED}"
    766  WriteRegStr ${RegKey} "$0\Capabilities" "ApplicationName" "${BrandShortName}"
    767 
    768  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".htm"   "FirefoxHTML$2"
    769  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".html"  "FirefoxHTML$2"
    770  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".shtml" "FirefoxHTML$2"
    771  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".xht"   "FirefoxHTML$2"
    772  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".xhtml" "FirefoxHTML$2"
    773  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".svg"   "FirefoxHTML$2"
    774  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".webp"  "FirefoxHTML$2"
    775  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".avif"  "FirefoxHTML$2"
    776 
    777  WriteRegStr ${RegKey} "$0\Capabilities\FileAssociations" ".pdf"   "FirefoxPDF$2"
    778 
    779  WriteRegStr ${RegKey} "$0\Capabilities\StartMenu" "StartMenuInternet" "$1"
    780 
    781  ; In the past, we supported ftp.  Since we don't delete and re-create the
    782  ; entire key, we need to remove any existing registration.
    783  DeleteRegValue ${RegKey} "$0\Capabilities\URLAssociations" "ftp"
    784 
    785  WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "http"   "FirefoxURL$2"
    786  WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "https"  "FirefoxURL$2"
    787  WriteRegStr ${RegKey} "$0\Capabilities\URLAssociations" "mailto" "FirefoxURL$2"
    788 
    789  WriteRegStr ${RegKey} "Software\RegisteredApplications" "$1" "$0\Capabilities"
    790 
    791  ; This key would be created by the Open With dialog when a user creates an
    792  ; association for us with a file type that we haven't registered as a handler
    793  ; for. We need to preemptively create it ourselves so that we can control the
    794  ; command line that's used to launch us in that situation. If it's too late
    795  ; and one already exists, then we need to edit its command line to make sure
    796  ; it contains the -osint flag.
    797  ReadRegStr $6 ${RegKey} "Software\Classes\Applications\${FileMainEXE}\shell\open\command" ""
    798  ${If} $6 != ""
    799    ${GetPathFromString} "$6" $6
    800    WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\shell\open\command" \
    801                "" "$\"$6$\" -osint -url $\"%1$\""
    802  ${Else}
    803    WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\shell\open\command" \
    804                "" "$\"$8$\" -osint -url $\"%1$\""
    805    ; Make sure files associated this way use the document icon instead of the
    806    ; application icon.
    807    WriteRegStr ${RegKey} "Software\Classes\Applications\${FileMainEXE}\DefaultIcon" \
    808                "" "$8,${IDI_DOCUMENT_ZERO_BASED}"
    809    ; If we're going to create this key at all, we also need to list our supported
    810    ; file types in it, because otherwise we'll be shown as a suggestion for every
    811    ; single file type, whether we support it in any way or not.
    812    ; We take a more expansive approach to the set of file types registered
    813    ; here compared to elsewhere because this key is interpreted by the OS as
    814    ; containing every file type that we can possibly open, so if something
    815    ; isn't listed it assumes we can't open it and hides us from e.g. the Open
    816    ; With context menu, even if the user has tried to add us there manually.
    817    ; The list here was derived from the file /layout/build/components.conf,
    818    ; filtered down to only those types which make sense to open on their own
    819    ; in Firefox, basically meaning that plain text file types were left out,
    820    ; but not JSON or XML types because we have specific viewers for those.
    821    ${WriteApplicationsSupportedType} ${RegKey} ".apng"
    822    ${WriteApplicationsSupportedType} ${RegKey} ".bmp"
    823    ${WriteApplicationsSupportedType} ${RegKey} ".flac"
    824    ${WriteApplicationsSupportedType} ${RegKey} ".gif"
    825    ${WriteApplicationsSupportedType} ${RegKey} ".htm"
    826    ${WriteApplicationsSupportedType} ${RegKey} ".html"
    827    ${WriteApplicationsSupportedType} ${RegKey} ".ico"
    828    ${WriteApplicationsSupportedType} ${RegKey} ".jfif"
    829    ${WriteApplicationsSupportedType} ${RegKey} ".jpeg"
    830    ${WriteApplicationsSupportedType} ${RegKey} ".jpg"
    831    ${WriteApplicationsSupportedType} ${RegKey} ".json"
    832    ${WriteApplicationsSupportedType} ${RegKey} ".m4a"
    833    ${WriteApplicationsSupportedType} ${RegKey} ".mp3"
    834    ${WriteApplicationsSupportedType} ${RegKey} ".oga"
    835    ${WriteApplicationsSupportedType} ${RegKey} ".ogg"
    836    ${WriteApplicationsSupportedType} ${RegKey} ".ogv"
    837    ${WriteApplicationsSupportedType} ${RegKey} ".opus"
    838    ${WriteApplicationsSupportedType} ${RegKey} ".pdf"
    839    ${WriteApplicationsSupportedType} ${RegKey} ".pjpeg"
    840    ${WriteApplicationsSupportedType} ${RegKey} ".pjp"
    841    ${WriteApplicationsSupportedType} ${RegKey} ".png"
    842    ${WriteApplicationsSupportedType} ${RegKey} ".rdf"
    843    ${WriteApplicationsSupportedType} ${RegKey} ".shtml"
    844    ${WriteApplicationsSupportedType} ${RegKey} ".svg"
    845    ${WriteApplicationsSupportedType} ${RegKey} ".webm"
    846    ${WriteApplicationsSupportedType} ${RegKey} ".webp"
    847    ${WriteApplicationsSupportedType} ${RegKey} ".avif"
    848    ${WriteApplicationsSupportedType} ${RegKey} ".xht"
    849    ${WriteApplicationsSupportedType} ${RegKey} ".xhtml"
    850    ${WriteApplicationsSupportedType} ${RegKey} ".xml"
    851  ${EndIf}
    852 !macroend
    853 !define SetStartMenuInternet "!insertmacro SetStartMenuInternet"
    854 
    855 ; Add registry keys to support the Firefox 32 bit to 64 bit migration. These
    856 ; registry entries are not removed on uninstall at this time. After the Firefox
    857 ; 32 bit to 64 bit migration effort is completed these registry entries can be
    858 ; removed during install, post update, and uninstall.
    859 !macro Set32to64DidMigrateReg
    860  ${GetLongPath} "$INSTDIR" $1
    861  ; These registry keys are always in the 32 bit hive since they are never
    862  ; needed by a Firefox 64 bit install unless it has been updated from Firefox
    863  ; 32 bit.
    864  SetRegView 32
    865 
    866 !ifdef HAVE_64BIT_BUILD
    867 
    868  ; Running Firefox 64 bit on Windows 64 bit
    869  ClearErrors
    870  ReadRegDWORD $2 HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
    871  ; If there were no errors then the system was updated from Firefox 32 bit to
    872  ; Firefox 64 bit and if the value is already 1 then the registry value has
    873  ; already been updated in the HKLM registry.
    874  ${IfNot} ${Errors}
    875  ${AndIf} $2 != 1
    876    ClearErrors
    877    WriteRegDWORD HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 1
    878    ${If} ${Errors}
    879      ; There was an error writing to HKLM so just write it to HKCU
    880      WriteRegDWORD HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 1
    881    ${Else}
    882      ; This will delete the value from HKCU if it exists
    883      DeleteRegValue HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
    884    ${EndIf}
    885  ${EndIf}
    886 
    887  ClearErrors
    888  ReadRegDWORD $2 HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
    889  ; If there were no errors then the system was updated from Firefox 32 bit to
    890  ; Firefox 64 bit and if the value is already 1 then the registry value has
    891  ; already been updated in the HKCU registry.
    892  ${IfNot} ${Errors}
    893  ${AndIf} $2 != 1
    894    WriteRegDWORD HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 1
    895  ${EndIf}
    896 
    897 !else
    898 
    899  ; Running Firefox 32 bit
    900  ${If} ${RunningX64}
    901  ${OrIf} ${IsNativeARM64}
    902    ; Running Firefox 32 bit on a Windows 64 bit system
    903    ClearErrors
    904    ReadRegDWORD $2 HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1"
    905    ; If there were errors the value doesn't exist yet.
    906    ${If} ${Errors}
    907      ClearErrors
    908      WriteRegDWORD HKLM "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 0
    909      ; If there were errors write the value in HKCU.
    910      ${If} ${Errors}
    911        WriteRegDWORD HKCU "Software\Mozilla\${AppName}\32to64DidMigrate" "$1" 0
    912      ${EndIf}
    913    ${EndIf}
    914  ${EndIf}
    915 
    916 !endif
    917 
    918  ClearErrors
    919  SetRegView lastused
    920 !macroend
    921 !define Set32to64DidMigrateReg "!insertmacro Set32to64DidMigrateReg"
    922 
    923 ; The IconHandler reference for FirefoxHTML can end up in an inconsistent state
    924 ; due to changes not being detected by the IconHandler for side by side
    925 ; installs (see bug 268512). The symptoms can be either an incorrect icon or no
    926 ; icon being displayed for files associated with Firefox (does not use SHCTX).
    927 !macro FixShellIconHandler RegKey
    928  ; Find the correct key to update, either FirefoxHTML or FirefoxHTML-[PathHash]
    929  StrCpy $3 "FirefoxHTML-$AppUserModelID"
    930  ClearErrors
    931  ReadRegStr $0 ${RegKey} "Software\Classes\$3\DefaultIcon" ""
    932  ${If} ${Errors}
    933    StrCpy $3 "FirefoxHTML"
    934  ${EndIf}
    935 
    936  ClearErrors
    937  ReadRegStr $1 ${RegKey} "Software\Classes\$3\ShellEx\IconHandler" ""
    938  ${Unless} ${Errors}
    939    ReadRegStr $1 ${RegKey} "Software\Classes\$3\DefaultIcon" ""
    940    ${GetLongPath} "$INSTDIR\${FileMainEXE}" $2
    941    ${If} "$1" != "$2,${IDI_DOCUMENT_ZERO_BASED}"
    942      WriteRegStr ${RegKey} "Software\Classes\$3\DefaultIcon" "" "$2,${IDI_DOCUMENT_ZERO_BASED}"
    943    ${EndIf}
    944  ${EndUnless}
    945 !macroend
    946 !define FixShellIconHandler "!insertmacro FixShellIconHandler"
    947 
    948 ; Add Software\Mozilla\ registry entries (uses SHCTX).
    949 ; This expects $RegHive to already have been set correctly.
    950 !macro SetAppKeys
    951  ; Check if this is an ESR release and if so add registry values so it is
    952  ; possible to determine that this is an ESR install (bug 726781).
    953  ClearErrors
    954  ${WordFind} "${UpdateChannel}" "esr" "E#" $3
    955  ${If} ${Errors}
    956    StrCpy $3 ""
    957  ${Else}
    958    StrCpy $3 " ESR"
    959  ${EndIf}
    960 
    961  ${GetLongPath} "$INSTDIR" $8
    962  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})\Main"
    963  ${WriteRegStr2} $RegHive "$0" "Install Directory" "$8" 0
    964  ${WriteRegStr2} $RegHive "$0" "PathToExe" "$8\${FileMainEXE}" 0
    965 
    966  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})\Uninstall"
    967  ${WriteRegStr2} $RegHive "$0" "Description" "${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" 0
    968 
    969  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion}$3 (${ARCH} ${AB_CD})"
    970  ${WriteRegStr2} $RegHive  "$0" "" "${AppVersion}$3 (${ARCH} ${AB_CD})" 0
    971  ${If} "$3" == ""
    972    DeleteRegValue SHCTX "$0" "ESR"
    973  ${Else}
    974    ${WriteRegDWORD2} $RegHive "$0" "ESR" 1 0
    975  ${EndIf}
    976 
    977  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3\bin"
    978  ${WriteRegStr2} $RegHive "$0" "PathToExe" "$8\${FileMainEXE}" 0
    979 
    980  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3\extensions"
    981  ${WriteRegStr2} $RegHive "$0" "Components" "$8\components" 0
    982  ${WriteRegStr2} $RegHive "$0" "Plugins" "$8\plugins" 0
    983 
    984  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}$3"
    985  ${WriteRegStr2} $RegHive "$0" "GeckoVer" "${GREVersion}" 0
    986  ${If} "$3" == ""
    987    DeleteRegValue SHCTX "$0" "ESR"
    988  ${Else}
    989    ${WriteRegDWORD2} $RegHive "$0" "ESR" 1 0
    990  ${EndIf}
    991 
    992  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}$3"
    993  ${WriteRegStr2} $RegHive "$0" "" "${GREVersion}" 0
    994  ${WriteRegStr2} $RegHive "$0" "CurrentVersion" "${AppVersion}$3 (${ARCH} ${AB_CD})" 0
    995 !macroend
    996 !define SetAppKeys "!insertmacro SetAppKeys"
    997 
    998 !macro RegistryWriteVersion
    999  Exch $0
   1000  Push $R0
   1001  Push $R1
   1002  Push $R2
   1003  Push $R3
   1004 
   1005  GetDLLVersion "$8\${FileMainEXE}" $R0 $R1
   1006  IntOp $R2 $R0 >> 16
   1007  IntOp $R2 $R2 & 0x0000FFFF ; $R2 now contains major version
   1008  IntOp $R3 $R0 & 0x0000FFFF ; $R3 now contains minor version
   1009 
   1010  ${WriteRegStr2} $RegHive "$0" "DisplayVersion" "${AppVersion}" 0
   1011  ${WriteRegStr2} $RegHive "$0" "VersionMajor" "$R2" 0
   1012  ${WriteRegStr2} $RegHive "$0" "VersionMinor" "$R3" 0
   1013 
   1014  Pop $R3
   1015  Pop $R2
   1016  Pop $R1
   1017  Pop $R0
   1018  Pop $0
   1019 !macroend
   1020 
   1021 ; Add uninstall registry entries. This macro tests for write access to determine
   1022 ; if the uninstall keys should be added to HKLM or HKCU.
   1023 ; This expects $RegHive to already have been set correctly.
   1024 !macro SetUninstallKeys
   1025  ; Check if this is an ESR release and if so add registry values so it is
   1026  ; possible to determine that this is an ESR install (bug 726781).
   1027  ClearErrors
   1028  ${WordFind} "${UpdateChannel}" "esr" "E#" $3
   1029  ${If} ${Errors}
   1030    StrCpy $3 ""
   1031  ${Else}
   1032    StrCpy $3 " ESR"
   1033  ${EndIf}
   1034 
   1035  ${WinVerGetBuild} $0 ; determine the Windows build version, place it in $3
   1036  Push $0 ; push version number to the stack as parameter for getUninstallKey
   1037  Call getUninstallKey
   1038  Pop $0 ; the "return value" on the stack is the the target registry key.
   1039 
   1040  StrCpy $2 ""
   1041  ${If} "$RegHive" == "HKLM"
   1042    SetShellVarContext all     ; Set SHCTX to all users (e.g. HKLM)
   1043  ${Else}
   1044    SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   1045    Call findUninstallKey
   1046    Pop $2
   1047  ${EndIf}
   1048 
   1049  ${If} $2 == ""
   1050    ${GetLongPath} "$INSTDIR" $8
   1051 
   1052    ; Write the uninstall registry keys
   1053    ${WriteRegStr2} $RegHive "$0" "Comments" "${BrandFullNameInternal} ${AppVersion}$3 (${ARCH} ${AB_CD})" 0
   1054    ${WriteRegStr2} $RegHive "$0" "DisplayIcon" "$8\${FileMainEXE},${IDI_APPICON_ZERO_BASED}" 0
   1055    ${WriteRegStr2} $RegHive "$0" "DisplayName" "${BrandFullNameInternal}$3 (${ARCH} ${AB_CD})" 0
   1056    ${WriteRegStr2} $RegHive "$0" "HelpLink" "${HelpLink}" 0
   1057    ${WriteRegStr2} $RegHive "$0" "InstallLocation" "$8" 0
   1058    ${WriteRegStr2} $RegHive "$0" "Publisher" "Mozilla" 0
   1059    ${WriteRegStr2} $RegHive "$0" "UninstallString" "$\"$8\uninstall\helper.exe$\"" 0
   1060    DeleteRegValue SHCTX "$0" "URLInfoAbout"
   1061 ; Don't add URLUpdateInfo which is the release notes url except for the release
   1062 ; and esr channels since nightly, aurora, and beta do not have release notes.
   1063 ; Note: URLUpdateInfo is only defined in the official branding.nsi.
   1064 !ifdef URLUpdateInfo
   1065 !ifndef BETA_UPDATE_CHANNEL
   1066    ${WriteRegStr2} $RegHive "$0" "URLUpdateInfo" "${URLUpdateInfo}" 0
   1067 !endif
   1068 !endif
   1069    ${WriteRegStr2} $RegHive "$0" "URLInfoAbout" "${URLInfoAbout}" 0
   1070    ${WriteRegDWORD2} $RegHive "$0" "NoModify" 1 0
   1071    ${WriteRegDWORD2} $RegHive "$0" "NoRepair" 1 0
   1072 
   1073    ${GetSize} "$8" "/S=0K" $R2 $R3 $R4
   1074    ${WriteRegDWORD2} $RegHive "$0" "EstimatedSize" $R2 0
   1075 
   1076    Push $0
   1077    !insertmacro RegistryWriteVersion
   1078  ${EndIf}
   1079 !macroend
   1080 !define SetUninstallKeys "!insertmacro SetUninstallKeys"
   1081 
   1082 ; Due to a bug when associating some file handlers, only SHCTX was checked for
   1083 ; some file types such as ".pdf". SHCTX is set to HKCU or HKLM depending on
   1084 ; whether the installer has write access to HKLM. The bug would happen when
   1085 ; HCKU was checked and didn't exist since programs aren't required to set the
   1086 ; HKCU Software\Classes keys when associating handlers. The fix uses the merged
   1087 ; view in HKCR to check for existance of an existing association. This macro
   1088 ; cleans affected installations by removing the HKLM and HKCU value if it is set
   1089 ; to FirefoxHTML when there is a value for PersistentHandler or by removing the
   1090 ; HKCU value when the HKLM value has a value other than an empty string.
   1091 !macro FixBadFileAssociation FILE_TYPE
   1092  ; Only delete the default value in case the key has values for OpenWithList,
   1093  ; OpenWithProgids, PersistentHandler, etc.
   1094  ReadRegStr $0 HKCU "Software\Classes\${FILE_TYPE}" ""
   1095  ${WordFind} "$0" "-" "+1{" $0
   1096  ReadRegStr $1 HKLM "Software\Classes\${FILE_TYPE}" ""
   1097  ${WordFind} "$1" "-" "+1{" $1
   1098  ReadRegStr $2 HKCR "${FILE_TYPE}\PersistentHandler" ""
   1099  ${If} "$2" != ""
   1100    ; Since there is a persistent handler remove FirefoxHTML as the default
   1101    ; value from both HKCU and HKLM if it set to FirefoxHTML.
   1102    ${If} "$0" == "FirefoxHTML"
   1103      DeleteRegValue HKCU "Software\Classes\${FILE_TYPE}" ""
   1104    ${EndIf}
   1105    ${If} "$1" == "FirefoxHTML"
   1106      DeleteRegValue HKLM "Software\Classes\${FILE_TYPE}" ""
   1107    ${EndIf}
   1108  ${ElseIf} "$0" == "FirefoxHTML"
   1109    ; Since HKCU is set to FirefoxHTML remove FirefoxHTML as the default value
   1110    ; from HKCU if HKLM is set to a value other than an empty string.
   1111    ${If} "$1" != ""
   1112      DeleteRegValue HKCU "Software\Classes\${FILE_TYPE}" ""
   1113    ${EndIf}
   1114  ${EndIf}
   1115 !macroend
   1116 !define FixBadFileAssociation "!insertmacro FixBadFileAssociation"
   1117 
   1118 ; Add app specific handler registry entries under Software\Classes if they
   1119 ; don't exist (does not use SHCTX).
   1120 ; This expects $RegHive to already have been set correctly.
   1121 !macro FixClassKeys
   1122  StrCpy $1 "SOFTWARE\Classes"
   1123 
   1124  ; File handler keys and name value pairs that may need to be created during
   1125  ; install or upgrade.
   1126  ReadRegStr $0 HKCR ".shtml" "Content Type"
   1127  ${If} "$0" == ""
   1128    StrCpy $0 "$1\.shtml"
   1129    ${WriteRegStr2} $RegHive "$1\.shtml" "" "shtmlfile" 0
   1130    ${WriteRegStr2} $RegHive "$1\.shtml" "Content Type" "text/html" 0
   1131    ${WriteRegStr2} $RegHive "$1\.shtml" "PerceivedType" "text" 0
   1132  ${EndIf}
   1133 
   1134  ReadRegStr $0 HKCR ".xht" "Content Type"
   1135  ${If} "$0" == ""
   1136    ${WriteRegStr2} $RegHive "$1\.xht" "" "xhtfile" 0
   1137    ${WriteRegStr2} $RegHive "$1\.xht" "Content Type" "application/xhtml+xml" 0
   1138  ${EndIf}
   1139 
   1140  ReadRegStr $0 HKCR ".xhtml" "Content Type"
   1141  ${If} "$0" == ""
   1142    ${WriteRegStr2} $RegHive "$1\.xhtml" "" "xhtmlfile" 0
   1143    ${WriteRegStr2} $RegHive "$1\.xhtml" "Content Type" "application/xhtml+xml" 0
   1144  ${EndIf}
   1145 
   1146  ; Remove possibly badly associated file types
   1147  ${FixBadFileAssociation} ".pdf"
   1148  ${FixBadFileAssociation} ".oga"
   1149  ${FixBadFileAssociation} ".ogg"
   1150  ${FixBadFileAssociation} ".ogv"
   1151  ${FixBadFileAssociation} ".pdf"
   1152  ${FixBadFileAssociation} ".webm"
   1153 !macroend
   1154 !define FixClassKeys "!insertmacro FixClassKeys"
   1155 
   1156 ; Updates protocol handlers if their registry open command value is for this
   1157 ; install location (uses SHCTX).
   1158 !macro UpdateProtocolHandlers
   1159  ; Store the command to open the app with an url in a register for easy access.
   1160  ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
   1161  StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
   1162 
   1163  ; Only set the file and protocol handlers if the existing one under HKCR is
   1164  ; for this install location.
   1165 
   1166  ${IsHandlerForInstallDir} "FirefoxHTML-$AppUserModelID" $R9
   1167  ${If} "$R9" == "true"
   1168    ; An empty string is used for the 5th param because FirefoxHTML is not a
   1169    ; protocol handler.
   1170    ${AddDisabledDDEHandlerValues} "FirefoxHTML-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
   1171                                   "${AppRegName} HTML Document" ""
   1172  ${Else}
   1173    ${IsHandlerForInstallDir} "FirefoxHTML" $R9
   1174    ${If} "$R9" == "true"
   1175      ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
   1176                                     "${AppRegName} HTML Document" ""
   1177    ${EndIf}
   1178  ${EndIf}
   1179 
   1180  ; FirefoxPDF-* was added after FirefoxHTML and FirefoxURL, so we've never
   1181  ; supported bare "FirefoxPDF".  But we won't have it from the installer, so we
   1182  ; add/update it unconditionally.  `PostUpdate` is gated on `uninstall.log`
   1183  ; being present, so the invocation here will only happen for installed
   1184  ; directories, not unpackaged directories.
   1185  ${AddDisabledDDEHandlerValues} "FirefoxPDF-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_PDF_ZERO_BASED}" \
   1186                                 "${AppRegName} PDF Document" ""
   1187 
   1188  ${IsHandlerForInstallDir} "FirefoxURL-$AppUserModelID" $R9
   1189  ${If} "$R9" == "true"
   1190    ${AddDisabledDDEHandlerValues} "FirefoxURL-$AppUserModelID" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
   1191                                   "${AppRegName} URL" "true"
   1192  ${Else}
   1193    ${IsHandlerForInstallDir} "FirefoxURL" $R9
   1194    ${If} "$R9" == "true"
   1195      ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" \
   1196                                     "${AppRegName} URL" "true"
   1197    ${EndIf}
   1198  ${EndIf}
   1199 
   1200  ; An empty string is used for the 4th & 5th params because the following
   1201  ; protocol handlers already have a display name and the additional keys
   1202  ; required for a protocol handler.
   1203 
   1204  ${IsHandlerForInstallDir} "ftp" $R9
   1205  ${If} "$R9" == "true"
   1206    ; In the past, we supported ftp, so we need to delete any registration.
   1207    ${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" "delete"
   1208  ${EndIf}
   1209 
   1210  ${IsHandlerForInstallDir} "http" $R9
   1211  ${If} "$R9" == "true"
   1212    ${AddDisabledDDEHandlerValues} "http" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
   1213  ${EndIf}
   1214 
   1215  ${IsHandlerForInstallDir} "https" $R9
   1216  ${If} "$R9" == "true"
   1217    ${AddDisabledDDEHandlerValues} "https" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
   1218  ${EndIf}
   1219 
   1220  ${IsHandlerForInstallDir} "mailto" $R9
   1221  ${If} "$R9" == "true"
   1222    ${AddDisabledDDEHandlerValues} "mailto" "$2" "$8,${IDI_DOCUMENT_ZERO_BASED}" "" ""
   1223  ${EndIf}
   1224 !macroend
   1225 !define UpdateProtocolHandlers "!insertmacro UpdateProtocolHandlers"
   1226 
   1227 !ifdef MOZ_MAINTENANCE_SERVICE
   1228 ; Adds maintenance service certificate keys for the install dir.
   1229 ; For the cert to work, it must also be signed by a trusted cert for the user.
   1230 !macro AddMaintCertKeys
   1231  Push $R0
   1232  ; Allow main Mozilla cert information for updates
   1233  ; This call will push the needed key on the stack
   1234  ServicesHelper::PathToUniqueRegistryPath "$INSTDIR"
   1235  Pop $R0
   1236  ${If} $R0 != ""
   1237    ; More than one certificate can be specified in a different subfolder
   1238    ; for example: $R0\1, but each individual binary can be signed
   1239    ; with at most one certificate.  A fallback certificate can only be used
   1240    ; if the binary is replaced with a different certificate.
   1241    ; We always use the 64bit registry for certs.
   1242    ${If} ${RunningX64}
   1243    ${OrIf} ${IsNativeARM64}
   1244      SetRegView 64
   1245    ${EndIf}
   1246 
   1247    ; PrefetchProcessName was originally used to experiment with deleting
   1248    ; Windows prefetch as a speed optimization.  It is no longer used though.
   1249    DeleteRegValue HKLM "$R0" "prefetchProcessName"
   1250 
   1251    ; Setting the Attempted value will ensure that a new Maintenance Service
   1252    ; install will never be attempted again after this from updates.  The value
   1253    ; is used only to see if updates should attempt new service installs.
   1254    WriteRegDWORD HKLM "Software\Mozilla\MaintenanceService" "Attempted" 1
   1255 
   1256    ; These values associate the allowed certificates for the current
   1257    ; installation.
   1258    WriteRegStr HKLM "$R0\0" "name" "${CERTIFICATE_NAME}"
   1259    WriteRegStr HKLM "$R0\0" "issuer" "${CERTIFICATE_ISSUER}"
   1260    ; These values associate the allowed certificates for the previous
   1261    ;  installation, so that we can update from it cleanly using the
   1262    ;  old updater.exe (which will still have this signature).
   1263    WriteRegStr HKLM "$R0\1" "name" "${CERTIFICATE_NAME_PREVIOUS}"
   1264    WriteRegStr HKLM "$R0\1" "issuer" "${CERTIFICATE_ISSUER_PREVIOUS}"
   1265    ${If} ${RunningX64}
   1266    ${OrIf} ${IsNativeARM64}
   1267      SetRegView lastused
   1268    ${EndIf}
   1269    ClearErrors
   1270  ${EndIf}
   1271  ; Restore the previously used value back
   1272  Pop $R0
   1273 !macroend
   1274 !define AddMaintCertKeys "!insertmacro AddMaintCertKeys"
   1275 !endif
   1276 
   1277 !macro RegisterAccessibleMarshal
   1278  ${RegisterDLL} "$INSTDIR\AccessibleMarshal.dll"
   1279 !macroend
   1280 !define RegisterAccessibleMarshal "!insertmacro RegisterAccessibleMarshal"
   1281 
   1282 ; Removes various registry entries for reasons noted below (does not use SHCTX).
   1283 !macro RemoveDeprecatedKeys
   1284  StrCpy $0 "SOFTWARE\Classes"
   1285  ; Remove support for launching chrome urls from the shell during install or
   1286  ; update if the DefaultIcon is from firefox.exe (Bug 301073).
   1287  ${RegCleanAppHandler} "chrome"
   1288 
   1289  ; Remove protocol handler registry keys added by the MS shim
   1290  DeleteRegKey HKLM "Software\Classes\Firefox.URL"
   1291  DeleteRegKey HKCU "Software\Classes\Firefox.URL"
   1292 
   1293  ; Unregister deprecated AccessibleHandler.dll.
   1294  ${If} ${FileExists} "$INSTDIR\AccessibleHandler.dll"
   1295    ${UnregisterDLL} "$INSTDIR\AccessibleHandler.dll"
   1296  ${EndIf}
   1297 !macroend
   1298 !define RemoveDeprecatedKeys "!insertmacro RemoveDeprecatedKeys"
   1299 
   1300 ; Removes various directories and files for reasons noted below.
   1301 !macro RemoveDeprecatedFiles
   1302  ; Remove the toplevel chrome.manifest added by bug 1295542.
   1303  ${If} ${FileExists} "$INSTDIR\chrome.manifest"
   1304    Delete "$INSTDIR\chrome.manifest"
   1305  ${EndIf}
   1306 
   1307  ; Remove talkback if it is present (remove after bug 386760 is fixed)
   1308  ${If} ${FileExists} "$INSTDIR\extensions\talkback@mozilla.org"
   1309    RmDir /r /REBOOTOK "$INSTDIR\extensions\talkback@mozilla.org"
   1310  ${EndIf}
   1311 
   1312  ; Remove the Java Console extension (bug 1165156)
   1313  ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0031-ABCDEFFEDCBA}"
   1314    RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0031-ABCDEFFEDCBA}"
   1315  ${EndIf}
   1316  ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0034-ABCDEFFEDCBA}"
   1317    RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0034-ABCDEFFEDCBA}"
   1318  ${EndIf}
   1319  ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0039-ABCDEFFEDCBA}"
   1320    RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0039-ABCDEFFEDCBA}"
   1321  ${EndIf}
   1322  ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0045-ABCDEFFEDCBA}"
   1323    RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0016-0000-0045-ABCDEFFEDCBA}"
   1324  ${EndIf}
   1325  ${If} ${FileExists} "$INSTDIR\extensions\{CAFEEFAC-0017-0000-0000-ABCDEFFEDCBA}"
   1326    RmDir /r /REBOOTOK "$INSTDIR\extensions\{CAFEEFAC-0017-0000-0000-ABCDEFFEDCBA}"
   1327  ${EndIf}
   1328 !macroend
   1329 !define RemoveDeprecatedFiles "!insertmacro RemoveDeprecatedFiles"
   1330 
   1331 ; Converts specific partner distribution.ini from ansi to utf-8 (bug 882989)
   1332 !macro FixDistributionsINI
   1333  StrCpy $1 "$INSTDIR\distribution\distribution.ini"
   1334  StrCpy $2 "$INSTDIR\distribution\utf8fix"
   1335  StrCpy $0 "0" ; Default to not attempting to fix
   1336 
   1337  ; Check if the distribution.ini settings are for a partner build that needs
   1338  ; to have its distribution.ini converted from ansi to utf-8.
   1339  ${If} ${FileExists} "$1"
   1340    ${Unless} ${FileExists} "$2"
   1341      ReadINIStr $3 "$1" "Preferences" "app.distributor"
   1342      ${If} "$3" == "yahoo"
   1343        ReadINIStr $3 "$1" "Preferences" "app.distributor.channel"
   1344        ${If} "$3" == "de"
   1345        ${OrIf} "$3" == "es"
   1346        ${OrIf} "$3" == "e1"
   1347        ${OrIf} "$3" == "mx"
   1348          StrCpy $0 "1"
   1349        ${EndIf}
   1350      ${EndIf}
   1351      ; Create the utf8fix so this only runs once
   1352      FileOpen $3 "$2" w
   1353      FileClose $3
   1354    ${EndUnless}
   1355  ${EndIf}
   1356 
   1357  ${If} "$0" == "1"
   1358    StrCpy $0 "0"
   1359    ClearErrors
   1360    ReadINIStr $3 "$1" "Global" "version"
   1361    ${Unless} ${Errors}
   1362      StrCpy $4 "$3" 2
   1363      ${If} "$4" == "1."
   1364        StrCpy $4 "$3" "" 2 ; Everything after "1."
   1365        ${If} $4 < 23
   1366          StrCpy $0 "1"
   1367        ${EndIf}
   1368      ${EndIf}
   1369    ${EndUnless}
   1370  ${EndIf}
   1371 
   1372  ${If} "$0" == "1"
   1373    ClearErrors
   1374    FileOpen $3 "$1" r
   1375    ${If} ${Errors}
   1376      FileClose $3
   1377    ${Else}
   1378      StrCpy $2 "$INSTDIR\distribution\distribution.new"
   1379      ClearErrors
   1380      FileOpen $4 "$2" w
   1381      ${If} ${Errors}
   1382        FileClose $3
   1383        FileClose $4
   1384      ${Else}
   1385        StrCpy $0 "0" ; Default to not replacing the original distribution.ini
   1386        ${Do}
   1387          FileReadByte $3 $5
   1388          ${If} $5 == ""
   1389            ${Break}
   1390          ${EndIf}
   1391          ${If} $5 == 233 ; ansi é
   1392            StrCpy $0 "1"
   1393            FileWriteByte $4 195
   1394            FileWriteByte $4 169
   1395          ${ElseIf} $5 == 241 ; ansi ñ
   1396            StrCpy $0 "1"
   1397            FileWriteByte $4 195
   1398            FileWriteByte $4 177
   1399          ${ElseIf} $5 == 252 ; ansi ü
   1400            StrCpy $0 "1"
   1401            FileWriteByte $4 195
   1402            FileWriteByte $4 188
   1403          ${ElseIf} $5 < 128
   1404            FileWriteByte $4 $5
   1405          ${EndIf}
   1406        ${Loop}
   1407        FileClose $3
   1408        FileClose $4
   1409        ${If} "$0" == "1"
   1410          ClearErrors
   1411          Rename "$1" "$1.bak"
   1412          ${Unless} ${Errors}
   1413            Rename "$2" "$1"
   1414            Delete "$1.bak"
   1415          ${EndUnless}
   1416        ${Else}
   1417          Delete "$2"
   1418        ${EndIf}
   1419      ${EndIf}
   1420    ${EndIf}
   1421  ${EndIf}
   1422 !macroend
   1423 !define FixDistributionsINI "!insertmacro FixDistributionsINI"
   1424 
   1425 ; For updates, adds a pinned shortcut to Task Bar on update for Windows 7
   1426 ; and 8 if this macro has never been called before and the application
   1427 ; is default (see PinToTaskBar for more details). This doesn't get called
   1428 ; for Windows 10 and 11 on updates, so we will never pin on update there.
   1429 ;
   1430 ; For installs, adds a taskbar pin if SHOULD_PIN is 1. (Defaults to 1,
   1431 ; but is controllable through the UI, ini file, and command line flags.)
   1432 !macro MigrateTaskBarShortcut SHOULD_PIN
   1433  ${GetShortcutsLogPath} $0
   1434  ${If} ${FileExists} "$0"
   1435    ClearErrors
   1436    ReadINIStr $1 "$0" "TASKBAR" "Migrated"
   1437    ${If} ${Errors}
   1438      ClearErrors
   1439      WriteIniStr "$0" "TASKBAR" "Migrated" "true"
   1440      WriteRegDWORD HKCU \
   1441        "Software\Mozilla\${AppName}\Installer\$AppUserModelID" \
   1442        "WasPinnedToTaskbar" 1
   1443      ${If} "${SHOULD_PIN}" == "1"
   1444        ${PinToTaskBar}
   1445      ${EndIf}
   1446    ${EndIf}
   1447  ${EndIf}
   1448 !macroend
   1449 !define MigrateTaskBarShortcut "!insertmacro MigrateTaskBarShortcut"
   1450 
   1451 !define GetPinningSupportedByWindowsVersionWithoutSystemPopup "!insertmacro GetPinningSupportedByWindowsVersionWithoutSystemPopup "
   1452 
   1453 ; Starting with Windows 10 (> 10.0.19045.3996) and Windows 11 (> 10.0.22621.2361),
   1454 ; the OS will show a system popup when trying to pin to the taskbar.
   1455 ;
   1456 ; Pass in the variable to put the output into. A '1' means pinning is supported on this
   1457 ; OS without generating a popup, a '0' means pinning will generate a system popup.
   1458 ;
   1459 ; More info: a version of Windows was released that introduced a system popup when
   1460 ; an exe (such as setup.exe) attempts to pin an app to the taskbar.
   1461 ; We already handle pinning in the onboarding process once Firefox
   1462 ; launches so we don't want to also attempt to pin it in the installer
   1463 ; and have the OS ask the user for confirmation without the full context.
   1464 ;
   1465 ; The number for that version of windows is still unclear (it might be 22H2 or 23H2)
   1466 ; and it's not supported by the version of WinVer.nsh we have anyways,
   1467 ; so instead we are manually retrieving the major, minor, build and ubr numbers
   1468 ; (Update Build Revision) and confirming that the build numbers work to do pinning
   1469 ; in the installer.
   1470 ;
   1471 ; NOTE: there are currently running Windows where pinning fails and is a no-op. We haven't quite
   1472 ; determined how to identify when that will happen, and it's so far only been reported
   1473 ; on the newest versions of Windows. GetPinningSupportedByWindowsVersionWithoutSystemPopup
   1474 ; will current report that pinning is not supported in these cases, due to reporting
   1475 ; pinning as not supported on the newest builds of Windows.
   1476 ;
   1477 !macro GetPinningSupportedByWindowsVersionWithoutSystemPopup outvar
   1478  !define pin_lbl lbl_GPSBWVWSP_${__COUNTER__}
   1479 
   1480  Push $0
   1481  Push $1
   1482  Push $2
   1483  Push $3
   1484 
   1485  ${WinVerGetMajor} $0
   1486  ${WinVerGetMinor} $1
   1487  ${WinVerGetBuild} $2
   1488 
   1489  ; Get the UBR; only documented way I could figure out how to get this reliably
   1490  ClearErrors
   1491  ReadRegDWORD $3 HKLM \
   1492    "Software\Microsoft\Windows NT\CurrentVersion" \
   1493    "UBR"
   1494 
   1495  ; It's not obvious how to use LogicLib itself within a LogicLib custom
   1496  ; operator, so we do everything by hand with `IntCmp`.  The below lines
   1497  ; translate to:
   1498  ; StrCpy ${outvar} '0'  ; default to false
   1499  ; ${If} $0 == 10
   1500  ;   ${If} $1 == 0
   1501  ;     ${If} $2 < 19045
   1502  ;       StrCpy ${outvar} '1'
   1503  ;     ${ElseIf} $2 == 19045
   1504  ;       ; Test Windows 10
   1505  ;       ${If} $3 < 3996
   1506  ;         StrCpy ${outvar} '1'
   1507  ;       ${Endif}
   1508  ;     ; 22000 is the version number that splits between Win 10 and 11
   1509  ;     ${ElseIf} $2 >= 22000
   1510  ;       ; Test Windows 11
   1511  ;       ${If} $2 < 22621
   1512  ;         StrCpy ${outvar} '1'
   1513  ;       ${ElseIf} $2 == 22621
   1514  ;         ${If} $3 < 2361
   1515  ;           StrCpy ${outvar} '1'
   1516  ;         ${EndIf}
   1517  ;       ${EndIf}
   1518  ;     ${EndIf}
   1519  ;  ${Endif}
   1520  ; ${EndIf}
   1521 
   1522  StrCpy ${outvar} '0' ; default to false on pinning
   1523 
   1524  ; If the major version is greater than 10, no pinning in setup
   1525  IntCmp $0 10 "" "" ${pin_lbl}_bad
   1526 
   1527  ; If the minor version is greater than 0, no pinning in setup
   1528  IntCmp $1 0 "" "" ${pin_lbl}_bad
   1529 
   1530  ; If the build number equals 19045, we have to test the UBR
   1531  ; If it's greater than 19045, then we have to check if
   1532  ; it's a Windows 11 build or not to determine if more testing
   1533  ; is needed
   1534  IntCmp $2 19045 ${pin_lbl}_test_win10 ${pin_lbl}_good ""
   1535 
   1536  ; If the major number is less than 22000, then we're between
   1537  ; 19046 and 22000, meaning pinning will produce a popup
   1538  IntCmp $2 22000 "" ${pin_lbl}_bad ""
   1539 
   1540  ${pin_lbl}_test_win11:
   1541 
   1542  ; If the build number is less than 22621, jump to pinning; if greater than, no pinning
   1543  IntCmp $2 22621 "" ${pin_lbl}_good ${pin_lbl}_bad
   1544 
   1545  ; Only if the version is 10.0.22621 do we fall through to here
   1546  ; If the UBR is greater than or equal to 2361, jump to no pinning
   1547  ; Otherwise jump to pinning
   1548  IntCmp $3 2361 ${pin_lbl}_bad ${pin_lbl}_good ${pin_lbl}_bad
   1549 
   1550  ${pin_lbl}_test_win10:
   1551 
   1552  ; Only if the version is 10.0.19045 or greater (but not Windows 11) do we fall
   1553  ; through to here.
   1554  ; If the UBR is greater than or equal to 3996, jump to no pinning
   1555  IntCmp $3 3996 ${pin_lbl}_bad ${pin_lbl}_good ${pin_lbl}_bad
   1556 
   1557  ${pin_lbl}_good:
   1558 
   1559  StrCpy ${outvar} '1'
   1560 
   1561  ${pin_lbl}_bad:
   1562  !undef pin_lbl
   1563 
   1564  Pop $3
   1565  Pop $2
   1566  Pop $1
   1567  Pop $0
   1568 !macroend
   1569 
   1570 !macro _PinningSupportedByWindowsVersionWithoutSystemPopup _ignore _ignore2 _t _f
   1571  !insertmacro _LOGICLIB_TEMP
   1572  ${GetPinningSupportedByWindowsVersionWithoutSystemPopup} $_LOGICLIB_TEMP
   1573  !insertmacro _= $_LOGICLIB_TEMP "1" `${_t}` `${_f}`
   1574 !macroend
   1575 
   1576 ; The following is to make if statements for the functionality easier. When using an if statement,
   1577 ; Use IsPinningSupportedByWindowsVersionWithoutSystemPopup like so, instead of GetPinningSupportedByWindowsVersionWithoutSystemPopup:
   1578 ;
   1579 ; ${If} ${IsPinningSupportedByWindowsVersionWithoutSystemPopup}
   1580 ;    ; do something
   1581 ; ${EndIf}
   1582 ;
   1583 !define IsPinningSupportedByWindowsVersionWithoutSystemPopup `"" PinningSupportedByWindowsVersionWithoutSystemPopup "" `
   1584 
   1585 ; Adds a pinned Task Bar shortcut on Windows 7 if there isn't one for the main
   1586 ; application executable already. Existing pinned shortcuts for the same
   1587 ; application model ID must be removed first to prevent breaking the pinned
   1588 ; item's lists but multiple installations with the same application model ID is
   1589 ; an edgecase. If removing existing pinned shortcuts with the same application
   1590 ; model ID removes a pinned pinned Start Menu shortcut this will also add a
   1591 ; pinned Start Menu shortcut.
   1592 ; This expects $RegHive to already have been set correctly.
   1593 !macro PinToTaskBar
   1594  StrCpy $8 "false" ; Whether a shortcut had to be created
   1595  ${IsPinnedToTaskBar} "$INSTDIR\${FileMainEXE}" $R9
   1596  ${If} "$R9" == "false"
   1597    ; Find an existing Start Menu shortcut or create one to use for pinning
   1598    ${GetShortcutsLogPath} $0
   1599    ${If} ${FileExists} "$0"
   1600      ClearErrors
   1601      ReadINIStr $1 "$0" "STARTMENU" "Shortcut0"
   1602      ${Unless} ${Errors}
   1603        SetShellVarContext all ; Set SHCTX to all users
   1604        ${Unless} ${FileExists} "$SMPROGRAMS\$1"
   1605          SetShellVarContext current ; Set SHCTX to the current user
   1606          ${Unless} ${FileExists} "$SMPROGRAMS\$1"
   1607            StrCpy $8 "true"
   1608            CreateShortCut "$SMPROGRAMS\$1" "$INSTDIR\${FileMainEXE}"
   1609            ${If} ${FileExists} "$SMPROGRAMS\$1"
   1610              ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\$1" \
   1611                                                     "$INSTDIR"
   1612              ${If} "$AppUserModelID" != ""
   1613                ApplicationID::Set "$SMPROGRAMS\$1" "$AppUserModelID" "true"
   1614              ${EndIf}
   1615            ${EndIf}
   1616          ${EndUnless}
   1617        ${EndUnless}
   1618 
   1619        ${If} ${FileExists} "$SMPROGRAMS\$1"
   1620          ; Count of Start Menu pinned shortcuts before unpinning.
   1621          ${PinnedToStartMenuLnkCount} $R9
   1622 
   1623          ; Having multiple shortcuts pointing to different installations with
   1624          ; the same AppUserModelID (e.g. side by side installations of the
   1625          ; same version) will make the TaskBar shortcut's lists into an bad
   1626          ; state where the lists are not shown. To prevent this first
   1627          ; uninstall the pinned item.
   1628          ApplicationID::UninstallPinnedItem "$SMPROGRAMS\$1"
   1629 
   1630          ; Count of Start Menu pinned shortcuts after unpinning.
   1631          ${PinnedToStartMenuLnkCount} $R8
   1632 
   1633          ; If there is a change in the number of Start Menu pinned shortcuts
   1634          ; assume that unpinning unpinned a side by side installation from
   1635          ; the Start Menu and pin this installation to the Start Menu.
   1636          ${Unless} $R8 == $R9
   1637            ; Pin the shortcut to the Start Menu. 5381 is the shell32.dll
   1638            ; resource id for the "Pin to Start Menu" string.
   1639            InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "5381"
   1640          ${EndUnless}
   1641 
   1642          ${If} ${AtMostWaaS} 1809
   1643            ; In Windows 10 the "Pin to Taskbar" resource was removed, so we
   1644            ; can't access the verb that way anymore. We have to create a
   1645            ; command key using the GUID that's assigned to this action and
   1646            ; then invoke that as a verb. This works up until build 1809
   1647            ReadRegStr $R9 HKLM \
   1648              "Software\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Windows.taskbarpin" \
   1649              "ExplorerCommandHandler"
   1650            WriteRegStr HKCU "Software\Classes\*\shell\${AppRegName}-$AppUserModelID" "ExplorerCommandHandler" $R9
   1651            InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "${AppRegName}-$AppUserModelID"
   1652            DeleteRegKey HKCU "Software\Classes\*\shell\${AppRegName}-$AppUserModelID"
   1653          ${Else}
   1654            ; In Windows 10 1903 and up, and Windows 11 prior to 22H2, the above no
   1655            ; longer works. We have yet another method for these versions
   1656            ; which is detailed in the PinToTaskbar plugin code.
   1657            ${If} ${IsPinningSupportedByWindowsVersionWithoutSystemPopup}
   1658              PinToTaskbar::Pin "$SMPROGRAMS\$1"
   1659            ${EndIf}
   1660          ${EndIf}
   1661 
   1662          ; Delete the shortcut if it was created
   1663          ${If} "$8" == "true"
   1664            Delete "$SMPROGRAMS\$1"
   1665          ${EndIf}
   1666        ${EndIf}
   1667 
   1668        ${If} $RegHive == "HKCU"
   1669          SetShellVarContext current ; Set SHCTX to the current user
   1670        ${Else}
   1671          SetShellVarContext all ; Set SHCTX to all users
   1672        ${EndIf}
   1673      ${EndUnless}
   1674    ${EndIf}
   1675  ${EndIf}
   1676 !macroend
   1677 !define PinToTaskBar "!insertmacro PinToTaskBar"
   1678 
   1679 ; Removes the application's start menu directory along with its shortcuts if
   1680 ; they exist and if they exist creates a start menu shortcut in the root of the
   1681 ; start menu directory (bug 598779). If the application's start menu directory
   1682 ; is not empty after removing the shortucts the directory will not be removed
   1683 ; since these additional items were not created by the installer (uses SHCTX).
   1684 !macro RemoveStartMenuDir
   1685  ${GetShortcutsLogPath} $0
   1686  ${If} ${FileExists} "$0"
   1687    ; Delete Start Menu Programs shortcuts, directory if it is empty, and
   1688    ; parent directories if they are empty up to but not including the start
   1689    ; menu directory.
   1690    ${GetLongPath} "$SMPROGRAMS" $1
   1691    ClearErrors
   1692    ReadINIStr $2 "$0" "SMPROGRAMS" "RelativePathToDir"
   1693    ${Unless} ${Errors}
   1694      ${GetLongPath} "$1\$2" $2
   1695      ${If} "$2" != ""
   1696        ; Delete shortucts in the Start Menu Programs directory.
   1697        StrCpy $3 0
   1698        ${Do}
   1699          ClearErrors
   1700          ReadINIStr $4 "$0" "SMPROGRAMS" "Shortcut$3"
   1701          ; Stop if there are no more entries
   1702          ${If} ${Errors}
   1703            ${ExitDo}
   1704          ${EndIf}
   1705          ${If} ${FileExists} "$2\$4"
   1706            ShellLink::GetShortCutTarget "$2\$4"
   1707            Pop $5
   1708            ${If} "$INSTDIR\${FileMainEXE}" == "$5"
   1709              Delete "$2\$4"
   1710            ${EndIf}
   1711          ${EndIf}
   1712          IntOp $3 $3 + 1 ; Increment the counter
   1713        ${Loop}
   1714        ; Delete Start Menu Programs directory and parent directories
   1715        ${Do}
   1716          ; Stop if the current directory is the start menu directory
   1717          ${If} "$1" == "$2"
   1718            ${ExitDo}
   1719          ${EndIf}
   1720          ClearErrors
   1721          RmDir "$2"
   1722          ; Stop if removing the directory failed
   1723          ${If} ${Errors}
   1724            ${ExitDo}
   1725          ${EndIf}
   1726          ${GetParent} "$2" $2
   1727        ${Loop}
   1728      ${EndIf}
   1729      DeleteINISec "$0" "SMPROGRAMS"
   1730    ${EndUnless}
   1731  ${EndIf}
   1732 !macroend
   1733 !define RemoveStartMenuDir "!insertmacro RemoveStartMenuDir"
   1734 
   1735 ; Creates the shortcuts log ini file with the appropriate entries if it doesn't
   1736 ; already exist.
   1737 !macro CreateShortcutsLog
   1738  ${GetShortcutsLogPath} $0
   1739  ${Unless} ${FileExists} "$0"
   1740    ${LogStartMenuShortcut} "${BrandShortName}.lnk"
   1741    ${LogQuickLaunchShortcut} "${BrandShortName}.lnk"
   1742 !ifndef DESKTOP_LAUNCHER_ENABLED
   1743    ${LogDesktopShortcut} "${BrandShortName}.lnk"
   1744 !endif
   1745  ${EndUnless}
   1746 !macroend
   1747 !define CreateShortcutsLog "!insertmacro CreateShortcutsLog"
   1748 
   1749 ; The files to check if they are in use during (un)install so the restart is
   1750 ; required message is displayed. All files must be located in the $INSTDIR
   1751 ; directory.
   1752 !macro PushFilesToCheck
   1753  ; The first string to be pushed onto the stack MUST be "end" to indicate
   1754  ; that there are no more files to check in $INSTDIR and the last string
   1755  ; should be ${FileMainEXE} so if it is in use the CheckForFilesInUse macro
   1756  ; returns after the first check.
   1757  Push "end"
   1758  Push "AccessibleMarshal.dll"
   1759  Push "freebl3.dll"
   1760  Push "nspr4.dll"
   1761  Push "nssdbm3.dll"
   1762  Push "mozsqlite3.dll"
   1763  Push "xpcom.dll"
   1764  Push "crashhelper.exe"
   1765  Push "crashreporter.exe"
   1766  Push "default-browser-agent.exe"
   1767  Push "nmhproxy.exe"
   1768  Push "updater.exe"
   1769  Push "mozwer.dll"
   1770  Push "${FileMainEXE}"
   1771 !macroend
   1772 !define PushFilesToCheck "!insertmacro PushFilesToCheck"
   1773 
   1774 
   1775 ; Pushes the string "true" to the top of the stack if the Firewall service is
   1776 ; running and pushes the string "false" to the top of the stack if it isn't.
   1777 !define SC_MANAGER_ALL_ACCESS 0x3F
   1778 !define SERVICE_QUERY_CONFIG 0x0001
   1779 !define SERVICE_QUERY_STATUS 0x0004
   1780 !define SERVICE_RUNNING 0x4
   1781 
   1782 !macro IsFirewallSvcRunning
   1783  Push $R9
   1784  Push $R8
   1785  Push $R7
   1786  Push $R6
   1787  Push "false"
   1788 
   1789  System::Call 'advapi32::OpenSCManagerW(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.R6'
   1790  ${If} $R6 != 0
   1791    ; MpsSvc is the Firewall service.
   1792    ; When opening the service with SERVICE_QUERY_CONFIG the return value will
   1793    ; be 0 if the service is not installed.
   1794    System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_CONFIG}) i.R7'
   1795    ${If} $R7 != 0
   1796      System::Call 'advapi32::CloseServiceHandle(i R7) n'
   1797      ; Open the service with SERVICE_QUERY_STATUS so its status can be queried.
   1798      System::Call 'advapi32::OpenServiceW(i R6, t "MpsSvc", i ${SERVICE_QUERY_STATUS}) i.R7'
   1799    ${EndIf}
   1800    ; Did the calls to OpenServiceW succeed?
   1801    ${If} $R7 != 0
   1802      System::Call '*(i,i,i,i,i,i,i) i.R9'
   1803      ; Query the current status of the service.
   1804      System::Call 'advapi32::QueryServiceStatus(i R7, i $R9) i'
   1805      System::Call '*$R9(i, i.R8)'
   1806      System::Free $R9
   1807      System::Call 'advapi32::CloseServiceHandle(i R7) n'
   1808      IntFmt $R8 "0x%X" $R8
   1809      ${If} $R8 == ${SERVICE_RUNNING}
   1810        Pop $R9
   1811        Push "true"
   1812      ${EndIf}
   1813    ${EndIf}
   1814    System::Call 'advapi32::CloseServiceHandle(i R6) n'
   1815  ${EndIf}
   1816 
   1817  Exch 1
   1818  Pop $R6
   1819  Exch 1
   1820  Pop $R7
   1821  Exch 1
   1822  Pop $R8
   1823  Exch 1
   1824  Pop $R9
   1825 !macroend
   1826 !define IsFirewallSvcRunning "!insertmacro IsFirewallSvcRunning"
   1827 !define un.IsFirewallSvcRunning "!insertmacro IsFirewallSvcRunning"
   1828 
   1829 ; Sets this installation as the default browser by setting the registry keys
   1830 ; under HKEY_CURRENT_USER via registry calls and using the AppAssocReg NSIS
   1831 ; plugin. This is a function instead of a macro so it is
   1832 ; easily called from an elevated instance of the binary. Since this can be
   1833 ; called by an elevated instance logging is not performed in this function.
   1834 Function SetAsDefaultAppUserHKCU
   1835  ; See if we're using path hash suffixed registry keys for this install
   1836  ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
   1837  ${StrFilter} "${FileMainEXE}" "+" "" "" $R9
   1838  ClearErrors
   1839  ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
   1840  ${If} ${Errors}
   1841    ClearErrors
   1842    ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
   1843  ${EndIf}
   1844  StrCpy $0 $0 -2
   1845  ${If} $0 != $8
   1846    ${If} $AppUserModelID == ""
   1847      ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
   1848    ${EndIf}
   1849    StrCpy $R9 "${AppRegName}-$AppUserModelID"
   1850  ${EndIf}
   1851 
   1852  ; Set ourselves as the user's selected StartMenuInternet browser, but only
   1853  ; if we have StartMenuInternet registry keys that are for this install.
   1854  ClearErrors
   1855  ReadRegStr $0 HKCU "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
   1856  ${If} ${Errors}
   1857    ClearErrors
   1858    ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
   1859  ${EndIf}
   1860  ${Unless} ${Errors}
   1861    ${GetPathFromString} "$0" $0
   1862    ${GetParent} "$0" $0
   1863    ${If} ${FileExists} "$0"
   1864      ${GetLongPath} "$0" $0
   1865      ${If} "$0" == "$INSTDIR"
   1866        ; This function cannot do anything to actually set the default browser,
   1867        ; it can only set up the registry entries to allow the user to do so.
   1868        ; Getting here means that those entries already exist for this
   1869        ; installation, we just found them, so there is nothing more to be
   1870        ; done.
   1871        Return
   1872      ${EndIf}
   1873    ${EndIf}
   1874  ${EndUnless}
   1875 
   1876  SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   1877 
   1878  ; It's unlikely that we didn't find a StartMenuInternet key above, but it is
   1879  ; possible; it likely would mean this copy of the application was extracted
   1880  ; directly from a ZIP file and the installer was never run.
   1881  ${SetStartMenuInternet} "HKCU"
   1882  ${FixShellIconHandler} "HKCU"
   1883  ${FixClassKeys} ; Does not use SHCTX
   1884 
   1885  ${SetHandlers}
   1886 
   1887  ; Only register as the handler if the app registry name
   1888  ; exists under the RegisteredApplications registry key. The protocol and
   1889  ; file handlers set previously at the user level will associate this install
   1890  ; as the default browser.
   1891  ClearErrors
   1892  ReadRegStr $0 HKLM "Software\RegisteredApplications" "$R9"
   1893  ${Unless} ${Errors}
   1894    ; This is all protected by a user choice hash in Windows 8 so it won't
   1895    ; help, but it also won't hurt.
   1896    AppAssocReg::SetAppAsDefault "$R9" ".htm" "file"
   1897    Pop $0
   1898    AppAssocReg::SetAppAsDefault "$R9" ".html" "file"
   1899    Pop $0
   1900    AppAssocReg::SetAppAsDefault "$R9" ".shtml" "file"
   1901    Pop $0
   1902    AppAssocReg::SetAppAsDefault "$R9" ".webp" "file"
   1903    Pop $0
   1904    AppAssocReg::SetAppAsDefault "$R9" ".avif" "file"
   1905    Pop $0
   1906    AppAssocReg::SetAppAsDefault "$R9" ".xht" "file"
   1907    Pop $0
   1908    AppAssocReg::SetAppAsDefault "$R9" ".xhtml" "file"
   1909    Pop $0
   1910    AppAssocReg::SetAppAsDefault "$R9" "http" "protocol"
   1911    Pop $0
   1912    AppAssocReg::SetAppAsDefault "$R9" "https" "protocol"
   1913    Pop $0
   1914  ${EndUnless}
   1915  ${RemoveDeprecatedKeys}
   1916  ${MigrateTaskBarShortcut} "$R0"
   1917 FunctionEnd
   1918 
   1919 ; Helper for updating the shortcut application model IDs.
   1920 Function FixShortcutAppModelIDs
   1921  ${If} "$AppUserModelID" != ""
   1922    ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "$AppUserModelID" $0
   1923  ${EndIf}
   1924 FunctionEnd
   1925 
   1926 ; Helper for adding Firewall exceptions during install and after app update.
   1927 Function AddFirewallEntries
   1928  ${IsFirewallSvcRunning}
   1929  Pop $0
   1930  ${If} "$0" == "true"
   1931    liteFirewallW::AddRule "$INSTDIR\${FileMainEXE}" "${BrandShortName} ($INSTDIR)"
   1932  ${EndIf}
   1933 FunctionEnd
   1934 
   1935 ; The !ifdef NO_LOG prevents warnings when compiling the installer.nsi due to
   1936 ; this function only being used by the uninstaller.nsi.
   1937 !ifdef NO_LOG
   1938 
   1939 Function SetAsDefaultAppUser
   1940  ; AddTaskbarSC is needed by MigrateTaskBarShortcut, which is called by
   1941  ; SetAsDefaultAppUserHKCU. If this is called via ExecCodeSegment,
   1942  ; MigrateTaskBarShortcut will not see the value of AddTaskbarSC, so we
   1943  ; send it via a register instead.
   1944  StrCpy $R0 $AddTaskbarSC
   1945  ; We want to avoid having a UAC prompt since we'll already have another
   1946  ; action for control panel default browser selection popping upto the user.
   1947  ; The start menu keys can be added into HKCU.  The call to
   1948  ; SetAsDefaultAppUserHKCU will have already set the HKCU keys for
   1949  ; SetStartMenuInternet.
   1950  ; Check if this is running in an elevated process
   1951  ClearErrors
   1952  ${GetParameters} $0
   1953  ${GetOptions} "$0" "/UAC:" $0
   1954  ${If} ${Errors} ; Not elevated
   1955    Call SetAsDefaultAppUserHKCU
   1956  ${Else} ; Elevated - execute the function in the unelevated process
   1957    GetFunctionAddress $0 SetAsDefaultAppUserHKCU
   1958    UAC::ExecCodeSegment $0
   1959  ${EndIf}
   1960 FunctionEnd
   1961 !define SetAsDefaultAppUser "Call SetAsDefaultAppUser"
   1962 
   1963 !endif ; NO_LOG
   1964 
   1965 !ifdef MOZ_LAUNCHER_PROCESS
   1966 !macro ResetLauncherProcessDefaults
   1967  # By deleting these values, we remove remnants of any force-disable settings
   1968  # that may have been set during the SHIELD study in 67. Note that this setting
   1969  # was only intended to distinguish between test and control groups for the
   1970  # purposes of the study, not as a user preference.
   1971  DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Launcher"
   1972  DeleteRegValue HKCU ${MOZ_LAUNCHER_SUBKEY} "$INSTDIR\${FileMainEXE}|Browser"
   1973 !macroend
   1974 !define ResetLauncherProcessDefaults "!insertmacro ResetLauncherProcessDefaults"
   1975 !endif
   1976 
   1977 !macro WriteToastNotificationRegistration RegKey
   1978  ; Find or create a GUID to use for this installation.  For simplicity, We
   1979  ; always update our registration.
   1980  ClearErrors
   1981  ReadRegStr $0 SHCTX "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator"
   1982  ${If} "$0" == ""
   1983    ; Create a GUID.
   1984    System::Call "rpcrt4::UuidCreate(g . r0)i"
   1985    ; StringFromGUID2 (which is what System::Call uses internally to stringify
   1986    ; GUIDs) includes braces in its output.  In this case, we want the braces.
   1987  ${EndIf}
   1988 
   1989  ; Check if this is an ESR release.
   1990  ClearErrors
   1991  ${WordFind} "${UpdateChannel}" "esr" "E#" $1
   1992  ${If} ${Errors}
   1993    StrCpy $1 ""
   1994  ${Else}
   1995    StrCpy $1 " ESR"
   1996  ${EndIf}
   1997 
   1998  ; Write the following keys and values to the registry.
   1999  ; HKEY_CURRENT_USER\Software\Classes\AppID\{GUID}                                     DllSurrogate    : REG_SZ        = ""
   2000  ;                                   \AppUserModelId\{ToastAumidPrefix}{install hash}  CustomActivator : REG_SZ        = {GUID}
   2001  ;                                                                                     DisplayName     : REG_EXPAND_SZ = {display name}
   2002  ;                                                                                     IconUri         : REG_EXPAND_SZ = {icon path}
   2003  ;                                   \CLSID\{GUID}                                     AppID           : REG_SZ        = {GUID}
   2004  ;                                                \InprocServer32                      (Default)       : REG_SZ        = {notificationserver.dll path}
   2005  ${WriteRegStr2} ${RegKey} "Software\Classes\AppID\$0" "DllSurrogate" "" 0
   2006  ${WriteRegStr2} ${RegKey} "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "CustomActivator" "$0" 0
   2007  ${WriteRegStr2} ${RegKey} "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "DisplayName" "${BrandFullNameInternal}$1" 0
   2008  ; Sadly, we can't use embedded resources like `firefox.exe,1`.
   2009  ${WriteRegStr2} ${RegKey} "Software\Classes\AppUserModelId\${ToastAumidPrefix}$AppUserModelID" "IconUri" "$INSTDIR\browser\VisualElements\VisualElements_70.png" 0
   2010  ${WriteRegStr2} ${RegKey} "Software\Classes\CLSID\$0" "AppID" "$0" 0
   2011  ${WriteRegStr2} ${RegKey} "Software\Classes\CLSID\$0\InProcServer32" "" "$INSTDIR\notificationserver.dll" 0
   2012 !macroend
   2013 !define WriteToastNotificationRegistration "!insertmacro WriteToastNotificationRegistration"
   2014 
   2015 /**
   2016 * Deletes the registry keys for a protocol handler but only if those registry
   2017 * keys were pointed to the installation being uninstalled.
   2018 * Does this with both the HKLM and the HKCU registry entries.
   2019 *
   2020 * @param   _PROTOCOL
   2021 *          The protocol to delete the registry keys for
   2022 */
   2023 !macro DeleteProtocolRegistryIfSetToInstallation INSTALL_PATH _PROTOCOL
   2024  Push $0
   2025 
   2026  ; Check if there is a protocol handler registered by fetching the DefaultIcon value
   2027  ; in the registry.
   2028  ; If there is something registered for the icon, it will be the path to the executable,
   2029  ; plus a comma and a number for the id of the resource for the icon.
   2030  ; Use StrCpy with -2 to remove the comma and the resource id so that
   2031  ; the whole path to the executable can be compared against what's being
   2032  ; uninstalled.
   2033 
   2034  ; Do all of that twice, once for the local machine and once for the current user
   2035  
   2036  ; Remove protocol handlers
   2037  ClearErrors
   2038  ReadRegStr $0 HKLM "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
   2039  ${If} $0 != ""
   2040    StrCpy $0 $0 -2
   2041    ${If} $0 == '"${INSTALL_PATH}"'
   2042      DeleteRegKey HKLM "Software\Classes\${_PROTOCOL}"
   2043    ${EndIf}
   2044  ${EndIf}
   2045 
   2046  ClearErrors
   2047  ReadRegStr $0 HKCU "Software\Classes\${_PROTOCOL}\DefaultIcon" ""
   2048  ${If} $0 != ""
   2049    StrCpy $0 $0 -2
   2050    ${If} $0 == '"${INSTALL_PATH}"'
   2051      DeleteRegKey HKCU "Software\Classes\${_PROTOCOL}"
   2052    ${EndIf}
   2053  ${EndIf}
   2054 
   2055  ClearErrors
   2056 
   2057  Pop $0
   2058 !macroend
   2059 !define DeleteProtocolRegistryIfSetToInstallation '!insertmacro DeleteProtocolRegistryIfSetToInstallation'