toolkit/mozapps/installer/windows/nsis/common.nsh

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/mozapps/installer/windows/nsis/common.nsh	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,7878 @@
     1.4 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.7 +
     1.8 +
     1.9 +################################################################################
    1.10 +# Helper defines and macros for toolkit applications
    1.11 +
    1.12 +/**
    1.13 + * Avoid creating macros / functions that overwrite registers (see the
    1.14 + * GetLongPath macro for one way to avoid this)!
    1.15 + *
    1.16 + * Before using the registers exchange the passed in params and save existing
    1.17 + * register values to the stack.
    1.18 + *
    1.19 + * Exch $R9 ; exhange the original $R9 with the top of the stack
    1.20 + * Exch 1   ; exchange the top of the stack with 1 below the top of the stack
    1.21 + * Exch $R8 ; exchange the original $R8 with the top of the stack
    1.22 + * Exch 2   ; exchange the top of the stack with 2 below the top of the stack
    1.23 + * Exch $R7 ; exchange the original $R7 with the top of the stack
    1.24 + * Push $R6 ; push the original $R6 onto the top of the stack
    1.25 + * Push $R5 ; push the original $R5 onto the top of the stack
    1.26 + * Push $R4 ; push the original $R4 onto the top of the stack
    1.27 + *
    1.28 + * <do stuff>
    1.29 + *
    1.30 + * ; Restore the values.
    1.31 + * Pop $R4  ; restore the value for $R4 from the top of the stack
    1.32 + * Pop $R5  ; restore the value for $R5 from the top of the stack
    1.33 + * Pop $R6  ; restore the value for $R6 from the top of the stack
    1.34 + * Exch $R7 ; exchange the new $R7 value with the top of the stack
    1.35 + * Exch 2   ; exchange the top of the stack with 2 below the top of the stack
    1.36 + * Exch $R8 ; exchange the new $R8 value with the top of the stack
    1.37 + * Exch 1   ; exchange the top of the stack with 2 below the top of the stack
    1.38 + * Exch $R9 ; exchange the new $R9 value with the top of the stack
    1.39 + *
    1.40 + *
    1.41 + * When inserting macros in common.nsh from another macro in common.nsh that
    1.42 + * can be used from the uninstaller _MOZFUNC_UN will be undefined when it is
    1.43 + * inserted. Use the following to redefine _MOZFUNC_UN with its original value
    1.44 + * (see the RegCleanMain macro for an example).
    1.45 + *
    1.46 + * !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
    1.47 + * !insertmacro ${_MOZFUNC_UN_TMP}FileJoin
    1.48 + * !insertmacro ${_MOZFUNC_UN_TMP}LineFind
    1.49 + * !insertmacro ${_MOZFUNC_UN_TMP}TextCompareNoDetails
    1.50 + * !insertmacro ${_MOZFUNC_UN_TMP}TrimNewLines
    1.51 + * !undef _MOZFUNC_UN
    1.52 + * !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
    1.53 + * !undef _MOZFUNC_UN_TMP
    1.54 + */
    1.55 +
    1.56 +; When including a file provided by NSIS check if its verbose macro is defined
    1.57 +; to prevent loading the file a second time.
    1.58 +!ifmacrondef TEXTFUNC_VERBOSE
    1.59 +  !include TextFunc.nsh
    1.60 +!endif
    1.61 +
    1.62 +!ifmacrondef FILEFUNC_VERBOSE
    1.63 +  !include FileFunc.nsh
    1.64 +!endif
    1.65 +
    1.66 +!ifmacrondef LOGICLIB_VERBOSITY
    1.67 +  !include LogicLib.nsh
    1.68 +!endif
    1.69 +
    1.70 +!ifndef WINMESSAGES_INCLUDED
    1.71 +  !include WinMessages.nsh
    1.72 +!endif
    1.73 +
    1.74 +; When including WinVer.nsh check if ___WINVER__NSH___ is defined to prevent
    1.75 +; loading the file a second time.
    1.76 +!ifndef ___WINVER__NSH___
    1.77 +  !include WinVer.nsh
    1.78 +!endif
    1.79 +
    1.80 +!include x64.nsh
    1.81 +
    1.82 +; NSIS provided macros that we have overridden.
    1.83 +!include overrides.nsh
    1.84 +
    1.85 +!define SHORTCUTS_LOG "shortcuts_log.ini"
    1.86 +!define TO_BE_DELETED "tobedeleted"
    1.87 +
    1.88 +; !define SHCNF_DWORD     0x0003
    1.89 +; !define SHCNF_FLUSH     0x1000
    1.90 +!ifndef SHCNF_DWORDFLUSH
    1.91 +  !define SHCNF_DWORDFLUSH 0x1003
    1.92 +!endif
    1.93 +!ifndef SHCNE_ASSOCCHANGED
    1.94 +  !define SHCNE_ASSOCCHANGED 0x08000000
    1.95 +!endif
    1.96 +
    1.97 +################################################################################
    1.98 +# Macros for debugging
    1.99 +
   1.100 +/**
   1.101 + * The following two macros assist with verifying that a macro doesn't
   1.102 + * overwrite any registers.
   1.103 + *
   1.104 + * Usage:
   1.105 + * ${debugSetRegisters}
   1.106 + * <do stuff>
   1.107 + * ${debugDisplayRegisters}
   1.108 + */
   1.109 +
   1.110 +/**
   1.111 + * Sets all register values to their name to assist with verifying that a macro
   1.112 + * doesn't overwrite any registers.
   1.113 + */
   1.114 +!macro debugSetRegisters
   1.115 +  StrCpy $0 "$$0"
   1.116 +  StrCpy $1 "$$1"
   1.117 +  StrCpy $2 "$$2"
   1.118 +  StrCpy $3 "$$3"
   1.119 +  StrCpy $4 "$$4"
   1.120 +  StrCpy $5 "$$5"
   1.121 +  StrCpy $6 "$$6"
   1.122 +  StrCpy $7 "$$7"
   1.123 +  StrCpy $8 "$$8"
   1.124 +  StrCpy $9 "$$9"
   1.125 +  StrCpy $R0 "$$R0"
   1.126 +  StrCpy $R1 "$$R1"
   1.127 +  StrCpy $R2 "$$R2"
   1.128 +  StrCpy $R3 "$$R3"
   1.129 +  StrCpy $R4 "$$R4"
   1.130 +  StrCpy $R5 "$$R5"
   1.131 +  StrCpy $R6 "$$R6"
   1.132 +  StrCpy $R7 "$$R7"
   1.133 +  StrCpy $R8 "$$R8"
   1.134 +  StrCpy $R9 "$$R9"
   1.135 +!macroend
   1.136 +!define debugSetRegisters "!insertmacro debugSetRegisters"
   1.137 +
   1.138 +/**
   1.139 + * Displays all register values to assist with verifying that a macro doesn't
   1.140 + * overwrite any registers.
   1.141 + */
   1.142 +!macro debugDisplayRegisters
   1.143 +  MessageBox MB_OK \
   1.144 +      "Register Values:$\n\
   1.145 +       $$0 = $0$\n$$1 = $1$\n$$2 = $2$\n$$3 = $3$\n$$4 = $4$\n\
   1.146 +       $$5 = $5$\n$$6 = $6$\n$$7 = $7$\n$$8 = $8$\n$$9 = $9$\n\
   1.147 +       $$R0 = $R0$\n$$R1 = $R1$\n$$R2 = $R2$\n$$R3 = $R3$\n$$R4 = $R4$\n\
   1.148 +       $$R5 = $R5$\n$$R6 = $R6$\n$$R7 = $R7$\n$$R8 = $R8$\n$$R9 = $R9"
   1.149 +!macroend
   1.150 +!define debugDisplayRegisters "!insertmacro debugDisplayRegisters"
   1.151 +
   1.152 +
   1.153 +################################################################################
   1.154 +# Modern User Interface (MUI) override macros
   1.155 +
   1.156 +; Removed macros in nsis 2.33u (ported from nsis 2.22)
   1.157 +;  MUI_LANGUAGEFILE_DEFINE
   1.158 +;  MUI_LANGUAGEFILE_LANGSTRING_PAGE
   1.159 +;  MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE
   1.160 +;  MUI_LANGUAGEFILE_LANGSTRING_DEFINE
   1.161 +;  MUI_LANGUAGEFILE_UNLANGSTRING_PAGE
   1.162 +
   1.163 +!macro MOZ_MUI_LANGUAGEFILE_DEFINE DEFINE NAME
   1.164 +
   1.165 +  !ifndef "${DEFINE}"
   1.166 +    !define "${DEFINE}" "${${NAME}}"
   1.167 +  !endif
   1.168 +  !undef "${NAME}"
   1.169 +
   1.170 +!macroend
   1.171 +
   1.172 +!macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE PAGE NAME
   1.173 +
   1.174 +  !ifdef MUI_${PAGE}PAGE
   1.175 +    LangString "${NAME}" 0 "${${NAME}}"
   1.176 +    !undef "${NAME}"
   1.177 +  !else
   1.178 +    !undef "${NAME}"
   1.179 +  !endif
   1.180 +
   1.181 +!macroend
   1.182 +
   1.183 +!macro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE PAGE NAME
   1.184 +
   1.185 +  !ifdef MUI_${PAGE}PAGE | MUI_UN${PAGE}PAGE
   1.186 +    LangString "${NAME}" 0 "${${NAME}}"
   1.187 +    !undef "${NAME}"
   1.188 +  !else
   1.189 +    !undef "${NAME}"
   1.190 +  !endif
   1.191 +
   1.192 +!macroend
   1.193 +
   1.194 +!macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE DEFINE NAME
   1.195 +
   1.196 +  !ifdef "${DEFINE}"
   1.197 +    LangString "${NAME}" 0 "${${NAME}}"
   1.198 +  !endif
   1.199 +  !undef "${NAME}"
   1.200 +
   1.201 +!macroend
   1.202 +
   1.203 +!macro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE PAGE NAME
   1.204 +
   1.205 +  !ifdef MUI_UNINSTALLER
   1.206 +    !ifdef MUI_UN${PAGE}PAGE
   1.207 +      LangString "${NAME}" 0 "${${NAME}}"
   1.208 +      !undef "${NAME}"
   1.209 +    !else
   1.210 +      !undef "${NAME}"
   1.211 +    !endif
   1.212 +  !else
   1.213 +    !undef "${NAME}"
   1.214 +  !endif
   1.215 +
   1.216 +!macroend
   1.217 +
   1.218 +; Modified version of the following MUI macros to support Mozilla localization.
   1.219 +; MUI_LANGUAGE
   1.220 +; MUI_LANGUAGEFILE_BEGIN
   1.221 +; MOZ_MUI_LANGUAGEFILE_END
   1.222 +; See <NSIS App Dir>/Contrib/Modern UI/System.nsh for more information
   1.223 +!define MUI_INSTALLOPTIONS_READ "!insertmacro MUI_INSTALLOPTIONS_READ"
   1.224 +
   1.225 +!macro MOZ_MUI_LANGUAGE LANGUAGE
   1.226 +  !verbose push
   1.227 +  !verbose ${MUI_VERBOSE}
   1.228 +  !include "${LANGUAGE}.nsh"
   1.229 +  !verbose pop
   1.230 +!macroend
   1.231 +
   1.232 +!macro MOZ_MUI_LANGUAGEFILE_BEGIN LANGUAGE
   1.233 +  !insertmacro MUI_INSERT
   1.234 +  !ifndef "MUI_LANGUAGEFILE_${LANGUAGE}_USED"
   1.235 +    !define "MUI_LANGUAGEFILE_${LANGUAGE}_USED"
   1.236 +    LoadLanguageFile "${LANGUAGE}.nlf"
   1.237 +  !else
   1.238 +    !error "Modern UI language file ${LANGUAGE} included twice!"
   1.239 +  !endif
   1.240 +!macroend
   1.241 +
   1.242 +; Custom version of MUI_LANGUAGEFILE_END. The macro to add the default MUI
   1.243 +; strings and the macros for several strings that are part of the NSIS MUI and
   1.244 +; not in our locale files have been commented out.
   1.245 +!macro MOZ_MUI_LANGUAGEFILE_END
   1.246 +
   1.247 +#  !include "${NSISDIR}\Contrib\Modern UI\Language files\Default.nsh"
   1.248 +  !ifdef MUI_LANGUAGEFILE_DEFAULT_USED
   1.249 +    !undef MUI_LANGUAGEFILE_DEFAULT_USED
   1.250 +    !warning "${LANGUAGE} Modern UI language file version doesn't match. Using default English texts for missing strings."
   1.251 +  !endif
   1.252 +
   1.253 +  !insertmacro MOZ_MUI_LANGUAGEFILE_DEFINE "MUI_${LANGUAGE}_LANGNAME" "MUI_LANGNAME"
   1.254 +
   1.255 +  !ifndef MUI_LANGDLL_PUSHLIST
   1.256 +    !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} "
   1.257 +  !else
   1.258 +    !ifdef MUI_LANGDLL_PUSHLIST_TEMP
   1.259 +      !undef MUI_LANGDLL_PUSHLIST_TEMP
   1.260 +    !endif
   1.261 +    !define MUI_LANGDLL_PUSHLIST_TEMP "${MUI_LANGDLL_PUSHLIST}"
   1.262 +    !undef MUI_LANGDLL_PUSHLIST
   1.263 +    !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} ${MUI_LANGDLL_PUSHLIST_TEMP}"
   1.264 +  !endif
   1.265 +
   1.266 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TITLE"
   1.267 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TEXT"
   1.268 +
   1.269 +!ifdef MUI_TEXT_LICENSE_TITLE
   1.270 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_TITLE"
   1.271 +!endif
   1.272 +!ifdef MUI_TEXT_LICENSE_SUBTITLE
   1.273 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_SUBTITLE"
   1.274 +!endif
   1.275 +!ifdef MUI_INNERTEXT_LICENSE_TOP
   1.276 +  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_TOP"
   1.277 +!endif
   1.278 +
   1.279 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM"
   1.280 +
   1.281 +!ifdef MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX
   1.282 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX"
   1.283 +!endif
   1.284 +
   1.285 +!ifdef MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS
   1.286 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS"
   1.287 +!endif
   1.288 +
   1.289 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_TITLE"
   1.290 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_SUBTITLE"
   1.291 +  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE"
   1.292 +  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO"
   1.293 +
   1.294 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_TITLE"
   1.295 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_SUBTITLE"
   1.296 +
   1.297 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_TITLE"
   1.298 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_SUBTITLE"
   1.299 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_TOP"
   1.300 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_CHECKBOX"
   1.301 +
   1.302 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_TITLE"
   1.303 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_SUBTITLE"
   1.304 +
   1.305 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_TITLE"
   1.306 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_SUBTITLE"
   1.307 +
   1.308 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_TITLE"
   1.309 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_SUBTITLE"
   1.310 +
   1.311 +  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_BUTTONTEXT_FINISH"
   1.312 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TITLE"
   1.313 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TEXT"
   1.314 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_REBOOT"
   1.315 +  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTNOW"
   1.316 +  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTLATER"
   1.317 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_RUN"
   1.318 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_SHOWREADME"
   1.319 +
   1.320 +; Support for using the existing MUI_TEXT_ABORTWARNING string
   1.321 +!ifdef MOZ_MUI_CUSTOM_ABORT
   1.322 +    LangString MOZ_MUI_TEXT_ABORTWARNING 0 "${MUI_TEXT_ABORTWARNING}"
   1.323 +!endif
   1.324 +
   1.325 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_ABORTWARNING "MUI_TEXT_ABORTWARNING"
   1.326 +
   1.327 +
   1.328 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TITLE"
   1.329 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TEXT"
   1.330 +
   1.331 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_TITLE"
   1.332 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_SUBTITLE"
   1.333 +
   1.334 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_TITLE"
   1.335 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_SUBTITLE"
   1.336 +
   1.337 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM"
   1.338 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_CHECKBOX"
   1.339 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS"
   1.340 +
   1.341 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_TITLE"
   1.342 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_SUBTITLE"
   1.343 +
   1.344 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_TITLE"
   1.345 +#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY  "MUI_UNTEXT_DIRECTORY_SUBTITLE"
   1.346 +
   1.347 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_TITLE"
   1.348 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_SUBTITLE"
   1.349 +
   1.350 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_TITLE"
   1.351 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_SUBTITLE"
   1.352 +
   1.353 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_TITLE"
   1.354 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_SUBTITLE"
   1.355 +
   1.356 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TITLE"
   1.357 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TEXT"
   1.358 +  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_REBOOT"
   1.359 +
   1.360 +  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_UNABORTWARNING "MUI_UNTEXT_ABORTWARNING"
   1.361 +
   1.362 +  !ifndef MUI_LANGDLL_LANGUAGES
   1.363 +    !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' "
   1.364 +    !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' "
   1.365 +  !else
   1.366 +    !ifdef MUI_LANGDLL_LANGUAGES_TEMP
   1.367 +      !undef MUI_LANGDLL_LANGUAGES_TEMP
   1.368 +    !endif
   1.369 +    !define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}"
   1.370 +    !undef MUI_LANGDLL_LANGUAGES
   1.371 +
   1.372 +    !ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP
   1.373 +      !undef MUI_LANGDLL_LANGUAGES_CP_TEMP
   1.374 +    !endif
   1.375 +    !define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}"
   1.376 +    !undef MUI_LANGDLL_LANGUAGES_CP
   1.377 +
   1.378 +    !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}"
   1.379 +    !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}"
   1.380 +  !endif
   1.381 +
   1.382 +!macroend
   1.383 +
   1.384 +/**
   1.385 + * Creates an InstallOptions file with a UTF-16LE BOM and adds the RTL value
   1.386 + * to the Settings section.
   1.387 + *
   1.388 + * @param   _FILE
   1.389 + *          The name of the file to be created in $PLUGINSDIR.
   1.390 + */
   1.391 +!macro InitInstallOptionsFile _FILE
   1.392 +  Push $R9
   1.393 +
   1.394 +  FileOpen $R9 "$PLUGINSDIR\${_FILE}" w
   1.395 +  FileWriteWord $R9 "65279"
   1.396 +  FileClose $R9
   1.397 +  WriteIniStr "$PLUGINSDIR\${_FILE}" "Settings" "RTL" "$(^RTL)"
   1.398 +
   1.399 +  Pop $R9
   1.400 +!macroend
   1.401 +
   1.402 +
   1.403 +################################################################################
   1.404 +# Macros for handling files in use
   1.405 +
   1.406 +/**
   1.407 + * Checks for files in use in the $INSTDIR directory. To check files in
   1.408 + * sub-directories this macro would need to be rewritten to create
   1.409 + * sub-directories in the temporary directory used to backup the files that are
   1.410 + * checked.
   1.411 + *
   1.412 + * Example usage:
   1.413 + *
   1.414 + *  ; The first string to be pushed onto the stack MUST be "end" to indicate
   1.415 + *  ; that there are no more files in the $INSTDIR directory to check.
   1.416 + *  Push "end"
   1.417 + *  Push "freebl3.dll"
   1.418 + *  ; The last file pushed should be the app's main exe so if it is in use this
   1.419 + *  ; macro will return after the first check.
   1.420 + *  Push "${FileMainEXE}"
   1.421 + *  ${CheckForFilesInUse} $R9
   1.422 + *
   1.423 + * !IMPORTANT - this macro uses the $R7, $R8, and $R9 registers and makes no
   1.424 + *              attempt to restore their original values.
   1.425 + *
   1.426 + * @return  _RESULT
   1.427 + *          false if all of the files popped from the stack are not in use.
   1.428 + *          True if any of the files popped from the stack are in use.
   1.429 + * $R7 = Temporary backup directory where the files will be copied to.
   1.430 + * $R8 = value popped from the stack. This will either be a file name for a file
   1.431 + *       in the $INSTDIR directory or "end" to indicate that there are no
   1.432 + *       additional files to check.
   1.433 + * $R9 = _RESULT
   1.434 + */
   1.435 +!macro CheckForFilesInUse
   1.436 +
   1.437 +  !ifndef ${_MOZFUNC_UN}CheckForFilesInUse
   1.438 +    !verbose push
   1.439 +    !verbose ${_MOZFUNC_VERBOSE}
   1.440 +    !define ${_MOZFUNC_UN}CheckForFilesInUse "!insertmacro ${_MOZFUNC_UN}CheckForFilesInUseCall"
   1.441 +
   1.442 +    Function ${_MOZFUNC_UN}CheckForFilesInUse
   1.443 +      ; Create a temporary backup directory.
   1.444 +      GetTempFileName $R7 "$INSTDIR"
   1.445 +      Delete "$R7"
   1.446 +      SetOutPath "$R7"
   1.447 +      StrCpy $R9 "false"
   1.448 +
   1.449 +      Pop $R8
   1.450 +      ${While} $R8 != "end"
   1.451 +        ${Unless} ${FileExists} "$INSTDIR\$R8"
   1.452 +          Pop $R8 ; get next file to check before continuing
   1.453 +          ${Continue}
   1.454 +        ${EndUnless}
   1.455 +
   1.456 +        ClearErrors
   1.457 +        CopyFiles /SILENT "$INSTDIR\$R8" "$R7\$R8" ; try to copy
   1.458 +        ${If} ${Errors}
   1.459 +          ; File is in use
   1.460 +          StrCpy $R9 "true"
   1.461 +          ${Break}
   1.462 +        ${EndIf}
   1.463 +
   1.464 +        Delete "$INSTDIR\$R8" ; delete original
   1.465 +        ${If} ${Errors}
   1.466 +          ; File is in use
   1.467 +          StrCpy $R9 "true"
   1.468 +          Delete "$R7\$R8" ; delete temp copy
   1.469 +          ${Break}
   1.470 +        ${EndIf}
   1.471 +
   1.472 +        Pop $R8 ; get next file to check
   1.473 +      ${EndWhile}
   1.474 +
   1.475 +      ; clear stack
   1.476 +      ${While} $R8 != "end"
   1.477 +        Pop $R8
   1.478 +      ${EndWhile}
   1.479 +
   1.480 +      ; restore everything
   1.481 +      SetOutPath "$INSTDIR"
   1.482 +      CopyFiles /SILENT "$R7\*" "$INSTDIR\"
   1.483 +      RmDir /r "$R7"
   1.484 +      SetOutPath "$EXEDIR"
   1.485 +      ClearErrors
   1.486 +
   1.487 +      Push $R9
   1.488 +    FunctionEnd
   1.489 +
   1.490 +    !verbose pop
   1.491 +  !endif
   1.492 +!macroend
   1.493 +
   1.494 +!macro CheckForFilesInUseCall _RESULT
   1.495 +  !verbose push
   1.496 +  !verbose ${_MOZFUNC_VERBOSE}
   1.497 +  Call CheckForFilesInUse
   1.498 +  Pop ${_RESULT}
   1.499 +  !verbose pop
   1.500 +!macroend
   1.501 +
   1.502 +!macro un.CheckForFilesInUseCall _RESULT
   1.503 +  !verbose push
   1.504 +  !verbose ${_MOZFUNC_VERBOSE}
   1.505 +  Call un.CheckForFilesInUse
   1.506 +  Pop ${_RESULT}
   1.507 +  !verbose pop
   1.508 +!macroend
   1.509 +
   1.510 +!macro un.CheckForFilesInUse
   1.511 +  !ifndef un.CheckForFilesInUse
   1.512 +    !verbose push
   1.513 +    !verbose ${_MOZFUNC_VERBOSE}
   1.514 +    !undef _MOZFUNC_UN
   1.515 +    !define _MOZFUNC_UN "un."
   1.516 +
   1.517 +    !insertmacro CheckForFilesInUse
   1.518 +
   1.519 +    !undef _MOZFUNC_UN
   1.520 +    !define _MOZFUNC_UN
   1.521 +    !verbose pop
   1.522 +  !endif
   1.523 +!macroend
   1.524 +
   1.525 +/**
   1.526 + * The macros below will automatically prepend un. to the function names when
   1.527 + * they are defined (e.g. !define un.RegCleanMain).
   1.528 + */
   1.529 +!verbose push
   1.530 +!verbose 3
   1.531 +!ifndef _MOZFUNC_VERBOSE
   1.532 +  !define _MOZFUNC_VERBOSE 3
   1.533 +!endif
   1.534 +!verbose ${_MOZFUNC_VERBOSE}
   1.535 +!define MOZFUNC_VERBOSE "!insertmacro MOZFUNC_VERBOSE"
   1.536 +!define _MOZFUNC_UN
   1.537 +!define _MOZFUNC_S
   1.538 +!verbose pop
   1.539 +
   1.540 +!macro MOZFUNC_VERBOSE _VERBOSE
   1.541 +  !verbose push
   1.542 +  !verbose 3
   1.543 +  !undef _MOZFUNC_VERBOSE
   1.544 +  !define _MOZFUNC_VERBOSE ${_VERBOSE}
   1.545 +  !verbose pop
   1.546 +!macroend
   1.547 +
   1.548 +/**
   1.549 + * Displays a MessageBox and then calls abort to prevent continuing to the
   1.550 + * next page when the specified Window Class is found.
   1.551 + *
   1.552 + * @param   _WINDOW_CLASS
   1.553 + *          The Window Class to search for with FindWindow.
   1.554 + * @param   _MSG
   1.555 + *          The message text to display in the message box.
   1.556 + *
   1.557 + * $R7 = return value from FindWindow
   1.558 + * $R8 = _WINDOW_CLASS
   1.559 + * $R9 = _MSG
   1.560 + */
   1.561 +!macro ManualCloseAppPrompt
   1.562 +
   1.563 +  !ifndef ${_MOZFUNC_UN}ManualCloseAppPrompt
   1.564 +    !verbose push
   1.565 +    !verbose ${_MOZFUNC_VERBOSE}
   1.566 +    !define ${_MOZFUNC_UN}ManualCloseAppPrompt "!insertmacro ${_MOZFUNC_UN}ManualCloseAppPromptCall"
   1.567 +
   1.568 +    Function ${_MOZFUNC_UN}ManualCloseAppPrompt
   1.569 +      Exch $R9
   1.570 +      Exch 1
   1.571 +      Exch $R8
   1.572 +      Push $R7
   1.573 +
   1.574 +      FindWindow $R7 "$R8"
   1.575 +      ${If} $R7 <> 0 ; integer comparison
   1.576 +        MessageBox MB_OK|MB_ICONQUESTION "$R9"
   1.577 +        Abort
   1.578 +      ${EndIf}
   1.579 +
   1.580 +      Pop $R7
   1.581 +      Exch $R8
   1.582 +      Exch 1
   1.583 +      Exch $R9
   1.584 +    FunctionEnd
   1.585 +
   1.586 +    !verbose pop
   1.587 +  !endif
   1.588 +!macroend
   1.589 +
   1.590 +!macro ManualCloseAppPromptCall _WINDOW_CLASS _MSG
   1.591 +  !verbose push
   1.592 +  !verbose ${_MOZFUNC_VERBOSE}
   1.593 +  Push "${_WINDOW_CLASS}"
   1.594 +  Push "${_MSG}"
   1.595 +  Call ManualCloseAppPrompt
   1.596 +  !verbose pop
   1.597 +!macroend
   1.598 +
   1.599 +!macro un.ManualCloseAppPromptCall _WINDOW_CLASS _MSG
   1.600 +  !verbose push
   1.601 +  !verbose ${_MOZFUNC_VERBOSE}
   1.602 +  Push "${_WINDOW_CLASS}"
   1.603 +  Push "${_MSG}"
   1.604 +  Call un.ManualCloseAppPrompt
   1.605 +  !verbose pop
   1.606 +!macroend
   1.607 +
   1.608 +!macro un.ManualCloseAppPrompt
   1.609 +  !ifndef un.ManualCloseAppPrompt
   1.610 +    !verbose push
   1.611 +    !verbose ${_MOZFUNC_VERBOSE}
   1.612 +    !undef _MOZFUNC_UN
   1.613 +    !define _MOZFUNC_UN "un."
   1.614 +
   1.615 +    !insertmacro ManualCloseAppPrompt
   1.616 +
   1.617 +    !undef _MOZFUNC_UN
   1.618 +    !define _MOZFUNC_UN
   1.619 +    !verbose pop
   1.620 +  !endif
   1.621 +!macroend
   1.622 +
   1.623 +
   1.624 +################################################################################
   1.625 +# Macros for working with the registry
   1.626 +
   1.627 +/**
   1.628 + * Writes a registry string using SHCTX and the supplied params and logs the
   1.629 + * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
   1.630 + *
   1.631 + * Define NO_LOG to prevent all logging when calling this from the uninstaller.
   1.632 + *
   1.633 + * @param   _ROOT
   1.634 + *          The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
   1.635 + *          This will only be used for logging.
   1.636 + * @param   _KEY
   1.637 + *          The subkey in relation to the key root.
   1.638 + * @param   _NAME
   1.639 + *          The key value name to write to.
   1.640 + * @param   _STR
   1.641 + *          The string to write to the key value name.
   1.642 + * @param   _LOG_UNINSTALL
   1.643 + *          0 = don't add to uninstall log, 1 = add to uninstall log.
   1.644 + *
   1.645 + * $R5 = _ROOT
   1.646 + * $R6 = _KEY
   1.647 + * $R7 = _NAME
   1.648 + * $R8 = _STR
   1.649 + * $R9 = _LOG_UNINSTALL
   1.650 + */
   1.651 +!macro WriteRegStr2
   1.652 +
   1.653 +  !ifndef ${_MOZFUNC_UN}WriteRegStr2
   1.654 +    !verbose push
   1.655 +    !verbose ${_MOZFUNC_VERBOSE}
   1.656 +    !define ${_MOZFUNC_UN}WriteRegStr2 "!insertmacro ${_MOZFUNC_UN}WriteRegStr2Call"
   1.657 +
   1.658 +    Function ${_MOZFUNC_UN}WriteRegStr2
   1.659 +      Exch $R9
   1.660 +      Exch 1
   1.661 +      Exch $R8
   1.662 +      Exch 2
   1.663 +      Exch $R7
   1.664 +      Exch 3
   1.665 +      Exch $R6
   1.666 +      Exch 4
   1.667 +      Exch $R5
   1.668 +
   1.669 +      ClearErrors
   1.670 +      WriteRegStr SHCTX "$R6" "$R7" "$R8"
   1.671 +
   1.672 +      !ifndef NO_LOG
   1.673 +        ${If} ${Errors}
   1.674 +          ${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **"
   1.675 +        ${Else}
   1.676 +          ${If} $R9 == 1 ; add to the uninstall log?
   1.677 +            ${LogUninstall} "RegVal: $R5 | $R6 | $R7"
   1.678 +          ${EndIf}
   1.679 +          ${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8"
   1.680 +        ${EndIf}
   1.681 +      !endif
   1.682 +
   1.683 +      Exch $R5
   1.684 +      Exch 4
   1.685 +      Exch $R6
   1.686 +      Exch 3
   1.687 +      Exch $R7
   1.688 +      Exch 2
   1.689 +      Exch $R8
   1.690 +      Exch 1
   1.691 +      Exch $R9
   1.692 +    FunctionEnd
   1.693 +
   1.694 +    !verbose pop
   1.695 +  !endif
   1.696 +!macroend
   1.697 +
   1.698 +!macro WriteRegStr2Call _ROOT _KEY _NAME _STR _LOG_UNINSTALL
   1.699 +  !verbose push
   1.700 +  !verbose ${_MOZFUNC_VERBOSE}
   1.701 +  Push "${_ROOT}"
   1.702 +  Push "${_KEY}"
   1.703 +  Push "${_NAME}"
   1.704 +  Push "${_STR}"
   1.705 +  Push "${_LOG_UNINSTALL}"
   1.706 +  Call WriteRegStr2
   1.707 +  !verbose pop
   1.708 +!macroend
   1.709 +
   1.710 +!macro un.WriteRegStr2Call _ROOT _KEY _NAME _STR _LOG_UNINSTALL
   1.711 +  !verbose push
   1.712 +  !verbose ${_MOZFUNC_VERBOSE}
   1.713 +  Push "${_ROOT}"
   1.714 +  Push "${_KEY}"
   1.715 +  Push "${_NAME}"
   1.716 +  Push "${_STR}"
   1.717 +  Push "${_LOG_UNINSTALL}"
   1.718 +  Call un.WriteRegStr2
   1.719 +  !verbose pop
   1.720 +!macroend
   1.721 +
   1.722 +!macro un.WriteRegStr2
   1.723 +  !ifndef un.WriteRegStr2
   1.724 +    !verbose push
   1.725 +    !verbose ${_MOZFUNC_VERBOSE}
   1.726 +    !undef _MOZFUNC_UN
   1.727 +    !define _MOZFUNC_UN "un."
   1.728 +
   1.729 +    !insertmacro WriteRegStr2
   1.730 +
   1.731 +    !undef _MOZFUNC_UN
   1.732 +    !define _MOZFUNC_UN
   1.733 +    !verbose pop
   1.734 +  !endif
   1.735 +!macroend
   1.736 +
   1.737 +/**
   1.738 + * Writes a registry dword using SHCTX and the supplied params and logs the
   1.739 + * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
   1.740 + *
   1.741 + * Define NO_LOG to prevent all logging when calling this from the uninstaller.
   1.742 + *
   1.743 + * @param   _ROOT
   1.744 + *          The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
   1.745 + *          This will only be used for logging.
   1.746 + * @param   _KEY
   1.747 + *          The subkey in relation to the key root.
   1.748 + * @param   _NAME
   1.749 + *          The key value name to write to.
   1.750 + * @param   _DWORD
   1.751 + *          The dword to write to the key value name.
   1.752 + * @param   _LOG_UNINSTALL
   1.753 + *          0 = don't add to uninstall log, 1 = add to uninstall log.
   1.754 + *
   1.755 + * $R5 = _ROOT
   1.756 + * $R6 = _KEY
   1.757 + * $R7 = _NAME
   1.758 + * $R8 = _DWORD
   1.759 + * $R9 = _LOG_UNINSTALL
   1.760 + */
   1.761 +!macro WriteRegDWORD2
   1.762 +
   1.763 +  !ifndef ${_MOZFUNC_UN}WriteRegDWORD2
   1.764 +    !verbose push
   1.765 +    !verbose ${_MOZFUNC_VERBOSE}
   1.766 +    !define ${_MOZFUNC_UN}WriteRegDWORD2 "!insertmacro ${_MOZFUNC_UN}WriteRegDWORD2Call"
   1.767 +
   1.768 +    Function ${_MOZFUNC_UN}WriteRegDWORD2
   1.769 +      Exch $R9
   1.770 +      Exch 1
   1.771 +      Exch $R8
   1.772 +      Exch 2
   1.773 +      Exch $R7
   1.774 +      Exch 3
   1.775 +      Exch $R6
   1.776 +      Exch 4
   1.777 +      Exch $R5
   1.778 +
   1.779 +      ClearErrors
   1.780 +      WriteRegDWORD SHCTX "$R6" "$R7" "$R8"
   1.781 +
   1.782 +      !ifndef NO_LOG
   1.783 +        ${If} ${Errors}
   1.784 +          ${LogMsg} "** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **"
   1.785 +        ${Else}
   1.786 +          ${If} $R9 == 1 ; add to the uninstall log?
   1.787 +            ${LogUninstall} "RegVal: $R5 | $R6 | $R7"
   1.788 +          ${EndIf}
   1.789 +          ${LogMsg} "Added Registry DWord: $R5 | $R6 | $R7 | $R8"
   1.790 +        ${EndIf}
   1.791 +      !endif
   1.792 +
   1.793 +      Exch $R5
   1.794 +      Exch 4
   1.795 +      Exch $R6
   1.796 +      Exch 3
   1.797 +      Exch $R7
   1.798 +      Exch 2
   1.799 +      Exch $R8
   1.800 +      Exch 1
   1.801 +      Exch $R9
   1.802 +    FunctionEnd
   1.803 +
   1.804 +    !verbose pop
   1.805 +  !endif
   1.806 +!macroend
   1.807 +
   1.808 +!macro WriteRegDWORD2Call _ROOT _KEY _NAME _DWORD _LOG_UNINSTALL
   1.809 +  !verbose push
   1.810 +  !verbose ${_MOZFUNC_VERBOSE}
   1.811 +  Push "${_ROOT}"
   1.812 +  Push "${_KEY}"
   1.813 +  Push "${_NAME}"
   1.814 +  Push "${_DWORD}"
   1.815 +  Push "${_LOG_UNINSTALL}"
   1.816 +  Call WriteRegDWORD2
   1.817 +  !verbose pop
   1.818 +!macroend
   1.819 +
   1.820 +!macro un.WriteRegDWORD2Call _ROOT _KEY _NAME _DWORD _LOG_UNINSTALL
   1.821 +  !verbose push
   1.822 +  !verbose ${_MOZFUNC_VERBOSE}
   1.823 +  Push "${_ROOT}"
   1.824 +  Push "${_KEY}"
   1.825 +  Push "${_NAME}"
   1.826 +  Push "${_DWORD}"
   1.827 +  Push "${_LOG_UNINSTALL}"
   1.828 +  Call un.WriteRegDWORD2
   1.829 +  !verbose pop
   1.830 +!macroend
   1.831 +
   1.832 +!macro un.WriteRegDWORD2
   1.833 +  !ifndef un.WriteRegDWORD2
   1.834 +    !verbose push
   1.835 +    !verbose ${_MOZFUNC_VERBOSE}
   1.836 +    !undef _MOZFUNC_UN
   1.837 +    !define _MOZFUNC_UN "un."
   1.838 +
   1.839 +    !insertmacro WriteRegDWORD2
   1.840 +
   1.841 +    !undef _MOZFUNC_UN
   1.842 +    !define _MOZFUNC_UN
   1.843 +    !verbose pop
   1.844 +  !endif
   1.845 +!macroend
   1.846 +
   1.847 +/**
   1.848 + * Writes a registry string to HKCR using the supplied params and logs the
   1.849 + * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
   1.850 + *
   1.851 + * Define NO_LOG to prevent all logging when calling this from the uninstaller.
   1.852 + *
   1.853 + * @param   _ROOT
   1.854 + *          The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
   1.855 + *          This will only be used for logging.
   1.856 + * @param   _KEY
   1.857 + *          The subkey in relation to the key root.
   1.858 + * @param   _NAME
   1.859 + *          The key value name to write to.
   1.860 + * @param   _STR
   1.861 + *          The string to write to the key value name.
   1.862 + * @param   _LOG_UNINSTALL
   1.863 + *          0 = don't add to uninstall log, 1 = add to uninstall log.
   1.864 + *
   1.865 + * $R5 = _ROOT
   1.866 + * $R6 = _KEY
   1.867 + * $R7 = _NAME
   1.868 + * $R8 = _STR
   1.869 + * $R9 = _LOG_UNINSTALL
   1.870 + */
   1.871 +!macro WriteRegStrHKCR
   1.872 +
   1.873 +  !ifndef ${_MOZFUNC_UN}WriteRegStrHKCR
   1.874 +    !verbose push
   1.875 +    !verbose ${_MOZFUNC_VERBOSE}
   1.876 +    !define ${_MOZFUNC_UN}WriteRegStrHKCR "!insertmacro ${_MOZFUNC_UN}WriteRegStrHKCRCall"
   1.877 +
   1.878 +    Function ${_MOZFUNC_UN}WriteRegStrHKCR
   1.879 +      Exch $R9
   1.880 +      Exch 1
   1.881 +      Exch $R8
   1.882 +      Exch 2
   1.883 +      Exch $R7
   1.884 +      Exch 3
   1.885 +      Exch $R6
   1.886 +      Exch 4
   1.887 +      Exch $R5
   1.888 +
   1.889 +      ClearErrors
   1.890 +      WriteRegStr HKCR "$R6" "$R7" "$R8"
   1.891 +
   1.892 +      !ifndef NO_LOG
   1.893 +        ${If} ${Errors}
   1.894 +          ${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **"
   1.895 +        ${Else}
   1.896 +          ${If} $R9 == 1 ; add to the uninstall log?
   1.897 +            ${LogUninstall} "RegVal: $R5 | $R6 | $R7"
   1.898 +          ${EndIf}
   1.899 +          ${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8"
   1.900 +        ${EndIf}
   1.901 +      !endif
   1.902 +
   1.903 +      Exch $R5
   1.904 +      Exch 4
   1.905 +      Exch $R6
   1.906 +      Exch 3
   1.907 +      Exch $R7
   1.908 +      Exch 2
   1.909 +      Exch $R8
   1.910 +      Exch 1
   1.911 +      Exch $R9
   1.912 +    FunctionEnd
   1.913 +
   1.914 +    !verbose pop
   1.915 +  !endif
   1.916 +!macroend
   1.917 +
   1.918 +!macro WriteRegStrHKCRCall _ROOT _KEY _NAME _STR _LOG_UNINSTALL
   1.919 +  !verbose push
   1.920 +  !verbose ${_MOZFUNC_VERBOSE}
   1.921 +  Push "${_ROOT}"
   1.922 +  Push "${_KEY}"
   1.923 +  Push "${_NAME}"
   1.924 +  Push "${_STR}"
   1.925 +  Push "${_LOG_UNINSTALL}"
   1.926 +  Call WriteRegStrHKCR
   1.927 +  !verbose pop
   1.928 +!macroend
   1.929 +
   1.930 +!macro un.WriteRegStrHKCRCall _ROOT _KEY _NAME _STR _LOG_UNINSTALL
   1.931 +  !verbose push
   1.932 +  !verbose ${_MOZFUNC_VERBOSE}
   1.933 +  Push "${_ROOT}"
   1.934 +  Push "${_KEY}"
   1.935 +  Push "${_NAME}"
   1.936 +  Push "${_STR}"
   1.937 +  Push "${_LOG_UNINSTALL}"
   1.938 +  Call un.WriteRegStrHKCR
   1.939 +  !verbose pop
   1.940 +!macroend
   1.941 +
   1.942 +!macro un.WriteRegStrHKCR
   1.943 +  !ifndef un.WriteRegStrHKCR
   1.944 +    !verbose push
   1.945 +    !verbose ${_MOZFUNC_VERBOSE}
   1.946 +    !undef _MOZFUNC_UN
   1.947 +    !define _MOZFUNC_UN "un."
   1.948 +
   1.949 +    !insertmacro WriteRegStrHKCR
   1.950 +
   1.951 +    !undef _MOZFUNC_UN
   1.952 +    !define _MOZFUNC_UN
   1.953 +    !verbose pop
   1.954 +  !endif
   1.955 +!macroend
   1.956 +
   1.957 +!ifndef KEY_SET_VALUE
   1.958 +  !define KEY_SET_VALUE 0x0002
   1.959 +!endif
   1.960 +!ifndef KEY_WOW64_64KEY
   1.961 +  !define KEY_WOW64_64KEY 0x0100
   1.962 +!endif
   1.963 +!ifndef HAVE_64BIT_OS
   1.964 +  !define CREATE_KEY_SAM ${KEY_SET_VALUE}
   1.965 +!else
   1.966 +  !define CREATE_KEY_SAM ${KEY_SET_VALUE}|${KEY_WOW64_64KEY}
   1.967 +!endif
   1.968 +
   1.969 +/**
   1.970 + * Creates a registry key. This will log the actions to the install and
   1.971 + * uninstall logs. Alternatively you can set a registry value to create the key
   1.972 + * and then delete the value.
   1.973 + *
   1.974 + * Define NO_LOG to prevent all logging when calling this from the uninstaller.
   1.975 + *
   1.976 + * @param   _ROOT
   1.977 + *          The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
   1.978 + * @param   _KEY
   1.979 + *          The subkey in relation to the key root.
   1.980 + * @param   _LOG_UNINSTALL
   1.981 + *          0 = don't add to uninstall log, 1 = add to uninstall log.
   1.982 + *
   1.983 + * $R4 = [out] handle to newly created registry key. If this is not a key
   1.984 + *       located in one of the predefined registry keys this must be closed
   1.985 + *       with RegCloseKey (this should not be needed unless someone decides to
   1.986 + *       do something extremely squirrelly with NSIS).
   1.987 + * $R5 = return value from RegCreateKeyExW (represented by R5 in the system call).
   1.988 + * $R6 = [in] hKey passed to RegCreateKeyExW.
   1.989 + * $R7 = _ROOT
   1.990 + * $R8 = _KEY
   1.991 + * $R9 = _LOG_UNINSTALL
   1.992 + */
   1.993 +!macro CreateRegKey
   1.994 +
   1.995 +  !ifndef ${_MOZFUNC_UN}CreateRegKey
   1.996 +    !verbose push
   1.997 +    !verbose ${_MOZFUNC_VERBOSE}
   1.998 +    !define ${_MOZFUNC_UN}CreateRegKey "!insertmacro ${_MOZFUNC_UN}CreateRegKeyCall"
   1.999 +
  1.1000 +    Function ${_MOZFUNC_UN}CreateRegKey
  1.1001 +      Exch $R9
  1.1002 +      Exch 1
  1.1003 +      Exch $R8
  1.1004 +      Exch 2
  1.1005 +      Exch $R7
  1.1006 +      Push $R6
  1.1007 +      Push $R5
  1.1008 +      Push $R4
  1.1009 +
  1.1010 +      StrCmp $R7 "HKCR" +1 +2
  1.1011 +      StrCpy $R6 "0x80000000"
  1.1012 +      StrCmp $R7 "HKCU" +1 +2
  1.1013 +      StrCpy $R6 "0x80000001"
  1.1014 +      StrCmp $R7 "HKLM" +1 +2
  1.1015 +      StrCpy $R6 "0x80000002"
  1.1016 +
  1.1017 +      ; see definition of RegCreateKey
  1.1018 +      System::Call "Advapi32::RegCreateKeyExW(i R6, w R8, i 0, i 0, i 0,\
  1.1019 +                                              i ${CREATE_KEY_SAM}, i 0, *i .R4,\
  1.1020 +                                              i 0) i .R5"
  1.1021 +
  1.1022 +      !ifndef NO_LOG
  1.1023 +        ; if $R5 is not 0 then there was an error creating the registry key.
  1.1024 +        ${If} $R5 <> 0
  1.1025 +          ${LogMsg} "** ERROR Adding Registry Key: $R7 | $R8 **"
  1.1026 +        ${Else}
  1.1027 +          ${If} $R9 == 1 ; add to the uninstall log?
  1.1028 +            ${LogUninstall} "RegKey: $R7 | $R8"
  1.1029 +          ${EndIf}
  1.1030 +          ${LogMsg} "Added Registry Key: $R7 | $R8"
  1.1031 +        ${EndIf}
  1.1032 +      !endif
  1.1033 +
  1.1034 +      StrCmp $R5 0 +1 +2
  1.1035 +      System::Call "Advapi32::RegCloseKey(iR4)"
  1.1036 +
  1.1037 +      Pop $R4
  1.1038 +      Pop $R5
  1.1039 +      Pop $R6
  1.1040 +      Exch $R7
  1.1041 +      Exch 2
  1.1042 +      Exch $R8
  1.1043 +      Exch 1
  1.1044 +      Exch $R9
  1.1045 +    FunctionEnd
  1.1046 +
  1.1047 +    !verbose pop
  1.1048 +  !endif
  1.1049 +!macroend
  1.1050 +
  1.1051 +!macro CreateRegKeyCall _ROOT _KEY _LOG_UNINSTALL
  1.1052 +  !verbose push
  1.1053 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1054 +  Push "${_ROOT}"
  1.1055 +  Push "${_KEY}"
  1.1056 +  Push "${_LOG_UNINSTALL}"
  1.1057 +  Call CreateRegKey
  1.1058 +  !verbose pop
  1.1059 +!macroend
  1.1060 +
  1.1061 +!macro un.CreateRegKeyCall _ROOT _KEY _LOG_UNINSTALL
  1.1062 +  !verbose push
  1.1063 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1064 +  Push "${_ROOT}"
  1.1065 +  Push "${_KEY}"
  1.1066 +  Push "${_LOG_UNINSTALL}"
  1.1067 +  Call un.CreateRegKey
  1.1068 +  !verbose pop
  1.1069 +!macroend
  1.1070 +
  1.1071 +!macro un.CreateRegKey
  1.1072 +  !ifndef un.CreateRegKey
  1.1073 +    !verbose push
  1.1074 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1075 +    !undef _MOZFUNC_UN
  1.1076 +    !define _MOZFUNC_UN "un."
  1.1077 +
  1.1078 +    !insertmacro CreateRegKey
  1.1079 +
  1.1080 +    !undef _MOZFUNC_UN
  1.1081 +    !define _MOZFUNC_UN
  1.1082 +    !verbose pop
  1.1083 +  !endif
  1.1084 +!macroend
  1.1085 +
  1.1086 +/**
  1.1087 + * Helper for checking for the existence of a registry key.
  1.1088 + * SHCTX is the root key to search.
  1.1089 + *
  1.1090 + * @param   _MAIN_KEY
  1.1091 + *          Sub key to iterate for the key in question
  1.1092 + * @param   _KEY
  1.1093 + *          Key name to search for
  1.1094 + * @return  _RESULT
  1.1095 + *          'true' / 'false' result
  1.1096 + */
  1.1097 +!macro CheckIfRegistryKeyExists
  1.1098 +  !ifndef CheckIfRegistryKeyExists
  1.1099 +    !verbose push
  1.1100 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1101 +    !define CheckIfRegistryKeyExists "!insertmacro CheckIfRegistryKeyExistsCall"
  1.1102 +
  1.1103 +    Function CheckIfRegistryKeyExists
  1.1104 +      ; stack: main key, key
  1.1105 +      Exch $R9 ; main key, stack: old R9, key
  1.1106 +      Exch 1   ; stack: key, old R9
  1.1107 +      Exch $R8 ; key, stack: old R8, old R9
  1.1108 +      Push $R7
  1.1109 +      Push $R6
  1.1110 +      Push $R5
  1.1111 +
  1.1112 +      StrCpy $R5 "false"
  1.1113 +      StrCpy $R7 "0" # loop index
  1.1114 +      ${Do}
  1.1115 +        EnumRegKey $R6 SHCTX "$R9" "$R7"
  1.1116 +        ${If} "$R6" == "$R8"
  1.1117 +          StrCpy $R5 "true"
  1.1118 +          ${Break}
  1.1119 +        ${EndIf}
  1.1120 +        IntOp $R7 $R7 + 1
  1.1121 +      ${LoopWhile} $R6 != ""
  1.1122 +      ClearErrors
  1.1123 +
  1.1124 +      StrCpy $R9 $R5
  1.1125 +
  1.1126 +      Pop $R5
  1.1127 +      Pop $R6
  1.1128 +      Pop $R7 ; stack: old R8, old R9
  1.1129 +      Pop $R8 ; stack: old R9
  1.1130 +      Exch $R9 ; stack: result
  1.1131 +    FunctionEnd
  1.1132 +
  1.1133 +    !verbose pop
  1.1134 +  !endif
  1.1135 +!macroend
  1.1136 +
  1.1137 +!macro CheckIfRegistryKeyExistsCall _MAIN_KEY _KEY _RESULT
  1.1138 +  !verbose push
  1.1139 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1140 +  Push "${_KEY}"
  1.1141 +  Push "${_MAIN_KEY}"
  1.1142 +  Call CheckIfRegistryKeyExists
  1.1143 +  Pop ${_RESULT}
  1.1144 +  !verbose pop
  1.1145 +!macroend
  1.1146 +
  1.1147 +################################################################################
  1.1148 +# Macros for adding file and protocol handlers
  1.1149 +
  1.1150 +/**
  1.1151 + * Writes common registry values for a handler using SHCTX.
  1.1152 + *
  1.1153 + * @param   _KEY
  1.1154 + *          The subkey in relation to the key root.
  1.1155 + * @param   _VALOPEN
  1.1156 + *          The path and args to launch the application.
  1.1157 + * @param   _VALICON
  1.1158 + *          The path to the binary that contains the icon group for the default icon
  1.1159 + *          followed by a comma and either the icon group's resource index or the icon
  1.1160 + *          group's resource id prefixed with a minus sign
  1.1161 + * @param   _DISPNAME
  1.1162 + *          The display name for the handler. If emtpy no value will be set.
  1.1163 + * @param   _ISPROTOCOL
  1.1164 + *          Sets protocol handler specific registry values when "true".
  1.1165 + *          Deletes protocol handler specific registry values when "delete".
  1.1166 + *          Otherwise doesn't touch handler specific registry values.
  1.1167 + * @param   _ISDDE
  1.1168 + *          Sets DDE specific registry values when "true".
  1.1169 + *
  1.1170 + * $R3 = string value of the current registry key path.
  1.1171 + * $R4 = _KEY
  1.1172 + * $R5 = _VALOPEN
  1.1173 + * $R6 = _VALICON
  1.1174 + * $R7 = _DISPNAME
  1.1175 + * $R8 = _ISPROTOCOL
  1.1176 + * $R9 = _ISDDE
  1.1177 + */
  1.1178 +!macro AddHandlerValues
  1.1179 +
  1.1180 +  !ifndef ${_MOZFUNC_UN}AddHandlerValues
  1.1181 +    !verbose push
  1.1182 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1183 +    !define ${_MOZFUNC_UN}AddHandlerValues "!insertmacro ${_MOZFUNC_UN}AddHandlerValuesCall"
  1.1184 +
  1.1185 +    Function ${_MOZFUNC_UN}AddHandlerValues
  1.1186 +      Exch $R9
  1.1187 +      Exch 1
  1.1188 +      Exch $R8
  1.1189 +      Exch 2
  1.1190 +      Exch $R7
  1.1191 +      Exch 3
  1.1192 +      Exch $R6
  1.1193 +      Exch 4
  1.1194 +      Exch $R5
  1.1195 +      Exch 5
  1.1196 +      Exch $R4
  1.1197 +      Push $R3
  1.1198 +
  1.1199 +      StrCmp "$R7" "" +6 +1
  1.1200 +      ReadRegStr $R3 SHCTX "$R4" "FriendlyTypeName"
  1.1201 +
  1.1202 +      StrCmp "$R3" "" +1 +3
  1.1203 +      WriteRegStr SHCTX "$R4" "" "$R7"
  1.1204 +      WriteRegStr SHCTX "$R4" "FriendlyTypeName" "$R7"
  1.1205 +
  1.1206 +      StrCmp "$R8" "true" +1 +2
  1.1207 +      WriteRegStr SHCTX "$R4" "URL Protocol" ""
  1.1208 +      StrCmp "$R8" "delete" +1 +2
  1.1209 +      DeleteRegValue SHCTX "$R4" "URL Protocol"
  1.1210 +      StrCpy $R3 ""
  1.1211 +      ReadRegDWord $R3 SHCTX "$R4" "EditFlags"
  1.1212 +      StrCmp $R3 "" +1 +3  ; Only add EditFlags if a value doesn't exist
  1.1213 +      DeleteRegValue SHCTX "$R4" "EditFlags"
  1.1214 +      WriteRegDWord SHCTX "$R4" "EditFlags" 0x00000002
  1.1215 +
  1.1216 +      StrCmp "$R6" "" +2 +1
  1.1217 +      WriteRegStr SHCTX "$R4\DefaultIcon" "" "$R6"
  1.1218 +
  1.1219 +      StrCmp "$R5" "" +2 +1
  1.1220 +      WriteRegStr SHCTX "$R4\shell\open\command" "" "$R5"
  1.1221 +
  1.1222 +!ifdef DDEApplication
  1.1223 +      StrCmp "$R9" "true" +1 +11
  1.1224 +      WriteRegStr SHCTX "$R4\shell\open\ddeexec" "" "$\"%1$\",,0,0,,,,"
  1.1225 +      WriteRegStr SHCTX "$R4\shell\open\ddeexec" "NoActivateHandler" ""
  1.1226 +      WriteRegStr SHCTX "$R4\shell\open\ddeexec\Application" "" "${DDEApplication}"
  1.1227 +      WriteRegStr SHCTX "$R4\shell\open\ddeexec\Topic" "" "WWW_OpenURL"
  1.1228 +      ; The ifexec key may have been added by another application so try to
  1.1229 +      ; delete it to prevent it from breaking this app's shell integration.
  1.1230 +      ; Also, IE 6 and below doesn't remove this key when it sets itself as the
  1.1231 +      ; default handler and if this key exists IE's shell integration breaks.
  1.1232 +      DeleteRegKey HKLM "$R4\shell\open\ddeexec\ifexec"
  1.1233 +      DeleteRegKey HKCU "$R4\shell\open\ddeexec\ifexec"
  1.1234 +!endif
  1.1235 +
  1.1236 +      ClearErrors
  1.1237 +
  1.1238 +      Pop $R3
  1.1239 +      Exch $R4
  1.1240 +      Exch 5
  1.1241 +      Exch $R5
  1.1242 +      Exch 4
  1.1243 +      Exch $R6
  1.1244 +      Exch 3
  1.1245 +      Exch $R7
  1.1246 +      Exch 2
  1.1247 +      Exch $R8
  1.1248 +      Exch 1
  1.1249 +      Exch $R9
  1.1250 +    FunctionEnd
  1.1251 +
  1.1252 +    !verbose pop
  1.1253 +  !endif
  1.1254 +!macroend
  1.1255 +
  1.1256 +!macro AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE
  1.1257 +  !verbose push
  1.1258 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1259 +  Push "${_KEY}"
  1.1260 +  Push "${_VALOPEN}"
  1.1261 +  Push "${_VALICON}"
  1.1262 +  Push "${_DISPNAME}"
  1.1263 +  Push "${_ISPROTOCOL}"
  1.1264 +  Push "${_ISDDE}"
  1.1265 +  Call AddHandlerValues
  1.1266 +  !verbose pop
  1.1267 +!macroend
  1.1268 +
  1.1269 +!macro un.AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE
  1.1270 +  !verbose push
  1.1271 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1272 +  Push "${_KEY}"
  1.1273 +  Push "${_VALOPEN}"
  1.1274 +  Push "${_VALICON}"
  1.1275 +  Push "${_DISPNAME}"
  1.1276 +  Push "${_ISPROTOCOL}"
  1.1277 +  Push "${_ISDDE}"
  1.1278 +  Call un.AddHandlerValues
  1.1279 +  !verbose pop
  1.1280 +!macroend
  1.1281 +
  1.1282 +!macro un.AddHandlerValues
  1.1283 +  !ifndef un.AddHandlerValues
  1.1284 +    !verbose push
  1.1285 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1286 +    !undef _MOZFUNC_UN
  1.1287 +    !define _MOZFUNC_UN "un."
  1.1288 +
  1.1289 +    !insertmacro AddHandlerValues
  1.1290 +
  1.1291 +    !undef _MOZFUNC_UN
  1.1292 +    !define _MOZFUNC_UN
  1.1293 +    !verbose pop
  1.1294 +  !endif
  1.1295 +!macroend
  1.1296 +
  1.1297 +/**
  1.1298 + * Writes common registry values for a handler that uses DDE using SHCTX.
  1.1299 + *
  1.1300 + * @param   _KEY
  1.1301 + *          The key name in relation to the HKCR root. SOFTWARE\Classes is
  1.1302 + *          prefixed to this value when using SHCTX.
  1.1303 + * @param   _VALOPEN
  1.1304 + *          The path and args to launch the application.
  1.1305 + * @param   _VALICON
  1.1306 + *          The path to the binary that contains the icon group for the default icon
  1.1307 + *          followed by a comma and either the icon group's resource index or the icon
  1.1308 + *          group's resource id prefixed with a minus sign
  1.1309 + * @param   _DISPNAME
  1.1310 + *          The display name for the handler. If emtpy no value will be set.
  1.1311 + * @param   _ISPROTOCOL
  1.1312 + *          Sets protocol handler specific registry values when "true".
  1.1313 + *          Deletes protocol handler specific registry values when "delete".
  1.1314 + *          Otherwise doesn't touch handler specific registry values.
  1.1315 + * @param   _DDE_APPNAME
  1.1316 + *          Sets DDE specific registry values when not an empty string.
  1.1317 + *
  1.1318 + * $R0 = storage for SOFTWARE\Classes
  1.1319 + * $R1 = string value of the current registry key path.
  1.1320 + * $R2 = _KEY
  1.1321 + * $R3 = _VALOPEN
  1.1322 + * $R4 = _VALICON
  1.1323 + * $R5 = _DISPNAME
  1.1324 + * $R6 = _ISPROTOCOL
  1.1325 + * $R7 = _DDE_APPNAME
  1.1326 + * $R8 = _DDE_DEFAULT
  1.1327 + * $R9 = _DDE_TOPIC
  1.1328 + */
  1.1329 +!macro AddDDEHandlerValues
  1.1330 +
  1.1331 +  !ifndef ${_MOZFUNC_UN}AddDDEHandlerValues
  1.1332 +    !verbose push
  1.1333 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1334 +    !define ${_MOZFUNC_UN}AddDDEHandlerValues "!insertmacro ${_MOZFUNC_UN}AddDDEHandlerValuesCall"
  1.1335 +
  1.1336 +    Function ${_MOZFUNC_UN}AddDDEHandlerValues
  1.1337 +      Exch $R9
  1.1338 +      Exch 1
  1.1339 +      Exch $R8
  1.1340 +      Exch 2
  1.1341 +      Exch $R7
  1.1342 +      Exch 3
  1.1343 +      Exch $R6
  1.1344 +      Exch 4
  1.1345 +      Exch $R5
  1.1346 +      Exch 5
  1.1347 +      Exch $R4
  1.1348 +      Exch 6
  1.1349 +      Exch $R3
  1.1350 +      Exch 7
  1.1351 +      Exch $R2
  1.1352 +      Push $R1
  1.1353 +      Push $R0
  1.1354 +
  1.1355 +      StrCpy $R0 "SOFTWARE\Classes"
  1.1356 +      StrCmp "$R5" "" +6 +1
  1.1357 +      ReadRegStr $R1 SHCTX "$R2" "FriendlyTypeName"
  1.1358 +
  1.1359 +      StrCmp "$R1" "" +1 +3
  1.1360 +      WriteRegStr SHCTX "$R0\$R2" "" "$R5"
  1.1361 +      WriteRegStr SHCTX "$R0\$R2" "FriendlyTypeName" "$R5"
  1.1362 +
  1.1363 +      StrCmp "$R6" "true" +1 +2
  1.1364 +      WriteRegStr SHCTX "$R0\$R2" "URL Protocol" ""
  1.1365 +      StrCmp "$R6" "delete" +1 +2
  1.1366 +      DeleteRegValue SHCTX "$R0\$R2" "URL Protocol"
  1.1367 +      StrCpy $R1 ""
  1.1368 +      ReadRegDWord $R1 SHCTX "$R0\$R2" "EditFlags"
  1.1369 +      StrCmp $R1 "" +1 +3  ; Only add EditFlags if a value doesn't exist
  1.1370 +      DeleteRegValue SHCTX "$R0\$R2" "EditFlags"
  1.1371 +      WriteRegDWord SHCTX "$R0\$R2" "EditFlags" 0x00000002
  1.1372 +
  1.1373 +      StrCmp "$R4" "" +2 +1
  1.1374 +      WriteRegStr SHCTX "$R0\$R2\DefaultIcon" "" "$R4"
  1.1375 +
  1.1376 +      WriteRegStr SHCTX "$R0\$R2\shell" "" "open"
  1.1377 +      WriteRegStr SHCTX "$R0\$R2\shell\open\command" "" "$R3"
  1.1378 +
  1.1379 +      WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec" "" "$R8"
  1.1380 +      WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec" "NoActivateHandler" ""
  1.1381 +      WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec\Application" "" "$R7"
  1.1382 +      WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec\Topic" "" "$R9"
  1.1383 +
  1.1384 +      ; The ifexec key may have been added by another application so try to
  1.1385 +      ; delete it to prevent it from breaking this app's shell integration.
  1.1386 +      ; Also, IE 6 and below doesn't remove this key when it sets itself as the
  1.1387 +      ; default handler and if this key exists IE's shell integration breaks.
  1.1388 +      DeleteRegKey HKLM "$R0\$R2\shell\open\ddeexec\ifexec"
  1.1389 +      DeleteRegKey HKCU "$R0\$R2\shell\open\ddeexec\ifexec"
  1.1390 +      ClearErrors
  1.1391 +
  1.1392 +      Pop $R0
  1.1393 +      Pop $R1
  1.1394 +      Exch $R2
  1.1395 +      Exch 7
  1.1396 +      Exch $R3
  1.1397 +      Exch 6
  1.1398 +      Exch $R4
  1.1399 +      Exch 5
  1.1400 +      Exch $R5
  1.1401 +      Exch 4
  1.1402 +      Exch $R6
  1.1403 +      Exch 3
  1.1404 +      Exch $R7
  1.1405 +      Exch 2
  1.1406 +      Exch $R8
  1.1407 +      Exch 1
  1.1408 +      Exch $R9
  1.1409 +    FunctionEnd
  1.1410 +
  1.1411 +    !verbose pop
  1.1412 +  !endif
  1.1413 +!macroend
  1.1414 +
  1.1415 +!macro AddDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _DDE_APPNAME _DDE_DEFAULT _DDE_TOPIC
  1.1416 +  !verbose push
  1.1417 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1418 +  Push "${_KEY}"
  1.1419 +  Push "${_VALOPEN}"
  1.1420 +  Push "${_VALICON}"
  1.1421 +  Push "${_DISPNAME}"
  1.1422 +  Push "${_ISPROTOCOL}"
  1.1423 +  Push "${_DDE_APPNAME}"
  1.1424 +  Push "${_DDE_DEFAULT}"
  1.1425 +  Push "${_DDE_TOPIC}"
  1.1426 +  Call AddDDEHandlerValues
  1.1427 +  !verbose pop
  1.1428 +!macroend
  1.1429 +
  1.1430 +!macro un.AddDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _DDE_APPNAME _DDE_DEFAULT _DDE_TOPIC
  1.1431 +  !verbose push
  1.1432 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1433 +  Push "${_KEY}"
  1.1434 +  Push "${_VALOPEN}"
  1.1435 +  Push "${_VALICON}"
  1.1436 +  Push "${_DISPNAME}"
  1.1437 +  Push "${_ISPROTOCOL}"
  1.1438 +  Push "${_DDE_APPNAME}"
  1.1439 +  Push "${_DDE_DEFAULT}"
  1.1440 +  Push "${_DDE_TOPIC}"
  1.1441 +  Call un.AddDDEHandlerValues
  1.1442 +  !verbose pop
  1.1443 +!macroend
  1.1444 +
  1.1445 +!macro un.AddDDEHandlerValues
  1.1446 +  !ifndef un.AddDDEHandlerValues
  1.1447 +    !verbose push
  1.1448 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1449 +    !undef _MOZFUNC_UN
  1.1450 +    !define _MOZFUNC_UN "un."
  1.1451 +
  1.1452 +    !insertmacro AddDDEHandlerValues
  1.1453 +
  1.1454 +    !undef _MOZFUNC_UN
  1.1455 +    !define _MOZFUNC_UN
  1.1456 +    !verbose pop
  1.1457 +  !endif
  1.1458 +!macroend
  1.1459 +
  1.1460 +/**
  1.1461 + * Writes common registry values for a handler that DOES NOT use DDE using SHCTX.
  1.1462 + *
  1.1463 + * @param   _KEY
  1.1464 + *          The key name in relation to the HKCR root. SOFTWARE\Classes is
  1.1465 + *          prefixed to this value when using SHCTX.
  1.1466 + * @param   _VALOPEN
  1.1467 + *          The path and args to launch the application.
  1.1468 + * @param   _VALICON
  1.1469 + *          The path to the binary that contains the icon group for the default icon
  1.1470 + *          followed by a comma and either the icon group's resource index or the icon
  1.1471 + *          group's resource id prefixed with a minus sign
  1.1472 + * @param   _DISPNAME
  1.1473 + *          The display name for the handler. If emtpy no value will be set.
  1.1474 + * @param   _ISPROTOCOL
  1.1475 + *          Sets protocol handler specific registry values when "true".
  1.1476 + *          Deletes protocol handler specific registry values when "delete".
  1.1477 + *          Otherwise doesn't touch handler specific registry values.
  1.1478 + *
  1.1479 + * $R3 = storage for SOFTWARE\Classes
  1.1480 + * $R4 = string value of the current registry key path.
  1.1481 + * $R5 = _KEY
  1.1482 + * $R6 = _VALOPEN
  1.1483 + * $R7 = _VALICON
  1.1484 + * $R8 = _DISPNAME
  1.1485 + * $R9 = _ISPROTOCOL
  1.1486 + */
  1.1487 +!macro AddDisabledDDEHandlerValues
  1.1488 +
  1.1489 +  !ifndef ${_MOZFUNC_UN}AddDisabledDDEHandlerValues
  1.1490 +    !verbose push
  1.1491 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1492 +    !define ${_MOZFUNC_UN}AddDisabledDDEHandlerValues "!insertmacro ${_MOZFUNC_UN}AddDisabledDDEHandlerValuesCall"
  1.1493 +
  1.1494 +    Function ${_MOZFUNC_UN}AddDisabledDDEHandlerValues
  1.1495 +      Exch $R9 ; _ISPROTOCOL
  1.1496 +      Exch 1
  1.1497 +      Exch $R8 ; FriendlyTypeName
  1.1498 +      Exch 2
  1.1499 +      Exch $R7 ; icon index
  1.1500 +      Exch 3
  1.1501 +      Exch $R6 ; shell\open\command
  1.1502 +      Exch 4
  1.1503 +      Exch $R5 ; reg key
  1.1504 +      Push $R4 ;
  1.1505 +      Push $R3 ; base reg class
  1.1506 +
  1.1507 +      StrCpy $R3 "SOFTWARE\Classes"
  1.1508 +      StrCmp "$R8" "" +6 +1
  1.1509 +      ReadRegStr $R4 SHCTX "$R5" "FriendlyTypeName"
  1.1510 +
  1.1511 +      StrCmp "$R4" "" +1 +3
  1.1512 +      WriteRegStr SHCTX "$R3\$R5" "" "$R8"
  1.1513 +      WriteRegStr SHCTX "$R3\$R5" "FriendlyTypeName" "$R8"
  1.1514 +
  1.1515 +      StrCmp "$R9" "true" +1 +2
  1.1516 +      WriteRegStr SHCTX "$R3\$R5" "URL Protocol" ""
  1.1517 +      StrCmp "$R9" "delete" +1 +2
  1.1518 +      DeleteRegValue SHCTX "$R3\$R5" "URL Protocol"
  1.1519 +      StrCpy $R4 ""
  1.1520 +      ReadRegDWord $R4 SHCTX "$R3\$R5" "EditFlags"
  1.1521 +      StrCmp $R4 "" +1 +3  ; Only add EditFlags if a value doesn't exist
  1.1522 +      DeleteRegValue SHCTX "$R3\$R5" "EditFlags"
  1.1523 +      WriteRegDWord SHCTX "$R3\$R5" "EditFlags" 0x00000002
  1.1524 +
  1.1525 +      StrCmp "$R7" "" +2 +1
  1.1526 +      WriteRegStr SHCTX "$R3\$R5\DefaultIcon" "" "$R7"
  1.1527 +
  1.1528 +      ; Main command handler for the app
  1.1529 +      WriteRegStr SHCTX "$R3\$R5\shell" "" "open"
  1.1530 +      WriteRegStr SHCTX "$R3\$R5\shell\open\command" "" "$R6"
  1.1531 +
  1.1532 +      ; Drop support for DDE (bug 491947), and remove old dde entries if
  1.1533 +      ; they exist.
  1.1534 +      ;
  1.1535 +      ; Note, changes in SHCTX should propegate to hkey classes root when
  1.1536 +      ; current user or local machine entries are written. Windows will also
  1.1537 +      ; attempt to propegate entries when a handler is used. CR entries are a
  1.1538 +      ; combination of LM and CU, with CU taking priority.
  1.1539 +      ;
  1.1540 +      ; To disable dde, an empty shell/ddeexec key must be created in current
  1.1541 +      ; user or local machine. Unfortunately, settings have various different
  1.1542 +      ; behaviors depending on the windows version. The following code attempts
  1.1543 +      ; to address these differences.
  1.1544 +      ;
  1.1545 +      ; On XP (no SP, SP1, SP2), Vista: An empty default string
  1.1546 +      ; must be set under ddeexec. Empty strings propagate to CR.
  1.1547 +      ;
  1.1548 +      ; Win7: IE does not configure ddeexec, so issues with left over ddeexec keys
  1.1549 +      ; in LM are reduced. We configure an empty ddeexec key with an empty default
  1.1550 +      ; string in CU to be sure.
  1.1551 +      ;
  1.1552 +      DeleteRegKey SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec"
  1.1553 +      WriteRegStr SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec" "" ""
  1.1554 +
  1.1555 +      ClearErrors
  1.1556 +
  1.1557 +      Pop $R3
  1.1558 +      Pop $R4
  1.1559 +      Exch $R5
  1.1560 +      Exch 4
  1.1561 +      Exch $R6
  1.1562 +      Exch 3
  1.1563 +      Exch $R7
  1.1564 +      Exch 2
  1.1565 +      Exch $R8
  1.1566 +      Exch 1
  1.1567 +      Exch $R9
  1.1568 +    FunctionEnd
  1.1569 +
  1.1570 +    !verbose pop
  1.1571 +  !endif
  1.1572 +!macroend
  1.1573 +
  1.1574 +!macro AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL
  1.1575 +  !verbose push
  1.1576 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1577 +  Push "${_KEY}"
  1.1578 +  Push "${_VALOPEN}"
  1.1579 +  Push "${_VALICON}"
  1.1580 +  Push "${_DISPNAME}"
  1.1581 +  Push "${_ISPROTOCOL}"
  1.1582 +  Call AddDisabledDDEHandlerValues
  1.1583 +  !verbose pop
  1.1584 +!macroend
  1.1585 +
  1.1586 +!macro un.AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL
  1.1587 +  !verbose push
  1.1588 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1589 +  Push "${_KEY}"
  1.1590 +  Push "${_VALOPEN}"
  1.1591 +  Push "${_VALICON}"
  1.1592 +  Push "${_DISPNAME}"
  1.1593 +  Push "${_ISPROTOCOL}"
  1.1594 +  Call un.AddDisabledDDEHandlerValues
  1.1595 +  !verbose pop
  1.1596 +!macroend
  1.1597 +
  1.1598 +!macro un.AddDisabledDDEHandlerValues
  1.1599 +  !ifndef un.AddDisabledDDEHandlerValues
  1.1600 +    !verbose push
  1.1601 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1602 +    !undef _MOZFUNC_UN
  1.1603 +    !define _MOZFUNC_UN "un."
  1.1604 +
  1.1605 +    !insertmacro AddDisabledDDEHandlerValues
  1.1606 +
  1.1607 +    !undef _MOZFUNC_UN
  1.1608 +    !define _MOZFUNC_UN
  1.1609 +    !verbose pop
  1.1610 +  !endif
  1.1611 +!macroend
  1.1612 +
  1.1613 +
  1.1614 +################################################################################
  1.1615 +# Macros for handling DLL registration
  1.1616 +
  1.1617 +!macro RegisterDLL DLL
  1.1618 +
  1.1619 +  ; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above
  1.1620 +  ; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it
  1.1621 +  ; when installing on an x64 systems even when installing an x86 application.
  1.1622 +  ${If} ${RunningX64}
  1.1623 +    ${DisableX64FSRedirection}
  1.1624 +    ExecWait '"$SYSDIR\regsvr32.exe" /s "${DLL}"'
  1.1625 +    ${EnableX64FSRedirection}
  1.1626 +  ${Else}
  1.1627 +    RegDLL "${DLL}"
  1.1628 +  ${EndIf}
  1.1629 +
  1.1630 +!macroend
  1.1631 +
  1.1632 +!macro UnregisterDLL DLL
  1.1633 +
  1.1634 +  ; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above
  1.1635 +  ; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it
  1.1636 +  ; when installing on an x64 systems even when installing an x86 application.
  1.1637 +  ${If} ${RunningX64}
  1.1638 +    ${DisableX64FSRedirection}
  1.1639 +    ExecWait '"$SYSDIR\regsvr32.exe" /s /u "${DLL}"'
  1.1640 +    ${EnableX64FSRedirection}
  1.1641 +  ${Else}
  1.1642 +    UnRegDLL "${DLL}"
  1.1643 +  ${EndIf}
  1.1644 +
  1.1645 +!macroend
  1.1646 +
  1.1647 +!define RegisterDLL `!insertmacro RegisterDLL`
  1.1648 +!define UnregisterDLL `!insertmacro UnregisterDLL`
  1.1649 +
  1.1650 +
  1.1651 +################################################################################
  1.1652 +# Macros for retrieving existing install paths
  1.1653 +
  1.1654 +/**
  1.1655 + * Finds a second installation of the application so we can make informed
  1.1656 + * decisions about registry operations. This uses SHCTX to determine the
  1.1657 + * registry hive so you must call SetShellVarContext first.
  1.1658 + *
  1.1659 + * @param   _KEY
  1.1660 + *          The registry subkey (typically this will be Software\Mozilla).
  1.1661 + * @return  _RESULT
  1.1662 + *          false if a second install isn't found, path to the main exe if a
  1.1663 + *          second install is found.
  1.1664 + *
  1.1665 + * $R3 = stores the long path to $INSTDIR
  1.1666 + * $R4 = counter for the outer loop's EnumRegKey
  1.1667 + * $R5 = return value from ReadRegStr and RemoveQuotesFromPath
  1.1668 + * $R6 = return value from GetParent
  1.1669 + * $R7 = return value from the loop's EnumRegKey
  1.1670 + * $R8 = storage for _KEY
  1.1671 + * $R9 = _KEY and _RESULT
  1.1672 + */
  1.1673 +!macro GetSecondInstallPath
  1.1674 +
  1.1675 +  !ifndef ${_MOZFUNC_UN}GetSecondInstallPath
  1.1676 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.1677 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.1678 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.1679 +    !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath
  1.1680 +    !undef _MOZFUNC_UN
  1.1681 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.1682 +    !undef _MOZFUNC_UN_TMP
  1.1683 +
  1.1684 +    !verbose push
  1.1685 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1686 +    !define ${_MOZFUNC_UN}GetSecondInstallPath "!insertmacro ${_MOZFUNC_UN}GetSecondInstallPathCall"
  1.1687 +
  1.1688 +    Function ${_MOZFUNC_UN}GetSecondInstallPath
  1.1689 +      Exch $R9
  1.1690 +      Push $R8
  1.1691 +      Push $R7
  1.1692 +      Push $R6
  1.1693 +      Push $R5
  1.1694 +      Push $R4
  1.1695 +      Push $R3
  1.1696 +
  1.1697 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R3
  1.1698 +
  1.1699 +      StrCpy $R4 0       ; set the counter for the loop to 0
  1.1700 +      StrCpy $R8 "$R9"   ; Registry key path to search
  1.1701 +      StrCpy $R9 "false" ; default return value
  1.1702 +
  1.1703 +      loop:
  1.1704 +      EnumRegKey $R7 SHCTX $R8 $R4
  1.1705 +      StrCmp $R7 "" end +1  ; if empty there are no more keys to enumerate
  1.1706 +      IntOp $R4 $R4 + 1     ; increment the loop's counter
  1.1707 +      ClearErrors
  1.1708 +      ReadRegStr $R5 SHCTX "$R8\$R7\bin" "PathToExe"
  1.1709 +      IfErrors loop
  1.1710 +
  1.1711 +      ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R5
  1.1712 +
  1.1713 +      IfFileExists "$R5" +1 loop
  1.1714 +      ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.1715 +      ${${_MOZFUNC_UN}GetParent} "$R5" $R6
  1.1716 +      StrCmp "$R6" "$R3" loop +1
  1.1717 +      StrCmp "$R6\${FileMainEXE}" "$R5" +1 loop
  1.1718 +      StrCpy $R9 "$R5"
  1.1719 +
  1.1720 +      end:
  1.1721 +      ClearErrors
  1.1722 +
  1.1723 +      Pop $R3
  1.1724 +      Pop $R4
  1.1725 +      Pop $R5
  1.1726 +      Pop $R6
  1.1727 +      Pop $R7
  1.1728 +      Pop $R8
  1.1729 +      Exch $R9
  1.1730 +    FunctionEnd
  1.1731 +
  1.1732 +    !verbose pop
  1.1733 +  !endif
  1.1734 +!macroend
  1.1735 +
  1.1736 +!macro GetSecondInstallPathCall _KEY _RESULT
  1.1737 +  !verbose push
  1.1738 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1739 +  Push "${_KEY}"
  1.1740 +  Call GetSecondInstallPath
  1.1741 +  Pop ${_RESULT}
  1.1742 +  !verbose pop
  1.1743 +!macroend
  1.1744 +
  1.1745 +!macro un.GetSecondInstallPathCall _KEY _RESULT
  1.1746 +  !verbose push
  1.1747 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1748 +  Push "${_KEY}"
  1.1749 +  Call un.GetSecondInstallPath
  1.1750 +  Pop ${_RESULT}
  1.1751 +  !verbose pop
  1.1752 +!macroend
  1.1753 +
  1.1754 +!macro un.GetSecondInstallPath
  1.1755 +  !ifndef un.GetSecondInstallPath
  1.1756 +    !verbose push
  1.1757 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1758 +    !undef _MOZFUNC_UN
  1.1759 +    !define _MOZFUNC_UN "un."
  1.1760 +
  1.1761 +    !insertmacro GetSecondInstallPath
  1.1762 +
  1.1763 +    !undef _MOZFUNC_UN
  1.1764 +    !define _MOZFUNC_UN
  1.1765 +    !verbose pop
  1.1766 +  !endif
  1.1767 +!macroend
  1.1768 +
  1.1769 +/**
  1.1770 + * Finds an existing installation path for the application based on the
  1.1771 + * application's executable name so we can default to using this path for the
  1.1772 + * install. If there is zero or more than one installation of the application
  1.1773 + * then we default to the default installation path. This uses SHCTX to
  1.1774 + * determine the registry hive to read from so you must call SetShellVarContext
  1.1775 + * first.
  1.1776 + *
  1.1777 + * @param   _KEY
  1.1778 + *          The registry subkey (typically this will be Software\Mozilla\App Name).
  1.1779 + * @return  _RESULT
  1.1780 + *          false if a single install location for this app name isn't found,
  1.1781 + *          path to the install directory if a single install location is found.
  1.1782 + *
  1.1783 + * $R5 = counter for the loop's EnumRegKey
  1.1784 + * $R6 = return value from EnumRegKey
  1.1785 + * $R7 = return value from ReadRegStr
  1.1786 + * $R8 = storage for _KEY
  1.1787 + * $R9 = _KEY and _RESULT
  1.1788 + */
  1.1789 +!macro GetSingleInstallPath
  1.1790 +
  1.1791 +  !ifndef ${_MOZFUNC_UN}GetSingleInstallPath
  1.1792 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.1793 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.1794 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.1795 +    !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath
  1.1796 +    !undef _MOZFUNC_UN
  1.1797 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.1798 +    !undef _MOZFUNC_UN_TMP
  1.1799 +
  1.1800 +    !verbose push
  1.1801 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1802 +    !define ${_MOZFUNC_UN}GetSingleInstallPath "!insertmacro ${_MOZFUNC_UN}GetSingleInstallPathCall"
  1.1803 +
  1.1804 +    Function ${_MOZFUNC_UN}GetSingleInstallPath
  1.1805 +      Exch $R9
  1.1806 +      Push $R8
  1.1807 +      Push $R7
  1.1808 +      Push $R6
  1.1809 +      Push $R5
  1.1810 +
  1.1811 +      StrCpy $R8 $R9
  1.1812 +      StrCpy $R9 "false"
  1.1813 +      StrCpy $R5 0  ; set the counter for the loop to 0
  1.1814 +
  1.1815 +      loop:
  1.1816 +      ClearErrors
  1.1817 +      EnumRegKey $R6 SHCTX $R8 $R5
  1.1818 +      IfErrors cleanup
  1.1819 +      StrCmp $R6 "" cleanup +1  ; if empty there are no more keys to enumerate
  1.1820 +      IntOp $R5 $R5 + 1         ; increment the loop's counter
  1.1821 +      ClearErrors
  1.1822 +      ReadRegStr $R7 SHCTX "$R8\$R6\Main" "PathToExe"
  1.1823 +      IfErrors loop
  1.1824 +      ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R7" $R7
  1.1825 +      GetFullPathName $R7 "$R7"
  1.1826 +      IfErrors loop
  1.1827 +
  1.1828 +      StrCmp "$R9" "false" +1 +3
  1.1829 +      StrCpy $R9 "$R7"
  1.1830 +      GoTo Loop
  1.1831 +
  1.1832 +      StrCpy $R9 "false"
  1.1833 +
  1.1834 +      cleanup:
  1.1835 +      StrCmp $R9 "false" end +1
  1.1836 +      ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
  1.1837 +      ${${_MOZFUNC_UN}GetParent} "$R9" $R9
  1.1838 +
  1.1839 +      end:
  1.1840 +      ClearErrors
  1.1841 +
  1.1842 +      Pop $R5
  1.1843 +      Pop $R6
  1.1844 +      Pop $R7
  1.1845 +      Pop $R8
  1.1846 +      Exch $R9
  1.1847 +    FunctionEnd
  1.1848 +
  1.1849 +    !verbose pop
  1.1850 +  !endif
  1.1851 +!macroend
  1.1852 +
  1.1853 +!macro GetSingleInstallPathCall _KEY _RESULT
  1.1854 +  !verbose push
  1.1855 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1856 +  Push "${_KEY}"
  1.1857 +  Call GetSingleInstallPath
  1.1858 +  Pop ${_RESULT}
  1.1859 +  !verbose pop
  1.1860 +!macroend
  1.1861 +
  1.1862 +!macro un.GetSingleInstallPathCall _KEY _RESULT
  1.1863 +  !verbose push
  1.1864 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1865 +  Push "${_KEY}"
  1.1866 +  Call un.GetSingleInstallPath
  1.1867 +  Pop ${_RESULT}
  1.1868 +  !verbose pop
  1.1869 +!macroend
  1.1870 +
  1.1871 +!macro un.GetSingleInstallPath
  1.1872 +  !ifndef un.GetSingleInstallPath
  1.1873 +    !verbose push
  1.1874 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1875 +    !undef _MOZFUNC_UN
  1.1876 +    !define _MOZFUNC_UN "un."
  1.1877 +
  1.1878 +    !insertmacro GetSingleInstallPath
  1.1879 +
  1.1880 +    !undef _MOZFUNC_UN
  1.1881 +    !define _MOZFUNC_UN
  1.1882 +    !verbose pop
  1.1883 +  !endif
  1.1884 +!macroend
  1.1885 +
  1.1886 +
  1.1887 +################################################################################
  1.1888 +# Macros for working with the file system
  1.1889 +
  1.1890 +/**
  1.1891 + * Attempts to delete a file if it exists. This will fail if the file is in use.
  1.1892 + *
  1.1893 + * @param   _FILE
  1.1894 + *          The path to the file that is to be deleted.
  1.1895 + */
  1.1896 +!macro DeleteFile _FILE
  1.1897 +  ${If} ${FileExists} "${_FILE}"
  1.1898 +    Delete "${_FILE}"
  1.1899 +  ${EndIf}
  1.1900 +!macroend
  1.1901 +!define DeleteFile "!insertmacro DeleteFile"
  1.1902 +
  1.1903 +/**
  1.1904 + * Removes a directory if it exists and is empty.
  1.1905 + *
  1.1906 + * @param   _DIR
  1.1907 + *          The path to the directory that is to be removed.
  1.1908 + */
  1.1909 +!macro RemoveDir _DIR
  1.1910 +  ${If} ${FileExists} "${_DIR}"
  1.1911 +    RmDir "${_DIR}"
  1.1912 +  ${EndIf}
  1.1913 +!macroend
  1.1914 +!define RemoveDir "!insertmacro RemoveDir"
  1.1915 +
  1.1916 +/**
  1.1917 + * Checks whether it is possible to create and delete a directory and a file in
  1.1918 + * the install directory. Creation and deletion of files and directories are
  1.1919 + * checked since a user may have rights for one and not the other. If creation
  1.1920 + * and deletion of a file and a directory are successful this macro will return
  1.1921 + * true... if not, this it return false.
  1.1922 + *
  1.1923 + * @return  _RESULT
  1.1924 + *          true if files and directories can be created and deleted in the
  1.1925 + *          install directory otherwise false.
  1.1926 + *
  1.1927 + * $R8 = temporary filename in the installation directory returned from
  1.1928 + *       GetTempFileName.
  1.1929 + * $R9 = _RESULT
  1.1930 + */
  1.1931 +!macro CanWriteToInstallDir
  1.1932 +
  1.1933 +  !ifndef ${_MOZFUNC_UN}CanWriteToInstallDir
  1.1934 +    !verbose push
  1.1935 +    !verbose ${_MOZFUNC_VERBOSE}
  1.1936 +    !define ${_MOZFUNC_UN}CanWriteToInstallDir "!insertmacro ${_MOZFUNC_UN}CanWriteToInstallDirCall"
  1.1937 +
  1.1938 +    Function ${_MOZFUNC_UN}CanWriteToInstallDir
  1.1939 +      Push $R9
  1.1940 +      Push $R8
  1.1941 +
  1.1942 +      StrCpy $R9 "true"
  1.1943 +
  1.1944 +      ; IfFileExists returns false for $INSTDIR when $INSTDIR is the root of a
  1.1945 +      ; UNC path so always try to create $INSTDIR
  1.1946 +      CreateDirectory "$INSTDIR\"
  1.1947 +      GetTempFileName $R8 "$INSTDIR\"
  1.1948 +
  1.1949 +      ${Unless} ${FileExists} $R8 ; Can files be created?
  1.1950 +        StrCpy $R9 "false"
  1.1951 +        Goto done
  1.1952 +      ${EndUnless}
  1.1953 +
  1.1954 +      Delete $R8
  1.1955 +      ${If} ${FileExists} $R8 ; Can files be deleted?
  1.1956 +        StrCpy $R9 "false"
  1.1957 +        Goto done
  1.1958 +      ${EndIf}
  1.1959 +
  1.1960 +      CreateDirectory $R8
  1.1961 +      ${Unless} ${FileExists} $R8  ; Can directories be created?
  1.1962 +        StrCpy $R9 "false"
  1.1963 +        Goto done
  1.1964 +      ${EndUnless}
  1.1965 +
  1.1966 +      RmDir $R8
  1.1967 +      ${If} ${FileExists} $R8  ; Can directories be deleted?
  1.1968 +        StrCpy $R9 "false"
  1.1969 +        Goto done
  1.1970 +      ${EndIf}
  1.1971 +
  1.1972 +      done:
  1.1973 +
  1.1974 +      RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty
  1.1975 +      ClearErrors
  1.1976 +
  1.1977 +      Pop $R8
  1.1978 +      Exch $R9
  1.1979 +    FunctionEnd
  1.1980 +
  1.1981 +    !verbose pop
  1.1982 +  !endif
  1.1983 +!macroend
  1.1984 +
  1.1985 +!macro CanWriteToInstallDirCall _RESULT
  1.1986 +  !verbose push
  1.1987 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1988 +  Call CanWriteToInstallDir
  1.1989 +  Pop ${_RESULT}
  1.1990 +  !verbose pop
  1.1991 +!macroend
  1.1992 +
  1.1993 +!macro un.CanWriteToInstallDirCall _RESULT
  1.1994 +  !verbose push
  1.1995 +  !verbose ${_MOZFUNC_VERBOSE}
  1.1996 +  Call un.CanWriteToInstallDir
  1.1997 +  Pop ${_RESULT}
  1.1998 +  !verbose pop
  1.1999 +!macroend
  1.2000 +
  1.2001 +!macro un.CanWriteToInstallDir
  1.2002 +  !ifndef un.CanWriteToInstallDir
  1.2003 +    !verbose push
  1.2004 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2005 +    !undef _MOZFUNC_UN
  1.2006 +    !define _MOZFUNC_UN "un."
  1.2007 +
  1.2008 +    !insertmacro CanWriteToInstallDir
  1.2009 +
  1.2010 +    !undef _MOZFUNC_UN
  1.2011 +    !define _MOZFUNC_UN
  1.2012 +    !verbose pop
  1.2013 +  !endif
  1.2014 +!macroend
  1.2015 +
  1.2016 +/**
  1.2017 + * Checks whether there is sufficient free space available for the installation
  1.2018 + * directory using GetDiskFreeSpaceExW which respects disk quotas. This macro
  1.2019 + * will calculate the size of all sections that are selected, compare that with
  1.2020 + * the free space available, and if there is sufficient free space it will
  1.2021 + * return true... if not, it will return false.
  1.2022 + *
  1.2023 + * @return  _RESULT
  1.2024 + *          "true" if there is sufficient free space otherwise "false".
  1.2025 + *
  1.2026 + * $R5 = return value from SectionGetSize
  1.2027 + * $R6 = return value from SectionGetFlags
  1.2028 + *       return value from an 'and' comparison of SectionGetFlags (1=selected)
  1.2029 + *       return value for lpFreeBytesAvailable from GetDiskFreeSpaceExW
  1.2030 + *       return value for System::Int64Op $R6 / 1024
  1.2031 + *       return value for System::Int64Op $R6 > $R8
  1.2032 + * $R7 = the counter for enumerating the sections
  1.2033 + *       the temporary file name for the directory created under $INSTDIR passed
  1.2034 + *       to GetDiskFreeSpaceExW.
  1.2035 + * $R8 = sum in KB of all selected sections
  1.2036 + * $R9 = _RESULT
  1.2037 + */
  1.2038 +!macro CheckDiskSpace
  1.2039 +
  1.2040 +  !ifndef ${_MOZFUNC_UN}CheckDiskSpace
  1.2041 +    !verbose push
  1.2042 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2043 +    !define ${_MOZFUNC_UN}CheckDiskSpace "!insertmacro ${_MOZFUNC_UN}CheckDiskSpaceCall"
  1.2044 +
  1.2045 +    Function ${_MOZFUNC_UN}CheckDiskSpace
  1.2046 +      Push $R9
  1.2047 +      Push $R8
  1.2048 +      Push $R7
  1.2049 +      Push $R6
  1.2050 +      Push $R5
  1.2051 +
  1.2052 +      ClearErrors
  1.2053 +
  1.2054 +      StrCpy $R9 "true" ; default return value
  1.2055 +      StrCpy $R8 "0"    ; sum in KB of all selected sections
  1.2056 +      StrCpy $R7 "0"    ; counter for enumerating sections
  1.2057 +
  1.2058 +      ; Enumerate the sections and sum up the sizes of the sections that are
  1.2059 +      ; selected.
  1.2060 +      SectionGetFlags $R7 $R6
  1.2061 +      IfErrors +7 +1
  1.2062 +      IntOp $R6 ${SF_SELECTED} & $R6
  1.2063 +      IntCmp $R6 0 +3 +1 +1
  1.2064 +      SectionGetSize $R7 $R5
  1.2065 +      IntOp $R8 $R8 + $R5
  1.2066 +      IntOp $R7 $R7 + 1
  1.2067 +      GoTo -7
  1.2068 +
  1.2069 +      ; The directory passed to GetDiskFreeSpaceExW must exist for the call to
  1.2070 +      ; succeed.  Since the CanWriteToInstallDir macro is called prior to this
  1.2071 +      ; macro the call to CreateDirectory will always succeed.
  1.2072 +
  1.2073 +      ; IfFileExists returns false for $INSTDIR when $INSTDIR is the root of a
  1.2074 +      ; UNC path so always try to create $INSTDIR
  1.2075 +      CreateDirectory "$INSTDIR\"
  1.2076 +      GetTempFileName $R7 "$INSTDIR\"
  1.2077 +      Delete "$R7"
  1.2078 +      CreateDirectory "$R7"
  1.2079 +
  1.2080 +      System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i(R7, .R6, ., .) .'
  1.2081 +
  1.2082 +      ; Convert to KB for comparison with $R8 which is in KB
  1.2083 +      System::Int64Op $R6 / 1024
  1.2084 +      Pop $R6
  1.2085 +
  1.2086 +      System::Int64Op $R6 > $R8
  1.2087 +      Pop $R6
  1.2088 +
  1.2089 +      IntCmp $R6 1 end +1 +1
  1.2090 +      StrCpy $R9 "false"
  1.2091 +
  1.2092 +      end:
  1.2093 +      RmDir "$R7"
  1.2094 +      RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty
  1.2095 +
  1.2096 +      ClearErrors
  1.2097 +
  1.2098 +      Pop $R5
  1.2099 +      Pop $R6
  1.2100 +      Pop $R7
  1.2101 +      Pop $R8
  1.2102 +      Exch $R9
  1.2103 +    FunctionEnd
  1.2104 +
  1.2105 +    !verbose pop
  1.2106 +  !endif
  1.2107 +!macroend
  1.2108 +
  1.2109 +!macro CheckDiskSpaceCall _RESULT
  1.2110 +  !verbose push
  1.2111 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2112 +  Call CheckDiskSpace
  1.2113 +  Pop ${_RESULT}
  1.2114 +  !verbose pop
  1.2115 +!macroend
  1.2116 +
  1.2117 +!macro un.CheckDiskSpaceCall _RESULT
  1.2118 +  !verbose push
  1.2119 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2120 +  Call un.CheckDiskSpace
  1.2121 +  Pop ${_RESULT}
  1.2122 +  !verbose pop
  1.2123 +!macroend
  1.2124 +
  1.2125 +!macro un.CheckDiskSpace
  1.2126 +  !ifndef un.CheckDiskSpace
  1.2127 +    !verbose push
  1.2128 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2129 +    !undef _MOZFUNC_UN
  1.2130 +    !define _MOZFUNC_UN "un."
  1.2131 +
  1.2132 +    !insertmacro CheckDiskSpace
  1.2133 +
  1.2134 +    !undef _MOZFUNC_UN
  1.2135 +    !define _MOZFUNC_UN
  1.2136 +    !verbose pop
  1.2137 +  !endif
  1.2138 +!macroend
  1.2139 +
  1.2140 +/**
  1.2141 +* Returns the path found within a passed in string. The path is quoted or not
  1.2142 +* with the exception of an unquoted non 8dot3 path without arguments that is
  1.2143 +* also not a DefaultIcon path, is a 8dot3 path or not, has command line
  1.2144 +* arguments, or is a registry DefaultIcon path (e.g. <path to binary>,# where #
  1.2145 +* is the icon's resuorce id). The string does not need to be a valid path or
  1.2146 +* exist. It is up to the caller to pass in a string of one of the forms noted
  1.2147 +* above and to verify existence if necessary.
  1.2148 +*
  1.2149 +* Examples:
  1.2150 +* In:  C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -flag "%1"
  1.2151 +* In:  C:\PROGRA~1\MOZILL~1\FIREFOX.EXE,0
  1.2152 +* In:  C:\PROGRA~1\MOZILL~1\FIREFOX.EXE
  1.2153 +* In:  "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE"
  1.2154 +* In:  "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE" -flag "%1"
  1.2155 +* Out: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE
  1.2156 +*
  1.2157 +* In:  "C:\Program Files\Mozilla Firefox\firefox.exe" -flag "%1"
  1.2158 +* In:  C:\Program Files\Mozilla Firefox\firefox.exe,0
  1.2159 +* In:  "C:\Program Files\Mozilla Firefox\firefox.exe"
  1.2160 +* Out: C:\Program Files\Mozilla Firefox\firefox.exe
  1.2161 +*
  1.2162 +* @param   _IN_PATH
  1.2163 +*          The string containing the path.
  1.2164 +* @param   _OUT_PATH
  1.2165 +*          The register to store the path to.
  1.2166 +*
  1.2167 +* $R7 = counter for the outer loop's EnumRegKey
  1.2168 +* $R8 = return value from ReadRegStr
  1.2169 +* $R9 = _IN_PATH and _OUT_PATH
  1.2170 +*/
  1.2171 +!macro GetPathFromString
  1.2172 +
  1.2173 +  !ifndef ${_MOZFUNC_UN}GetPathFromString
  1.2174 +    !verbose push
  1.2175 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2176 +    !define ${_MOZFUNC_UN}GetPathFromString "!insertmacro ${_MOZFUNC_UN}GetPathFromStringCall"
  1.2177 +
  1.2178 +    Function ${_MOZFUNC_UN}GetPathFromString
  1.2179 +      Exch $R9
  1.2180 +      Push $R8
  1.2181 +      Push $R7
  1.2182 +
  1.2183 +      StrCpy $R7 0          ; Set the counter to 0.
  1.2184 +
  1.2185 +      ; Handle quoted paths with arguments.
  1.2186 +      StrCpy $R8 $R9 1      ; Copy the first char.
  1.2187 +      StrCmp $R8 '"' +2 +1  ; Is it a "?
  1.2188 +      StrCmp $R8 "'" +1 +9  ; Is it a '?
  1.2189 +      StrCpy $R9 $R9 "" 1   ; Remove the first char.
  1.2190 +      IntOp $R7 $R7 + 1     ; Increment the counter.
  1.2191 +      StrCpy $R8 $R9 1 $R7  ; Starting from the counter copy the next char.
  1.2192 +      StrCmp $R8 "" end +1  ; Are there no more chars?
  1.2193 +      StrCmp $R8 '"' +2 +1  ; Is it a " char?
  1.2194 +      StrCmp $R8 "'" +1 -4  ; Is it a ' char?
  1.2195 +      StrCpy $R9 $R9 $R7    ; Copy chars up to the counter.
  1.2196 +      GoTo end
  1.2197 +
  1.2198 +      ; Handle DefaultIcon paths. DefaultIcon paths are not quoted and end with
  1.2199 +      ; a , and a number.
  1.2200 +      IntOp $R7 $R7 - 1     ; Decrement the counter.
  1.2201 +      StrCpy $R8 $R9 1 $R7  ; Copy one char from the end minus the counter.
  1.2202 +      StrCmp $R8 '' +4 +1   ; Are there no more chars?
  1.2203 +      StrCmp $R8 ',' +1 -3  ; Is it a , char?
  1.2204 +      StrCpy $R9 $R9 $R7    ; Copy chars up to the end minus the counter.
  1.2205 +      GoTo end
  1.2206 +
  1.2207 +      ; Handle unquoted paths with arguments. An unquoted path with arguments
  1.2208 +      ; must be an 8dot3 path.
  1.2209 +      StrCpy $R7 -1          ; Set the counter to -1 so it will start at 0.
  1.2210 +      IntOp $R7 $R7 + 1      ; Increment the counter.
  1.2211 +      StrCpy $R8 $R9 1 $R7   ; Starting from the counter copy the next char.
  1.2212 +      StrCmp $R8 "" end +1   ; Are there no more chars?
  1.2213 +      StrCmp $R8 " " +1 -3   ; Is it a space char?
  1.2214 +      StrCpy $R9 $R9 $R7     ; Copy chars up to the counter.
  1.2215 +
  1.2216 +      end:
  1.2217 +      ClearErrors
  1.2218 +
  1.2219 +      Pop $R7
  1.2220 +      Pop $R8
  1.2221 +      Exch $R9
  1.2222 +    FunctionEnd
  1.2223 +
  1.2224 +    !verbose pop
  1.2225 +  !endif
  1.2226 +!macroend
  1.2227 +
  1.2228 +!macro GetPathFromStringCall _IN_PATH _OUT_PATH
  1.2229 +  !verbose push
  1.2230 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2231 +  Push "${_IN_PATH}"
  1.2232 +  Call GetPathFromString
  1.2233 +  Pop ${_OUT_PATH}
  1.2234 +  !verbose pop
  1.2235 +!macroend
  1.2236 +
  1.2237 +!macro un.GetPathFromStringCall _IN_PATH _OUT_PATH
  1.2238 +  !verbose push
  1.2239 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2240 +  Push "${_IN_PATH}"
  1.2241 +  Call un.GetPathFromString
  1.2242 +  Pop ${_OUT_PATH}
  1.2243 +  !verbose pop
  1.2244 +!macroend
  1.2245 +
  1.2246 +!macro un.GetPathFromString
  1.2247 +  !ifndef un.GetPathFromString
  1.2248 +    !verbose push
  1.2249 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2250 +    !undef _MOZFUNC_UN
  1.2251 +    !define _MOZFUNC_UN "un."
  1.2252 +
  1.2253 +    !insertmacro GetPathFromString
  1.2254 +
  1.2255 +    !undef _MOZFUNC_UN
  1.2256 +    !define _MOZFUNC_UN
  1.2257 +    !verbose pop
  1.2258 +  !endif
  1.2259 +!macroend
  1.2260 +
  1.2261 +/**
  1.2262 + * Removes the quotes from each end of a string if present.
  1.2263 + *
  1.2264 + * @param   _IN_PATH
  1.2265 + *          The string containing the path.
  1.2266 + * @param   _OUT_PATH
  1.2267 + *          The register to store the long path.
  1.2268 + *
  1.2269 + * $R7 = storage for single character comparison
  1.2270 + * $R8 = storage for _IN_PATH
  1.2271 + * $R9 = _IN_PATH and _OUT_PATH
  1.2272 + */
  1.2273 +!macro RemoveQuotesFromPath
  1.2274 +
  1.2275 +  !ifndef ${_MOZFUNC_UN}RemoveQuotesFromPath
  1.2276 +    !verbose push
  1.2277 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2278 +    !define ${_MOZFUNC_UN}RemoveQuotesFromPath "!insertmacro ${_MOZFUNC_UN}RemoveQuotesFromPathCall"
  1.2279 +
  1.2280 +    Function ${_MOZFUNC_UN}RemoveQuotesFromPath
  1.2281 +      Exch $R9
  1.2282 +      Push $R8
  1.2283 +      Push $R7
  1.2284 +
  1.2285 +      StrCpy $R7 "$R9" 1
  1.2286 +      StrCmp $R7 "$\"" +1 +2
  1.2287 +      StrCpy $R9 "$R9" "" 1
  1.2288 +
  1.2289 +      StrCpy $R7 "$R9" "" -1
  1.2290 +      StrCmp $R7 "$\"" +1 +2
  1.2291 +      StrCpy $R9 "$R9" -1
  1.2292 +
  1.2293 +      Pop $R7
  1.2294 +      Pop $R8
  1.2295 +      Exch $R9
  1.2296 +    FunctionEnd
  1.2297 +
  1.2298 +    !verbose pop
  1.2299 +  !endif
  1.2300 +!macroend
  1.2301 +
  1.2302 +!macro RemoveQuotesFromPathCall _IN_PATH _OUT_PATH
  1.2303 +  !verbose push
  1.2304 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2305 +  Push "${_IN_PATH}"
  1.2306 +  Call RemoveQuotesFromPath
  1.2307 +  Pop ${_OUT_PATH}
  1.2308 +  !verbose pop
  1.2309 +!macroend
  1.2310 +
  1.2311 +!macro un.RemoveQuotesFromPathCall _IN_PATH _OUT_PATH
  1.2312 +  !verbose push
  1.2313 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2314 +  Push "${_IN_PATH}"
  1.2315 +  Call un.RemoveQuotesFromPath
  1.2316 +  Pop ${_OUT_PATH}
  1.2317 +  !verbose pop
  1.2318 +!macroend
  1.2319 +
  1.2320 +!macro un.RemoveQuotesFromPath
  1.2321 +  !ifndef un.RemoveQuotesFromPath
  1.2322 +    !verbose push
  1.2323 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2324 +    !undef _MOZFUNC_UN
  1.2325 +    !define _MOZFUNC_UN "un."
  1.2326 +
  1.2327 +    !insertmacro RemoveQuotesFromPath
  1.2328 +
  1.2329 +    !undef _MOZFUNC_UN
  1.2330 +    !define _MOZFUNC_UN
  1.2331 +    !verbose pop
  1.2332 +  !endif
  1.2333 +!macroend
  1.2334 +
  1.2335 +/**
  1.2336 + * Returns the long path for an existing file or directory. GetLongPathNameW
  1.2337 + * may not be available on Win95 if Microsoft Layer for Unicode is not
  1.2338 + * installed and GetFullPathName only returns a long path for the last file or
  1.2339 + * directory that doesn't end with a \ in the path that it is passed. If the
  1.2340 + * path does not exist on the file system this will return an empty string. To
  1.2341 + * provide a consistent result trailing back-slashes are always removed.
  1.2342 + *
  1.2343 + * Note: 1024 used by GetLongPathNameW is the maximum NSIS string length.
  1.2344 + *
  1.2345 + * @param   _IN_PATH
  1.2346 + *          The string containing the path.
  1.2347 + * @param   _OUT_PATH
  1.2348 + *          The register to store the long path.
  1.2349 + *
  1.2350 + * $R4 = counter value when the previous \ was found
  1.2351 + * $R5 = directory or file name found during loop
  1.2352 + * $R6 = return value from GetLongPathNameW and loop counter
  1.2353 + * $R7 = long path from GetLongPathNameW and single char from path for comparison
  1.2354 + * $R8 = storage for _IN_PATH
  1.2355 + * $R9 = _IN_PATH _OUT_PATH
  1.2356 + */
  1.2357 +!macro GetLongPath
  1.2358 +
  1.2359 +  !ifndef ${_MOZFUNC_UN}GetLongPath
  1.2360 +    !verbose push
  1.2361 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2362 +    !define ${_MOZFUNC_UN}GetLongPath "!insertmacro ${_MOZFUNC_UN}GetLongPathCall"
  1.2363 +
  1.2364 +    Function ${_MOZFUNC_UN}GetLongPath
  1.2365 +      Exch $R9
  1.2366 +      Push $R8
  1.2367 +      Push $R7
  1.2368 +      Push $R6
  1.2369 +      Push $R5
  1.2370 +      Push $R4
  1.2371 +
  1.2372 +      ClearErrors
  1.2373 +
  1.2374 +      GetFullPathName $R8 "$R9"
  1.2375 +      IfErrors end_GetLongPath +1 ; If the path doesn't exist return an empty string.
  1.2376 +
  1.2377 +      System::Call 'kernel32::GetLongPathNameW(w R8, w .R7, i 1024)i .R6'
  1.2378 +      StrCmp "$R7" "" +4 +1 ; Empty string when GetLongPathNameW is not present.
  1.2379 +      StrCmp $R6 0 +3 +1    ; Should never equal 0 since the path exists.
  1.2380 +      StrCpy $R9 "$R7"
  1.2381 +      GoTo end_GetLongPath
  1.2382 +
  1.2383 +      ; Do it the hard way.
  1.2384 +      StrCpy $R4 0     ; Stores the position in the string of the last \ found.
  1.2385 +      StrCpy $R6 -1    ; Set the counter to -1 so it will start at 0.
  1.2386 +
  1.2387 +      loop_GetLongPath:
  1.2388 +      IntOp $R6 $R6 + 1      ; Increment the counter.
  1.2389 +      StrCpy $R7 $R8 1 $R6   ; Starting from the counter copy the next char.
  1.2390 +      StrCmp $R7 "" +2 +1    ; Are there no more chars?
  1.2391 +      StrCmp $R7 "\" +1 -3   ; Is it a \?
  1.2392 +
  1.2393 +      ; Copy chars starting from the previously found \ to the counter.
  1.2394 +      StrCpy $R5 $R8 $R6 $R4
  1.2395 +
  1.2396 +      ; If this is the first \ found we want to swap R9 with R5 so a \ will
  1.2397 +      ; be appended to the drive letter and colon (e.g. C: will become C:\).
  1.2398 +      StrCmp $R4 0 +1 +3
  1.2399 +      StrCpy $R9 $R5
  1.2400 +      StrCpy $R5 ""
  1.2401 +
  1.2402 +      GetFullPathName $R9 "$R9\$R5"
  1.2403 +
  1.2404 +      StrCmp $R7 "" end_GetLongPath +1 ; Are there no more chars?
  1.2405 +
  1.2406 +      ; Store the counter for the current \ and prefix it for StrCpy operations.
  1.2407 +      StrCpy $R4 "+$R6"
  1.2408 +      IntOp $R6 $R6 + 1      ; Increment the counter so we skip over the \.
  1.2409 +      StrCpy $R8 $R8 "" $R6  ; Copy chars starting from the counter to the end.
  1.2410 +      StrCpy $R6 -1          ; Reset the counter to -1 so it will start over at 0.
  1.2411 +      GoTo loop_GetLongPath
  1.2412 +
  1.2413 +      end_GetLongPath:
  1.2414 +      ; If there is a trailing slash remove it
  1.2415 +      StrCmp $R9 "" +4 +1
  1.2416 +      StrCpy $R8 "$R9" "" -1
  1.2417 +      StrCmp $R8 "\" +1 +2
  1.2418 +      StrCpy $R9 "$R9" -1
  1.2419 +
  1.2420 +      ClearErrors
  1.2421 +
  1.2422 +      Pop $R4
  1.2423 +      Pop $R5
  1.2424 +      Pop $R6
  1.2425 +      Pop $R7
  1.2426 +      Pop $R8
  1.2427 +      Exch $R9
  1.2428 +    FunctionEnd
  1.2429 +
  1.2430 +    !verbose pop
  1.2431 +  !endif
  1.2432 +!macroend
  1.2433 +
  1.2434 +!macro GetLongPathCall _IN_PATH _OUT_PATH
  1.2435 +  !verbose push
  1.2436 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2437 +  Push "${_IN_PATH}"
  1.2438 +  Call GetLongPath
  1.2439 +  Pop ${_OUT_PATH}
  1.2440 +  !verbose pop
  1.2441 +!macroend
  1.2442 +
  1.2443 +!macro un.GetLongPathCall _IN_PATH _OUT_PATH
  1.2444 +  !verbose push
  1.2445 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2446 +  Push "${_IN_PATH}"
  1.2447 +  Call un.GetLongPath
  1.2448 +  Pop ${_OUT_PATH}
  1.2449 +  !verbose pop
  1.2450 +!macroend
  1.2451 +
  1.2452 +!macro un.GetLongPath
  1.2453 +  !ifndef un.GetLongPath
  1.2454 +    !verbose push
  1.2455 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2456 +    !undef _MOZFUNC_UN
  1.2457 +    !define _MOZFUNC_UN "un."
  1.2458 +
  1.2459 +    !insertmacro GetLongPath
  1.2460 +
  1.2461 +    !undef _MOZFUNC_UN
  1.2462 +    !define _MOZFUNC_UN
  1.2463 +    !verbose pop
  1.2464 +  !endif
  1.2465 +!macroend
  1.2466 +
  1.2467 +
  1.2468 +################################################################################
  1.2469 +# Macros for cleaning up the registry and file system
  1.2470 +
  1.2471 +/**
  1.2472 + * Removes registry keys that reference this install location and for paths that
  1.2473 + * no longer exist. This uses SHCTX to determine the registry hive so you must
  1.2474 + * call SetShellVarContext first.
  1.2475 + *
  1.2476 + * @param   _KEY
  1.2477 + *          The registry subkey (typically this will be Software\Mozilla).
  1.2478 + *
  1.2479 + * XXXrstrong - there is the potential for Key: Software/Mozilla/AppName,
  1.2480 + * ValueName: CurrentVersion, ValueData: AppVersion to reference a key that is
  1.2481 + * no longer available due to this cleanup. This should be no worse than prior
  1.2482 + * to this reg cleanup since the referenced key would be for an app that is no
  1.2483 + * longer installed on the system.
  1.2484 + *
  1.2485 + * $R0 = on x64 systems set to 'false' at the beginning of the macro when
  1.2486 + *       enumerating the x86 registry view and set to 'true' when enumerating
  1.2487 + *       the x64 registry view.
  1.2488 + * $R1 = stores the long path to $INSTDIR
  1.2489 + * $R2 = return value from the stack from the GetParent and GetLongPath macros
  1.2490 + * $R3 = return value from the outer loop's EnumRegKey
  1.2491 + * $R4 = return value from the inner loop's EnumRegKey
  1.2492 + * $R5 = return value from ReadRegStr
  1.2493 + * $R6 = counter for the outer loop's EnumRegKey
  1.2494 + * $R7 = counter for the inner loop's EnumRegKey
  1.2495 + * $R8 = return value from the stack from the RemoveQuotesFromPath macro
  1.2496 + * $R9 = _KEY
  1.2497 + */
  1.2498 +!macro RegCleanMain
  1.2499 +
  1.2500 +  !ifndef ${_MOZFUNC_UN}RegCleanMain
  1.2501 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.2502 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.2503 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.2504 +    !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath
  1.2505 +    !undef _MOZFUNC_UN
  1.2506 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.2507 +    !undef _MOZFUNC_UN_TMP
  1.2508 +
  1.2509 +    !verbose push
  1.2510 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2511 +    !define ${_MOZFUNC_UN}RegCleanMain "!insertmacro ${_MOZFUNC_UN}RegCleanMainCall"
  1.2512 +
  1.2513 +    Function ${_MOZFUNC_UN}RegCleanMain
  1.2514 +      Exch $R9
  1.2515 +      Push $R8
  1.2516 +      Push $R7
  1.2517 +      Push $R6
  1.2518 +      Push $R5
  1.2519 +      Push $R4
  1.2520 +      Push $R3
  1.2521 +      Push $R2
  1.2522 +      Push $R1
  1.2523 +      Push $R0
  1.2524 +
  1.2525 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R1
  1.2526 +      StrCpy $R6 0  ; set the counter for the outer loop to 0
  1.2527 +
  1.2528 +      ${If} ${RunningX64}
  1.2529 +        StrCpy $R0 "false"
  1.2530 +        ; Set the registry to the 32 bit registry for 64 bit installations or to
  1.2531 +        ; the 64 bit registry for 32 bit installations at the beginning so it can
  1.2532 +        ; easily be set back to the correct registry view when finished.
  1.2533 +        !ifdef HAVE_64BIT_OS
  1.2534 +          SetRegView 32
  1.2535 +        !else
  1.2536 +          SetRegView 64
  1.2537 +        !endif
  1.2538 +      ${EndIf}
  1.2539 +
  1.2540 +      outerloop:
  1.2541 +      EnumRegKey $R3 SHCTX $R9 $R6
  1.2542 +      StrCmp $R3 "" end +1  ; if empty there are no more keys to enumerate
  1.2543 +      IntOp $R6 $R6 + 1     ; increment the outer loop's counter
  1.2544 +      ClearErrors
  1.2545 +      ReadRegStr $R5 SHCTX "$R9\$R3\bin" "PathToExe"
  1.2546 +      IfErrors 0 outercontinue
  1.2547 +      StrCpy $R7 0  ; set the counter for the inner loop to 0
  1.2548 +
  1.2549 +      innerloop:
  1.2550 +      EnumRegKey $R4 SHCTX "$R9\$R3" $R7
  1.2551 +      StrCmp $R4 "" outerloop +1  ; if empty there are no more keys to enumerate
  1.2552 +      IntOp $R7 $R7 + 1  ; increment the inner loop's counter
  1.2553 +      ClearErrors
  1.2554 +      ReadRegStr $R5 SHCTX "$R9\$R3\$R4\Main" "PathToExe"
  1.2555 +      IfErrors innerloop
  1.2556 +
  1.2557 +      ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R8
  1.2558 +      ${${_MOZFUNC_UN}GetParent} "$R8" $R2
  1.2559 +      ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2
  1.2560 +      IfFileExists "$R2" +1 innerloop
  1.2561 +      StrCmp "$R2" "$R1" +1 innerloop
  1.2562 +
  1.2563 +      ClearErrors
  1.2564 +      DeleteRegKey SHCTX "$R9\$R3\$R4"
  1.2565 +      IfErrors innerloop
  1.2566 +      IntOp $R7 $R7 - 1 ; decrement the inner loop's counter when the key is deleted successfully.
  1.2567 +      ClearErrors
  1.2568 +      DeleteRegKey /ifempty SHCTX "$R9\$R3"
  1.2569 +      IfErrors innerloop outerdecrement
  1.2570 +
  1.2571 +      outercontinue:
  1.2572 +      ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R8
  1.2573 +      ${${_MOZFUNC_UN}GetParent} "$R8" $R2
  1.2574 +      ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2
  1.2575 +      IfFileExists "$R2" +1 outerloop
  1.2576 +      StrCmp "$R2" "$R1" +1 outerloop
  1.2577 +
  1.2578 +      ClearErrors
  1.2579 +      DeleteRegKey SHCTX "$R9\$R3"
  1.2580 +      IfErrors outerloop
  1.2581 +
  1.2582 +      outerdecrement:
  1.2583 +      IntOp $R6 $R6 - 1 ; decrement the outer loop's counter when the key is deleted successfully.
  1.2584 +      GoTo outerloop
  1.2585 +
  1.2586 +      end:
  1.2587 +      ${If} ${RunningX64}
  1.2588 +      ${AndIf} "$R0" == "false"
  1.2589 +        ; Set the registry to the correct view.
  1.2590 +        !ifdef HAVE_64BIT_OS
  1.2591 +          SetRegView 64
  1.2592 +        !else
  1.2593 +          SetRegView 32
  1.2594 +        !endif
  1.2595 +
  1.2596 +        StrCpy $R6 0  ; set the counter for the outer loop to 0
  1.2597 +        StrCpy $R0 "true"
  1.2598 +        GoTo outerloop
  1.2599 +      ${EndIf}
  1.2600 +
  1.2601 +      ClearErrors
  1.2602 +
  1.2603 +      Pop $R0
  1.2604 +      Pop $R1
  1.2605 +      Pop $R2
  1.2606 +      Pop $R3
  1.2607 +      Pop $R4
  1.2608 +      Pop $R5
  1.2609 +      Pop $R6
  1.2610 +      Pop $R7
  1.2611 +      Pop $R8
  1.2612 +      Exch $R9
  1.2613 +    FunctionEnd
  1.2614 +
  1.2615 +    !verbose pop
  1.2616 +  !endif
  1.2617 +!macroend
  1.2618 +
  1.2619 +!macro RegCleanMainCall _KEY
  1.2620 +  !verbose push
  1.2621 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2622 +  Push "${_KEY}"
  1.2623 +  Call RegCleanMain
  1.2624 +  !verbose pop
  1.2625 +!macroend
  1.2626 +
  1.2627 +!macro un.RegCleanMainCall _KEY
  1.2628 +  !verbose push
  1.2629 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2630 +  Push "${_KEY}"
  1.2631 +  Call un.RegCleanMain
  1.2632 +  !verbose pop
  1.2633 +!macroend
  1.2634 +
  1.2635 +!macro un.RegCleanMain
  1.2636 +  !ifndef un.RegCleanMain
  1.2637 +    !verbose push
  1.2638 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2639 +    !undef _MOZFUNC_UN
  1.2640 +    !define _MOZFUNC_UN "un."
  1.2641 +
  1.2642 +    !insertmacro RegCleanMain
  1.2643 +
  1.2644 +    !undef _MOZFUNC_UN
  1.2645 +    !define _MOZFUNC_UN
  1.2646 +    !verbose pop
  1.2647 +  !endif
  1.2648 +!macroend
  1.2649 +
  1.2650 +/**
  1.2651 + * Removes all registry keys from \Software\Windows\CurrentVersion\Uninstall
  1.2652 + * that reference this install location in both the 32 bit and 64 bit registry
  1.2653 + * view. This macro uses SHCTX to determine the registry hive so you must call
  1.2654 + * SetShellVarContext first.
  1.2655 + *
  1.2656 + * $R3 = on x64 systems set to 'false' at the beginning of the macro when
  1.2657 + *       enumerating the x86 registry view and set to 'true' when enumerating
  1.2658 + *       the x64 registry view.
  1.2659 + * $R4 = stores the long path to $INSTDIR
  1.2660 + * $R5 = return value from ReadRegStr
  1.2661 + * $R6 = string for the base reg key (e.g. Software\Microsoft\Windows\CurrentVersion\Uninstall)
  1.2662 + * $R7 = return value from EnumRegKey
  1.2663 + * $R8 = counter for EnumRegKey
  1.2664 + * $R9 = return value from the stack from the RemoveQuotesFromPath and GetLongPath macros
  1.2665 + */
  1.2666 +!macro RegCleanUninstall
  1.2667 +
  1.2668 +  !ifndef ${_MOZFUNC_UN}RegCleanUninstall
  1.2669 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.2670 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.2671 +    !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath
  1.2672 +    !undef _MOZFUNC_UN
  1.2673 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.2674 +    !undef _MOZFUNC_UN_TMP
  1.2675 +
  1.2676 +    !verbose push
  1.2677 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2678 +    !define ${_MOZFUNC_UN}RegCleanUninstall "!insertmacro ${_MOZFUNC_UN}RegCleanUninstallCall"
  1.2679 +
  1.2680 +    Function ${_MOZFUNC_UN}RegCleanUninstall
  1.2681 +      Push $R9
  1.2682 +      Push $R8
  1.2683 +      Push $R7
  1.2684 +      Push $R6
  1.2685 +      Push $R5
  1.2686 +      Push $R4
  1.2687 +      Push $R3
  1.2688 +
  1.2689 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R4
  1.2690 +      StrCpy $R6 "Software\Microsoft\Windows\CurrentVersion\Uninstall"
  1.2691 +      StrCpy $R7 ""
  1.2692 +      StrCpy $R8 0
  1.2693 +
  1.2694 +      ${If} ${RunningX64}
  1.2695 +        StrCpy $R3 "false"
  1.2696 +        ; Set the registry to the 32 bit registry for 64 bit installations or to
  1.2697 +        ; the 64 bit registry for 32 bit installations at the beginning so it can
  1.2698 +        ; easily be set back to the correct registry view when finished.
  1.2699 +        !ifdef HAVE_64BIT_OS
  1.2700 +          SetRegView 32
  1.2701 +        !else
  1.2702 +          SetRegView 64
  1.2703 +        !endif
  1.2704 +      ${EndIf}
  1.2705 +
  1.2706 +      loop:
  1.2707 +      EnumRegKey $R7 SHCTX $R6 $R8
  1.2708 +      StrCmp $R7 "" end +1
  1.2709 +      IntOp $R8 $R8 + 1 ; Increment the counter
  1.2710 +      ClearErrors
  1.2711 +      ReadRegStr $R5 SHCTX "$R6\$R7" "InstallLocation"
  1.2712 +      IfErrors loop
  1.2713 +      ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R9
  1.2714 +      ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
  1.2715 +      StrCmp "$R9" "$R4" +1 loop
  1.2716 +      ClearErrors
  1.2717 +      DeleteRegKey SHCTX "$R6\$R7"
  1.2718 +      IfErrors loop +1
  1.2719 +      IntOp $R8 $R8 - 1 ; Decrement the counter on successful deletion
  1.2720 +      GoTo loop
  1.2721 +
  1.2722 +      end:
  1.2723 +      ${If} ${RunningX64}
  1.2724 +      ${AndIf} "$R3" == "false"
  1.2725 +        ; Set the registry to the correct view.
  1.2726 +        !ifdef HAVE_64BIT_OS
  1.2727 +          SetRegView 64
  1.2728 +        !else
  1.2729 +          SetRegView 32
  1.2730 +        !endif
  1.2731 +
  1.2732 +        StrCpy $R7 ""
  1.2733 +        StrCpy $R8 0
  1.2734 +        StrCpy $R3 "true"
  1.2735 +        GoTo loop
  1.2736 +      ${EndIf}
  1.2737 +
  1.2738 +      ClearErrors
  1.2739 +
  1.2740 +      Pop $R3
  1.2741 +      Pop $R4
  1.2742 +      Pop $R5
  1.2743 +      Pop $R6
  1.2744 +      Pop $R7
  1.2745 +      Pop $R8
  1.2746 +      Pop $R9
  1.2747 +    FunctionEnd
  1.2748 +
  1.2749 +    !verbose pop
  1.2750 +  !endif
  1.2751 +!macroend
  1.2752 +
  1.2753 +!macro RegCleanUninstallCall
  1.2754 +  !verbose push
  1.2755 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2756 +  Call RegCleanUninstall
  1.2757 +  !verbose pop
  1.2758 +!macroend
  1.2759 +
  1.2760 +!macro un.RegCleanUninstallCall
  1.2761 +  !verbose push
  1.2762 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2763 +  Call un.RegCleanUninstall
  1.2764 +  !verbose pop
  1.2765 +!macroend
  1.2766 +
  1.2767 +!macro un.RegCleanUninstall
  1.2768 +  !ifndef un.RegCleanUninstall
  1.2769 +    !verbose push
  1.2770 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2771 +    !undef _MOZFUNC_UN
  1.2772 +    !define _MOZFUNC_UN "un."
  1.2773 +
  1.2774 +    !insertmacro RegCleanUninstall
  1.2775 +
  1.2776 +    !undef _MOZFUNC_UN
  1.2777 +    !define _MOZFUNC_UN
  1.2778 +    !verbose pop
  1.2779 +  !endif
  1.2780 +!macroend
  1.2781 +
  1.2782 +/**
  1.2783 + * Removes an application specific handler registry key under Software\Classes
  1.2784 + * for both HKCU and HKLM when its open command refers to this install
  1.2785 + * location or the install location doesn't exist.
  1.2786 + *
  1.2787 + * @param   _HANDLER_NAME
  1.2788 + *          The registry name for the handler.
  1.2789 + *
  1.2790 + * $R7 = stores the long path to the $INSTDIR
  1.2791 + * $R8 = stores the path to the open command's parent directory
  1.2792 + * $R9 = _HANDLER_NAME
  1.2793 + */
  1.2794 +!macro RegCleanAppHandler
  1.2795 +
  1.2796 +  !ifndef ${_MOZFUNC_UN}RegCleanAppHandler
  1.2797 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.2798 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.2799 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.2800 +    !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString
  1.2801 +    !undef _MOZFUNC_UN
  1.2802 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.2803 +    !undef _MOZFUNC_UN_TMP
  1.2804 +
  1.2805 +    !verbose push
  1.2806 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2807 +    !define ${_MOZFUNC_UN}RegCleanAppHandler "!insertmacro ${_MOZFUNC_UN}RegCleanAppHandlerCall"
  1.2808 +
  1.2809 +    Function ${_MOZFUNC_UN}RegCleanAppHandler
  1.2810 +      Exch $R9
  1.2811 +      Push $R8
  1.2812 +      Push $R7
  1.2813 +
  1.2814 +      ClearErrors
  1.2815 +      ReadRegStr $R8 HKCU "Software\Classes\$R9\shell\open\command" ""
  1.2816 +      IfErrors next +1
  1.2817 +      ${${_MOZFUNC_UN}GetPathFromString} "$R8" $R8
  1.2818 +      ${${_MOZFUNC_UN}GetParent} "$R8" $R8
  1.2819 +      IfFileExists "$R8" +3 +1
  1.2820 +      DeleteRegKey HKCU "Software\Classes\$R9"
  1.2821 +      GoTo next
  1.2822 +
  1.2823 +      ${${_MOZFUNC_UN}GetLongPath} "$R8" $R8
  1.2824 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R7
  1.2825 +      StrCmp "$R7" "$R8" +1 next
  1.2826 +      DeleteRegKey HKCU "Software\Classes\$R9"
  1.2827 +
  1.2828 +      next:
  1.2829 +      ReadRegStr $R8 HKLM "Software\Classes\$R9\shell\open\command" ""
  1.2830 +      IfErrors end
  1.2831 +      ${${_MOZFUNC_UN}GetPathFromString} "$R8" $R8
  1.2832 +      ${${_MOZFUNC_UN}GetParent} "$R8" $R8
  1.2833 +      IfFileExists "$R8" +3 +1
  1.2834 +      DeleteRegKey HKLM "Software\Classes\$R9"
  1.2835 +      GoTo end
  1.2836 +
  1.2837 +      ${${_MOZFUNC_UN}GetLongPath} "$R8" $R8
  1.2838 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R7
  1.2839 +      StrCmp "$R7" "$R8" +1 end
  1.2840 +      DeleteRegKey HKLM "Software\Classes\$R9"
  1.2841 +
  1.2842 +      end:
  1.2843 +
  1.2844 +      Pop $R7
  1.2845 +      Pop $R8
  1.2846 +      Exch $R9
  1.2847 +    FunctionEnd
  1.2848 +
  1.2849 +    !verbose pop
  1.2850 +  !endif
  1.2851 +!macroend
  1.2852 +
  1.2853 +!macro RegCleanAppHandlerCall _HANDLER_NAME
  1.2854 +  !verbose push
  1.2855 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2856 +  Push "${_HANDLER_NAME}"
  1.2857 +  Call RegCleanAppHandler
  1.2858 +  !verbose pop
  1.2859 +!macroend
  1.2860 +
  1.2861 +!macro un.RegCleanAppHandlerCall _HANDLER_NAME
  1.2862 +  !verbose push
  1.2863 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2864 +  Push "${_HANDLER_NAME}"
  1.2865 +  Call un.RegCleanAppHandler
  1.2866 +  !verbose pop
  1.2867 +!macroend
  1.2868 +
  1.2869 +!macro un.RegCleanAppHandler
  1.2870 +  !ifndef un.RegCleanAppHandler
  1.2871 +    !verbose push
  1.2872 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2873 +    !undef _MOZFUNC_UN
  1.2874 +    !define _MOZFUNC_UN "un."
  1.2875 +
  1.2876 +    !insertmacro RegCleanAppHandler
  1.2877 +
  1.2878 +    !undef _MOZFUNC_UN
  1.2879 +    !define _MOZFUNC_UN
  1.2880 +    !verbose pop
  1.2881 +  !endif
  1.2882 +!macroend
  1.2883 +
  1.2884 +/**
  1.2885 + * Cleans up the registry for a protocol handler when its open command
  1.2886 + * refers to this install location. For HKCU the registry key is deleted
  1.2887 + * and for HKLM the values set by the application are deleted.
  1.2888 + *
  1.2889 + * @param   _HANDLER_NAME
  1.2890 + *          The registry name for the handler.
  1.2891 + *
  1.2892 + * $R7 = stores the long path to $INSTDIR
  1.2893 + * $R8 = stores the the long path to the open command's parent directory
  1.2894 + * $R9 = _HANDLER_NAME
  1.2895 + */
  1.2896 +!macro un.RegCleanProtocolHandler
  1.2897 +
  1.2898 +  !ifndef un.RegCleanProtocolHandler
  1.2899 +    !insertmacro un.GetLongPath
  1.2900 +    !insertmacro un.GetParent
  1.2901 +    !insertmacro un.GetPathFromString
  1.2902 +
  1.2903 +    !verbose push
  1.2904 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2905 +    !define un.RegCleanProtocolHandler "!insertmacro un.RegCleanProtocolHandlerCall"
  1.2906 +
  1.2907 +    Function un.RegCleanProtocolHandler
  1.2908 +      Exch $R9
  1.2909 +      Push $R8
  1.2910 +      Push $R7
  1.2911 +
  1.2912 +      ReadRegStr $R8 HKCU "Software\Classes\$R9\shell\open\command" ""
  1.2913 +      ${un.GetLongPath} "$INSTDIR" $R7
  1.2914 +
  1.2915 +      StrCmp "$R8" "" next +1
  1.2916 +      ${un.GetPathFromString} "$R8" $R8
  1.2917 +      ${un.GetParent} "$R8" $R8
  1.2918 +      ${un.GetLongPath} "$R8" $R8
  1.2919 +      StrCmp "$R7" "$R8" +1 next
  1.2920 +      DeleteRegKey HKCU "Software\Classes\$R9"
  1.2921 +
  1.2922 +      next:
  1.2923 +      ReadRegStr $R8 HKLM "Software\Classes\$R9\shell\open\command" ""
  1.2924 +      StrCmp "$R8" "" end +1
  1.2925 +      ${un.GetLongPath} "$INSTDIR" $R7
  1.2926 +      ${un.GetPathFromString} "$R8" $R8
  1.2927 +      ${un.GetParent} "$R8" $R8
  1.2928 +      ${un.GetLongPath} "$R8" $R8
  1.2929 +      StrCmp "$R7" "$R8" +1 end
  1.2930 +      DeleteRegValue HKLM "Software\Classes\$R9\DefaultIcon" ""
  1.2931 +      DeleteRegValue HKLM "Software\Classes\$R9\shell\open" ""
  1.2932 +      DeleteRegValue HKLM "Software\Classes\$R9\shell\open\command" ""
  1.2933 +      DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec" ""
  1.2934 +      DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Application" ""
  1.2935 +      DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Topic" ""
  1.2936 +
  1.2937 +      end:
  1.2938 +
  1.2939 +      Pop $R7
  1.2940 +      Pop $R8
  1.2941 +      Exch $R9
  1.2942 +    FunctionEnd
  1.2943 +
  1.2944 +    !verbose pop
  1.2945 +  !endif
  1.2946 +!macroend
  1.2947 +
  1.2948 +!macro un.RegCleanProtocolHandlerCall _HANDLER_NAME
  1.2949 +  !verbose push
  1.2950 +  !verbose ${_MOZFUNC_VERBOSE}
  1.2951 +  Push "${_HANDLER_NAME}"
  1.2952 +  Call un.RegCleanProtocolHandler
  1.2953 +  !verbose pop
  1.2954 +!macroend
  1.2955 +
  1.2956 +/**
  1.2957 + * Cleans up the registry for a file handler when the passed in value equals
  1.2958 + * the default value for the file handler. For HKCU the registry key is deleted
  1.2959 + * and for HKLM the default value is deleted.
  1.2960 + *
  1.2961 + * @param   _HANDLER_NAME
  1.2962 + *          The registry name for the handler.
  1.2963 + * @param   _DEFAULT_VALUE
  1.2964 + *          The value to check for against the handler's default value.
  1.2965 + *
  1.2966 + * $R6 = stores the long path to $INSTDIR
  1.2967 + * $R7 = _DEFAULT_VALUE
  1.2968 + * $R9 = _HANDLER_NAME
  1.2969 + */
  1.2970 +!macro RegCleanFileHandler
  1.2971 +
  1.2972 +  !ifndef ${_MOZFUNC_UN}RegCleanFileHandler
  1.2973 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.2974 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.2975 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.2976 +    !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString
  1.2977 +    !undef _MOZFUNC_UN
  1.2978 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.2979 +    !undef _MOZFUNC_UN_TMP
  1.2980 +
  1.2981 +    !verbose push
  1.2982 +    !verbose ${_MOZFUNC_VERBOSE}
  1.2983 +    !define ${_MOZFUNC_UN}RegCleanFileHandler "!insertmacro ${_MOZFUNC_UN}RegCleanFileHandlerCall"
  1.2984 +
  1.2985 +    Function ${_MOZFUNC_UN}RegCleanFileHandler
  1.2986 +      Exch $R9
  1.2987 +      Exch 1
  1.2988 +      Exch $R8
  1.2989 +      Push $R7
  1.2990 +
  1.2991 +      ReadRegStr $R7 HKCU "Software\Classes\$R9" ""
  1.2992 +      StrCmp "$R7" "$R8" +1 +2
  1.2993 +      DeleteRegKey HKCU "Software\Classes\$R9"
  1.2994 +
  1.2995 +      ReadRegStr $R7 HKLM "Software\Classes\$R9" ""
  1.2996 +      StrCmp "$R7" "$R8" +1 +2
  1.2997 +      DeleteRegValue HKLM "Software\Classes\$R9" ""
  1.2998 +
  1.2999 +      ClearErrors
  1.3000 +
  1.3001 +      Pop $R7
  1.3002 +      Exch $R8
  1.3003 +      Exch 1
  1.3004 +      Exch $R9
  1.3005 +    FunctionEnd
  1.3006 +
  1.3007 +    !verbose pop
  1.3008 +  !endif
  1.3009 +!macroend
  1.3010 +
  1.3011 +!macro RegCleanFileHandlerCall _HANDLER_NAME _DEFAULT_VALUE
  1.3012 +  !verbose push
  1.3013 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3014 +  Push "${_DEFAULT_VALUE}"
  1.3015 +  Push "${_HANDLER_NAME}"
  1.3016 +  Call RegCleanFileHandler
  1.3017 +  !verbose pop
  1.3018 +!macroend
  1.3019 +
  1.3020 +!macro un.RegCleanFileHandlerCall _HANDLER_NAME _DEFAULT_VALUE
  1.3021 +  !verbose push
  1.3022 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3023 +  Push "${_DEFAULT_VALUE}"
  1.3024 +  Push "${_HANDLER_NAME}"
  1.3025 +  Call un.RegCleanFileHandler
  1.3026 +  !verbose pop
  1.3027 +!macroend
  1.3028 +
  1.3029 +!macro un.RegCleanFileHandler
  1.3030 +  !ifndef un.RegCleanFileHandler
  1.3031 +    !verbose push
  1.3032 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3033 +    !undef _MOZFUNC_UN
  1.3034 +    !define _MOZFUNC_UN "un."
  1.3035 +
  1.3036 +    !insertmacro RegCleanFileHandler
  1.3037 +
  1.3038 +    !undef _MOZFUNC_UN
  1.3039 +    !define _MOZFUNC_UN
  1.3040 +    !verbose pop
  1.3041 +  !endif
  1.3042 +!macroend
  1.3043 +
  1.3044 +/**
  1.3045 + * Checks if a handler's open command points to this installation directory.
  1.3046 + * Uses SHCTX to determine the registry hive (e.g. HKLM or HKCU) to check.
  1.3047 + *
  1.3048 + * @param   _HANDLER_NAME
  1.3049 + *          The registry name for the handler.
  1.3050 + * @param   _RESULT
  1.3051 + *          true if it is the handler's open command points to this
  1.3052 + *          installation directory and false if it does not.
  1.3053 + *
  1.3054 + * $R7 = stores the value of the open command and the path macros return values
  1.3055 + * $R8 = stores the handler's registry key name
  1.3056 + * $R9 = _DEFAULT_VALUE and _RESULT
  1.3057 + */
  1.3058 +!macro IsHandlerForInstallDir
  1.3059 +
  1.3060 +  !ifndef ${_MOZFUNC_UN}IsHandlerForInstallDir
  1.3061 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.3062 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.3063 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.3064 +    !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString
  1.3065 +    !undef _MOZFUNC_UN
  1.3066 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.3067 +    !undef _MOZFUNC_UN_TMP
  1.3068 +
  1.3069 +    !verbose push
  1.3070 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3071 +    !define ${_MOZFUNC_UN}IsHandlerForInstallDir "!insertmacro ${_MOZFUNC_UN}IsHandlerForInstallDirCall"
  1.3072 +
  1.3073 +    Function ${_MOZFUNC_UN}IsHandlerForInstallDir
  1.3074 +      Exch $R9
  1.3075 +      Push $R8
  1.3076 +      Push $R7
  1.3077 +
  1.3078 +      StrCpy $R8 "$R9"
  1.3079 +      StrCpy $R9 "false"
  1.3080 +      ReadRegStr $R7 SHCTX "Software\Classes\$R8\shell\open\command" ""
  1.3081 +
  1.3082 +      ${If} $R7 != ""
  1.3083 +        ${GetPathFromString} "$R7" $R7
  1.3084 +        ${GetParent} "$R7" $R7
  1.3085 +        ${GetLongPath} "$R7" $R7
  1.3086 +        ${If} $R7 == $INSTDIR
  1.3087 +          StrCpy $R9 "true"
  1.3088 +        ${EndIf}
  1.3089 +      ${EndIf}
  1.3090 +
  1.3091 +      ClearErrors
  1.3092 +
  1.3093 +      Pop $R7
  1.3094 +      Pop $R8
  1.3095 +      Exch $R9
  1.3096 +    FunctionEnd
  1.3097 +
  1.3098 +    !verbose pop
  1.3099 +  !endif
  1.3100 +!macroend
  1.3101 +
  1.3102 +!macro IsHandlerForInstallDirCall _HANDLER_NAME _RESULT
  1.3103 +  !verbose push
  1.3104 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3105 +  Push "${_HANDLER_NAME}"
  1.3106 +  Call IsHandlerForInstallDir
  1.3107 +  Pop "${_RESULT}"
  1.3108 +  !verbose pop
  1.3109 +!macroend
  1.3110 +
  1.3111 +!macro un.IsHandlerForInstallDirCall _HANDLER_NAME _RESULT
  1.3112 +  !verbose push
  1.3113 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3114 +  Push "${_HANDLER_NAME}"
  1.3115 +  Call un.IsHandlerForInstallDir
  1.3116 +  Pop "${_RESULT}"
  1.3117 +  !verbose pop
  1.3118 +!macroend
  1.3119 +
  1.3120 +!macro un.IsHandlerForInstallDir
  1.3121 +  !ifndef un.IsHandlerForInstallDir
  1.3122 +    !verbose push
  1.3123 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3124 +    !undef _MOZFUNC_UN
  1.3125 +    !define _MOZFUNC_UN "un."
  1.3126 +
  1.3127 +    !insertmacro IsHandlerForInstallDir
  1.3128 +
  1.3129 +    !undef _MOZFUNC_UN
  1.3130 +    !define _MOZFUNC_UN
  1.3131 +    !verbose pop
  1.3132 +  !endif
  1.3133 +!macroend
  1.3134 +
  1.3135 +/**
  1.3136 + * Removes the application's VirtualStore directory if present when the
  1.3137 + * installation directory is a sub-directory of the program files directory.
  1.3138 + *
  1.3139 + * $R4 = $PROGRAMFILES/$PROGRAMFILES64 for CleanVirtualStore_Internal
  1.3140 + * $R5 = various path values.
  1.3141 + * $R6 = length of the long path to $PROGRAMFILES32 or $PROGRAMFILES64
  1.3142 + * $R7 = long path to $PROGRAMFILES32 or $PROGRAMFILES64
  1.3143 + * $R8 = length of the long path to $INSTDIR
  1.3144 + * $R9 = long path to $INSTDIR
  1.3145 + */
  1.3146 +!macro CleanVirtualStore
  1.3147 +
  1.3148 +  !ifndef ${_MOZFUNC_UN}CleanVirtualStore
  1.3149 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.3150 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.3151 +    !undef _MOZFUNC_UN
  1.3152 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.3153 +    !undef _MOZFUNC_UN_TMP
  1.3154 +
  1.3155 +    !verbose push
  1.3156 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3157 +    !define ${_MOZFUNC_UN}CleanVirtualStore "!insertmacro ${_MOZFUNC_UN}CleanVirtualStoreCall"
  1.3158 +
  1.3159 +    Function ${_MOZFUNC_UN}CleanVirtualStore
  1.3160 +      Push $R9
  1.3161 +      Push $R8
  1.3162 +      Push $R7
  1.3163 +      Push $R6
  1.3164 +      Push $R5
  1.3165 +      Push $R4
  1.3166 +
  1.3167 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R9
  1.3168 +      ${If} "$R9" != ""
  1.3169 +        StrLen $R8 "$R9"
  1.3170 +
  1.3171 +        StrCpy $R4 $PROGRAMFILES32
  1.3172 +        Call ${_MOZFUNC_UN}CleanVirtualStore_Internal
  1.3173 +
  1.3174 +        ${If} ${RunningX64}
  1.3175 +          StrCpy $R4 $PROGRAMFILES64
  1.3176 +          Call ${_MOZFUNC_UN}CleanVirtualStore_Internal
  1.3177 +        ${EndIf}
  1.3178 +
  1.3179 +      ${EndIf}
  1.3180 +
  1.3181 +      ClearErrors
  1.3182 +
  1.3183 +      Pop $R4
  1.3184 +      Pop $R5
  1.3185 +      Pop $R6
  1.3186 +      Pop $R7
  1.3187 +      Pop $R8
  1.3188 +      Pop $R9
  1.3189 +    FunctionEnd
  1.3190 +
  1.3191 +    Function ${_MOZFUNC_UN}CleanVirtualStore_Internal
  1.3192 +      ${${_MOZFUNC_UN}GetLongPath} "" $R7
  1.3193 +      ${If} "$R7" != ""
  1.3194 +        StrLen $R6 "$R7"
  1.3195 +        ${If} $R8 < $R6
  1.3196 +          ; Copy from the start of $INSTDIR the length of $PROGRAMFILES64
  1.3197 +          StrCpy $R5 "$R9" $R6
  1.3198 +          ${If} "$R5" == "$R7"
  1.3199 +            ; Remove the drive letter and colon from the $INSTDIR long path
  1.3200 +            StrCpy $R5 "$R9" "" 2
  1.3201 +            StrCpy $R5 "$LOCALAPPDATA\VirtualStore$R5"
  1.3202 +            ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3203 +            ${If} "$R5" != ""
  1.3204 +            ${AndIf} ${FileExists} "$R5"
  1.3205 +              RmDir /r "$R5"
  1.3206 +            ${EndIf}
  1.3207 +          ${EndIf}
  1.3208 +        ${EndIf}
  1.3209 +      ${EndIf}
  1.3210 +    FunctionEnd
  1.3211 +
  1.3212 +    !verbose pop
  1.3213 +  !endif
  1.3214 +!macroend
  1.3215 +
  1.3216 +!macro CleanVirtualStoreCall
  1.3217 +  !verbose push
  1.3218 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3219 +  Call CleanVirtualStore
  1.3220 +  !verbose pop
  1.3221 +!macroend
  1.3222 +
  1.3223 +!macro un.CleanVirtualStoreCall
  1.3224 +  !verbose push
  1.3225 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3226 +  Call un.CleanVirtualStore
  1.3227 +  !verbose pop
  1.3228 +!macroend
  1.3229 +
  1.3230 +!macro un.CleanVirtualStore
  1.3231 +  !ifndef un.CleanVirtualStore
  1.3232 +    !verbose push
  1.3233 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3234 +    !undef _MOZFUNC_UN
  1.3235 +    !define _MOZFUNC_UN "un."
  1.3236 +
  1.3237 +    !insertmacro CleanVirtualStore
  1.3238 +
  1.3239 +    !undef _MOZFUNC_UN
  1.3240 +    !define _MOZFUNC_UN
  1.3241 +    !verbose pop
  1.3242 +  !endif
  1.3243 +!macroend
  1.3244 +
  1.3245 +/**
  1.3246 + * If present removes the updates directory located in the profile's local
  1.3247 + * directory for this installation.
  1.3248 + * This macro is obsolete and should no longer be used. Please see
  1.3249 + * CleanUpdateDirectories.
  1.3250 + *
  1.3251 + * @param   _REL_PROFILE_PATH
  1.3252 + *          The relative path to the profile directory from $LOCALAPPDATA.
  1.3253 + *
  1.3254 + * $R4 = various path values.
  1.3255 + * $R5 = length of the long path to $PROGRAMFILES
  1.3256 + * $R6 = length of the long path to $INSTDIR
  1.3257 + * $R7 = long path to $PROGRAMFILES
  1.3258 + * $R8 = long path to $INSTDIR
  1.3259 + * $R9 = _REL_PROFILE_PATH
  1.3260 + */
  1.3261 +!macro CleanUpdatesDir
  1.3262 +
  1.3263 +  !ifndef ${_MOZFUNC_UN}CleanUpdatesDir
  1.3264 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.3265 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.3266 +    !undef _MOZFUNC_UN
  1.3267 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.3268 +    !undef _MOZFUNC_UN_TMP
  1.3269 +
  1.3270 +    !verbose push
  1.3271 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3272 +    !define ${_MOZFUNC_UN}CleanUpdatesDir "!insertmacro ${_MOZFUNC_UN}CleanUpdatesDirCall"
  1.3273 +
  1.3274 +    Function ${_MOZFUNC_UN}CleanUpdatesDir
  1.3275 +      Exch $R9
  1.3276 +      Push $R8
  1.3277 +      Push $R7
  1.3278 +      Push $R6
  1.3279 +      Push $R5
  1.3280 +      Push $R4
  1.3281 +
  1.3282 +      StrCmp $R9 "" end +1 ; The relative path to the app's profiles is required
  1.3283 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R8
  1.3284 +      StrCmp $R8 "" end +1
  1.3285 +      ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R7
  1.3286 +      StrCmp $R7 "" end +1
  1.3287 +
  1.3288 +      StrLen $R6 "$R8"
  1.3289 +      StrLen $R5 "$R7"
  1.3290 +      ; Only continue If the length of $INSTDIR is greater than the length of
  1.3291 +      ; $PROGRAMFILES
  1.3292 +      IntCmp $R6 $R5 end end +1
  1.3293 +
  1.3294 +      ; Copy from the start of $INSTDIR the length of $PROGRAMFILES
  1.3295 +      StrCpy $R4 "$R8" $R5
  1.3296 +      StrCmp "$R4" "$R7" +1 end ; Check if $INSTDIR is under $PROGRAMFILES
  1.3297 +
  1.3298 +      ; Copy the relative path to $INSTDIR from $PROGRAMFILES
  1.3299 +      StrCpy $R4 "$R8" "" $R5
  1.3300 +
  1.3301 +      ; Concatenate the path to $LOCALAPPDATA the relative profile path and the
  1.3302 +      ; relative path to $INSTDIR from $PROGRAMFILES
  1.3303 +      StrCpy $R4 "$LOCALAPPDATA\$R9$R4"
  1.3304 +      ${${_MOZFUNC_UN}GetLongPath} "$R4" $R4
  1.3305 +      StrCmp $R4 "" end +1
  1.3306 +
  1.3307 +      IfFileExists "$R4\updates" +1 end
  1.3308 +      RmDir /r "$R4"
  1.3309 +
  1.3310 +      end:
  1.3311 +      ClearErrors
  1.3312 +
  1.3313 +      Pop $R4
  1.3314 +      Pop $R5
  1.3315 +      Pop $R6
  1.3316 +      Pop $R7
  1.3317 +      Pop $R8
  1.3318 +      Exch $R9
  1.3319 +    FunctionEnd
  1.3320 +
  1.3321 +    !verbose pop
  1.3322 +  !endif
  1.3323 +!macroend
  1.3324 +
  1.3325 +!macro CleanUpdatesDirCall _REL_PROFILE_PATH
  1.3326 +  !verbose push
  1.3327 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3328 +  Push "${_REL_PROFILE_PATH}"
  1.3329 +  Call CleanUpdatesDir
  1.3330 +  !verbose pop
  1.3331 +!macroend
  1.3332 +
  1.3333 +!macro un.CleanUpdatesDirCall _REL_PROFILE_PATH
  1.3334 +  !verbose push
  1.3335 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3336 +  Push "${_REL_PROFILE_PATH}"
  1.3337 +  Call un.CleanUpdatesDir
  1.3338 +  !verbose pop
  1.3339 +!macroend
  1.3340 +
  1.3341 +!macro un.CleanUpdatesDir
  1.3342 +  !ifndef un.CleanUpdatesDir
  1.3343 +    !verbose push
  1.3344 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3345 +    !undef _MOZFUNC_UN
  1.3346 +    !define _MOZFUNC_UN "un."
  1.3347 +
  1.3348 +    !insertmacro CleanUpdatesDir
  1.3349 +
  1.3350 +    !undef _MOZFUNC_UN
  1.3351 +    !define _MOZFUNC_UN
  1.3352 +    !verbose pop
  1.3353 +  !endif
  1.3354 +!macroend
  1.3355 +
  1.3356 +/**
  1.3357 + * If present removes the updates directory located in the profile's local
  1.3358 + * directory for this installation.
  1.3359 + *
  1.3360 + * @param   _OLD_REL_PATH
  1.3361 + *          The relative path to the profile directory from $LOCALAPPDATA.
  1.3362 + *          Calculated for the old update directory not based on a hash.
  1.3363 + * @param   _NEW_REL_PATH
  1.3364 + *          The relative path to the profile directory from $LOCALAPPDATA.
  1.3365 + *          Calculated for the new update directory based on a hash.
  1.3366 + *
  1.3367 + * $R8 = _NEW_REL_PATH
  1.3368 + * $R7 = _OLD_REL_PATH
  1.3369 + * $R1 = taskBar ID hash located in registry at SOFTWARE\_OLD_REL_PATH\TaskBarIDs
  1.3370 + * $R2 = various path values.
  1.3371 + * $R3 = length of the long path to $PROGRAMFILES
  1.3372 + * $R4 = length of the long path to $INSTDIR
  1.3373 + * $R5 = long path to $PROGRAMFILES
  1.3374 + * $R6 = long path to $INSTDIR
  1.3375 + * $R0 = path to the new update directory built from _NEW_REL_PATH and
  1.3376 + *       the taskbar ID.
  1.3377 + */
  1.3378 +!macro CleanUpdateDirectories
  1.3379 +
  1.3380 +  !ifndef ${_MOZFUNC_UN}CleanUpdateDirectories
  1.3381 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.3382 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.3383 +    !undef _MOZFUNC_UN
  1.3384 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.3385 +    !undef _MOZFUNC_UN_TMP
  1.3386 +
  1.3387 +    !verbose push
  1.3388 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3389 +    !define ${_MOZFUNC_UN}CleanUpdateDirectories "!insertmacro ${_MOZFUNC_UN}CleanUpdateDirectoriesCall"
  1.3390 +
  1.3391 +    Function ${_MOZFUNC_UN}CleanUpdateDirectories
  1.3392 +      Exch $R8
  1.3393 +      Exch 1
  1.3394 +      Exch $R7
  1.3395 +      Push $R6
  1.3396 +      Push $R5
  1.3397 +      Push $R4
  1.3398 +      Push $R3
  1.3399 +      Push $R2
  1.3400 +      Push $R1
  1.3401 +      Push $R0
  1.3402 +
  1.3403 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R6
  1.3404 +      StrLen $R4 "$R6"
  1.3405 +
  1.3406 +      ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R5
  1.3407 +      StrLen $R3 "$R5"
  1.3408 +
  1.3409 +      ${If} $R7 != "" ; _OLD_REL_PATH was passed
  1.3410 +      ${AndIf} $R6 != "" ; We have the install dir path
  1.3411 +      ${AndIf} $R5 != "" ; We the program files path
  1.3412 +      ${AndIf} $R4 > $R3 ; The length of $INSTDIR > the length of $PROGRAMFILES
  1.3413 +
  1.3414 +        ; Copy from the start of $INSTDIR the length of $PROGRAMFILES
  1.3415 +        StrCpy $R2 "$R6" $R3
  1.3416 +
  1.3417 +        ; Check if $INSTDIR is under $PROGRAMFILES
  1.3418 +        ${If} $R2 == $R5
  1.3419 +
  1.3420 +          ; Copy the relative path to $INSTDIR from $PROGRAMFILES
  1.3421 +          StrCpy $R2 "$R6" "" $R3
  1.3422 +
  1.3423 +          ; Concatenate the path $LOCALAPPDATA to the relative profile path and
  1.3424 +          ; the relative path to $INSTDIR from $PROGRAMFILES
  1.3425 +          StrCpy $R2 "$LOCALAPPDATA\$R7$R2"
  1.3426 +          ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2
  1.3427 +
  1.3428 +          ${If} $R2 != ""
  1.3429 +            ; Backup the old update directory logs and delete the directory
  1.3430 +            ${If} ${FileExists} "$R2\updates\last-update.log"
  1.3431 +              Rename "$R2\updates\last-update.log" "$TEMP\moz-update-old-last-update.log"
  1.3432 +            ${EndIf}
  1.3433 +
  1.3434 +            ${If} ${FileExists} "$R2\updates\backup-update.log"
  1.3435 +              Rename "$R2\updates\backup-update.log" "$TEMP\moz-update-old-backup-update.log"
  1.3436 +            ${EndIf}
  1.3437 +
  1.3438 +            ${If} ${FileExists} "$R2\updates"
  1.3439 +                RmDir /r "$R2"
  1.3440 +            ${EndIf}
  1.3441 +          ${EndIf}
  1.3442 +
  1.3443 +          ; Get the taskbar ID hash for this installation path
  1.3444 +          ReadRegStr $R1 HKLM "SOFTWARE\$R7\TaskBarIDs" $R6
  1.3445 +          ${If} $R1 == ""
  1.3446 +            ReadRegStr $R1 HKCU "SOFTWARE\$R7\TaskBarIDs" $R6
  1.3447 +          ${EndIf}
  1.3448 +
  1.3449 +          ; If the taskbar ID hash exists then delete the new update directory
  1.3450 +          ; Backup its logs before deleting it.
  1.3451 +          ${If} $R1 != ""
  1.3452 +            StrCpy $R0 "$LOCALAPPDATA\$R8\$R1"
  1.3453 +
  1.3454 +            ${If} ${FileExists} "$R0\updates\last-update.log"
  1.3455 +              Rename "$R0\updates\last-update.log" "$TEMP\moz-update-new-last-update.log"
  1.3456 +            ${EndIf}
  1.3457 +
  1.3458 +            ${If} ${FileExists} "$R0\updates\backup-update.log"
  1.3459 +              Rename "$R0\updates\backup-update.log" "$TEMP\moz-update-new-backup-update.log"
  1.3460 +            ${EndIf}
  1.3461 +
  1.3462 +            ; Remove the old updates directory
  1.3463 +            ${If} ${FileExists} "$R0\updates"
  1.3464 +              RmDir /r "$R0"
  1.3465 +            ${EndIf}
  1.3466 +          ${EndIf}
  1.3467 +        ${EndIf}
  1.3468 +      ${EndIf}
  1.3469 +
  1.3470 +      ClearErrors
  1.3471 +
  1.3472 +      Pop $R0
  1.3473 +      Pop $R1
  1.3474 +      Pop $R2
  1.3475 +      Pop $R3
  1.3476 +      Pop $R4
  1.3477 +      Pop $R5
  1.3478 +      Pop $R6
  1.3479 +      Exch $R7
  1.3480 +      Exch 1
  1.3481 +      Exch $R8
  1.3482 +    FunctionEnd
  1.3483 +
  1.3484 +    !verbose pop
  1.3485 +  !endif
  1.3486 +!macroend
  1.3487 +
  1.3488 +!macro CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH
  1.3489 +  !verbose push
  1.3490 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3491 +  Push "${_OLD_REL_PATH}"
  1.3492 +  Push "${_NEW_REL_PATH}"
  1.3493 +  Call CleanUpdateDirectories
  1.3494 +  !verbose pop
  1.3495 +!macroend
  1.3496 +
  1.3497 +!macro un.CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH
  1.3498 +  !verbose push
  1.3499 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3500 +  Push "${_OLD_REL_PATH}"
  1.3501 +  Push "${_NEW_REL_PATH}"
  1.3502 +  Call un.CleanUpdateDirectories
  1.3503 +  !verbose pop
  1.3504 +!macroend
  1.3505 +
  1.3506 +!macro un.CleanUpdateDirectories
  1.3507 +  !ifndef un.CleanUpdateDirectories
  1.3508 +    !verbose push
  1.3509 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3510 +    !undef _MOZFUNC_UN
  1.3511 +    !define _MOZFUNC_UN "un."
  1.3512 +
  1.3513 +    !insertmacro CleanUpdateDirectories
  1.3514 +
  1.3515 +    !undef _MOZFUNC_UN
  1.3516 +    !define _MOZFUNC_UN
  1.3517 +    !verbose pop
  1.3518 +  !endif
  1.3519 +!macroend
  1.3520 +
  1.3521 +/**
  1.3522 + * Deletes all relative profiles specified in an application's profiles.ini and
  1.3523 + * performs various other cleanup.
  1.3524 + *
  1.3525 + * @param   _REL_PROFILE_PATH
  1.3526 + *          The relative path to the profile directory.
  1.3527 + *
  1.3528 + * $R6 = value of IsRelative read from profiles.ini
  1.3529 + * $R7 = value of Path to profile read from profiles.ini
  1.3530 + * $R8 = counter for reading profiles (e.g. Profile0, Profile1, etc.)
  1.3531 + * $R9 = _REL_PROFILE_PATH
  1.3532 + */
  1.3533 +!macro DeleteRelativeProfiles
  1.3534 +
  1.3535 +  !ifndef ${_MOZFUNC_UN}DeleteRelativeProfiles
  1.3536 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.3537 +    !insertmacro ${_MOZFUNC_UN_TMP}WordReplace
  1.3538 +    !undef _MOZFUNC_UN
  1.3539 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.3540 +    !undef _MOZFUNC_UN_TMP
  1.3541 +
  1.3542 +    !verbose push
  1.3543 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3544 +    !define ${_MOZFUNC_UN}DeleteRelativeProfiles "!insertmacro ${_MOZFUNC_UN}DeleteRelativeProfilesCall"
  1.3545 +
  1.3546 +    Function ${_MOZFUNC_UN}DeleteRelativeProfiles
  1.3547 +      Exch $R9
  1.3548 +      Push $R8
  1.3549 +      Push $R7
  1.3550 +      Push $R6
  1.3551 +
  1.3552 +      SetShellVarContext current
  1.3553 +      StrCpy $R8 -1
  1.3554 +
  1.3555 +      loop:
  1.3556 +      IntOp $R8 $R8 + 1  ; Increment the counter.
  1.3557 +      ReadINIStr $R7 "$APPDATA\$R9\profiles.ini" "Profile$R8" "Path"
  1.3558 +      IfErrors end +1
  1.3559 +
  1.3560 +      ; Only remove relative profiles
  1.3561 +      ReadINIStr $R6 "$APPDATA\$R9\profiles.ini" "Profile$R8" "IsRelative"
  1.3562 +      StrCmp "$R6" "1" +1 loop
  1.3563 +
  1.3564 +      ; Relative paths in profiles.ini use / as a separator
  1.3565 +      ${${_MOZFUNC_UN}WordReplace} "$R7" "/" "\" "+" $R7
  1.3566 +
  1.3567 +      IfFileExists "$LOCALAPPDATA\$R9\$R7" +1 +2
  1.3568 +      RmDir /r "$LOCALAPPDATA\$R9\$R7"
  1.3569 +      IfFileExists "$APPDATA\$R9\$R7" +1 +2
  1.3570 +      RmDir /r "$APPDATA\$R9\$R7"
  1.3571 +      GoTo loop
  1.3572 +
  1.3573 +      end:
  1.3574 +      ; Remove profiles directory under LOCALAPPDATA (e.g. cache, etc.) since
  1.3575 +      ; they are at times abandoned.
  1.3576 +      RmDir /r "$LOCALAPPDATA\$R9\Profiles"
  1.3577 +      RmDir /r "$APPDATA\$R9\Crash Reports"
  1.3578 +      Delete "$APPDATA\$R9\profiles.ini"
  1.3579 +      Delete "$APPDATA\$R9\console.log"
  1.3580 +      Delete "$APPDATA\$R9\pluginreg.dat"
  1.3581 +      RmDir "$APPDATA\$R9\Profiles"
  1.3582 +      RmDir "$APPDATA\$R9"
  1.3583 +
  1.3584 +      Pop $R6
  1.3585 +      Pop $R7
  1.3586 +      Pop $R8
  1.3587 +      Exch $R9
  1.3588 +    FunctionEnd
  1.3589 +
  1.3590 +    !verbose pop
  1.3591 +  !endif
  1.3592 +!macroend
  1.3593 +
  1.3594 +!macro DeleteRelativeProfilesCall _REL_PROFILE_PATH
  1.3595 +  !verbose push
  1.3596 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3597 +  Push "${_REL_PROFILE_PATH}"
  1.3598 +  Call DeleteRelativeProfiles
  1.3599 +  !verbose pop
  1.3600 +!macroend
  1.3601 +
  1.3602 +!macro un.DeleteRelativeProfilesCall _REL_PROFILE_PATH
  1.3603 +  !verbose push
  1.3604 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3605 +  Push "${_REL_PROFILE_PATH}"
  1.3606 +  Call un.DeleteRelativeProfiles
  1.3607 +  !verbose pop
  1.3608 +!macroend
  1.3609 +
  1.3610 +!macro un.DeleteRelativeProfiles
  1.3611 +  !ifndef un.DeleteRelativeProfiles
  1.3612 +    !verbose push
  1.3613 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3614 +    !undef _MOZFUNC_UN
  1.3615 +    !define _MOZFUNC_UN "un."
  1.3616 +
  1.3617 +    !insertmacro DeleteRelativeProfiles
  1.3618 +
  1.3619 +    !undef _MOZFUNC_UN
  1.3620 +    !define _MOZFUNC_UN
  1.3621 +    !verbose pop
  1.3622 +  !endif
  1.3623 +!macroend
  1.3624 +
  1.3625 +/**
  1.3626 + * Deletes shortcuts and Start Menu directories under Programs as specified by
  1.3627 + * the shortcuts log ini file and on Windows 7 unpins TaskBar and Start Menu
  1.3628 + * shortcuts. The shortcuts will not be deleted if the shortcut target isn't for
  1.3629 + * this install location which is determined by the shortcut having a target of
  1.3630 + * $INSTDIR\${FileMainEXE}. The context (All Users or Current User) of the
  1.3631 + * $DESKTOP and $SMPROGRAMS constants depends on the
  1.3632 + * SetShellVarContext setting and must be set by the caller of this macro. There
  1.3633 + * is no All Users context for $QUICKLAUNCH but this will not cause a problem
  1.3634 + * since the macro will just continue past the $QUICKLAUNCH shortcut deletion
  1.3635 + * section on subsequent calls.
  1.3636 + *
  1.3637 + * The ini file sections must have the following format (the order of the
  1.3638 + * sections in the ini file is not important):
  1.3639 + * [SMPROGRAMS]
  1.3640 + * ; RelativePath is the directory relative from the Start Menu
  1.3641 + * ; Programs directory.
  1.3642 + * RelativePath=Mozilla App
  1.3643 + * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
  1.3644 + * ; on. There must not be a break in the sequence of the numbers.
  1.3645 + * Shortcut1=Mozilla App.lnk
  1.3646 + * Shortcut2=Mozilla App (Safe Mode).lnk
  1.3647 + * [DESKTOP]
  1.3648 + * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
  1.3649 + * ; on. There must not be a break in the sequence of the numbers.
  1.3650 + * Shortcut1=Mozilla App.lnk
  1.3651 + * Shortcut2=Mozilla App (Safe Mode).lnk
  1.3652 + * [QUICKLAUNCH]
  1.3653 + * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
  1.3654 + * ; on. There must not be a break in the sequence of the numbers for the
  1.3655 + * ; suffix.
  1.3656 + * Shortcut1=Mozilla App.lnk
  1.3657 + * Shortcut2=Mozilla App (Safe Mode).lnk
  1.3658 + * [STARTMENU]
  1.3659 + * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
  1.3660 + * ; on. There must not be a break in the sequence of the numbers for the
  1.3661 + * ; suffix.
  1.3662 + * Shortcut1=Mozilla App.lnk
  1.3663 + * Shortcut2=Mozilla App (Safe Mode).lnk
  1.3664 + *
  1.3665 + * $R4 = counter for appending to Shortcut for enumerating the ini file entries
  1.3666 + * $R5 = return value from ShellLink::GetShortCutTarget and
  1.3667 + *       ApplicationID::UninstallPinnedItem
  1.3668 + * $R6 = find handle and the long path to the Start Menu Programs directory
  1.3669 + *       (e.g. $SMPROGRAMS)
  1.3670 + * $R7 = path to the $QUICKLAUNCH\User Pinned directory and the return value
  1.3671 + *       from ReadINIStr for the relative path to the applications directory
  1.3672 + *       under the Start Menu Programs directory and the long path to this
  1.3673 + *       directory
  1.3674 + * $R8 = return filename from FindFirst / FindNext and the return value from
  1.3675 + *       ReadINIStr for enumerating shortcuts
  1.3676 + * $R9 = long path to the shortcuts log ini file
  1.3677 + */
  1.3678 +!macro DeleteShortcuts
  1.3679 +
  1.3680 +  !ifndef ${_MOZFUNC_UN}DeleteShortcuts
  1.3681 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.3682 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.3683 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
  1.3684 +    !undef _MOZFUNC_UN
  1.3685 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.3686 +    !undef _MOZFUNC_UN_TMP
  1.3687 +
  1.3688 +    !verbose push
  1.3689 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3690 +    !define ${_MOZFUNC_UN}DeleteShortcuts "!insertmacro ${_MOZFUNC_UN}DeleteShortcutsCall"
  1.3691 +
  1.3692 +    Function ${_MOZFUNC_UN}DeleteShortcuts
  1.3693 +      Push $R9
  1.3694 +      Push $R8
  1.3695 +      Push $R7
  1.3696 +      Push $R6
  1.3697 +      Push $R5
  1.3698 +      Push $R4
  1.3699 +
  1.3700 +      ${If} ${AtLeastWin7}
  1.3701 +        ; Since shortcuts that are pinned can later be removed without removing
  1.3702 +        ; the pinned shortcut unpin the pinned shortcuts for the application's
  1.3703 +        ; main exe using the pinned shortcuts themselves.
  1.3704 +        StrCpy $R7 "$QUICKLAUNCH\User Pinned"
  1.3705 +
  1.3706 +        ${If} ${FileExists} "$R7\TaskBar"
  1.3707 +          ; Delete TaskBar pinned shortcuts for the application's main exe
  1.3708 +          FindFirst $R6 $R8 "$R7\TaskBar\*.lnk"
  1.3709 +          ${Do}
  1.3710 +            ${If} ${FileExists} "$R7\TaskBar\$R8"
  1.3711 +              ShellLink::GetShortCutTarget "$R7\TaskBar\$R8"
  1.3712 +              Pop $R5
  1.3713 +              ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3714 +              ${If} "$R5" == "$INSTDIR\${FileMainEXE}"
  1.3715 +                ApplicationID::UninstallPinnedItem "$R7\TaskBar\$R8"
  1.3716 +                Pop $R5
  1.3717 +              ${EndIf}
  1.3718 +            ${EndIf}
  1.3719 +            ClearErrors
  1.3720 +            FindNext $R6 $R8
  1.3721 +            ${If} ${Errors}
  1.3722 +              ${ExitDo}
  1.3723 +            ${EndIf}
  1.3724 +          ${Loop}
  1.3725 +          FindClose $R6
  1.3726 +        ${EndIf}
  1.3727 +
  1.3728 +        ${If} ${FileExists} "$R7\StartMenu"
  1.3729 +          ; Delete Start Menu pinned shortcuts for the application's main exe
  1.3730 +          FindFirst $R6 $R8 "$R7\StartMenu\*.lnk"
  1.3731 +          ${Do}
  1.3732 +            ${If} ${FileExists} "$R7\StartMenu\$R8"
  1.3733 +              ShellLink::GetShortCutTarget "$R7\StartMenu\$R8"
  1.3734 +              Pop $R5
  1.3735 +              ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3736 +              ${If} "$R5" == "$INSTDIR\${FileMainEXE}"
  1.3737 +                  ApplicationID::UninstallPinnedItem "$R7\StartMenu\$R8"
  1.3738 +                  Pop $R5
  1.3739 +              ${EndIf}
  1.3740 +            ${EndIf}
  1.3741 +            ClearErrors
  1.3742 +            FindNext $R6 $R8
  1.3743 +            ${If} ${Errors}
  1.3744 +              ${ExitDo}
  1.3745 +            ${EndIf}
  1.3746 +          ${Loop}
  1.3747 +          FindClose $R6
  1.3748 +        ${EndIf}
  1.3749 +      ${EndIf}
  1.3750 +
  1.3751 +      ; Don't call ApplicationID::UninstallPinnedItem since pinned items for
  1.3752 +      ; this application were removed above and removing them below will remove
  1.3753 +      ; the association of side by side installations.
  1.3754 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9
  1.3755 +      ${If} ${FileExists} "$R9"
  1.3756 +        ; Delete Start Menu shortcuts for this application
  1.3757 +        StrCpy $R4 -1
  1.3758 +        ${Do}
  1.3759 +          IntOp $R4 $R4 + 1 ; Increment the counter
  1.3760 +          ClearErrors
  1.3761 +          ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4"
  1.3762 +          ${If} ${Errors}
  1.3763 +            ${ExitDo}
  1.3764 +          ${EndIf}
  1.3765 +
  1.3766 +          ${If} ${FileExists} "$SMPROGRAMS\$R8"
  1.3767 +            ShellLink::GetShortCutTarget "$SMPROGRAMS\$R8"
  1.3768 +            Pop $R5
  1.3769 +            ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3770 +            ${If} "$INSTDIR\${FileMainEXE}" == "$R5"
  1.3771 +              Delete "$SMPROGRAMS\$R8"
  1.3772 +            ${EndIf}
  1.3773 +          ${EndIf}
  1.3774 +        ${Loop}
  1.3775 +
  1.3776 +        ; Delete Quick Launch shortcuts for this application
  1.3777 +        StrCpy $R4 -1
  1.3778 +        ${Do}
  1.3779 +          IntOp $R4 $R4 + 1 ; Increment the counter
  1.3780 +          ClearErrors
  1.3781 +          ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4"
  1.3782 +          ${If} ${Errors}
  1.3783 +            ${ExitDo}
  1.3784 +          ${EndIf}
  1.3785 +
  1.3786 +          ${If} ${FileExists} "$QUICKLAUNCH\$R8"
  1.3787 +            ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8"
  1.3788 +            Pop $R5
  1.3789 +            ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3790 +            ${If} "$INSTDIR\${FileMainEXE}" == "$R5"
  1.3791 +              Delete "$QUICKLAUNCH\$R8"
  1.3792 +            ${EndIf}
  1.3793 +          ${EndIf}
  1.3794 +        ${Loop}
  1.3795 +
  1.3796 +        ; Delete Desktop shortcuts for this application
  1.3797 +        StrCpy $R4 -1
  1.3798 +        ${Do}
  1.3799 +          IntOp $R4 $R4 + 1 ; Increment the counter
  1.3800 +          ClearErrors
  1.3801 +          ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4"
  1.3802 +          ${If} ${Errors}
  1.3803 +            ${ExitDo}
  1.3804 +          ${EndIf}
  1.3805 +
  1.3806 +          ${If} ${FileExists} "$DESKTOP\$R8"
  1.3807 +            ShellLink::GetShortCutTarget "$DESKTOP\$R8"
  1.3808 +            Pop $R5
  1.3809 +            ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3810 +            ${If} "$INSTDIR\${FileMainEXE}" == "$R5"
  1.3811 +              Delete "$DESKTOP\$R8"
  1.3812 +            ${EndIf}
  1.3813 +          ${EndIf}
  1.3814 +        ${Loop}
  1.3815 +
  1.3816 +        ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6
  1.3817 +
  1.3818 +        ; Delete Start Menu Programs shortcuts for this application
  1.3819 +        ClearErrors
  1.3820 +        ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir"
  1.3821 +        ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7
  1.3822 +        ${Unless} "$R7" == ""
  1.3823 +          StrCpy $R4 -1
  1.3824 +          ${Do}
  1.3825 +            IntOp $R4 $R4 + 1 ; Increment the counter
  1.3826 +            ClearErrors
  1.3827 +            ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4"
  1.3828 +            ${If} ${Errors}
  1.3829 +              ${ExitDo}
  1.3830 +            ${EndIf}
  1.3831 +
  1.3832 +            ${If} ${FileExists} "$R7\$R8"
  1.3833 +              ShellLink::GetShortCutTarget "$R7\$R8"
  1.3834 +              Pop $R5
  1.3835 +              ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5
  1.3836 +              ${If} "$INSTDIR\${FileMainEXE}" == "$R5"
  1.3837 +                Delete "$R7\$R8"
  1.3838 +              ${EndIf}
  1.3839 +            ${EndIf}
  1.3840 +          ${Loop}
  1.3841 +
  1.3842 +          ; Delete Start Menu Programs directories for this application
  1.3843 +          ${Do}
  1.3844 +            ClearErrors
  1.3845 +            ${If} "$R6" == "$R7"
  1.3846 +              ${ExitDo}
  1.3847 +            ${EndIf}
  1.3848 +            RmDir "$R7"
  1.3849 +            ${If} ${Errors}
  1.3850 +              ${ExitDo}
  1.3851 +            ${EndIf}
  1.3852 +            ${${_MOZFUNC_UN}GetParent} "$R7" $R7
  1.3853 +          ${Loop}
  1.3854 +        ${EndUnless}
  1.3855 +      ${EndIf}
  1.3856 +
  1.3857 +      ClearErrors
  1.3858 +
  1.3859 +      Pop $R4
  1.3860 +      Pop $R5
  1.3861 +      Pop $R6
  1.3862 +      Pop $R7
  1.3863 +      Pop $R8
  1.3864 +      Pop $R9
  1.3865 +    FunctionEnd
  1.3866 +
  1.3867 +    !verbose pop
  1.3868 +  !endif
  1.3869 +!macroend
  1.3870 +
  1.3871 +!macro DeleteShortcutsCall
  1.3872 +  !verbose push
  1.3873 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3874 +  Call DeleteShortcuts
  1.3875 +  !verbose pop
  1.3876 +!macroend
  1.3877 +
  1.3878 +!macro un.DeleteShortcutsCall
  1.3879 +  !verbose push
  1.3880 +  !verbose ${_MOZFUNC_VERBOSE}
  1.3881 +  Call un.DeleteShortcuts
  1.3882 +  !verbose pop
  1.3883 +!macroend
  1.3884 +
  1.3885 +!macro un.DeleteShortcuts
  1.3886 +  !ifndef un.DeleteShortcuts
  1.3887 +    !verbose push
  1.3888 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3889 +    !undef _MOZFUNC_UN
  1.3890 +    !define _MOZFUNC_UN "un."
  1.3891 +
  1.3892 +    !insertmacro DeleteShortcuts
  1.3893 +
  1.3894 +    !undef _MOZFUNC_UN
  1.3895 +    !define _MOZFUNC_UN
  1.3896 +    !verbose pop
  1.3897 +  !endif
  1.3898 +!macroend
  1.3899 +
  1.3900 +
  1.3901 +################################################################################
  1.3902 +# Macros for parsing and updating the uninstall.log
  1.3903 +
  1.3904 +/**
  1.3905 + * Updates the uninstall.log with new files added by software update.
  1.3906 + *
  1.3907 + * When modifying this macro be aware that LineFind uses all registers except
  1.3908 + * $R0-$R3 and TextCompareNoDetails uses all registers except $R0-$R9 so be
  1.3909 + * cautious. Callers of this macro are not affected.
  1.3910 + */
  1.3911 +!macro UpdateUninstallLog
  1.3912 +
  1.3913 +  !ifndef UpdateUninstallLog
  1.3914 +    !insertmacro FileJoin
  1.3915 +    !insertmacro LineFind
  1.3916 +    !insertmacro TextCompareNoDetails
  1.3917 +    !insertmacro TrimNewLines
  1.3918 +
  1.3919 +    !verbose push
  1.3920 +    !verbose ${_MOZFUNC_VERBOSE}
  1.3921 +    !define UpdateUninstallLog "!insertmacro UpdateUninstallLogCall"
  1.3922 +
  1.3923 +    Function UpdateUninstallLog
  1.3924 +      Push $R3
  1.3925 +      Push $R2
  1.3926 +      Push $R1
  1.3927 +      Push $R0
  1.3928 +
  1.3929 +      ClearErrors
  1.3930 +
  1.3931 +      GetFullPathName $R3 "$INSTDIR\uninstall"
  1.3932 +      ${If} ${FileExists} "$R3\uninstall.update"
  1.3933 +        ${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog"
  1.3934 +
  1.3935 +        GetTempFileName $R2 "$R3"
  1.3936 +        FileOpen $R1 "$R2" w
  1.3937 +        ${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff"
  1.3938 +        FileClose $R1
  1.3939 +
  1.3940 +        IfErrors +2 0
  1.3941 +        ${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log"
  1.3942 +
  1.3943 +        ${DeleteFile} "$R2"
  1.3944 +      ${EndIf}
  1.3945 +
  1.3946 +      ClearErrors
  1.3947 +
  1.3948 +      Pop $R0
  1.3949 +      Pop $R1
  1.3950 +      Pop $R2
  1.3951 +      Pop $R3
  1.3952 +    FunctionEnd
  1.3953 +
  1.3954 +    ; This callback MUST use labels vs. relative line numbers.
  1.3955 +    Function CleanupUpdateLog
  1.3956 +      StrCpy $R2 "$R9" 12
  1.3957 +      StrCmp "$R2" "EXECUTE ADD " +1 skip
  1.3958 +      StrCpy $R9 "$R9" "" 12
  1.3959 +
  1.3960 +      Push $R6
  1.3961 +      Push $R5
  1.3962 +      Push $R4
  1.3963 +      StrCpy $R4 ""         ; Initialize to an empty string.
  1.3964 +      StrCpy $R6 -1         ; Set the counter to -1 so it will start at 0.
  1.3965 +
  1.3966 +      loop:
  1.3967 +      IntOp $R6 $R6 + 1     ; Increment the counter.
  1.3968 +      StrCpy $R5 $R9 1 $R6  ; Starting from the counter copy the next char.
  1.3969 +      StrCmp $R5 "" copy    ; Are there no more chars?
  1.3970 +      StrCmp $R5 "/" +1 +2  ; Is the char a /?
  1.3971 +      StrCpy $R5 "\"        ; Replace the char with a \.
  1.3972 +
  1.3973 +      StrCpy $R4 "$R4$R5"
  1.3974 +      GoTo loop
  1.3975 +
  1.3976 +      copy:
  1.3977 +      StrCpy $R9 "File: \$R4"
  1.3978 +      Pop $R6
  1.3979 +      Pop $R5
  1.3980 +      Pop $R4
  1.3981 +      GoTo end
  1.3982 +
  1.3983 +      skip:
  1.3984 +      StrCpy $0 "SkipWrite"
  1.3985 +
  1.3986 +      end:
  1.3987 +      Push $0
  1.3988 +    FunctionEnd
  1.3989 +
  1.3990 +    Function CreateUpdateDiff
  1.3991 +      ${TrimNewLines} "$9" $9
  1.3992 +      ${If} $9 != ""
  1.3993 +        FileWrite $R1 "$9$\r$\n"
  1.3994 +      ${EndIf}
  1.3995 +
  1.3996 +      Push 0
  1.3997 +    FunctionEnd
  1.3998 +
  1.3999 +    !verbose pop
  1.4000 +  !endif
  1.4001 +!macroend
  1.4002 +
  1.4003 +!macro UpdateUninstallLogCall
  1.4004 +  !verbose push
  1.4005 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4006 +  Call UpdateUninstallLog
  1.4007 +  !verbose pop
  1.4008 +!macroend
  1.4009 +
  1.4010 +/**
  1.4011 + * Copies files from a source directory to a destination directory with logging
  1.4012 + * to the uninstall.log. If any destination files are in use a reboot will be
  1.4013 + * necessary to complete the installation and the reboot flag (see IfRebootFlag
  1.4014 + * in the NSIS documentation).
  1.4015 + *
  1.4016 + * @param   _PATH_TO_SOURCE
  1.4017 + *          Source path to copy the files from. This must not end with a \.
  1.4018 + *
  1.4019 + * @param   _PATH_TO_DESTINATION
  1.4020 + *          Destination path to copy the files to. This must not end with a \.
  1.4021 + *
  1.4022 + * @param   _PREFIX_ERROR_CREATEDIR
  1.4023 + *          Prefix for the directory creation error message. The directory path
  1.4024 + *          will be inserted below this string.
  1.4025 + *
  1.4026 + * @param   _SUFFIX_ERROR_CREATEDIR
  1.4027 + *          Suffix for the directory creation error message. The directory path
  1.4028 + *          will be inserted above this string.
  1.4029 + *
  1.4030 + * $0  = destination file's parent directory used in the create_dir label
  1.4031 + * $R0 = copied value from $R6 (e.g. _PATH_TO_SOURCE)
  1.4032 + * $R1 = copied value from $R7 (e.g. _PATH_TO_DESTINATION)
  1.4033 + * $R2 = string length of the path to source
  1.4034 + * $R3 = relative path from the path to source
  1.4035 + * $R4 = copied value from $R8 (e.g. _PREFIX_ERROR_CREATEDIR)
  1.4036 + * $R5 = copied value from $R9 (e.g. _SUFFIX_ERROR_CREATEDIR)
  1.4037 + * note: the LocateNoDetails macro uses these registers so we copy the values
  1.4038 + *       to other registers.
  1.4039 + * $R6 = initially _PATH_TO_SOURCE and then set to "size" ($R6="" if directory,
  1.4040 + *       $R6="0" if file with /S=)"path\name" in callback
  1.4041 + * $R7 = initially _PATH_TO_DESTINATION and then set to "name" in callback
  1.4042 + * $R8 = initially _PREFIX_ERROR_CREATEDIR and then set to "path" in callback
  1.4043 + * $R9 = initially _SUFFIX_ERROR_CREATEDIR and then set to "path\name" in
  1.4044 + *       callback
  1.4045 + */
  1.4046 +!macro CopyFilesFromDir
  1.4047 +
  1.4048 +  !ifndef CopyFilesFromDir
  1.4049 +    !insertmacro LocateNoDetails
  1.4050 +    !insertmacro OnEndCommon
  1.4051 +    !insertmacro WordReplace
  1.4052 +
  1.4053 +    !verbose push
  1.4054 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4055 +    !define CopyFilesFromDir "!insertmacro CopyFilesFromDirCall"
  1.4056 +
  1.4057 +    Function CopyFilesFromDir
  1.4058 +      Exch $R9
  1.4059 +      Exch 1
  1.4060 +      Exch $R8
  1.4061 +      Exch 2
  1.4062 +      Exch $R7
  1.4063 +      Exch 3
  1.4064 +      Exch $R6
  1.4065 +      Push $R5
  1.4066 +      Push $R4
  1.4067 +      Push $R3
  1.4068 +      Push $R2
  1.4069 +      Push $R1
  1.4070 +      Push $R0
  1.4071 +      Push $0
  1.4072 +
  1.4073 +      StrCpy $R0 "$R6"
  1.4074 +      StrCpy $R1 "$R7"
  1.4075 +      StrCpy $R4 "$R8"
  1.4076 +      StrCpy $R5 "$R9"
  1.4077 +
  1.4078 +      StrLen $R2 "$R0"
  1.4079 +
  1.4080 +      ${LocateNoDetails} "$R0" "/L=FD" "CopyFileCallback"
  1.4081 +
  1.4082 +      Pop $0
  1.4083 +      Pop $R0
  1.4084 +      Pop $R1
  1.4085 +      Pop $R2
  1.4086 +      Pop $R3
  1.4087 +      Pop $R4
  1.4088 +      Pop $R5
  1.4089 +      Exch $R6
  1.4090 +      Exch 3
  1.4091 +      Exch $R7
  1.4092 +      Exch 2
  1.4093 +      Exch $R8
  1.4094 +      Exch 1
  1.4095 +      Exch $R9
  1.4096 +    FunctionEnd
  1.4097 +
  1.4098 +    Function CopyFileCallback
  1.4099 +      StrCpy $R3 $R8 "" $R2 ; $R3 always begins with a \.
  1.4100 +
  1.4101 +      retry:
  1.4102 +      ClearErrors
  1.4103 +      StrCmp $R6 "" +1 copy_file
  1.4104 +      IfFileExists "$R1$R3\$R7" end +1
  1.4105 +      StrCpy $0 "$R1$R3\$R7"
  1.4106 +
  1.4107 +      create_dir:
  1.4108 +      ClearErrors
  1.4109 +      CreateDirectory "$0"
  1.4110 +      IfFileExists "$0" +1 err_create_dir  ; protect against looping.
  1.4111 +      ${LogMsg} "Created Directory: $0"
  1.4112 +      StrCmp $R6 "" end copy_file
  1.4113 +
  1.4114 +      err_create_dir:
  1.4115 +      ${LogMsg} "** ERROR Creating Directory: $0 **"
  1.4116 +      MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$R4$\r$\n$\r$\n$0$\r$\n$\r$\n$R5" IDRETRY retry
  1.4117 +      ${OnEndCommon}
  1.4118 +      Quit
  1.4119 +
  1.4120 +      copy_file:
  1.4121 +      StrCpy $0 "$R1$R3"
  1.4122 +      StrCmp "$0" "$INSTDIR" +2 +1
  1.4123 +      IfFileExists "$0" +1 create_dir
  1.4124 +
  1.4125 +      ClearErrors
  1.4126 +      ${DeleteFile} "$R1$R3\$R7"
  1.4127 +      IfErrors +1 dest_clear
  1.4128 +      ClearErrors
  1.4129 +      Rename "$R1$R3\$R7" "$R1$R3\$R7.moz-delete"
  1.4130 +      IfErrors +1 reboot_delete
  1.4131 +
  1.4132 +      ; file will replace destination file on reboot
  1.4133 +      Rename "$R9" "$R9.moz-upgrade"
  1.4134 +      CopyFiles /SILENT "$R9.moz-upgrade" "$R1$R3"
  1.4135 +      Rename /REBOOTOK "$R1$R3\$R7.moz-upgrade" "$R1$R3\$R7"
  1.4136 +      ${LogMsg} "Copied File: $R1$R3\$R7.moz-upgrade"
  1.4137 +      ${LogMsg} "Delayed Install File (Reboot Required): $R1$R3\$R7"
  1.4138 +      GoTo log_uninstall
  1.4139 +
  1.4140 +      ; file will be deleted on reboot
  1.4141 +      reboot_delete:
  1.4142 +      CopyFiles /SILENT $R9 "$R1$R3"
  1.4143 +      Delete /REBOOTOK "$R1$R3\$R7.moz-delete"
  1.4144 +      ${LogMsg} "Installed File: $R1$R3\$R7"
  1.4145 +      ${LogMsg} "Delayed Delete File (Reboot Required): $R1$R3\$R7.moz-delete"
  1.4146 +      GoTo log_uninstall
  1.4147 +
  1.4148 +      ; destination file doesn't exist - coast is clear
  1.4149 +      dest_clear:
  1.4150 +      CopyFiles /SILENT $R9 "$R1$R3"
  1.4151 +      ${LogMsg} "Installed File: $R1$R3\$R7"
  1.4152 +
  1.4153 +      log_uninstall:
  1.4154 +      ; If the file is installed into the installation directory remove the
  1.4155 +      ; installation directory's path from the file path when writing to the
  1.4156 +      ; uninstall.log so it will be a relative path. This allows the same
  1.4157 +      ; helper.exe to be used with zip builds if we supply an uninstall.log.
  1.4158 +      ${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3
  1.4159 +      ${LogUninstall} "File: $R3"
  1.4160 +
  1.4161 +      end:
  1.4162 +      Push 0
  1.4163 +    FunctionEnd
  1.4164 +
  1.4165 +    !verbose pop
  1.4166 +  !endif
  1.4167 +!macroend
  1.4168 +
  1.4169 +!macro CopyFilesFromDirCall _PATH_TO_SOURCE _PATH_TO_DESTINATION \
  1.4170 +                            _PREFIX_ERROR_CREATEDIR _SUFFIX_ERROR_CREATEDIR
  1.4171 +  !verbose push
  1.4172 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4173 +  Push "${_PATH_TO_SOURCE}"
  1.4174 +  Push "${_PATH_TO_DESTINATION}"
  1.4175 +  Push "${_PREFIX_ERROR_CREATEDIR}"
  1.4176 +  Push "${_SUFFIX_ERROR_CREATEDIR}"
  1.4177 +  Call CopyFilesFromDir
  1.4178 +  !verbose pop
  1.4179 +!macroend
  1.4180 +
  1.4181 +/**
  1.4182 + * Parses the uninstall.log on install to first remove a previous installation's
  1.4183 + * files and then their directories if empty prior to installing.
  1.4184 + *
  1.4185 + * When modifying this macro be aware that LineFind uses all registers except
  1.4186 + * $R0-$R3 so be cautious. Callers of this macro are not affected.
  1.4187 + */
  1.4188 +!macro OnInstallUninstall
  1.4189 +
  1.4190 +  !ifndef OnInstallUninstall
  1.4191 +    !insertmacro GetParent
  1.4192 +    !insertmacro LineFind
  1.4193 +    !insertmacro TrimNewLines
  1.4194 +
  1.4195 +    !verbose push
  1.4196 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4197 +    !define OnInstallUninstall "!insertmacro OnInstallUninstallCall"
  1.4198 +
  1.4199 +    Function OnInstallUninstall
  1.4200 +      Push $R9
  1.4201 +      Push $R8
  1.4202 +      Push $R7
  1.4203 +      Push $R6
  1.4204 +      Push $R5
  1.4205 +      Push $R4
  1.4206 +      Push $R3
  1.4207 +      Push $R2
  1.4208 +      Push $R1
  1.4209 +      Push $R0
  1.4210 +      Push $TmpVal
  1.4211 +
  1.4212 +      IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end
  1.4213 +
  1.4214 +      ${LogHeader} "Removing Previous Installation"
  1.4215 +
  1.4216 +      ; Copy the uninstall log file to a temporary file
  1.4217 +      GetTempFileName $TmpVal
  1.4218 +      CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal"
  1.4219 +
  1.4220 +      ; Delete files
  1.4221 +      ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveFilesCallback"
  1.4222 +
  1.4223 +      ; Remove empty directories
  1.4224 +      ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveDirsCallback"
  1.4225 +
  1.4226 +      ; Delete the temporary uninstall log file
  1.4227 +      Delete /REBOOTOK "$TmpVal"
  1.4228 +
  1.4229 +      ; Delete the uninstall log file
  1.4230 +      Delete "$INSTDIR\uninstall\uninstall.log"
  1.4231 +
  1.4232 +      end:
  1.4233 +      ClearErrors
  1.4234 +
  1.4235 +      Pop $TmpVal
  1.4236 +      Pop $R0
  1.4237 +      Pop $R1
  1.4238 +      Pop $R2
  1.4239 +      Pop $R3
  1.4240 +      Pop $R4
  1.4241 +      Pop $R5
  1.4242 +      Pop $R6
  1.4243 +      Pop $R7
  1.4244 +      Pop $R8
  1.4245 +      Pop $R9
  1.4246 +    FunctionEnd
  1.4247 +
  1.4248 +    Function RemoveFilesCallback
  1.4249 +      ${TrimNewLines} "$R9" $R9
  1.4250 +      StrCpy $R1 "$R9" 5       ; Copy the first five chars
  1.4251 +
  1.4252 +      StrCmp "$R1" "File:" +1 end
  1.4253 +      StrCpy $R9 "$R9" "" 6    ; Copy string starting after the 6th char
  1.4254 +      StrCpy $R0 "$R9" 1       ; Copy the first char
  1.4255 +
  1.4256 +      StrCmp "$R0" "\" +1 end  ; If this isn't a relative path goto end
  1.4257 +      StrCmp "$R9" "\install.log" end +1 ; Skip the install.log
  1.4258 +      StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll
  1.4259 +      StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll
  1.4260 +
  1.4261 +      StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string
  1.4262 +      IfFileExists "$R1" +1 end
  1.4263 +
  1.4264 +      ClearErrors
  1.4265 +      Delete "$R1"
  1.4266 +      ${Unless} ${Errors}
  1.4267 +        ${LogMsg} "Deleted File: $R1"
  1.4268 +        Goto end
  1.4269 +      ${EndUnless}
  1.4270 +
  1.4271 +      ClearErrors
  1.4272 +      Rename "$R1" "$R1.moz-delete"
  1.4273 +      ${Unless} ${Errors}
  1.4274 +        Delete /REBOOTOK "$R1.moz-delete"
  1.4275 +        ${LogMsg} "Delayed Delete File (Reboot Required): $R1.moz-delete"
  1.4276 +        GoTo end
  1.4277 +      ${EndUnless}
  1.4278 +
  1.4279 +      ; Check if the file exists in the source. If it does the new file will
  1.4280 +      ; replace the existing file when the system is rebooted. If it doesn't
  1.4281 +      ; the file will be deleted when the system is rebooted.
  1.4282 +      ${Unless} ${FileExists} "$EXEDIR\core$R9"
  1.4283 +      ${AndUnless}  ${FileExists} "$EXEDIR\optional$R9"
  1.4284 +        Delete /REBOOTOK "$R1"
  1.4285 +        ${LogMsg} "Delayed Delete File (Reboot Required): $R1"
  1.4286 +      ${EndUnless}
  1.4287 +
  1.4288 +      end:
  1.4289 +      ClearErrors
  1.4290 +
  1.4291 +      Push 0
  1.4292 +    FunctionEnd
  1.4293 +
  1.4294 +    ; Using locate will leave file handles open to some of the directories
  1.4295 +    ; which will prevent the deletion of these directories. This parses the
  1.4296 +    ; uninstall.log and uses the file entries to find / remove empty
  1.4297 +    ; directories.
  1.4298 +    Function RemoveDirsCallback
  1.4299 +      ${TrimNewLines} "$R9" $R9
  1.4300 +      StrCpy $R0 "$R9" 5          ; Copy the first five chars
  1.4301 +      StrCmp "$R0" "File:" +1 end
  1.4302 +
  1.4303 +      StrCpy $R9 "$R9" "" 6       ; Copy string starting after the 6th char
  1.4304 +      StrCpy $R0 "$R9" 1          ; Copy the first char
  1.4305 +
  1.4306 +      StrCpy $R1 "$INSTDIR$R9"    ; Copy the install dir path and suffix it with the string
  1.4307 +      StrCmp "$R0" "\" loop end   ; If this isn't a relative path goto end
  1.4308 +
  1.4309 +      loop:
  1.4310 +      ${GetParent} "$R1" $R1         ; Get the parent directory for the path
  1.4311 +      StrCmp "$R1" "$INSTDIR" end +1 ; If the directory is the install dir goto end
  1.4312 +
  1.4313 +      IfFileExists "$R1" +1 loop  ; Only try to remove the dir if it exists
  1.4314 +      ClearErrors
  1.4315 +      RmDir "$R1"     ; Remove the dir
  1.4316 +      IfErrors end +1  ; If we fail there is no use trying to remove its parent dir
  1.4317 +      ${LogMsg} "Deleted Directory: $R1"
  1.4318 +      GoTo loop
  1.4319 +
  1.4320 +      end:
  1.4321 +      ClearErrors
  1.4322 +
  1.4323 +      Push 0
  1.4324 +    FunctionEnd
  1.4325 +
  1.4326 +    !verbose pop
  1.4327 +  !endif
  1.4328 +!macroend
  1.4329 +
  1.4330 +!macro OnInstallUninstallCall
  1.4331 +  !verbose push
  1.4332 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4333 +  Call OnInstallUninstall
  1.4334 +  !verbose pop
  1.4335 +!macroend
  1.4336 +
  1.4337 +/**
  1.4338 + * Parses the uninstall.log for the stub installer on install to first remove a
  1.4339 + * previous installation's files prior to installing.
  1.4340 + *
  1.4341 + * When modifying this macro be aware that LineFind uses all registers except
  1.4342 + * $R0-$R3 so be cautious. Callers of this macro are not affected.
  1.4343 + *
  1.4344 + * @param   _PROGRESSBAR
  1.4345 + *          The progress bar to update using PBM_STEPIT. Can also be "false" if
  1.4346 + *          updating a progressbar isn't needed.
  1.4347 + * @param   _INSTALL_STEP_COUNTER
  1.4348 + *          The install step counter to increment. The variable specified in
  1.4349 + *          this parameter is also updated. Can also be "false" if a counter
  1.4350 + *          isn't needed.
  1.4351 + *
  1.4352 + * $R2 = _INSTALL_STEP_COUNTER
  1.4353 + * $R3 = _PROGRESSBAR
  1.4354 + */
  1.4355 +!macro OnStubInstallUninstall
  1.4356 +
  1.4357 +  !ifndef OnStubInstallUninstall
  1.4358 +    !insertmacro GetParent
  1.4359 +    !insertmacro LineFind
  1.4360 +    !insertmacro TrimNewLines
  1.4361 +
  1.4362 +    !verbose push
  1.4363 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4364 +    !define OnStubInstallUninstall "!insertmacro OnStubInstallUninstallCall"
  1.4365 +
  1.4366 +    Function OnStubInstallUninstall
  1.4367 +      Exch $R2
  1.4368 +      Exch 1
  1.4369 +      Exch $R3
  1.4370 +      Push $R9
  1.4371 +      Push $R8
  1.4372 +      Push $R7
  1.4373 +      Push $R6
  1.4374 +      Push $R5
  1.4375 +      Push $R4
  1.4376 +      Push $R1
  1.4377 +      Push $R0
  1.4378 +      Push $TmpVal
  1.4379 +
  1.4380 +      IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end
  1.4381 +
  1.4382 +      ; Copy the uninstall log file to a temporary file
  1.4383 +      GetTempFileName $TmpVal
  1.4384 +      CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal"
  1.4385 +
  1.4386 +      CreateDirectory "$INSTDIR\${TO_BE_DELETED}"
  1.4387 +
  1.4388 +      ; Delete files
  1.4389 +      ${LineFind} "$TmpVal" "/NUL" "1:-1" "StubRemoveFilesCallback"
  1.4390 +
  1.4391 +      ; Delete the temporary uninstall log file
  1.4392 +      Delete /REBOOTOK "$TmpVal"
  1.4393 +
  1.4394 +      RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}"
  1.4395 +
  1.4396 +      end:
  1.4397 +      ClearErrors
  1.4398 +
  1.4399 +      Pop $TmpVal
  1.4400 +      Pop $R0
  1.4401 +      Pop $R1
  1.4402 +      Pop $R4
  1.4403 +      Pop $R5
  1.4404 +      Pop $R6
  1.4405 +      Pop $R7
  1.4406 +      Pop $R8
  1.4407 +      Pop $R9
  1.4408 +      Exch $R3
  1.4409 +      Exch 1
  1.4410 +      Exch $R2
  1.4411 +    FunctionEnd
  1.4412 +
  1.4413 +    Function StubRemoveFilesCallback
  1.4414 +      ${TrimNewLines} "$R9" $R9
  1.4415 +      StrCpy $R1 "$R9" 5       ; Copy the first five chars
  1.4416 +
  1.4417 +      StrCmp "$R1" "File:" +1 end
  1.4418 +      StrCpy $R9 "$R9" "" 6    ; Copy string starting after the 6th char
  1.4419 +      StrCpy $R0 "$R9" 1       ; Copy the first char
  1.4420 +
  1.4421 +      StrCmp "$R0" "\" +1 end  ; If this isn't a relative path goto end
  1.4422 +      StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll
  1.4423 +      StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll
  1.4424 +
  1.4425 +      StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string
  1.4426 +      IfFileExists "$R1" +1 end
  1.4427 +
  1.4428 +      ${Unless} "$R2" == "false"
  1.4429 +        IntOp $R2 $R2 + 2
  1.4430 +      ${EndIf}
  1.4431 +      ${Unless} "$R3" == "false"
  1.4432 +        SendMessage $R3 ${PBM_STEPIT} 0 0
  1.4433 +        SendMessage $R3 ${PBM_STEPIT} 0 0
  1.4434 +      ${EndIf}
  1.4435 +
  1.4436 +      ClearErrors
  1.4437 +      Delete "$R1"
  1.4438 +      ${Unless} ${Errors}
  1.4439 +        Goto end
  1.4440 +      ${EndUnless}
  1.4441 +
  1.4442 +      GetTempFileName $R0 "$INSTDIR\${TO_BE_DELETED}"
  1.4443 +      Delete "$R0"
  1.4444 +      ClearErrors
  1.4445 +      Rename "$R1" "$R0"
  1.4446 +      ${If} ${Errors}
  1.4447 +        Delete /REBOOTOK "$R1"
  1.4448 +      ${EndUnless}
  1.4449 +
  1.4450 +      end:
  1.4451 +      ClearErrors
  1.4452 +
  1.4453 +      Push 0
  1.4454 +    FunctionEnd
  1.4455 +
  1.4456 +    !verbose pop
  1.4457 +  !endif
  1.4458 +!macroend
  1.4459 +
  1.4460 +!macro OnStubInstallUninstallCall _PROGRESSBAR _INSTALL_STEP_COUNTER
  1.4461 +  !verbose push
  1.4462 +  Push "${_PROGRESSBAR}"
  1.4463 +  Push "${_INSTALL_STEP_COUNTER}"
  1.4464 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4465 +  Call OnStubInstallUninstall
  1.4466 +  Pop ${_INSTALL_STEP_COUNTER}
  1.4467 +  !verbose pop
  1.4468 +!macroend
  1.4469 +
  1.4470 +/**
  1.4471 + * Parses the uninstall.log to unregister dll's, remove files, and remove
  1.4472 + * empty directories for this installation.
  1.4473 + *
  1.4474 + * When modifying this macro be aware that LineFind uses all registers except
  1.4475 + * $R0-$R3 so be cautious. Callers of this macro are not affected.
  1.4476 + */
  1.4477 +!macro un.ParseUninstallLog
  1.4478 +
  1.4479 +  !ifndef un.ParseUninstallLog
  1.4480 +    !insertmacro un.GetParent
  1.4481 +    !insertmacro un.LineFind
  1.4482 +    !insertmacro un.TrimNewLines
  1.4483 +
  1.4484 +    !verbose push
  1.4485 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4486 +    !define un.ParseUninstallLog "!insertmacro un.ParseUninstallLogCall"
  1.4487 +
  1.4488 +    Function un.ParseUninstallLog
  1.4489 +      Push $R9
  1.4490 +      Push $R8
  1.4491 +      Push $R7
  1.4492 +      Push $R6
  1.4493 +      Push $R5
  1.4494 +      Push $R4
  1.4495 +      Push $R3
  1.4496 +      Push $R2
  1.4497 +      Push $R1
  1.4498 +      Push $R0
  1.4499 +      Push $TmpVal
  1.4500 +
  1.4501 +      IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end
  1.4502 +
  1.4503 +      ; Copy the uninstall log file to a temporary file
  1.4504 +      GetTempFileName $TmpVal
  1.4505 +      CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal"
  1.4506 +
  1.4507 +      ; Unregister DLL's
  1.4508 +      ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.UnRegDLLsCallback"
  1.4509 +
  1.4510 +      ; Delete files
  1.4511 +      ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveFilesCallback"
  1.4512 +
  1.4513 +      ; Remove empty directories
  1.4514 +      ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveDirsCallback"
  1.4515 +
  1.4516 +      ; Delete the temporary uninstall log file
  1.4517 +      Delete /REBOOTOK "$TmpVal"
  1.4518 +
  1.4519 +      end:
  1.4520 +
  1.4521 +      Pop $TmpVal
  1.4522 +      Pop $R0
  1.4523 +      Pop $R1
  1.4524 +      Pop $R2
  1.4525 +      Pop $R3
  1.4526 +      Pop $R4
  1.4527 +      Pop $R5
  1.4528 +      Pop $R6
  1.4529 +      Pop $R7
  1.4530 +      Pop $R8
  1.4531 +      Pop $R9
  1.4532 +    FunctionEnd
  1.4533 +
  1.4534 +    Function un.RemoveFilesCallback
  1.4535 +      ${un.TrimNewLines} "$R9" $R9
  1.4536 +      StrCpy $R1 "$R9" 5
  1.4537 +
  1.4538 +      StrCmp "$R1" "File:" +1 end
  1.4539 +      StrCpy $R9 "$R9" "" 6
  1.4540 +      StrCpy $R0 "$R9" 1
  1.4541 +
  1.4542 +      StrCpy $R1 "$INSTDIR$R9"
  1.4543 +      StrCmp "$R0" "\" +2 +1
  1.4544 +      StrCpy $R1 "$R9"
  1.4545 +
  1.4546 +      IfFileExists "$R1" +1 end
  1.4547 +      Delete "$R1"
  1.4548 +      IfErrors +1 end
  1.4549 +      ClearErrors
  1.4550 +      Rename "$R1" "$R1.moz-delete"
  1.4551 +      IfErrors +1 +3
  1.4552 +      Delete /REBOOTOK "$R1"
  1.4553 +      GoTo end
  1.4554 +
  1.4555 +      Delete /REBOOTOK "$R1.moz-delete"
  1.4556 +
  1.4557 +      end:
  1.4558 +      ClearErrors
  1.4559 +
  1.4560 +      Push 0
  1.4561 +    FunctionEnd
  1.4562 +
  1.4563 +    Function un.UnRegDLLsCallback
  1.4564 +      ${un.TrimNewLines} "$R9" $R9
  1.4565 +      StrCpy $R1 "$R9" 7
  1.4566 +
  1.4567 +      StrCmp $R1 "DLLReg:" +1 end
  1.4568 +      StrCpy $R9 "$R9" "" 8
  1.4569 +      StrCpy $R0 "$R9" 1
  1.4570 +
  1.4571 +      StrCpy $R1 "$INSTDIR$R9"
  1.4572 +      StrCmp $R0 "\" +2 +1
  1.4573 +      StrCpy $R1 "$R9"
  1.4574 +
  1.4575 +      ${UnregisterDLL} $R1
  1.4576 +
  1.4577 +      end:
  1.4578 +      ClearErrors
  1.4579 +
  1.4580 +      Push 0
  1.4581 +    FunctionEnd
  1.4582 +
  1.4583 +    ; Using locate will leave file handles open to some of the directories
  1.4584 +    ; which will prevent the deletion of these directories. This parses the
  1.4585 +    ; uninstall.log and uses the file entries to find / remove empty
  1.4586 +    ; directories.
  1.4587 +    Function un.RemoveDirsCallback
  1.4588 +      ${un.TrimNewLines} "$R9" $R9
  1.4589 +      StrCpy $R0 "$R9" 5          ; Copy the first five chars
  1.4590 +      StrCmp "$R0" "File:" +1 end
  1.4591 +
  1.4592 +      StrCpy $R9 "$R9" "" 6       ; Copy string starting after the 6th char
  1.4593 +      StrCpy $R0 "$R9" 1          ; Copy the first char
  1.4594 +
  1.4595 +      StrCpy $R1 "$INSTDIR$R9"    ; Copy the install dir path and suffix it with the string
  1.4596 +      StrCmp "$R0" "\" loop       ; If this is a relative path goto the loop
  1.4597 +      StrCpy $R1 "$R9"            ; Already a full path so copy the string
  1.4598 +
  1.4599 +      loop:
  1.4600 +      ${un.GetParent} "$R1" $R1   ; Get the parent directory for the path
  1.4601 +      StrCmp "$R1" "$INSTDIR" end ; If the directory is the install dir goto end
  1.4602 +
  1.4603 +      ; We only try to remove empty directories but the Desktop, StartMenu, and
  1.4604 +      ; QuickLaunch directories can be empty so guard against removing them.
  1.4605 +      SetShellVarContext all          ; Set context to all users
  1.4606 +      StrCmp "$R1" "$DESKTOP" end     ; All users desktop
  1.4607 +      StrCmp "$R1" "$STARTMENU" end   ; All users start menu
  1.4608 +
  1.4609 +      SetShellVarContext current      ; Set context to all users
  1.4610 +      StrCmp "$R1" "$DESKTOP" end     ; Current user desktop
  1.4611 +      StrCmp "$R1" "$STARTMENU" end   ; Current user start menu
  1.4612 +      StrCmp "$R1" "$QUICKLAUNCH" end ; Current user quick launch
  1.4613 +
  1.4614 +      IfFileExists "$R1" +1 +3  ; Only try to remove the dir if it exists
  1.4615 +      ClearErrors
  1.4616 +      RmDir "$R1"    ; Remove the dir
  1.4617 +      IfErrors end   ; If we fail there is no use trying to remove its parent dir
  1.4618 +
  1.4619 +      StrCmp "$R0" "\" loop end  ; Only loop when the path is relative to the install dir
  1.4620 +
  1.4621 +      end:
  1.4622 +      ClearErrors
  1.4623 +
  1.4624 +      Push 0
  1.4625 +    FunctionEnd
  1.4626 +
  1.4627 +    !verbose pop
  1.4628 +  !endif
  1.4629 +!macroend
  1.4630 +
  1.4631 +!macro un.ParseUninstallLogCall
  1.4632 +  !verbose push
  1.4633 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4634 +  Call un.ParseUninstallLog
  1.4635 +  !verbose pop
  1.4636 +!macroend
  1.4637 +
  1.4638 +/**
  1.4639 + * Finds a valid Start Menu shortcut in the uninstall log and returns the
  1.4640 + * relative path from the Start Menu's Programs directory to the shortcut's
  1.4641 + * directory.
  1.4642 + *
  1.4643 + * When modifying this macro be aware that LineFind uses all registers except
  1.4644 + * $R0-$R3 so be cautious. Callers of this macro are not affected.
  1.4645 + *
  1.4646 + * @return  _REL_PATH_TO_DIR
  1.4647 + *          The relative path to the application's Start Menu directory from the
  1.4648 + *          Start Menu's Programs directory.
  1.4649 + */
  1.4650 +!macro FindSMProgramsDir
  1.4651 +
  1.4652 +  !ifndef FindSMProgramsDir
  1.4653 +    !insertmacro GetParent
  1.4654 +    !insertmacro LineFind
  1.4655 +    !insertmacro TrimNewLines
  1.4656 +
  1.4657 +    !verbose push
  1.4658 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4659 +    !define FindSMProgramsDir "!insertmacro FindSMProgramsDirCall"
  1.4660 +
  1.4661 +    Function FindSMProgramsDir
  1.4662 +      Exch $R3
  1.4663 +      Push $R2
  1.4664 +      Push $R1
  1.4665 +      Push $R0
  1.4666 +
  1.4667 +      StrCpy $R3 ""
  1.4668 +      ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log"
  1.4669 +        ${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath"
  1.4670 +      ${EndIf}
  1.4671 +      ClearErrors
  1.4672 +
  1.4673 +      Pop $R0
  1.4674 +      Pop $R1
  1.4675 +      Pop $R2
  1.4676 +      Exch $R3
  1.4677 +    FunctionEnd
  1.4678 +
  1.4679 +    ; This callback MUST use labels vs. relative line numbers.
  1.4680 +    Function FindSMProgramsDirRelPath
  1.4681 +      Push 0
  1.4682 +      ${TrimNewLines} "$R9" $R9
  1.4683 +      StrCpy $R4 "$R9" 5
  1.4684 +
  1.4685 +      StrCmp "$R4" "File:" +1 end_FindSMProgramsDirRelPath
  1.4686 +      StrCpy $R9 "$R9" "" 6
  1.4687 +      StrCpy $R4 "$R9" 1
  1.4688 +
  1.4689 +      StrCmp "$R4" "\" end_FindSMProgramsDirRelPath +1
  1.4690 +
  1.4691 +      SetShellVarContext all
  1.4692 +      ${GetLongPath} "$SMPROGRAMS" $R4
  1.4693 +      StrLen $R2 "$R4"
  1.4694 +      StrCpy $R1 "$R9" $R2
  1.4695 +      StrCmp "$R1" "$R4" +1 end_FindSMProgramsDirRelPath
  1.4696 +      IfFileExists "$R9" +1 end_FindSMProgramsDirRelPath
  1.4697 +      ShellLink::GetShortCutTarget "$R9"
  1.4698 +      Pop $R0
  1.4699 +      StrCmp "$INSTDIR\${FileMainEXE}" "$R0" +1 end_FindSMProgramsDirRelPath
  1.4700 +      ${GetParent} "$R9" $R3
  1.4701 +      IntOp $R2 $R2 + 1
  1.4702 +      StrCpy $R3 "$R3" "" $R2
  1.4703 +
  1.4704 +      Pop $R4             ; Remove the previously pushed 0 from the stack and
  1.4705 +      push "StopLineFind" ; push StopLineFind to stop finding more lines.
  1.4706 +
  1.4707 +      end_FindSMProgramsDirRelPath:
  1.4708 +      ClearErrors
  1.4709 +
  1.4710 +    FunctionEnd
  1.4711 +
  1.4712 +    !verbose pop
  1.4713 +  !endif
  1.4714 +!macroend
  1.4715 +
  1.4716 +!macro FindSMProgramsDirCall _REL_PATH_TO_DIR
  1.4717 +  !verbose push
  1.4718 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4719 +  Call FindSMProgramsDir
  1.4720 +  Pop ${_REL_PATH_TO_DIR}
  1.4721 +  !verbose pop
  1.4722 +!macroend
  1.4723 +
  1.4724 +
  1.4725 +################################################################################
  1.4726 +# Macros for custom branding
  1.4727 +
  1.4728 +/**
  1.4729 + * Sets BrandFullName and / or BrandShortName to values provided in the specified
  1.4730 + * ini file and defaults to BrandShortName and BrandFullName as defined in
  1.4731 + * branding.nsi when the associated ini file entry is not specified.
  1.4732 + *
  1.4733 + * ini file format:
  1.4734 + * [Branding]
  1.4735 + * BrandFullName=Custom Full Name
  1.4736 + * BrandShortName=Custom Short Name
  1.4737 + *
  1.4738 + * @param   _PATH_TO_INI
  1.4739 + *          Path to the ini file.
  1.4740 + *
  1.4741 + * $R6 = return value from ReadINIStr
  1.4742 + * $R7 = stores BrandShortName
  1.4743 + * $R8 = stores BrandFullName
  1.4744 + * $R9 = _PATH_TO_INI
  1.4745 + */
  1.4746 +!macro SetBrandNameVars
  1.4747 +
  1.4748 +  !ifndef ${_MOZFUNC_UN}SetBrandNameVars
  1.4749 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.4750 +    !insertmacro ${_MOZFUNC_UN_TMP}WordReplace
  1.4751 +    !undef _MOZFUNC_UN
  1.4752 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.4753 +    !undef _MOZFUNC_UN_TMP
  1.4754 +
  1.4755 +    ; Prevent declaring vars twice when the SetBrandNameVars macro is
  1.4756 +    ; inserted into both the installer and uninstaller.
  1.4757 +    !ifndef SetBrandNameVars
  1.4758 +      Var BrandFullName
  1.4759 +      Var BrandFullNameDA
  1.4760 +      Var BrandShortName
  1.4761 +    !endif
  1.4762 +
  1.4763 +    !verbose push
  1.4764 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4765 +    !define ${_MOZFUNC_UN}SetBrandNameVars "!insertmacro ${_MOZFUNC_UN}SetBrandNameVarsCall"
  1.4766 +
  1.4767 +    Function ${_MOZFUNC_UN}SetBrandNameVars
  1.4768 +      Exch $R9
  1.4769 +      Push $R8
  1.4770 +      Push $R7
  1.4771 +      Push $R6
  1.4772 +
  1.4773 +      StrCpy $R8 "${BrandFullName}"
  1.4774 +      StrCpy $R7 "${BrandShortName}"
  1.4775 +
  1.4776 +      IfFileExists "$R9" +1 finish
  1.4777 +
  1.4778 +      ClearErrors
  1.4779 +      ReadINIStr $R6 $R9 "Branding" "BrandFullName"
  1.4780 +      IfErrors +2 +1
  1.4781 +      StrCpy $R8 "$R6"
  1.4782 +
  1.4783 +      ClearErrors
  1.4784 +      ReadINIStr $R6 $R9 "Branding" "BrandShortName"
  1.4785 +      IfErrors +2 +1
  1.4786 +      StrCpy $R7 "$R6"
  1.4787 +
  1.4788 +      finish:
  1.4789 +      StrCpy $BrandFullName "$R8"
  1.4790 +      ${${_MOZFUNC_UN}WordReplace} "$R8" "&" "&&" "+" $R8
  1.4791 +      StrCpy $BrandFullNameDA "$R8"
  1.4792 +      StrCpy $BrandShortName "$R7"
  1.4793 +
  1.4794 +      Pop $R6
  1.4795 +      Pop $R7
  1.4796 +      Pop $R8
  1.4797 +      Exch $R9
  1.4798 +    FunctionEnd
  1.4799 +
  1.4800 +    !verbose pop
  1.4801 +  !endif
  1.4802 +!macroend
  1.4803 +
  1.4804 +!macro SetBrandNameVarsCall _PATH_TO_INI
  1.4805 +  !verbose push
  1.4806 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4807 +  Push "${_PATH_TO_INI}"
  1.4808 +  Call SetBrandNameVars
  1.4809 +  !verbose pop
  1.4810 +!macroend
  1.4811 +
  1.4812 +!macro un.SetBrandNameVarsCall _PATH_TO_INI
  1.4813 +  !verbose push
  1.4814 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4815 +  Push "${_PATH_TO_INI}"
  1.4816 +  Call un.SetBrandNameVars
  1.4817 +  !verbose pop
  1.4818 +!macroend
  1.4819 +
  1.4820 +!macro un.SetBrandNameVars
  1.4821 +  !ifndef un.SetBrandNameVars
  1.4822 +    !verbose push
  1.4823 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4824 +    !undef _MOZFUNC_UN
  1.4825 +    !define _MOZFUNC_UN "un."
  1.4826 +
  1.4827 +    !insertmacro SetBrandNameVars
  1.4828 +
  1.4829 +    !undef _MOZFUNC_UN
  1.4830 +    !define _MOZFUNC_UN
  1.4831 +    !verbose pop
  1.4832 +  !endif
  1.4833 +!macroend
  1.4834 +
  1.4835 +/**
  1.4836 + * Replaces the wizard's header image with the one specified.
  1.4837 + *
  1.4838 + * @param   _PATH_TO_IMAGE
  1.4839 + *          Fully qualified path to the bitmap to use for the header image.
  1.4840 + *
  1.4841 + * $R8 = hwnd for the control returned from GetDlgItem.
  1.4842 + * $R9 = _PATH_TO_IMAGE
  1.4843 + */
  1.4844 +!macro ChangeMUIHeaderImage
  1.4845 +
  1.4846 +  !ifndef ${_MOZFUNC_UN}ChangeMUIHeaderImage
  1.4847 +    Var hHeaderBitmap
  1.4848 +
  1.4849 +    !verbose push
  1.4850 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4851 +    !define ${_MOZFUNC_UN}ChangeMUIHeaderImage "!insertmacro ${_MOZFUNC_UN}ChangeMUIHeaderImageCall"
  1.4852 +
  1.4853 +    Function ${_MOZFUNC_UN}ChangeMUIHeaderImage
  1.4854 +      Exch $R9
  1.4855 +      Push $R8
  1.4856 +
  1.4857 +      GetDlgItem $R8 $HWNDPARENT 1046
  1.4858 +      System::Call 'user32::LoadImageW(i 0, w "$R9", i 0, i 0, i 0, i 0x0010|0x2000) i.s'
  1.4859 +      Pop $hHeaderBitmap
  1.4860 +      SendMessage $R8 ${STM_SETIMAGE} 0 $hHeaderBitmap
  1.4861 +      ; There is no way to specify a show function for a custom page so hide
  1.4862 +      ; and then show the control to force the bitmap to redraw.
  1.4863 +      ShowWindow $R8 ${SW_HIDE}
  1.4864 +      ShowWindow $R8 ${SW_SHOW}
  1.4865 +
  1.4866 +      Pop $R8
  1.4867 +      Exch $R9
  1.4868 +    FunctionEnd
  1.4869 +
  1.4870 +    !verbose pop
  1.4871 +  !endif
  1.4872 +!macroend
  1.4873 +
  1.4874 +!macro ChangeMUIHeaderImageCall _PATH_TO_IMAGE
  1.4875 +  !verbose push
  1.4876 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4877 +  Push "${_PATH_TO_IMAGE}"
  1.4878 +  Call ChangeMUIHeaderImage
  1.4879 +  !verbose pop
  1.4880 +!macroend
  1.4881 +
  1.4882 +!macro un.ChangeMUIHeaderImageCall _PATH_TO_IMAGE
  1.4883 +  !verbose push
  1.4884 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4885 +  Push "${_PATH_TO_IMAGE}"
  1.4886 +  Call un.ChangeMUIHeaderImage
  1.4887 +  !verbose pop
  1.4888 +!macroend
  1.4889 +
  1.4890 +!macro un.ChangeMUIHeaderImage
  1.4891 +  !ifndef un.ChangeMUIHeaderImage
  1.4892 +    !verbose push
  1.4893 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4894 +    !undef _MOZFUNC_UN
  1.4895 +    !define _MOZFUNC_UN "un."
  1.4896 +
  1.4897 +    !insertmacro ChangeMUIHeaderImage
  1.4898 +
  1.4899 +    !undef _MOZFUNC_UN
  1.4900 +    !define _MOZFUNC_UN
  1.4901 +    !verbose pop
  1.4902 +  !endif
  1.4903 +!macroend
  1.4904 +
  1.4905 +
  1.4906 +################################################################################
  1.4907 +# User interface callback helper defines and macros
  1.4908 +
  1.4909 +/* Install type defines */
  1.4910 +!ifndef INSTALLTYPE_BASIC
  1.4911 +  !define INSTALLTYPE_BASIC     1
  1.4912 +!endif
  1.4913 +
  1.4914 +!ifndef INSTALLTYPE_CUSTOM
  1.4915 +  !define INSTALLTYPE_CUSTOM    2
  1.4916 +!endif
  1.4917 +
  1.4918 +/**
  1.4919 + * Checks whether to display the current page (e.g. if not performing a custom
  1.4920 + * install don't display the custom pages).
  1.4921 + */
  1.4922 +!macro CheckCustomCommon
  1.4923 +
  1.4924 +  !ifndef CheckCustomCommon
  1.4925 +    !verbose push
  1.4926 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4927 +    !define CheckCustomCommon "!insertmacro CheckCustomCommonCall"
  1.4928 +
  1.4929 +    Function CheckCustomCommon
  1.4930 +
  1.4931 +      ; Abort if not a custom install
  1.4932 +      IntCmp $InstallType ${INSTALLTYPE_CUSTOM} +2 +1 +1
  1.4933 +      Abort
  1.4934 +
  1.4935 +    FunctionEnd
  1.4936 +
  1.4937 +    !verbose pop
  1.4938 +  !endif
  1.4939 +!macroend
  1.4940 +
  1.4941 +!macro CheckCustomCommonCall
  1.4942 +  !verbose push
  1.4943 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4944 +  Call CheckCustomCommon
  1.4945 +  !verbose pop
  1.4946 +!macroend
  1.4947 +
  1.4948 +/**
  1.4949 + * Unloads dll's and releases references when the installer and uninstaller
  1.4950 + * exit.
  1.4951 + */
  1.4952 +!macro OnEndCommon
  1.4953 +
  1.4954 +  !ifndef ${_MOZFUNC_UN}OnEndCommon
  1.4955 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.4956 +    !insertmacro ${_MOZFUNC_UN_TMP}UnloadUAC
  1.4957 +    !undef _MOZFUNC_UN
  1.4958 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.4959 +    !undef _MOZFUNC_UN_TMP
  1.4960 +
  1.4961 +    !verbose push
  1.4962 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4963 +    !define ${_MOZFUNC_UN}OnEndCommon "!insertmacro ${_MOZFUNC_UN}OnEndCommonCall"
  1.4964 +
  1.4965 +    Function ${_MOZFUNC_UN}OnEndCommon
  1.4966 +
  1.4967 +      ${${_MOZFUNC_UN}UnloadUAC}
  1.4968 +      StrCmp $hHeaderBitmap "" +3 +1
  1.4969 +      System::Call "gdi32::DeleteObject(i s)" $hHeaderBitmap
  1.4970 +      StrCpy $hHeaderBitmap ""
  1.4971 +
  1.4972 +      System::Free 0
  1.4973 +
  1.4974 +    FunctionEnd
  1.4975 +
  1.4976 +    !verbose pop
  1.4977 +  !endif
  1.4978 +!macroend
  1.4979 +
  1.4980 +!macro OnEndCommonCall
  1.4981 +  !verbose push
  1.4982 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4983 +  Call OnEndCommon
  1.4984 +  !verbose pop
  1.4985 +!macroend
  1.4986 +
  1.4987 +!macro un.OnEndCommonCall
  1.4988 +  !verbose push
  1.4989 +  !verbose ${_MOZFUNC_VERBOSE}
  1.4990 +  Call un.OnEndCommon
  1.4991 +  !verbose pop
  1.4992 +!macroend
  1.4993 +
  1.4994 +!macro un.OnEndCommon
  1.4995 +  !ifndef un.OnEndCommon
  1.4996 +    !verbose push
  1.4997 +    !verbose ${_MOZFUNC_VERBOSE}
  1.4998 +    !undef _MOZFUNC_UN
  1.4999 +    !define _MOZFUNC_UN "un."
  1.5000 +
  1.5001 +    !insertmacro OnEndCommon
  1.5002 +
  1.5003 +    !undef _MOZFUNC_UN
  1.5004 +    !define _MOZFUNC_UN
  1.5005 +    !verbose pop
  1.5006 +  !endif
  1.5007 +!macroend
  1.5008 +
  1.5009 +/**
  1.5010 + * Called from the installer's .onInit function not to be confused with the
  1.5011 + * uninstaller's .onInit or the uninstaller's un.onInit functions.
  1.5012 + *
  1.5013 + * @param   _WARN_UNSUPPORTED_MSG
  1.5014 + *          Message displayed when the Windows version is not supported.
  1.5015 + *
  1.5016 + * $R5 = return value from the GetSize macro
  1.5017 + * $R6 = general string values, return value from GetTempFileName, return
  1.5018 + *       value from the GetSize macro
  1.5019 + * $R7 = full path to the configuration ini file
  1.5020 + * $R8 = used for OS Version and Service Pack detection and the return value
  1.5021 + *       from the GetParameters macro
  1.5022 + * $R9 = _WARN_UNSUPPORTED_MSG
  1.5023 + */
  1.5024 +!macro InstallOnInitCommon
  1.5025 +
  1.5026 +  !ifndef InstallOnInitCommon
  1.5027 +    !insertmacro ElevateUAC
  1.5028 +    !insertmacro GetOptions
  1.5029 +    !insertmacro GetParameters
  1.5030 +    !insertmacro GetSize
  1.5031 +
  1.5032 +    !verbose push
  1.5033 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5034 +    !define InstallOnInitCommon "!insertmacro InstallOnInitCommonCall"
  1.5035 +
  1.5036 +    Function InstallOnInitCommon
  1.5037 +      Exch $R9
  1.5038 +      Push $R8
  1.5039 +      Push $R7
  1.5040 +      Push $R6
  1.5041 +      Push $R5
  1.5042 +
  1.5043 +      !ifdef HAVE_64BIT_OS
  1.5044 +        ${Unless} ${RunningX64}
  1.5045 +        ${OrUnless} ${AtLeastWinVista}
  1.5046 +          MessageBox MB_OK|MB_ICONSTOP "$R9" IDOK
  1.5047 +          ; Nothing initialized so no need to call OnEndCommon
  1.5048 +          Quit
  1.5049 +        ${EndUnless}
  1.5050 +
  1.5051 +        SetRegView 64
  1.5052 +      !else
  1.5053 +        StrCpy $R8 "0"
  1.5054 +        ${If} ${AtMostWin2000}
  1.5055 +          StrCpy $R8 "1"
  1.5056 +        ${EndIf}
  1.5057 +
  1.5058 +        ${If} ${IsWinXP}
  1.5059 +        ${AndIf} ${AtMostServicePack} 1
  1.5060 +          StrCpy $R8 "1"
  1.5061 +        ${EndIf}
  1.5062 +
  1.5063 +        ${If} $R8 == "1"
  1.5064 +          ; XXX-rstrong - some systems failed the AtLeastWin2000 test that we
  1.5065 +          ; used to use for an unknown reason and likely fail the AtMostWin2000
  1.5066 +          ; and possibly the IsWinXP test as well. To work around this also
  1.5067 +          ; check if the Windows NT registry Key exists and if it does if the
  1.5068 +          ; first char in CurrentVersion is equal to 3 (Windows NT 3.5 and
  1.5069 +          ; 3.5.1), to 4 (Windows NT 4) or 5 (Windows 2000 and Windows XP).
  1.5070 +          StrCpy $R8 ""
  1.5071 +          ClearErrors
  1.5072 +          ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion"
  1.5073 +          StrCpy $R8 "$R8" 1
  1.5074 +          ${If} ${Errors}
  1.5075 +          ${OrIf} "$R8" == "3"
  1.5076 +          ${OrIf} "$R8" == "4"
  1.5077 +          ${OrIf} "$R8" == "5"
  1.5078 +            MessageBox MB_OK|MB_ICONSTOP "$R9" IDOK
  1.5079 +            ; Nothing initialized so no need to call OnEndCommon
  1.5080 +            Quit
  1.5081 +          ${EndIf}
  1.5082 +        ${EndUnless}
  1.5083 +      !endif
  1.5084 +
  1.5085 +      ${GetParameters} $R8
  1.5086 +
  1.5087 +      ; Require elevation if the user can elevate
  1.5088 +      ${ElevateUAC}
  1.5089 +
  1.5090 +      ${If} $R8 != ""
  1.5091 +        ; Default install type
  1.5092 +        StrCpy $InstallType ${INSTALLTYPE_BASIC}
  1.5093 +
  1.5094 +        ${Unless} ${Silent}
  1.5095 +          ; Manually check for /S in the command line due to Bug 506867
  1.5096 +          ClearErrors
  1.5097 +          ${GetOptions} "$R8" "/S" $R7
  1.5098 +          ${Unless} ${Errors}
  1.5099 +            SetSilent silent
  1.5100 +          ${Else}
  1.5101 +            ; Support for the deprecated -ms command line argument. The new command
  1.5102 +            ; line arguments are not supported when -ms is used.
  1.5103 +            ClearErrors
  1.5104 +            ${GetOptions} "$R8" "-ms" $R7
  1.5105 +            ${Unless} ${Errors}
  1.5106 +              SetSilent silent
  1.5107 +            ${EndUnless}
  1.5108 +          ${EndUnless}
  1.5109 +        ${EndUnless}
  1.5110 +
  1.5111 +        ; Support for specifying an installation configuration file.
  1.5112 +        ClearErrors
  1.5113 +        ${GetOptions} "$R8" "/INI=" $R7
  1.5114 +        ${Unless} ${Errors}
  1.5115 +          ; The configuration file must also exist
  1.5116 +          ${If} ${FileExists} "$R7"
  1.5117 +            SetSilent silent
  1.5118 +            ReadINIStr $R8 $R7 "Install" "InstallDirectoryName"
  1.5119 +            ${If} $R8 != ""
  1.5120 +              !ifdef HAVE_64BIT_OS
  1.5121 +                StrCpy $INSTDIR "$PROGRAMFILES64\$R8"
  1.5122 +              !else
  1.5123 +                StrCpy $INSTDIR "$PROGRAMFILES32\$R8"
  1.5124 +              !endif
  1.5125 +            ${Else}
  1.5126 +              ReadINIStr $R8 $R7 "Install" "InstallDirectoryPath"
  1.5127 +              ${If} $R8 != ""
  1.5128 +                StrCpy $INSTDIR "$R8"
  1.5129 +              ${EndIf}
  1.5130 +            ${EndIf}
  1.5131 +
  1.5132 +            ; Quit if we are unable to create the installation directory or we are
  1.5133 +            ; unable to write to a file in the installation directory.
  1.5134 +            ClearErrors
  1.5135 +            ${If} ${FileExists} "$INSTDIR"
  1.5136 +              GetTempFileName $R6 "$INSTDIR"
  1.5137 +              FileOpen $R5 "$R6" w
  1.5138 +              FileWrite $R5 "Write Access Test"
  1.5139 +              FileClose $R5
  1.5140 +              Delete $R6
  1.5141 +              ${If} ${Errors}
  1.5142 +                ; Nothing initialized so no need to call OnEndCommon
  1.5143 +                Quit
  1.5144 +              ${EndIf}
  1.5145 +            ${Else}
  1.5146 +              CreateDirectory "$INSTDIR"
  1.5147 +              ${If} ${Errors}
  1.5148 +                ; Nothing initialized so no need to call OnEndCommon
  1.5149 +                Quit
  1.5150 +              ${EndIf}
  1.5151 +            ${EndIf}
  1.5152 +
  1.5153 +            ReadINIStr $R8 $R7 "Install" "QuickLaunchShortcut"
  1.5154 +            ${If} $R8 == "false"
  1.5155 +              StrCpy $AddQuickLaunchSC "0"
  1.5156 +            ${Else}
  1.5157 +              StrCpy $AddQuickLaunchSC "1"
  1.5158 +            ${EndIf}
  1.5159 +
  1.5160 +            ReadINIStr $R8 $R7 "Install" "DesktopShortcut"
  1.5161 +            ${If} $R8 == "false"
  1.5162 +              StrCpy $AddDesktopSC "0"
  1.5163 +            ${Else}
  1.5164 +              StrCpy $AddDesktopSC "1"
  1.5165 +            ${EndIf}
  1.5166 +
  1.5167 +            ReadINIStr $R8 $R7 "Install" "StartMenuShortcuts"
  1.5168 +            ${If} $R8 == "false"
  1.5169 +              StrCpy $AddStartMenuSC "0"
  1.5170 +            ${Else}
  1.5171 +              StrCpy $AddStartMenuSC "1"
  1.5172 +            ${EndIf}
  1.5173 +
  1.5174 +            ReadINIStr $R8 $R7 "Install" "MaintenanceService"
  1.5175 +            ${If} $R8 == "false"
  1.5176 +              StrCpy $InstallMaintenanceService "0"
  1.5177 +            ${EndIf}
  1.5178 +
  1.5179 +            !ifndef NO_STARTMENU_DIR
  1.5180 +              ReadINIStr $R8 $R7 "Install" "StartMenuDirectoryName"
  1.5181 +              ${If} $R8 != ""
  1.5182 +                StrCpy $StartMenuDir "$R8"
  1.5183 +              ${EndIf}
  1.5184 +            !endif
  1.5185 +          ${EndIf}
  1.5186 +        ${EndUnless}
  1.5187 +      ${EndIf}
  1.5188 +      ClearErrors
  1.5189 +
  1.5190 +      Pop $R5
  1.5191 +      Pop $R6
  1.5192 +      Pop $R7
  1.5193 +      Pop $R8
  1.5194 +      Exch $R9
  1.5195 +    FunctionEnd
  1.5196 +
  1.5197 +    !verbose pop
  1.5198 +  !endif
  1.5199 +!macroend
  1.5200 +
  1.5201 +!macro InstallOnInitCommonCall _WARN_UNSUPPORTED_MSG
  1.5202 +  !verbose push
  1.5203 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5204 +  Push "${_WARN_UNSUPPORTED_MSG}"
  1.5205 +  Call InstallOnInitCommon
  1.5206 +  !verbose pop
  1.5207 +!macroend
  1.5208 +
  1.5209 +/**
  1.5210 + * Called from the uninstaller's .onInit function not to be confused with the
  1.5211 + * installer's .onInit or the uninstaller's un.onInit functions.
  1.5212 + */
  1.5213 +!macro UninstallOnInitCommon
  1.5214 +
  1.5215 +  !ifndef UninstallOnInitCommon
  1.5216 +    !insertmacro ElevateUAC
  1.5217 +    !insertmacro GetLongPath
  1.5218 +    !insertmacro GetOptions
  1.5219 +    !insertmacro GetParameters
  1.5220 +    !insertmacro GetParent
  1.5221 +    !insertmacro UnloadUAC
  1.5222 +    !insertmacro UpdateShortcutAppModelIDs
  1.5223 +    !insertmacro UpdateUninstallLog
  1.5224 +
  1.5225 +    !verbose push
  1.5226 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5227 +    !define UninstallOnInitCommon "!insertmacro UninstallOnInitCommonCall"
  1.5228 +
  1.5229 +    Function UninstallOnInitCommon
  1.5230 +      ; Prevents breaking apps that don't use SetBrandNameVars
  1.5231 +      !ifdef SetBrandNameVars
  1.5232 +        ${SetBrandNameVars} "$EXEDIR\distribution\setup.ini"
  1.5233 +      !endif
  1.5234 +
  1.5235 +      ; Prevent launching the application when a reboot is required and this
  1.5236 +      ; executable is the main application executable
  1.5237 +      IfFileExists "$EXEDIR\${FileMainEXE}.moz-upgrade" +1 +4
  1.5238 +      MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
  1.5239 +      Reboot
  1.5240 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5241 +
  1.5242 +      ${GetParent} "$EXEDIR" $INSTDIR
  1.5243 +      ${GetLongPath} "$INSTDIR" $INSTDIR
  1.5244 +      IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1
  1.5245 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5246 +
  1.5247 +!ifmacrodef InitHashAppModelId
  1.5248 +      ; setup the application model id registration value
  1.5249 +      !ifdef AppName
  1.5250 +      ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
  1.5251 +      !endif
  1.5252 +!endif
  1.5253 +
  1.5254 +      ; Prevents breaking apps that don't use SetBrandNameVars
  1.5255 +      !ifdef SetBrandNameVars
  1.5256 +        ${SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
  1.5257 +      !endif
  1.5258 +
  1.5259 +      ; Application update uses a directory named tobedeleted in the $INSTDIR to
  1.5260 +      ; delete files on OS reboot when they are in use. Try to delete this
  1.5261 +      ; directory if it exists.
  1.5262 +      ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}"
  1.5263 +        RmDir /r "$INSTDIR\${TO_BE_DELETED}"
  1.5264 +      ${EndIf}
  1.5265 +
  1.5266 +      ; Prevent all operations (e.g. set as default, postupdate, etc.) when a
  1.5267 +      ; reboot is required and the executable launched is helper.exe
  1.5268 +      IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4
  1.5269 +      MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
  1.5270 +      Reboot
  1.5271 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5272 +
  1.5273 +      !ifdef HAVE_64BIT_OS
  1.5274 +        SetRegView 64
  1.5275 +      !endif
  1.5276 +
  1.5277 +      ${GetParameters} $R0
  1.5278 +
  1.5279 +      StrCmp "$R0" "" continue +1
  1.5280 +
  1.5281 +      ; Update this user's shortcuts with the latest app user model id.
  1.5282 +      ClearErrors
  1.5283 +      ${GetOptions} "$R0" "/UpdateShortcutAppUserModelIds" $R2
  1.5284 +      IfErrors hideshortcuts +1
  1.5285 +      StrCpy $R2 ""
  1.5286 +!ifmacrodef InitHashAppModelId
  1.5287 +      ${If} "$AppUserModelID" != ""
  1.5288 +        ${UpdateShortcutAppModelIDs}  "$INSTDIR\${FileMainEXE}" "$AppUserModelID" $R2
  1.5289 +      ${EndIf}
  1.5290 +!endif
  1.5291 +      StrCmp "$R2" "false" +1 finish ; true indicates that shortcuts have been updated
  1.5292 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5293 +
  1.5294 +      ; Require elevation if the user can elevate
  1.5295 +      hideshortcuts:
  1.5296 +      ClearErrors
  1.5297 +      ${GetOptions} "$R0" "/HideShortcuts" $R2
  1.5298 +      IfErrors showshortcuts +1
  1.5299 +!ifndef NONADMIN_ELEVATE
  1.5300 +      ${ElevateUAC}
  1.5301 +!endif
  1.5302 +      ${HideShortcuts}
  1.5303 +      GoTo finish
  1.5304 +
  1.5305 +      ; Require elevation if the user can elevate
  1.5306 +      showshortcuts:
  1.5307 +      ClearErrors
  1.5308 +      ${GetOptions} "$R0" "/ShowShortcuts" $R2
  1.5309 +      IfErrors defaultappuser +1
  1.5310 +!ifndef NONADMIN_ELEVATE
  1.5311 +      ${ElevateUAC}
  1.5312 +!endif
  1.5313 +      ${ShowShortcuts}
  1.5314 +      GoTo finish
  1.5315 +
  1.5316 +      ; Require elevation if the the StartMenuInternet registry keys require
  1.5317 +      ; updating and the user can elevate
  1.5318 +      defaultappuser:
  1.5319 +      ClearErrors
  1.5320 +      ${GetOptions} "$R0" "/SetAsDefaultAppUser" $R2
  1.5321 +      IfErrors defaultappglobal +1
  1.5322 +      ${SetAsDefaultAppUser}
  1.5323 +      GoTo finish
  1.5324 +
  1.5325 +      ; Require elevation if the user can elevate
  1.5326 +      defaultappglobal:
  1.5327 +      ClearErrors
  1.5328 +      ${GetOptions} "$R0" "/SetAsDefaultAppGlobal" $R2
  1.5329 +      IfErrors postupdate +1
  1.5330 +      ${ElevateUAC}
  1.5331 +      ${SetAsDefaultAppGlobal}
  1.5332 +      GoTo finish
  1.5333 +
  1.5334 +      ; Do not attempt to elevate. The application launching this executable is
  1.5335 +      ; responsible for elevation if it is required.
  1.5336 +      postupdate:
  1.5337 +      ${WordReplace} "$R0" "$\"" "" "+" $R0
  1.5338 +      ClearErrors
  1.5339 +      ${GetOptions} "$R0" "/PostUpdate" $R2
  1.5340 +      IfErrors continue +1
  1.5341 +      ; If the uninstall.log does not exist don't perform post update
  1.5342 +      ; operations. This prevents updating the registry for zip builds.
  1.5343 +      IfFileExists "$EXEDIR\uninstall.log" +2 +1
  1.5344 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5345 +      ${PostUpdate}
  1.5346 +      ClearErrors
  1.5347 +      ${GetOptions} "$R0" "/UninstallLog=" $R2
  1.5348 +      IfErrors updateuninstalllog +1
  1.5349 +      StrCmp "$R2" "" finish +1
  1.5350 +      GetFullPathName $R3 "$R2"
  1.5351 +      IfFileExists "$R3" +1 finish
  1.5352 +      Delete "$INSTDIR\uninstall\*wizard*"
  1.5353 +      Delete "$INSTDIR\uninstall\uninstall.log"
  1.5354 +      CopyFiles /SILENT /FILESONLY "$R3" "$INSTDIR\uninstall\"
  1.5355 +      ${GetParent} "$R3" $R4
  1.5356 +      Delete "$R3"
  1.5357 +      RmDir "$R4"
  1.5358 +      GoTo finish
  1.5359 +
  1.5360 +      ; Do not attempt to elevate. The application launching this executable is
  1.5361 +      ; responsible for elevation if it is required.
  1.5362 +      updateuninstalllog:
  1.5363 +      ${UpdateUninstallLog}
  1.5364 +
  1.5365 +      finish:
  1.5366 +      ${UnloadUAC}
  1.5367 +      System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i 0, i 0, i 0)"
  1.5368 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5369 +
  1.5370 +      continue:
  1.5371 +
  1.5372 +      ; If the uninstall.log does not exist don't perform uninstall
  1.5373 +      ; operations. This prevents running the uninstaller for zip builds.
  1.5374 +      IfFileExists "$INSTDIR\uninstall\uninstall.log" +2 +1
  1.5375 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5376 +
  1.5377 +      ; Require elevation if the user can elevate
  1.5378 +      ${ElevateUAC}
  1.5379 +
  1.5380 +      ; If we made it this far then this installer is being used as an uninstaller.
  1.5381 +      WriteUninstaller "$EXEDIR\uninstaller.exe"
  1.5382 +
  1.5383 +      ${Unless} ${Silent}
  1.5384 +        ; Manually check for /S in the command line due to Bug 506867
  1.5385 +        ClearErrors
  1.5386 +        ${GetOptions} "$R0" "/S" $R2
  1.5387 +        ${Unless} ${Errors}
  1.5388 +          SetSilent silent
  1.5389 +        ${Else}
  1.5390 +          ; Support for the deprecated -ms command line argument.
  1.5391 +          ClearErrors
  1.5392 +          ${GetOptions} "$R0" "-ms" $R2
  1.5393 +          ${Unless} ${Errors}
  1.5394 +            SetSilent silent
  1.5395 +          ${EndUnless}
  1.5396 +        ${EndUnless}
  1.5397 +      ${EndUnless}
  1.5398 +
  1.5399 +      ${If} ${Silent}
  1.5400 +        StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\" /S"
  1.5401 +      ${Else}
  1.5402 +        StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\""
  1.5403 +      ${EndIf}
  1.5404 +
  1.5405 +      ; When the uninstaller is launched it copies itself to the temp directory
  1.5406 +      ; so it won't be in use so it can delete itself.
  1.5407 +      ExecWait $R1
  1.5408 +      ${DeleteFile} "$EXEDIR\uninstaller.exe"
  1.5409 +      ${UnloadUAC}
  1.5410 +      SetErrorLevel 0
  1.5411 +      Quit ; Nothing initialized so no need to call OnEndCommon
  1.5412 +
  1.5413 +    FunctionEnd
  1.5414 +
  1.5415 +    !verbose pop
  1.5416 +  !endif
  1.5417 +!macroend
  1.5418 +
  1.5419 +!macro UninstallOnInitCommonCall
  1.5420 +  !verbose push
  1.5421 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5422 +  Call UninstallOnInitCommon
  1.5423 +  !verbose pop
  1.5424 +!macroend
  1.5425 +
  1.5426 +/**
  1.5427 + * Called from the uninstaller's un.onInit function not to be confused with the
  1.5428 + * installer's .onInit or the uninstaller's .onInit functions.
  1.5429 + */
  1.5430 +!macro un.UninstallUnOnInitCommon
  1.5431 +
  1.5432 +  !ifndef un.UninstallUnOnInitCommon
  1.5433 +    !insertmacro un.GetLongPath
  1.5434 +    !insertmacro un.GetParent
  1.5435 +    !insertmacro un.SetBrandNameVars
  1.5436 +
  1.5437 +    !verbose push
  1.5438 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5439 +    !define un.UninstallUnOnInitCommon "!insertmacro un.UninstallUnOnInitCommonCall"
  1.5440 +
  1.5441 +    Function un.UninstallUnOnInitCommon
  1.5442 +      ${un.GetParent} "$INSTDIR" $INSTDIR
  1.5443 +      ${un.GetLongPath} "$INSTDIR" $INSTDIR
  1.5444 +      ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
  1.5445 +        Abort
  1.5446 +      ${EndUnless}
  1.5447 +
  1.5448 +      !ifdef HAVE_64BIT_OS
  1.5449 +        SetRegView 64
  1.5450 +      !endif
  1.5451 +
  1.5452 +      ; Prevents breaking apps that don't use SetBrandNameVars
  1.5453 +      !ifdef un.SetBrandNameVars
  1.5454 +        ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
  1.5455 +      !endif
  1.5456 +
  1.5457 +      ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
  1.5458 +      ; the user clicks the back button
  1.5459 +      StrCpy $hHeaderBitmap ""
  1.5460 +    FunctionEnd
  1.5461 +
  1.5462 +    !verbose pop
  1.5463 +  !endif
  1.5464 +!macroend
  1.5465 +
  1.5466 +!macro un.UninstallUnOnInitCommonCall
  1.5467 +  !verbose push
  1.5468 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5469 +  Call un.UninstallUnOnInitCommon
  1.5470 +  !verbose pop
  1.5471 +!macroend
  1.5472 +
  1.5473 +/**
  1.5474 + * Called from the MUI leaveOptions function to set the value of $INSTDIR.
  1.5475 + */
  1.5476 +!macro LeaveOptionsCommon
  1.5477 +
  1.5478 +  !ifndef LeaveOptionsCommon
  1.5479 +    !insertmacro CanWriteToInstallDir
  1.5480 +    !insertmacro GetLongPath
  1.5481 +
  1.5482 +!ifndef NO_INSTDIR_FROM_REG
  1.5483 +    !insertmacro GetSingleInstallPath
  1.5484 +!endif
  1.5485 +
  1.5486 +    !verbose push
  1.5487 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5488 +    !define LeaveOptionsCommon "!insertmacro LeaveOptionsCommonCall"
  1.5489 +
  1.5490 +    Function LeaveOptionsCommon
  1.5491 +      Push $R9
  1.5492 +
  1.5493 +!ifndef NO_INSTDIR_FROM_REG
  1.5494 +      SetShellVarContext all      ; Set SHCTX to HKLM
  1.5495 +      ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
  1.5496 +
  1.5497 +      StrCmp "$R9" "false" +1 finish_get_install_dir
  1.5498 +
  1.5499 +      SetShellVarContext current  ; Set SHCTX to HKCU
  1.5500 +      ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
  1.5501 +
  1.5502 +      finish_get_install_dir:
  1.5503 +      StrCmp "$R9" "false" +2 +1
  1.5504 +      StrCpy $INSTDIR "$R9"
  1.5505 +!endif
  1.5506 +
  1.5507 +      ; If the user doesn't have write access to the installation directory set
  1.5508 +      ; the installation directory to a subdirectory of the All Users application
  1.5509 +      ; directory and if the user can't write to that location set the installation
  1.5510 +      ; directory to a subdirectory of the users local application directory
  1.5511 +      ; (e.g. non-roaming).
  1.5512 +      ${CanWriteToInstallDir} $R9
  1.5513 +      StrCmp "$R9" "false" +1 finish_check_install_dir
  1.5514 +
  1.5515 +      SetShellVarContext all      ; Set SHCTX to All Users
  1.5516 +      StrCpy $INSTDIR "$APPDATA\${BrandFullName}\"
  1.5517 +      ${CanWriteToInstallDir} $R9
  1.5518 +      StrCmp "$R9" "false" +2 +1
  1.5519 +      StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\"
  1.5520 +
  1.5521 +      finish_check_install_dir:
  1.5522 +      IfFileExists "$INSTDIR" +3 +1
  1.5523 +      Pop $R9
  1.5524 +      Return
  1.5525 +
  1.5526 +      ; Always display the long path if the path already exists.
  1.5527 +      ${GetLongPath} "$INSTDIR" $INSTDIR
  1.5528 +
  1.5529 +      ; The call to GetLongPath returns a long path without a trailing
  1.5530 +      ; back-slash. Append a \ to the path to prevent the directory
  1.5531 +      ; name from being appended when using the NSIS create new folder.
  1.5532 +      ; http://www.nullsoft.com/free/nsis/makensis.htm#InstallDir
  1.5533 +      StrCpy $INSTDIR "$INSTDIR\"
  1.5534 +
  1.5535 +      Pop $R9
  1.5536 +    FunctionEnd
  1.5537 +
  1.5538 +    !verbose pop
  1.5539 +  !endif
  1.5540 +!macroend
  1.5541 +
  1.5542 +!macro LeaveOptionsCommonCall
  1.5543 +  !verbose push
  1.5544 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5545 +  Call LeaveOptionsCommon
  1.5546 +  !verbose pop
  1.5547 +!macroend
  1.5548 +
  1.5549 +/**
  1.5550 + * Called from the MUI preDirectory function to verify there is enough disk
  1.5551 + * space for the installation and the installation directory is writable.
  1.5552 + *
  1.5553 + * $R9 = returned value from CheckDiskSpace and CanWriteToInstallDir macros
  1.5554 + */
  1.5555 +!macro PreDirectoryCommon
  1.5556 +
  1.5557 +  !ifndef PreDirectoryCommon
  1.5558 +    !insertmacro CanWriteToInstallDir
  1.5559 +    !insertmacro CheckDiskSpace
  1.5560 +
  1.5561 +    !verbose push
  1.5562 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5563 +    !define PreDirectoryCommon "!insertmacro PreDirectoryCommonCall"
  1.5564 +
  1.5565 +    Function PreDirectoryCommon
  1.5566 +      Push $R9
  1.5567 +
  1.5568 +      IntCmp $InstallType ${INSTALLTYPE_CUSTOM} end +1 +1
  1.5569 +      ${CanWriteToInstallDir} $R9
  1.5570 +      StrCmp "$R9" "false" end +1
  1.5571 +      ${CheckDiskSpace} $R9
  1.5572 +      StrCmp "$R9" "false" end +1
  1.5573 +      Abort
  1.5574 +
  1.5575 +      end:
  1.5576 +
  1.5577 +      Pop $R9
  1.5578 +    FunctionEnd
  1.5579 +
  1.5580 +    !verbose pop
  1.5581 +  !endif
  1.5582 +!macroend
  1.5583 +
  1.5584 +!macro PreDirectoryCommonCall
  1.5585 +  !verbose push
  1.5586 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5587 +  Call PreDirectoryCommon
  1.5588 +  !verbose pop
  1.5589 +!macroend
  1.5590 +
  1.5591 +/**
  1.5592 + * Called from the MUI leaveDirectory function
  1.5593 + *
  1.5594 + * @param   _WARN_DISK_SPACE
  1.5595 + *          Message displayed when there isn't enough disk space to perform the
  1.5596 + *          installation.
  1.5597 + * @param   _WARN_WRITE_ACCESS
  1.5598 + *          Message displayed when the installer does not have write access to
  1.5599 + *          $INSTDIR.
  1.5600 + *
  1.5601 + * $R7 = returned value from CheckDiskSpace and CanWriteToInstallDir macros
  1.5602 + * $R8 = _WARN_DISK_SPACE
  1.5603 + * $R9 = _WARN_WRITE_ACCESS
  1.5604 + */
  1.5605 +!macro LeaveDirectoryCommon
  1.5606 +
  1.5607 +  !ifndef LeaveDirectoryCommon
  1.5608 +    !insertmacro CheckDiskSpace
  1.5609 +    !insertmacro CanWriteToInstallDir
  1.5610 +
  1.5611 +    !verbose push
  1.5612 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5613 +    !define LeaveDirectoryCommon "!insertmacro LeaveDirectoryCommonCall"
  1.5614 +
  1.5615 +    Function LeaveDirectoryCommon
  1.5616 +      Exch $R9
  1.5617 +      Exch 1
  1.5618 +      Exch $R8
  1.5619 +      Push $R7
  1.5620 +
  1.5621 +      ${CanWriteToInstallDir} $R7
  1.5622 +      ${If} $R7 == "false"
  1.5623 +        MessageBox MB_OK|MB_ICONEXCLAMATION "$R9"
  1.5624 +        Abort
  1.5625 +      ${EndIf}
  1.5626 +
  1.5627 +      ${CheckDiskSpace} $R7
  1.5628 +      ${If} $R7 == "false"
  1.5629 +        MessageBox MB_OK|MB_ICONEXCLAMATION "$R8"
  1.5630 +        Abort
  1.5631 +      ${EndIf}
  1.5632 +
  1.5633 +      Pop $R7
  1.5634 +      Exch $R8
  1.5635 +      Exch 1
  1.5636 +      Exch $R9
  1.5637 +    FunctionEnd
  1.5638 +
  1.5639 +    !verbose pop
  1.5640 +  !endif
  1.5641 +!macroend
  1.5642 +
  1.5643 +!macro LeaveDirectoryCommonCall _WARN_DISK_SPACE _WARN_WRITE_ACCESS
  1.5644 +  !verbose push
  1.5645 +  Push "${_WARN_DISK_SPACE}"
  1.5646 +  Push "${_WARN_WRITE_ACCESS}"
  1.5647 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5648 +  Call LeaveDirectoryCommon
  1.5649 +  !verbose pop
  1.5650 +!macroend
  1.5651 +
  1.5652 +
  1.5653 +################################################################################
  1.5654 +# Install Section common macros.
  1.5655 +
  1.5656 +/**
  1.5657 + * Performs common cleanup operations prior to the actual installation.
  1.5658 + * This macro should be called first when installation starts.
  1.5659 + */
  1.5660 +!macro InstallStartCleanupCommon
  1.5661 +
  1.5662 +  !ifndef InstallStartCleanupCommon
  1.5663 +    !insertmacro CleanVirtualStore
  1.5664 +    !insertmacro EndUninstallLog
  1.5665 +    !insertmacro OnInstallUninstall
  1.5666 +
  1.5667 +    !verbose push
  1.5668 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5669 +    !define InstallStartCleanupCommon "!insertmacro InstallStartCleanupCommonCall"
  1.5670 +
  1.5671 +    Function InstallStartCleanupCommon
  1.5672 +
  1.5673 +      ; Remove files not removed by parsing the uninstall.log
  1.5674 +      Delete "$INSTDIR\install_wizard.log"
  1.5675 +      Delete "$INSTDIR\install_status.log"
  1.5676 +
  1.5677 +      RmDir /r "$INSTDIR\updates"
  1.5678 +      Delete "$INSTDIR\updates.xml"
  1.5679 +      Delete "$INSTDIR\active-update.xml"
  1.5680 +
  1.5681 +      RmDir /r "$INSTDIR\distribution"
  1.5682 +
  1.5683 +      ; Remove files from the uninstall directory.
  1.5684 +      ${If} ${FileExists} "$INSTDIR\uninstall"
  1.5685 +        Delete "$INSTDIR\uninstall\*wizard*"
  1.5686 +        Delete "$INSTDIR\uninstall\uninstall.ini"
  1.5687 +        Delete "$INSTDIR\uninstall\cleanup.log"
  1.5688 +        Delete "$INSTDIR\uninstall\uninstall.update"
  1.5689 +        ${OnInstallUninstall}
  1.5690 +      ${EndIf}
  1.5691 +
  1.5692 +      ; Since we write to the uninstall.log in this directory during the
  1.5693 +      ; installation create the directory if it doesn't already exist.
  1.5694 +      IfFileExists "$INSTDIR\uninstall" +2 +1
  1.5695 +      CreateDirectory "$INSTDIR\uninstall"
  1.5696 +
  1.5697 +      ; Application update uses a directory named tobedeleted in the $INSTDIR to
  1.5698 +      ; delete files on OS reboot when they are in use. Try to delete this
  1.5699 +      ; directory if it exists.
  1.5700 +      ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}"
  1.5701 +        RmDir /r "$INSTDIR\${TO_BE_DELETED}"
  1.5702 +      ${EndIf}
  1.5703 +
  1.5704 +      ; Remove files that may be left behind by the application in the
  1.5705 +      ; VirtualStore directory.
  1.5706 +      ${CleanVirtualStore}
  1.5707 +    FunctionEnd
  1.5708 +
  1.5709 +    !verbose pop
  1.5710 +  !endif
  1.5711 +!macroend
  1.5712 +
  1.5713 +!macro InstallStartCleanupCommonCall
  1.5714 +  !verbose push
  1.5715 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5716 +  Call InstallStartCleanupCommon
  1.5717 +  !verbose pop
  1.5718 +!macroend
  1.5719 +
  1.5720 +/**
  1.5721 + * Performs common cleanup operations after the actual installation.
  1.5722 + * This macro should be called last during the installation.
  1.5723 + */
  1.5724 +!macro InstallEndCleanupCommon
  1.5725 +
  1.5726 +  !ifndef InstallEndCleanupCommon
  1.5727 +    !insertmacro EndUninstallLog
  1.5728 +
  1.5729 +    !verbose push
  1.5730 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5731 +    !define InstallEndCleanupCommon "!insertmacro InstallEndCleanupCommonCall"
  1.5732 +
  1.5733 +    Function InstallEndCleanupCommon
  1.5734 +
  1.5735 +      ; Close the file handle to the uninstall.log
  1.5736 +      ${EndUninstallLog}
  1.5737 +
  1.5738 +    FunctionEnd
  1.5739 +
  1.5740 +    !verbose pop
  1.5741 +  !endif
  1.5742 +!macroend
  1.5743 +
  1.5744 +!macro InstallEndCleanupCommonCall
  1.5745 +  !verbose push
  1.5746 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5747 +  Call InstallEndCleanupCommon
  1.5748 +  !verbose pop
  1.5749 +!macroend
  1.5750 +
  1.5751 +
  1.5752 +################################################################################
  1.5753 +# UAC Related Macros
  1.5754 +
  1.5755 +/**
  1.5756 + * Provides UAC elevation support for Vista and above (requires the UAC plugin).
  1.5757 + *
  1.5758 + * $0 = return values from calls to the UAC plugin (always uses $0)
  1.5759 + * $R9 = return values from GetParameters and GetOptions macros
  1.5760 + */
  1.5761 +!macro ElevateUAC
  1.5762 +
  1.5763 +  !ifndef ${_MOZFUNC_UN}ElevateUAC
  1.5764 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.5765 +    !insertmacro ${_MOZFUNC_UN_TMP}GetOptions
  1.5766 +    !insertmacro ${_MOZFUNC_UN_TMP}GetParameters
  1.5767 +    !undef _MOZFUNC_UN
  1.5768 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.5769 +    !undef _MOZFUNC_UN_TMP
  1.5770 +
  1.5771 +    !verbose push
  1.5772 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5773 +    !define ${_MOZFUNC_UN}ElevateUAC "!insertmacro ${_MOZFUNC_UN}ElevateUACCall"
  1.5774 +
  1.5775 +    Function ${_MOZFUNC_UN}ElevateUAC
  1.5776 +      Push $R9
  1.5777 +      Push $0
  1.5778 +
  1.5779 +!ifndef NONADMIN_ELEVATE
  1.5780 +        ${If} ${AtLeastWinVista}
  1.5781 +          UAC::IsAdmin
  1.5782 +          ; If the user is not an admin already
  1.5783 +          ${If} "$0" != "1"
  1.5784 +            UAC::SupportsUAC
  1.5785 +            ; If the system supports UAC
  1.5786 +            ${If} "$0" == "1"
  1.5787 +              UAC::GetElevationType
  1.5788 +              ; If the user account has a split token
  1.5789 +              ${If} "$0" == "3"
  1.5790 +                UAC::RunElevated
  1.5791 +                UAC::Unload
  1.5792 +                ; Nothing besides UAC initialized so no need to call OnEndCommon
  1.5793 +                Quit
  1.5794 +              ${EndIf}
  1.5795 +            ${EndIf}
  1.5796 +          ${Else}
  1.5797 +            ${GetParameters} $R9
  1.5798 +            ${If} $R9 != ""
  1.5799 +              ClearErrors
  1.5800 +              ${GetOptions} "$R9" "/UAC:" $0
  1.5801 +              ; If the command line contains /UAC then we need to initialize
  1.5802 +              ; the UAC plugin to use UAC::ExecCodeSegment to execute code in
  1.5803 +              ; the non-elevated context.
  1.5804 +              ${Unless} ${Errors}
  1.5805 +                UAC::RunElevated
  1.5806 +              ${EndUnless}
  1.5807 +            ${EndIf}
  1.5808 +          ${EndIf}
  1.5809 +        ${EndIf}
  1.5810 +!else
  1.5811 +      ${If} ${AtLeastWinVista}
  1.5812 +        UAC::IsAdmin
  1.5813 +        ; If the user is not an admin already
  1.5814 +        ${If} "$0" != "1"
  1.5815 +          UAC::SupportsUAC
  1.5816 +          ; If the system supports UAC require that the user elevate
  1.5817 +          ${If} "$0" == "1"
  1.5818 +            UAC::GetElevationType
  1.5819 +            ; If the user account has a split token
  1.5820 +            ${If} "$0" == "3"
  1.5821 +              UAC::RunElevated
  1.5822 +              UAC::Unload
  1.5823 +              ; Nothing besides UAC initialized so no need to call OnEndCommon
  1.5824 +              Quit
  1.5825 +            ${EndIf}
  1.5826 +          ${Else}
  1.5827 +            ; Check if UAC is enabled. If the user has turned UAC on or off
  1.5828 +            ; without rebooting this value will be incorrect. This is an
  1.5829 +            ; edgecase that we have to live with when trying to allow
  1.5830 +            ; installing when the user doesn't have privileges such as a public
  1.5831 +            ; computer while trying to also achieve UAC elevation. When this
  1.5832 +            ; happens the user will be presented with the runas dialog if the
  1.5833 +            ; value is 1 and won't be presented with the UAC dialog when the
  1.5834 +            ; value is 0.
  1.5835 +            ReadRegDWord $R9 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "EnableLUA"
  1.5836 +            ${If} "$R9" == "1"
  1.5837 +              ; This will display the UAC version of the runas dialog which
  1.5838 +              ; requires a password for an existing user account.
  1.5839 +              UAC::RunElevated
  1.5840 +              ${If} "$0" == "0" ; Was elevation successful
  1.5841 +                UAC::Unload
  1.5842 +                ; Nothing besides UAC initialized so no need to call OnEndCommon
  1.5843 +                Quit
  1.5844 +              ${EndIf}
  1.5845 +              ; Unload UAC since the elevation request was not successful and
  1.5846 +              ; install anyway.
  1.5847 +              UAC::Unload
  1.5848 +            ${EndIf}
  1.5849 +          ${EndIf}
  1.5850 +        ${Else}
  1.5851 +          ClearErrors
  1.5852 +          ${${_MOZFUNC_UN}GetParameters} $R9
  1.5853 +          ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9
  1.5854 +          ; If the command line contains /UAC then we need to initialize the UAC
  1.5855 +          ; plugin to use UAC::ExecCodeSegment to execute code in the
  1.5856 +          ; non-elevated context.
  1.5857 +          ${Unless} ${Errors}
  1.5858 +            UAC::RunElevated
  1.5859 +          ${EndUnless}
  1.5860 +        ${EndIf}
  1.5861 +      ${EndIf}
  1.5862 +!endif
  1.5863 +
  1.5864 +      ClearErrors
  1.5865 +
  1.5866 +      Pop $0
  1.5867 +      Pop $R9
  1.5868 +    FunctionEnd
  1.5869 +
  1.5870 +    !verbose pop
  1.5871 +  !endif
  1.5872 +!macroend
  1.5873 +
  1.5874 +!macro ElevateUACCall
  1.5875 +  !verbose push
  1.5876 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5877 +  Call ElevateUAC
  1.5878 +  !verbose pop
  1.5879 +!macroend
  1.5880 +
  1.5881 +!macro un.ElevateUACCall
  1.5882 +  !verbose push
  1.5883 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5884 +  Call un.ElevateUAC
  1.5885 +  !verbose pop
  1.5886 +!macroend
  1.5887 +
  1.5888 +!macro un.ElevateUAC
  1.5889 +  !ifndef un.ElevateUAC
  1.5890 +    !verbose push
  1.5891 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5892 +    !undef _MOZFUNC_UN
  1.5893 +    !define _MOZFUNC_UN "un."
  1.5894 +
  1.5895 +    !insertmacro ElevateUAC
  1.5896 +
  1.5897 +    !undef _MOZFUNC_UN
  1.5898 +    !define _MOZFUNC_UN
  1.5899 +    !verbose pop
  1.5900 +  !endif
  1.5901 +!macroend
  1.5902 +
  1.5903 +/**
  1.5904 + * Unloads the UAC plugin so the NSIS plugins can be removed when the installer
  1.5905 + * and uninstaller exit.
  1.5906 + *
  1.5907 + * $R9 = return values from GetParameters and GetOptions macros
  1.5908 + */
  1.5909 +!macro UnloadUAC
  1.5910 +
  1.5911 +  !ifndef ${_MOZFUNC_UN}UnloadUAC
  1.5912 +    !define _MOZFUNC_UN_TMP_UnloadUAC ${_MOZFUNC_UN}
  1.5913 +    !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetOptions
  1.5914 +    !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetParameters
  1.5915 +    !undef _MOZFUNC_UN
  1.5916 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP_UnloadUAC}
  1.5917 +    !undef _MOZFUNC_UN_TMP_UnloadUAC
  1.5918 +
  1.5919 +    !verbose push
  1.5920 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5921 +    !define ${_MOZFUNC_UN}UnloadUAC "!insertmacro ${_MOZFUNC_UN}UnloadUACCall"
  1.5922 +
  1.5923 +    Function ${_MOZFUNC_UN}UnloadUAC
  1.5924 +      ${Unless} ${AtLeastWinVista}
  1.5925 +        Return
  1.5926 +      ${EndUnless}
  1.5927 +
  1.5928 +      Push $R9
  1.5929 +
  1.5930 +      ClearErrors
  1.5931 +      ${${_MOZFUNC_UN}GetParameters} $R9
  1.5932 +      ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9
  1.5933 +      ; If the command line contains /UAC then we need to unload the UAC plugin
  1.5934 +      IfErrors +2 +1
  1.5935 +      UAC::Unload
  1.5936 +
  1.5937 +      ClearErrors
  1.5938 +
  1.5939 +      Pop $R9
  1.5940 +    FunctionEnd
  1.5941 +
  1.5942 +    !verbose pop
  1.5943 +  !endif
  1.5944 +!macroend
  1.5945 +
  1.5946 +!macro UnloadUACCall
  1.5947 +  !verbose push
  1.5948 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5949 +  Call UnloadUAC
  1.5950 +  !verbose pop
  1.5951 +!macroend
  1.5952 +
  1.5953 +!macro un.UnloadUACCall
  1.5954 +  !verbose push
  1.5955 +  !verbose ${_MOZFUNC_VERBOSE}
  1.5956 +  Call un.UnloadUAC
  1.5957 +  !verbose pop
  1.5958 +!macroend
  1.5959 +
  1.5960 +!macro un.UnloadUAC
  1.5961 +  !ifndef un.UnloadUAC
  1.5962 +    !verbose push
  1.5963 +    !verbose ${_MOZFUNC_VERBOSE}
  1.5964 +    !undef _MOZFUNC_UN
  1.5965 +    !define _MOZFUNC_UN "un."
  1.5966 +
  1.5967 +    !insertmacro UnloadUAC
  1.5968 +
  1.5969 +    !undef _MOZFUNC_UN
  1.5970 +    !define _MOZFUNC_UN
  1.5971 +    !verbose pop
  1.5972 +  !endif
  1.5973 +!macroend
  1.5974 +
  1.5975 +
  1.5976 +################################################################################
  1.5977 +# Macros for uninstall.log and install.log logging
  1.5978 +#
  1.5979 +# Since these are used by other macros they should be inserted first. All of
  1.5980 +# these macros can be easily inserted using the _LoggingCommon macro.
  1.5981 +
  1.5982 +/**
  1.5983 + * Adds all logging macros in the correct order in one fell swoop as well as
  1.5984 + * the vars for the install.log and uninstall.log file handles.
  1.5985 + */
  1.5986 +!macro _LoggingCommon
  1.5987 +  Var /GLOBAL fhInstallLog
  1.5988 +  Var /GLOBAL fhUninstallLog
  1.5989 +  !insertmacro StartInstallLog
  1.5990 +  !insertmacro EndInstallLog
  1.5991 +  !insertmacro StartUninstallLog
  1.5992 +  !insertmacro EndUninstallLog
  1.5993 +!macroend
  1.5994 +!define _LoggingCommon "!insertmacro _LoggingCommon"
  1.5995 +
  1.5996 +/**
  1.5997 + * Creates a file named install.log in the install directory (e.g. $INSTDIR)
  1.5998 + * and adds the installation started message to the install.log for this
  1.5999 + * installation. This also adds the fhInstallLog and fhUninstallLog vars used
  1.6000 + * for logging.
  1.6001 + *
  1.6002 + * $fhInstallLog = filehandle for $INSTDIR\install.log
  1.6003 + *
  1.6004 + * @param   _APP_NAME
  1.6005 + *          Typically the BrandFullName
  1.6006 + * @param   _AB_CD
  1.6007 + *          The locale identifier
  1.6008 + * @param   _APP_VERSION
  1.6009 + *          The application version
  1.6010 + * @param   _GRE_VERSION
  1.6011 + *          The Gecko Runtime Engine version
  1.6012 + *
  1.6013 + * $R6 = _APP_NAME
  1.6014 + * $R7 = _AB_CD
  1.6015 + * $R8 = _APP_VERSION
  1.6016 + * $R9 = _GRE_VERSION
  1.6017 + */
  1.6018 +!macro StartInstallLog
  1.6019 +
  1.6020 +  !ifndef StartInstallLog
  1.6021 +    !insertmacro GetTime
  1.6022 +
  1.6023 +    !verbose push
  1.6024 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6025 +    !define StartInstallLog "!insertmacro StartInstallLogCall"
  1.6026 +
  1.6027 +    Function StartInstallLog
  1.6028 +      Exch $R9
  1.6029 +      Exch 1
  1.6030 +      Exch $R8
  1.6031 +      Exch 2
  1.6032 +      Exch $R7
  1.6033 +      Exch 3
  1.6034 +      Exch $R6
  1.6035 +      Push $R5
  1.6036 +      Push $R4
  1.6037 +      Push $R3
  1.6038 +      Push $R2
  1.6039 +      Push $R1
  1.6040 +      Push $R0
  1.6041 +      Push $9
  1.6042 +
  1.6043 +      ${DeleteFile} "$INSTDIR\install.log"
  1.6044 +      FileOpen $fhInstallLog "$INSTDIR\install.log" w
  1.6045 +      FileWriteWord $fhInstallLog "65279"
  1.6046 +
  1.6047 +      ${GetTime} "" "L" $9 $R0 $R1 $R2 $R3 $R4 $R5
  1.6048 +      FileWriteUTF16LE $fhInstallLog "$R6 Installation Started: $R1-$R0-$9 $R3:$R4:$R5"
  1.6049 +      ${WriteLogSeparator}
  1.6050 +
  1.6051 +      ${LogHeader} "Installation Details"
  1.6052 +      ${LogMsg} "Install Dir: $INSTDIR"
  1.6053 +      ${LogMsg} "Locale     : $R7"
  1.6054 +      ${LogMsg} "App Version: $R8"
  1.6055 +      ${LogMsg} "GRE Version: $R9"
  1.6056 +
  1.6057 +      ${If} ${IsWinXP}
  1.6058 +        ${LogMsg} "OS Name    : Windows XP"
  1.6059 +      ${ElseIf} ${IsWin2003}
  1.6060 +        ${LogMsg} "OS Name    : Windows 2003"
  1.6061 +      ${ElseIf} ${IsWinVista}
  1.6062 +        ${LogMsg} "OS Name    : Windows Vista"
  1.6063 +      ${ElseIf} ${IsWin7}
  1.6064 +        ${LogMsg} "OS Name    : Windows 7"
  1.6065 +      ${ElseIf} ${IsWin8}
  1.6066 +        ${LogMsg} "OS Name    : Windows 8"
  1.6067 +      ${ElseIf} ${AtLeastWin8}
  1.6068 +        ${LogMsg} "OS Name    : Above Windows 8"
  1.6069 +      ${Else}
  1.6070 +        ${LogMsg} "OS Name    : Unable to detect"
  1.6071 +      ${EndIf}
  1.6072 +
  1.6073 +      !ifdef HAVE_64BIT_OS
  1.6074 +        ${LogMsg} "Target CPU : x64"
  1.6075 +      !else
  1.6076 +        ${LogMsg} "Target CPU : x86"
  1.6077 +      !endif
  1.6078 +
  1.6079 +      Pop $9
  1.6080 +      Pop $R0
  1.6081 +      Pop $R1
  1.6082 +      Pop $R2
  1.6083 +      Pop $R3
  1.6084 +      Pop $R4
  1.6085 +      Pop $R5
  1.6086 +      Exch $R6
  1.6087 +      Exch 3
  1.6088 +      Exch $R7
  1.6089 +      Exch 2
  1.6090 +      Exch $R8
  1.6091 +      Exch 1
  1.6092 +      Exch $R9
  1.6093 +    FunctionEnd
  1.6094 +
  1.6095 +    !verbose pop
  1.6096 +  !endif
  1.6097 +!macroend
  1.6098 +
  1.6099 +!macro StartInstallLogCall _APP_NAME _AB_CD _APP_VERSION _GRE_VERSION
  1.6100 +  !verbose push
  1.6101 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6102 +  Push "${_APP_NAME}"
  1.6103 +  Push "${_AB_CD}"
  1.6104 +  Push "${_APP_VERSION}"
  1.6105 +  Push "${_GRE_VERSION}"
  1.6106 +  Call StartInstallLog
  1.6107 +  !verbose pop
  1.6108 +!macroend
  1.6109 +
  1.6110 +/**
  1.6111 + * Writes the installation finished message to the install.log and closes the
  1.6112 + * file handles to the install.log and uninstall.log
  1.6113 + *
  1.6114 + * @param   _APP_NAME
  1.6115 + *
  1.6116 + * $R9 = _APP_NAME
  1.6117 + */
  1.6118 +!macro EndInstallLog
  1.6119 +
  1.6120 +  !ifndef EndInstallLog
  1.6121 +    !insertmacro GetTime
  1.6122 +
  1.6123 +    !verbose push
  1.6124 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6125 +    !define EndInstallLog "!insertmacro EndInstallLogCall"
  1.6126 +
  1.6127 +    Function EndInstallLog
  1.6128 +      Exch $R9
  1.6129 +      Push $R8
  1.6130 +      Push $R7
  1.6131 +      Push $R6
  1.6132 +      Push $R5
  1.6133 +      Push $R4
  1.6134 +      Push $R3
  1.6135 +      Push $R2
  1.6136 +
  1.6137 +      ${WriteLogSeparator}
  1.6138 +      ${GetTime} "" "L" $R2 $R3 $R4 $R5 $R6 $R7 $R8
  1.6139 +      FileWriteUTF16LE $fhInstallLog "$R9 Installation Finished: $R4-$R3-$R2 $R6:$R7:$R8$\r$\n"
  1.6140 +      FileClose $fhInstallLog
  1.6141 +
  1.6142 +      Pop $R2
  1.6143 +      Pop $R3
  1.6144 +      Pop $R4
  1.6145 +      Pop $R5
  1.6146 +      Pop $R6
  1.6147 +      Pop $R7
  1.6148 +      Pop $R8
  1.6149 +      Exch $R9
  1.6150 +    FunctionEnd
  1.6151 +
  1.6152 +    !verbose pop
  1.6153 +  !endif
  1.6154 +!macroend
  1.6155 +
  1.6156 +!macro EndInstallLogCall _APP_NAME
  1.6157 +  !verbose push
  1.6158 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6159 +  Push "${_APP_NAME}"
  1.6160 +  Call EndInstallLog
  1.6161 +  !verbose pop
  1.6162 +!macroend
  1.6163 +
  1.6164 +/**
  1.6165 + * Opens the file handle to the uninstall.log.
  1.6166 + *
  1.6167 + * $fhUninstallLog = filehandle for $INSTDIR\uninstall\uninstall.log
  1.6168 + */
  1.6169 +!macro StartUninstallLog
  1.6170 +
  1.6171 +  !ifndef StartUninstallLog
  1.6172 +    !verbose push
  1.6173 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6174 +    !define StartUninstallLog "!insertmacro StartUninstallLogCall"
  1.6175 +
  1.6176 +    Function StartUninstallLog
  1.6177 +      FileOpen $fhUninstallLog "$INSTDIR\uninstall\uninstall.log" w
  1.6178 +    FunctionEnd
  1.6179 +
  1.6180 +    !verbose pop
  1.6181 +  !endif
  1.6182 +!macroend
  1.6183 +
  1.6184 +!macro StartUninstallLogCall
  1.6185 +  !verbose push
  1.6186 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6187 +  Call StartUninstallLog
  1.6188 +  !verbose pop
  1.6189 +!macroend
  1.6190 +
  1.6191 +/**
  1.6192 + * Closes the file handle to the uninstall.log.
  1.6193 + */
  1.6194 +!macro EndUninstallLog
  1.6195 +
  1.6196 +  !ifndef EndUninstallLog
  1.6197 +
  1.6198 +    !verbose push
  1.6199 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6200 +    !define EndUninstallLog "!insertmacro EndUninstallLogCall"
  1.6201 +
  1.6202 +    Function EndUninstallLog
  1.6203 +      FileClose $fhUninstallLog
  1.6204 +    FunctionEnd
  1.6205 +
  1.6206 +    !verbose pop
  1.6207 +  !endif
  1.6208 +!macroend
  1.6209 +
  1.6210 +!macro EndUninstallLogCall
  1.6211 +  !verbose push
  1.6212 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6213 +  Call EndUninstallLog
  1.6214 +  !verbose pop
  1.6215 +!macroend
  1.6216 +
  1.6217 +/**
  1.6218 + * Adds a section header to the human readable log.
  1.6219 + *
  1.6220 + * @param   _HEADER
  1.6221 + *          The header text to write to the log.
  1.6222 + */
  1.6223 +!macro LogHeader _HEADER
  1.6224 +  ${WriteLogSeparator}
  1.6225 +  FileWriteUTF16LE $fhInstallLog "${_HEADER}"
  1.6226 +  ${WriteLogSeparator}
  1.6227 +!macroend
  1.6228 +!define LogHeader "!insertmacro LogHeader"
  1.6229 +
  1.6230 +/**
  1.6231 + * Adds a section message to the human readable log.
  1.6232 + *
  1.6233 + * @param   _MSG
  1.6234 + *          The message text to write to the log.
  1.6235 + */
  1.6236 +!macro LogMsg _MSG
  1.6237 +  FileWriteUTF16LE $fhInstallLog "  ${_MSG}$\r$\n"
  1.6238 +!macroend
  1.6239 +!define LogMsg "!insertmacro LogMsg"
  1.6240 +
  1.6241 +/**
  1.6242 + * Adds an uninstall entry to the uninstall log.
  1.6243 + *
  1.6244 + * @param   _MSG
  1.6245 + *          The message text to write to the log.
  1.6246 + */
  1.6247 +!macro LogUninstall _MSG
  1.6248 +  FileWrite $fhUninstallLog "${_MSG}$\r$\n"
  1.6249 +!macroend
  1.6250 +!define LogUninstall "!insertmacro LogUninstall"
  1.6251 +
  1.6252 +/**
  1.6253 + * Adds a section divider to the human readable log.
  1.6254 + */
  1.6255 +!macro WriteLogSeparator
  1.6256 +  FileWriteUTF16LE $fhInstallLog "$\r$\n----------------------------------------\
  1.6257 +                                  ---------------------------------------$\r$\n"
  1.6258 +!macroend
  1.6259 +!define WriteLogSeparator "!insertmacro WriteLogSeparator"
  1.6260 +
  1.6261 +
  1.6262 +################################################################################
  1.6263 +# Macros for managing the shortcuts log ini file
  1.6264 +
  1.6265 +/**
  1.6266 + * Adds the most commonly used shortcut logging macros for the installer in one
  1.6267 + * fell swoop.
  1.6268 + */
  1.6269 +!macro _LoggingShortcutsCommon
  1.6270 +  !insertmacro LogDesktopShortcut
  1.6271 +  !insertmacro LogQuickLaunchShortcut
  1.6272 +  !insertmacro LogSMProgramsShortcut
  1.6273 +!macroend
  1.6274 +!define _LoggingShortcutsCommon "!insertmacro _LoggingShortcutsCommon"
  1.6275 +
  1.6276 +/**
  1.6277 + * Creates the shortcuts log ini file with a UTF-16LE BOM if it doesn't exist.
  1.6278 + */
  1.6279 +!macro initShortcutsLog
  1.6280 +  Push $R9
  1.6281 +
  1.6282 +  IfFileExists "$INSTDIR\uninstall\${SHORTCUTS_LOG}" +4 +1
  1.6283 +  FileOpen $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" w
  1.6284 +  FileWriteWord $R9 "65279"
  1.6285 +  FileClose $R9
  1.6286 +
  1.6287 +  Pop $R9
  1.6288 +!macroend
  1.6289 +!define initShortcutsLog "!insertmacro initShortcutsLog"
  1.6290 +
  1.6291 +/**
  1.6292 + * Adds shortcut entries to the shortcuts log ini file. This macro is primarily
  1.6293 + * a helper used by the LogDesktopShortcut, LogQuickLaunchShortcut, and
  1.6294 + * LogSMProgramsShortcut macros but it can be used by other code if desired. If
  1.6295 + * the value already exists the the value is not written to the file.
  1.6296 + *
  1.6297 + * @param   _SECTION_NAME
  1.6298 + *          The section name to write to in the shortcut log ini file
  1.6299 + * @param   _FILE_NAME
  1.6300 + *          The shortcut's file name
  1.6301 + *
  1.6302 + * $R6 = return value from ReadIniStr for the shortcut file name
  1.6303 + * $R7 = counter for supporting multiple shortcuts in the same location
  1.6304 + * $R8 = _SECTION_NAME
  1.6305 + * $R9 = _FILE_NAME
  1.6306 + */
  1.6307 +!macro LogShortcut
  1.6308 +
  1.6309 +  !ifndef LogShortcut
  1.6310 +    !verbose push
  1.6311 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6312 +    !define LogShortcut "!insertmacro LogShortcutCall"
  1.6313 +
  1.6314 +    Function LogShortcut
  1.6315 +      Exch $R9
  1.6316 +      Exch 1
  1.6317 +      Exch $R8
  1.6318 +      Push $R7
  1.6319 +      Push $R6
  1.6320 +
  1.6321 +      ClearErrors
  1.6322 +
  1.6323 +      !insertmacro initShortcutsLog
  1.6324 +
  1.6325 +      StrCpy $R6 ""
  1.6326 +      StrCpy $R7 -1
  1.6327 +
  1.6328 +      StrCmp "$R6" "$R9" +5 +1 ; if the shortcut already exists don't add it
  1.6329 +      IntOp $R7 $R7 + 1 ; increment the counter
  1.6330 +      ReadIniStr $R6 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7"
  1.6331 +      IfErrors +1 -3
  1.6332 +      WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" "$R9"
  1.6333 +
  1.6334 +      ClearErrors
  1.6335 +
  1.6336 +      Pop $R6
  1.6337 +      Pop $R7
  1.6338 +      Exch $R8
  1.6339 +      Exch 1
  1.6340 +      Exch $R9
  1.6341 +    FunctionEnd
  1.6342 +
  1.6343 +    !verbose pop
  1.6344 +  !endif
  1.6345 +!macroend
  1.6346 +
  1.6347 +!macro LogShortcutCall _SECTION_NAME _FILE_NAME
  1.6348 +  !verbose push
  1.6349 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6350 +  Push "${_SECTION_NAME}"
  1.6351 +  Push "${_FILE_NAME}"
  1.6352 +  Call LogShortcut
  1.6353 +  !verbose pop
  1.6354 +!macroend
  1.6355 +
  1.6356 +/**
  1.6357 + * Adds a Desktop shortcut entry to the shortcuts log ini file.
  1.6358 + *
  1.6359 + * @param   _FILE_NAME
  1.6360 + *          The shortcut file name (e.g. shortcut.lnk)
  1.6361 + */
  1.6362 +!macro LogDesktopShortcut
  1.6363 +
  1.6364 +  !ifndef LogDesktopShortcut
  1.6365 +    !insertmacro LogShortcut
  1.6366 +
  1.6367 +    !verbose push
  1.6368 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6369 +    !define LogDesktopShortcut "!insertmacro LogDesktopShortcutCall"
  1.6370 +
  1.6371 +    Function LogDesktopShortcut
  1.6372 +      Call LogShortcut
  1.6373 +    FunctionEnd
  1.6374 +
  1.6375 +    !verbose pop
  1.6376 +  !endif
  1.6377 +!macroend
  1.6378 +
  1.6379 +!macro LogDesktopShortcutCall _FILE_NAME
  1.6380 +  !verbose push
  1.6381 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6382 +  Push "DESKTOP"
  1.6383 +  Push "${_FILE_NAME}"
  1.6384 +  Call LogDesktopShortcut
  1.6385 +  !verbose pop
  1.6386 +!macroend
  1.6387 +
  1.6388 +/**
  1.6389 + * Adds a QuickLaunch shortcut entry to the shortcuts log ini file.
  1.6390 + *
  1.6391 + * @param   _FILE_NAME
  1.6392 + *          The shortcut file name (e.g. shortcut.lnk)
  1.6393 + */
  1.6394 +!macro LogQuickLaunchShortcut
  1.6395 +
  1.6396 +  !ifndef LogQuickLaunchShortcut
  1.6397 +    !insertmacro LogShortcut
  1.6398 +
  1.6399 +    !verbose push
  1.6400 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6401 +    !define LogQuickLaunchShortcut "!insertmacro LogQuickLaunchShortcutCall"
  1.6402 +
  1.6403 +    Function LogQuickLaunchShortcut
  1.6404 +      Call LogShortcut
  1.6405 +    FunctionEnd
  1.6406 +
  1.6407 +    !verbose pop
  1.6408 +  !endif
  1.6409 +!macroend
  1.6410 +
  1.6411 +!macro LogQuickLaunchShortcutCall _FILE_NAME
  1.6412 +  !verbose push
  1.6413 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6414 +  Push "QUICKLAUNCH"
  1.6415 +  Push "${_FILE_NAME}"
  1.6416 +  Call LogQuickLaunchShortcut
  1.6417 +  !verbose pop
  1.6418 +!macroend
  1.6419 +
  1.6420 +/**
  1.6421 + * Adds a Start Menu shortcut entry to the shortcuts log ini file.
  1.6422 + *
  1.6423 + * @param   _FILE_NAME
  1.6424 + *          The shortcut file name (e.g. shortcut.lnk)
  1.6425 + */
  1.6426 +!macro LogStartMenuShortcut
  1.6427 +
  1.6428 +  !ifndef LogStartMenuShortcut
  1.6429 +    !insertmacro LogShortcut
  1.6430 +
  1.6431 +    !verbose push
  1.6432 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6433 +    !define LogStartMenuShortcut "!insertmacro LogStartMenuShortcutCall"
  1.6434 +
  1.6435 +    Function LogStartMenuShortcut
  1.6436 +      Call LogShortcut
  1.6437 +    FunctionEnd
  1.6438 +
  1.6439 +    !verbose pop
  1.6440 +  !endif
  1.6441 +!macroend
  1.6442 +
  1.6443 +!macro LogStartMenuShortcutCall _FILE_NAME
  1.6444 +  !verbose push
  1.6445 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6446 +  Push "STARTMENU"
  1.6447 +  Push "${_FILE_NAME}"
  1.6448 +  Call LogStartMenuShortcut
  1.6449 +  !verbose pop
  1.6450 +!macroend
  1.6451 +
  1.6452 +/**
  1.6453 + * Adds a Start Menu Programs shortcut entry to the shortcuts log ini file.
  1.6454 + *
  1.6455 + * @param   _FILE_NAME
  1.6456 + *          The shortcut file name (e.g. shortcut.lnk)
  1.6457 + */
  1.6458 +!macro LogSMProgramsShortcut
  1.6459 +
  1.6460 +  !ifndef LogSMProgramsShortcut
  1.6461 +    !insertmacro LogShortcut
  1.6462 +
  1.6463 +    !verbose push
  1.6464 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6465 +    !define LogSMProgramsShortcut "!insertmacro LogSMProgramsShortcutCall"
  1.6466 +
  1.6467 +    Function LogSMProgramsShortcut
  1.6468 +      Call LogShortcut
  1.6469 +    FunctionEnd
  1.6470 +
  1.6471 +    !verbose pop
  1.6472 +  !endif
  1.6473 +!macroend
  1.6474 +
  1.6475 +!macro LogSMProgramsShortcutCall _FILE_NAME
  1.6476 +  !verbose push
  1.6477 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6478 +  Push "SMPROGRAMS"
  1.6479 +  Push "${_FILE_NAME}"
  1.6480 +  Call LogSMProgramsShortcut
  1.6481 +  !verbose pop
  1.6482 +!macroend
  1.6483 +
  1.6484 +/**
  1.6485 + * Adds the relative path from the Start Menu Programs directory for the
  1.6486 + * application's Start Menu directory if it is different from the existing value
  1.6487 + * to the shortcuts log ini file.
  1.6488 + *
  1.6489 + * @param   _REL_PATH_TO_DIR
  1.6490 + *          The relative path from the Start Menu Programs directory to the
  1.6491 + *          program's directory.
  1.6492 + *
  1.6493 + * $R9 = _REL_PATH_TO_DIR
  1.6494 + */
  1.6495 +!macro LogSMProgramsDirRelPath _REL_PATH_TO_DIR
  1.6496 +  Push $R9
  1.6497 +
  1.6498 +  !insertmacro initShortcutsLog
  1.6499 +
  1.6500 +  ReadINIStr $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir"
  1.6501 +  StrCmp "$R9" "${_REL_PATH_TO_DIR}" +2 +1
  1.6502 +  WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" "${_REL_PATH_TO_DIR}"
  1.6503 +
  1.6504 +  Pop $R9
  1.6505 +!macroend
  1.6506 +!define LogSMProgramsDirRelPath "!insertmacro LogSMProgramsDirRelPath"
  1.6507 +
  1.6508 +/**
  1.6509 + * Copies the value for the relative path from the Start Menu programs directory
  1.6510 + * (e.g. $SMPROGRAMS) to the Start Menu directory as it is stored in the
  1.6511 + * shortcuts log ini file to the variable specified in the first parameter.
  1.6512 + */
  1.6513 +!macro GetSMProgramsDirRelPath _VAR
  1.6514 +  ReadINIStr ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" \
  1.6515 +             "RelativePathToDir"
  1.6516 +!macroend
  1.6517 +!define GetSMProgramsDirRelPath "!insertmacro GetSMProgramsDirRelPath"
  1.6518 +
  1.6519 +/**
  1.6520 + * Copies the shortcuts log ini file path to the variable specified in the
  1.6521 + * first parameter.
  1.6522 + */
  1.6523 +!macro GetShortcutsLogPath _VAR
  1.6524 +  StrCpy ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}"
  1.6525 +!macroend
  1.6526 +!define GetShortcutsLogPath "!insertmacro GetShortcutsLogPath"
  1.6527 +
  1.6528 +/**
  1.6529 + * Deletes the shortcuts log ini file.
  1.6530 + */
  1.6531 +!macro DeleteShortcutsLogFile
  1.6532 +  ${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}"
  1.6533 +!macroend
  1.6534 +!define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile"
  1.6535 +
  1.6536 +
  1.6537 +################################################################################
  1.6538 +# Macros for managing specific Windows version features
  1.6539 +
  1.6540 +/**
  1.6541 + * Sets the permitted layered service provider (LSP) categories on Windows
  1.6542 + * Vista and above for the application. Consumers should call this after an
  1.6543 + * installation log section has completed since this macro will log the results
  1.6544 + * to the installation log along with a header.
  1.6545 + *
  1.6546 + * !IMPORTANT - When calling this macro from an uninstaller do not specify a
  1.6547 + *              parameter. The paramter is hardcoded with 0x00000000 to remove
  1.6548 + *              the LSP category for the application when performing an
  1.6549 + *              uninstall.
  1.6550 + *
  1.6551 + * @param   _LSP_CATEGORIES
  1.6552 + *          The permitted LSP categories for the application. When called by an
  1.6553 + *          uninstaller this will always be 0x00000000.
  1.6554 + *
  1.6555 + * $R5 = error code popped from the stack for the WSCSetApplicationCategory call
  1.6556 + * $R6 = return value from the WSCSetApplicationCategory call
  1.6557 + * $R7 = string length for the long path to the main application executable
  1.6558 + * $R8 = long path to the main application executable
  1.6559 + * $R9 = _LSP_CATEGORIES
  1.6560 + */
  1.6561 +!macro SetAppLSPCategories
  1.6562 +
  1.6563 +  !ifndef ${_MOZFUNC_UN}SetAppLSPCategories
  1.6564 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.6565 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.6566 +    !undef _MOZFUNC_UN
  1.6567 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.6568 +    !undef _MOZFUNC_UN_TMP
  1.6569 +
  1.6570 +    !verbose push
  1.6571 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6572 +    !define ${_MOZFUNC_UN}SetAppLSPCategories "!insertmacro ${_MOZFUNC_UN}SetAppLSPCategoriesCall"
  1.6573 +
  1.6574 +    Function ${_MOZFUNC_UN}SetAppLSPCategories
  1.6575 +      ${Unless} ${AtLeastWinVista}
  1.6576 +        Return
  1.6577 +      ${EndUnless}
  1.6578 +
  1.6579 +      Exch $R9
  1.6580 +      Push $R8
  1.6581 +      Push $R7
  1.6582 +      Push $R6
  1.6583 +      Push $R5
  1.6584 +
  1.6585 +      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\${FileMainEXE}" $R8
  1.6586 +      StrLen $R7 "$R8"
  1.6587 +
  1.6588 +      ; Remove existing categories by setting the permitted categories to
  1.6589 +      ; 0x00000000 since new categories are ANDed with existing categories. If
  1.6590 +      ; the param value stored in $R9 is 0x00000000 then skip the removal since
  1.6591 +      ; the categories  will be removed by the second call to
  1.6592 +      ; WSCSetApplicationCategory.
  1.6593 +      StrCmp "$R9" "0x00000000" +2 +1
  1.6594 +      System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\
  1.6595 +                                                      i 0x00000000, i n, *i) i"
  1.6596 +
  1.6597 +      ; Set the permitted LSP categories
  1.6598 +      System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\
  1.6599 +                                                      i R9, i n, *i .s) i.R6"
  1.6600 +      Pop $R5
  1.6601 +
  1.6602 +!ifndef NO_LOG
  1.6603 +      ${LogHeader} "Setting Permitted LSP Categories"
  1.6604 +      StrCmp "$R6" 0 +3 +1
  1.6605 +      ${LogMsg} "** ERROR Setting LSP Categories: $R5 **"
  1.6606 +      GoTo +2
  1.6607 +      ${LogMsg} "Permitted LSP Categories: $R9"
  1.6608 +!endif
  1.6609 +
  1.6610 +      ClearErrors
  1.6611 +
  1.6612 +      Pop $R5
  1.6613 +      Pop $R6
  1.6614 +      Pop $R7
  1.6615 +      Pop $R8
  1.6616 +      Exch $R9
  1.6617 +    FunctionEnd
  1.6618 +
  1.6619 +    !verbose pop
  1.6620 +  !endif
  1.6621 +!macroend
  1.6622 +
  1.6623 +!macro SetAppLSPCategoriesCall _LSP_CATEGORIES
  1.6624 +  !verbose push
  1.6625 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6626 +  Push "${_LSP_CATEGORIES}"
  1.6627 +  Call SetAppLSPCategories
  1.6628 +  !verbose pop
  1.6629 +!macroend
  1.6630 +
  1.6631 +!macro un.SetAppLSPCategoriesCall
  1.6632 +  !verbose push
  1.6633 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6634 +  Push "0x00000000"
  1.6635 +  Call un.SetAppLSPCategories
  1.6636 +  !verbose pop
  1.6637 +!macroend
  1.6638 +
  1.6639 +!macro un.SetAppLSPCategories
  1.6640 +  !ifndef un.SetAppLSPCategories
  1.6641 +    !verbose push
  1.6642 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6643 +    !undef _MOZFUNC_UN
  1.6644 +    !define _MOZFUNC_UN "un."
  1.6645 +
  1.6646 +    !insertmacro SetAppLSPCategories
  1.6647 +
  1.6648 +    !undef _MOZFUNC_UN
  1.6649 +    !define _MOZFUNC_UN
  1.6650 +    !verbose pop
  1.6651 +  !endif
  1.6652 +!macroend
  1.6653 +
  1.6654 +/**
  1.6655 + * Checks if any pinned TaskBar lnk files point to the executable's path passed
  1.6656 + * to the macro.
  1.6657 + *
  1.6658 + * @param   _EXE_PATH
  1.6659 + *          The executable path
  1.6660 + * @return  _RESULT
  1.6661 + *          false if no pinned shotcuts were found for this install location.
  1.6662 + *          true if pinned shotcuts were found for this install location.
  1.6663 + *
  1.6664 + * $R5 = stores whether a TaskBar lnk file has been found for the executable
  1.6665 + * $R6 = long path returned from GetShortCutTarget and GetLongPath
  1.6666 + * $R7 = file name returned from FindFirst and FindNext
  1.6667 + * $R8 = find handle for FindFirst and FindNext
  1.6668 + * $R9 = _EXE_PATH and _RESULT
  1.6669 + */
  1.6670 +!macro IsPinnedToTaskBar
  1.6671 +
  1.6672 +  !ifndef IsPinnedToTaskBar
  1.6673 +    !insertmacro GetLongPath
  1.6674 +
  1.6675 +    !verbose push
  1.6676 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6677 +    !define IsPinnedToTaskBar "!insertmacro IsPinnedToTaskBarCall"
  1.6678 +
  1.6679 +    Function IsPinnedToTaskBar
  1.6680 +      Exch $R9
  1.6681 +      Push $R8
  1.6682 +      Push $R7
  1.6683 +      Push $R6
  1.6684 +      Push $R5
  1.6685 +
  1.6686 +      StrCpy $R5 "false"
  1.6687 +
  1.6688 +      ${If} ${AtLeastWin7}
  1.6689 +      ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar"
  1.6690 +        FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk"
  1.6691 +        ${Do}
  1.6692 +          ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7"
  1.6693 +            ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\TaskBar\$R7"
  1.6694 +            Pop $R6
  1.6695 +            ${GetLongPath} "$R6" $R6
  1.6696 +            ${If} "$R6" == "$R9"
  1.6697 +              StrCpy $R5 "true"
  1.6698 +              ${ExitDo}
  1.6699 +            ${EndIf}
  1.6700 +          ${EndIf}
  1.6701 +          ClearErrors
  1.6702 +          FindNext $R8 $R7
  1.6703 +          ${If} ${Errors}
  1.6704 +            ${ExitDo}
  1.6705 +          ${EndIf}
  1.6706 +        ${Loop}
  1.6707 +        FindClose $R8
  1.6708 +      ${EndIf}
  1.6709 +
  1.6710 +      ClearErrors
  1.6711 +
  1.6712 +      StrCpy $R9 $R5
  1.6713 +
  1.6714 +      Pop $R5
  1.6715 +      Pop $R6
  1.6716 +      Pop $R7
  1.6717 +      Pop $R8
  1.6718 +      Exch $R9
  1.6719 +    FunctionEnd
  1.6720 +
  1.6721 +    !verbose pop
  1.6722 +  !endif
  1.6723 +!macroend
  1.6724 +
  1.6725 +!macro IsPinnedToTaskBarCall _EXE_PATH _RESULT
  1.6726 +  !verbose push
  1.6727 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6728 +  Push "${_EXE_PATH}"
  1.6729 +  Call IsPinnedToTaskBar
  1.6730 +  Pop ${_RESULT}
  1.6731 +  !verbose pop
  1.6732 +!macroend
  1.6733 +
  1.6734 +/**
  1.6735 + * Checks if any pinned Start Menu lnk files point to the executable's path
  1.6736 + * passed to the macro.
  1.6737 + *
  1.6738 + * @param   _EXE_PATH
  1.6739 + *          The executable path
  1.6740 + * @return  _RESULT
  1.6741 + *          false if no pinned shotcuts were found for this install location.
  1.6742 + *          true if pinned shotcuts were found for this install location.
  1.6743 + *
  1.6744 + * $R5 = stores whether a Start Menu lnk file has been found for the executable
  1.6745 + * $R6 = long path returned from GetShortCutTarget and GetLongPath
  1.6746 + * $R7 = file name returned from FindFirst and FindNext
  1.6747 + * $R8 = find handle for FindFirst and FindNext
  1.6748 + * $R9 = _EXE_PATH and _RESULT
  1.6749 + */
  1.6750 +!macro IsPinnedToStartMenu
  1.6751 +
  1.6752 +  !ifndef IsPinnedToStartMenu
  1.6753 +    !insertmacro GetLongPath
  1.6754 +
  1.6755 +    !verbose push
  1.6756 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6757 +    !define IsPinnedToStartMenu "!insertmacro IsPinnedToStartMenuCall"
  1.6758 +
  1.6759 +    Function IsPinnedToStartMenu
  1.6760 +      Exch $R9
  1.6761 +      Push $R8
  1.6762 +      Push $R7
  1.6763 +      Push $R6
  1.6764 +      Push $R5
  1.6765 +
  1.6766 +      StrCpy $R5 "false"
  1.6767 +
  1.6768 +      ${If} ${AtLeastWin7}
  1.6769 +      ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu"
  1.6770 +        FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk"
  1.6771 +        ${Do}
  1.6772 +          ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7"
  1.6773 +            ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\StartMenu\$R7"
  1.6774 +            Pop $R6
  1.6775 +            ${GetLongPath} "$R6" $R6
  1.6776 +            ${If} "$R6" == "$R9"
  1.6777 +              StrCpy $R5 "true"
  1.6778 +              ${ExitDo}
  1.6779 +            ${EndIf}
  1.6780 +          ${EndIf}
  1.6781 +          ClearErrors
  1.6782 +          FindNext $R8 $R7
  1.6783 +          ${If} ${Errors}
  1.6784 +            ${ExitDo}
  1.6785 +          ${EndIf}
  1.6786 +        ${Loop}
  1.6787 +        FindClose $R8
  1.6788 +      ${EndIf}
  1.6789 +
  1.6790 +      ClearErrors
  1.6791 +
  1.6792 +      StrCpy $R9 $R5
  1.6793 +
  1.6794 +      Pop $R5
  1.6795 +      Pop $R6
  1.6796 +      Pop $R7
  1.6797 +      Pop $R8
  1.6798 +      Exch $R9
  1.6799 +    FunctionEnd
  1.6800 +
  1.6801 +    !verbose pop
  1.6802 +  !endif
  1.6803 +!macroend
  1.6804 +
  1.6805 +!macro IsPinnedToStartMenuCall _EXE_PATH _RESULT
  1.6806 +  !verbose push
  1.6807 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6808 +  Push "${_EXE_PATH}"
  1.6809 +  Call IsPinnedToStartMenu
  1.6810 +  Pop ${_RESULT}
  1.6811 +  !verbose pop
  1.6812 +!macroend
  1.6813 +
  1.6814 +/**
  1.6815 + * Gets the number of pinned shortcut lnk files pinned to the Task Bar.
  1.6816 + *
  1.6817 + * @return  _RESULT
  1.6818 + *          number of pinned shortcut lnk files.
  1.6819 + *
  1.6820 + * $R7 = file name returned from FindFirst and FindNext
  1.6821 + * $R8 = find handle for FindFirst and FindNext
  1.6822 + * $R9 = _RESULT
  1.6823 + */
  1.6824 +!macro PinnedToTaskBarLnkCount
  1.6825 +
  1.6826 +  !ifndef PinnedToTaskBarLnkCount
  1.6827 +    !insertmacro GetLongPath
  1.6828 +
  1.6829 +    !verbose push
  1.6830 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6831 +    !define PinnedToTaskBarLnkCount "!insertmacro PinnedToTaskBarLnkCountCall"
  1.6832 +
  1.6833 +    Function PinnedToTaskBarLnkCount
  1.6834 +      Push $R9
  1.6835 +      Push $R8
  1.6836 +      Push $R7
  1.6837 +
  1.6838 +      StrCpy $R9 0
  1.6839 +
  1.6840 +      ${If} ${AtLeastWin7}
  1.6841 +      ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar"
  1.6842 +        FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk"
  1.6843 +        ${Do}
  1.6844 +          ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7"
  1.6845 +            IntOp $R9 $R9 + 1
  1.6846 +          ${EndIf}
  1.6847 +          ClearErrors
  1.6848 +          FindNext $R8 $R7
  1.6849 +          ${If} ${Errors}
  1.6850 +            ${ExitDo}
  1.6851 +          ${EndIf}
  1.6852 +        ${Loop}
  1.6853 +        FindClose $R8
  1.6854 +      ${EndIf}
  1.6855 +
  1.6856 +      ClearErrors
  1.6857 +
  1.6858 +      Pop $R7
  1.6859 +      Pop $R8
  1.6860 +      Exch $R9
  1.6861 +    FunctionEnd
  1.6862 +
  1.6863 +    !verbose pop
  1.6864 +  !endif
  1.6865 +!macroend
  1.6866 +
  1.6867 +!macro PinnedToTaskBarLnkCountCall _RESULT
  1.6868 +  !verbose push
  1.6869 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6870 +  Call PinnedToTaskBarLnkCount
  1.6871 +  Pop ${_RESULT}
  1.6872 +  !verbose pop
  1.6873 +!macroend
  1.6874 +
  1.6875 +/**
  1.6876 + * Gets the number of pinned shortcut lnk files pinned to the Start Menu.
  1.6877 + *
  1.6878 + * @return  _RESULT
  1.6879 + *          number of pinned shortcut lnk files.
  1.6880 + *
  1.6881 + * $R7 = file name returned from FindFirst and FindNext
  1.6882 + * $R8 = find handle for FindFirst and FindNext
  1.6883 + * $R9 = _RESULT
  1.6884 + */
  1.6885 +!macro PinnedToStartMenuLnkCount
  1.6886 +
  1.6887 +  !ifndef PinnedToStartMenuLnkCount
  1.6888 +    !insertmacro GetLongPath
  1.6889 +
  1.6890 +    !verbose push
  1.6891 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6892 +    !define PinnedToStartMenuLnkCount "!insertmacro PinnedToStartMenuLnkCountCall"
  1.6893 +
  1.6894 +    Function PinnedToStartMenuLnkCount
  1.6895 +      Push $R9
  1.6896 +      Push $R8
  1.6897 +      Push $R7
  1.6898 +
  1.6899 +      StrCpy $R9 0
  1.6900 +
  1.6901 +      ${If} ${AtLeastWin7}
  1.6902 +      ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu"
  1.6903 +        FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk"
  1.6904 +        ${Do}
  1.6905 +          ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7"
  1.6906 +            IntOp $R9 $R9 + 1
  1.6907 +          ${EndIf}
  1.6908 +          ClearErrors
  1.6909 +          FindNext $R8 $R7
  1.6910 +          ${If} ${Errors}
  1.6911 +            ${ExitDo}
  1.6912 +          ${EndIf}
  1.6913 +        ${Loop}
  1.6914 +        FindClose $R8
  1.6915 +      ${EndIf}
  1.6916 +
  1.6917 +      ClearErrors
  1.6918 +
  1.6919 +      Pop $R7
  1.6920 +      Pop $R8
  1.6921 +      Exch $R9
  1.6922 +    FunctionEnd
  1.6923 +
  1.6924 +    !verbose pop
  1.6925 +  !endif
  1.6926 +!macroend
  1.6927 +
  1.6928 +!macro PinnedToStartMenuLnkCountCall _RESULT
  1.6929 +  !verbose push
  1.6930 +  !verbose ${_MOZFUNC_VERBOSE}
  1.6931 +  Call PinnedToStartMenuLnkCount
  1.6932 +  Pop ${_RESULT}
  1.6933 +  !verbose pop
  1.6934 +!macroend
  1.6935 +
  1.6936 +/**
  1.6937 + * Update Start Menu / TaskBar lnk files that point to the executable's path
  1.6938 + * passed to the macro and all other shortcuts installed by the application with
  1.6939 + * the current application user model ID. Requires ApplicationID.
  1.6940 + *
  1.6941 + * NOTE: this does not update Desktop shortcut application user model ID due to
  1.6942 + *       bug 633728.
  1.6943 + *
  1.6944 + * @param   _EXE_PATH
  1.6945 + *          The main application executable path
  1.6946 + * @param   _APP_ID
  1.6947 + *          The application user model ID for the current install
  1.6948 + * @return  _RESULT
  1.6949 + *          false if no pinned shotcuts were found for this install location.
  1.6950 + *          true if pinned shotcuts were found for this install location.
  1.6951 + */
  1.6952 +!macro UpdateShortcutAppModelIDs
  1.6953 +
  1.6954 +  !ifndef UpdateShortcutAppModelIDs
  1.6955 +    !insertmacro GetLongPath
  1.6956 +
  1.6957 +    !verbose push
  1.6958 +    !verbose ${_MOZFUNC_VERBOSE}
  1.6959 +    !define UpdateShortcutAppModelIDs "!insertmacro UpdateShortcutAppModelIDsCall"
  1.6960 +
  1.6961 +    Function UpdateShortcutAppModelIDs
  1.6962 +      ; stack: path, appid
  1.6963 +      Exch $R9 ; stack: $R9, appid | $R9 = path
  1.6964 +      Exch 1   ; stack: appid, $R9
  1.6965 +      Exch $R8 ; stack: $R8, $R9   | $R8 = appid
  1.6966 +      Push $R7 ; stack: $R7, $R8, $R9
  1.6967 +      Push $R6
  1.6968 +      Push $R5
  1.6969 +      Push $R4
  1.6970 +      Push $R3 ; stack: $R3, $R5, $R6, $R7, $R8, $R9
  1.6971 +      Push $R2
  1.6972 +
  1.6973 +      ; $R9 = main application executable path
  1.6974 +      ; $R8 = appid
  1.6975 +      ; $R7 = path to the application's start menu programs directory
  1.6976 +      ; $R6 = path to the shortcut log ini file
  1.6977 +      ; $R5 = shortcut filename
  1.6978 +      ; $R4 = GetShortCutTarget result
  1.6979 +
  1.6980 +      StrCpy $R3 "false"
  1.6981 +
  1.6982 +      ${If} ${AtLeastWin7}
  1.6983 +        ; installed shortcuts
  1.6984 +        ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6
  1.6985 +        ${If} ${FileExists} "$R6"
  1.6986 +          ; Update the Start Menu shortcuts' App ID for this application
  1.6987 +          StrCpy $R2 -1
  1.6988 +          ${Do}
  1.6989 +            IntOp $R2 $R2 + 1 ; Increment the counter
  1.6990 +            ClearErrors
  1.6991 +            ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2"
  1.6992 +            ${If} ${Errors}
  1.6993 +              ${ExitDo}
  1.6994 +            ${EndIf}
  1.6995 +
  1.6996 +            ${If} ${FileExists} "$SMPROGRAMS\$R5"
  1.6997 +              ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5"
  1.6998 +              Pop $R4
  1.6999 +              ${GetLongPath} "$R4" $R4
  1.7000 +              ${If} "$R4" == "$R9" ; link path == install path
  1.7001 +                ApplicationID::Set "$SMPROGRAMS\$R5" "$R8"
  1.7002 +                Pop $R4
  1.7003 +              ${EndIf}
  1.7004 +            ${EndIf}
  1.7005 +          ${Loop}
  1.7006 +
  1.7007 +          ; Update the Quick Launch shortcuts' App ID for this application
  1.7008 +          StrCpy $R2 -1
  1.7009 +          ${Do}
  1.7010 +            IntOp $R2 $R2 + 1 ; Increment the counter
  1.7011 +            ClearErrors
  1.7012 +            ReadINIStr $R5 "$R6" "QUICKLAUNCH" "Shortcut$R2"
  1.7013 +            ${If} ${Errors}
  1.7014 +              ${ExitDo}
  1.7015 +            ${EndIf}
  1.7016 +
  1.7017 +            ${If} ${FileExists} "$QUICKLAUNCH\$R5"
  1.7018 +              ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R5"
  1.7019 +              Pop $R4
  1.7020 +              ${GetLongPath} "$R4" $R4
  1.7021 +              ${If} "$R4" == "$R9" ; link path == install path
  1.7022 +                ApplicationID::Set "$QUICKLAUNCH\$R5" "$R8"
  1.7023 +                Pop $R4
  1.7024 +              ${EndIf}
  1.7025 +            ${EndIf}
  1.7026 +          ${Loop}
  1.7027 +
  1.7028 +          ; Update the Start Menu Programs shortcuts' App ID for this application
  1.7029 +          ClearErrors
  1.7030 +          ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir"
  1.7031 +          ${Unless} ${Errors}
  1.7032 +            ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7
  1.7033 +            ${Unless} "$R7" == ""
  1.7034 +              StrCpy $R2 -1
  1.7035 +              ${Do}
  1.7036 +                IntOp $R2 $R2 + 1 ; Increment the counter
  1.7037 +                ClearErrors
  1.7038 +                ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2"
  1.7039 +                ${If} ${Errors}
  1.7040 +                  ${ExitDo}
  1.7041 +                ${EndIf}
  1.7042 +
  1.7043 +                ${If} ${FileExists} "$R7\$R5"
  1.7044 +                  ShellLink::GetShortCutTarget "$R7\$R5"
  1.7045 +                  Pop $R4
  1.7046 +                  ${GetLongPath} "$R4" $R4
  1.7047 +                  ${If} "$R4" == "$R9" ; link path == install path
  1.7048 +                    ApplicationID::Set "$R7\$R5" "$R8"
  1.7049 +                    Pop $R4
  1.7050 +                  ${EndIf}
  1.7051 +                ${EndIf}
  1.7052 +              ${Loop}
  1.7053 +            ${EndUnless}
  1.7054 +          ${EndUnless}
  1.7055 +        ${EndIf}
  1.7056 +
  1.7057 +        StrCpy $R7 "$QUICKLAUNCH\User Pinned"
  1.7058 +        StrCpy $R3 "false"
  1.7059 +
  1.7060 +        ; $R9 = main application executable path
  1.7061 +        ; $R8 = appid
  1.7062 +        ; $R7 = user pinned path
  1.7063 +        ; $R6 = find handle
  1.7064 +        ; $R5 = found filename
  1.7065 +        ; $R4 = GetShortCutTarget result
  1.7066 +
  1.7067 +        ; TaskBar links
  1.7068 +        FindFirst $R6 $R5 "$R7\TaskBar\*.lnk"
  1.7069 +        ${Do}
  1.7070 +          ${If} ${FileExists} "$R7\TaskBar\$R5"
  1.7071 +            ShellLink::GetShortCutTarget "$R7\TaskBar\$R5"
  1.7072 +            Pop $R4
  1.7073 +            ${If} "$R4" == "$R9" ; link path == install path
  1.7074 +              ApplicationID::Set "$R7\TaskBar\$R5" "$R8"
  1.7075 +              Pop $R4 ; pop Set result off the stack
  1.7076 +              StrCpy $R3 "true"
  1.7077 +            ${EndIf}
  1.7078 +          ${EndIf}
  1.7079 +          ClearErrors
  1.7080 +          FindNext $R6 $R5
  1.7081 +          ${If} ${Errors}
  1.7082 +            ${ExitDo}
  1.7083 +          ${EndIf}
  1.7084 +        ${Loop}
  1.7085 +        FindClose $R6
  1.7086 +
  1.7087 +        ; Start menu links
  1.7088 +        FindFirst $R6 $R5 "$R7\StartMenu\*.lnk"
  1.7089 +        ${Do}
  1.7090 +          ${If} ${FileExists} "$R7\StartMenu\$R5"
  1.7091 +            ShellLink::GetShortCutTarget "$R7\StartMenu\$R5"
  1.7092 +            Pop $R4
  1.7093 +            ${If} "$R4" == "$R9" ; link path == install path
  1.7094 +              ApplicationID::Set "$R7\StartMenu\$R5" "$R8"
  1.7095 +              Pop $R4 ; pop Set result off the stack
  1.7096 +              StrCpy $R3 "true"
  1.7097 +            ${EndIf}
  1.7098 +          ${EndIf}
  1.7099 +          ClearErrors
  1.7100 +          FindNext $R6 $R5
  1.7101 +          ${If} ${Errors}
  1.7102 +            ${ExitDo}
  1.7103 +          ${EndIf}
  1.7104 +        ${Loop}
  1.7105 +        FindClose $R6
  1.7106 +      ${EndIf}
  1.7107 +
  1.7108 +      ClearErrors
  1.7109 +
  1.7110 +      StrCpy $R9 $R3
  1.7111 +
  1.7112 +      Pop $R2
  1.7113 +      Pop $R3  ; stack: $R4, $R5, $R6, $R7, $R8, $R9
  1.7114 +      Pop $R4  ; stack: $R5, $R6, $R7, $R8, $R9
  1.7115 +      Pop $R5  ; stack: $R6, $R7, $R8, $R9
  1.7116 +      Pop $R6  ; stack: $R7, $R8, $R9
  1.7117 +      Pop $R7  ; stack: $R8, $R9
  1.7118 +      Exch $R8 ; stack: appid, $R9 | $R8 = old $R8
  1.7119 +      Exch 1   ; stack: $R9, appid
  1.7120 +      Exch $R9 ; stack: path, appid | $R9 = old $R9
  1.7121 +    FunctionEnd
  1.7122 +
  1.7123 +    !verbose pop
  1.7124 +  !endif
  1.7125 +!macroend
  1.7126 +
  1.7127 +!macro UpdateShortcutAppModelIDsCall _EXE_PATH _APP_ID _RESULT
  1.7128 +  !verbose push
  1.7129 +  !verbose ${_MOZFUNC_VERBOSE}
  1.7130 +  Push "${_APP_ID}"
  1.7131 +  Push "${_EXE_PATH}"
  1.7132 +  Call UpdateShortcutAppModelIDs
  1.7133 +  Pop ${_RESULT}
  1.7134 +  !verbose pop
  1.7135 +!macroend
  1.7136 +
  1.7137 +!macro IsUserAdmin
  1.7138 +  ; Copied from: http://nsis.sourceforge.net/IsUserAdmin
  1.7139 +  Function IsUserAdmin
  1.7140 +    Push $R0
  1.7141 +    Push $R1
  1.7142 +    Push $R2
  1.7143 +
  1.7144 +    ClearErrors
  1.7145 +    UserInfo::GetName
  1.7146 +    IfErrors Win9x
  1.7147 +    Pop $R1
  1.7148 +    UserInfo::GetAccountType
  1.7149 +    Pop $R2
  1.7150 +
  1.7151 +    StrCmp $R2 "Admin" 0 Continue
  1.7152 +    StrCpy $R0 "true"
  1.7153 +    Goto Done
  1.7154 +
  1.7155 +    Continue:
  1.7156 +
  1.7157 +    StrCmp $R2 "" Win9x
  1.7158 +    StrCpy $R0 "false"
  1.7159 +    Goto Done
  1.7160 +
  1.7161 +    Win9x:
  1.7162 +    StrCpy $R0 "true"
  1.7163 +
  1.7164 +    Done:
  1.7165 +    Pop $R2
  1.7166 +    Pop $R1
  1.7167 +    Exch $R0
  1.7168 +  FunctionEnd
  1.7169 +!macroend
  1.7170 +
  1.7171 +/**
  1.7172 + * Retrieve if present or generate and store a 64 bit hash of an install path
  1.7173 + * using the City Hash algorithm.  On return the resulting id is saved in the
  1.7174 + * $AppUserModelID variable declared by inserting this macro. InitHashAppModelId
  1.7175 + * will attempt to load from HKLM/_REG_PATH first, then HKCU/_REG_PATH. If found
  1.7176 + * in either it will return the hash it finds. If not found it will generate a
  1.7177 + * new hash and attempt to store the hash in HKLM/_REG_PATH, then HKCU/_REG_PATH.
  1.7178 + * Subsequent calls will then retreive the stored hash value. On any failure,
  1.7179 + * $AppUserModelID will be set to an empty string.
  1.7180 + *
  1.7181 + * Registry format: root/_REG_PATH/"_EXE_PATH" = "hash"
  1.7182 + *
  1.7183 + * @param   _EXE_PATH
  1.7184 + *          The main application executable path
  1.7185 + * @param   _REG_PATH
  1.7186 + *          The HKLM/HKCU agnostic registry path where the key hash should
  1.7187 + *          be stored. ex: "Software\Mozilla\Firefox\TaskBarIDs"
  1.7188 + * @result  (Var) $AppUserModelID contains the app model id.
  1.7189 + */
  1.7190 +!macro InitHashAppModelId
  1.7191 +  !ifndef ${_MOZFUNC_UN}InitHashAppModelId
  1.7192 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.7193 +    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
  1.7194 +    !undef _MOZFUNC_UN
  1.7195 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.7196 +    !undef _MOZFUNC_UN_TMP
  1.7197 +
  1.7198 +    !ifndef InitHashAppModelId
  1.7199 +      Var AppUserModelID
  1.7200 +    !endif
  1.7201 +
  1.7202 +    !verbose push
  1.7203 +    !verbose ${_MOZFUNC_VERBOSE}
  1.7204 +    !define ${_MOZFUNC_UN}InitHashAppModelId "!insertmacro ${_MOZFUNC_UN}InitHashAppModelIdCall"
  1.7205 +
  1.7206 +    Function ${_MOZFUNC_UN}InitHashAppModelId
  1.7207 +      ; stack: apppath, regpath
  1.7208 +      Exch $R9 ; stack: $R9, regpath | $R9 = apppath
  1.7209 +      Exch 1   ; stack: regpath, $R9
  1.7210 +      Exch $R8 ; stack: $R8, $R9   | $R8 = regpath
  1.7211 +      Push $R7
  1.7212 +
  1.7213 +      ${If} ${AtLeastWin7}
  1.7214 +        ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9
  1.7215 +        ; Always create a new AppUserModelID and overwrite the existing one
  1.7216 +        ; for the current installation path.
  1.7217 +        CityHash::GetCityHash64 "$R9"
  1.7218 +        Pop $AppUserModelID
  1.7219 +        ${If} $AppUserModelID == "error"
  1.7220 +          GoTo end
  1.7221 +        ${EndIf}
  1.7222 +        ClearErrors
  1.7223 +        WriteRegStr HKLM "$R8" "$R9" "$AppUserModelID"
  1.7224 +        ${If} ${Errors}
  1.7225 +          ClearErrors
  1.7226 +          WriteRegStr HKCU "$R8" "$R9" "$AppUserModelID"
  1.7227 +          ${If} ${Errors}
  1.7228 +            StrCpy $AppUserModelID "error"
  1.7229 +          ${EndIf}
  1.7230 +        ${EndIf}
  1.7231 +      ${EndIf}
  1.7232 +
  1.7233 +      end:
  1.7234 +      ${If} "$AppUserModelID" == "error"
  1.7235 +        StrCpy $AppUserModelID ""
  1.7236 +      ${EndIf}
  1.7237 +
  1.7238 +      ClearErrors
  1.7239 +      Pop $R7
  1.7240 +      Exch $R8
  1.7241 +      Exch 1
  1.7242 +      Exch $R9
  1.7243 +    FunctionEnd
  1.7244 +
  1.7245 +    !verbose pop
  1.7246 +  !endif
  1.7247 +!macroend
  1.7248 +
  1.7249 +!macro InitHashAppModelIdCall _EXE_PATH _REG_PATH
  1.7250 +  !verbose push
  1.7251 +  !verbose ${_MOZFUNC_VERBOSE}
  1.7252 +  Push "${_REG_PATH}"
  1.7253 +  Push "${_EXE_PATH}"
  1.7254 +  Call InitHashAppModelId
  1.7255 +  !verbose pop
  1.7256 +!macroend
  1.7257 +
  1.7258 +!macro un.InitHashAppModelIdCall _EXE_PATH _REG_PATH
  1.7259 +  !verbose push
  1.7260 +  !verbose ${_MOZFUNC_VERBOSE}
  1.7261 +  Push "${_REG_PATH}"
  1.7262 +  Push "${_EXE_PATH}"
  1.7263 +  Call un.InitHashAppModelId
  1.7264 +  !verbose pop
  1.7265 +!macroend
  1.7266 +
  1.7267 +!macro un.InitHashAppModelId
  1.7268 +  !ifndef un.InitHashAppModelId
  1.7269 +    !verbose push
  1.7270 +    !verbose ${_MOZFUNC_VERBOSE}
  1.7271 +    !undef _MOZFUNC_UN
  1.7272 +    !define _MOZFUNC_UN "un."
  1.7273 +
  1.7274 +    !insertmacro InitHashAppModelId
  1.7275 +
  1.7276 +    !undef _MOZFUNC_UN
  1.7277 +    !define _MOZFUNC_UN
  1.7278 +    !verbose pop
  1.7279 +  !endif
  1.7280 +!macroend
  1.7281 +
  1.7282 +
  1.7283 +################################################################################
  1.7284 +# Helpers for the new user interface
  1.7285 +
  1.7286 +!ifndef MAXDWORD
  1.7287 +  !define MAXDWORD 0xffffffff
  1.7288 +!endif
  1.7289 +
  1.7290 +!ifndef DT_WORDBREAK
  1.7291 +  !define DT_WORDBREAK 0x0010
  1.7292 +!endif
  1.7293 +!ifndef DT_SINGLELINE
  1.7294 +  !define DT_SINGLELINE 0x0020
  1.7295 +!endif
  1.7296 +!ifndef DT_NOCLIP
  1.7297 +  !define DT_NOCLIP 0x0100
  1.7298 +!endif
  1.7299 +!ifndef DT_CALCRECT
  1.7300 +  !define DT_CALCRECT 0x0400
  1.7301 +!endif
  1.7302 +!ifndef DT_EDITCONTROL
  1.7303 +  !define DT_EDITCONTROL 0x2000
  1.7304 +!endif
  1.7305 +!ifndef DT_RTLREADING
  1.7306 +  !define DT_RTLREADING 0x00020000
  1.7307 +!endif
  1.7308 +!ifndef DT_NOFULLWIDTHCHARBREAK
  1.7309 +  !define DT_NOFULLWIDTHCHARBREAK 0x00080000
  1.7310 +!endif
  1.7311 +
  1.7312 +!ifndef WS_EX_NOINHERITLAYOUT
  1.7313 +  !define WS_EX_NOINHERITLAYOUT 0x00100000
  1.7314 +!endif
  1.7315 +!ifndef WS_EX_LAYOUTRTL
  1.7316 +  !define WS_EX_LAYOUTRTL 0x00400000
  1.7317 +!endif
  1.7318 +
  1.7319 +!ifndef PBS_MARQUEE
  1.7320 +  !define PBS_MARQUEE 0x08
  1.7321 +!endif
  1.7322 +
  1.7323 +!ifndef PBM_SETRANGE32
  1.7324 +  !define PBM_SETRANGE32 0x406
  1.7325 +!endif
  1.7326 +!ifndef PBM_GETRANGE
  1.7327 +  !define PBM_GETRANGE 0x407
  1.7328 +!endif
  1.7329 +
  1.7330 +!ifndef SHACF_FILESYSTEM
  1.7331 +  !define SHACF_FILESYSTEM 1
  1.7332 +!endif
  1.7333 +
  1.7334 +!define MOZ_LOADTRANSPARENT ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS}
  1.7335 +
  1.7336 +; Extend nsDialogs.nsh to support creating centered labels if it is already
  1.7337 +; included
  1.7338 +!ifmacrodef __NSD_DefineControl
  1.7339 +!insertmacro __NSD_DefineControl LabelCenter
  1.7340 +!define __NSD_LabelCenter_CLASS STATIC
  1.7341 +!define __NSD_LabelCenter_STYLE ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_CENTER}
  1.7342 +!define __NSD_LabelCenter_EXSTYLE ${WS_EX_TRANSPARENT}
  1.7343 +!endif
  1.7344 +
  1.7345 +/**
  1.7346 + * Modified version of the __NSD_SetStretchedImage macro from nsDialogs.nsh that
  1.7347 + * supports transparency. See nsDialogs documentation for additional info.
  1.7348 + */
  1.7349 +!macro __SetStretchedTransparentImage CONTROL IMAGE HANDLE
  1.7350 +  Push $0
  1.7351 +  Push $1
  1.7352 +  Push $2
  1.7353 +  Push $R0
  1.7354 +
  1.7355 +  StrCpy $R0 ${CONTROL} ; in case ${CONTROL} is $0
  1.7356 +  StrCpy $1 ""
  1.7357 +  StrCpy $2 ""
  1.7358 +
  1.7359 +  System::Call '*(i, i, i, i) i.s'
  1.7360 +  Pop $0
  1.7361 +
  1.7362 +  ${If} $0 <> 0
  1.7363 +    System::Call 'user32::GetClientRect(i R0, i r0)'
  1.7364 +    System::Call '*$0(i, i, i .s, i .s)'
  1.7365 +    System::Free $0
  1.7366 +    Pop $1
  1.7367 +    Pop $2
  1.7368 +  ${EndIf}
  1.7369 +
  1.7370 +  System::Call 'user32::LoadImageW(i 0, t s, i ${IMAGE_BITMAP}, i r1, i r2, \
  1.7371 +                                   i ${MOZ_LOADTRANSPARENT}) i .s' "${IMAGE}"
  1.7372 +  Pop $0
  1.7373 +  SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0
  1.7374 +
  1.7375 +  SetCtlColors $R0 "" transparent
  1.7376 +  ${NSD_AddExStyle} $R0 ${WS_EX_TRANSPARENT}|${WS_EX_TOPMOST}
  1.7377 +
  1.7378 +  Pop $R0
  1.7379 +  Pop $2
  1.7380 +  Pop $1
  1.7381 +  Exch $0
  1.7382 +  Pop ${HANDLE}
  1.7383 +!macroend
  1.7384 +!define SetStretchedTransparentImage `!insertmacro __SetStretchedTransparentImage`
  1.7385 +
  1.7386 +/**
  1.7387 + * Removes a single style from a control.
  1.7388 + *
  1.7389 + * _HANDLE the handle of the control
  1.7390 + * _STYLE  the style to remove
  1.7391 + */
  1.7392 +!macro _RemoveStyle _HANDLE _STYLE
  1.7393 +  Push $0
  1.7394 +
  1.7395 +  System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}) i .r0'
  1.7396 +  IntOp $0 $0 | ${_STYLE}
  1.7397 +  IntOp $0 $0 - ${_STYLE}
  1.7398 +  System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}, i r0)'
  1.7399 +
  1.7400 +  Pop $0
  1.7401 +!macroend
  1.7402 +!define RemoveStyle "!insertmacro _RemoveStyle"
  1.7403 +
  1.7404 +/**
  1.7405 + * Removes a single extended style from a control.
  1.7406 + *
  1.7407 + * _HANDLE  the handle of the control
  1.7408 + * _EXSTYLE the extended style to remove
  1.7409 + */
  1.7410 +!macro _RemoveExStyle _HANDLE _EXSTYLE
  1.7411 +  Push $0
  1.7412 +
  1.7413 +  System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}) i .r0'
  1.7414 +  IntOp $0 $0 | ${_EXSTYLE}
  1.7415 +  IntOp $0 $0 - ${_EXSTYLE}
  1.7416 +  System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}, i r0)'
  1.7417 +
  1.7418 +  Pop $0
  1.7419 +!macroend
  1.7420 +!define RemoveExStyle "!insertmacro _RemoveExStyle"
  1.7421 +
  1.7422 +/**
  1.7423 + * Gets the extent of the specified text in pixels for sizing a control.
  1.7424 + *
  1.7425 + * _TEXT       the text to get the text extent for
  1.7426 + * _FONT       the font to use when getting the text extent
  1.7427 + * _RES_WIDTH  return value - control width for the text
  1.7428 + * _RES_HEIGHT return value - control height for the text
  1.7429 + */
  1.7430 +!macro GetTextExtentCall _TEXT _FONT _RES_WIDTH _RES_HEIGHT
  1.7431 +  Push "${_TEXT}"
  1.7432 +  Push "${_FONT}"
  1.7433 +  ${CallArtificialFunction} GetTextExtent_
  1.7434 +  Pop ${_RES_WIDTH}
  1.7435 +  Pop ${_RES_HEIGHT}
  1.7436 +!macroend
  1.7437 +
  1.7438 +!define GetTextExtent "!insertmacro GetTextExtentCall"
  1.7439 +!define un.GetTextExtent "!insertmacro GetTextExtentCall"
  1.7440 +
  1.7441 +!macro GetTextExtent_
  1.7442 +  Exch $0 ; font
  1.7443 +  Exch 1
  1.7444 +  Exch $1 ; text
  1.7445 +  Push $2
  1.7446 +  Push $3
  1.7447 +  Push $4
  1.7448 +  Push $5
  1.7449 +  Push $6
  1.7450 +  Push $7
  1.7451 +
  1.7452 +  ; Reuse the existing NSIS control which is used for BrandingText instead of
  1.7453 +  ; creating a new control.
  1.7454 +  GetDlgItem $2 $HWNDPARENT 1028
  1.7455 +
  1.7456 +  System::Call 'user32::GetDC(i r2) i .r3'
  1.7457 +  System::Call 'gdi32::SelectObject(i r3, i r0)'
  1.7458 +
  1.7459 +  StrLen $4 "$1"
  1.7460 +
  1.7461 +  System::Call '*(i, i) i .r5'
  1.7462 +  System::Call 'gdi32::GetTextExtentPoint32W(i r3, t$\"$1$\", i r4, i r5)'
  1.7463 +  System::Call '*$5(i .r6, i .r7)'
  1.7464 +  System::Free $5
  1.7465 +
  1.7466 +  System::Call 'user32::ReleaseDC(i r2, i r3)'
  1.7467 +
  1.7468 +  StrCpy $1 $7
  1.7469 +  StrCpy $0 $6
  1.7470 +
  1.7471 +  Pop $7
  1.7472 +  Pop $6
  1.7473 +  Pop $5
  1.7474 +  Pop $4
  1.7475 +  Pop $3
  1.7476 +  Pop $2
  1.7477 +  Exch $1 ; return height
  1.7478 +  Exch 1
  1.7479 +  Exch $0 ; return width
  1.7480 +!macroend
  1.7481 +
  1.7482 +/**
  1.7483 + * Gets the width and the height of a control in pixels.
  1.7484 + *
  1.7485 + * _HANDLE     the handle of the control
  1.7486 + * _RES_WIDTH  return value - control width for the text
  1.7487 + * _RES_HEIGHT return value - control height for the text
  1.7488 + */
  1.7489 +!macro GetDlgItemWidthHeightCall _HANDLE _RES_WIDTH _RES_HEIGHT
  1.7490 +  Push "${_HANDLE}"
  1.7491 +  ${CallArtificialFunction} GetDlgItemWidthHeight_
  1.7492 +  Pop ${_RES_WIDTH}
  1.7493 +  Pop ${_RES_HEIGHT}
  1.7494 +!macroend
  1.7495 +
  1.7496 +!define GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall"
  1.7497 +!define un.GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall"
  1.7498 +
  1.7499 +!macro GetDlgItemWidthHeight_
  1.7500 +  Exch $0 ; handle for the control
  1.7501 +  Push $1
  1.7502 +  Push $2
  1.7503 +
  1.7504 +  System::Call '*(i, i, i, i) i .r2'
  1.7505 +  ; The left and top values will always be 0 so the right and bottom values
  1.7506 +  ; will be the width and height.
  1.7507 +  System::Call 'user32::GetClientRect(i r0, i r2)'
  1.7508 +  System::Call '*$2(i, i, i .r0, i .r1)'
  1.7509 +  System::Free $2
  1.7510 +
  1.7511 +  Pop $2
  1.7512 +  Exch $1 ; return height
  1.7513 +  Exch 1
  1.7514 +  Exch $0 ; return width
  1.7515 +!macroend
  1.7516 +
  1.7517 +/**
  1.7518 + * Gets the number of pixels from the beginning of the dialog to the end of a
  1.7519 + * control in a RTL friendly manner.
  1.7520 + *
  1.7521 + * _HANDLE the handle of the control
  1.7522 + * _RES_PX return value - pixels from the beginning of the dialog to the end of
  1.7523 + *         the control
  1.7524 + */
  1.7525 +!macro GetDlgItemEndPXCall _HANDLE _RES_PX
  1.7526 +  Push "${_HANDLE}"
  1.7527 +  ${CallArtificialFunction} GetDlgItemEndPX_
  1.7528 +  Pop ${_RES_PX}
  1.7529 +!macroend
  1.7530 +
  1.7531 +!define GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall"
  1.7532 +!define un.GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall"
  1.7533 +
  1.7534 +!macro GetDlgItemEndPX_
  1.7535 +  Exch $0 ; handle of the control
  1.7536 +  Push $1
  1.7537 +  Push $2
  1.7538 +
  1.7539 +  ; #32770 is the dialog class
  1.7540 +  FindWindow $1 "#32770" "" $HWNDPARENT
  1.7541 +  System::Call '*(i, i, i, i) i .r2'
  1.7542 +  System::Call 'user32::GetWindowRect(i r0, i r2)'
  1.7543 +  System::Call 'user32::MapWindowPoints(i 0, i r1,i r2, i 2)'
  1.7544 +  System::Call '*$2(i, i, i .r0, i)'
  1.7545 +  System::Free $2
  1.7546 +
  1.7547 +  Pop $2
  1.7548 +  Pop $1
  1.7549 +  Exch $0 ; pixels from the beginning of the dialog to the end of the control
  1.7550 +!macroend
  1.7551 +
  1.7552 +/**
  1.7553 + * Gets the width and height for sizing a control that has the specified text.
  1.7554 + * If the text has embedded newlines then the width and height will be
  1.7555 + * determined without trying to optimize the control's width and height. If the
  1.7556 + * text doesn't contain newlines the control's height and width will be
  1.7557 + * dynamically determined using a minimum of 3 lines (incrementing the
  1.7558 + * number of lines if necessary) for the height and the maximum width specified.
  1.7559 + *
  1.7560 + * _TEXT       the text
  1.7561 + * _FONT       the font to use when getting the width and height
  1.7562 + * _MAX_WIDTH  the maximum width for the control
  1.7563 + * _RES_WIDTH  return value - control width for the text
  1.7564 + * _RES_HEIGHT return value - control height for the text
  1.7565 + */
  1.7566 +!macro GetTextWidthHeight
  1.7567 +
  1.7568 +  !ifndef ${_MOZFUNC_UN}GetTextWidthHeight
  1.7569 +    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
  1.7570 +    !insertmacro ${_MOZFUNC_UN_TMP}WordFind
  1.7571 +    !undef _MOZFUNC_UN
  1.7572 +    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
  1.7573 +    !undef _MOZFUNC_UN_TMP
  1.7574 +
  1.7575 +    !verbose push
  1.7576 +    !verbose ${_MOZFUNC_VERBOSE}
  1.7577 +    !define ${_MOZFUNC_UN}GetTextWidthHeight "!insertmacro ${_MOZFUNC_UN}GetTextWidthHeightCall"
  1.7578 +
  1.7579 +    Function ${_MOZFUNC_UN}GetTextWidthHeight
  1.7580 +      Exch $0  ; maximum width use to calculate the control's width and height
  1.7581 +      Exch 1
  1.7582 +      Exch $1  ; font
  1.7583 +      Exch 2
  1.7584 +      Exch $2  ; text
  1.7585 +      Push $3
  1.7586 +      Push $4
  1.7587 +      Push $5
  1.7588 +      Push $6
  1.7589 +      Push $7
  1.7590 +      Push $8
  1.7591 +      Push $9
  1.7592 +      Push $R0
  1.7593 +      Push $R1
  1.7594 +      Push $R2
  1.7595 +
  1.7596 +      StrCpy $R2 "${DT_NOCLIP}|${DT_CALCRECT}"
  1.7597 +      !ifdef ${AB_CD}_rtl
  1.7598 +        StrCpy $R2 "$R2|${DT_RTLREADING}"
  1.7599 +      !endif
  1.7600 +
  1.7601 +      ; Reuse the existing NSIS control which is used for BrandingText instead
  1.7602 +      ; of creating a new control.
  1.7603 +      GetDlgItem $3 $HWNDPARENT 1028
  1.7604 +
  1.7605 +      System::Call 'user32::GetDC(i r3) i .r4'
  1.7606 +      System::Call 'gdi32::SelectObject(i r4, i r1)'
  1.7607 +
  1.7608 +      StrLen $5 "$2" ; text length
  1.7609 +      System::Call '*(i, i, i, i) i .r6'
  1.7610 +
  1.7611 +      ClearErrors
  1.7612 +      ${${_MOZFUNC_UN}WordFind} "$2" "$\n" "E#" $R0
  1.7613 +      ${If} ${Errors}
  1.7614 +        ; When there aren't newlines in the text calculate the size of the
  1.7615 +        ; rectangle needed for the text with a minimum of three lines of text.
  1.7616 +        ClearErrors
  1.7617 +        System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, \
  1.7618 +                                        i $R2|${DT_SINGLELINE})'
  1.7619 +        System::Call '*$6(i, i, i .r8, i .r7)'
  1.7620 +        System::Free $6
  1.7621 +
  1.7622 +        ; Get the approximate number height needed to display the text starting
  1.7623 +        ; with a minimum of 3 lines of text.
  1.7624 +        StrCpy $9 $8
  1.7625 +        StrCpy $R1 2 ; set the number of lines initially to 2
  1.7626 +        ${Do}
  1.7627 +          IntOp $R1 $R1 + 1 ; increment the number of lines
  1.7628 +          IntOp $9 $8 / $R1
  1.7629 +        ${LoopUntil} $9 < $0
  1.7630 +        IntOp $7 $7 * $R1
  1.7631 +
  1.7632 +        StrCpy $R0 $9
  1.7633 +        ${Do}
  1.7634 +          IntOp $R0 $R0 + 20
  1.7635 +          System::Call '*(i, i, i R0, i r7) i .r6'
  1.7636 +          System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, \
  1.7637 +                                          i $R2|${DT_WORDBREAK}) i .R1'
  1.7638 +          System::Call '*$6(i, i, i .r8, i .r9)'
  1.7639 +          System::Free $6
  1.7640 +        ${LoopUntil} $7 >= $R1
  1.7641 +      ${Else}
  1.7642 +        ; When there are newlines in the text just return the size of the
  1.7643 +        ; rectangle for the text.
  1.7644 +        System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, i $R2)'
  1.7645 +        System::Call '*$6(i, i, i .r8, i .r9)'
  1.7646 +        System::Free $6
  1.7647 +      ${EndIf}
  1.7648 +
  1.7649 +      ; Reselect the original DC
  1.7650 +      System::Call 'gdi32::SelectObject(i r4, i r1)'
  1.7651 +      System::Call 'user32::ReleaseDC(i r3, i r4)'
  1.7652 +
  1.7653 +      StrCpy $1 $9
  1.7654 +      StrCpy $0 $8
  1.7655 +
  1.7656 +      Pop $R2
  1.7657 +      Pop $R1
  1.7658 +      Pop $R0
  1.7659 +      Pop $9
  1.7660 +      Pop $8
  1.7661 +      Pop $7
  1.7662 +      Pop $6
  1.7663 +      Pop $5
  1.7664 +      Pop $4
  1.7665 +      Pop $3
  1.7666 +      Exch $2
  1.7667 +      Exch 2
  1.7668 +      Exch $1 ; return height
  1.7669 +      Exch 1
  1.7670 +      Exch $0 ; return width
  1.7671 +    FunctionEnd
  1.7672 +
  1.7673 +    !verbose pop
  1.7674 +  !endif
  1.7675 +!macroend
  1.7676 +
  1.7677 +!macro GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT
  1.7678 +  !verbose push
  1.7679 +  !verbose ${_MOZFUNC_VERBOSE}
  1.7680 +  Push "${_TEXT}"
  1.7681 +  Push "${_FONT}"
  1.7682 +  Push "${_MAX_WIDTH}"
  1.7683 +  Call GetTextWidthHeight
  1.7684 +  Pop ${_RES_WIDTH}
  1.7685 +  Pop ${_RES_HEIGHT}
  1.7686 +  !verbose pop
  1.7687 +!macroend
  1.7688 +
  1.7689 +!macro un.GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT
  1.7690 +  !verbose push
  1.7691 +  !verbose ${_MOZFUNC_VERBOSE}
  1.7692 +  Push "${_TEXT}"
  1.7693 +  Push "${_FONT}"
  1.7694 +  Push "${_MAX_WIDTH}"
  1.7695 +  Call un.GetTextWidthHeight
  1.7696 +  Pop ${_RES_WIDTH}
  1.7697 +  Pop ${_RES_HEIGHT}
  1.7698 +  !verbose pop
  1.7699 +!macroend
  1.7700 +
  1.7701 +!macro un.GetTextWidthHeight
  1.7702 +  !ifndef un.GetTextWidthHeight
  1.7703 +    !verbose push
  1.7704 +    !verbose ${_MOZFUNC_VERBOSE}
  1.7705 +    !undef _MOZFUNC_UN
  1.7706 +    !define _MOZFUNC_UN "un."
  1.7707 +
  1.7708 +    !insertmacro GetTextWidthHeight
  1.7709 +
  1.7710 +    !undef _MOZFUNC_UN
  1.7711 +    !define _MOZFUNC_UN
  1.7712 +    !verbose pop
  1.7713 +  !endif
  1.7714 +!macroend
  1.7715 +
  1.7716 +/**
  1.7717 + * Gets the elapsed time in seconds between two values in milliseconds stored as
  1.7718 + * an int64. The caller will typically get the millisecond values using
  1.7719 + * GetTickCount with a long return value as follows.
  1.7720 + * System::Call "kernel32::GetTickCount()l .s"
  1.7721 + * Pop $varname
  1.7722 + *
  1.7723 + * _START_TICK_COUNT    
  1.7724 + * _FINISH_TICK_COUNT   
  1.7725 + * _RES_ELAPSED_SECONDS return value - elapsed time between _START_TICK_COUNT
  1.7726 + *                      and _FINISH_TICK_COUNT in seconds.
  1.7727 + */
  1.7728 +!macro GetSecondsElapsedCall _START_TICK_COUNT _FINISH_TICK_COUNT _RES_ELAPSED_SECONDS
  1.7729 +  Push "${_START_TICK_COUNT}"
  1.7730 +  Push "${_FINISH_TICK_COUNT}"
  1.7731 +  ${CallArtificialFunction} GetSecondsElapsed_
  1.7732 +  Pop ${_RES_ELAPSED_SECONDS}
  1.7733 +!macroend
  1.7734 +
  1.7735 +!define GetSecondsElapsed "!insertmacro GetSecondsElapsedCall"
  1.7736 +!define un.GetSecondsElapsed "!insertmacro GetSecondsElapsedCall"
  1.7737 +
  1.7738 +!macro GetSecondsElapsed_
  1.7739 +  Exch $0 ; finish tick count
  1.7740 +  Exch 1
  1.7741 +  Exch $1 ; start tick count
  1.7742 +
  1.7743 +  System::Int64Op $0 - $1
  1.7744 +  Pop $0
  1.7745 +  ; Discard the top bits of the int64 by bitmasking with MAXDWORD
  1.7746 +  System::Int64Op $0 & ${MAXDWORD}
  1.7747 +  Pop $0
  1.7748 +
  1.7749 +  ; Convert from milliseconds to seconds
  1.7750 +  System::Int64Op $0 / 1000
  1.7751 +  Pop $0
  1.7752 +
  1.7753 +  Pop $1
  1.7754 +  Exch $0 ; return elapsed seconds
  1.7755 +!macroend
  1.7756 +
  1.7757 +!ifdef MOZ_METRO
  1.7758 +; Removes the CEH registration if it's set to our installation directory.
  1.7759 +; If it's set to some other installation directory, then it should be removed
  1.7760 +; by that installation.
  1.7761 +!macro RemoveDEHRegistrationIfMatchingCall un
  1.7762 +
  1.7763 +  Function ${un}RemoveDEHRegistrationIfMatchingCall
  1.7764 +    ; Retrieve DEH ID from the stack into $R9
  1.7765 +    Exch $R9
  1.7766 +    Exch 1
  1.7767 +
  1.7768 +    ; Retrieve Protocol Activation ID from stack into $R8
  1.7769 +    Exch $R8
  1.7770 +    Exch 2
  1.7771 +
  1.7772 +    ; Retrieve File Activation ID from stack into $R7
  1.7773 +    Exch $R7
  1.7774 +
  1.7775 +    ; Backup the old values of R6 and R5 on the stack
  1.7776 +    Push $R6
  1.7777 +    Push $R5
  1.7778 +
  1.7779 +    ; Conditionally remove the DEH as long as we are the default (HKCU)
  1.7780 +    ReadRegStr $R6 HKCU "Software\Classes\CLSID\$R9\LocalServer32" ""
  1.7781 +    ${${un}GetLongPath} "$INSTDIR" $R5
  1.7782 +    StrCmp "$R6" "" next +1
  1.7783 +    IfFileExists "$R6" +1 clearHKCU
  1.7784 +    ${${un}GetParent} "$R6" $R6
  1.7785 +    ${${un}GetLongPath} "$R6" $R6
  1.7786 +    StrCmp "$R5" "$R6" clearHKCU next
  1.7787 +    clearHKCU:
  1.7788 +    DeleteRegKey HKCU "Software\Classes\CLSID\$R9"
  1.7789 +    DeleteRegValue HKCU "Software\Classes\$R8\shell\open\command" "DelegateExecute"
  1.7790 +    DeleteRegValue HKCU "Software\Classes\$R7\shell\open\command" "DelegateExecute"
  1.7791 +    next:
  1.7792 +
  1.7793 +    ; Conditionally remove the DEH as long as we are the default (HKLM)
  1.7794 +    ReadRegStr $R6 HKLM "Software\Classes\CLSID\$R9\LocalServer32" ""
  1.7795 +    ${${un}GetLongPath} "$INSTDIR" $R5
  1.7796 +    StrCmp "$R6" "" done +1
  1.7797 +    IfFileExists "$R6" +1 clearHKLM
  1.7798 +    ${${un}GetParent} "$R6" $R6
  1.7799 +    ${${un}GetLongPath} "$R6" $R6
  1.7800 +    StrCmp "$R5" "$R6" clearHKLM done
  1.7801 +    clearHKLM:
  1.7802 +    DeleteRegKey HKLM "Software\Classes\CLSID\$R9"
  1.7803 +    DeleteRegValue HKLM "Software\Classes\$R8\shell\open\command" "DelegateExecute"
  1.7804 +    DeleteRegValue HKLM "Software\Classes\$R7\shell\open\command" "DelegateExecute"
  1.7805 +    done:
  1.7806 +
  1.7807 +    ; Always remove the AppUserModelID keys for this installation
  1.7808 +    DeleteRegKey HKCU "Software\Classes\$AppUserModelID"
  1.7809 +    DeleteRegKey HKLM "Software\Classes\$AppUserModelID"
  1.7810 +
  1.7811 +    ; Restore the registers back to their original state
  1.7812 +    Pop $R5
  1.7813 +    Pop $R6
  1.7814 +    Exch $R7
  1.7815 +    Exch 2
  1.7816 +    Exch $R8
  1.7817 +    Exch 1
  1.7818 +    Exch $R9
  1.7819 +  FunctionEnd
  1.7820 +!macroend
  1.7821 +
  1.7822 +!macro RemoveDEHRegistrationIfMatching
  1.7823 +  !insertmacro RemoveDEHRegistrationIfMatchingCall ""
  1.7824 +!macroend
  1.7825 +
  1.7826 +!macro un.RemoveDEHRegistrationIfMatching
  1.7827 +  !insertmacro RemoveDEHRegistrationIfMatchingCall "un."
  1.7828 +!macroend
  1.7829 +
  1.7830 +!macro CleanupMetroBrowserHandlerValues un DELEGATE_EXECUTE_HANDLER_ID \
  1.7831 +                                           PROTOCOL_ACTIVATION_ID \
  1.7832 +                                           FILE_ACTIVATION_ID
  1.7833 +  Push ${FILE_ACTIVATION_ID}
  1.7834 +  Push ${PROTOCOL_ACTIVATION_ID}
  1.7835 +  Push ${DELEGATE_EXECUTE_HANDLER_ID}
  1.7836 +  Call ${un}RemoveDEHRegistrationIfMatchingCall
  1.7837 +!macroend
  1.7838 +!define CleanupMetroBrowserHandlerValues '!insertmacro CleanupMetroBrowserHandlerValues ""'
  1.7839 +!define un.CleanupMetroBrowserHandlerValues '!insertmacro CleanupMetroBrowserHandlerValues "un."'
  1.7840 +
  1.7841 +!macro AddMetroBrowserHandlerValues DELEGATE_EXECUTE_HANDLER_ID \
  1.7842 +                                    DELEGATE_EXECUTE_HANDLER_PATH \
  1.7843 +                                    APP_USER_MODEL_ID \
  1.7844 +                                    PROTOCOL_ACTIVATION_ID \
  1.7845 +                                    FILE_ACTIVATION_ID
  1.7846 +  ; Win8 doesn't use conventional progid command data to launch anymore.
  1.7847 +  ; Instead it uses a delegate execute handler which is a light weight COM
  1.7848 +  ; server for choosing the metro or desktop browser to launch depending
  1.7849 +  ; on the current environment (metro/desktop) it was activated in.
  1.7850 +  WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}" "" ""
  1.7851 +  WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe" "" ""
  1.7852 +  WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell" "" "open"
  1.7853 +  WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell\open" "CommandId" "open"
  1.7854 +  WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell\open\command" "" "$2"
  1.7855 +  WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell\open\command" "DelegateExecute" "${DELEGATE_EXECUTE_HANDLER_ID}"
  1.7856 +
  1.7857 +  ; Augment the url handler registrations with additional data needed for Metro
  1.7858 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}" "AppUserModelID" "${APP_USER_MODEL_ID}"
  1.7859 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "AppUserModelID" "${APP_USER_MODEL_ID}"
  1.7860 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationName" "$BrandShortName"
  1.7861 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationIcon" "$INSTDIR\${FileMainEXE},0"
  1.7862 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationCompany" "${CompanyName}"
  1.7863 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationDescription" "$(REG_APP_DESC)"
  1.7864 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\shell" "" "open"
  1.7865 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\shell\open" "CommandId" "open"
  1.7866 +  WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\shell\open\command" "DelegateExecute" "${DELEGATE_EXECUTE_HANDLER_ID}"
  1.7867 +
  1.7868 +  ; Augment the file handler registrations with additional data needed for Metro
  1.7869 +  WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}" "AppUserModelID" "${APP_USER_MODEL_ID}"
  1.7870 +  WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}\shell" "" "open"
  1.7871 +  WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}\shell\open" "CommandId" "open"
  1.7872 +  WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}\shell\open\command" "DelegateExecute" "${DELEGATE_EXECUTE_HANDLER_ID}"
  1.7873 +
  1.7874 +  ; Win8 Metro delegate execute handler registration
  1.7875 +  WriteRegStr SHCTX "Software\Classes\CLSID\${DELEGATE_EXECUTE_HANDLER_ID}" "" "$BrandShortName CommandExecuteHandler"
  1.7876 +  WriteRegStr SHCTX "Software\Classes\CLSID\${DELEGATE_EXECUTE_HANDLER_ID}" "AppId" "${DELEGATE_EXECUTE_HANDLER_ID}"
  1.7877 +  WriteRegStr SHCTX "Software\Classes\CLSID\${DELEGATE_EXECUTE_HANDLER_ID}\LocalServer32" "" "${DELEGATE_EXECUTE_HANDLER_PATH}"
  1.7878 +!macroend
  1.7879 +!define AddMetroBrowserHandlerValues "!insertmacro AddMetroBrowserHandlerValues"
  1.7880 +!endif ;end MOZ_METRO
  1.7881 +

mercurial