1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 6################################################################################ 7# Helper defines and macros for toolkit applications 8 9/** 10 * Avoid creating macros / functions that overwrite registers (see the 11 * GetLongPath macro for one way to avoid this)! 12 * 13 * Before using the registers exchange the passed in params and save existing 14 * register values to the stack. 15 * 16 * Exch $R9 ; exhange the original $R9 with the top of the stack 17 * Exch 1 ; exchange the top of the stack with 1 below the top of the stack 18 * Exch $R8 ; exchange the original $R8 with the top of the stack 19 * Exch 2 ; exchange the top of the stack with 2 below the top of the stack 20 * Exch $R7 ; exchange the original $R7 with the top of the stack 21 * Push $R6 ; push the original $R6 onto the top of the stack 22 * Push $R5 ; push the original $R5 onto the top of the stack 23 * Push $R4 ; push the original $R4 onto the top of the stack 24 * 25 * <do stuff> 26 * 27 * ; Restore the values. 28 * Pop $R4 ; restore the value for $R4 from the top of the stack 29 * Pop $R5 ; restore the value for $R5 from the top of the stack 30 * Pop $R6 ; restore the value for $R6 from the top of the stack 31 * Exch $R7 ; exchange the new $R7 value with the top of the stack 32 * Exch 2 ; exchange the top of the stack with 2 below the top of the stack 33 * Exch $R8 ; exchange the new $R8 value with the top of the stack 34 * Exch 1 ; exchange the top of the stack with 2 below the top of the stack 35 * Exch $R9 ; exchange the new $R9 value with the top of the stack 36 * 37 * 38 * When inserting macros in common.nsh from another macro in common.nsh that 39 * can be used from the uninstaller _MOZFUNC_UN will be undefined when it is 40 * inserted. Use the following to redefine _MOZFUNC_UN with its original value 41 * (see the RegCleanMain macro for an example). 42 * 43 * !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 44 * !insertmacro ${_MOZFUNC_UN_TMP}FileJoin 45 * !insertmacro ${_MOZFUNC_UN_TMP}LineFind 46 * !insertmacro ${_MOZFUNC_UN_TMP}TextCompareNoDetails 47 * !insertmacro ${_MOZFUNC_UN_TMP}TrimNewLines 48 * !undef _MOZFUNC_UN 49 * !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 50 * !undef _MOZFUNC_UN_TMP 51 */ 52 53; When including a file provided by NSIS check if its verbose macro is defined 54; to prevent loading the file a second time. 55!ifmacrondef TEXTFUNC_VERBOSE 56 !include TextFunc.nsh 57!endif 58 59!ifmacrondef FILEFUNC_VERBOSE 60 !include FileFunc.nsh 61!endif 62 63!ifmacrondef LOGICLIB_VERBOSITY 64 !include LogicLib.nsh 65!endif 66 67!ifndef WINMESSAGES_INCLUDED 68 !include WinMessages.nsh 69!endif 70 71; When including WinVer.nsh check if ___WINVER__NSH___ is defined to prevent 72; loading the file a second time. 73!ifndef ___WINVER__NSH___ 74 !include WinVer.nsh 75!endif 76 77; When including x64.nsh check if ___X64__NSH___ is defined to prevent 78; loading the file a second time. 79!ifndef ___X64__NSH___ 80 !include x64.nsh 81!endif 82 83; NSIS provided macros that we have overridden. 84!include overrides.nsh 85 86!define SHORTCUTS_LOG "shortcuts_log.ini" 87!define TO_BE_DELETED "tobedeleted" 88 89; !define SHCNF_DWORD 0x0003 90; !define SHCNF_FLUSH 0x1000 91!ifndef SHCNF_DWORDFLUSH 92 !define SHCNF_DWORDFLUSH 0x1003 93!endif 94!ifndef SHCNE_ASSOCCHANGED 95 !define SHCNE_ASSOCCHANGED 0x08000000 96!endif 97 98################################################################################ 99# Macros for debugging 100 101/** 102 * The following two macros assist with verifying that a macro doesn't 103 * overwrite any registers. 104 * 105 * Usage: 106 * ${debugSetRegisters} 107 * <do stuff> 108 * ${debugDisplayRegisters} 109 */ 110 111/** 112 * Sets all register values to their name to assist with verifying that a macro 113 * doesn't overwrite any registers. 114 */ 115!macro debugSetRegisters 116 StrCpy $0 "$$0" 117 StrCpy $1 "$$1" 118 StrCpy $2 "$$2" 119 StrCpy $3 "$$3" 120 StrCpy $4 "$$4" 121 StrCpy $5 "$$5" 122 StrCpy $6 "$$6" 123 StrCpy $7 "$$7" 124 StrCpy $8 "$$8" 125 StrCpy $9 "$$9" 126 StrCpy $R0 "$$R0" 127 StrCpy $R1 "$$R1" 128 StrCpy $R2 "$$R2" 129 StrCpy $R3 "$$R3" 130 StrCpy $R4 "$$R4" 131 StrCpy $R5 "$$R5" 132 StrCpy $R6 "$$R6" 133 StrCpy $R7 "$$R7" 134 StrCpy $R8 "$$R8" 135 StrCpy $R9 "$$R9" 136!macroend 137!define debugSetRegisters "!insertmacro debugSetRegisters" 138 139/** 140 * Displays all register values to assist with verifying that a macro doesn't 141 * overwrite any registers. 142 */ 143!macro debugDisplayRegisters 144 MessageBox MB_OK \ 145 "Register Values:$\n\ 146 $$0 = $0$\n$$1 = $1$\n$$2 = $2$\n$$3 = $3$\n$$4 = $4$\n\ 147 $$5 = $5$\n$$6 = $6$\n$$7 = $7$\n$$8 = $8$\n$$9 = $9$\n\ 148 $$R0 = $R0$\n$$R1 = $R1$\n$$R2 = $R2$\n$$R3 = $R3$\n$$R4 = $R4$\n\ 149 $$R5 = $R5$\n$$R6 = $R6$\n$$R7 = $R7$\n$$R8 = $R8$\n$$R9 = $R9" 150!macroend 151!define debugDisplayRegisters "!insertmacro debugDisplayRegisters" 152 153 154################################################################################ 155# Modern User Interface (MUI) override macros 156 157; Removed macros in nsis 2.33u (ported from nsis 2.22) 158; MUI_LANGUAGEFILE_DEFINE 159; MUI_LANGUAGEFILE_LANGSTRING_PAGE 160; MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE 161; MUI_LANGUAGEFILE_LANGSTRING_DEFINE 162; MUI_LANGUAGEFILE_UNLANGSTRING_PAGE 163 164!macro MOZ_MUI_LANGUAGEFILE_DEFINE DEFINE NAME 165 166 !ifndef "${DEFINE}" 167 !define "${DEFINE}" "${${NAME}}" 168 !endif 169 !undef "${NAME}" 170 171!macroend 172 173!macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE PAGE NAME 174 175 !ifdef MUI_${PAGE}PAGE 176 LangString "${NAME}" 0 "${${NAME}}" 177 !undef "${NAME}" 178 !else 179 !undef "${NAME}" 180 !endif 181 182!macroend 183 184!macro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE PAGE NAME 185 186 !ifdef MUI_${PAGE}PAGE | MUI_UN${PAGE}PAGE 187 LangString "${NAME}" 0 "${${NAME}}" 188 !undef "${NAME}" 189 !else 190 !undef "${NAME}" 191 !endif 192 193!macroend 194 195!macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE DEFINE NAME 196 197 !ifdef "${DEFINE}" 198 LangString "${NAME}" 0 "${${NAME}}" 199 !endif 200 !undef "${NAME}" 201 202!macroend 203 204!macro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE PAGE NAME 205 206 !ifdef MUI_UNINSTALLER 207 !ifdef MUI_UN${PAGE}PAGE 208 LangString "${NAME}" 0 "${${NAME}}" 209 !undef "${NAME}" 210 !else 211 !undef "${NAME}" 212 !endif 213 !else 214 !undef "${NAME}" 215 !endif 216 217!macroend 218 219; Modified version of the following MUI macros to support Mozilla localization. 220; MUI_LANGUAGE 221; MUI_LANGUAGEFILE_BEGIN 222; MOZ_MUI_LANGUAGEFILE_END 223; See <NSIS App Dir>/Contrib/Modern UI/System.nsh for more information 224!define MUI_INSTALLOPTIONS_READ "!insertmacro MUI_INSTALLOPTIONS_READ" 225 226!macro MOZ_MUI_LANGUAGE LANGUAGE 227 !verbose push 228 !verbose ${MUI_VERBOSE} 229 !include "${LANGUAGE}.nsh" 230 !verbose pop 231!macroend 232 233!macro MOZ_MUI_LANGUAGEFILE_BEGIN LANGUAGE 234 !insertmacro MUI_INSERT 235 !ifndef "MUI_LANGUAGEFILE_${LANGUAGE}_USED" 236 !define "MUI_LANGUAGEFILE_${LANGUAGE}_USED" 237 LoadLanguageFile "${LANGUAGE}.nlf" 238 !else 239 !error "Modern UI language file ${LANGUAGE} included twice!" 240 !endif 241!macroend 242 243; Custom version of MUI_LANGUAGEFILE_END. The macro to add the default MUI 244; strings and the macros for several strings that are part of the NSIS MUI and 245; not in our locale files have been commented out. 246!macro MOZ_MUI_LANGUAGEFILE_END 247 248# !include "${NSISDIR}\Contrib\Modern UI\Language files\Default.nsh" 249 !ifdef MUI_LANGUAGEFILE_DEFAULT_USED 250 !undef MUI_LANGUAGEFILE_DEFAULT_USED 251 !warning "${LANGUAGE} Modern UI language file version doesn't match. Using default English texts for missing strings." 252 !endif 253 254 !insertmacro MOZ_MUI_LANGUAGEFILE_DEFINE "MUI_${LANGUAGE}_LANGNAME" "MUI_LANGNAME" 255 256 !ifndef MUI_LANGDLL_PUSHLIST 257 !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} " 258 !else 259 !ifdef MUI_LANGDLL_PUSHLIST_TEMP 260 !undef MUI_LANGDLL_PUSHLIST_TEMP 261 !endif 262 !define MUI_LANGDLL_PUSHLIST_TEMP "${MUI_LANGDLL_PUSHLIST}" 263 !undef MUI_LANGDLL_PUSHLIST 264 !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} ${MUI_LANGDLL_PUSHLIST_TEMP}" 265 !endif 266 267 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TITLE" 268 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TEXT" 269 270!ifdef MUI_TEXT_LICENSE_TITLE 271 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_TITLE" 272!endif 273!ifdef MUI_TEXT_LICENSE_SUBTITLE 274 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_SUBTITLE" 275!endif 276!ifdef MUI_INNERTEXT_LICENSE_TOP 277 !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_TOP" 278!endif 279 280# !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM" 281 282!ifdef MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX 283 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX" 284!endif 285 286!ifdef MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS 287 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS" 288!endif 289 290 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_TITLE" 291 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_SUBTITLE" 292 !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE" 293 !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO" 294 295 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_TITLE" 296 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_SUBTITLE" 297 298 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_TITLE" 299 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_SUBTITLE" 300 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_TOP" 301# !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_CHECKBOX" 302 303 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_TITLE" 304 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_SUBTITLE" 305 306 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_TITLE" 307 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_SUBTITLE" 308 309 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_TITLE" 310 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_SUBTITLE" 311 312 !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_BUTTONTEXT_FINISH" 313 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TITLE" 314 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TEXT" 315 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_REBOOT" 316 !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTNOW" 317 !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTLATER" 318# !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_RUN" 319# !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_SHOWREADME" 320 321; Support for using the existing MUI_TEXT_ABORTWARNING string 322!ifdef MOZ_MUI_CUSTOM_ABORT 323 LangString MOZ_MUI_TEXT_ABORTWARNING 0 "${MUI_TEXT_ABORTWARNING}" 324!endif 325 326 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_ABORTWARNING "MUI_TEXT_ABORTWARNING" 327 328 329 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TITLE" 330 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TEXT" 331 332 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_TITLE" 333 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_SUBTITLE" 334 335# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_TITLE" 336# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_SUBTITLE" 337 338# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM" 339# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_CHECKBOX" 340# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS" 341 342# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_TITLE" 343# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_SUBTITLE" 344 345# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_TITLE" 346# !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_SUBTITLE" 347 348 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_TITLE" 349 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_SUBTITLE" 350 351 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_TITLE" 352 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_SUBTITLE" 353 354 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_TITLE" 355 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_SUBTITLE" 356 357 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TITLE" 358 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TEXT" 359 !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_REBOOT" 360 361 !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_UNABORTWARNING "MUI_UNTEXT_ABORTWARNING" 362 363 !ifndef MUI_LANGDLL_LANGUAGES 364 !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' " 365 !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' " 366 !else 367 !ifdef MUI_LANGDLL_LANGUAGES_TEMP 368 !undef MUI_LANGDLL_LANGUAGES_TEMP 369 !endif 370 !define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}" 371 !undef MUI_LANGDLL_LANGUAGES 372 373 !ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP 374 !undef MUI_LANGDLL_LANGUAGES_CP_TEMP 375 !endif 376 !define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}" 377 !undef MUI_LANGDLL_LANGUAGES_CP 378 379 !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}" 380 !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}" 381 !endif 382 383!macroend 384 385/** 386 * Creates an InstallOptions file with a UTF-16LE BOM and adds the RTL value 387 * to the Settings section. 388 * 389 * @param _FILE 390 * The name of the file to be created in $PLUGINSDIR. 391 */ 392!macro InitInstallOptionsFile _FILE 393 Push $R9 394 395 FileOpen $R9 "$PLUGINSDIR\${_FILE}" w 396 FileWriteWord $R9 "65279" 397 FileClose $R9 398 WriteIniStr "$PLUGINSDIR\${_FILE}" "Settings" "RTL" "$(^RTL)" 399 400 Pop $R9 401!macroend 402 403 404################################################################################ 405# Macros for handling files in use 406 407/** 408 * Checks for files in use in the $INSTDIR directory. To check files in 409 * sub-directories this macro would need to be rewritten to create 410 * sub-directories in the temporary directory used to backup the files that are 411 * checked. 412 * 413 * Example usage: 414 * 415 * ; The first string to be pushed onto the stack MUST be "end" to indicate 416 * ; that there are no more files in the $INSTDIR directory to check. 417 * Push "end" 418 * Push "freebl3.dll" 419 * ; The last file pushed should be the app's main exe so if it is in use this 420 * ; macro will return after the first check. 421 * Push "${FileMainEXE}" 422 * ${CheckForFilesInUse} $R9 423 * 424 * !IMPORTANT - this macro uses the $R7, $R8, and $R9 registers and makes no 425 * attempt to restore their original values. 426 * 427 * @return _RESULT 428 * false if all of the files popped from the stack are not in use. 429 * True if any of the files popped from the stack are in use. 430 * $R7 = Temporary backup directory where the files will be copied to. 431 * $R8 = value popped from the stack. This will either be a file name for a file 432 * in the $INSTDIR directory or "end" to indicate that there are no 433 * additional files to check. 434 * $R9 = _RESULT 435 */ 436!macro CheckForFilesInUse 437 438 !ifndef ${_MOZFUNC_UN}CheckForFilesInUse 439 !verbose push 440 !verbose ${_MOZFUNC_VERBOSE} 441 !define ${_MOZFUNC_UN}CheckForFilesInUse "!insertmacro ${_MOZFUNC_UN}CheckForFilesInUseCall" 442 443 Function ${_MOZFUNC_UN}CheckForFilesInUse 444 ; Create a temporary backup directory. 445 GetTempFileName $R7 "$INSTDIR" 446 Delete "$R7" 447 SetOutPath "$R7" 448 StrCpy $R9 "false" 449 450 Pop $R8 451 ${While} $R8 != "end" 452 ${Unless} ${FileExists} "$INSTDIR\$R8" 453 Pop $R8 ; get next file to check before continuing 454 ${Continue} 455 ${EndUnless} 456 457 ClearErrors 458 CopyFiles /SILENT "$INSTDIR\$R8" "$R7\$R8" ; try to copy 459 ${If} ${Errors} 460 ; File is in use 461 StrCpy $R9 "true" 462 ${Break} 463 ${EndIf} 464 465 Delete "$INSTDIR\$R8" ; delete original 466 ${If} ${Errors} 467 ; File is in use 468 StrCpy $R9 "true" 469 Delete "$R7\$R8" ; delete temp copy 470 ${Break} 471 ${EndIf} 472 473 Pop $R8 ; get next file to check 474 ${EndWhile} 475 476 ; clear stack 477 ${While} $R8 != "end" 478 Pop $R8 479 ${EndWhile} 480 481 ; restore everything 482 SetOutPath "$INSTDIR" 483 CopyFiles /SILENT "$R7\*" "$INSTDIR\" 484 RmDir /r "$R7" 485 SetOutPath "$EXEDIR" 486 ClearErrors 487 488 Push $R9 489 FunctionEnd 490 491 !verbose pop 492 !endif 493!macroend 494 495!macro CheckForFilesInUseCall _RESULT 496 !verbose push 497 !verbose ${_MOZFUNC_VERBOSE} 498 Call CheckForFilesInUse 499 Pop ${_RESULT} 500 !verbose pop 501!macroend 502 503!macro un.CheckForFilesInUseCall _RESULT 504 !verbose push 505 !verbose ${_MOZFUNC_VERBOSE} 506 Call un.CheckForFilesInUse 507 Pop ${_RESULT} 508 !verbose pop 509!macroend 510 511!macro un.CheckForFilesInUse 512 !ifndef un.CheckForFilesInUse 513 !verbose push 514 !verbose ${_MOZFUNC_VERBOSE} 515 !undef _MOZFUNC_UN 516 !define _MOZFUNC_UN "un." 517 518 !insertmacro CheckForFilesInUse 519 520 !undef _MOZFUNC_UN 521 !define _MOZFUNC_UN 522 !verbose pop 523 !endif 524!macroend 525 526/** 527 * The macros below will automatically prepend un. to the function names when 528 * they are defined (e.g. !define un.RegCleanMain). 529 */ 530!verbose push 531!verbose 3 532!ifndef _MOZFUNC_VERBOSE 533 !define _MOZFUNC_VERBOSE 3 534!endif 535!verbose ${_MOZFUNC_VERBOSE} 536!define MOZFUNC_VERBOSE "!insertmacro MOZFUNC_VERBOSE" 537!define _MOZFUNC_UN 538!define _MOZFUNC_S 539!verbose pop 540 541!macro MOZFUNC_VERBOSE _VERBOSE 542 !verbose push 543 !verbose 3 544 !undef _MOZFUNC_VERBOSE 545 !define _MOZFUNC_VERBOSE ${_VERBOSE} 546 !verbose pop 547!macroend 548 549/** 550 * Displays a MessageBox and then calls abort to prevent continuing to the 551 * next page when the specified Window Class is found. 552 * 553 * @param _WINDOW_CLASS 554 * The Window Class to search for with FindWindow. 555 * @param _MSG 556 * The message text to display in the message box. 557 * 558 * $R7 = return value from FindWindow 559 * $R8 = _WINDOW_CLASS 560 * $R9 = _MSG 561 */ 562!macro ManualCloseAppPrompt 563 564 !ifndef ${_MOZFUNC_UN}ManualCloseAppPrompt 565 !verbose push 566 !verbose ${_MOZFUNC_VERBOSE} 567 !define ${_MOZFUNC_UN}ManualCloseAppPrompt "!insertmacro ${_MOZFUNC_UN}ManualCloseAppPromptCall" 568 569 Function ${_MOZFUNC_UN}ManualCloseAppPrompt 570 Exch $R9 571 Exch 1 572 Exch $R8 573 Push $R7 574 575 FindWindow $R7 "$R8" 576 ${If} $R7 <> 0 ; integer comparison 577 MessageBox MB_OK|MB_ICONQUESTION "$R9" 578 Abort 579 ${EndIf} 580 581 Pop $R7 582 Exch $R8 583 Exch 1 584 Exch $R9 585 FunctionEnd 586 587 !verbose pop 588 !endif 589!macroend 590 591!macro ManualCloseAppPromptCall _WINDOW_CLASS _MSG 592 !verbose push 593 !verbose ${_MOZFUNC_VERBOSE} 594 Push "${_WINDOW_CLASS}" 595 Push "${_MSG}" 596 Call ManualCloseAppPrompt 597 !verbose pop 598!macroend 599 600!macro un.ManualCloseAppPromptCall _WINDOW_CLASS _MSG 601 !verbose push 602 !verbose ${_MOZFUNC_VERBOSE} 603 Push "${_WINDOW_CLASS}" 604 Push "${_MSG}" 605 Call un.ManualCloseAppPrompt 606 !verbose pop 607!macroend 608 609!macro un.ManualCloseAppPrompt 610 !ifndef un.ManualCloseAppPrompt 611 !verbose push 612 !verbose ${_MOZFUNC_VERBOSE} 613 !undef _MOZFUNC_UN 614 !define _MOZFUNC_UN "un." 615 616 !insertmacro ManualCloseAppPrompt 617 618 !undef _MOZFUNC_UN 619 !define _MOZFUNC_UN 620 !verbose pop 621 !endif 622!macroend 623 624 625################################################################################ 626# Macros for working with the registry 627 628/** 629 * Writes a registry string using SHCTX and the supplied params and logs the 630 * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1. 631 * 632 * Define NO_LOG to prevent all logging when calling this from the uninstaller. 633 * 634 * @param _ROOT 635 * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). 636 * This will only be used for logging. 637 * @param _KEY 638 * The subkey in relation to the key root. 639 * @param _NAME 640 * The key value name to write to. 641 * @param _STR 642 * The string to write to the key value name. 643 * @param _LOG_UNINSTALL 644 * 0 = don't add to uninstall log, 1 = add to uninstall log. 645 * 646 * $R5 = _ROOT 647 * $R6 = _KEY 648 * $R7 = _NAME 649 * $R8 = _STR 650 * $R9 = _LOG_UNINSTALL 651 */ 652!macro WriteRegStr2 653 654 !ifndef ${_MOZFUNC_UN}WriteRegStr2 655 !verbose push 656 !verbose ${_MOZFUNC_VERBOSE} 657 !define ${_MOZFUNC_UN}WriteRegStr2 "!insertmacro ${_MOZFUNC_UN}WriteRegStr2Call" 658 659 Function ${_MOZFUNC_UN}WriteRegStr2 660 Exch $R9 661 Exch 1 662 Exch $R8 663 Exch 2 664 Exch $R7 665 Exch 3 666 Exch $R6 667 Exch 4 668 Exch $R5 669 670 ClearErrors 671 WriteRegStr SHCTX "$R6" "$R7" "$R8" 672 673 !ifndef NO_LOG 674 ${If} ${Errors} 675 ${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **" 676 ${Else} 677 ${If} $R9 == 1 ; add to the uninstall log? 678 ${LogUninstall} "RegVal: $R5 | $R6 | $R7" 679 ${EndIf} 680 ${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8" 681 ${EndIf} 682 !endif 683 684 Exch $R5 685 Exch 4 686 Exch $R6 687 Exch 3 688 Exch $R7 689 Exch 2 690 Exch $R8 691 Exch 1 692 Exch $R9 693 FunctionEnd 694 695 !verbose pop 696 !endif 697!macroend 698 699!macro WriteRegStr2Call _ROOT _KEY _NAME _STR _LOG_UNINSTALL 700 !verbose push 701 !verbose ${_MOZFUNC_VERBOSE} 702 Push "${_ROOT}" 703 Push "${_KEY}" 704 Push "${_NAME}" 705 Push "${_STR}" 706 Push "${_LOG_UNINSTALL}" 707 Call WriteRegStr2 708 !verbose pop 709!macroend 710 711!macro un.WriteRegStr2Call _ROOT _KEY _NAME _STR _LOG_UNINSTALL 712 !verbose push 713 !verbose ${_MOZFUNC_VERBOSE} 714 Push "${_ROOT}" 715 Push "${_KEY}" 716 Push "${_NAME}" 717 Push "${_STR}" 718 Push "${_LOG_UNINSTALL}" 719 Call un.WriteRegStr2 720 !verbose pop 721!macroend 722 723!macro un.WriteRegStr2 724 !ifndef un.WriteRegStr2 725 !verbose push 726 !verbose ${_MOZFUNC_VERBOSE} 727 !undef _MOZFUNC_UN 728 !define _MOZFUNC_UN "un." 729 730 !insertmacro WriteRegStr2 731 732 !undef _MOZFUNC_UN 733 !define _MOZFUNC_UN 734 !verbose pop 735 !endif 736!macroend 737 738/** 739 * Writes a registry dword using SHCTX and the supplied params and logs the 740 * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1. 741 * 742 * Define NO_LOG to prevent all logging when calling this from the uninstaller. 743 * 744 * @param _ROOT 745 * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). 746 * This will only be used for logging. 747 * @param _KEY 748 * The subkey in relation to the key root. 749 * @param _NAME 750 * The key value name to write to. 751 * @param _DWORD 752 * The dword to write to the key value name. 753 * @param _LOG_UNINSTALL 754 * 0 = don't add to uninstall log, 1 = add to uninstall log. 755 * 756 * $R5 = _ROOT 757 * $R6 = _KEY 758 * $R7 = _NAME 759 * $R8 = _DWORD 760 * $R9 = _LOG_UNINSTALL 761 */ 762!macro WriteRegDWORD2 763 764 !ifndef ${_MOZFUNC_UN}WriteRegDWORD2 765 !verbose push 766 !verbose ${_MOZFUNC_VERBOSE} 767 !define ${_MOZFUNC_UN}WriteRegDWORD2 "!insertmacro ${_MOZFUNC_UN}WriteRegDWORD2Call" 768 769 Function ${_MOZFUNC_UN}WriteRegDWORD2 770 Exch $R9 771 Exch 1 772 Exch $R8 773 Exch 2 774 Exch $R7 775 Exch 3 776 Exch $R6 777 Exch 4 778 Exch $R5 779 780 ClearErrors 781 WriteRegDWORD SHCTX "$R6" "$R7" "$R8" 782 783 !ifndef NO_LOG 784 ${If} ${Errors} 785 ${LogMsg} "** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **" 786 ${Else} 787 ${If} $R9 == 1 ; add to the uninstall log? 788 ${LogUninstall} "RegVal: $R5 | $R6 | $R7" 789 ${EndIf} 790 ${LogMsg} "Added Registry DWord: $R5 | $R6 | $R7 | $R8" 791 ${EndIf} 792 !endif 793 794 Exch $R5 795 Exch 4 796 Exch $R6 797 Exch 3 798 Exch $R7 799 Exch 2 800 Exch $R8 801 Exch 1 802 Exch $R9 803 FunctionEnd 804 805 !verbose pop 806 !endif 807!macroend 808 809!macro WriteRegDWORD2Call _ROOT _KEY _NAME _DWORD _LOG_UNINSTALL 810 !verbose push 811 !verbose ${_MOZFUNC_VERBOSE} 812 Push "${_ROOT}" 813 Push "${_KEY}" 814 Push "${_NAME}" 815 Push "${_DWORD}" 816 Push "${_LOG_UNINSTALL}" 817 Call WriteRegDWORD2 818 !verbose pop 819!macroend 820 821!macro un.WriteRegDWORD2Call _ROOT _KEY _NAME _DWORD _LOG_UNINSTALL 822 !verbose push 823 !verbose ${_MOZFUNC_VERBOSE} 824 Push "${_ROOT}" 825 Push "${_KEY}" 826 Push "${_NAME}" 827 Push "${_DWORD}" 828 Push "${_LOG_UNINSTALL}" 829 Call un.WriteRegDWORD2 830 !verbose pop 831!macroend 832 833!macro un.WriteRegDWORD2 834 !ifndef un.WriteRegDWORD2 835 !verbose push 836 !verbose ${_MOZFUNC_VERBOSE} 837 !undef _MOZFUNC_UN 838 !define _MOZFUNC_UN "un." 839 840 !insertmacro WriteRegDWORD2 841 842 !undef _MOZFUNC_UN 843 !define _MOZFUNC_UN 844 !verbose pop 845 !endif 846!macroend 847 848/** 849 * Writes a registry string to HKCR using the supplied params and logs the 850 * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1. 851 * 852 * Define NO_LOG to prevent all logging when calling this from the uninstaller. 853 * 854 * @param _ROOT 855 * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). 856 * This will only be used for logging. 857 * @param _KEY 858 * The subkey in relation to the key root. 859 * @param _NAME 860 * The key value name to write to. 861 * @param _STR 862 * The string to write to the key value name. 863 * @param _LOG_UNINSTALL 864 * 0 = don't add to uninstall log, 1 = add to uninstall log. 865 * 866 * $R5 = _ROOT 867 * $R6 = _KEY 868 * $R7 = _NAME 869 * $R8 = _STR 870 * $R9 = _LOG_UNINSTALL 871 */ 872!macro WriteRegStrHKCR 873 874 !ifndef ${_MOZFUNC_UN}WriteRegStrHKCR 875 !verbose push 876 !verbose ${_MOZFUNC_VERBOSE} 877 !define ${_MOZFUNC_UN}WriteRegStrHKCR "!insertmacro ${_MOZFUNC_UN}WriteRegStrHKCRCall" 878 879 Function ${_MOZFUNC_UN}WriteRegStrHKCR 880 Exch $R9 881 Exch 1 882 Exch $R8 883 Exch 2 884 Exch $R7 885 Exch 3 886 Exch $R6 887 Exch 4 888 Exch $R5 889 890 ClearErrors 891 WriteRegStr HKCR "$R6" "$R7" "$R8" 892 893 !ifndef NO_LOG 894 ${If} ${Errors} 895 ${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **" 896 ${Else} 897 ${If} $R9 == 1 ; add to the uninstall log? 898 ${LogUninstall} "RegVal: $R5 | $R6 | $R7" 899 ${EndIf} 900 ${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8" 901 ${EndIf} 902 !endif 903 904 Exch $R5 905 Exch 4 906 Exch $R6 907 Exch 3 908 Exch $R7 909 Exch 2 910 Exch $R8 911 Exch 1 912 Exch $R9 913 FunctionEnd 914 915 !verbose pop 916 !endif 917!macroend 918 919!macro WriteRegStrHKCRCall _ROOT _KEY _NAME _STR _LOG_UNINSTALL 920 !verbose push 921 !verbose ${_MOZFUNC_VERBOSE} 922 Push "${_ROOT}" 923 Push "${_KEY}" 924 Push "${_NAME}" 925 Push "${_STR}" 926 Push "${_LOG_UNINSTALL}" 927 Call WriteRegStrHKCR 928 !verbose pop 929!macroend 930 931!macro un.WriteRegStrHKCRCall _ROOT _KEY _NAME _STR _LOG_UNINSTALL 932 !verbose push 933 !verbose ${_MOZFUNC_VERBOSE} 934 Push "${_ROOT}" 935 Push "${_KEY}" 936 Push "${_NAME}" 937 Push "${_STR}" 938 Push "${_LOG_UNINSTALL}" 939 Call un.WriteRegStrHKCR 940 !verbose pop 941!macroend 942 943!macro un.WriteRegStrHKCR 944 !ifndef un.WriteRegStrHKCR 945 !verbose push 946 !verbose ${_MOZFUNC_VERBOSE} 947 !undef _MOZFUNC_UN 948 !define _MOZFUNC_UN "un." 949 950 !insertmacro WriteRegStrHKCR 951 952 !undef _MOZFUNC_UN 953 !define _MOZFUNC_UN 954 !verbose pop 955 !endif 956!macroend 957 958!ifndef KEY_SET_VALUE 959 !define KEY_SET_VALUE 0x0002 960!endif 961!ifndef KEY_WOW64_64KEY 962 !define KEY_WOW64_64KEY 0x0100 963!endif 964!ifndef HAVE_64BIT_BUILD 965 !define CREATE_KEY_SAM ${KEY_SET_VALUE} 966!else 967 !define CREATE_KEY_SAM ${KEY_SET_VALUE}|${KEY_WOW64_64KEY} 968!endif 969 970/** 971 * Creates a registry key. This will log the actions to the install and 972 * uninstall logs. Alternatively you can set a registry value to create the key 973 * and then delete the value. 974 * 975 * Define NO_LOG to prevent all logging when calling this from the uninstaller. 976 * 977 * @param _ROOT 978 * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). 979 * @param _KEY 980 * The subkey in relation to the key root. 981 * @param _LOG_UNINSTALL 982 * 0 = don't add to uninstall log, 1 = add to uninstall log. 983 * 984 * $R4 = [out] handle to newly created registry key. If this is not a key 985 * located in one of the predefined registry keys this must be closed 986 * with RegCloseKey (this should not be needed unless someone decides to 987 * do something extremely squirrelly with NSIS). 988 * $R5 = return value from RegCreateKeyExW (represented by R5 in the system call). 989 * $R6 = [in] hKey passed to RegCreateKeyExW. 990 * $R7 = _ROOT 991 * $R8 = _KEY 992 * $R9 = _LOG_UNINSTALL 993 */ 994!macro CreateRegKey 995 996 !ifndef ${_MOZFUNC_UN}CreateRegKey 997 !verbose push 998 !verbose ${_MOZFUNC_VERBOSE} 999 !define ${_MOZFUNC_UN}CreateRegKey "!insertmacro ${_MOZFUNC_UN}CreateRegKeyCall" 1000 1001 Function ${_MOZFUNC_UN}CreateRegKey 1002 Exch $R9 1003 Exch 1 1004 Exch $R8 1005 Exch 2 1006 Exch $R7 1007 Push $R6 1008 Push $R5 1009 Push $R4 1010 1011 StrCmp $R7 "HKCR" +1 +2 1012 StrCpy $R6 "0x80000000" 1013 StrCmp $R7 "HKCU" +1 +2 1014 StrCpy $R6 "0x80000001" 1015 StrCmp $R7 "HKLM" +1 +2 1016 StrCpy $R6 "0x80000002" 1017 1018 ; see definition of RegCreateKey 1019 System::Call "Advapi32::RegCreateKeyExW(i R6, w R8, i 0, i 0, i 0,\ 1020 i ${CREATE_KEY_SAM}, i 0, *i .R4,\ 1021 i 0) i .R5" 1022 1023 !ifndef NO_LOG 1024 ; if $R5 is not 0 then there was an error creating the registry key. 1025 ${If} $R5 <> 0 1026 ${LogMsg} "** ERROR Adding Registry Key: $R7 | $R8 **" 1027 ${Else} 1028 ${If} $R9 == 1 ; add to the uninstall log? 1029 ${LogUninstall} "RegKey: $R7 | $R8" 1030 ${EndIf} 1031 ${LogMsg} "Added Registry Key: $R7 | $R8" 1032 ${EndIf} 1033 !endif 1034 1035 StrCmp $R5 0 +1 +2 1036 System::Call "Advapi32::RegCloseKey(iR4)" 1037 1038 Pop $R4 1039 Pop $R5 1040 Pop $R6 1041 Exch $R7 1042 Exch 2 1043 Exch $R8 1044 Exch 1 1045 Exch $R9 1046 FunctionEnd 1047 1048 !verbose pop 1049 !endif 1050!macroend 1051 1052!macro CreateRegKeyCall _ROOT _KEY _LOG_UNINSTALL 1053 !verbose push 1054 !verbose ${_MOZFUNC_VERBOSE} 1055 Push "${_ROOT}" 1056 Push "${_KEY}" 1057 Push "${_LOG_UNINSTALL}" 1058 Call CreateRegKey 1059 !verbose pop 1060!macroend 1061 1062!macro un.CreateRegKeyCall _ROOT _KEY _LOG_UNINSTALL 1063 !verbose push 1064 !verbose ${_MOZFUNC_VERBOSE} 1065 Push "${_ROOT}" 1066 Push "${_KEY}" 1067 Push "${_LOG_UNINSTALL}" 1068 Call un.CreateRegKey 1069 !verbose pop 1070!macroend 1071 1072!macro un.CreateRegKey 1073 !ifndef un.CreateRegKey 1074 !verbose push 1075 !verbose ${_MOZFUNC_VERBOSE} 1076 !undef _MOZFUNC_UN 1077 !define _MOZFUNC_UN "un." 1078 1079 !insertmacro CreateRegKey 1080 1081 !undef _MOZFUNC_UN 1082 !define _MOZFUNC_UN 1083 !verbose pop 1084 !endif 1085!macroend 1086 1087/** 1088 * Helper for checking for the existence of a registry key. 1089 * SHCTX is the root key to search. 1090 * 1091 * @param _MAIN_KEY 1092 * Sub key to iterate for the key in question 1093 * @param _KEY 1094 * Key name to search for 1095 * @return _RESULT 1096 * 'true' / 'false' result 1097 */ 1098!macro CheckIfRegistryKeyExists 1099 !ifndef CheckIfRegistryKeyExists 1100 !verbose push 1101 !verbose ${_MOZFUNC_VERBOSE} 1102 !define CheckIfRegistryKeyExists "!insertmacro CheckIfRegistryKeyExistsCall" 1103 1104 Function CheckIfRegistryKeyExists 1105 ; stack: main key, key 1106 Exch $R9 ; main key, stack: old R9, key 1107 Exch 1 ; stack: key, old R9 1108 Exch $R8 ; key, stack: old R8, old R9 1109 Push $R7 1110 Push $R6 1111 Push $R5 1112 1113 StrCpy $R5 "false" 1114 StrCpy $R7 "0" # loop index 1115 ${Do} 1116 EnumRegKey $R6 SHCTX "$R9" "$R7" 1117 ${If} "$R6" == "$R8" 1118 StrCpy $R5 "true" 1119 ${Break} 1120 ${EndIf} 1121 IntOp $R7 $R7 + 1 1122 ${LoopWhile} $R6 != "" 1123 ClearErrors 1124 1125 StrCpy $R9 $R5 1126 1127 Pop $R5 1128 Pop $R6 1129 Pop $R7 ; stack: old R8, old R9 1130 Pop $R8 ; stack: old R9 1131 Exch $R9 ; stack: result 1132 FunctionEnd 1133 1134 !verbose pop 1135 !endif 1136!macroend 1137 1138!macro CheckIfRegistryKeyExistsCall _MAIN_KEY _KEY _RESULT 1139 !verbose push 1140 !verbose ${_MOZFUNC_VERBOSE} 1141 Push "${_KEY}" 1142 Push "${_MAIN_KEY}" 1143 Call CheckIfRegistryKeyExists 1144 Pop ${_RESULT} 1145 !verbose pop 1146!macroend 1147 1148/** 1149 * Read the value of an installer pref that's been set by the product. 1150 * 1151 * @param _KEY ($R1) 1152 * Sub key containing all the installer prefs 1153 * Usually "Software\Mozilla\${AppName}" 1154 * @param _PREF ($R2) 1155 * Name of the pref to look up 1156 * @return _RESULT ($R3) 1157 * 'true' or 'false' (only boolean prefs are supported) 1158 * If no value exists for the requested pref, the result is 'false' 1159 */ 1160!macro GetInstallerRegistryPref 1161 !ifndef ${_MOZFUNC_UN}GetInstallerRegistryPref 1162 !verbose push 1163 !verbose ${_MOZFUNC_VERBOSE} 1164 !define ${_MOZFUNC_UN}GetInstallerRegistryPref "!insertmacro GetInstallerRegistryPrefCall" 1165 1166 Function ${_MOZFUNC_UN}GetInstallerRegistryPref 1167 ; stack: key, pref 1168 Exch $R1 ; key, stack: old R1, pref 1169 Exch 1 ; stack: pref, old R1 1170 Exch $R2 ; pref, stack: old R2, old R1 1171 Push $R3 1172 1173 StrCpy $R3 0 1174 1175 ; These prefs are always stored in the native registry. 1176 SetRegView 64 1177 1178 ClearErrors 1179 ReadRegDWORD $R3 HKCU "$R1\Installer\$AppUserModelID" "$R2" 1180 1181 SetRegView lastused 1182 1183 ${IfNot} ${Errors} 1184 ${AndIf} $R3 != 0 1185 StrCpy $R1 "true" 1186 ${Else} 1187 StrCpy $R1 "false" 1188 ${EndIf} 1189 1190 ; stack: old R3, old R2, old R1 1191 Pop $R3 ; stack: old R2, old R1 1192 Pop $R2 ; stack: old R1 1193 Exch $R1 ; stack: result 1194 FunctionEnd 1195 1196 !verbose pop 1197 !endif 1198!macroend 1199 1200!macro GetInstallerRegistryPrefCall _KEY _PREF _RESULT 1201 !verbose push 1202 !verbose ${_MOZFUNC_VERBOSE} 1203 Push "${_PREF}" 1204 Push "${_KEY}" 1205 Call GetInstallerRegistryPref 1206 Pop ${_RESULT} 1207 !verbose pop 1208!macroend 1209 1210!macro un.GetInstallerRegistryPrefCall _KEY _PREF _RESULT 1211 !verbose push 1212 !verbose ${_MOZFUNC_VERBOSE} 1213 Push "${_PREF}" 1214 Push "${_KEY}" 1215 Call un.GetInstallerRegistryPref 1216 Pop ${_RESULT} 1217 !verbose pop 1218!macroend 1219 1220!macro un.GetInstallerRegistryPref 1221 !ifndef un.GetInstallerRegistryPref 1222 !verbose push 1223 !verbose ${_MOZFUNC_VERBOSE} 1224 !undef _MOZFUNC_UN 1225 !define _MOZFUNC_UN "un." 1226 1227 !insertmacro GetInstallerRegistryPref 1228 1229 !undef _MOZFUNC_UN 1230 !define _MOZFUNC_UN 1231 !verbose pop 1232 !endif 1233!macroend 1234 1235################################################################################ 1236# Macros for adding file and protocol handlers 1237 1238/** 1239 * Writes common registry values for a handler using SHCTX. 1240 * 1241 * @param _KEY 1242 * The subkey in relation to the key root. 1243 * @param _VALOPEN 1244 * The path and args to launch the application. 1245 * @param _VALICON 1246 * The path to the binary that contains the icon group for the default icon 1247 * followed by a comma and either the icon group's resource index or the icon 1248 * group's resource id prefixed with a minus sign 1249 * @param _DISPNAME 1250 * The display name for the handler. If emtpy no value will be set. 1251 * @param _ISPROTOCOL 1252 * Sets protocol handler specific registry values when "true". 1253 * Deletes protocol handler specific registry values when "delete". 1254 * Otherwise doesn't touch handler specific registry values. 1255 * @param _ISDDE 1256 * Sets DDE specific registry values when "true". 1257 * 1258 * $R3 = string value of the current registry key path. 1259 * $R4 = _KEY 1260 * $R5 = _VALOPEN 1261 * $R6 = _VALICON 1262 * $R7 = _DISPNAME 1263 * $R8 = _ISPROTOCOL 1264 * $R9 = _ISDDE 1265 */ 1266!macro AddHandlerValues 1267 1268 !ifndef ${_MOZFUNC_UN}AddHandlerValues 1269 !verbose push 1270 !verbose ${_MOZFUNC_VERBOSE} 1271 !define ${_MOZFUNC_UN}AddHandlerValues "!insertmacro ${_MOZFUNC_UN}AddHandlerValuesCall" 1272 1273 Function ${_MOZFUNC_UN}AddHandlerValues 1274 Exch $R9 1275 Exch 1 1276 Exch $R8 1277 Exch 2 1278 Exch $R7 1279 Exch 3 1280 Exch $R6 1281 Exch 4 1282 Exch $R5 1283 Exch 5 1284 Exch $R4 1285 Push $R3 1286 1287 StrCmp "$R7" "" +6 +1 1288 ReadRegStr $R3 SHCTX "$R4" "FriendlyTypeName" 1289 1290 StrCmp "$R3" "" +1 +3 1291 WriteRegStr SHCTX "$R4" "" "$R7" 1292 WriteRegStr SHCTX "$R4" "FriendlyTypeName" "$R7" 1293 1294 StrCmp "$R8" "true" +1 +2 1295 WriteRegStr SHCTX "$R4" "URL Protocol" "" 1296 StrCmp "$R8" "delete" +1 +2 1297 DeleteRegValue SHCTX "$R4" "URL Protocol" 1298 StrCpy $R3 "" 1299 ReadRegDWord $R3 SHCTX "$R4" "EditFlags" 1300 StrCmp $R3 "" +1 +3 ; Only add EditFlags if a value doesn't exist 1301 DeleteRegValue SHCTX "$R4" "EditFlags" 1302 WriteRegDWord SHCTX "$R4" "EditFlags" 0x00000002 1303 1304 StrCmp "$R6" "" +2 +1 1305 WriteRegStr SHCTX "$R4\DefaultIcon" "" "$R6" 1306 1307 StrCmp "$R5" "" +2 +1 1308 WriteRegStr SHCTX "$R4\shell\open\command" "" "$R5" 1309 1310!ifdef DDEApplication 1311 StrCmp "$R9" "true" +1 +11 1312 WriteRegStr SHCTX "$R4\shell\open\ddeexec" "" "$\"%1$\",,0,0,,,," 1313 WriteRegStr SHCTX "$R4\shell\open\ddeexec" "NoActivateHandler" "" 1314 WriteRegStr SHCTX "$R4\shell\open\ddeexec\Application" "" "${DDEApplication}" 1315 WriteRegStr SHCTX "$R4\shell\open\ddeexec\Topic" "" "WWW_OpenURL" 1316 ; The ifexec key may have been added by another application so try to 1317 ; delete it to prevent it from breaking this app's shell integration. 1318 ; Also, IE 6 and below doesn't remove this key when it sets itself as the 1319 ; default handler and if this key exists IE's shell integration breaks. 1320 DeleteRegKey HKLM "$R4\shell\open\ddeexec\ifexec" 1321 DeleteRegKey HKCU "$R4\shell\open\ddeexec\ifexec" 1322!endif 1323 1324 ClearErrors 1325 1326 Pop $R3 1327 Exch $R4 1328 Exch 5 1329 Exch $R5 1330 Exch 4 1331 Exch $R6 1332 Exch 3 1333 Exch $R7 1334 Exch 2 1335 Exch $R8 1336 Exch 1 1337 Exch $R9 1338 FunctionEnd 1339 1340 !verbose pop 1341 !endif 1342!macroend 1343 1344!macro AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE 1345 !verbose push 1346 !verbose ${_MOZFUNC_VERBOSE} 1347 Push "${_KEY}" 1348 Push "${_VALOPEN}" 1349 Push "${_VALICON}" 1350 Push "${_DISPNAME}" 1351 Push "${_ISPROTOCOL}" 1352 Push "${_ISDDE}" 1353 Call AddHandlerValues 1354 !verbose pop 1355!macroend 1356 1357!macro un.AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE 1358 !verbose push 1359 !verbose ${_MOZFUNC_VERBOSE} 1360 Push "${_KEY}" 1361 Push "${_VALOPEN}" 1362 Push "${_VALICON}" 1363 Push "${_DISPNAME}" 1364 Push "${_ISPROTOCOL}" 1365 Push "${_ISDDE}" 1366 Call un.AddHandlerValues 1367 !verbose pop 1368!macroend 1369 1370!macro un.AddHandlerValues 1371 !ifndef un.AddHandlerValues 1372 !verbose push 1373 !verbose ${_MOZFUNC_VERBOSE} 1374 !undef _MOZFUNC_UN 1375 !define _MOZFUNC_UN "un." 1376 1377 !insertmacro AddHandlerValues 1378 1379 !undef _MOZFUNC_UN 1380 !define _MOZFUNC_UN 1381 !verbose pop 1382 !endif 1383!macroend 1384 1385/** 1386 * Writes common registry values for a handler that DOES NOT use DDE using SHCTX. 1387 * 1388 * @param _KEY 1389 * The key name in relation to the HKCR root. SOFTWARE\Classes is 1390 * prefixed to this value when using SHCTX. 1391 * @param _VALOPEN 1392 * The path and args to launch the application. 1393 * @param _VALICON 1394 * The path to the binary that contains the icon group for the default icon 1395 * followed by a comma and either the icon group's resource index or the icon 1396 * group's resource id prefixed with a minus sign 1397 * @param _DISPNAME 1398 * The display name for the handler. If emtpy no value will be set. 1399 * @param _ISPROTOCOL 1400 * Sets protocol handler specific registry values when "true". 1401 * Deletes protocol handler specific registry values when "delete". 1402 * Otherwise doesn't touch handler specific registry values. 1403 * 1404 * $R3 = storage for SOFTWARE\Classes 1405 * $R4 = string value of the current registry key path. 1406 * $R5 = _KEY 1407 * $R6 = _VALOPEN 1408 * $R7 = _VALICON 1409 * $R8 = _DISPNAME 1410 * $R9 = _ISPROTOCOL 1411 */ 1412!macro AddDisabledDDEHandlerValues 1413 1414 !ifndef ${_MOZFUNC_UN}AddDisabledDDEHandlerValues 1415 !verbose push 1416 !verbose ${_MOZFUNC_VERBOSE} 1417 !define ${_MOZFUNC_UN}AddDisabledDDEHandlerValues "!insertmacro ${_MOZFUNC_UN}AddDisabledDDEHandlerValuesCall" 1418 1419 Function ${_MOZFUNC_UN}AddDisabledDDEHandlerValues 1420 Exch $R9 ; _ISPROTOCOL 1421 Exch 1 1422 Exch $R8 ; FriendlyTypeName 1423 Exch 2 1424 Exch $R7 ; icon index 1425 Exch 3 1426 Exch $R6 ; shell\open\command 1427 Exch 4 1428 Exch $R5 ; reg key 1429 Push $R4 ; 1430 Push $R3 ; base reg class 1431 1432 StrCpy $R3 "SOFTWARE\Classes" 1433 StrCmp "$R8" "" +6 +1 1434 ReadRegStr $R4 SHCTX "$R5" "FriendlyTypeName" 1435 1436 StrCmp "$R4" "" +1 +3 1437 WriteRegStr SHCTX "$R3\$R5" "" "$R8" 1438 WriteRegStr SHCTX "$R3\$R5" "FriendlyTypeName" "$R8" 1439 1440 StrCmp "$R9" "true" +1 +2 1441 WriteRegStr SHCTX "$R3\$R5" "URL Protocol" "" 1442 StrCmp "$R9" "delete" +1 +2 1443 DeleteRegValue SHCTX "$R3\$R5" "URL Protocol" 1444 StrCpy $R4 "" 1445 ReadRegDWord $R4 SHCTX "$R3\$R5" "EditFlags" 1446 StrCmp $R4 "" +1 +3 ; Only add EditFlags if a value doesn't exist 1447 DeleteRegValue SHCTX "$R3\$R5" "EditFlags" 1448 WriteRegDWord SHCTX "$R3\$R5" "EditFlags" 0x00000002 1449 1450 StrCmp "$R7" "" +2 +1 1451 WriteRegStr SHCTX "$R3\$R5\DefaultIcon" "" "$R7" 1452 1453 ; Main command handler for the app 1454 WriteRegStr SHCTX "$R3\$R5\shell" "" "open" 1455 WriteRegStr SHCTX "$R3\$R5\shell\open\command" "" "$R6" 1456 1457 ; Drop support for DDE (bug 491947), and remove old dde entries if 1458 ; they exist. 1459 ; 1460 ; Note, changes in SHCTX should propegate to hkey classes root when 1461 ; current user or local machine entries are written. Windows will also 1462 ; attempt to propegate entries when a handler is used. CR entries are a 1463 ; combination of LM and CU, with CU taking priority. 1464 ; 1465 ; To disable dde, an empty shell/ddeexec key must be created in current 1466 ; user or local machine. Unfortunately, settings have various different 1467 ; behaviors depending on the windows version. The following code attempts 1468 ; to address these differences. 1469 ; 1470 ; IE does not configure ddeexec, so issues with left over ddeexec keys 1471 ; in LM are reduced. We configure an empty ddeexec key with an empty default 1472 ; string in CU to be sure. 1473 ; 1474 DeleteRegKey SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec" 1475 WriteRegStr SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec" "" "" 1476 1477 ClearErrors 1478 1479 Pop $R3 1480 Pop $R4 1481 Exch $R5 1482 Exch 4 1483 Exch $R6 1484 Exch 3 1485 Exch $R7 1486 Exch 2 1487 Exch $R8 1488 Exch 1 1489 Exch $R9 1490 FunctionEnd 1491 1492 !verbose pop 1493 !endif 1494!macroend 1495 1496!macro AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL 1497 !verbose push 1498 !verbose ${_MOZFUNC_VERBOSE} 1499 Push "${_KEY}" 1500 Push "${_VALOPEN}" 1501 Push "${_VALICON}" 1502 Push "${_DISPNAME}" 1503 Push "${_ISPROTOCOL}" 1504 Call AddDisabledDDEHandlerValues 1505 !verbose pop 1506!macroend 1507 1508!macro un.AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL 1509 !verbose push 1510 !verbose ${_MOZFUNC_VERBOSE} 1511 Push "${_KEY}" 1512 Push "${_VALOPEN}" 1513 Push "${_VALICON}" 1514 Push "${_DISPNAME}" 1515 Push "${_ISPROTOCOL}" 1516 Call un.AddDisabledDDEHandlerValues 1517 !verbose pop 1518!macroend 1519 1520!macro un.AddDisabledDDEHandlerValues 1521 !ifndef un.AddDisabledDDEHandlerValues 1522 !verbose push 1523 !verbose ${_MOZFUNC_VERBOSE} 1524 !undef _MOZFUNC_UN 1525 !define _MOZFUNC_UN "un." 1526 1527 !insertmacro AddDisabledDDEHandlerValues 1528 1529 !undef _MOZFUNC_UN 1530 !define _MOZFUNC_UN 1531 !verbose pop 1532 !endif 1533!macroend 1534 1535 1536################################################################################ 1537# Macros for handling DLL registration 1538 1539!macro RegisterDLL DLL 1540 1541 ; The x64 regsvr32.exe registers x86 DLL's properly so just use it 1542 ; when installing on an x64 systems even when installing an x86 application. 1543 ${If} ${RunningX64} 1544 ${OrIf} ${IsNativeARM64} 1545 ${DisableX64FSRedirection} 1546 ExecWait '"$SYSDIR\regsvr32.exe" /s "${DLL}"' 1547 ${EnableX64FSRedirection} 1548 ${Else} 1549 RegDLL "${DLL}" 1550 ${EndIf} 1551 1552!macroend 1553 1554!macro UnregisterDLL DLL 1555 1556 ; The x64 regsvr32.exe registers x86 DLL's properly so just use it 1557 ; when installing on an x64 systems even when installing an x86 application. 1558 ${If} ${RunningX64} 1559 ${OrIf} ${IsNativeARM64} 1560 ${DisableX64FSRedirection} 1561 ExecWait '"$SYSDIR\regsvr32.exe" /s /u "${DLL}"' 1562 ${EnableX64FSRedirection} 1563 ${Else} 1564 UnRegDLL "${DLL}" 1565 ${EndIf} 1566 1567!macroend 1568 1569!define RegisterDLL "!insertmacro RegisterDLL" 1570!define UnregisterDLL "!insertmacro UnregisterDLL" 1571 1572 1573################################################################################ 1574# Macros for retrieving existing install paths 1575 1576/** 1577 * Finds a second installation of the application so we can make informed 1578 * decisions about registry operations. This uses SHCTX to determine the 1579 * registry hive so you must call SetShellVarContext first. 1580 * 1581 * @param _KEY 1582 * The registry subkey (typically this will be Software\Mozilla). 1583 * @return _RESULT 1584 * false if a second install isn't found, path to the main exe if a 1585 * second install is found. 1586 * 1587 * $R3 = stores the long path to $INSTDIR 1588 * $R4 = counter for the outer loop's EnumRegKey 1589 * $R5 = return value from ReadRegStr and RemoveQuotesFromPath 1590 * $R6 = return value from GetParent 1591 * $R7 = return value from the loop's EnumRegKey 1592 * $R8 = storage for _KEY 1593 * $R9 = _KEY and _RESULT 1594 */ 1595!macro GetSecondInstallPath 1596 1597 !ifndef ${_MOZFUNC_UN}GetSecondInstallPath 1598 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 1599 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 1600 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 1601 !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath 1602 !undef _MOZFUNC_UN 1603 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 1604 !undef _MOZFUNC_UN_TMP 1605 1606 !verbose push 1607 !verbose ${_MOZFUNC_VERBOSE} 1608 !define ${_MOZFUNC_UN}GetSecondInstallPath "!insertmacro ${_MOZFUNC_UN}GetSecondInstallPathCall" 1609 1610 Function ${_MOZFUNC_UN}GetSecondInstallPath 1611 Exch $R9 1612 Push $R8 1613 Push $R7 1614 Push $R6 1615 Push $R5 1616 Push $R4 1617 Push $R3 1618 1619 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R3 1620 1621 StrCpy $R4 0 ; set the counter for the loop to 0 1622 StrCpy $R8 "$R9" ; Registry key path to search 1623 StrCpy $R9 "false" ; default return value 1624 1625 loop: 1626 EnumRegKey $R7 SHCTX $R8 $R4 1627 StrCmp $R7 "" end +1 ; if empty there are no more keys to enumerate 1628 IntOp $R4 $R4 + 1 ; increment the loop's counter 1629 ClearErrors 1630 ReadRegStr $R5 SHCTX "$R8\$R7\bin" "PathToExe" 1631 IfErrors loop 1632 1633 ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R5 1634 1635 IfFileExists "$R5" +1 loop 1636 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 1637 ${${_MOZFUNC_UN}GetParent} "$R5" $R6 1638 StrCmp "$R6" "$R3" loop +1 1639 StrCmp "$R6\${FileMainEXE}" "$R5" +1 loop 1640 StrCpy $R9 "$R5" 1641 1642 end: 1643 ClearErrors 1644 1645 Pop $R3 1646 Pop $R4 1647 Pop $R5 1648 Pop $R6 1649 Pop $R7 1650 Pop $R8 1651 Exch $R9 1652 FunctionEnd 1653 1654 !verbose pop 1655 !endif 1656!macroend 1657 1658!macro GetSecondInstallPathCall _KEY _RESULT 1659 !verbose push 1660 !verbose ${_MOZFUNC_VERBOSE} 1661 Push "${_KEY}" 1662 Call GetSecondInstallPath 1663 Pop ${_RESULT} 1664 !verbose pop 1665!macroend 1666 1667!macro un.GetSecondInstallPathCall _KEY _RESULT 1668 !verbose push 1669 !verbose ${_MOZFUNC_VERBOSE} 1670 Push "${_KEY}" 1671 Call un.GetSecondInstallPath 1672 Pop ${_RESULT} 1673 !verbose pop 1674!macroend 1675 1676!macro un.GetSecondInstallPath 1677 !ifndef un.GetSecondInstallPath 1678 !verbose push 1679 !verbose ${_MOZFUNC_VERBOSE} 1680 !undef _MOZFUNC_UN 1681 !define _MOZFUNC_UN "un." 1682 1683 !insertmacro GetSecondInstallPath 1684 1685 !undef _MOZFUNC_UN 1686 !define _MOZFUNC_UN 1687 !verbose pop 1688 !endif 1689!macroend 1690 1691/** 1692 * Finds an existing installation path for the application based on the 1693 * application's executable name so we can default to using this path for the 1694 * install. If there is zero or more than one installation of the application 1695 * then we default to the default installation path. This uses SHCTX to 1696 * determine the registry hive to read from so you must call SetShellVarContext 1697 * first. 1698 * 1699 * @param _KEY 1700 * The registry subkey (typically this will be Software\Mozilla\App Name). 1701 * @return _RESULT 1702 * false if a single install location for this app name isn't found, 1703 * path to the install directory if a single install location is found. 1704 * 1705 * $R5 = counter for the loop's EnumRegKey 1706 * $R6 = return value from EnumRegKey 1707 * $R7 = return value from ReadRegStr 1708 * $R8 = storage for _KEY 1709 * $R9 = _KEY and _RESULT 1710 */ 1711!macro GetSingleInstallPath 1712 1713 !ifndef ${_MOZFUNC_UN}GetSingleInstallPath 1714 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 1715 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 1716 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 1717 !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath 1718 !undef _MOZFUNC_UN 1719 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 1720 !undef _MOZFUNC_UN_TMP 1721 1722 !verbose push 1723 !verbose ${_MOZFUNC_VERBOSE} 1724 !define ${_MOZFUNC_UN}GetSingleInstallPath "!insertmacro ${_MOZFUNC_UN}GetSingleInstallPathCall" 1725 1726 Function ${_MOZFUNC_UN}GetSingleInstallPath 1727 Exch $R9 1728 Push $R8 1729 Push $R7 1730 Push $R6 1731 Push $R5 1732 1733 StrCpy $R8 $R9 1734 StrCpy $R9 "false" 1735 StrCpy $R5 0 ; set the counter for the loop to 0 1736 1737 loop: 1738 ClearErrors 1739 EnumRegKey $R6 SHCTX $R8 $R5 1740 IfErrors cleanup 1741 StrCmp $R6 "" cleanup +1 ; if empty there are no more keys to enumerate 1742 IntOp $R5 $R5 + 1 ; increment the loop's counter 1743 ClearErrors 1744 ReadRegStr $R7 SHCTX "$R8\$R6\Main" "PathToExe" 1745 IfErrors loop 1746 ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R7" $R7 1747 GetFullPathName $R7 "$R7" 1748 IfErrors loop 1749 1750 StrCmp "$R9" "false" +1 +3 1751 StrCpy $R9 "$R7" 1752 GoTo Loop 1753 1754 StrCpy $R9 "false" 1755 1756 cleanup: 1757 StrCmp $R9 "false" end +1 1758 ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 1759 ${${_MOZFUNC_UN}GetParent} "$R9" $R9 1760 1761 end: 1762 ClearErrors 1763 1764 Pop $R5 1765 Pop $R6 1766 Pop $R7 1767 Pop $R8 1768 Exch $R9 1769 FunctionEnd 1770 1771 !verbose pop 1772 !endif 1773!macroend 1774 1775!macro GetSingleInstallPathCall _KEY _RESULT 1776 !verbose push 1777 !verbose ${_MOZFUNC_VERBOSE} 1778 Push "${_KEY}" 1779 Call GetSingleInstallPath 1780 Pop ${_RESULT} 1781 !verbose pop 1782!macroend 1783 1784!macro un.GetSingleInstallPathCall _KEY _RESULT 1785 !verbose push 1786 !verbose ${_MOZFUNC_VERBOSE} 1787 Push "${_KEY}" 1788 Call un.GetSingleInstallPath 1789 Pop ${_RESULT} 1790 !verbose pop 1791!macroend 1792 1793!macro un.GetSingleInstallPath 1794 !ifndef un.GetSingleInstallPath 1795 !verbose push 1796 !verbose ${_MOZFUNC_VERBOSE} 1797 !undef _MOZFUNC_UN 1798 !define _MOZFUNC_UN "un." 1799 1800 !insertmacro GetSingleInstallPath 1801 1802 !undef _MOZFUNC_UN 1803 !define _MOZFUNC_UN 1804 !verbose pop 1805 !endif 1806!macroend 1807 1808/** 1809 * Find the first existing installation for the application. 1810 * This is similar to GetSingleInstallPath, except that it always returns the 1811 * first path it finds, instead of an error when more than one path exists. 1812 * 1813 * The shell context and the registry view should already have been set. 1814 * 1815 * @param _KEY 1816 * The registry subkey (typically Software\Mozilla\App Name). 1817 * @return _RESULT 1818 * path to the install directory of the first location found, or 1819 * the string "false" if no existing installation was found. 1820 * 1821 * $R5 = counter for the loop's EnumRegKey 1822 * $R6 = return value from EnumRegKey 1823 * $R7 = return value from ReadRegStr 1824 * $R8 = storage for _KEY 1825 * $R9 = _KEY and _RESULT 1826 */ 1827!macro GetFirstInstallPath 1828 !ifndef ${_MOZFUNC_UN}GetFirstInstallPath 1829 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 1830 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 1831 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 1832 !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath 1833 !undef _MOZFUNC_UN 1834 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 1835 !undef _MOZFUNC_UN_TMP 1836 1837 !verbose push 1838 !verbose ${_MOZFUNC_VERBOSE} 1839 !define ${_MOZFUNC_UN}GetFirstInstallPath "!insertmacro ${_MOZFUNC_UN}__GetFirstInstallPathCall" 1840 1841 Function ${_MOZFUNC_UN}__GetFirstInstallPath 1842 Exch $R9 1843 Push $R8 1844 Push $R7 1845 Push $R6 1846 Push $R5 1847 1848 StrCpy $R8 $R9 1849 StrCpy $R9 "false" 1850 StrCpy $R5 0 1851 1852 ${Do} 1853 ClearErrors 1854 EnumRegKey $R6 SHCTX $R8 $R5 1855 ${If} ${Errors} 1856 ${OrIf} $R6 == "" 1857 ${Break} 1858 ${EndIf} 1859 1860 IntOp $R5 $R5 + 1 1861 1862 ReadRegStr $R7 SHCTX "$R8\$R6\Main" "PathToExe" 1863 ${If} ${Errors} 1864 ${Continue} 1865 ${EndIf} 1866 1867 ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R7" $R7 1868 GetFullPathName $R7 "$R7" 1869 ${If} ${Errors} 1870 ${Continue} 1871 ${EndIf} 1872 1873 StrCpy $R9 "$R7" 1874 ${Break} 1875 ${Loop} 1876 1877 ${If} $R9 != "false" 1878 ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 1879 ${${_MOZFUNC_UN}GetParent} "$R9" $R9 1880 ${EndIf} 1881 1882 Pop $R5 1883 Pop $R6 1884 Pop $R7 1885 Pop $R8 1886 Exch $R9 1887 FunctionEnd 1888 1889 !verbose pop 1890 !endif 1891!macroend 1892 1893!macro __GetFirstInstallPathCall _KEY _RESULT 1894 !verbose push 1895 !verbose ${_MOZFUNC_VERBOSE} 1896 Push "${_KEY}" 1897 Call __GetFirstInstallPath 1898 Pop ${_RESULT} 1899 !verbose pop 1900!macroend 1901 1902!macro un.__GetFirstInstallPathCall _KEY _RESULT 1903 !verbose push 1904 !verbose ${_MOZFUNC_VERBOSE} 1905 Push "${_KEY}" 1906 Call un.__GetFirstInstallPath 1907 Pop ${_RESULT} 1908 !verbose pop 1909!macroend 1910 1911!macro un.__GetFirstInstallPath 1912 !ifndef un.__GetFirstInstallPath 1913 !verbose push 1914 !verbose ${_MOZFUNC_VERBOSE} 1915 !undef _MOZFUNC_UN 1916 !define _MOZFUNC_UN "un." 1917 1918 !insertmacro __GetFirstInstallPath 1919 1920 !undef _MOZFUNC_UN 1921 !define _MOZFUNC_UN 1922 !verbose pop 1923 !endif 1924!macroend 1925 1926 1927################################################################################ 1928# Macros for working with the file system 1929 1930/** 1931 * Attempts to delete a file if it exists. This will fail if the file is in use. 1932 * 1933 * @param _FILE 1934 * The path to the file that is to be deleted. 1935 */ 1936!macro DeleteFile _FILE 1937 ${If} ${FileExists} "${_FILE}" 1938 Delete "${_FILE}" 1939 ${EndIf} 1940!macroend 1941!define DeleteFile "!insertmacro DeleteFile" 1942 1943/** 1944 * Removes a directory if it exists and is empty. 1945 * 1946 * @param _DIR 1947 * The path to the directory that is to be removed. 1948 */ 1949!macro RemoveDir _DIR 1950 ${If} ${FileExists} "${_DIR}" 1951 RmDir "${_DIR}" 1952 ${EndIf} 1953!macroend 1954!define RemoveDir "!insertmacro RemoveDir" 1955 1956/** 1957 * Checks whether it is possible to create and delete a directory and a file in 1958 * the install directory. Creation and deletion of files and directories are 1959 * checked since a user may have rights for one and not the other. If creation 1960 * and deletion of a file and a directory are successful this macro will return 1961 * true... if not, this it return false. 1962 * 1963 * @return _RESULT 1964 * true if files and directories can be created and deleted in the 1965 * install directory otherwise false. 1966 * 1967 * $R8 = temporary filename in the installation directory returned from 1968 * GetTempFileName. 1969 * $R9 = _RESULT 1970 */ 1971!macro CanWriteToInstallDir 1972 1973 !ifndef ${_MOZFUNC_UN}CanWriteToInstallDir 1974 !verbose push 1975 !verbose ${_MOZFUNC_VERBOSE} 1976 !define ${_MOZFUNC_UN}CanWriteToInstallDir "!insertmacro ${_MOZFUNC_UN}CanWriteToInstallDirCall" 1977 1978 Function ${_MOZFUNC_UN}CanWriteToInstallDir 1979 Push $R9 1980 Push $R8 1981 1982 StrCpy $R9 "true" 1983 1984 ; IfFileExists returns false for $INSTDIR when $INSTDIR is the root of a 1985 ; UNC path so always try to create $INSTDIR 1986 CreateDirectory "$INSTDIR\" 1987 GetTempFileName $R8 "$INSTDIR\" 1988 1989 ${Unless} ${FileExists} $R8 ; Can files be created? 1990 StrCpy $R9 "false" 1991 Goto done 1992 ${EndUnless} 1993 1994 Delete $R8 1995 ${If} ${FileExists} $R8 ; Can files be deleted? 1996 StrCpy $R9 "false" 1997 Goto done 1998 ${EndIf} 1999 2000 CreateDirectory $R8 2001 ${Unless} ${FileExists} $R8 ; Can directories be created? 2002 StrCpy $R9 "false" 2003 Goto done 2004 ${EndUnless} 2005 2006 RmDir $R8 2007 ${If} ${FileExists} $R8 ; Can directories be deleted? 2008 StrCpy $R9 "false" 2009 Goto done 2010 ${EndIf} 2011 2012 done: 2013 2014 RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty 2015 ClearErrors 2016 2017 Pop $R8 2018 Exch $R9 2019 FunctionEnd 2020 2021 !verbose pop 2022 !endif 2023!macroend 2024 2025!macro CanWriteToInstallDirCall _RESULT 2026 !verbose push 2027 !verbose ${_MOZFUNC_VERBOSE} 2028 Call CanWriteToInstallDir 2029 Pop ${_RESULT} 2030 !verbose pop 2031!macroend 2032 2033!macro un.CanWriteToInstallDirCall _RESULT 2034 !verbose push 2035 !verbose ${_MOZFUNC_VERBOSE} 2036 Call un.CanWriteToInstallDir 2037 Pop ${_RESULT} 2038 !verbose pop 2039!macroend 2040 2041!macro un.CanWriteToInstallDir 2042 !ifndef un.CanWriteToInstallDir 2043 !verbose push 2044 !verbose ${_MOZFUNC_VERBOSE} 2045 !undef _MOZFUNC_UN 2046 !define _MOZFUNC_UN "un." 2047 2048 !insertmacro CanWriteToInstallDir 2049 2050 !undef _MOZFUNC_UN 2051 !define _MOZFUNC_UN 2052 !verbose pop 2053 !endif 2054!macroend 2055 2056/** 2057 * Checks whether there is sufficient free space available for the installation 2058 * directory using GetDiskFreeSpaceExW which respects disk quotas. This macro 2059 * will calculate the size of all sections that are selected, compare that with 2060 * the free space available, and if there is sufficient free space it will 2061 * return true... if not, it will return false. 2062 * 2063 * @return _RESULT 2064 * "true" if there is sufficient free space otherwise "false". 2065 * 2066 * $R5 = return value from SectionGetSize 2067 * $R6 = return value from SectionGetFlags 2068 * return value from an 'and' comparison of SectionGetFlags (1=selected) 2069 * return value for lpFreeBytesAvailable from GetDiskFreeSpaceExW 2070 * return value for System::Int64Op $R6 / 1024 2071 * return value for System::Int64Op $R6 > $R8 2072 * $R7 = the counter for enumerating the sections 2073 * the temporary file name for the directory created under $INSTDIR passed 2074 * to GetDiskFreeSpaceExW. 2075 * $R8 = sum in KB of all selected sections 2076 * $R9 = _RESULT 2077 */ 2078!macro CheckDiskSpace 2079 2080 !ifndef ${_MOZFUNC_UN}CheckDiskSpace 2081 !verbose push 2082 !verbose ${_MOZFUNC_VERBOSE} 2083 !define ${_MOZFUNC_UN}CheckDiskSpace "!insertmacro ${_MOZFUNC_UN}CheckDiskSpaceCall" 2084 2085 Function ${_MOZFUNC_UN}CheckDiskSpace 2086 Push $R9 2087 Push $R8 2088 Push $R7 2089 Push $R6 2090 Push $R5 2091 2092 ClearErrors 2093 2094 StrCpy $R9 "true" ; default return value 2095 StrCpy $R8 "0" ; sum in KB of all selected sections 2096 StrCpy $R7 "0" ; counter for enumerating sections 2097 2098 ; Enumerate the sections and sum up the sizes of the sections that are 2099 ; selected. 2100 SectionGetFlags $R7 $R6 2101 IfErrors +7 +1 2102 IntOp $R6 ${SF_SELECTED} & $R6 2103 IntCmp $R6 0 +3 +1 +1 2104 SectionGetSize $R7 $R5 2105 IntOp $R8 $R8 + $R5 2106 IntOp $R7 $R7 + 1 2107 GoTo -7 2108 2109 ; The directory passed to GetDiskFreeSpaceExW must exist for the call to 2110 ; succeed. Since the CanWriteToInstallDir macro is called prior to this 2111 ; macro the call to CreateDirectory will always succeed. 2112 2113 ; IfFileExists returns false for $INSTDIR when $INSTDIR is the root of a 2114 ; UNC path so always try to create $INSTDIR 2115 CreateDirectory "$INSTDIR\" 2116 GetTempFileName $R7 "$INSTDIR\" 2117 Delete "$R7" 2118 CreateDirectory "$R7" 2119 2120 System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i(R7, .R6, ., .) .' 2121 2122 ; Convert to KB for comparison with $R8 which is in KB 2123 System::Int64Op $R6 / 1024 2124 Pop $R6 2125 2126 System::Int64Op $R6 > $R8 2127 Pop $R6 2128 2129 IntCmp $R6 1 end +1 +1 2130 StrCpy $R9 "false" 2131 2132 end: 2133 RmDir "$R7" 2134 RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty 2135 2136 ClearErrors 2137 2138 Pop $R5 2139 Pop $R6 2140 Pop $R7 2141 Pop $R8 2142 Exch $R9 2143 FunctionEnd 2144 2145 !verbose pop 2146 !endif 2147!macroend 2148 2149!macro CheckDiskSpaceCall _RESULT 2150 !verbose push 2151 !verbose ${_MOZFUNC_VERBOSE} 2152 Call CheckDiskSpace 2153 Pop ${_RESULT} 2154 !verbose pop 2155!macroend 2156 2157!macro un.CheckDiskSpaceCall _RESULT 2158 !verbose push 2159 !verbose ${_MOZFUNC_VERBOSE} 2160 Call un.CheckDiskSpace 2161 Pop ${_RESULT} 2162 !verbose pop 2163!macroend 2164 2165!macro un.CheckDiskSpace 2166 !ifndef un.CheckDiskSpace 2167 !verbose push 2168 !verbose ${_MOZFUNC_VERBOSE} 2169 !undef _MOZFUNC_UN 2170 !define _MOZFUNC_UN "un." 2171 2172 !insertmacro CheckDiskSpace 2173 2174 !undef _MOZFUNC_UN 2175 !define _MOZFUNC_UN 2176 !verbose pop 2177 !endif 2178!macroend 2179 2180/** 2181* Returns the path found within a passed in string. The path is quoted or not 2182* with the exception of an unquoted non 8dot3 path without arguments that is 2183* also not a DefaultIcon path, is a 8dot3 path or not, has command line 2184* arguments, or is a registry DefaultIcon path (e.g. <path to binary>,# where # 2185* is the icon's resuorce id). The string does not need to be a valid path or 2186* exist. It is up to the caller to pass in a string of one of the forms noted 2187* above and to verify existence if necessary. 2188* 2189* Examples: 2190* In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -flag "%1" 2191* In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE,0 2192* In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE 2193* In: "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE" 2194* In: "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE" -flag "%1" 2195* Out: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE 2196* 2197* In: "C:\Program Files\Mozilla Firefox\firefox.exe" -flag "%1" 2198* In: C:\Program Files\Mozilla Firefox\firefox.exe,0 2199* In: "C:\Program Files\Mozilla Firefox\firefox.exe" 2200* Out: C:\Program Files\Mozilla Firefox\firefox.exe 2201* 2202* @param _IN_PATH 2203* The string containing the path. 2204* @param _OUT_PATH 2205* The register to store the path to. 2206* 2207* $R7 = counter for the outer loop's EnumRegKey 2208* $R8 = return value from ReadRegStr 2209* $R9 = _IN_PATH and _OUT_PATH 2210*/ 2211!macro GetPathFromString 2212 2213 !ifndef ${_MOZFUNC_UN}GetPathFromString 2214 !verbose push 2215 !verbose ${_MOZFUNC_VERBOSE} 2216 !define ${_MOZFUNC_UN}GetPathFromString "!insertmacro ${_MOZFUNC_UN}GetPathFromStringCall" 2217 2218 Function ${_MOZFUNC_UN}GetPathFromString 2219 Exch $R9 2220 Push $R8 2221 Push $R7 2222 2223 StrCpy $R7 0 ; Set the counter to 0. 2224 2225 ; Handle quoted paths with arguments. 2226 StrCpy $R8 $R9 1 ; Copy the first char. 2227 StrCmp $R8 '"' +2 +1 ; Is it a "? 2228 StrCmp $R8 "'" +1 +9 ; Is it a '? 2229 StrCpy $R9 $R9 "" 1 ; Remove the first char. 2230 IntOp $R7 $R7 + 1 ; Increment the counter. 2231 StrCpy $R8 $R9 1 $R7 ; Starting from the counter copy the next char. 2232 StrCmp $R8 "" end +1 ; Are there no more chars? 2233 StrCmp $R8 '"' +2 +1 ; Is it a " char? 2234 StrCmp $R8 "'" +1 -4 ; Is it a ' char? 2235 StrCpy $R9 $R9 $R7 ; Copy chars up to the counter. 2236 GoTo end 2237 2238 ; Handle DefaultIcon paths. DefaultIcon paths are not quoted and end with 2239 ; a , and a number. 2240 IntOp $R7 $R7 - 1 ; Decrement the counter. 2241 StrCpy $R8 $R9 1 $R7 ; Copy one char from the end minus the counter. 2242 StrCmp $R8 '' +4 +1 ; Are there no more chars? 2243 StrCmp $R8 ',' +1 -3 ; Is it a , char? 2244 StrCpy $R9 $R9 $R7 ; Copy chars up to the end minus the counter. 2245 GoTo end 2246 2247 ; Handle unquoted paths with arguments. An unquoted path with arguments 2248 ; must be an 8dot3 path. 2249 StrCpy $R7 -1 ; Set the counter to -1 so it will start at 0. 2250 IntOp $R7 $R7 + 1 ; Increment the counter. 2251 StrCpy $R8 $R9 1 $R7 ; Starting from the counter copy the next char. 2252 StrCmp $R8 "" end +1 ; Are there no more chars? 2253 StrCmp $R8 " " +1 -3 ; Is it a space char? 2254 StrCpy $R9 $R9 $R7 ; Copy chars up to the counter. 2255 2256 end: 2257 ClearErrors 2258 2259 Pop $R7 2260 Pop $R8 2261 Exch $R9 2262 FunctionEnd 2263 2264 !verbose pop 2265 !endif 2266!macroend 2267 2268!macro GetPathFromStringCall _IN_PATH _OUT_PATH 2269 !verbose push 2270 !verbose ${_MOZFUNC_VERBOSE} 2271 Push "${_IN_PATH}" 2272 Call GetPathFromString 2273 Pop ${_OUT_PATH} 2274 !verbose pop 2275!macroend 2276 2277!macro un.GetPathFromStringCall _IN_PATH _OUT_PATH 2278 !verbose push 2279 !verbose ${_MOZFUNC_VERBOSE} 2280 Push "${_IN_PATH}" 2281 Call un.GetPathFromString 2282 Pop ${_OUT_PATH} 2283 !verbose pop 2284!macroend 2285 2286!macro un.GetPathFromString 2287 !ifndef un.GetPathFromString 2288 !verbose push 2289 !verbose ${_MOZFUNC_VERBOSE} 2290 !undef _MOZFUNC_UN 2291 !define _MOZFUNC_UN "un." 2292 2293 !insertmacro GetPathFromString 2294 2295 !undef _MOZFUNC_UN 2296 !define _MOZFUNC_UN 2297 !verbose pop 2298 !endif 2299!macroend 2300 2301/** 2302 * Removes the quotes from each end of a string if present. 2303 * 2304 * @param _IN_PATH 2305 * The string containing the path. 2306 * @param _OUT_PATH 2307 * The register to store the long path. 2308 * 2309 * $R7 = storage for single character comparison 2310 * $R8 = storage for _IN_PATH 2311 * $R9 = _IN_PATH and _OUT_PATH 2312 */ 2313!macro RemoveQuotesFromPath 2314 2315 !ifndef ${_MOZFUNC_UN}RemoveQuotesFromPath 2316 !verbose push 2317 !verbose ${_MOZFUNC_VERBOSE} 2318 !define ${_MOZFUNC_UN}RemoveQuotesFromPath "!insertmacro ${_MOZFUNC_UN}RemoveQuotesFromPathCall" 2319 2320 Function ${_MOZFUNC_UN}RemoveQuotesFromPath 2321 Exch $R9 2322 Push $R8 2323 Push $R7 2324 2325 StrCpy $R7 "$R9" 1 2326 StrCmp $R7 "$\"" +1 +2 2327 StrCpy $R9 "$R9" "" 1 2328 2329 StrCpy $R7 "$R9" "" -1 2330 StrCmp $R7 "$\"" +1 +2 2331 StrCpy $R9 "$R9" -1 2332 2333 Pop $R7 2334 Pop $R8 2335 Exch $R9 2336 FunctionEnd 2337 2338 !verbose pop 2339 !endif 2340!macroend 2341 2342!macro RemoveQuotesFromPathCall _IN_PATH _OUT_PATH 2343 !verbose push 2344 !verbose ${_MOZFUNC_VERBOSE} 2345 Push "${_IN_PATH}" 2346 Call RemoveQuotesFromPath 2347 Pop ${_OUT_PATH} 2348 !verbose pop 2349!macroend 2350 2351!macro un.RemoveQuotesFromPathCall _IN_PATH _OUT_PATH 2352 !verbose push 2353 !verbose ${_MOZFUNC_VERBOSE} 2354 Push "${_IN_PATH}" 2355 Call un.RemoveQuotesFromPath 2356 Pop ${_OUT_PATH} 2357 !verbose pop 2358!macroend 2359 2360!macro un.RemoveQuotesFromPath 2361 !ifndef un.RemoveQuotesFromPath 2362 !verbose push 2363 !verbose ${_MOZFUNC_VERBOSE} 2364 !undef _MOZFUNC_UN 2365 !define _MOZFUNC_UN "un." 2366 2367 !insertmacro RemoveQuotesFromPath 2368 2369 !undef _MOZFUNC_UN 2370 !define _MOZFUNC_UN 2371 !verbose pop 2372 !endif 2373!macroend 2374 2375/** 2376 * Returns the long path for an existing file or directory. GetLongPathNameW 2377 * may not be available on Win95 if Microsoft Layer for Unicode is not 2378 * installed and GetFullPathName only returns a long path for the last file or 2379 * directory that doesn't end with a \ in the path that it is passed. If the 2380 * path does not exist on the file system this will return an empty string. To 2381 * provide a consistent result trailing back-slashes are always removed. 2382 * 2383 * Note: 1024 used by GetLongPathNameW is the maximum NSIS string length. 2384 * 2385 * @param _IN_PATH 2386 * The string containing the path. 2387 * @param _OUT_PATH 2388 * The register to store the long path. 2389 * 2390 * $R4 = counter value when the previous \ was found 2391 * $R5 = directory or file name found during loop 2392 * $R6 = return value from GetLongPathNameW and loop counter 2393 * $R7 = long path from GetLongPathNameW and single char from path for comparison 2394 * $R8 = storage for _IN_PATH 2395 * $R9 = _IN_PATH _OUT_PATH 2396 */ 2397!macro GetLongPath 2398 2399 !ifndef ${_MOZFUNC_UN}GetLongPath 2400 !verbose push 2401 !verbose ${_MOZFUNC_VERBOSE} 2402 !define ${_MOZFUNC_UN}GetLongPath "!insertmacro ${_MOZFUNC_UN}GetLongPathCall" 2403 2404 Function ${_MOZFUNC_UN}GetLongPath 2405 Exch $R9 2406 Push $R8 2407 Push $R7 2408 Push $R6 2409 Push $R5 2410 Push $R4 2411 2412 ClearErrors 2413 2414 GetFullPathName $R8 "$R9" 2415 IfErrors end_GetLongPath +1 ; If the path doesn't exist return an empty string. 2416 2417 ; Make the drive letter uppercase. 2418 StrCpy $R9 "$R8" 1 ; Copy the first char. 2419 StrCpy $R8 "$R8" "" 1 ; Copy everything after the first char. 2420 ; Convert the first char to uppercase. 2421 System::Call "User32::CharUpper(w R9 R9)i" 2422 StrCpy $R8 "$R9$R8" ; Copy the uppercase char and the rest of the chars. 2423 2424 ; Do it the hard way. 2425 StrCpy $R4 0 ; Stores the position in the string of the last \ found. 2426 StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0. 2427 2428 loop_GetLongPath: 2429 IntOp $R6 $R6 + 1 ; Increment the counter. 2430 StrCpy $R7 $R8 1 $R6 ; Starting from the counter copy the next char. 2431 StrCmp $R7 "" +2 +1 ; Are there no more chars? 2432 StrCmp $R7 "\" +1 -3 ; Is it a \? 2433 2434 ; Copy chars starting from the previously found \ to the counter. 2435 StrCpy $R5 $R8 $R6 $R4 2436 2437 ; If this is the first \ found we want to swap R9 with R5 so a \ will 2438 ; be appended to the drive letter and colon (e.g. C: will become C:\). 2439 StrCmp $R4 0 +1 +3 2440 StrCpy $R9 $R5 2441 StrCpy $R5 "" 2442 2443 GetFullPathName $R9 "$R9\$R5" 2444 2445 StrCmp $R7 "" end_GetLongPath +1 ; Are there no more chars? 2446 2447 ; Store the counter for the current \ and prefix it for StrCpy operations. 2448 StrCpy $R4 "+$R6" 2449 IntOp $R6 $R6 + 1 ; Increment the counter so we skip over the \. 2450 StrCpy $R8 $R8 "" $R6 ; Copy chars starting from the counter to the end. 2451 StrCpy $R6 -1 ; Reset the counter to -1 so it will start over at 0. 2452 GoTo loop_GetLongPath 2453 2454 end_GetLongPath: 2455 ; If there is a trailing slash remove it 2456 StrCmp $R9 "" +4 +1 2457 StrCpy $R8 "$R9" "" -1 2458 StrCmp $R8 "\" +1 +2 2459 StrCpy $R9 "$R9" -1 2460 2461 ClearErrors 2462 2463 Pop $R4 2464 Pop $R5 2465 Pop $R6 2466 Pop $R7 2467 Pop $R8 2468 Exch $R9 2469 FunctionEnd 2470 2471 !verbose pop 2472 !endif 2473!macroend 2474 2475!macro GetLongPathCall _IN_PATH _OUT_PATH 2476 !verbose push 2477 !verbose ${_MOZFUNC_VERBOSE} 2478 Push "${_IN_PATH}" 2479 Call GetLongPath 2480 Pop ${_OUT_PATH} 2481 !verbose pop 2482!macroend 2483 2484!macro un.GetLongPathCall _IN_PATH _OUT_PATH 2485 !verbose push 2486 !verbose ${_MOZFUNC_VERBOSE} 2487 Push "${_IN_PATH}" 2488 Call un.GetLongPath 2489 Pop ${_OUT_PATH} 2490 !verbose pop 2491!macroend 2492 2493!macro un.GetLongPath 2494 !ifndef un.GetLongPath 2495 !verbose push 2496 !verbose ${_MOZFUNC_VERBOSE} 2497 !undef _MOZFUNC_UN 2498 !define _MOZFUNC_UN "un." 2499 2500 !insertmacro GetLongPath 2501 2502 !undef _MOZFUNC_UN 2503 !define _MOZFUNC_UN 2504 !verbose pop 2505 !endif 2506!macroend 2507 2508 2509################################################################################ 2510# Macros for cleaning up the registry and file system 2511 2512/** 2513 * Removes registry keys that reference this install location and for paths that 2514 * no longer exist. This uses SHCTX to determine the registry hive so you must 2515 * call SetShellVarContext first. 2516 * 2517 * @param _KEY 2518 * The registry subkey (typically this will be Software\Mozilla). 2519 * 2520 * $0 = loop counter 2521 * $1 = temporary value used for string searches 2522 * $R0 = on x64 systems set to 'false' at the beginning of the macro when 2523 * enumerating the x86 registry view and set to 'true' when enumerating 2524 * the x64 registry view. 2525 * $R1 = stores the long path to $INSTDIR 2526 * $R2 = return value from the stack from the GetParent and GetLongPath macros 2527 * $R3 = return value from the outer loop's EnumRegKey and ESR string 2528 * $R4 = return value from the inner loop's EnumRegKey 2529 * $R5 = return value from ReadRegStr 2530 * $R6 = counter for the outer loop's EnumRegKey 2531 * $R7 = counter for the inner loop's EnumRegKey 2532 * $R8 = return value from the stack from the RemoveQuotesFromPath macro 2533 * $R9 = _KEY 2534 */ 2535!macro RegCleanMain 2536 2537 !ifndef ${_MOZFUNC_UN}RegCleanMain 2538 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 2539 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 2540 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 2541 !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath 2542 !undef _MOZFUNC_UN 2543 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 2544 !undef _MOZFUNC_UN_TMP 2545 2546 !verbose push 2547 !verbose ${_MOZFUNC_VERBOSE} 2548 !define ${_MOZFUNC_UN}RegCleanMain "!insertmacro ${_MOZFUNC_UN}RegCleanMainCall" 2549 2550 Function ${_MOZFUNC_UN}RegCleanMain 2551 Exch $R9 2552 Push $R8 2553 Push $R7 2554 Push $R6 2555 Push $R5 2556 Push $R4 2557 Push $R3 2558 Push $R2 2559 Push $R1 2560 Push $R0 2561 Push $0 2562 Push $1 2563 2564 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R1 2565 StrCpy $R6 0 ; set the counter for the outer loop to 0 2566 2567 ${If} ${RunningX64} 2568 ${OrIf} ${IsNativeARM64} 2569 StrCpy $R0 "false" 2570 ; Set the registry to the 32 bit registry for 64 bit installations or to 2571 ; the 64 bit registry for 32 bit installations at the beginning so it can 2572 ; easily be set back to the correct registry view when finished. 2573 !ifdef HAVE_64BIT_BUILD 2574 SetRegView 32 2575 !else 2576 SetRegView 64 2577 !endif 2578 ${EndIf} 2579 2580 outerloop: 2581 EnumRegKey $R3 SHCTX $R9 $R6 2582 StrCmp $R3 "" end +1 ; if empty there are no more keys to enumerate 2583 IntOp $R6 $R6 + 1 ; increment the outer loop's counter 2584 ClearErrors 2585 ReadRegStr $R5 SHCTX "$R9\$R3\bin" "PathToExe" 2586 IfErrors 0 outercontinue 2587 StrCpy $R7 0 ; set the counter for the inner loop to 0 2588 2589 innerloop: 2590 EnumRegKey $R4 SHCTX "$R9\$R3" $R7 2591 StrCmp $R4 "" outerloop +1 ; if empty there are no more keys to enumerate 2592 IntOp $R7 $R7 + 1 ; increment the inner loop's counter 2593 ClearErrors 2594 ReadRegStr $R5 SHCTX "$R9\$R3\$R4\Main" "PathToExe" 2595 IfErrors innerloop 2596 2597 ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R8 2598 ${${_MOZFUNC_UN}GetParent} "$R8" $R2 2599 ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2 2600 IfFileExists "$R2" +1 innerloop 2601 StrCmp "$R2" "$R1" +1 innerloop 2602 2603 ClearErrors 2604 DeleteRegKey SHCTX "$R9\$R3\$R4" 2605 IfErrors innerloop 2606 IntOp $R7 $R7 - 1 ; decrement the inner loop's counter when the key is deleted successfully. 2607 ClearErrors 2608 DeleteRegKey /ifempty SHCTX "$R9\$R3" 2609 IfErrors innerloop outerdecrement 2610 2611 outercontinue: 2612 ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R8 2613 ${${_MOZFUNC_UN}GetParent} "$R8" $R2 2614 ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2 2615 IfFileExists "$R2" +1 outerloop 2616 StrCmp "$R2" "$R1" +1 outerloop 2617 2618 ClearErrors 2619 DeleteRegKey SHCTX "$R9\$R3" 2620 IfErrors outerloop 2621 2622 outerdecrement: 2623 IntOp $R6 $R6 - 1 ; decrement the outer loop's counter when the key is deleted successfully. 2624 GoTo outerloop 2625 2626 end: 2627 ; Check if _KEY\${BrandFullNameInternal} refers to a key that's been 2628 ; removed, either just now by this function or earlier by something else, 2629 ; and if so either update it to a key that does exist or remove it if we 2630 ; can't find anything to update it to. 2631 ; We'll run this check twice, once looking for non-ESR keys and then again 2632 ; looking specifically for the separate ESR keys. 2633 StrCpy $R3 "" 2634 ${For} $0 0 1 2635 ClearErrors 2636 ReadRegStr $R5 SHCTX "$R9\${BrandFullNameInternal}$R3" "CurrentVersion" 2637 ${IfNot} ${Errors} 2638 ReadRegStr $R5 SHCTX "$R9\${BrandFullNameInternal}\$R5" "" 2639 ${If} ${Errors} 2640 ; Key doesn't exist, update or remove CurrentVersion and default. 2641 StrCpy $R5 "" 2642 StrCpy $R6 0 2643 EnumRegKey $R4 SHCTX "$R9\${BrandFullNameInternal}" $R6 2644 ${While} $R4 != "" 2645 ClearErrors 2646 ${WordFind} "$R4" "esr" "E#" $1 2647 ${If} $R3 == "" 2648 ; The key we're looking to update is a non-ESR, so we need to 2649 ; select only another non-ESR to update it with. 2650 ${If} ${Errors} 2651 StrCpy $R5 "$R4" 2652 ${Break} 2653 ${EndIf} 2654 ${Else} 2655 ; The key we're looking to update is an ESR, so we need to 2656 ; select only another ESR to update it with. 2657 ${IfNot} ${Errors} 2658 StrCpy $R5 "$R4" 2659 ${Break} 2660 ${EndIf} 2661 ${EndIf} 2662 2663 IntOp $R6 $R6 + 1 2664 EnumRegKey $R4 SHCTX "$R9\${BrandFullNameInternal}" $R6 2665 ${EndWhile} 2666 2667 ${If} $R5 == "" 2668 ; We didn't find an install to update the key with, so delete the 2669 ; CurrentVersion value and the entire key if it has no subkeys. 2670 DeleteRegValue SHCTX "$R9\${BrandFullNameInternal}$R3" "CurrentVersion" 2671 DeleteRegValue SHCTX "$R9\${BrandFullNameInternal}$R3" "" 2672 DeleteRegKey /ifempty SHCTX "$R9\${BrandFullNameInternal}$R3" 2673 ${Else} 2674 ; We do have another still-existing install, so update the key to 2675 ; that version. 2676 WriteRegStr SHCTX "$R9\${BrandFullNameInternal}$R3" \ 2677 "CurrentVersion" "$R5" 2678 ${WordFind} "$R5" " " "+1{" $R5 2679 WriteRegStr SHCTX "$R9\${BrandFullNameInternal}$R3" "" "$R5" 2680 ${EndIf} 2681 ${EndIf} 2682 ; Else, the key referenced in CurrentVersion still exists, 2683 ; so there's nothing to update or remove. 2684 ${EndIf} 2685 2686 ; Set up for the second iteration of the loop, where we'll be looking 2687 ; for the separate ESR keys. 2688 StrCpy $R3 " ESR" 2689 ${Next} 2690 2691 ${If} ${RunningX64} 2692 ${OrIf} ${IsNativeARM64} 2693 ${If} "$R0" == "false" 2694 ; Set the registry to the correct view. 2695 !ifdef HAVE_64BIT_BUILD 2696 SetRegView 64 2697 !else 2698 SetRegView 32 2699 !endif 2700 2701 StrCpy $R6 0 ; set the counter for the outer loop to 0 2702 StrCpy $R0 "true" 2703 GoTo outerloop 2704 ${EndIf} 2705 ${EndIf} 2706 2707 ClearErrors 2708 2709 Pop $1 2710 Pop $0 2711 Pop $R0 2712 Pop $R1 2713 Pop $R2 2714 Pop $R3 2715 Pop $R4 2716 Pop $R5 2717 Pop $R6 2718 Pop $R7 2719 Pop $R8 2720 Exch $R9 2721 FunctionEnd 2722 2723 !verbose pop 2724 !endif 2725!macroend 2726 2727!macro RegCleanMainCall _KEY 2728 !verbose push 2729 !verbose ${_MOZFUNC_VERBOSE} 2730 Push "${_KEY}" 2731 Call RegCleanMain 2732 !verbose pop 2733!macroend 2734 2735!macro un.RegCleanMainCall _KEY 2736 !verbose push 2737 !verbose ${_MOZFUNC_VERBOSE} 2738 Push "${_KEY}" 2739 Call un.RegCleanMain 2740 !verbose pop 2741!macroend 2742 2743!macro un.RegCleanMain 2744 !ifndef un.RegCleanMain 2745 !verbose push 2746 !verbose ${_MOZFUNC_VERBOSE} 2747 !undef _MOZFUNC_UN 2748 !define _MOZFUNC_UN "un." 2749 2750 !insertmacro RegCleanMain 2751 2752 !undef _MOZFUNC_UN 2753 !define _MOZFUNC_UN 2754 !verbose pop 2755 !endif 2756!macroend 2757 2758 2759/** 2760 * Removes registry keys that reference this install location and for paths that 2761 * no longer exist. 2762 * 2763 * @param _KEY ($R1) 2764 * The registry subkey 2765 * (typically this will be Software\Mozilla\${AppName}). 2766 */ 2767!macro RegCleanPrefs 2768 !ifndef ${_MOZFUNC_UN}RegCleanPrefs 2769 !verbose push 2770 !verbose ${_MOZFUNC_VERBOSE} 2771 !define ${_MOZFUNC_UN}RegCleanPrefs "!insertmacro ${_MOZFUNC_UN}RegCleanPrefsCall" 2772 2773 Function ${_MOZFUNC_UN}RegCleanPrefs 2774 Exch $R1 ; get _KEY from the stack 2775 2776 ; These prefs are always stored in the native registry. 2777 SetRegView 64 2778 2779 ; Delete the installer prefs key for this installation, if one exists. 2780 DeleteRegKey HKCU "$R1\Installer\$AppUserModelID" 2781 2782 ; If there aren't any more installer prefs keys, delete the parent key. 2783 DeleteRegKey /ifempty HKCU "$R1\Installer" 2784 2785 SetRegView lastused 2786 2787 Pop $R1 ; restore the previous $R1 2788 FunctionEnd 2789 2790 !verbose pop 2791 !endif 2792!macroend 2793 2794!macro RegCleanPrefsCall _KEY 2795 !verbose push 2796 !verbose ${_MOZFUNC_VERBOSE} 2797 Push "${_KEY}" 2798 Call RegCleanPrefs 2799 !verbose pop 2800!macroend 2801 2802!macro un.RegCleanPrefsCall _KEY 2803 !verbose push 2804 !verbose ${_MOZFUNC_VERBOSE} 2805 Push "${_KEY}" 2806 Call un.RegCleanPrefs 2807 !verbose pop 2808!macroend 2809 2810!macro un.RegCleanPrefs 2811 !ifndef un.RegCleanPrefs 2812 !verbose push 2813 !verbose ${_MOZFUNC_VERBOSE} 2814 !undef _MOZFUNC_UN 2815 !define _MOZFUNC_UN "un." 2816 2817 !insertmacro RegCleanPrefs 2818 2819 !undef _MOZFUNC_UN 2820 !define _MOZFUNC_UN 2821 !verbose pop 2822 !endif 2823!macroend 2824 2825/** 2826 * Removes all registry keys from \Software\Windows\CurrentVersion\Uninstall 2827 * that reference this install location in both the 32 bit and 64 bit registry 2828 * view. This macro uses SHCTX to determine the registry hive so you must call 2829 * SetShellVarContext first. 2830 * 2831 * $R3 = on x64 systems set to 'false' at the beginning of the macro when 2832 * enumerating the x86 registry view and set to 'true' when enumerating 2833 * the x64 registry view. 2834 * $R4 = stores the long path to $INSTDIR 2835 * $R5 = return value from ReadRegStr 2836 * $R6 = string for the base reg key (e.g. Software\Microsoft\Windows\CurrentVersion\Uninstall) 2837 * $R7 = return value from EnumRegKey 2838 * $R8 = counter for EnumRegKey 2839 * $R9 = return value from the stack from the RemoveQuotesFromPath and GetLongPath macros 2840 */ 2841!macro RegCleanUninstall 2842 2843 !ifndef ${_MOZFUNC_UN}RegCleanUninstall 2844 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 2845 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 2846 !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath 2847 !undef _MOZFUNC_UN 2848 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 2849 !undef _MOZFUNC_UN_TMP 2850 2851 !verbose push 2852 !verbose ${_MOZFUNC_VERBOSE} 2853 !define ${_MOZFUNC_UN}RegCleanUninstall "!insertmacro ${_MOZFUNC_UN}RegCleanUninstallCall" 2854 2855 Function ${_MOZFUNC_UN}RegCleanUninstall 2856 Push $R9 2857 Push $R8 2858 Push $R7 2859 Push $R6 2860 Push $R5 2861 Push $R4 2862 Push $R3 2863 2864 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R4 2865 StrCpy $R6 "Software\Microsoft\Windows\CurrentVersion\Uninstall" 2866 StrCpy $R7 "" 2867 StrCpy $R8 0 2868 2869 ${If} ${RunningX64} 2870 ${OrIf} ${IsNativeARM64} 2871 StrCpy $R3 "false" 2872 ; Set the registry to the 32 bit registry for 64 bit installations or to 2873 ; the 64 bit registry for 32 bit installations at the beginning so it can 2874 ; easily be set back to the correct registry view when finished. 2875 !ifdef HAVE_64BIT_BUILD 2876 SetRegView 32 2877 !else 2878 SetRegView 64 2879 !endif 2880 ${EndIf} 2881 2882 loop: 2883 EnumRegKey $R7 SHCTX $R6 $R8 2884 StrCmp $R7 "" end +1 2885 IntOp $R8 $R8 + 1 ; Increment the counter 2886 ClearErrors 2887 ReadRegStr $R5 SHCTX "$R6\$R7" "InstallLocation" 2888 IfErrors loop 2889 ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R9 2890 2891 ; Detect when the path is just a drive letter without a trailing 2892 ; backslash (e.g., "C:"), and add a backslash. If we don't, the Win32 2893 ; calls in GetLongPath will interpret that syntax as a shorthand 2894 ; for the working directory, because that's the DOS 2.0 convention, 2895 ; and will return the path to that directory instead of just the drive. 2896 ; Back here, we would then successfully match that with our $INSTDIR, 2897 ; and end up deleting a registry key that isn't really ours. 2898 StrLen $R5 "$R9" 2899 ${If} $R5 == 2 2900 StrCpy $R5 "$R9" 1 1 2901 ${If} "$R5" == ":" 2902 StrCpy $R9 "$R9\" 2903 ${EndIf} 2904 ${EndIf} 2905 2906 ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 2907 StrCmp "$R9" "$R4" +1 loop 2908 ClearErrors 2909 DeleteRegKey SHCTX "$R6\$R7" 2910 IfErrors loop +1 2911 IntOp $R8 $R8 - 1 ; Decrement the counter on successful deletion 2912 GoTo loop 2913 2914 end: 2915 ${If} ${RunningX64} 2916 ${OrIf} ${IsNativeARM64} 2917 ${If} "$R3" == "false" 2918 ; Set the registry to the correct view. 2919 !ifdef HAVE_64BIT_BUILD 2920 SetRegView 64 2921 !else 2922 SetRegView 32 2923 !endif 2924 2925 StrCpy $R7 "" 2926 StrCpy $R8 0 2927 StrCpy $R3 "true" 2928 GoTo loop 2929 ${EndIf} 2930 ${EndIf} 2931 2932 ClearErrors 2933 2934 Pop $R3 2935 Pop $R4 2936 Pop $R5 2937 Pop $R6 2938 Pop $R7 2939 Pop $R8 2940 Pop $R9 2941 FunctionEnd 2942 2943 !verbose pop 2944 !endif 2945!macroend 2946 2947!macro RegCleanUninstallCall 2948 !verbose push 2949 !verbose ${_MOZFUNC_VERBOSE} 2950 Call RegCleanUninstall 2951 !verbose pop 2952!macroend 2953 2954!macro un.RegCleanUninstallCall 2955 !verbose push 2956 !verbose ${_MOZFUNC_VERBOSE} 2957 Call un.RegCleanUninstall 2958 !verbose pop 2959!macroend 2960 2961!macro un.RegCleanUninstall 2962 !ifndef un.RegCleanUninstall 2963 !verbose push 2964 !verbose ${_MOZFUNC_VERBOSE} 2965 !undef _MOZFUNC_UN 2966 !define _MOZFUNC_UN "un." 2967 2968 !insertmacro RegCleanUninstall 2969 2970 !undef _MOZFUNC_UN 2971 !define _MOZFUNC_UN 2972 !verbose pop 2973 !endif 2974!macroend 2975 2976/** 2977 * Removes an application specific handler registry key under Software\Classes 2978 * for both HKCU and HKLM when its open command refers to this install 2979 * location or the install location doesn't exist. 2980 * 2981 * @param _HANDLER_NAME 2982 * The registry name for the handler. 2983 * 2984 * $R7 = stores the long path to the $INSTDIR 2985 * $R8 = stores the path to the open command's parent directory 2986 * $R9 = _HANDLER_NAME 2987 */ 2988!macro RegCleanAppHandler 2989 2990 !ifndef ${_MOZFUNC_UN}RegCleanAppHandler 2991 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 2992 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 2993 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 2994 !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString 2995 !undef _MOZFUNC_UN 2996 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 2997 !undef _MOZFUNC_UN_TMP 2998 2999 !verbose push 3000 !verbose ${_MOZFUNC_VERBOSE} 3001 !define ${_MOZFUNC_UN}RegCleanAppHandler "!insertmacro ${_MOZFUNC_UN}RegCleanAppHandlerCall" 3002 3003 Function ${_MOZFUNC_UN}RegCleanAppHandler 3004 Exch $R9 3005 Push $R8 3006 Push $R7 3007 3008 ClearErrors 3009 ReadRegStr $R8 HKCU "Software\Classes\$R9\shell\open\command" "" 3010 IfErrors next +1 3011 ${${_MOZFUNC_UN}GetPathFromString} "$R8" $R8 3012 ${${_MOZFUNC_UN}GetParent} "$R8" $R8 3013 IfFileExists "$R8" +3 +1 3014 DeleteRegKey HKCU "Software\Classes\$R9" 3015 GoTo next 3016 3017 ${${_MOZFUNC_UN}GetLongPath} "$R8" $R8 3018 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R7 3019 StrCmp "$R7" "$R8" +1 next 3020 DeleteRegKey HKCU "Software\Classes\$R9" 3021 3022 next: 3023 ReadRegStr $R8 HKLM "Software\Classes\$R9\shell\open\command" "" 3024 IfErrors end 3025 ${${_MOZFUNC_UN}GetPathFromString} "$R8" $R8 3026 ${${_MOZFUNC_UN}GetParent} "$R8" $R8 3027 IfFileExists "$R8" +3 +1 3028 DeleteRegKey HKLM "Software\Classes\$R9" 3029 GoTo end 3030 3031 ${${_MOZFUNC_UN}GetLongPath} "$R8" $R8 3032 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R7 3033 StrCmp "$R7" "$R8" +1 end 3034 DeleteRegKey HKLM "Software\Classes\$R9" 3035 3036 end: 3037 3038 Pop $R7 3039 Pop $R8 3040 Exch $R9 3041 FunctionEnd 3042 3043 !verbose pop 3044 !endif 3045!macroend 3046 3047!macro RegCleanAppHandlerCall _HANDLER_NAME 3048 !verbose push 3049 !verbose ${_MOZFUNC_VERBOSE} 3050 Push "${_HANDLER_NAME}" 3051 Call RegCleanAppHandler 3052 !verbose pop 3053!macroend 3054 3055!macro un.RegCleanAppHandlerCall _HANDLER_NAME 3056 !verbose push 3057 !verbose ${_MOZFUNC_VERBOSE} 3058 Push "${_HANDLER_NAME}" 3059 Call un.RegCleanAppHandler 3060 !verbose pop 3061!macroend 3062 3063!macro un.RegCleanAppHandler 3064 !ifndef un.RegCleanAppHandler 3065 !verbose push 3066 !verbose ${_MOZFUNC_VERBOSE} 3067 !undef _MOZFUNC_UN 3068 !define _MOZFUNC_UN "un." 3069 3070 !insertmacro RegCleanAppHandler 3071 3072 !undef _MOZFUNC_UN 3073 !define _MOZFUNC_UN 3074 !verbose pop 3075 !endif 3076!macroend 3077 3078/** 3079 * Cleans up the registry for a protocol handler when its open command 3080 * refers to this install location. For HKCU the registry key is deleted 3081 * and for HKLM the values set by the application are deleted. 3082 * 3083 * @param _HANDLER_NAME 3084 * The registry name for the handler. 3085 * 3086 * $R7 = stores the long path to $INSTDIR 3087 * $R8 = stores the the long path to the open command's parent directory 3088 * $R9 = _HANDLER_NAME 3089 */ 3090!macro un.RegCleanProtocolHandler 3091 3092 !ifndef un.RegCleanProtocolHandler 3093 !insertmacro un.GetLongPath 3094 !insertmacro un.GetParent 3095 !insertmacro un.GetPathFromString 3096 3097 !verbose push 3098 !verbose ${_MOZFUNC_VERBOSE} 3099 !define un.RegCleanProtocolHandler "!insertmacro un.RegCleanProtocolHandlerCall" 3100 3101 Function un.RegCleanProtocolHandler 3102 Exch $R9 3103 Push $R8 3104 Push $R7 3105 3106 ReadRegStr $R8 HKCU "Software\Classes\$R9\shell\open\command" "" 3107 ${un.GetLongPath} "$INSTDIR" $R7 3108 3109 StrCmp "$R8" "" next +1 3110 ${un.GetPathFromString} "$R8" $R8 3111 ${un.GetParent} "$R8" $R8 3112 ${un.GetLongPath} "$R8" $R8 3113 StrCmp "$R7" "$R8" +1 next 3114 DeleteRegKey HKCU "Software\Classes\$R9" 3115 3116 next: 3117 ReadRegStr $R8 HKLM "Software\Classes\$R9\shell\open\command" "" 3118 StrCmp "$R8" "" end +1 3119 ${un.GetLongPath} "$INSTDIR" $R7 3120 ${un.GetPathFromString} "$R8" $R8 3121 ${un.GetParent} "$R8" $R8 3122 ${un.GetLongPath} "$R8" $R8 3123 StrCmp "$R7" "$R8" +1 end 3124 DeleteRegValue HKLM "Software\Classes\$R9\DefaultIcon" "" 3125 DeleteRegValue HKLM "Software\Classes\$R9\shell\open" "" 3126 DeleteRegValue HKLM "Software\Classes\$R9\shell\open\command" "" 3127 DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec" "" 3128 DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Application" "" 3129 DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Topic" "" 3130 3131 end: 3132 3133 Pop $R7 3134 Pop $R8 3135 Exch $R9 3136 FunctionEnd 3137 3138 !verbose pop 3139 !endif 3140!macroend 3141 3142!macro un.RegCleanProtocolHandlerCall _HANDLER_NAME 3143 !verbose push 3144 !verbose ${_MOZFUNC_VERBOSE} 3145 Push "${_HANDLER_NAME}" 3146 Call un.RegCleanProtocolHandler 3147 !verbose pop 3148!macroend 3149 3150/** 3151 * Cleans up the registry for a file handler when the passed in value equals 3152 * the default value for the file handler. For HKCU the registry key is deleted 3153 * and for HKLM the default value is deleted. 3154 * 3155 * @param _HANDLER_NAME 3156 * The registry name for the handler. 3157 * @param _DEFAULT_VALUE 3158 * The value to check for against the handler's default value. 3159 * 3160 * $R6 = stores the long path to $INSTDIR 3161 * $R7 = _DEFAULT_VALUE 3162 * $R9 = _HANDLER_NAME 3163 */ 3164!macro RegCleanFileHandler 3165 3166 !ifndef ${_MOZFUNC_UN}RegCleanFileHandler 3167 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3168 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 3169 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 3170 !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString 3171 !undef _MOZFUNC_UN 3172 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3173 !undef _MOZFUNC_UN_TMP 3174 3175 !verbose push 3176 !verbose ${_MOZFUNC_VERBOSE} 3177 !define ${_MOZFUNC_UN}RegCleanFileHandler "!insertmacro ${_MOZFUNC_UN}RegCleanFileHandlerCall" 3178 3179 Function ${_MOZFUNC_UN}RegCleanFileHandler 3180 Exch $R9 3181 Exch 1 3182 Exch $R8 3183 Push $R7 3184 3185 DeleteRegValue HKCU "Software\Classes\$R9\OpenWithProgids" $R8 3186 EnumRegValue $R7 HKCU "Software\Classes\$R9\OpenWithProgids" 0 3187 StrCmp "$R7" "" +1 +2 3188 DeleteRegKey HKCU "Software\Classes\$R9\OpenWithProgids" 3189 ReadRegStr $R7 HKCU "Software\Classes\$R9" "" 3190 StrCmp "$R7" "$R8" +1 +2 3191 DeleteRegKey HKCU "Software\Classes\$R9" 3192 3193 DeleteRegValue HKLM "Software\Classes\$R9\OpenWithProgids" $R8 3194 EnumRegValue $R7 HKLM "Software\Classes\$R9\OpenWithProgids" 0 3195 StrCmp "$R7" "" +1 +2 3196 DeleteRegKey HKLM "Software\Classes\$R9\OpenWithProgids" 3197 ReadRegStr $R7 HKLM "Software\Classes\$R9" "" 3198 StrCmp "$R7" "$R8" +1 +2 3199 DeleteRegValue HKLM "Software\Classes\$R9" "" 3200 3201 ClearErrors 3202 3203 Pop $R7 3204 Exch $R8 3205 Exch 1 3206 Exch $R9 3207 FunctionEnd 3208 3209 !verbose pop 3210 !endif 3211!macroend 3212 3213!macro RegCleanFileHandlerCall _HANDLER_NAME _DEFAULT_VALUE 3214 !verbose push 3215 !verbose ${_MOZFUNC_VERBOSE} 3216 Push "${_DEFAULT_VALUE}" 3217 Push "${_HANDLER_NAME}" 3218 Call RegCleanFileHandler 3219 !verbose pop 3220!macroend 3221 3222!macro un.RegCleanFileHandlerCall _HANDLER_NAME _DEFAULT_VALUE 3223 !verbose push 3224 !verbose ${_MOZFUNC_VERBOSE} 3225 Push "${_DEFAULT_VALUE}" 3226 Push "${_HANDLER_NAME}" 3227 Call un.RegCleanFileHandler 3228 !verbose pop 3229!macroend 3230 3231!macro un.RegCleanFileHandler 3232 !ifndef un.RegCleanFileHandler 3233 !verbose push 3234 !verbose ${_MOZFUNC_VERBOSE} 3235 !undef _MOZFUNC_UN 3236 !define _MOZFUNC_UN "un." 3237 3238 !insertmacro RegCleanFileHandler 3239 3240 !undef _MOZFUNC_UN 3241 !define _MOZFUNC_UN 3242 !verbose pop 3243 !endif 3244!macroend 3245 3246/** 3247 * Checks if a handler's open command points to this installation directory. 3248 * Uses SHCTX to determine the registry hive (e.g. HKLM or HKCU) to check. 3249 * 3250 * @param _HANDLER_NAME 3251 * The registry name for the handler. 3252 * @param _RESULT 3253 * true if it is the handler's open command points to this 3254 * installation directory and false if it does not. 3255 * 3256 * $R7 = stores the value of the open command and the path macros return values 3257 * $R8 = stores the handler's registry key name 3258 * $R9 = _DEFAULT_VALUE and _RESULT 3259 */ 3260!macro IsHandlerForInstallDir 3261 3262 !ifndef ${_MOZFUNC_UN}IsHandlerForInstallDir 3263 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3264 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 3265 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 3266 !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString 3267 !undef _MOZFUNC_UN 3268 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3269 !undef _MOZFUNC_UN_TMP 3270 3271 !verbose push 3272 !verbose ${_MOZFUNC_VERBOSE} 3273 !define ${_MOZFUNC_UN}IsHandlerForInstallDir "!insertmacro ${_MOZFUNC_UN}IsHandlerForInstallDirCall" 3274 3275 Function ${_MOZFUNC_UN}IsHandlerForInstallDir 3276 Exch $R9 3277 Push $R8 3278 Push $R7 3279 3280 StrCpy $R8 "$R9" 3281 StrCpy $R9 "false" 3282 ReadRegStr $R7 SHCTX "Software\Classes\$R8\shell\open\command" "" 3283 3284 ${If} $R7 != "" 3285 ${GetPathFromString} "$R7" $R7 3286 ${GetParent} "$R7" $R7 3287 ${GetLongPath} "$R7" $R7 3288 ${If} $R7 == $INSTDIR 3289 StrCpy $R9 "true" 3290 ${EndIf} 3291 ${EndIf} 3292 3293 ClearErrors 3294 3295 Pop $R7 3296 Pop $R8 3297 Exch $R9 3298 FunctionEnd 3299 3300 !verbose pop 3301 !endif 3302!macroend 3303 3304!macro IsHandlerForInstallDirCall _HANDLER_NAME _RESULT 3305 !verbose push 3306 !verbose ${_MOZFUNC_VERBOSE} 3307 Push "${_HANDLER_NAME}" 3308 Call IsHandlerForInstallDir 3309 Pop "${_RESULT}" 3310 !verbose pop 3311!macroend 3312 3313!macro un.IsHandlerForInstallDirCall _HANDLER_NAME _RESULT 3314 !verbose push 3315 !verbose ${_MOZFUNC_VERBOSE} 3316 Push "${_HANDLER_NAME}" 3317 Call un.IsHandlerForInstallDir 3318 Pop "${_RESULT}" 3319 !verbose pop 3320!macroend 3321 3322!macro un.IsHandlerForInstallDir 3323 !ifndef un.IsHandlerForInstallDir 3324 !verbose push 3325 !verbose ${_MOZFUNC_VERBOSE} 3326 !undef _MOZFUNC_UN 3327 !define _MOZFUNC_UN "un." 3328 3329 !insertmacro IsHandlerForInstallDir 3330 3331 !undef _MOZFUNC_UN 3332 !define _MOZFUNC_UN 3333 !verbose pop 3334 !endif 3335!macroend 3336 3337/** 3338 * Removes the application's VirtualStore directory if present when the 3339 * installation directory is a sub-directory of the program files directory. 3340 * 3341 * $R4 = $PROGRAMFILES/$PROGRAMFILES64 for CleanVirtualStore_Internal 3342 * $R5 = various path values. 3343 * $R6 = length of the long path to $PROGRAMFILES32 or $PROGRAMFILES64 3344 * $R7 = long path to $PROGRAMFILES32 or $PROGRAMFILES64 3345 * $R8 = length of the long path to $INSTDIR 3346 * $R9 = long path to $INSTDIR 3347 */ 3348!macro CleanVirtualStore 3349 3350 !ifndef ${_MOZFUNC_UN}CleanVirtualStore 3351 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3352 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 3353 !undef _MOZFUNC_UN 3354 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3355 !undef _MOZFUNC_UN_TMP 3356 3357 !verbose push 3358 !verbose ${_MOZFUNC_VERBOSE} 3359 !define ${_MOZFUNC_UN}CleanVirtualStore "!insertmacro ${_MOZFUNC_UN}CleanVirtualStoreCall" 3360 3361 Function ${_MOZFUNC_UN}CleanVirtualStore 3362 Push $R9 3363 Push $R8 3364 Push $R7 3365 Push $R6 3366 Push $R5 3367 Push $R4 3368 3369 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R9 3370 ${If} "$R9" != "" 3371 StrLen $R8 "$R9" 3372 3373 StrCpy $R4 $PROGRAMFILES32 3374 Call ${_MOZFUNC_UN}CleanVirtualStore_Internal 3375 3376 ${If} ${RunningX64} 3377 ${OrIf} ${IsNativeARM64} 3378 StrCpy $R4 $PROGRAMFILES64 3379 Call ${_MOZFUNC_UN}CleanVirtualStore_Internal 3380 ${EndIf} 3381 3382 ${EndIf} 3383 3384 ClearErrors 3385 3386 Pop $R4 3387 Pop $R5 3388 Pop $R6 3389 Pop $R7 3390 Pop $R8 3391 Pop $R9 3392 FunctionEnd 3393 3394 Function ${_MOZFUNC_UN}CleanVirtualStore_Internal 3395 ${${_MOZFUNC_UN}GetLongPath} "" $R7 3396 ${If} "$R7" != "" 3397 StrLen $R6 "$R7" 3398 ${If} $R8 < $R6 3399 ; Copy from the start of $INSTDIR the length of $PROGRAMFILES64 3400 StrCpy $R5 "$R9" $R6 3401 ${If} "$R5" == "$R7" 3402 ; Remove the drive letter and colon from the $INSTDIR long path 3403 StrCpy $R5 "$R9" "" 2 3404 StrCpy $R5 "$LOCALAPPDATA\VirtualStore$R5" 3405 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 3406 ${If} "$R5" != "" 3407 ${AndIf} ${FileExists} "$R5" 3408 RmDir /r "$R5" 3409 ${EndIf} 3410 ${EndIf} 3411 ${EndIf} 3412 ${EndIf} 3413 FunctionEnd 3414 3415 !verbose pop 3416 !endif 3417!macroend 3418 3419!macro CleanVirtualStoreCall 3420 !verbose push 3421 !verbose ${_MOZFUNC_VERBOSE} 3422 Call CleanVirtualStore 3423 !verbose pop 3424!macroend 3425 3426!macro un.CleanVirtualStoreCall 3427 !verbose push 3428 !verbose ${_MOZFUNC_VERBOSE} 3429 Call un.CleanVirtualStore 3430 !verbose pop 3431!macroend 3432 3433!macro un.CleanVirtualStore 3434 !ifndef un.CleanVirtualStore 3435 !verbose push 3436 !verbose ${_MOZFUNC_VERBOSE} 3437 !undef _MOZFUNC_UN 3438 !define _MOZFUNC_UN "un." 3439 3440 !insertmacro CleanVirtualStore 3441 3442 !undef _MOZFUNC_UN 3443 !define _MOZFUNC_UN 3444 !verbose pop 3445 !endif 3446!macroend 3447 3448/** 3449 * If present removes the updates directory located in the profile's local 3450 * directory for this installation. 3451 * This macro is obsolete and should no longer be used. Please see 3452 * CleanUpdateDirectories. 3453 * 3454 * @param _REL_PROFILE_PATH 3455 * The relative path to the profile directory from $LOCALAPPDATA. 3456 * 3457 * $R4 = various path values. 3458 * $R5 = length of the long path to $PROGRAMFILES 3459 * $R6 = length of the long path to $INSTDIR 3460 * $R7 = long path to $PROGRAMFILES 3461 * $R8 = long path to $INSTDIR 3462 * $R9 = _REL_PROFILE_PATH 3463 */ 3464!macro CleanUpdatesDir 3465 3466 !ifndef ${_MOZFUNC_UN}CleanUpdatesDir 3467 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3468 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 3469 !undef _MOZFUNC_UN 3470 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3471 !undef _MOZFUNC_UN_TMP 3472 3473 !verbose push 3474 !verbose ${_MOZFUNC_VERBOSE} 3475 !define ${_MOZFUNC_UN}CleanUpdatesDir "!insertmacro ${_MOZFUNC_UN}CleanUpdatesDirCall" 3476 3477 Function ${_MOZFUNC_UN}CleanUpdatesDir 3478 Exch $R9 3479 Push $R8 3480 Push $R7 3481 Push $R6 3482 Push $R5 3483 Push $R4 3484 3485 StrCmp $R9 "" end +1 ; The relative path to the app's profiles is required 3486 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R8 3487 StrCmp $R8 "" end +1 3488 ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R7 3489 StrCmp $R7 "" end +1 3490 3491 StrLen $R6 "$R8" 3492 StrLen $R5 "$R7" 3493 ; Only continue If the length of $INSTDIR is greater than the length of 3494 ; $PROGRAMFILES 3495 IntCmp $R6 $R5 end end +1 3496 3497 ; Copy from the start of $INSTDIR the length of $PROGRAMFILES 3498 StrCpy $R4 "$R8" $R5 3499 StrCmp "$R4" "$R7" +1 end ; Check if $INSTDIR is under $PROGRAMFILES 3500 3501 ; Copy the relative path to $INSTDIR from $PROGRAMFILES 3502 StrCpy $R4 "$R8" "" $R5 3503 3504 ; Concatenate the path to $LOCALAPPDATA the relative profile path and the 3505 ; relative path to $INSTDIR from $PROGRAMFILES 3506 StrCpy $R4 "$LOCALAPPDATA\$R9$R4" 3507 ${${_MOZFUNC_UN}GetLongPath} "$R4" $R4 3508 StrCmp $R4 "" end +1 3509 3510 IfFileExists "$R4\updates" +1 end 3511 RmDir /r "$R4" 3512 3513 end: 3514 ClearErrors 3515 3516 Pop $R4 3517 Pop $R5 3518 Pop $R6 3519 Pop $R7 3520 Pop $R8 3521 Exch $R9 3522 FunctionEnd 3523 3524 !verbose pop 3525 !endif 3526!macroend 3527 3528!macro CleanUpdatesDirCall _REL_PROFILE_PATH 3529 !verbose push 3530 !verbose ${_MOZFUNC_VERBOSE} 3531 Push "${_REL_PROFILE_PATH}" 3532 Call CleanUpdatesDir 3533 !verbose pop 3534!macroend 3535 3536!macro un.CleanUpdatesDirCall _REL_PROFILE_PATH 3537 !verbose push 3538 !verbose ${_MOZFUNC_VERBOSE} 3539 Push "${_REL_PROFILE_PATH}" 3540 Call un.CleanUpdatesDir 3541 !verbose pop 3542!macroend 3543 3544!macro un.CleanUpdatesDir 3545 !ifndef un.CleanUpdatesDir 3546 !verbose push 3547 !verbose ${_MOZFUNC_VERBOSE} 3548 !undef _MOZFUNC_UN 3549 !define _MOZFUNC_UN "un." 3550 3551 !insertmacro CleanUpdatesDir 3552 3553 !undef _MOZFUNC_UN 3554 !define _MOZFUNC_UN 3555 !verbose pop 3556 !endif 3557!macroend 3558 3559/** 3560 * If present removes the updates directory located in the profile's local 3561 * directory for this installation. 3562 * 3563 * @param _OLD_REL_PATH 3564 * The relative path to the profile directory from $LOCALAPPDATA. 3565 * Calculated for the old update directory not based on a hash. 3566 * @param _NEW_REL_PATH 3567 * The relative path to the profile directory from $LOCALAPPDATA. 3568 * Calculated for the new update directory based on a hash. 3569 * 3570 * $R8 = _NEW_REL_PATH 3571 * $R7 = _OLD_REL_PATH 3572 * $R1 = taskBar ID hash located in registry at SOFTWARE\_OLD_REL_PATH\TaskBarIDs 3573 * $R2 = various path values. 3574 * $R3 = length of the long path to $PROGRAMFILES 3575 * $R4 = length of the long path to $INSTDIR 3576 * $R5 = long path to $PROGRAMFILES 3577 * $R6 = long path to $INSTDIR 3578 * $R0 = path to the new update directory built from _NEW_REL_PATH and 3579 * the taskbar ID. 3580 */ 3581!macro CleanUpdateDirectories 3582 3583 !ifndef ${_MOZFUNC_UN}CleanUpdateDirectories 3584 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3585 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 3586 !undef _MOZFUNC_UN 3587 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3588 !undef _MOZFUNC_UN_TMP 3589 3590 !verbose push 3591 !verbose ${_MOZFUNC_VERBOSE} 3592 !define ${_MOZFUNC_UN}CleanUpdateDirectories "!insertmacro ${_MOZFUNC_UN}CleanUpdateDirectoriesCall" 3593 3594 Function ${_MOZFUNC_UN}CleanUpdateDirectories 3595 Exch $R8 3596 Exch 1 3597 Exch $R7 3598 Push $R6 3599 Push $R5 3600 Push $R4 3601 Push $R3 3602 Push $R2 3603 Push $R1 3604 Push $R0 3605 3606 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R6 3607 StrLen $R4 "$R6" 3608 3609!ifdef HAVE_64BIT_BUILD 3610 ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES64" $R5 3611!else 3612 ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R5 3613!endif 3614 StrLen $R3 "$R5" 3615 3616 ${If} $R7 != "" ; _OLD_REL_PATH was passed 3617 ${AndIf} $R6 != "" ; We have the install dir path 3618 ${AndIf} $R5 != "" ; We the program files path 3619 ${AndIf} $R4 > $R3 ; The length of $INSTDIR > the length of $PROGRAMFILES 3620 3621 ; Copy from the start of $INSTDIR the length of $PROGRAMFILES 3622 StrCpy $R2 "$R6" $R3 3623 3624 ; Check if $INSTDIR is under $PROGRAMFILES 3625 ${If} $R2 == $R5 3626 3627 ; Copy the relative path to $INSTDIR from $PROGRAMFILES 3628 StrCpy $R2 "$R6" "" $R3 3629 3630 ; Concatenate the path $LOCALAPPDATA to the relative profile path and 3631 ; the relative path to $INSTDIR from $PROGRAMFILES 3632 StrCpy $R2 "$LOCALAPPDATA\$R7$R2" 3633 ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2 3634 3635 ${If} $R2 != "" 3636 ; Backup the old update directory logs and delete the directory 3637 ${If} ${FileExists} "$R2\updates\last-update.log" 3638 Rename "$R2\updates\last-update.log" "$TEMP\moz-update-oldest-last-update.log" 3639 ${EndIf} 3640 3641 ${If} ${FileExists} "$R2\updates\backup-update.log" 3642 Rename "$R2\updates\backup-update.log" "$TEMP\moz-update-oldest-backup-update.log" 3643 ${EndIf} 3644 3645 ${If} ${FileExists} "$R2\updates" 3646 RmDir /r "$R2" 3647 ${EndIf} 3648 ${EndIf} 3649 ${EndIf} 3650 3651 ; Get the taskbar ID hash for this installation path 3652 ReadRegStr $R1 HKLM "SOFTWARE\$R7\TaskBarIDs" $R6 3653 ${If} $R1 == "" 3654 ReadRegStr $R1 HKCU "SOFTWARE\$R7\TaskBarIDs" $R6 3655 ${EndIf} 3656 3657 ; If the taskbar ID hash exists then delete the new update directory 3658 ; Backup its logs before deleting it. 3659 ${If} $R1 != "" 3660 StrCpy $R0 "$LOCALAPPDATA\$R8\$R1" 3661 3662 ${If} ${FileExists} "$R0\updates\last-update.log" 3663 Rename "$R0\updates\last-update.log" "$TEMP\moz-update-older-last-update.log" 3664 ${EndIf} 3665 3666 ${If} ${FileExists} "$R0\updates\backup-update.log" 3667 Rename "$R0\updates\backup-update.log" "$TEMP\moz-update-older-backup-update.log" 3668 ${EndIf} 3669 3670 ; Remove the old updates directory, located in the user's Windows profile directory 3671 ${If} ${FileExists} "$R0\updates" 3672 RmDir /r "$R0" 3673 ${EndIf} 3674 3675 ; Get the new updates directory so we can remove that too 3676 ; The new update directory is in the Program Data directory 3677 ; (currently C:\ProgramData). 3678 ; This system call gets that directory path. The arguments are: 3679 ; A null ptr for hwnd 3680 ; $R0 for the output string 3681 ; CSIDL_COMMON_APPDATA == 0x0023 == 35 for the csidl indicating which dir to get 3682 ; false for fCreate (i.e. Do not create the folder if it doesn't exist) 3683 ; We could use %APPDATA% for this instead, but that requires state: the shell 3684 ; var context would need to be saved, set, and reset. It is easier just to use 3685 ; the system call. 3686 System::Call "Shell32::SHGetSpecialFolderPathW(p 0, t.R0, i 35, i 0)" 3687 StrCpy $R0 "$R0\$R8\$R1" 3688 3689 ${If} ${FileExists} "$R0\updates\last-update.log" 3690 Rename "$R0\updates\last-update.log" "$TEMP\moz-update-newest-last-update.log" 3691 ${EndIf} 3692 3693 ${If} ${FileExists} "$R0\updates\backup-update.log" 3694 Rename "$R0\updates\backup-update.log" "$TEMP\moz-update-newest-backup-update.log" 3695 ${EndIf} 3696 3697 ; Remove the new updates directory, which is shared by all users of the installation 3698 ${If} ${FileExists} "$R0\updates" 3699 RmDir /r "$R0" 3700 ${EndIf} 3701 ${EndIf} 3702 ${EndIf} 3703 3704 ClearErrors 3705 3706 Pop $R0 3707 Pop $R1 3708 Pop $R2 3709 Pop $R3 3710 Pop $R4 3711 Pop $R5 3712 Pop $R6 3713 Exch $R7 3714 Exch 1 3715 Exch $R8 3716 FunctionEnd 3717 3718 !verbose pop 3719 !endif 3720!macroend 3721 3722!macro CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH 3723 !verbose push 3724 !verbose ${_MOZFUNC_VERBOSE} 3725 Push "${_OLD_REL_PATH}" 3726 Push "${_NEW_REL_PATH}" 3727 Call CleanUpdateDirectories 3728 !verbose pop 3729!macroend 3730 3731!macro un.CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH 3732 !verbose push 3733 !verbose ${_MOZFUNC_VERBOSE} 3734 Push "${_OLD_REL_PATH}" 3735 Push "${_NEW_REL_PATH}" 3736 Call un.CleanUpdateDirectories 3737 !verbose pop 3738!macroend 3739 3740!macro un.CleanUpdateDirectories 3741 !ifndef un.CleanUpdateDirectories 3742 !verbose push 3743 !verbose ${_MOZFUNC_VERBOSE} 3744 !undef _MOZFUNC_UN 3745 !define _MOZFUNC_UN "un." 3746 3747 !insertmacro CleanUpdateDirectories 3748 3749 !undef _MOZFUNC_UN 3750 !define _MOZFUNC_UN 3751 !verbose pop 3752 !endif 3753!macroend 3754 3755/** 3756 * Create the update directory and sets the permissions correctly 3757 * 3758 * @param ROOT_DIR_NAME 3759 * The name of the update directory to be created in the common 3760 * application directory. For example, if ROOT_DIR_NAME is "Mozilla", 3761 * the created directory will be "C:\ProgramData\Mozilla". 3762 * 3763 * $R0 = Used for checking errors 3764 * $R1 = The common application directory path 3765 * $R9 = An error message to be returned on the stack 3766 */ 3767!macro CreateUpdateDir ROOT_DIR_NAME 3768 Push $R9 3769 Push $R0 3770 Push $R1 3771 3772 ; The update directory is in the Program Data directory 3773 ; (currently C:\ProgramData). 3774 ; This system call gets that directory path. The arguments are: 3775 ; A null ptr for hwnd 3776 ; $R1 for the output string 3777 ; CSIDL_COMMON_APPDATA == 0x0023 == 35 for the csidl indicating which dir to get 3778 ; true for fCreate (i.e. Do create the folder if it doesn't exist) 3779 ; We could use %APPDATA% for this instead, but that requires state: the shell 3780 ; var context would need to be saved, set, and reset. It is easier just to use 3781 ; the system call. 3782 System::Call "Shell32::SHGetSpecialFolderPathW(p 0, t.R1, i 35, i 1)" 3783 StrCpy $R1 "$R1\${ROOT_DIR_NAME}" 3784 3785 ClearErrors 3786 ${IfNot} ${FileExists} "$R1" 3787 CreateDirectory "$R1" 3788 ${If} ${Errors} 3789 StrCpy $R9 "Unable to create directory: $R1" 3790 GoTo end 3791 ${EndIf} 3792 ${EndIf} 3793 3794 ; Grant Full Access to the Builtin User group 3795 AccessControl::SetOnFile "$R1" "(BU)" "FullAccess" 3796 Pop $R0 3797 ${If} $R0 == error 3798 Pop $R9 ; Get AccessControl's Error Message 3799 SetErrors 3800 GoTo end 3801 ${EndIf} 3802 3803 ; Grant Full Access to the Builtin Administrator group 3804 AccessControl::SetOnFile "$R1" "(BA)" "FullAccess" 3805 Pop $R0 3806 ${If} $R0 == error 3807 Pop $R9 ; Get AccessControl's Error Message 3808 SetErrors 3809 GoTo end 3810 ${EndIf} 3811 3812 ; Grant Full Access to the SYSTEM user 3813 AccessControl::SetOnFile "$R1" "(SY)" "FullAccess" 3814 Pop $R0 3815 ${If} $R0 == error 3816 Pop $R9 ; Get AccessControl's Error Message 3817 SetErrors 3818 GoTo end 3819 ${EndIf} 3820 3821 ; Remove inherited permissions 3822 AccessControl::DisableFileInheritance "$R1" 3823 Pop $R0 3824 ${If} $R0 == error 3825 Pop $R9 ; Get AccessControl's Error Message 3826 SetErrors 3827 GoTo end 3828 ${EndIf} 3829 3830end: 3831 Pop $R1 3832 Pop $R0 3833 ${If} ${Errors} 3834 Exch $R9 3835 ${Else} 3836 Pop $R9 3837 ${EndIf} 3838!macroend 3839!define CreateUpdateDir "!insertmacro CreateUpdateDir" 3840 3841/** 3842 * Deletes all relative profiles specified in an application's profiles.ini and 3843 * performs various other cleanup. 3844 * 3845 * @param _REL_PROFILE_PATH 3846 * The relative path to the profile directory. 3847 * 3848 * $R6 = value of IsRelative read from profiles.ini 3849 * $R7 = value of Path to profile read from profiles.ini 3850 * $R8 = counter for reading profiles (e.g. Profile0, Profile1, etc.) 3851 * $R9 = _REL_PROFILE_PATH 3852 */ 3853!macro DeleteRelativeProfiles 3854 3855 !ifndef ${_MOZFUNC_UN}DeleteRelativeProfiles 3856 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3857 !insertmacro ${_MOZFUNC_UN_TMP}WordReplace 3858 !undef _MOZFUNC_UN 3859 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3860 !undef _MOZFUNC_UN_TMP 3861 3862 !verbose push 3863 !verbose ${_MOZFUNC_VERBOSE} 3864 !define ${_MOZFUNC_UN}DeleteRelativeProfiles "!insertmacro ${_MOZFUNC_UN}DeleteRelativeProfilesCall" 3865 3866 Function ${_MOZFUNC_UN}DeleteRelativeProfiles 3867 Exch $R9 3868 Push $R8 3869 Push $R7 3870 Push $R6 3871 3872 SetShellVarContext current 3873 StrCpy $R8 -1 3874 3875 loop: 3876 IntOp $R8 $R8 + 1 ; Increment the counter. 3877 ReadINIStr $R7 "$APPDATA\$R9\profiles.ini" "Profile$R8" "Path" 3878 IfErrors end +1 3879 3880 ; Only remove relative profiles 3881 ReadINIStr $R6 "$APPDATA\$R9\profiles.ini" "Profile$R8" "IsRelative" 3882 StrCmp "$R6" "1" +1 loop 3883 3884 ; Relative paths in profiles.ini use / as a separator 3885 ${${_MOZFUNC_UN}WordReplace} "$R7" "/" "\" "+" $R7 3886 3887 IfFileExists "$LOCALAPPDATA\$R9\$R7" +1 +2 3888 RmDir /r "$LOCALAPPDATA\$R9\$R7" 3889 IfFileExists "$APPDATA\$R9\$R7" +1 +2 3890 RmDir /r "$APPDATA\$R9\$R7" 3891 GoTo loop 3892 3893 end: 3894 ; Remove profiles directory under LOCALAPPDATA (e.g. cache, etc.) since 3895 ; they are at times abandoned. 3896 RmDir /r "$LOCALAPPDATA\$R9\Profiles" 3897 RmDir /r "$APPDATA\$R9\Crash Reports" 3898 Delete "$APPDATA\$R9\profiles.ini" 3899 Delete "$APPDATA\$R9\console.log" 3900 Delete "$APPDATA\$R9\pluginreg.dat" 3901 RmDir "$APPDATA\$R9\Profiles" 3902 RmDir "$APPDATA\$R9" 3903 3904 Pop $R6 3905 Pop $R7 3906 Pop $R8 3907 Exch $R9 3908 FunctionEnd 3909 3910 !verbose pop 3911 !endif 3912!macroend 3913 3914!macro DeleteRelativeProfilesCall _REL_PROFILE_PATH 3915 !verbose push 3916 !verbose ${_MOZFUNC_VERBOSE} 3917 Push "${_REL_PROFILE_PATH}" 3918 Call DeleteRelativeProfiles 3919 !verbose pop 3920!macroend 3921 3922!macro un.DeleteRelativeProfilesCall _REL_PROFILE_PATH 3923 !verbose push 3924 !verbose ${_MOZFUNC_VERBOSE} 3925 Push "${_REL_PROFILE_PATH}" 3926 Call un.DeleteRelativeProfiles 3927 !verbose pop 3928!macroend 3929 3930!macro un.DeleteRelativeProfiles 3931 !ifndef un.DeleteRelativeProfiles 3932 !verbose push 3933 !verbose ${_MOZFUNC_VERBOSE} 3934 !undef _MOZFUNC_UN 3935 !define _MOZFUNC_UN "un." 3936 3937 !insertmacro DeleteRelativeProfiles 3938 3939 !undef _MOZFUNC_UN 3940 !define _MOZFUNC_UN 3941 !verbose pop 3942 !endif 3943!macroend 3944 3945/** 3946 * Deletes shortcuts and Start Menu directories under Programs as specified by 3947 * the shortcuts log ini file and on Windows 7 unpins TaskBar and Start Menu 3948 * shortcuts. The shortcuts will not be deleted if the shortcut target isn't for 3949 * this install location which is determined by the shortcut having a target of 3950 * $INSTDIR\${FileMainEXE}. The context (All Users or Current User) of the 3951 * $DESKTOP and $SMPROGRAMS constants depends on the 3952 * SetShellVarContext setting and must be set by the caller of this macro. There 3953 * is no All Users context for $QUICKLAUNCH but this will not cause a problem 3954 * since the macro will just continue past the $QUICKLAUNCH shortcut deletion 3955 * section on subsequent calls. 3956 * 3957 * The ini file sections must have the following format (the order of the 3958 * sections in the ini file is not important): 3959 * [SMPROGRAMS] 3960 * ; RelativePath is the directory relative from the Start Menu 3961 * ; Programs directory. 3962 * RelativePath=Mozilla App 3963 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 3964 * ; on. There must not be a break in the sequence of the numbers. 3965 * Shortcut1=Mozilla App.lnk 3966 * Shortcut2=Mozilla App (Safe Mode).lnk 3967 * [DESKTOP] 3968 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 3969 * ; on. There must not be a break in the sequence of the numbers. 3970 * Shortcut1=Mozilla App.lnk 3971 * Shortcut2=Mozilla App (Safe Mode).lnk 3972 * [QUICKLAUNCH] 3973 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 3974 * ; on. There must not be a break in the sequence of the numbers for the 3975 * ; suffix. 3976 * Shortcut1=Mozilla App.lnk 3977 * Shortcut2=Mozilla App (Safe Mode).lnk 3978 * [STARTMENU] 3979 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 3980 * ; on. There must not be a break in the sequence of the numbers for the 3981 * ; suffix. 3982 * Shortcut1=Mozilla App.lnk 3983 * Shortcut2=Mozilla App (Safe Mode).lnk 3984 * 3985 * $R4 = counter for appending to Shortcut for enumerating the ini file entries 3986 * $R5 = return value from ShellLink::GetShortCutTarget and 3987 * ApplicationID::UninstallPinnedItem 3988 * $R6 = find handle and the long path to the Start Menu Programs directory 3989 * (e.g. $SMPROGRAMS) 3990 * $R7 = path to the $QUICKLAUNCH\User Pinned directory and the return value 3991 * from ReadINIStr for the relative path to the applications directory 3992 * under the Start Menu Programs directory and the long path to this 3993 * directory 3994 * $R8 = return filename from FindFirst / FindNext and the return value from 3995 * ReadINIStr for enumerating shortcuts 3996 * $R9 = long path to the shortcuts log ini file 3997 */ 3998!macro DeleteShortcuts 3999 4000 !ifndef ${_MOZFUNC_UN}DeleteShortcuts 4001 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 4002 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 4003 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 4004 !undef _MOZFUNC_UN 4005 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 4006 !undef _MOZFUNC_UN_TMP 4007 4008 !verbose push 4009 !verbose ${_MOZFUNC_VERBOSE} 4010 !define ${_MOZFUNC_UN}DeleteShortcuts "!insertmacro ${_MOZFUNC_UN}DeleteShortcutsCall" 4011 4012 Function ${_MOZFUNC_UN}DeleteShortcuts 4013 Push $R9 4014 Push $R8 4015 Push $R7 4016 Push $R6 4017 Push $R5 4018 Push $R4 4019 4020 ${If} ${AtLeastWin7} 4021 ; Since shortcuts that are pinned can later be removed without removing 4022 ; the pinned shortcut unpin the pinned shortcuts for the application's 4023 ; main exe using the pinned shortcuts themselves. 4024 StrCpy $R7 "$QUICKLAUNCH\User Pinned" 4025 4026 ${If} ${FileExists} "$R7\TaskBar" 4027 ; Delete TaskBar pinned shortcuts for the application's main exe 4028 FindFirst $R6 $R8 "$R7\TaskBar\*.lnk" 4029 ${Do} 4030 ${If} ${FileExists} "$R7\TaskBar\$R8" 4031 ShellLink::GetShortCutTarget "$R7\TaskBar\$R8" 4032 Pop $R5 4033 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4034 ${If} "$R5" == "$INSTDIR\${FileMainEXE}" 4035 ApplicationID::UninstallPinnedItem "$R7\TaskBar\$R8" 4036 Pop $R5 4037 ${EndIf} 4038 ${EndIf} 4039 ClearErrors 4040 FindNext $R6 $R8 4041 ${If} ${Errors} 4042 ${ExitDo} 4043 ${EndIf} 4044 ${Loop} 4045 FindClose $R6 4046 ${EndIf} 4047 4048 ${If} ${FileExists} "$R7\StartMenu" 4049 ; Delete Start Menu pinned shortcuts for the application's main exe 4050 FindFirst $R6 $R8 "$R7\StartMenu\*.lnk" 4051 ${Do} 4052 ${If} ${FileExists} "$R7\StartMenu\$R8" 4053 ShellLink::GetShortCutTarget "$R7\StartMenu\$R8" 4054 Pop $R5 4055 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4056 ${If} "$R5" == "$INSTDIR\${FileMainEXE}" 4057 ApplicationID::UninstallPinnedItem "$R7\StartMenu\$R8" 4058 Pop $R5 4059 ${EndIf} 4060 ${EndIf} 4061 ClearErrors 4062 FindNext $R6 $R8 4063 ${If} ${Errors} 4064 ${ExitDo} 4065 ${EndIf} 4066 ${Loop} 4067 FindClose $R6 4068 ${EndIf} 4069 ${EndIf} 4070 4071 ; Don't call ApplicationID::UninstallPinnedItem since pinned items for 4072 ; this application were removed above and removing them below will remove 4073 ; the association of side by side installations. 4074 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9 4075 ${If} ${FileExists} "$R9" 4076 ; Delete Start Menu shortcuts for this application 4077 StrCpy $R4 -1 4078 ${Do} 4079 IntOp $R4 $R4 + 1 ; Increment the counter 4080 ClearErrors 4081 ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4" 4082 ${If} ${Errors} 4083 ${ExitDo} 4084 ${EndIf} 4085 4086 ${If} ${FileExists} "$SMPROGRAMS\$R8" 4087 ShellLink::GetShortCutTarget "$SMPROGRAMS\$R8" 4088 Pop $R5 4089 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4090 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4091 Delete "$SMPROGRAMS\$R8" 4092 ${EndIf} 4093 ${EndIf} 4094 ${Loop} 4095 ; There might also be a shortcut with a different name created by a 4096 ; previous version of the installer. 4097 ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" 4098 ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandFullName}.lnk" 4099 Pop $R5 4100 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4101 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4102 Delete "$SMPROGRAMS\${BrandFullName}.lnk" 4103 ${EndIf} 4104 ${EndIf} 4105 4106 ; Delete Quick Launch shortcuts for this application 4107 StrCpy $R4 -1 4108 ${Do} 4109 IntOp $R4 $R4 + 1 ; Increment the counter 4110 ClearErrors 4111 ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4" 4112 ${If} ${Errors} 4113 ${ExitDo} 4114 ${EndIf} 4115 4116 ${If} ${FileExists} "$QUICKLAUNCH\$R8" 4117 ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8" 4118 Pop $R5 4119 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4120 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4121 Delete "$QUICKLAUNCH\$R8" 4122 ${EndIf} 4123 ${EndIf} 4124 ${Loop} 4125 ; There might also be a shortcut with a different name created by a 4126 ; previous version of the installer. 4127 ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" 4128 ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk" 4129 Pop $R5 4130 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4131 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4132 Delete "$QUICKLAUNCH\${BrandFullName}.lnk" 4133 ${EndIf} 4134 ${EndIf} 4135 4136 ; Delete Desktop shortcuts for this application 4137 StrCpy $R4 -1 4138 ${Do} 4139 IntOp $R4 $R4 + 1 ; Increment the counter 4140 ClearErrors 4141 ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4" 4142 ${If} ${Errors} 4143 ${ExitDo} 4144 ${EndIf} 4145 4146 ${If} ${FileExists} "$DESKTOP\$R8" 4147 ShellLink::GetShortCutTarget "$DESKTOP\$R8" 4148 Pop $R5 4149 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4150 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4151 Delete "$DESKTOP\$R8" 4152 ${EndIf} 4153 ${EndIf} 4154 ${Loop} 4155 ; There might also be a shortcut with a different name created by a 4156 ; previous version of the installer. 4157 ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" 4158 ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk" 4159 Pop $R5 4160 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4161 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4162 Delete "$DESKTOP\${BrandFullName}.lnk" 4163 ${EndIf} 4164 ${EndIf} 4165 4166 ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6 4167 4168 ; Delete Start Menu Programs shortcuts for this application 4169 ClearErrors 4170 ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir" 4171 ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7 4172 ${Unless} "$R7" == "" 4173 StrCpy $R4 -1 4174 ${Do} 4175 IntOp $R4 $R4 + 1 ; Increment the counter 4176 ClearErrors 4177 ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4" 4178 ${If} ${Errors} 4179 ${ExitDo} 4180 ${EndIf} 4181 4182 ${If} ${FileExists} "$R7\$R8" 4183 ShellLink::GetShortCutTarget "$R7\$R8" 4184 Pop $R5 4185 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4186 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4187 Delete "$R7\$R8" 4188 ${EndIf} 4189 ${EndIf} 4190 ${Loop} 4191 4192 ; Delete Start Menu Programs directories for this application 4193 ${Do} 4194 ClearErrors 4195 ${If} "$R6" == "$R7" 4196 ${ExitDo} 4197 ${EndIf} 4198 RmDir "$R7" 4199 ${If} ${Errors} 4200 ${ExitDo} 4201 ${EndIf} 4202 ${${_MOZFUNC_UN}GetParent} "$R7" $R7 4203 ${Loop} 4204 ${EndUnless} 4205 ${EndIf} 4206 4207 ClearErrors 4208 4209 Pop $R4 4210 Pop $R5 4211 Pop $R6 4212 Pop $R7 4213 Pop $R8 4214 Pop $R9 4215 FunctionEnd 4216 4217 !verbose pop 4218 !endif 4219!macroend 4220 4221!macro DeleteShortcutsCall 4222 !verbose push 4223 !verbose ${_MOZFUNC_VERBOSE} 4224 Call DeleteShortcuts 4225 !verbose pop 4226!macroend 4227 4228!macro un.DeleteShortcutsCall 4229 !verbose push 4230 !verbose ${_MOZFUNC_VERBOSE} 4231 Call un.DeleteShortcuts 4232 !verbose pop 4233!macroend 4234 4235!macro un.DeleteShortcuts 4236 !ifndef un.DeleteShortcuts 4237 !verbose push 4238 !verbose ${_MOZFUNC_VERBOSE} 4239 !undef _MOZFUNC_UN 4240 !define _MOZFUNC_UN "un." 4241 4242 !insertmacro DeleteShortcuts 4243 4244 !undef _MOZFUNC_UN 4245 !define _MOZFUNC_UN 4246 !verbose pop 4247 !endif 4248!macroend 4249 4250 4251################################################################################ 4252# Macros for parsing and updating the uninstall.log 4253 4254/** 4255 * Updates the uninstall.log with new files added by software update. 4256 * 4257 * When modifying this macro be aware that LineFind uses all registers except 4258 * $R0-$R3 and TextCompareNoDetails uses all registers except $R0-$R9 so be 4259 * cautious. Callers of this macro are not affected. 4260 */ 4261!macro UpdateUninstallLog 4262 4263 !ifndef UpdateUninstallLog 4264 !insertmacro FileJoin 4265 !insertmacro LineFind 4266 !insertmacro TextCompareNoDetails 4267 !insertmacro TrimNewLines 4268 4269 !verbose push 4270 !verbose ${_MOZFUNC_VERBOSE} 4271 !define UpdateUninstallLog "!insertmacro UpdateUninstallLogCall" 4272 4273 Function UpdateUninstallLog 4274 Push $R3 4275 Push $R2 4276 Push $R1 4277 Push $R0 4278 4279 ClearErrors 4280 4281 GetFullPathName $R3 "$INSTDIR\uninstall" 4282 ${If} ${FileExists} "$R3\uninstall.update" 4283 ${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog" 4284 4285 GetTempFileName $R2 "$R3" 4286 FileOpen $R1 "$R2" w 4287 ${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff" 4288 FileClose $R1 4289 4290 IfErrors +2 0 4291 ${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log" 4292 4293 ${DeleteFile} "$R2" 4294 ${EndIf} 4295 4296 ClearErrors 4297 4298 Pop $R0 4299 Pop $R1 4300 Pop $R2 4301 Pop $R3 4302 FunctionEnd 4303 4304 ; This callback MUST use labels vs. relative line numbers. 4305 Function CleanupUpdateLog 4306 StrCpy $R2 "$R9" 12 4307 StrCmp "$R2" "EXECUTE ADD " +1 skip 4308 StrCpy $R9 "$R9" "" 12 4309 4310 Push $R6 4311 Push $R5 4312 Push $R4 4313 StrCpy $R4 "" ; Initialize to an empty string. 4314 StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0. 4315 4316 loop: 4317 IntOp $R6 $R6 + 1 ; Increment the counter. 4318 StrCpy $R5 $R9 1 $R6 ; Starting from the counter copy the next char. 4319 StrCmp $R5 "" copy ; Are there no more chars? 4320 StrCmp $R5 "/" +1 +2 ; Is the char a /? 4321 StrCpy $R5 "\" ; Replace the char with a \. 4322 4323 StrCpy $R4 "$R4$R5" 4324 GoTo loop 4325 4326 copy: 4327 StrCpy $R9 "File: \$R4" 4328 Pop $R6 4329 Pop $R5 4330 Pop $R4 4331 GoTo end 4332 4333 skip: 4334 StrCpy $0 "SkipWrite" 4335 4336 end: 4337 Push $0 4338 FunctionEnd 4339 4340 Function CreateUpdateDiff 4341 ${TrimNewLines} "$9" $9 4342 ${If} $9 != "" 4343 FileWrite $R1 "$9$\r$\n" 4344 ${EndIf} 4345 4346 Push 0 4347 FunctionEnd 4348 4349 !verbose pop 4350 !endif 4351!macroend 4352 4353!macro UpdateUninstallLogCall 4354 !verbose push 4355 !verbose ${_MOZFUNC_VERBOSE} 4356 Call UpdateUninstallLog 4357 !verbose pop 4358!macroend 4359 4360/** 4361 * Copies files from a source directory to a destination directory with logging 4362 * to the uninstall.log. If any destination files are in use a reboot will be 4363 * necessary to complete the installation and the reboot flag (see IfRebootFlag 4364 * in the NSIS documentation). 4365 * 4366 * @param _PATH_TO_SOURCE 4367 * Source path to copy the files from. This must not end with a \. 4368 * 4369 * @param _PATH_TO_DESTINATION 4370 * Destination path to copy the files to. This must not end with a \. 4371 * 4372 * @param _PREFIX_ERROR_CREATEDIR 4373 * Prefix for the directory creation error message. The directory path 4374 * will be inserted below this string. 4375 * 4376 * @param _SUFFIX_ERROR_CREATEDIR 4377 * Suffix for the directory creation error message. The directory path 4378 * will be inserted above this string. 4379 * 4380 * $0 = destination file's parent directory used in the create_dir label 4381 * $R0 = copied value from $R6 (e.g. _PATH_TO_SOURCE) 4382 * $R1 = copied value from $R7 (e.g. _PATH_TO_DESTINATION) 4383 * $R2 = string length of the path to source 4384 * $R3 = relative path from the path to source 4385 * $R4 = copied value from $R8 (e.g. _PREFIX_ERROR_CREATEDIR) 4386 * $R5 = copied value from $R9 (e.g. _SUFFIX_ERROR_CREATEDIR) 4387 * note: the LocateNoDetails macro uses these registers so we copy the values 4388 * to other registers. 4389 * $R6 = initially _PATH_TO_SOURCE and then set to "size" ($R6="" if directory, 4390 * $R6="0" if file with /S=)"path\name" in callback 4391 * $R7 = initially _PATH_TO_DESTINATION and then set to "name" in callback 4392 * $R8 = initially _PREFIX_ERROR_CREATEDIR and then set to "path" in callback 4393 * $R9 = initially _SUFFIX_ERROR_CREATEDIR and then set to "path\name" in 4394 * callback 4395 */ 4396!macro CopyFilesFromDir 4397 4398 !ifndef CopyFilesFromDir 4399 !insertmacro LocateNoDetails 4400 !insertmacro OnEndCommon 4401 !insertmacro WordReplace 4402 4403 !verbose push 4404 !verbose ${_MOZFUNC_VERBOSE} 4405 !define CopyFilesFromDir "!insertmacro CopyFilesFromDirCall" 4406 4407 Function CopyFilesFromDir 4408 Exch $R9 4409 Exch 1 4410 Exch $R8 4411 Exch 2 4412 Exch $R7 4413 Exch 3 4414 Exch $R6 4415 Push $R5 4416 Push $R4 4417 Push $R3 4418 Push $R2 4419 Push $R1 4420 Push $R0 4421 Push $0 4422 4423 StrCpy $R0 "$R6" 4424 StrCpy $R1 "$R7" 4425 StrCpy $R4 "$R8" 4426 StrCpy $R5 "$R9" 4427 4428 StrLen $R2 "$R0" 4429 4430 ${LocateNoDetails} "$R0" "/L=FD" "CopyFileCallback" 4431 4432 Pop $0 4433 Pop $R0 4434 Pop $R1 4435 Pop $R2 4436 Pop $R3 4437 Pop $R4 4438 Pop $R5 4439 Exch $R6 4440 Exch 3 4441 Exch $R7 4442 Exch 2 4443 Exch $R8 4444 Exch 1 4445 Exch $R9 4446 FunctionEnd 4447 4448 Function CopyFileCallback 4449 StrCpy $R3 $R8 "" $R2 ; $R3 always begins with a \. 4450 4451 retry: 4452 ClearErrors 4453 StrCmp $R6 "" +1 copy_file 4454 IfFileExists "$R1$R3\$R7" end +1 4455 StrCpy $0 "$R1$R3\$R7" 4456 4457 create_dir: 4458 ClearErrors 4459 CreateDirectory "$0" 4460 IfFileExists "$0" +1 err_create_dir ; protect against looping. 4461 ${LogMsg} "Created Directory: $0" 4462 StrCmp $R6 "" end copy_file 4463 4464 err_create_dir: 4465 ${LogMsg} "** ERROR Creating Directory: $0 **" 4466 MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$R4$\r$\n$\r$\n$0$\r$\n$\r$\n$R5" IDRETRY retry 4467 ${OnEndCommon} 4468 Quit 4469 4470 copy_file: 4471 StrCpy $0 "$R1$R3" 4472 StrCmp "$0" "$INSTDIR" +2 +1 4473 IfFileExists "$0" +1 create_dir 4474 4475 ClearErrors 4476 ${DeleteFile} "$R1$R3\$R7" 4477 IfErrors +1 dest_clear 4478 ClearErrors 4479 Rename "$R1$R3\$R7" "$R1$R3\$R7.moz-delete" 4480 IfErrors +1 reboot_delete 4481 4482 ; file will replace destination file on reboot 4483 Rename "$R9" "$R9.moz-upgrade" 4484 CopyFiles /SILENT "$R9.moz-upgrade" "$R1$R3" 4485 Rename /REBOOTOK "$R1$R3\$R7.moz-upgrade" "$R1$R3\$R7" 4486 ${LogMsg} "Copied File: $R1$R3\$R7.moz-upgrade" 4487 ${LogMsg} "Delayed Install File (Reboot Required): $R1$R3\$R7" 4488 GoTo log_uninstall 4489 4490 ; file will be deleted on reboot 4491 reboot_delete: 4492 CopyFiles /SILENT $R9 "$R1$R3" 4493 Delete /REBOOTOK "$R1$R3\$R7.moz-delete" 4494 ${LogMsg} "Installed File: $R1$R3\$R7" 4495 ${LogMsg} "Delayed Delete File (Reboot Required): $R1$R3\$R7.moz-delete" 4496 GoTo log_uninstall 4497 4498 ; destination file doesn't exist - coast is clear 4499 dest_clear: 4500 CopyFiles /SILENT $R9 "$R1$R3" 4501 ${LogMsg} "Installed File: $R1$R3\$R7" 4502 4503 log_uninstall: 4504 ; If the file is installed into the installation directory remove the 4505 ; installation directory's path from the file path when writing to the 4506 ; uninstall.log so it will be a relative path. This allows the same 4507 ; helper.exe to be used with zip builds if we supply an uninstall.log. 4508 ${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3 4509 ${LogUninstall} "File: $R3" 4510 4511 end: 4512 Push 0 4513 FunctionEnd 4514 4515 !verbose pop 4516 !endif 4517!macroend 4518 4519!macro CopyFilesFromDirCall _PATH_TO_SOURCE _PATH_TO_DESTINATION \ 4520 _PREFIX_ERROR_CREATEDIR _SUFFIX_ERROR_CREATEDIR 4521 !verbose push 4522 !verbose ${_MOZFUNC_VERBOSE} 4523 Push "${_PATH_TO_SOURCE}" 4524 Push "${_PATH_TO_DESTINATION}" 4525 Push "${_PREFIX_ERROR_CREATEDIR}" 4526 Push "${_SUFFIX_ERROR_CREATEDIR}" 4527 Call CopyFilesFromDir 4528 !verbose pop 4529!macroend 4530 4531/** 4532 * Parses the uninstall.log on install to first remove a previous installation's 4533 * files and then their directories if empty prior to installing. 4534 * 4535 * When modifying this macro be aware that LineFind uses all registers except 4536 * $R0-$R3 so be cautious. Callers of this macro are not affected. 4537 */ 4538!macro OnInstallUninstall 4539 4540 !ifndef OnInstallUninstall 4541 !insertmacro GetParent 4542 !insertmacro LineFind 4543 !insertmacro TrimNewLines 4544 4545 !verbose push 4546 !verbose ${_MOZFUNC_VERBOSE} 4547 !define OnInstallUninstall "!insertmacro OnInstallUninstallCall" 4548 4549 Function OnInstallUninstall 4550 Push $R9 4551 Push $R8 4552 Push $R7 4553 Push $R6 4554 Push $R5 4555 Push $R4 4556 Push $R3 4557 Push $R2 4558 Push $R1 4559 Push $R0 4560 Push $TmpVal 4561 4562 IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end 4563 4564 ${LogHeader} "Removing Previous Installation" 4565 4566 ; Copy the uninstall log file to a temporary file 4567 GetTempFileName $TmpVal 4568 CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" 4569 4570 ; Delete files 4571 ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveFilesCallback" 4572 4573 ; Remove empty directories 4574 ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveDirsCallback" 4575 4576 ; Delete the temporary uninstall log file 4577 Delete /REBOOTOK "$TmpVal" 4578 4579 ; Delete the uninstall log file 4580 Delete "$INSTDIR\uninstall\uninstall.log" 4581 4582 end: 4583 ClearErrors 4584 4585 Pop $TmpVal 4586 Pop $R0 4587 Pop $R1 4588 Pop $R2 4589 Pop $R3 4590 Pop $R4 4591 Pop $R5 4592 Pop $R6 4593 Pop $R7 4594 Pop $R8 4595 Pop $R9 4596 FunctionEnd 4597 4598 Function RemoveFilesCallback 4599 ${TrimNewLines} "$R9" $R9 4600 StrCpy $R1 "$R9" 5 ; Copy the first five chars 4601 4602 StrCmp "$R1" "File:" +1 end 4603 StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char 4604 StrCpy $R0 "$R9" 1 ; Copy the first char 4605 4606 StrCmp "$R0" "\" +1 end ; If this isn't a relative path goto end 4607 StrCmp "$R9" "\install.log" end +1 ; Skip the install.log 4608 StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll 4609 StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll 4610 4611 StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string 4612 IfFileExists "$R1" +1 end 4613 4614 ClearErrors 4615 Delete "$R1" 4616 ${Unless} ${Errors} 4617 ${LogMsg} "Deleted File: $R1" 4618 Goto end 4619 ${EndUnless} 4620 4621 ClearErrors 4622 Rename "$R1" "$R1.moz-delete" 4623 ${Unless} ${Errors} 4624 Delete /REBOOTOK "$R1.moz-delete" 4625 ${LogMsg} "Delayed Delete File (Reboot Required): $R1.moz-delete" 4626 GoTo end 4627 ${EndUnless} 4628 4629 ; Check if the file exists in the source. If it does the new file will 4630 ; replace the existing file when the system is rebooted. If it doesn't 4631 ; the file will be deleted when the system is rebooted. 4632 ${Unless} ${FileExists} "$EXEDIR\core$R9" 4633 ${AndUnless} ${FileExists} "$EXEDIR\optional$R9" 4634 Delete /REBOOTOK "$R1" 4635 ${LogMsg} "Delayed Delete File (Reboot Required): $R1" 4636 ${EndUnless} 4637 4638 end: 4639 ClearErrors 4640 4641 Push 0 4642 FunctionEnd 4643 4644 ; Using locate will leave file handles open to some of the directories 4645 ; which will prevent the deletion of these directories. This parses the 4646 ; uninstall.log and uses the file entries to find / remove empty 4647 ; directories. 4648 Function RemoveDirsCallback 4649 ${TrimNewLines} "$R9" $R9 4650 StrCpy $R0 "$R9" 5 ; Copy the first five chars 4651 StrCmp "$R0" "File:" +1 end 4652 4653 StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char 4654 StrCpy $R0 "$R9" 1 ; Copy the first char 4655 4656 StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string 4657 StrCmp "$R0" "\" loop end ; If this isn't a relative path goto end 4658 4659 loop: 4660 ${GetParent} "$R1" $R1 ; Get the parent directory for the path 4661 StrCmp "$R1" "$INSTDIR" end +1 ; If the directory is the install dir goto end 4662 4663 IfFileExists "$R1" +1 loop ; Only try to remove the dir if it exists 4664 ClearErrors 4665 RmDir "$R1" ; Remove the dir 4666 IfErrors end +1 ; If we fail there is no use trying to remove its parent dir 4667 ${LogMsg} "Deleted Directory: $R1" 4668 GoTo loop 4669 4670 end: 4671 ClearErrors 4672 4673 Push 0 4674 FunctionEnd 4675 4676 !verbose pop 4677 !endif 4678!macroend 4679 4680!macro OnInstallUninstallCall 4681 !verbose push 4682 !verbose ${_MOZFUNC_VERBOSE} 4683 Call OnInstallUninstall 4684 !verbose pop 4685!macroend 4686 4687/** 4688 * Parses the precomplete file to remove an installation's files and 4689 * directories. 4690 * 4691 * @param _CALLBACK 4692 * The function address of a callback function for progress or "false" 4693 * if there is no callback function. 4694 * 4695 * $R3 = false if all files were deleted or moved to the tobedeleted directory. 4696 * true if file(s) could not be moved to the tobedeleted directory. 4697 * $R4 = Path to temporary precomplete file. 4698 * $R5 = File handle for the temporary precomplete file. 4699 * $R6 = String returned from FileRead. 4700 * $R7 = First seven characters of the string returned from FileRead. 4701 * $R8 = Temporary file path used to rename files that are in use. 4702 * $R9 = _CALLBACK 4703 */ 4704!macro RemovePrecompleteEntries 4705 4706 !ifndef ${_MOZFUNC_UN}RemovePrecompleteEntries 4707 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 4708 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 4709 !insertmacro ${_MOZFUNC_UN_TMP}TrimNewLines 4710 !insertmacro ${_MOZFUNC_UN_TMP}WordReplace 4711 !undef _MOZFUNC_UN 4712 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 4713 !undef _MOZFUNC_UN_TMP 4714 4715 !verbose push 4716 !verbose ${_MOZFUNC_VERBOSE} 4717 !define ${_MOZFUNC_UN}RemovePrecompleteEntries "!insertmacro ${_MOZFUNC_UN}RemovePrecompleteEntriesCall" 4718 4719 Function ${_MOZFUNC_UN}RemovePrecompleteEntries 4720 Exch $R9 4721 Push $R8 4722 Push $R7 4723 Push $R6 4724 Push $R5 4725 Push $R4 4726 Push $R3 4727 4728 ${If} ${FileExists} "$INSTDIR\precomplete" 4729 StrCpy $R3 "false" 4730 4731 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 4732 CreateDirectory "$INSTDIR\${TO_BE_DELETED}" 4733 GetTempFileName $R4 "$INSTDIR\${TO_BE_DELETED}" 4734 Delete "$R4" 4735 Rename "$INSTDIR\precomplete" "$R4" 4736 4737 ClearErrors 4738 ; Rename and then remove files 4739 FileOpen $R5 "$R4" r 4740 ${Do} 4741 FileRead $R5 $R6 4742 ${If} ${Errors} 4743 ${Break} 4744 ${EndIf} 4745 4746 ${${_MOZFUNC_UN}TrimNewLines} "$R6" $R6 4747 ; Replace all occurrences of "/" with "\". 4748 ${${_MOZFUNC_UN}WordReplace} "$R6" "/" "\" "+" $R6 4749 4750 ; Copy the first 7 chars 4751 StrCpy $R7 "$R6" 7 4752 ${If} "$R7" == "remove " 4753 ; Copy the string starting after the 8th char 4754 StrCpy $R6 "$R6" "" 8 4755 ; Copy all but the last char to remove the double quote. 4756 StrCpy $R6 "$R6" -1 4757 ${If} ${FileExists} "$INSTDIR\$R6" 4758 ${Unless} "$R9" == "false" 4759 Call $R9 4760 ${EndUnless} 4761 4762 ClearErrors 4763 Delete "$INSTDIR\$R6" 4764 ${If} ${Errors} 4765 GetTempFileName $R8 "$INSTDIR\${TO_BE_DELETED}" 4766 Delete "$R8" 4767 ClearErrors 4768 Rename "$INSTDIR\$R6" "$R8" 4769 ${Unless} ${Errors} 4770 Delete /REBOOTOK "$R8" 4771 4772 ClearErrors 4773 ${EndUnless} 4774!ifdef __UNINSTALL__ 4775 ${If} ${Errors} 4776 Delete /REBOOTOK "$INSTDIR\$R6" 4777 StrCpy $R3 "true" 4778 ClearErrors 4779 ${EndIf} 4780!endif 4781 ${EndIf} 4782 ${EndIf} 4783 ${ElseIf} "$R7" == "rmdir $\"" 4784 ; Copy the string starting after the 7th char. 4785 StrCpy $R6 "$R6" "" 7 4786 ; Copy all but the last two chars to remove the slash and the double quote. 4787 StrCpy $R6 "$R6" -2 4788 ${If} ${FileExists} "$INSTDIR\$R6" 4789 ; Ignore directory removal errors 4790 RmDir "$INSTDIR\$R6" 4791 ClearErrors 4792 ${EndIf} 4793 ${EndIf} 4794 ${Loop} 4795 FileClose $R5 4796 4797 ; Delete the temporary precomplete file 4798 Delete /REBOOTOK "$R4" 4799 4800 RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}" 4801 4802 ${If} ${RebootFlag} 4803 ${AndIf} "$R3" == "false" 4804 ; Clear the reboot flag if all files were deleted or moved to the 4805 ; tobedeleted directory. 4806 SetRebootFlag false 4807 ${EndIf} 4808 ${EndIf} 4809 4810 ClearErrors 4811 4812 Pop $R3 4813 Pop $R4 4814 Pop $R5 4815 Pop $R6 4816 Pop $R7 4817 Pop $R8 4818 Exch $R9 4819 FunctionEnd 4820 4821 !verbose pop 4822 !endif 4823!macroend 4824 4825!macro RemovePrecompleteEntriesCall _CALLBACK 4826 !verbose push 4827 Push "${_CALLBACK}" 4828 !verbose ${_MOZFUNC_VERBOSE} 4829 Call RemovePrecompleteEntries 4830 !verbose pop 4831!macroend 4832 4833!macro un.RemovePrecompleteEntriesCall _CALLBACK 4834 !verbose push 4835 !verbose ${_MOZFUNC_VERBOSE} 4836 Push "${_CALLBACK}" 4837 Call un.RemovePrecompleteEntries 4838 !verbose pop 4839!macroend 4840 4841!macro un.RemovePrecompleteEntries 4842 !ifndef un.RemovePrecompleteEntries 4843 !verbose push 4844 !verbose ${_MOZFUNC_VERBOSE} 4845 !undef _MOZFUNC_UN 4846 !define _MOZFUNC_UN "un." 4847 4848 !insertmacro RemovePrecompleteEntries 4849 4850 !undef _MOZFUNC_UN 4851 !define _MOZFUNC_UN 4852 !verbose pop 4853 !endif 4854!macroend 4855 4856/** 4857 * Parses the uninstall.log to unregister dll's, remove files, and remove 4858 * empty directories for this installation. 4859 * 4860 * When modifying this macro be aware that LineFind uses all registers except 4861 * $R0-$R3 so be cautious. Callers of this macro are not affected. 4862 */ 4863!macro un.ParseUninstallLog 4864 4865 !ifndef un.ParseUninstallLog 4866 !insertmacro un.GetParent 4867 !insertmacro un.LineFind 4868 !insertmacro un.TrimNewLines 4869 4870 !verbose push 4871 !verbose ${_MOZFUNC_VERBOSE} 4872 !define un.ParseUninstallLog "!insertmacro un.ParseUninstallLogCall" 4873 4874 Function un.ParseUninstallLog 4875 Push $R9 4876 Push $R8 4877 Push $R7 4878 Push $R6 4879 Push $R5 4880 Push $R4 4881 Push $R3 4882 Push $R2 4883 Push $R1 4884 Push $R0 4885 Push $TmpVal 4886 4887 IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end 4888 4889 ; Copy the uninstall log file to a temporary file 4890 GetTempFileName $TmpVal 4891 CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" 4892 4893 ; Unregister DLL's 4894 ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.UnRegDLLsCallback" 4895 4896 ; Delete files 4897 ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveFilesCallback" 4898 4899 ; Remove empty directories 4900 ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveDirsCallback" 4901 4902 ; Delete the temporary uninstall log file 4903 Delete /REBOOTOK "$TmpVal" 4904 4905 end: 4906 4907 Pop $TmpVal 4908 Pop $R0 4909 Pop $R1 4910 Pop $R2 4911 Pop $R3 4912 Pop $R4 4913 Pop $R5 4914 Pop $R6 4915 Pop $R7 4916 Pop $R8 4917 Pop $R9 4918 FunctionEnd 4919 4920 Function un.RemoveFilesCallback 4921 ${un.TrimNewLines} "$R9" $R9 4922 StrCpy $R1 "$R9" 5 4923 4924 StrCmp "$R1" "File:" +1 end 4925 StrCpy $R9 "$R9" "" 6 4926 StrCpy $R0 "$R9" 1 4927 4928 StrCpy $R1 "$INSTDIR$R9" 4929 StrCmp "$R0" "\" +2 +1 4930 StrCpy $R1 "$R9" 4931 4932 IfFileExists "$R1" +1 end 4933 Delete "$R1" 4934 IfErrors +1 end 4935 ClearErrors 4936 Rename "$R1" "$R1.moz-delete" 4937 IfErrors +1 +3 4938 Delete /REBOOTOK "$R1" 4939 GoTo end 4940 4941 Delete /REBOOTOK "$R1.moz-delete" 4942 4943 end: 4944 ClearErrors 4945 4946 Push 0 4947 FunctionEnd 4948 4949 Function un.UnRegDLLsCallback 4950 ${un.TrimNewLines} "$R9" $R9 4951 StrCpy $R1 "$R9" 7 4952 4953 StrCmp $R1 "DLLReg:" +1 end 4954 StrCpy $R9 "$R9" "" 8 4955 StrCpy $R0 "$R9" 1 4956 4957 StrCpy $R1 "$INSTDIR$R9" 4958 StrCmp $R0 "\" +2 +1 4959 StrCpy $R1 "$R9" 4960 4961 ${UnregisterDLL} $R1 4962 4963 end: 4964 ClearErrors 4965 4966 Push 0 4967 FunctionEnd 4968 4969 ; Using locate will leave file handles open to some of the directories 4970 ; which will prevent the deletion of these directories. This parses the 4971 ; uninstall.log and uses the file entries to find / remove empty 4972 ; directories. 4973 Function un.RemoveDirsCallback 4974 ${un.TrimNewLines} "$R9" $R9 4975 StrCpy $R0 "$R9" 5 ; Copy the first five chars 4976 StrCmp "$R0" "File:" +1 end 4977 4978 StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char 4979 StrCpy $R0 "$R9" 1 ; Copy the first char 4980 4981 StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string 4982 StrCmp "$R0" "\" loop ; If this is a relative path goto the loop 4983 StrCpy $R1 "$R9" ; Already a full path so copy the string 4984 4985 loop: 4986 ${un.GetParent} "$R1" $R1 ; Get the parent directory for the path 4987 StrCmp "$R1" "$INSTDIR" end ; If the directory is the install dir goto end 4988 4989 ; We only try to remove empty directories but the Desktop, StartMenu, and 4990 ; QuickLaunch directories can be empty so guard against removing them. 4991 SetShellVarContext all ; Set context to all users 4992 StrCmp "$R1" "$DESKTOP" end ; All users desktop 4993 StrCmp "$R1" "$STARTMENU" end ; All users start menu 4994 4995 SetShellVarContext current ; Set context to all users 4996 StrCmp "$R1" "$DESKTOP" end ; Current user desktop 4997 StrCmp "$R1" "$STARTMENU" end ; Current user start menu 4998 StrCmp "$R1" "$QUICKLAUNCH" end ; Current user quick launch 4999 5000 IfFileExists "$R1" +1 +3 ; Only try to remove the dir if it exists 5001 ClearErrors 5002 RmDir "$R1" ; Remove the dir 5003 IfErrors end ; If we fail there is no use trying to remove its parent dir 5004 5005 StrCmp "$R0" "\" loop end ; Only loop when the path is relative to the install dir 5006 5007 end: 5008 ClearErrors 5009 5010 Push 0 5011 FunctionEnd 5012 5013 !verbose pop 5014 !endif 5015!macroend 5016 5017!macro un.ParseUninstallLogCall 5018 !verbose push 5019 !verbose ${_MOZFUNC_VERBOSE} 5020 Call un.ParseUninstallLog 5021 !verbose pop 5022!macroend 5023 5024/** 5025 * Finds a valid Start Menu shortcut in the uninstall log and returns the 5026 * relative path from the Start Menu's Programs directory to the shortcut's 5027 * directory. 5028 * 5029 * When modifying this macro be aware that LineFind uses all registers except 5030 * $R0-$R3 so be cautious. Callers of this macro are not affected. 5031 * 5032 * @return _REL_PATH_TO_DIR 5033 * The relative path to the application's Start Menu directory from the 5034 * Start Menu's Programs directory. 5035 */ 5036!macro FindSMProgramsDir 5037 5038 !ifndef FindSMProgramsDir 5039 !insertmacro GetParent 5040 !insertmacro LineFind 5041 !insertmacro TrimNewLines 5042 5043 !verbose push 5044 !verbose ${_MOZFUNC_VERBOSE} 5045 !define FindSMProgramsDir "!insertmacro FindSMProgramsDirCall" 5046 5047 Function FindSMProgramsDir 5048 Exch $R3 5049 Push $R2 5050 Push $R1 5051 Push $R0 5052 5053 StrCpy $R3 "" 5054 ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log" 5055 ${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath" 5056 ${EndIf} 5057 ClearErrors 5058 5059 Pop $R0 5060 Pop $R1 5061 Pop $R2 5062 Exch $R3 5063 FunctionEnd 5064 5065 ; This callback MUST use labels vs. relative line numbers. 5066 Function FindSMProgramsDirRelPath 5067 Push 0 5068 ${TrimNewLines} "$R9" $R9 5069 StrCpy $R4 "$R9" 5 5070 5071 StrCmp "$R4" "File:" +1 end_FindSMProgramsDirRelPath 5072 StrCpy $R9 "$R9" "" 6 5073 StrCpy $R4 "$R9" 1 5074 5075 StrCmp "$R4" "\" end_FindSMProgramsDirRelPath +1 5076 5077 SetShellVarContext all 5078 ${GetLongPath} "$SMPROGRAMS" $R4 5079 StrLen $R2 "$R4" 5080 StrCpy $R1 "$R9" $R2 5081 StrCmp "$R1" "$R4" +1 end_FindSMProgramsDirRelPath 5082 IfFileExists "$R9" +1 end_FindSMProgramsDirRelPath 5083 ShellLink::GetShortCutTarget "$R9" 5084 Pop $R0 5085 StrCmp "$INSTDIR\${FileMainEXE}" "$R0" +1 end_FindSMProgramsDirRelPath 5086 ${GetParent} "$R9" $R3 5087 IntOp $R2 $R2 + 1 5088 StrCpy $R3 "$R3" "" $R2 5089 5090 Pop $R4 ; Remove the previously pushed 0 from the stack and 5091 push "StopLineFind" ; push StopLineFind to stop finding more lines. 5092 5093 end_FindSMProgramsDirRelPath: 5094 ClearErrors 5095 5096 FunctionEnd 5097 5098 !verbose pop 5099 !endif 5100!macroend 5101 5102!macro FindSMProgramsDirCall _REL_PATH_TO_DIR 5103 !verbose push 5104 !verbose ${_MOZFUNC_VERBOSE} 5105 Call FindSMProgramsDir 5106 Pop ${_REL_PATH_TO_DIR} 5107 !verbose pop 5108!macroend 5109 5110 5111################################################################################ 5112# Macros for custom branding 5113 5114/** 5115 * Sets BrandFullName and / or BrandShortName to values provided in the specified 5116 * ini file and defaults to BrandShortName and BrandFullName as defined in 5117 * branding.nsi when the associated ini file entry is not specified. 5118 * 5119 * ini file format: 5120 * [Branding] 5121 * BrandFullName=Custom Full Name 5122 * BrandShortName=Custom Short Name 5123 * 5124 * @param _PATH_TO_INI 5125 * Path to the ini file. 5126 * 5127 * $R6 = return value from ReadINIStr 5128 * $R7 = stores BrandShortName 5129 * $R8 = stores BrandFullName 5130 * $R9 = _PATH_TO_INI 5131 */ 5132!macro SetBrandNameVars 5133 5134 !ifndef ${_MOZFUNC_UN}SetBrandNameVars 5135 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 5136 !insertmacro ${_MOZFUNC_UN_TMP}WordReplace 5137 !undef _MOZFUNC_UN 5138 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 5139 !undef _MOZFUNC_UN_TMP 5140 5141 ; Prevent declaring vars twice when the SetBrandNameVars macro is 5142 ; inserted into both the installer and uninstaller. 5143 !ifndef SetBrandNameVars 5144 Var BrandFullName 5145 Var BrandFullNameDA 5146 Var BrandShortName 5147 Var BrandProductName 5148 !endif 5149 5150 !verbose push 5151 !verbose ${_MOZFUNC_VERBOSE} 5152 !define ${_MOZFUNC_UN}SetBrandNameVars "!insertmacro ${_MOZFUNC_UN}SetBrandNameVarsCall" 5153 5154 Function ${_MOZFUNC_UN}SetBrandNameVars 5155 Exch $R9 5156 Push $R8 5157 Push $R7 5158 Push $R6 5159 Push $R5 5160 5161 StrCpy $R8 "${BrandFullName}" 5162 StrCpy $R7 "${BrandShortName}" 5163 StrCpy $R6 "${BrandProductName}" 5164 5165 IfFileExists "$R9" +1 finish 5166 5167 ClearErrors 5168 ReadINIStr $R5 $R9 "Branding" "BrandFullName" 5169 IfErrors +2 +1 5170 StrCpy $R8 "$R5" 5171 5172 ClearErrors 5173 ReadINIStr $R5 $R9 "Branding" "BrandShortName" 5174 IfErrors +2 +1 5175 StrCpy $R7 "$R5" 5176 5177 ClearErrors 5178 ReadINIStr $R5 $R9 "Branding" "BrandProductName" 5179 IfErrors +2 +1 5180 StrCpy $R6 "$R5" 5181 5182 finish: 5183 StrCpy $BrandFullName "$R8" 5184 ${${_MOZFUNC_UN}WordReplace} "$R8" "&" "&&" "+" $R8 5185 StrCpy $BrandFullNameDA "$R8" 5186 StrCpy $BrandShortName "$R7" 5187 StrCpy $BrandProductName "$R6" 5188 5189 Pop $R5 5190 Pop $R6 5191 Pop $R7 5192 Pop $R8 5193 Exch $R9 5194 FunctionEnd 5195 5196 !verbose pop 5197 !endif 5198!macroend 5199 5200!macro SetBrandNameVarsCall _PATH_TO_INI 5201 !verbose push 5202 !verbose ${_MOZFUNC_VERBOSE} 5203 Push "${_PATH_TO_INI}" 5204 Call SetBrandNameVars 5205 !verbose pop 5206!macroend 5207 5208!macro un.SetBrandNameVarsCall _PATH_TO_INI 5209 !verbose push 5210 !verbose ${_MOZFUNC_VERBOSE} 5211 Push "${_PATH_TO_INI}" 5212 Call un.SetBrandNameVars 5213 !verbose pop 5214!macroend 5215 5216!macro un.SetBrandNameVars 5217 !ifndef un.SetBrandNameVars 5218 !verbose push 5219 !verbose ${_MOZFUNC_VERBOSE} 5220 !undef _MOZFUNC_UN 5221 !define _MOZFUNC_UN "un." 5222 5223 !insertmacro SetBrandNameVars 5224 5225 !undef _MOZFUNC_UN 5226 !define _MOZFUNC_UN 5227 !verbose pop 5228 !endif 5229!macroend 5230 5231/** 5232 * Replaces the wizard's header image with the one specified. 5233 * 5234 * @param _PATH_TO_IMAGE 5235 * Fully qualified path to the bitmap to use for the header image. 5236 * 5237 * $R8 = hwnd for the control returned from GetDlgItem. 5238 * $R9 = _PATH_TO_IMAGE 5239 */ 5240!macro ChangeMUIHeaderImage 5241 5242 !ifndef ${_MOZFUNC_UN}ChangeMUIHeaderImage 5243 Var hHeaderBitmap 5244 5245 !verbose push 5246 !verbose ${_MOZFUNC_VERBOSE} 5247 !define ${_MOZFUNC_UN}ChangeMUIHeaderImage "!insertmacro ${_MOZFUNC_UN}ChangeMUIHeaderImageCall" 5248 5249 Function ${_MOZFUNC_UN}ChangeMUIHeaderImage 5250 Exch $R9 5251 Push $R8 5252 5253 GetDlgItem $R8 $HWNDPARENT 1046 5254 ${SetStretchedImageOLE} $R8 "$R9" $hHeaderBitmap 5255 ; There is no way to specify a show function for a custom page so hide 5256 ; and then show the control to force the bitmap to redraw. 5257 ShowWindow $R8 ${SW_HIDE} 5258 ShowWindow $R8 ${SW_SHOW} 5259 5260 Pop $R8 5261 Exch $R9 5262 FunctionEnd 5263 5264 !verbose pop 5265 !endif 5266!macroend 5267 5268!macro ChangeMUIHeaderImageCall _PATH_TO_IMAGE 5269 !verbose push 5270 !verbose ${_MOZFUNC_VERBOSE} 5271 Push "${_PATH_TO_IMAGE}" 5272 Call ChangeMUIHeaderImage 5273 !verbose pop 5274!macroend 5275 5276!macro un.ChangeMUIHeaderImageCall _PATH_TO_IMAGE 5277 !verbose push 5278 !verbose ${_MOZFUNC_VERBOSE} 5279 Push "${_PATH_TO_IMAGE}" 5280 Call un.ChangeMUIHeaderImage 5281 !verbose pop 5282!macroend 5283 5284!macro un.ChangeMUIHeaderImage 5285 !ifndef un.ChangeMUIHeaderImage 5286 !verbose push 5287 !verbose ${_MOZFUNC_VERBOSE} 5288 !undef _MOZFUNC_UN 5289 !define _MOZFUNC_UN "un." 5290 5291 !insertmacro ChangeMUIHeaderImage 5292 5293 !undef _MOZFUNC_UN 5294 !define _MOZFUNC_UN 5295 !verbose pop 5296 !endif 5297!macroend 5298 5299/** 5300 * Replaces the sidebar image on the wizard's welcome and finish pages. 5301 * 5302 * @param _PATH_TO_IMAGE 5303 * Fully qualified path to the bitmap to use for the header image. 5304 * 5305 * $R8 = hwnd for the bitmap control 5306 * $R9 = _PATH_TO_IMAGE 5307 */ 5308!macro ChangeMUISidebarImage 5309 5310 !ifndef ${_MOZFUNC_UN}ChangeMUISidebarImage 5311 Var hSidebarBitmap 5312 5313 !verbose push 5314 !verbose ${_MOZFUNC_VERBOSE} 5315 !define ${_MOZFUNC_UN}ChangeMUISidebarImage "!insertmacro ${_MOZFUNC_UN}ChangeMUISidebarImageCall" 5316 5317 Function ${_MOZFUNC_UN}ChangeMUISidebarImage 5318 Exch $R9 5319 Push $R8 5320 5321 ; Make sure we're not about to leak an existing handle. 5322 ${If} $hSidebarBitmap <> 0 5323 System::Call "gdi32::DeleteObject(p $hSidebarBitmap)" 5324 StrCpy $hSidebarBitmap 0 5325 ${EndIf} 5326 ; The controls on the welcome and finish pages aren't in the dialog 5327 ; template, they're always created manually from the INI file, so we need 5328 ; to query it to find the right HWND. 5329 ReadINIStr $R8 "$PLUGINSDIR\ioSpecial.ini" "Field 1" "HWND" 5330 ${SetStretchedImageOLE} $R8 "$R9" $hSidebarBitmap 5331 5332 Pop $R8 5333 Exch $R9 5334 FunctionEnd 5335 5336 !verbose pop 5337 !endif 5338!macroend 5339 5340!macro ChangeMUISidebarImageCall _PATH_TO_IMAGE 5341 !verbose push 5342 !verbose ${_MOZFUNC_VERBOSE} 5343 Push "${_PATH_TO_IMAGE}" 5344 Call ChangeMUISidebarImage 5345 !verbose pop 5346!macroend 5347 5348!macro un.ChangeMUISidebarImageCall _PATH_TO_IMAGE 5349 !verbose push 5350 !verbose ${_MOZFUNC_VERBOSE} 5351 Push "${_PATH_TO_IMAGE}" 5352 Call un.ChangeMUISidebarImage 5353 !verbose pop 5354!macroend 5355 5356!macro un.ChangeMUISidebarImage 5357 !ifndef un.ChangeMUISidebarImage 5358 !verbose push 5359 !verbose ${_MOZFUNC_VERBOSE} 5360 !undef _MOZFUNC_UN 5361 !define _MOZFUNC_UN "un." 5362 5363 !insertmacro ChangeMUISidebarImage 5364 5365 !undef _MOZFUNC_UN 5366 !define _MOZFUNC_UN 5367 !verbose pop 5368 !endif 5369!macroend 5370 5371################################################################################ 5372# User interface callback helper defines and macros 5373 5374/* Install type defines */ 5375!ifndef INSTALLTYPE_BASIC 5376 !define INSTALLTYPE_BASIC 1 5377!endif 5378 5379!ifndef INSTALLTYPE_CUSTOM 5380 !define INSTALLTYPE_CUSTOM 2 5381!endif 5382 5383/** 5384 * Checks whether to display the current page (e.g. if not performing a custom 5385 * install don't display the custom pages). 5386 */ 5387!macro CheckCustomCommon 5388 5389 !ifndef CheckCustomCommon 5390 !verbose push 5391 !verbose ${_MOZFUNC_VERBOSE} 5392 !define CheckCustomCommon "!insertmacro CheckCustomCommonCall" 5393 5394 Function CheckCustomCommon 5395 5396 ; Abort if not a custom install 5397 IntCmp $InstallType ${INSTALLTYPE_CUSTOM} +2 +1 +1 5398 Abort 5399 5400 FunctionEnd 5401 5402 !verbose pop 5403 !endif 5404!macroend 5405 5406!macro CheckCustomCommonCall 5407 !verbose push 5408 !verbose ${_MOZFUNC_VERBOSE} 5409 Call CheckCustomCommon 5410 !verbose pop 5411!macroend 5412 5413/** 5414 * Unloads dll's and releases references when the installer and uninstaller 5415 * exit. 5416 */ 5417!macro OnEndCommon 5418 5419 !ifndef ${_MOZFUNC_UN}OnEndCommon 5420 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 5421 !insertmacro ${_MOZFUNC_UN_TMP}UnloadUAC 5422 !undef _MOZFUNC_UN 5423 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 5424 !undef _MOZFUNC_UN_TMP 5425 5426 !verbose push 5427 !verbose ${_MOZFUNC_VERBOSE} 5428 !define ${_MOZFUNC_UN}OnEndCommon "!insertmacro ${_MOZFUNC_UN}OnEndCommonCall" 5429 5430 Function ${_MOZFUNC_UN}OnEndCommon 5431 5432 ${${_MOZFUNC_UN}UnloadUAC} 5433 StrCmp $hHeaderBitmap "" +3 +1 5434 System::Call "gdi32::DeleteObject(i s)" $hHeaderBitmap 5435 StrCpy $hHeaderBitmap "" 5436 ; If ChangeMUISidebarImage was called, then we also need to clean up the 5437 ; GDI bitmap handle that it would have created. 5438 !ifdef ${_MOZFUNC_UN}ChangeMUISidebarImage 5439 StrCmp $hSidebarBitmap "" +3 +1 5440 System::Call "gdi32::DeleteObject(i s)" $hSidebarBitmap 5441 StrCpy $hSidebarBitmap "" 5442 !endif 5443 5444 System::Free 0 5445 5446 FunctionEnd 5447 5448 !verbose pop 5449 !endif 5450!macroend 5451 5452!macro OnEndCommonCall 5453 !verbose push 5454 !verbose ${_MOZFUNC_VERBOSE} 5455 Call OnEndCommon 5456 !verbose pop 5457!macroend 5458 5459!macro un.OnEndCommonCall 5460 !verbose push 5461 !verbose ${_MOZFUNC_VERBOSE} 5462 Call un.OnEndCommon 5463 !verbose pop 5464!macroend 5465 5466!macro un.OnEndCommon 5467 !ifndef un.OnEndCommon 5468 !verbose push 5469 !verbose ${_MOZFUNC_VERBOSE} 5470 !undef _MOZFUNC_UN 5471 !define _MOZFUNC_UN "un." 5472 5473 !insertmacro OnEndCommon 5474 5475 !undef _MOZFUNC_UN 5476 !define _MOZFUNC_UN 5477 !verbose pop 5478 !endif 5479!macroend 5480 5481/** 5482 * Reads a flag option from the command line and sets a variable with its state, 5483 * if the option is present on the command line. 5484 * 5485 * @param FULL_COMMAND_LINE 5486 * The entire installer command line, such as from ${GetParameters} 5487 * @param OPTION 5488 * Name of the option to look for 5489 * @param OUTPUT 5490 * Variable/register to write the output to. Will be set to "0" if the 5491 * option was present with the value "false", will be set to "1" if the 5492 * option was present with another value, and will be untouched if the 5493 * option was not on the command line at all. 5494 */ 5495!macro InstallGetOption FULL_COMMAND_LINE OPTION OUTPUT 5496 Push $0 5497 ClearErrors 5498 ${GetOptions} ${FULL_COMMAND_LINE} "/${OPTION}" $0 5499 ${IfNot} ${Errors} 5500 ; Any valid command-line option triggers a silent installation. 5501 SetSilent silent 5502 5503 ${If} $0 == "=false" 5504 StrCpy ${OUTPUT} "0" 5505 ${Else} 5506 StrCpy ${OUTPUT} "1" 5507 ${EndIf} 5508 ${EndIf} 5509 Pop $0 5510!macroend 5511!define InstallGetOption "!insertmacro InstallGetOption" 5512 5513/** 5514 * Called from the installer's .onInit function not to be confused with the 5515 * uninstaller's .onInit or the uninstaller's un.onInit functions. 5516 * 5517 * @param _WARN_UNSUPPORTED_MSG 5518 * Message displayed when the Windows version is not supported. 5519 * 5520 * $R4 = keeps track of whether a custom install path was specified on either 5521 * the command line or in an INI file 5522 * $R5 = return value from the GetSize macro 5523 * $R6 = general string values, return value from GetTempFileName, return 5524 * value from the GetSize macro 5525 * $R7 = full path to the configuration ini file 5526 * $R8 = used for OS Version and Service Pack detection and the return value 5527 * from the GetParameters macro 5528 * $R9 = _WARN_UNSUPPORTED_MSG 5529 */ 5530!macro InstallOnInitCommon 5531 5532 !ifndef InstallOnInitCommon 5533 !insertmacro ElevateUAC 5534 !insertmacro GetOptions 5535 !insertmacro GetParameters 5536 !insertmacro GetSize 5537 5538 !verbose push 5539 !verbose ${_MOZFUNC_VERBOSE} 5540 !define InstallOnInitCommon "!insertmacro InstallOnInitCommonCall" 5541 5542 Function InstallOnInitCommon 5543 Exch $R9 5544 Push $R8 5545 Push $R7 5546 Push $R6 5547 Push $R5 5548 Push $R4 5549 5550 ; Don't install on systems that don't support SSE2. The parameter value of 5551 ; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the 5552 ; SSE2 instruction set is available. 5553 System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R8" 5554 ${If} "$R8" == "0" 5555 MessageBox MB_OK|MB_ICONSTOP "$R9" 5556 ; Nothing initialized so no need to call OnEndCommon 5557 Quit 5558 ${EndIf} 5559 5560 ; Windows NT 6.0 (Vista/Server 2008) and lower are not supported. 5561 ${Unless} ${AtLeastWin7} 5562 MessageBox MB_OK|MB_ICONSTOP "$R9" 5563 ; Nothing initialized so no need to call OnEndCommon 5564 Quit 5565 ${EndUnless} 5566 5567 !ifdef HAVE_64BIT_BUILD 5568 SetRegView 64 5569 !endif 5570 5571 StrCpy $R4 0 ; will be set to 1 if a custom install path is set 5572 5573 ${GetParameters} $R8 5574 ${If} $R8 != "" 5575 ; Default install type 5576 StrCpy $InstallType ${INSTALLTYPE_BASIC} 5577 5578 ${Unless} ${Silent} 5579 ; NSIS should check for /S for us, but we've had issues with it such 5580 ; as bug 506867 in the past, so we'll check for it ourselves also. 5581 ClearErrors 5582 ${GetOptions} "$R8" "/S" $R7 5583 ${Unless} ${Errors} 5584 SetSilent silent 5585 ${Else} 5586 ; NSIS dropped support for the deprecated -ms argument, but we don't 5587 ; want to break backcompat, so we'll check for it here too. 5588 ClearErrors 5589 ${GetOptions} "$R8" "-ms" $R7 5590 ${Unless} ${Errors} 5591 SetSilent silent 5592 ${EndUnless} 5593 ${EndUnless} 5594 ${EndUnless} 5595 5596 ; Support for specifying an installation configuration file. 5597 ClearErrors 5598 ${GetOptions} "$R8" "/INI=" $R7 5599 ${Unless} ${Errors} 5600 ; The configuration file must also exist 5601 ${If} ${FileExists} "$R7" 5602 ; Any valid command-line option triggers a silent installation. 5603 SetSilent silent 5604 5605 ReadINIStr $R8 $R7 "Install" "InstallDirectoryName" 5606 ${If} $R8 != "" 5607 StrCpy $R4 1 5608 !ifdef HAVE_64BIT_BUILD 5609 StrCpy $INSTDIR "$PROGRAMFILES64\$R8" 5610 !else 5611 StrCpy $INSTDIR "$PROGRAMFILES32\$R8" 5612 !endif 5613 ${Else} 5614 ReadINIStr $R8 $R7 "Install" "InstallDirectoryPath" 5615 ${If} $R8 != "" 5616 StrCpy $R4 1 5617 StrCpy $INSTDIR "$R8" 5618 ${EndIf} 5619 ${EndIf} 5620 5621 ReadINIStr $R8 $R7 "Install" "QuickLaunchShortcut" 5622 ${If} $R8 == "false" 5623 StrCpy $AddQuickLaunchSC "0" 5624 ${Else} 5625 StrCpy $AddQuickLaunchSC "1" 5626 ${EndIf} 5627 5628 ReadINIStr $R8 $R7 "Install" "DesktopShortcut" 5629 ${If} $R8 == "false" 5630 StrCpy $AddDesktopSC "0" 5631 ${Else} 5632 StrCpy $AddDesktopSC "1" 5633 ${EndIf} 5634 5635 ReadINIStr $R8 $R7 "Install" "StartMenuShortcuts" 5636 ${If} $R8 == "false" 5637 StrCpy $AddStartMenuSC "0" 5638 ${Else} 5639 StrCpy $AddStartMenuSC "1" 5640 ${EndIf} 5641 5642 ; We still accept the plural version for backwards compatibility, 5643 ; but the singular version takes priority. 5644 ClearErrors 5645 ReadINIStr $R8 $R7 "Install" "StartMenuShortcut" 5646 ${If} $R8 == "false" 5647 StrCpy $AddStartMenuSC "0" 5648 ${ElseIfNot} ${Errors} 5649 StrCpy $AddStartMenuSC "1" 5650 ${EndIf} 5651 5652 ReadINIStr $R8 $R7 "Install" "TaskbarShortcut" 5653 ${If} $R8 == "false" 5654 StrCpy $AddTaskbarSC "0" 5655 ${Else} 5656 StrCpy $AddTaskbarSC "1" 5657 ${EndIf} 5658 5659 ReadINIStr $R8 $R7 "Install" "MaintenanceService" 5660 ${If} $R8 == "false" 5661 StrCpy $InstallMaintenanceService "0" 5662 ${Else} 5663 StrCpy $InstallMaintenanceService "1" 5664 ${EndIf} 5665 5666 ReadINIStr $R8 $R7 "Install" "RegisterDefaultAgent" 5667 ${If} $R8 == "false" 5668 StrCpy $RegisterDefaultAgent "0" 5669 ${Else} 5670 StrCpy $RegisterDefaultAgent "1" 5671 ${EndIf} 5672 5673 !ifdef MOZ_OPTIONAL_EXTENSIONS 5674 ReadINIStr $R8 $R7 "Install" "OptionalExtensions" 5675 ${If} $R8 == "false" 5676 StrCpy $InstallOptionalExtensions "0" 5677 ${Else} 5678 StrCpy $InstallOptionalExtensions "1" 5679 ${EndIf} 5680 !endif 5681 5682 !ifndef NO_STARTMENU_DIR 5683 ReadINIStr $R8 $R7 "Install" "StartMenuDirectoryName" 5684 ${If} $R8 != "" 5685 StrCpy $StartMenuDir "$R8" 5686 ${EndIf} 5687 !endif 5688 ${EndIf} 5689 ${EndUnless} 5690 5691 ; Check for individual command line parameters after evaluating the INI 5692 ; file, because these should override the INI entires. 5693 ${GetParameters} $R8 5694 ${GetOptions} $R8 "/InstallDirectoryName=" $R7 5695 ${If} $R7 != "" 5696 StrCpy $R4 1 5697 !ifdef HAVE_64BIT_BUILD 5698 StrCpy $INSTDIR "$PROGRAMFILES64\$R7" 5699 !else 5700 StrCpy $INSTDIR "$PROGRAMFILES32\$R7" 5701 !endif 5702 ${Else} 5703 ${GetOptions} $R8 "/InstallDirectoryPath=" $R7 5704 ${If} $R7 != "" 5705 StrCpy $R4 1 5706 StrCpy $INSTDIR "$R7" 5707 ${EndIf} 5708 ${EndIf} 5709 5710 ${InstallGetOption} $R8 "QuickLaunchShortcut" $AddQuickLaunchSC 5711 ${InstallGetOption} $R8 "DesktopShortcut" $AddDesktopSC 5712 ${InstallGetOption} $R8 "StartMenuShortcuts" $AddStartMenuSC 5713 ; We still accept the plural version for backwards compatibility, 5714 ; but the singular version takes priority. 5715 ${InstallGetOption} $R8 "StartMenuShortcut" $AddStartMenuSC 5716 ${InstallGetOption} $R8 "TaskbarShortcut" $AddTaskbarSC 5717 ${InstallGetOption} $R8 "MaintenanceService" $InstallMaintenanceService 5718 ${InstallGetOption} $R8 "RegisterDefaultAgent" $RegisterDefaultAgent 5719 !ifdef MOZ_OPTIONAL_EXTENSIONS 5720 ${InstallGetOption} $R8 "OptionalExtensions" $InstallOptionalExtensions 5721 !endif 5722 5723 ; Installing the service always requires elevated privileges. 5724 ${If} $InstallMaintenanceService == "1" 5725 ${ElevateUAC} 5726 ${EndIf} 5727 ${EndIf} 5728 5729 ${If} $R4 == 1 5730 ; Any valid command-line option triggers a silent installation. 5731 SetSilent silent 5732 5733 ; Quit if we are unable to create the installation directory or we are 5734 ; unable to write to a file in the installation directory. 5735 ClearErrors 5736 ${If} ${FileExists} "$INSTDIR" 5737 GetTempFileName $R6 "$INSTDIR" 5738 FileOpen $R5 "$R6" w 5739 FileWrite $R5 "Write Access Test" 5740 FileClose $R5 5741 Delete $R6 5742 ${If} ${Errors} 5743 ; Attempt to elevate and then try again. 5744 ${ElevateUAC} 5745 GetTempFileName $R6 "$INSTDIR" 5746 FileOpen $R5 "$R6" w 5747 FileWrite $R5 "Write Access Test" 5748 FileClose $R5 5749 Delete $R6 5750 ${If} ${Errors} 5751 ; Nothing initialized so no need to call OnEndCommon 5752 Quit 5753 ${EndIf} 5754 ${EndIf} 5755 ${Else} 5756 CreateDirectory "$INSTDIR" 5757 ${If} ${Errors} 5758 ; Attempt to elevate and then try again. 5759 ${ElevateUAC} 5760 CreateDirectory "$INSTDIR" 5761 ${If} ${Errors} 5762 ; Nothing initialized so no need to call OnEndCommon 5763 Quit 5764 ${EndIf} 5765 ${EndIf} 5766 ${EndIf} 5767 ${Else} 5768 ; If we weren't given a custom path parameter, then try to elevate now. 5769 ; We'll check the user's permission level later on to determine the 5770 ; default install path (which will be the real install path for /S). 5771 ; If an INI file is used, we try to elevate down that path when needed. 5772 ${ElevateUAC} 5773 ${EndIf} 5774 5775 Pop $R4 5776 Pop $R5 5777 Pop $R6 5778 Pop $R7 5779 Pop $R8 5780 Exch $R9 5781 FunctionEnd 5782 5783 !verbose pop 5784 !endif 5785!macroend 5786 5787!macro InstallOnInitCommonCall _WARN_UNSUPPORTED_MSG 5788 !verbose push 5789 !verbose ${_MOZFUNC_VERBOSE} 5790 Push "${_WARN_UNSUPPORTED_MSG}" 5791 Call InstallOnInitCommon 5792 !verbose pop 5793!macroend 5794 5795/** 5796 * Called from the uninstaller's .onInit function not to be confused with the 5797 * installer's .onInit or the uninstaller's un.onInit functions. 5798 */ 5799!macro UninstallOnInitCommon 5800 5801 !ifndef UninstallOnInitCommon 5802 !insertmacro ElevateUAC 5803 !insertmacro GetLongPath 5804 !insertmacro GetOptions 5805 !insertmacro GetParameters 5806 !insertmacro GetParent 5807 !insertmacro UnloadUAC 5808 !insertmacro UpdateShortcutAppModelIDs 5809 !insertmacro UpdateUninstallLog 5810 5811 !verbose push 5812 !verbose ${_MOZFUNC_VERBOSE} 5813 !define UninstallOnInitCommon "!insertmacro UninstallOnInitCommonCall" 5814 5815 Function UninstallOnInitCommon 5816 ; Prevents breaking apps that don't use SetBrandNameVars 5817 !ifdef SetBrandNameVars 5818 ${SetBrandNameVars} "$EXEDIR\distribution\setup.ini" 5819 !endif 5820 5821 ; Prevent launching the application when a reboot is required and this 5822 ; executable is the main application executable 5823 IfFileExists "$EXEDIR\${FileMainEXE}.moz-upgrade" +1 +4 5824 MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 5825 Reboot 5826 Quit ; Nothing initialized so no need to call OnEndCommon 5827 5828 ${GetParent} "$EXEDIR" $INSTDIR 5829 ${GetLongPath} "$INSTDIR" $INSTDIR 5830 IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1 5831 Quit ; Nothing initialized so no need to call OnEndCommon 5832 5833!ifmacrodef InitHashAppModelId 5834 ; setup the application model id registration value 5835 !ifdef AppName 5836 ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" 5837 !endif 5838!endif 5839 5840 ; Prevents breaking apps that don't use SetBrandNameVars 5841 !ifdef SetBrandNameVars 5842 ${SetBrandNameVars} "$INSTDIR\distribution\setup.ini" 5843 !endif 5844 5845 ; Application update uses a directory named tobedeleted in the $INSTDIR to 5846 ; delete files on OS reboot when they are in use. Try to delete this 5847 ; directory if it exists. 5848 ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" 5849 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 5850 ${EndIf} 5851 5852 ; Prevent all operations (e.g. set as default, postupdate, etc.) when a 5853 ; reboot is required and the executable launched is helper.exe 5854 IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4 5855 MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 5856 Reboot 5857 Quit ; Nothing initialized so no need to call OnEndCommon 5858 5859 !ifdef HAVE_64BIT_BUILD 5860 SetRegView 64 5861 !endif 5862 5863 ${GetParameters} $R0 5864 5865 ${Unless} ${Silent} 5866 ; Manually check for /S in the command line due to Bug 506867 5867 ClearErrors 5868 ${GetOptions} "$R0" "/S" $R2 5869 ${Unless} ${Errors} 5870 SetSilent silent 5871 ${Else} 5872 ; Support for the deprecated -ms command line argument. 5873 ClearErrors 5874 ${GetOptions} "$R0" "-ms" $R2 5875 ${Unless} ${Errors} 5876 SetSilent silent 5877 ${EndUnless} 5878 ${EndUnless} 5879 ${EndUnless} 5880 5881 StrCmp "$R0" "" continue +1 5882 5883 ; Require elevation if the user can elevate 5884 hideshortcuts: 5885 ClearErrors 5886 ${GetOptions} "$R0" "/HideShortcuts" $R2 5887 IfErrors showshortcuts +1 5888!ifndef NONADMIN_ELEVATE 5889 ${ElevateUAC} 5890!endif 5891 ${HideShortcuts} 5892 GoTo finish 5893 5894 ; Require elevation if the user can elevate 5895 showshortcuts: 5896 ClearErrors 5897 ${GetOptions} "$R0" "/ShowShortcuts" $R2 5898 IfErrors defaultappuser +1 5899!ifndef NONADMIN_ELEVATE 5900 ${ElevateUAC} 5901!endif 5902 ${ShowShortcuts} 5903 GoTo finish 5904 5905 ; Require elevation if the the StartMenuInternet registry keys require 5906 ; updating and the user can elevate 5907 defaultappuser: 5908 ClearErrors 5909 ${GetOptions} "$R0" "/SetAsDefaultAppUser" $R2 5910 IfErrors defaultappglobal +1 5911 ${SetAsDefaultAppUser} 5912 GoTo finish 5913 5914 ; Require elevation if the user can elevate 5915 defaultappglobal: 5916 ClearErrors 5917 ${GetOptions} "$R0" "/SetAsDefaultAppGlobal" $R2 5918 IfErrors postupdate +1 5919 ${ElevateUAC} 5920 ${SetAsDefaultAppGlobal} 5921 GoTo finish 5922 5923 ; Do not attempt to elevate. The application launching this executable is 5924 ; responsible for elevation if it is required. 5925 postupdate: 5926 ${WordReplace} "$R0" "$\"" "" "+" $R0 5927 ClearErrors 5928 ${GetOptions} "$R0" "/PostUpdate" $R2 5929 IfErrors continue +1 5930 ; If the uninstall.log does not exist don't perform post update 5931 ; operations. This prevents updating the registry for zip builds. 5932 IfFileExists "$EXEDIR\uninstall.log" +2 +1 5933 Quit ; Nothing initialized so no need to call OnEndCommon 5934 ${PostUpdate} 5935 ClearErrors 5936 ${GetOptions} "$R0" "/UninstallLog=" $R2 5937 IfErrors updateuninstalllog +1 5938 StrCmp "$R2" "" finish +1 5939 GetFullPathName $R3 "$R2" 5940 IfFileExists "$R3" +1 finish 5941 Delete "$INSTDIR\uninstall\*wizard*" 5942 Delete "$INSTDIR\uninstall\uninstall.log" 5943 CopyFiles /SILENT /FILESONLY "$R3" "$INSTDIR\uninstall\" 5944 ${GetParent} "$R3" $R4 5945 Delete "$R3" 5946 RmDir "$R4" 5947 GoTo finish 5948 5949 ; Do not attempt to elevate. The application launching this executable is 5950 ; responsible for elevation if it is required. 5951 updateuninstalllog: 5952 ${UpdateUninstallLog} 5953 5954 finish: 5955 ${UnloadUAC} 5956 ${RefreshShellIcons} 5957 Quit ; Nothing initialized so no need to call OnEndCommon 5958 5959 continue: 5960 5961 ; If the uninstall.log does not exist don't perform uninstall 5962 ; operations. This prevents running the uninstaller for zip builds. 5963 IfFileExists "$INSTDIR\uninstall\uninstall.log" +2 +1 5964 Quit ; Nothing initialized so no need to call OnEndCommon 5965 5966 ; When silent, try to avoid elevation if we have a chance to succeed. We 5967 ; can succeed when we can write to (hence delete from) the install 5968 ; directory and when we can clean up all registry entries. Now, the 5969 ; installer when elevated writes privileged registry entries for the use 5970 ; of the Maintenance Service, even when the service is not and will not be 5971 ; installed. (In fact, even when a service installed in the future will 5972 ; never update the installation, for example due to not being in a 5973 ; privileged location.) In practice this means we can only truly silently 5974 ; remove an unelevated install: an elevated installer writing to an 5975 ; unprivileged install directory will still write privileged registry 5976 ; entries, requiring an elevated uninstaller to completely clean up. 5977 ; 5978 ; This avoids a wrinkle, whereby an uninstaller which runs unelevated will 5979 ; never itself launch the Maintenance Service uninstaller, because it will 5980 ; fail to remove its own service registration (removing the relevant 5981 ; registry key would require elevation). Therefore the check for the 5982 ; service being unused will fail, which will prevent running the service 5983 ; uninstaller. That's both subtle and possibly leaves the service 5984 ; registration hanging around, which might be a security risk. 5985 ; 5986 ; That is why we look for a privileged service registration for this 5987 ; installation when deciding to elevate, and elevate unconditionally if we 5988 ; find one, regardless of the result of the write check that would avoid 5989 ; elevation. 5990 5991 ; The reason for requiring elevation, or "" for not required. 5992 StrCpy $R4 "" 5993 5994 ${IfNot} ${Silent} 5995 ; In normal operation, require elevation if the user can elevate so that 5996 ; we are most likely to succeed. 5997 StrCpy $R4 "not silent" 5998 ${EndIf} 5999 6000 GetTempFileName $R6 "$INSTDIR" 6001 FileOpen $R5 "$R6" w 6002 FileWrite $R5 "Write Access Test" 6003 FileClose $R5 6004 Delete $R6 6005 ${If} ${Errors} 6006 StrCpy $R4 "write" 6007 ${EndIf} 6008 6009 !ifdef MOZ_MAINTENANCE_SERVICE 6010 ; We don't necessarily have $MaintCertKey, so use temporary registers. 6011 ServicesHelper::PathToUniqueRegistryPath "$INSTDIR" 6012 Pop $R5 6013 6014 ${If} $R5 != "" 6015 ; Always use the 64bit registry for certs on 64bit systems. 6016 ${If} ${RunningX64} 6017 ${OrIf} ${IsNativeARM64} 6018 SetRegView 64 6019 ${EndIf} 6020 6021 EnumRegKey $R6 HKLM $R5 0 6022 ClearErrors 6023 6024 ${If} ${RunningX64} 6025 ${OrIf} ${IsNativeARM64} 6026 SetRegView lastused 6027 ${EndIf} 6028 6029 ${IfNot} "$R6" == "" 6030 StrCpy $R4 "mms" 6031 ${EndIf} 6032 ${EndIf} 6033 !endif 6034 6035 ${If} "$R4" != "" 6036 ; In the future, we might not try to elevate to remain truly silent. Or 6037 ; we might add a command line arguments to specify behaviour. One 6038 ; reason to not do that immediately is that we have no great way to 6039 ; signal that we exited without taking action. 6040 ${ElevateUAC} 6041 ${EndIf} 6042 6043 ; Now we've elevated, try the write access test again. 6044 ClearErrors 6045 GetTempFileName $R6 "$INSTDIR" 6046 FileOpen $R5 "$R6" w 6047 FileWrite $R5 "Write Access Test" 6048 FileClose $R5 6049 Delete $R6 6050 ${If} ${Errors} 6051 ; Nothing initialized so no need to call OnEndCommon 6052 Quit 6053 ${EndIf} 6054 6055 !ifdef MOZ_MAINTENANCE_SERVICE 6056 ; And verify that if we need to, we're going to clean up the registry 6057 ; correctly. 6058 ${If} "$R4" == "mms" 6059 WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" 6060 ${If} ${Errors} 6061 ; Nothing initialized so no need to call OnEndCommon 6062 Quit 6063 ${Endif} 6064 DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" 6065 ${EndIf} 6066 !endif 6067 6068 ; If we made it this far then this installer is being used as an uninstaller. 6069 WriteUninstaller "$EXEDIR\uninstaller.exe" 6070 6071 ${If} ${Silent} 6072 StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\" /S" 6073 ${Else} 6074 StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\"" 6075 ${EndIf} 6076 6077 ; When the uninstaller is launched it copies itself to the temp directory 6078 ; so it won't be in use so it can delete itself. 6079 ExecWait $R1 6080 ${DeleteFile} "$EXEDIR\uninstaller.exe" 6081 ${UnloadUAC} 6082 SetErrorLevel 0 6083 Quit ; Nothing initialized so no need to call OnEndCommon 6084 6085 FunctionEnd 6086 6087 !verbose pop 6088 !endif 6089!macroend 6090 6091!macro UninstallOnInitCommonCall 6092 !verbose push 6093 !verbose ${_MOZFUNC_VERBOSE} 6094 Call UninstallOnInitCommon 6095 !verbose pop 6096!macroend 6097 6098/** 6099 * Called from the uninstaller's un.onInit function not to be confused with the 6100 * installer's .onInit or the uninstaller's .onInit functions. 6101 */ 6102!macro un.UninstallUnOnInitCommon 6103 6104 !ifndef un.UninstallUnOnInitCommon 6105 !insertmacro un.GetLongPath 6106 !insertmacro un.GetParent 6107 !insertmacro un.SetBrandNameVars 6108 6109 !verbose push 6110 !verbose ${_MOZFUNC_VERBOSE} 6111 !define un.UninstallUnOnInitCommon "!insertmacro un.UninstallUnOnInitCommonCall" 6112 6113 Function un.UninstallUnOnInitCommon 6114 ${un.GetParent} "$INSTDIR" $INSTDIR 6115 ${un.GetLongPath} "$INSTDIR" $INSTDIR 6116 ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}" 6117 Abort 6118 ${EndUnless} 6119 6120 !ifdef HAVE_64BIT_BUILD 6121 SetRegView 64 6122 !endif 6123 6124 ; Prevents breaking apps that don't use SetBrandNameVars 6125 !ifdef un.SetBrandNameVars 6126 ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini" 6127 !endif 6128 6129 ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if 6130 ; the user clicks the back button 6131 StrCpy $hHeaderBitmap "" 6132 FunctionEnd 6133 6134 !verbose pop 6135 !endif 6136!macroend 6137 6138!macro un.UninstallUnOnInitCommonCall 6139 !verbose push 6140 !verbose ${_MOZFUNC_VERBOSE} 6141 Call un.UninstallUnOnInitCommon 6142 !verbose pop 6143!macroend 6144 6145/** 6146 * Called from the MUI leaveOptions function to set the value of $INSTDIR. 6147 */ 6148!macro LeaveOptionsCommon 6149 6150 !ifndef LeaveOptionsCommon 6151 !insertmacro CanWriteToInstallDir 6152 !insertmacro GetLongPath 6153 6154!ifndef NO_INSTDIR_FROM_REG 6155 !insertmacro GetSingleInstallPath 6156!endif 6157 6158 !verbose push 6159 !verbose ${_MOZFUNC_VERBOSE} 6160 !define LeaveOptionsCommon "!insertmacro LeaveOptionsCommonCall" 6161 6162 Function LeaveOptionsCommon 6163 Push $R9 6164 6165 StrCpy $R9 "false" 6166 6167!ifndef NO_INSTDIR_FROM_REG 6168 SetShellVarContext all ; Set SHCTX to HKLM 6169 6170 ${If} ${IsNativeAMD64} 6171 ${OrIf} ${IsNativeARM64} 6172 SetRegView 64 6173 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 6174 SetRegView lastused 6175 ${EndIf} 6176 6177 StrCmp "$R9" "false" +1 finish_get_install_dir 6178 6179 SetRegView 32 6180 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 6181 SetRegView lastused 6182 6183 StrCmp "$R9" "false" +1 finish_get_install_dir 6184 6185 SetShellVarContext current ; Set SHCTX to HKCU 6186 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 6187 6188 finish_get_install_dir: 6189 StrCmp "$R9" "false" +2 +1 6190 StrCpy $INSTDIR "$R9" 6191!endif 6192 6193 ; If the user doesn't have write access to the installation directory set 6194 ; the installation directory to a subdirectory of the All Users application 6195 ; directory and if the user can't write to that location set the installation 6196 ; directory to a subdirectory of the users local application directory 6197 ; (e.g. non-roaming). 6198 ${CanWriteToInstallDir} $R9 6199 StrCmp "$R9" "false" +1 finish_check_install_dir 6200 6201 SetShellVarContext all ; Set SHCTX to All Users 6202 StrCpy $INSTDIR "$APPDATA\${BrandFullName}\" 6203 ${CanWriteToInstallDir} $R9 6204 StrCmp "$R9" "false" +2 +1 6205 StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\" 6206 6207 finish_check_install_dir: 6208 IfFileExists "$INSTDIR" +3 +1 6209 Pop $R9 6210 Return 6211 6212 ; Always display the long path if the path already exists. 6213 ${GetLongPath} "$INSTDIR" $INSTDIR 6214 6215 ; The call to GetLongPath returns a long path without a trailing 6216 ; back-slash. Append a \ to the path to prevent the directory 6217 ; name from being appended when using the NSIS create new folder. 6218 ; http://www.nullsoft.com/free/nsis/makensis.htm#InstallDir 6219 StrCpy $INSTDIR "$INSTDIR\" 6220 6221 Pop $R9 6222 FunctionEnd 6223 6224 !verbose pop 6225 !endif 6226!macroend 6227 6228!macro LeaveOptionsCommonCall 6229 !verbose push 6230 !verbose ${_MOZFUNC_VERBOSE} 6231 Call LeaveOptionsCommon 6232 !verbose pop 6233!macroend 6234 6235/** 6236 * Called from the MUI preDirectory function to verify there is enough disk 6237 * space for the installation and the installation directory is writable. 6238 * 6239 * $R9 = returned value from CheckDiskSpace and CanWriteToInstallDir macros 6240 */ 6241!macro PreDirectoryCommon 6242 6243 !ifndef PreDirectoryCommon 6244 !insertmacro CanWriteToInstallDir 6245 !insertmacro CheckDiskSpace 6246 6247 !verbose push 6248 !verbose ${_MOZFUNC_VERBOSE} 6249 !define PreDirectoryCommon "!insertmacro PreDirectoryCommonCall" 6250 6251 Function PreDirectoryCommon 6252 Push $R9 6253 6254 IntCmp $InstallType ${INSTALLTYPE_CUSTOM} end +1 +1 6255 ${CanWriteToInstallDir} $R9 6256 StrCmp "$R9" "false" end +1 6257 ${CheckDiskSpace} $R9 6258 StrCmp "$R9" "false" end +1 6259 Abort 6260 6261 end: 6262 6263 Pop $R9 6264 FunctionEnd 6265 6266 !verbose pop 6267 !endif 6268!macroend 6269 6270!macro PreDirectoryCommonCall 6271 !verbose push 6272 !verbose ${_MOZFUNC_VERBOSE} 6273 Call PreDirectoryCommon 6274 !verbose pop 6275!macroend 6276 6277/** 6278 * Called from the MUI leaveDirectory function 6279 * 6280 * @param _WARN_DISK_SPACE 6281 * Message displayed when there isn't enough disk space to perform the 6282 * installation. 6283 * @param _WARN_WRITE_ACCESS 6284 * Message displayed when the installer does not have write access to 6285 * $INSTDIR. 6286 * 6287 * $R7 = returned value from CheckDiskSpace and CanWriteToInstallDir macros 6288 * $R8 = _WARN_DISK_SPACE 6289 * $R9 = _WARN_WRITE_ACCESS 6290 */ 6291!macro LeaveDirectoryCommon 6292 6293 !ifndef LeaveDirectoryCommon 6294 !insertmacro CheckDiskSpace 6295 !insertmacro CanWriteToInstallDir 6296 6297 !verbose push 6298 !verbose ${_MOZFUNC_VERBOSE} 6299 !define LeaveDirectoryCommon "!insertmacro LeaveDirectoryCommonCall" 6300 6301 Function LeaveDirectoryCommon 6302 Exch $R9 6303 Exch 1 6304 Exch $R8 6305 Push $R7 6306 6307 ${CanWriteToInstallDir} $R7 6308 ${If} $R7 == "false" 6309 MessageBox MB_OK|MB_ICONEXCLAMATION "$R9" 6310 Abort 6311 ${EndIf} 6312 6313 ${CheckDiskSpace} $R7 6314 ${If} $R7 == "false" 6315 MessageBox MB_OK|MB_ICONEXCLAMATION "$R8" 6316 Abort 6317 ${EndIf} 6318 6319 Pop $R7 6320 Exch $R8 6321 Exch 1 6322 Exch $R9 6323 FunctionEnd 6324 6325 !verbose pop 6326 !endif 6327!macroend 6328 6329!macro LeaveDirectoryCommonCall _WARN_DISK_SPACE _WARN_WRITE_ACCESS 6330 !verbose push 6331 Push "${_WARN_DISK_SPACE}" 6332 Push "${_WARN_WRITE_ACCESS}" 6333 !verbose ${_MOZFUNC_VERBOSE} 6334 Call LeaveDirectoryCommon 6335 !verbose pop 6336!macroend 6337 6338 6339################################################################################ 6340# Install Section common macros. 6341 6342/** 6343 * Performs common cleanup operations prior to the actual installation. 6344 * This macro should be called first when installation starts. 6345 */ 6346!macro InstallStartCleanupCommon 6347 6348 !ifndef InstallStartCleanupCommon 6349 !insertmacro CleanVirtualStore 6350 !insertmacro EndUninstallLog 6351 !insertmacro OnInstallUninstall 6352 6353 !verbose push 6354 !verbose ${_MOZFUNC_VERBOSE} 6355 !define InstallStartCleanupCommon "!insertmacro InstallStartCleanupCommonCall" 6356 6357 Function InstallStartCleanupCommon 6358 6359 ; Remove files not removed by parsing the uninstall.log 6360 Delete "$INSTDIR\install_wizard.log" 6361 Delete "$INSTDIR\install_status.log" 6362 6363 RmDir /r "$INSTDIR\updates" 6364 Delete "$INSTDIR\updates.xml" 6365 Delete "$INSTDIR\active-update.xml" 6366 6367 ; Remove files from the uninstall directory. 6368 ${If} ${FileExists} "$INSTDIR\uninstall" 6369 Delete "$INSTDIR\uninstall\*wizard*" 6370 Delete "$INSTDIR\uninstall\uninstall.ini" 6371 Delete "$INSTDIR\uninstall\cleanup.log" 6372 Delete "$INSTDIR\uninstall\uninstall.update" 6373 ${OnInstallUninstall} 6374 ${EndIf} 6375 6376 ; Since we write to the uninstall.log in this directory during the 6377 ; installation create the directory if it doesn't already exist. 6378 IfFileExists "$INSTDIR\uninstall" +2 +1 6379 CreateDirectory "$INSTDIR\uninstall" 6380 6381 ; Application update uses a directory named tobedeleted in the $INSTDIR to 6382 ; delete files on OS reboot when they are in use. Try to delete this 6383 ; directory if it exists. 6384 ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" 6385 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 6386 ${EndIf} 6387 6388 ; Remove files that may be left behind by the application in the 6389 ; VirtualStore directory. 6390 ${CleanVirtualStore} 6391 FunctionEnd 6392 6393 !verbose pop 6394 !endif 6395!macroend 6396 6397!macro InstallStartCleanupCommonCall 6398 !verbose push 6399 !verbose ${_MOZFUNC_VERBOSE} 6400 Call InstallStartCleanupCommon 6401 !verbose pop 6402!macroend 6403 6404/** 6405 * Performs common cleanup operations after the actual installation. 6406 * This macro should be called last during the installation. 6407 */ 6408!macro InstallEndCleanupCommon 6409 6410 !ifndef InstallEndCleanupCommon 6411 !insertmacro EndUninstallLog 6412 6413 !verbose push 6414 !verbose ${_MOZFUNC_VERBOSE} 6415 !define InstallEndCleanupCommon "!insertmacro InstallEndCleanupCommonCall" 6416 6417 Function InstallEndCleanupCommon 6418 6419 ; Close the file handle to the uninstall.log 6420 ${EndUninstallLog} 6421 6422 FunctionEnd 6423 6424 !verbose pop 6425 !endif 6426!macroend 6427 6428!macro InstallEndCleanupCommonCall 6429 !verbose push 6430 !verbose ${_MOZFUNC_VERBOSE} 6431 Call InstallEndCleanupCommon 6432 !verbose pop 6433!macroend 6434 6435 6436################################################################################ 6437# UAC Related Macros 6438 6439/** 6440 * Provides UAC elevation support (requires the UAC plugin). 6441 * 6442 * $0 = return values from calls to the UAC plugin (always uses $0) 6443 * $R9 = return values from GetParameters and GetOptions macros 6444 */ 6445!macro ElevateUAC 6446 6447 !ifndef ${_MOZFUNC_UN}ElevateUAC 6448 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 6449 !insertmacro ${_MOZFUNC_UN_TMP}GetOptions 6450 !insertmacro ${_MOZFUNC_UN_TMP}GetParameters 6451 !undef _MOZFUNC_UN 6452 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 6453 !undef _MOZFUNC_UN_TMP 6454 6455 !verbose push 6456 !verbose ${_MOZFUNC_VERBOSE} 6457 !define ${_MOZFUNC_UN}ElevateUAC "!insertmacro ${_MOZFUNC_UN}ElevateUACCall" 6458 6459 Function ${_MOZFUNC_UN}ElevateUAC 6460 Push $R9 6461 Push $0 6462 6463!ifndef NONADMIN_ELEVATE 6464 UAC::IsAdmin 6465 ; If the user is not an admin already 6466 ${If} "$0" != "1" 6467 UAC::SupportsUAC 6468 ; If the system supports UAC 6469 ${If} "$0" == "1" 6470 UAC::GetElevationType 6471 ; If the user account has a split token 6472 ${If} "$0" == "3" 6473 UAC::RunElevated 6474 UAC::Unload 6475 ; Nothing besides UAC initialized so no need to call OnEndCommon 6476 Quit 6477 ${EndIf} 6478 ${EndIf} 6479 ${Else} 6480 ${GetParameters} $R9 6481 ${If} $R9 != "" 6482 ClearErrors 6483 ${GetOptions} "$R9" "/UAC:" $0 6484 ; If the command line contains /UAC then we need to initialize 6485 ; the UAC plugin to use UAC::ExecCodeSegment to execute code in 6486 ; the non-elevated context. 6487 ${Unless} ${Errors} 6488 UAC::RunElevated 6489 ${EndUnless} 6490 ${EndIf} 6491 ${EndIf} 6492!else 6493 UAC::IsAdmin 6494 ; If the user is not an admin already 6495 ${If} "$0" != "1" 6496 UAC::SupportsUAC 6497 ; If the system supports UAC require that the user elevate 6498 ${If} "$0" == "1" 6499 UAC::GetElevationType 6500 ; If the user account has a split token 6501 ${If} "$0" == "3" 6502 UAC::RunElevated 6503 ${If} "$0" == "0" ; Was elevation successful 6504 UAC::Unload 6505 ; Nothing besides UAC initialized so no need to call OnEndCommon 6506 Quit 6507 ${EndIf} 6508 ; Unload UAC since the elevation request was not successful and 6509 ; install anyway. 6510 UAC::Unload 6511 ${EndIf} 6512 ${Else} 6513 ; Check if UAC is enabled. If the user has turned UAC on or off 6514 ; without rebooting this value will be incorrect. This is an 6515 ; edgecase that we have to live with when trying to allow 6516 ; installing when the user doesn't have privileges such as a public 6517 ; computer while trying to also achieve UAC elevation. When this 6518 ; happens the user will be presented with the runas dialog if the 6519 ; value is 1 and won't be presented with the UAC dialog when the 6520 ; value is 0. 6521 ReadRegDWord $R9 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "EnableLUA" 6522 ${If} "$R9" == "1" 6523 ; This will display the UAC version of the runas dialog which 6524 ; requires a password for an existing user account. 6525 UAC::RunElevated 6526 ${If} "$0" == "0" ; Was elevation successful 6527 UAC::Unload 6528 ; Nothing besides UAC initialized so no need to call OnEndCommon 6529 Quit 6530 ${EndIf} 6531 ; Unload UAC since the elevation request was not successful and 6532 ; install anyway. 6533 UAC::Unload 6534 ${EndIf} 6535 ${EndIf} 6536 ${Else} 6537 ClearErrors 6538 ${${_MOZFUNC_UN}GetParameters} $R9 6539 ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9 6540 ; If the command line contains /UAC then we need to initialize the UAC 6541 ; plugin to use UAC::ExecCodeSegment to execute code in the 6542 ; non-elevated context. 6543 ${Unless} ${Errors} 6544 UAC::RunElevated 6545 ${EndUnless} 6546 ${EndIf} 6547!endif 6548 6549 ClearErrors 6550 6551 Pop $0 6552 Pop $R9 6553 FunctionEnd 6554 6555 !verbose pop 6556 !endif 6557!macroend 6558 6559!macro ElevateUACCall 6560 !verbose push 6561 !verbose ${_MOZFUNC_VERBOSE} 6562 Call ElevateUAC 6563 !verbose pop 6564!macroend 6565 6566!macro un.ElevateUACCall 6567 !verbose push 6568 !verbose ${_MOZFUNC_VERBOSE} 6569 Call un.ElevateUAC 6570 !verbose pop 6571!macroend 6572 6573!macro un.ElevateUAC 6574 !ifndef un.ElevateUAC 6575 !verbose push 6576 !verbose ${_MOZFUNC_VERBOSE} 6577 !undef _MOZFUNC_UN 6578 !define _MOZFUNC_UN "un." 6579 6580 !insertmacro ElevateUAC 6581 6582 !undef _MOZFUNC_UN 6583 !define _MOZFUNC_UN 6584 !verbose pop 6585 !endif 6586!macroend 6587 6588/** 6589 * Unloads the UAC plugin so the NSIS plugins can be removed when the installer 6590 * and uninstaller exit. 6591 * 6592 * $R9 = return values from GetParameters and GetOptions macros 6593 */ 6594!macro UnloadUAC 6595 6596 !ifndef ${_MOZFUNC_UN}UnloadUAC 6597 !define _MOZFUNC_UN_TMP_UnloadUAC ${_MOZFUNC_UN} 6598 !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetOptions 6599 !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetParameters 6600 !undef _MOZFUNC_UN 6601 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP_UnloadUAC} 6602 !undef _MOZFUNC_UN_TMP_UnloadUAC 6603 6604 !verbose push 6605 !verbose ${_MOZFUNC_VERBOSE} 6606 !define ${_MOZFUNC_UN}UnloadUAC "!insertmacro ${_MOZFUNC_UN}UnloadUACCall" 6607 6608 Function ${_MOZFUNC_UN}UnloadUAC 6609 Push $R9 6610 6611 ClearErrors 6612 ${${_MOZFUNC_UN}GetParameters} $R9 6613 ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9 6614 ; If the command line contains /UAC then we need to unload the UAC plugin 6615 IfErrors +2 +1 6616 UAC::Unload 6617 6618 ClearErrors 6619 6620 Pop $R9 6621 FunctionEnd 6622 6623 !verbose pop 6624 !endif 6625!macroend 6626 6627!macro UnloadUACCall 6628 !verbose push 6629 !verbose ${_MOZFUNC_VERBOSE} 6630 Call UnloadUAC 6631 !verbose pop 6632!macroend 6633 6634!macro un.UnloadUACCall 6635 !verbose push 6636 !verbose ${_MOZFUNC_VERBOSE} 6637 Call un.UnloadUAC 6638 !verbose pop 6639!macroend 6640 6641!macro un.UnloadUAC 6642 !ifndef un.UnloadUAC 6643 !verbose push 6644 !verbose ${_MOZFUNC_VERBOSE} 6645 !undef _MOZFUNC_UN 6646 !define _MOZFUNC_UN "un." 6647 6648 !insertmacro UnloadUAC 6649 6650 !undef _MOZFUNC_UN 6651 !define _MOZFUNC_UN 6652 !verbose pop 6653 !endif 6654!macroend 6655 6656 6657################################################################################ 6658# Macros for uninstall.log and install.log logging 6659# 6660# Since these are used by other macros they should be inserted first. All of 6661# these macros can be easily inserted using the _LoggingCommon macro. 6662 6663/** 6664 * Adds all logging macros in the correct order in one fell swoop as well as 6665 * the vars for the install.log and uninstall.log file handles. 6666 */ 6667!macro _LoggingCommon 6668 Var /GLOBAL fhInstallLog 6669 Var /GLOBAL fhUninstallLog 6670 !insertmacro StartInstallLog 6671 !insertmacro EndInstallLog 6672 !insertmacro StartUninstallLog 6673 !insertmacro EndUninstallLog 6674!macroend 6675!define _LoggingCommon "!insertmacro _LoggingCommon" 6676 6677/** 6678 * Creates a file named install.log in the install directory (e.g. $INSTDIR) 6679 * and adds the installation started message to the install.log for this 6680 * installation. This also adds the fhInstallLog and fhUninstallLog vars used 6681 * for logging. 6682 * 6683 * $fhInstallLog = filehandle for $INSTDIR\install.log 6684 * 6685 * @param _APP_NAME 6686 * Typically the BrandFullName 6687 * @param _AB_CD 6688 * The locale identifier 6689 * @param _APP_VERSION 6690 * The application version 6691 * @param _GRE_VERSION 6692 * The Gecko Runtime Engine version 6693 * 6694 * $R6 = _APP_NAME 6695 * $R7 = _AB_CD 6696 * $R8 = _APP_VERSION 6697 * $R9 = _GRE_VERSION 6698 */ 6699!macro StartInstallLog 6700 6701 !ifndef StartInstallLog 6702 !insertmacro GetTime 6703 6704 !verbose push 6705 !verbose ${_MOZFUNC_VERBOSE} 6706 !define StartInstallLog "!insertmacro StartInstallLogCall" 6707 6708 Function StartInstallLog 6709 Exch $R9 6710 Exch 1 6711 Exch $R8 6712 Exch 2 6713 Exch $R7 6714 Exch 3 6715 Exch $R6 6716 Push $R5 6717 Push $R4 6718 Push $R3 6719 Push $R2 6720 Push $R1 6721 Push $R0 6722 Push $9 6723 6724 ${DeleteFile} "$INSTDIR\install.log" 6725 FileOpen $fhInstallLog "$INSTDIR\install.log" w 6726 FileWriteWord $fhInstallLog "65279" 6727 6728 ${GetTime} "" "L" $9 $R0 $R1 $R2 $R3 $R4 $R5 6729 FileWriteUTF16LE $fhInstallLog "$R6 Installation Started: $R1-$R0-$9 $R3:$R4:$R5" 6730 ${WriteLogSeparator} 6731 6732 ${LogHeader} "Installation Details" 6733 ${LogMsg} "Install Dir: $INSTDIR" 6734 ${LogMsg} "Locale : $R7" 6735 ${LogMsg} "App Version: $R8" 6736 ${LogMsg} "GRE Version: $R9" 6737 6738 ${If} ${IsWin7} 6739 ${LogMsg} "OS Name : Windows 7" 6740 ${ElseIf} ${IsWin8} 6741 ${LogMsg} "OS Name : Windows 8" 6742 ${ElseIf} ${IsWin8.1} 6743 ${LogMsg} "OS Name : Windows 8.1" 6744 ${ElseIf} ${IsWin10} 6745 ${LogMsg} "OS Name : Windows 10" 6746 ${ElseIf} ${AtLeastWin10} 6747 ${LogMsg} "OS Name : Above Windows 10" 6748 ${Else} 6749 ${LogMsg} "OS Name : Unable to detect" 6750 ${EndIf} 6751 6752 ${LogMsg} "Target CPU : ${ARCH}" 6753 6754 Pop $9 6755 Pop $R0 6756 Pop $R1 6757 Pop $R2 6758 Pop $R3 6759 Pop $R4 6760 Pop $R5 6761 Exch $R6 6762 Exch 3 6763 Exch $R7 6764 Exch 2 6765 Exch $R8 6766 Exch 1 6767 Exch $R9 6768 FunctionEnd 6769 6770 !verbose pop 6771 !endif 6772!macroend 6773 6774!macro StartInstallLogCall _APP_NAME _AB_CD _APP_VERSION _GRE_VERSION 6775 !verbose push 6776 !verbose ${_MOZFUNC_VERBOSE} 6777 Push "${_APP_NAME}" 6778 Push "${_AB_CD}" 6779 Push "${_APP_VERSION}" 6780 Push "${_GRE_VERSION}" 6781 Call StartInstallLog 6782 !verbose pop 6783!macroend 6784 6785/** 6786 * Writes the installation finished message to the install.log and closes the 6787 * file handles to the install.log and uninstall.log 6788 * 6789 * @param _APP_NAME 6790 * 6791 * $R9 = _APP_NAME 6792 */ 6793!macro EndInstallLog 6794 6795 !ifndef EndInstallLog 6796 !insertmacro GetTime 6797 6798 !verbose push 6799 !verbose ${_MOZFUNC_VERBOSE} 6800 !define EndInstallLog "!insertmacro EndInstallLogCall" 6801 6802 Function EndInstallLog 6803 Exch $R9 6804 Push $R8 6805 Push $R7 6806 Push $R6 6807 Push $R5 6808 Push $R4 6809 Push $R3 6810 Push $R2 6811 6812 ${WriteLogSeparator} 6813 ${GetTime} "" "L" $R2 $R3 $R4 $R5 $R6 $R7 $R8 6814 FileWriteUTF16LE $fhInstallLog "$R9 Installation Finished: $R4-$R3-$R2 $R6:$R7:$R8$\r$\n" 6815 FileClose $fhInstallLog 6816 6817 Pop $R2 6818 Pop $R3 6819 Pop $R4 6820 Pop $R5 6821 Pop $R6 6822 Pop $R7 6823 Pop $R8 6824 Exch $R9 6825 FunctionEnd 6826 6827 !verbose pop 6828 !endif 6829!macroend 6830 6831!macro EndInstallLogCall _APP_NAME 6832 !verbose push 6833 !verbose ${_MOZFUNC_VERBOSE} 6834 Push "${_APP_NAME}" 6835 Call EndInstallLog 6836 !verbose pop 6837!macroend 6838 6839/** 6840 * Opens the file handle to the uninstall.log. 6841 * 6842 * $fhUninstallLog = filehandle for $INSTDIR\uninstall\uninstall.log 6843 */ 6844!macro StartUninstallLog 6845 6846 !ifndef StartUninstallLog 6847 !verbose push 6848 !verbose ${_MOZFUNC_VERBOSE} 6849 !define StartUninstallLog "!insertmacro StartUninstallLogCall" 6850 6851 Function StartUninstallLog 6852 FileOpen $fhUninstallLog "$INSTDIR\uninstall\uninstall.log" w 6853 FunctionEnd 6854 6855 !verbose pop 6856 !endif 6857!macroend 6858 6859!macro StartUninstallLogCall 6860 !verbose push 6861 !verbose ${_MOZFUNC_VERBOSE} 6862 Call StartUninstallLog 6863 !verbose pop 6864!macroend 6865 6866/** 6867 * Closes the file handle to the uninstall.log. 6868 */ 6869!macro EndUninstallLog 6870 6871 !ifndef EndUninstallLog 6872 6873 !verbose push 6874 !verbose ${_MOZFUNC_VERBOSE} 6875 !define EndUninstallLog "!insertmacro EndUninstallLogCall" 6876 6877 Function EndUninstallLog 6878 FileClose $fhUninstallLog 6879 FunctionEnd 6880 6881 !verbose pop 6882 !endif 6883!macroend 6884 6885!macro EndUninstallLogCall 6886 !verbose push 6887 !verbose ${_MOZFUNC_VERBOSE} 6888 Call EndUninstallLog 6889 !verbose pop 6890!macroend 6891 6892/** 6893 * Adds a section header to the human readable log. 6894 * 6895 * @param _HEADER 6896 * The header text to write to the log. 6897 */ 6898!macro LogHeader _HEADER 6899 ${WriteLogSeparator} 6900 FileWriteUTF16LE $fhInstallLog "${_HEADER}" 6901 ${WriteLogSeparator} 6902!macroend 6903!define LogHeader "!insertmacro LogHeader" 6904 6905/** 6906 * Adds a section message to the human readable log. 6907 * 6908 * @param _MSG 6909 * The message text to write to the log. 6910 */ 6911!macro LogMsg _MSG 6912 FileWriteUTF16LE $fhInstallLog " ${_MSG}$\r$\n" 6913!macroend 6914!define LogMsg "!insertmacro LogMsg" 6915 6916/** 6917 * Adds an uninstall entry to the uninstall log. 6918 * 6919 * @param _MSG 6920 * The message text to write to the log. 6921 */ 6922!macro LogUninstall _MSG 6923 FileWrite $fhUninstallLog "${_MSG}$\r$\n" 6924!macroend 6925!define LogUninstall "!insertmacro LogUninstall" 6926 6927/** 6928 * Adds a section divider to the human readable log. 6929 */ 6930!macro WriteLogSeparator 6931 FileWriteUTF16LE $fhInstallLog "$\r$\n----------------------------------------\ 6932 ---------------------------------------$\r$\n" 6933!macroend 6934!define WriteLogSeparator "!insertmacro WriteLogSeparator" 6935 6936 6937################################################################################ 6938# Macros for managing the shortcuts log ini file 6939 6940/** 6941 * Adds the most commonly used shortcut logging macros for the installer in one 6942 * fell swoop. 6943 */ 6944!macro _LoggingShortcutsCommon 6945 !insertmacro LogDesktopShortcut 6946 !insertmacro LogQuickLaunchShortcut 6947 !insertmacro LogSMProgramsShortcut 6948!macroend 6949!define _LoggingShortcutsCommon "!insertmacro _LoggingShortcutsCommon" 6950 6951/** 6952 * Creates the shortcuts log ini file with a UTF-16LE BOM if it doesn't exist. 6953 */ 6954!macro initShortcutsLog 6955 Push $R9 6956 6957 IfFileExists "$INSTDIR\uninstall\${SHORTCUTS_LOG}" +4 +1 6958 FileOpen $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" w 6959 FileWriteWord $R9 "65279" 6960 FileClose $R9 6961 6962 Pop $R9 6963!macroend 6964!define initShortcutsLog "!insertmacro initShortcutsLog" 6965 6966/** 6967 * Adds shortcut entries to the shortcuts log ini file. This macro is primarily 6968 * a helper used by the LogDesktopShortcut, LogQuickLaunchShortcut, and 6969 * LogSMProgramsShortcut macros but it can be used by other code if desired. If 6970 * the value already exists the the value is not written to the file. 6971 * 6972 * @param _SECTION_NAME 6973 * The section name to write to in the shortcut log ini file 6974 * @param _FILE_NAME 6975 * The shortcut's file name 6976 * 6977 * $R6 = return value from ReadIniStr for the shortcut file name 6978 * $R7 = counter for supporting multiple shortcuts in the same location 6979 * $R8 = _SECTION_NAME 6980 * $R9 = _FILE_NAME 6981 */ 6982!macro LogShortcut 6983 6984 !ifndef LogShortcut 6985 !verbose push 6986 !verbose ${_MOZFUNC_VERBOSE} 6987 !define LogShortcut "!insertmacro LogShortcutCall" 6988 6989 Function LogShortcut 6990 Exch $R9 6991 Exch 1 6992 Exch $R8 6993 Push $R7 6994 Push $R6 6995 6996 ClearErrors 6997 6998 !insertmacro initShortcutsLog 6999 7000 StrCpy $R6 "" 7001 StrCpy $R7 -1 7002 7003 StrCmp "$R6" "$R9" +5 +1 ; if the shortcut already exists don't add it 7004 IntOp $R7 $R7 + 1 ; increment the counter 7005 ReadIniStr $R6 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" 7006 IfErrors +1 -3 7007 WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" "$R9" 7008 7009 ClearErrors 7010 7011 Pop $R6 7012 Pop $R7 7013 Exch $R8 7014 Exch 1 7015 Exch $R9 7016 FunctionEnd 7017 7018 !verbose pop 7019 !endif 7020!macroend 7021 7022!macro LogShortcutCall _SECTION_NAME _FILE_NAME 7023 !verbose push 7024 !verbose ${_MOZFUNC_VERBOSE} 7025 Push "${_SECTION_NAME}" 7026 Push "${_FILE_NAME}" 7027 Call LogShortcut 7028 !verbose pop 7029!macroend 7030 7031/** 7032 * Adds a Desktop shortcut entry to the shortcuts log ini file. 7033 * 7034 * @param _FILE_NAME 7035 * The shortcut file name (e.g. shortcut.lnk) 7036 */ 7037!macro LogDesktopShortcut 7038 7039 !ifndef LogDesktopShortcut 7040 !insertmacro LogShortcut 7041 7042 !verbose push 7043 !verbose ${_MOZFUNC_VERBOSE} 7044 !define LogDesktopShortcut "!insertmacro LogDesktopShortcutCall" 7045 7046 Function LogDesktopShortcut 7047 Call LogShortcut 7048 FunctionEnd 7049 7050 !verbose pop 7051 !endif 7052!macroend 7053 7054!macro LogDesktopShortcutCall _FILE_NAME 7055 !verbose push 7056 !verbose ${_MOZFUNC_VERBOSE} 7057 Push "DESKTOP" 7058 Push "${_FILE_NAME}" 7059 Call LogDesktopShortcut 7060 !verbose pop 7061!macroend 7062 7063/** 7064 * Adds a QuickLaunch shortcut entry to the shortcuts log ini file. 7065 * 7066 * @param _FILE_NAME 7067 * The shortcut file name (e.g. shortcut.lnk) 7068 */ 7069!macro LogQuickLaunchShortcut 7070 7071 !ifndef LogQuickLaunchShortcut 7072 !insertmacro LogShortcut 7073 7074 !verbose push 7075 !verbose ${_MOZFUNC_VERBOSE} 7076 !define LogQuickLaunchShortcut "!insertmacro LogQuickLaunchShortcutCall" 7077 7078 Function LogQuickLaunchShortcut 7079 Call LogShortcut 7080 FunctionEnd 7081 7082 !verbose pop 7083 !endif 7084!macroend 7085 7086!macro LogQuickLaunchShortcutCall _FILE_NAME 7087 !verbose push 7088 !verbose ${_MOZFUNC_VERBOSE} 7089 Push "QUICKLAUNCH" 7090 Push "${_FILE_NAME}" 7091 Call LogQuickLaunchShortcut 7092 !verbose pop 7093!macroend 7094 7095/** 7096 * Adds a Start Menu shortcut entry to the shortcuts log ini file. 7097 * 7098 * @param _FILE_NAME 7099 * The shortcut file name (e.g. shortcut.lnk) 7100 */ 7101!macro LogStartMenuShortcut 7102 7103 !ifndef LogStartMenuShortcut 7104 !insertmacro LogShortcut 7105 7106 !verbose push 7107 !verbose ${_MOZFUNC_VERBOSE} 7108 !define LogStartMenuShortcut "!insertmacro LogStartMenuShortcutCall" 7109 7110 Function LogStartMenuShortcut 7111 Call LogShortcut 7112 FunctionEnd 7113 7114 !verbose pop 7115 !endif 7116!macroend 7117 7118!macro LogStartMenuShortcutCall _FILE_NAME 7119 !verbose push 7120 !verbose ${_MOZFUNC_VERBOSE} 7121 Push "STARTMENU" 7122 Push "${_FILE_NAME}" 7123 Call LogStartMenuShortcut 7124 !verbose pop 7125!macroend 7126 7127/** 7128 * Adds a Start Menu Programs shortcut entry to the shortcuts log ini file. 7129 * 7130 * @param _FILE_NAME 7131 * The shortcut file name (e.g. shortcut.lnk) 7132 */ 7133!macro LogSMProgramsShortcut 7134 7135 !ifndef LogSMProgramsShortcut 7136 !insertmacro LogShortcut 7137 7138 !verbose push 7139 !verbose ${_MOZFUNC_VERBOSE} 7140 !define LogSMProgramsShortcut "!insertmacro LogSMProgramsShortcutCall" 7141 7142 Function LogSMProgramsShortcut 7143 Call LogShortcut 7144 FunctionEnd 7145 7146 !verbose pop 7147 !endif 7148!macroend 7149 7150!macro LogSMProgramsShortcutCall _FILE_NAME 7151 !verbose push 7152 !verbose ${_MOZFUNC_VERBOSE} 7153 Push "SMPROGRAMS" 7154 Push "${_FILE_NAME}" 7155 Call LogSMProgramsShortcut 7156 !verbose pop 7157!macroend 7158 7159/** 7160 * Adds the relative path from the Start Menu Programs directory for the 7161 * application's Start Menu directory if it is different from the existing value 7162 * to the shortcuts log ini file. 7163 * 7164 * @param _REL_PATH_TO_DIR 7165 * The relative path from the Start Menu Programs directory to the 7166 * program's directory. 7167 * 7168 * $R9 = _REL_PATH_TO_DIR 7169 */ 7170!macro LogSMProgramsDirRelPath _REL_PATH_TO_DIR 7171 Push $R9 7172 7173 !insertmacro initShortcutsLog 7174 7175 ReadINIStr $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" 7176 StrCmp "$R9" "${_REL_PATH_TO_DIR}" +2 +1 7177 WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" "${_REL_PATH_TO_DIR}" 7178 7179 Pop $R9 7180!macroend 7181!define LogSMProgramsDirRelPath "!insertmacro LogSMProgramsDirRelPath" 7182 7183/** 7184 * Copies the value for the relative path from the Start Menu programs directory 7185 * (e.g. $SMPROGRAMS) to the Start Menu directory as it is stored in the 7186 * shortcuts log ini file to the variable specified in the first parameter. 7187 */ 7188!macro GetSMProgramsDirRelPath _VAR 7189 ReadINIStr ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" \ 7190 "RelativePathToDir" 7191!macroend 7192!define GetSMProgramsDirRelPath "!insertmacro GetSMProgramsDirRelPath" 7193 7194/** 7195 * Copies the shortcuts log ini file path to the variable specified in the 7196 * first parameter. 7197 */ 7198!macro GetShortcutsLogPath _VAR 7199 StrCpy ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" 7200!macroend 7201!define GetShortcutsLogPath "!insertmacro GetShortcutsLogPath" 7202 7203/** 7204 * Deletes the shortcuts log ini file. 7205 */ 7206!macro DeleteShortcutsLogFile 7207 ${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" 7208!macroend 7209!define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile" 7210 7211 7212################################################################################ 7213# Macros for managing specific Windows version features 7214 7215/** 7216 * Sets the permitted layered service provider (LSP) categories 7217 * for the application. Consumers should call this after an 7218 * installation log section has completed since this macro will log the results 7219 * to the installation log along with a header. 7220 * 7221 * !IMPORTANT - When calling this macro from an uninstaller do not specify a 7222 * parameter. The paramter is hardcoded with 0x00000000 to remove 7223 * the LSP category for the application when performing an 7224 * uninstall. 7225 * 7226 * @param _LSP_CATEGORIES 7227 * The permitted LSP categories for the application. When called by an 7228 * uninstaller this will always be 0x00000000. 7229 * 7230 * $R5 = error code popped from the stack for the WSCSetApplicationCategory call 7231 * $R6 = return value from the WSCSetApplicationCategory call 7232 * $R7 = string length for the long path to the main application executable 7233 * $R8 = long path to the main application executable 7234 * $R9 = _LSP_CATEGORIES 7235 */ 7236!macro SetAppLSPCategories 7237 7238 !ifndef ${_MOZFUNC_UN}SetAppLSPCategories 7239 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 7240 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 7241 !undef _MOZFUNC_UN 7242 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 7243 !undef _MOZFUNC_UN_TMP 7244 7245 !verbose push 7246 !verbose ${_MOZFUNC_VERBOSE} 7247 !define ${_MOZFUNC_UN}SetAppLSPCategories "!insertmacro ${_MOZFUNC_UN}SetAppLSPCategoriesCall" 7248 7249 Function ${_MOZFUNC_UN}SetAppLSPCategories 7250 Exch $R9 7251 Push $R8 7252 Push $R7 7253 Push $R6 7254 Push $R5 7255 7256 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\${FileMainEXE}" $R8 7257 StrLen $R7 "$R8" 7258 7259 ; Remove existing categories by setting the permitted categories to 7260 ; 0x00000000 since new categories are ANDed with existing categories. If 7261 ; the param value stored in $R9 is 0x00000000 then skip the removal since 7262 ; the categories will be removed by the second call to 7263 ; WSCSetApplicationCategory. 7264 StrCmp "$R9" "0x00000000" +2 +1 7265 System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\ 7266 i 0x00000000, i n, *i) i" 7267 7268 ; Set the permitted LSP categories 7269 System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\ 7270 i R9, i n, *i .s) i.R6" 7271 Pop $R5 7272 7273!ifndef NO_LOG 7274 ${LogHeader} "Setting Permitted LSP Categories" 7275 StrCmp "$R6" 0 +3 +1 7276 ${LogMsg} "** ERROR Setting LSP Categories: $R5 **" 7277 GoTo +2 7278 ${LogMsg} "Permitted LSP Categories: $R9" 7279!endif 7280 7281 ClearErrors 7282 7283 Pop $R5 7284 Pop $R6 7285 Pop $R7 7286 Pop $R8 7287 Exch $R9 7288 FunctionEnd 7289 7290 !verbose pop 7291 !endif 7292!macroend 7293 7294!macro SetAppLSPCategoriesCall _LSP_CATEGORIES 7295 !verbose push 7296 !verbose ${_MOZFUNC_VERBOSE} 7297 Push "${_LSP_CATEGORIES}" 7298 Call SetAppLSPCategories 7299 !verbose pop 7300!macroend 7301 7302!macro un.SetAppLSPCategoriesCall 7303 !verbose push 7304 !verbose ${_MOZFUNC_VERBOSE} 7305 Push "0x00000000" 7306 Call un.SetAppLSPCategories 7307 !verbose pop 7308!macroend 7309 7310!macro un.SetAppLSPCategories 7311 !ifndef un.SetAppLSPCategories 7312 !verbose push 7313 !verbose ${_MOZFUNC_VERBOSE} 7314 !undef _MOZFUNC_UN 7315 !define _MOZFUNC_UN "un." 7316 7317 !insertmacro SetAppLSPCategories 7318 7319 !undef _MOZFUNC_UN 7320 !define _MOZFUNC_UN 7321 !verbose pop 7322 !endif 7323!macroend 7324 7325/** 7326 * Checks if any pinned TaskBar lnk files point to the executable's path passed 7327 * to the macro. 7328 * 7329 * @param _EXE_PATH 7330 * The executable path 7331 * @return _RESULT 7332 * false if no pinned shotcuts were found for this install location. 7333 * true if pinned shotcuts were found for this install location. 7334 * 7335 * $R5 = stores whether a TaskBar lnk file has been found for the executable 7336 * $R6 = long path returned from GetShortCutTarget and GetLongPath 7337 * $R7 = file name returned from FindFirst and FindNext 7338 * $R8 = find handle for FindFirst and FindNext 7339 * $R9 = _EXE_PATH and _RESULT 7340 */ 7341!macro IsPinnedToTaskBar 7342 7343 !ifndef IsPinnedToTaskBar 7344 !insertmacro GetLongPath 7345 7346 !verbose push 7347 !verbose ${_MOZFUNC_VERBOSE} 7348 !define IsPinnedToTaskBar "!insertmacro IsPinnedToTaskBarCall" 7349 7350 Function IsPinnedToTaskBar 7351 Exch $R9 7352 Push $R8 7353 Push $R7 7354 Push $R6 7355 Push $R5 7356 7357 StrCpy $R5 "false" 7358 7359 ${If} ${AtLeastWin7} 7360 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" 7361 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" 7362 ${Do} 7363 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" 7364 ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\TaskBar\$R7" 7365 Pop $R6 7366 ${GetLongPath} "$R6" $R6 7367 ${If} "$R6" == "$R9" 7368 StrCpy $R5 "true" 7369 ${ExitDo} 7370 ${EndIf} 7371 ${EndIf} 7372 ClearErrors 7373 FindNext $R8 $R7 7374 ${If} ${Errors} 7375 ${ExitDo} 7376 ${EndIf} 7377 ${Loop} 7378 FindClose $R8 7379 ${EndIf} 7380 7381 ClearErrors 7382 7383 StrCpy $R9 $R5 7384 7385 Pop $R5 7386 Pop $R6 7387 Pop $R7 7388 Pop $R8 7389 Exch $R9 7390 FunctionEnd 7391 7392 !verbose pop 7393 !endif 7394!macroend 7395 7396!macro IsPinnedToTaskBarCall _EXE_PATH _RESULT 7397 !verbose push 7398 !verbose ${_MOZFUNC_VERBOSE} 7399 Push "${_EXE_PATH}" 7400 Call IsPinnedToTaskBar 7401 Pop ${_RESULT} 7402 !verbose pop 7403!macroend 7404 7405/** 7406 * Checks if any pinned Start Menu lnk files point to the executable's path 7407 * passed to the macro. 7408 * 7409 * @param _EXE_PATH 7410 * The executable path 7411 * @return _RESULT 7412 * false if no pinned shotcuts were found for this install location. 7413 * true if pinned shotcuts were found for this install location. 7414 * 7415 * $R5 = stores whether a Start Menu lnk file has been found for the executable 7416 * $R6 = long path returned from GetShortCutTarget and GetLongPath 7417 * $R7 = file name returned from FindFirst and FindNext 7418 * $R8 = find handle for FindFirst and FindNext 7419 * $R9 = _EXE_PATH and _RESULT 7420 */ 7421!macro IsPinnedToStartMenu 7422 7423 !ifndef IsPinnedToStartMenu 7424 !insertmacro GetLongPath 7425 7426 !verbose push 7427 !verbose ${_MOZFUNC_VERBOSE} 7428 !define IsPinnedToStartMenu "!insertmacro IsPinnedToStartMenuCall" 7429 7430 Function IsPinnedToStartMenu 7431 Exch $R9 7432 Push $R8 7433 Push $R7 7434 Push $R6 7435 Push $R5 7436 7437 StrCpy $R5 "false" 7438 7439 ${If} ${AtLeastWin7} 7440 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" 7441 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" 7442 ${Do} 7443 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" 7444 ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\StartMenu\$R7" 7445 Pop $R6 7446 ${GetLongPath} "$R6" $R6 7447 ${If} "$R6" == "$R9" 7448 StrCpy $R5 "true" 7449 ${ExitDo} 7450 ${EndIf} 7451 ${EndIf} 7452 ClearErrors 7453 FindNext $R8 $R7 7454 ${If} ${Errors} 7455 ${ExitDo} 7456 ${EndIf} 7457 ${Loop} 7458 FindClose $R8 7459 ${EndIf} 7460 7461 ClearErrors 7462 7463 StrCpy $R9 $R5 7464 7465 Pop $R5 7466 Pop $R6 7467 Pop $R7 7468 Pop $R8 7469 Exch $R9 7470 FunctionEnd 7471 7472 !verbose pop 7473 !endif 7474!macroend 7475 7476!macro IsPinnedToStartMenuCall _EXE_PATH _RESULT 7477 !verbose push 7478 !verbose ${_MOZFUNC_VERBOSE} 7479 Push "${_EXE_PATH}" 7480 Call IsPinnedToStartMenu 7481 Pop ${_RESULT} 7482 !verbose pop 7483!macroend 7484 7485/** 7486 * Gets the number of pinned shortcut lnk files pinned to the Task Bar. 7487 * 7488 * @return _RESULT 7489 * number of pinned shortcut lnk files. 7490 * 7491 * $R7 = file name returned from FindFirst and FindNext 7492 * $R8 = find handle for FindFirst and FindNext 7493 * $R9 = _RESULT 7494 */ 7495!macro PinnedToTaskBarLnkCount 7496 7497 !ifndef PinnedToTaskBarLnkCount 7498 !insertmacro GetLongPath 7499 7500 !verbose push 7501 !verbose ${_MOZFUNC_VERBOSE} 7502 !define PinnedToTaskBarLnkCount "!insertmacro PinnedToTaskBarLnkCountCall" 7503 7504 Function PinnedToTaskBarLnkCount 7505 Push $R9 7506 Push $R8 7507 Push $R7 7508 7509 StrCpy $R9 0 7510 7511 ${If} ${AtLeastWin7} 7512 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" 7513 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" 7514 ${Do} 7515 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" 7516 IntOp $R9 $R9 + 1 7517 ${EndIf} 7518 ClearErrors 7519 FindNext $R8 $R7 7520 ${If} ${Errors} 7521 ${ExitDo} 7522 ${EndIf} 7523 ${Loop} 7524 FindClose $R8 7525 ${EndIf} 7526 7527 ClearErrors 7528 7529 Pop $R7 7530 Pop $R8 7531 Exch $R9 7532 FunctionEnd 7533 7534 !verbose pop 7535 !endif 7536!macroend 7537 7538!macro PinnedToTaskBarLnkCountCall _RESULT 7539 !verbose push 7540 !verbose ${_MOZFUNC_VERBOSE} 7541 Call PinnedToTaskBarLnkCount 7542 Pop ${_RESULT} 7543 !verbose pop 7544!macroend 7545 7546/** 7547 * Gets the number of pinned shortcut lnk files pinned to the Start Menu. 7548 * 7549 * @return _RESULT 7550 * number of pinned shortcut lnk files. 7551 * 7552 * $R7 = file name returned from FindFirst and FindNext 7553 * $R8 = find handle for FindFirst and FindNext 7554 * $R9 = _RESULT 7555 */ 7556!macro PinnedToStartMenuLnkCount 7557 7558 !ifndef PinnedToStartMenuLnkCount 7559 !insertmacro GetLongPath 7560 7561 !verbose push 7562 !verbose ${_MOZFUNC_VERBOSE} 7563 !define PinnedToStartMenuLnkCount "!insertmacro PinnedToStartMenuLnkCountCall" 7564 7565 Function PinnedToStartMenuLnkCount 7566 Push $R9 7567 Push $R8 7568 Push $R7 7569 7570 StrCpy $R9 0 7571 7572 ${If} ${AtLeastWin7} 7573 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" 7574 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" 7575 ${Do} 7576 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" 7577 IntOp $R9 $R9 + 1 7578 ${EndIf} 7579 ClearErrors 7580 FindNext $R8 $R7 7581 ${If} ${Errors} 7582 ${ExitDo} 7583 ${EndIf} 7584 ${Loop} 7585 FindClose $R8 7586 ${EndIf} 7587 7588 ClearErrors 7589 7590 Pop $R7 7591 Pop $R8 7592 Exch $R9 7593 FunctionEnd 7594 7595 !verbose pop 7596 !endif 7597!macroend 7598 7599!macro PinnedToStartMenuLnkCountCall _RESULT 7600 !verbose push 7601 !verbose ${_MOZFUNC_VERBOSE} 7602 Call PinnedToStartMenuLnkCount 7603 Pop ${_RESULT} 7604 !verbose pop 7605!macroend 7606 7607/** 7608 * Update Start Menu / TaskBar lnk files that point to the executable's path 7609 * passed to the macro and all other shortcuts installed by the application with 7610 * the current application user model ID. Requires ApplicationID. 7611 * 7612 * NOTE: this does not update Desktop shortcut application user model ID due to 7613 * bug 633728. 7614 * 7615 * @param _EXE_PATH 7616 * The main application executable path 7617 * @param _APP_ID 7618 * The application user model ID for the current install 7619 * @return _RESULT 7620 * false if no pinned shotcuts were found for this install location. 7621 * true if pinned shotcuts were found for this install location. 7622 */ 7623!macro UpdateShortcutAppModelIDs 7624 7625 !ifndef UpdateShortcutAppModelIDs 7626 !insertmacro GetLongPath 7627 7628 !verbose push 7629 !verbose ${_MOZFUNC_VERBOSE} 7630 !define UpdateShortcutAppModelIDs "!insertmacro UpdateShortcutAppModelIDsCall" 7631 7632 Function UpdateShortcutAppModelIDs 7633 ; stack: path, appid 7634 Exch $R9 ; stack: $R9, appid | $R9 = path 7635 Exch 1 ; stack: appid, $R9 7636 Exch $R8 ; stack: $R8, $R9 | $R8 = appid 7637 Push $R7 ; stack: $R7, $R8, $R9 7638 Push $R6 7639 Push $R5 7640 Push $R4 7641 Push $R3 ; stack: $R3, $R5, $R6, $R7, $R8, $R9 7642 Push $R2 7643 7644 ; $R9 = main application executable path 7645 ; $R8 = appid 7646 ; $R7 = path to the application's start menu programs directory 7647 ; $R6 = path to the shortcut log ini file 7648 ; $R5 = shortcut filename 7649 ; $R4 = GetShortCutTarget result 7650 7651 StrCpy $R3 "false" 7652 7653 ${If} ${AtLeastWin7} 7654 ; installed shortcuts 7655 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6 7656 ${If} ${FileExists} "$R6" 7657 ; Update the Start Menu shortcuts' App ID for this application 7658 StrCpy $R2 -1 7659 ${Do} 7660 IntOp $R2 $R2 + 1 ; Increment the counter 7661 ClearErrors 7662 ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2" 7663 ${If} ${Errors} 7664 ${ExitDo} 7665 ${EndIf} 7666 7667 ${If} ${FileExists} "$SMPROGRAMS\$R5" 7668 ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5" 7669 Pop $R4 7670 ${GetLongPath} "$R4" $R4 7671 ${If} "$R4" == "$R9" ; link path == install path 7672 ApplicationID::Set "$SMPROGRAMS\$R5" "$R8" "true" 7673 Pop $R4 7674 ${EndIf} 7675 ${EndIf} 7676 ${Loop} 7677 7678 ; Update the Quick Launch shortcuts' App ID for this application 7679 StrCpy $R2 -1 7680 ${Do} 7681 IntOp $R2 $R2 + 1 ; Increment the counter 7682 ClearErrors 7683 ReadINIStr $R5 "$R6" "QUICKLAUNCH" "Shortcut$R2" 7684 ${If} ${Errors} 7685 ${ExitDo} 7686 ${EndIf} 7687 7688 ${If} ${FileExists} "$QUICKLAUNCH\$R5" 7689 ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R5" 7690 Pop $R4 7691 ${GetLongPath} "$R4" $R4 7692 ${If} "$R4" == "$R9" ; link path == install path 7693 ApplicationID::Set "$QUICKLAUNCH\$R5" "$R8" "true" 7694 Pop $R4 7695 ${EndIf} 7696 ${EndIf} 7697 ${Loop} 7698 7699 ; Update the Start Menu Programs shortcuts' App ID for this application 7700 ClearErrors 7701 ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir" 7702 ${Unless} ${Errors} 7703 ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7 7704 ${Unless} "$R7" == "" 7705 StrCpy $R2 -1 7706 ${Do} 7707 IntOp $R2 $R2 + 1 ; Increment the counter 7708 ClearErrors 7709 ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2" 7710 ${If} ${Errors} 7711 ${ExitDo} 7712 ${EndIf} 7713 7714 ${If} ${FileExists} "$R7\$R5" 7715 ShellLink::GetShortCutTarget "$R7\$R5" 7716 Pop $R4 7717 ${GetLongPath} "$R4" $R4 7718 ${If} "$R4" == "$R9" ; link path == install path 7719 ApplicationID::Set "$R7\$R5" "$R8" "true" 7720 Pop $R4 7721 ${EndIf} 7722 ${EndIf} 7723 ${Loop} 7724 ${EndUnless} 7725 ${EndUnless} 7726 ${EndIf} 7727 7728 StrCpy $R7 "$QUICKLAUNCH\User Pinned" 7729 StrCpy $R3 "false" 7730 7731 ; $R9 = main application executable path 7732 ; $R8 = appid 7733 ; $R7 = user pinned path 7734 ; $R6 = find handle 7735 ; $R5 = found filename 7736 ; $R4 = GetShortCutTarget result 7737 7738 ; TaskBar links 7739 FindFirst $R6 $R5 "$R7\TaskBar\*.lnk" 7740 ${Do} 7741 ${If} ${FileExists} "$R7\TaskBar\$R5" 7742 ShellLink::GetShortCutTarget "$R7\TaskBar\$R5" 7743 Pop $R4 7744 ${If} "$R4" == "$R9" ; link path == install path 7745 ApplicationID::Set "$R7\TaskBar\$R5" "$R8" "true" 7746 Pop $R4 ; pop Set result off the stack 7747 StrCpy $R3 "true" 7748 ${EndIf} 7749 ${EndIf} 7750 ClearErrors 7751 FindNext $R6 $R5 7752 ${If} ${Errors} 7753 ${ExitDo} 7754 ${EndIf} 7755 ${Loop} 7756 FindClose $R6 7757 7758 ; Start menu links 7759 FindFirst $R6 $R5 "$R7\StartMenu\*.lnk" 7760 ${Do} 7761 ${If} ${FileExists} "$R7\StartMenu\$R5" 7762 ShellLink::GetShortCutTarget "$R7\StartMenu\$R5" 7763 Pop $R4 7764 ${If} "$R4" == "$R9" ; link path == install path 7765 ApplicationID::Set "$R7\StartMenu\$R5" "$R8" "true" 7766 Pop $R4 ; pop Set result off the stack 7767 StrCpy $R3 "true" 7768 ${EndIf} 7769 ${EndIf} 7770 ClearErrors 7771 FindNext $R6 $R5 7772 ${If} ${Errors} 7773 ${ExitDo} 7774 ${EndIf} 7775 ${Loop} 7776 FindClose $R6 7777 ${EndIf} 7778 7779 ClearErrors 7780 7781 StrCpy $R9 $R3 7782 7783 Pop $R2 7784 Pop $R3 ; stack: $R4, $R5, $R6, $R7, $R8, $R9 7785 Pop $R4 ; stack: $R5, $R6, $R7, $R8, $R9 7786 Pop $R5 ; stack: $R6, $R7, $R8, $R9 7787 Pop $R6 ; stack: $R7, $R8, $R9 7788 Pop $R7 ; stack: $R8, $R9 7789 Exch $R8 ; stack: appid, $R9 | $R8 = old $R8 7790 Exch 1 ; stack: $R9, appid 7791 Exch $R9 ; stack: path, appid | $R9 = old $R9 7792 FunctionEnd 7793 7794 !verbose pop 7795 !endif 7796!macroend 7797 7798!macro UpdateShortcutAppModelIDsCall _EXE_PATH _APP_ID _RESULT 7799 !verbose push 7800 !verbose ${_MOZFUNC_VERBOSE} 7801 Push "${_APP_ID}" 7802 Push "${_EXE_PATH}" 7803 Call UpdateShortcutAppModelIDs 7804 Pop ${_RESULT} 7805 !verbose pop 7806!macroend 7807 7808!macro IsUserAdmin 7809 ; Copied from: http://nsis.sourceforge.net/IsUserAdmin 7810 Function IsUserAdmin 7811 Push $R0 7812 Push $R1 7813 Push $R2 7814 7815 ClearErrors 7816 UserInfo::GetName 7817 IfErrors Win9x 7818 Pop $R1 7819 UserInfo::GetAccountType 7820 Pop $R2 7821 7822 StrCmp $R2 "Admin" 0 Continue 7823 StrCpy $R0 "true" 7824 Goto Done 7825 7826 Continue: 7827 7828 StrCmp $R2 "" Win9x 7829 StrCpy $R0 "false" 7830 Goto Done 7831 7832 Win9x: 7833 StrCpy $R0 "true" 7834 7835 Done: 7836 Pop $R2 7837 Pop $R1 7838 Exch $R0 7839 FunctionEnd 7840!macroend 7841 7842/** 7843 * Retrieve if present or generate and store a 64 bit hash of an install path 7844 * using the City Hash algorithm. On return the resulting id is saved in the 7845 * $AppUserModelID variable declared by inserting this macro. InitHashAppModelId 7846 * will attempt to load from HKLM/_REG_PATH first, then HKCU/_REG_PATH. If found 7847 * in either it will return the hash it finds. If not found it will generate a 7848 * new hash and attempt to store the hash in HKLM/_REG_PATH, then HKCU/_REG_PATH. 7849 * Subsequent calls will then retreive the stored hash value. On any failure, 7850 * $AppUserModelID will be set to an empty string. 7851 * 7852 * Registry format: root/_REG_PATH/"_EXE_PATH" = "hash" 7853 * 7854 * @param _EXE_PATH 7855 * The main application executable path 7856 * @param _REG_PATH 7857 * The HKLM/HKCU agnostic registry path where the key hash should 7858 * be stored. ex: "Software\Mozilla\Firefox\TaskBarIDs" 7859 * @result (Var) $AppUserModelID contains the app model id. 7860 */ 7861!macro InitHashAppModelId 7862 !ifndef ${_MOZFUNC_UN}InitHashAppModelId 7863 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 7864 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 7865 !undef _MOZFUNC_UN 7866 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 7867 !undef _MOZFUNC_UN_TMP 7868 7869 !ifndef InitHashAppModelId 7870 Var AppUserModelID 7871 !endif 7872 7873 !verbose push 7874 !verbose ${_MOZFUNC_VERBOSE} 7875 !define ${_MOZFUNC_UN}InitHashAppModelId "!insertmacro ${_MOZFUNC_UN}InitHashAppModelIdCall" 7876 7877 Function ${_MOZFUNC_UN}InitHashAppModelId 7878 ; stack: apppath, regpath 7879 Exch $R9 ; stack: $R9, regpath | $R9 = apppath 7880 Exch 1 ; stack: regpath, $R9 7881 Exch $R8 ; stack: $R8, $R9 | $R8 = regpath 7882 Push $R7 7883 7884 ${If} ${AtLeastWin7} 7885 ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 7886 ; Always create a new AppUserModelID and overwrite the existing one 7887 ; for the current installation path. 7888 CityHash::GetCityHash64 "$R9" 7889 Pop $AppUserModelID 7890 ${If} $AppUserModelID == "error" 7891 GoTo end 7892 ${EndIf} 7893 ClearErrors 7894 WriteRegStr HKLM "$R8" "$R9" "$AppUserModelID" 7895 ${If} ${Errors} 7896 ClearErrors 7897 WriteRegStr HKCU "$R8" "$R9" "$AppUserModelID" 7898 ${If} ${Errors} 7899 StrCpy $AppUserModelID "error" 7900 ${EndIf} 7901 ${EndIf} 7902 ${EndIf} 7903 7904 end: 7905 ${If} "$AppUserModelID" == "error" 7906 StrCpy $AppUserModelID "" 7907 ${EndIf} 7908 7909 ClearErrors 7910 Pop $R7 7911 Exch $R8 7912 Exch 1 7913 Exch $R9 7914 FunctionEnd 7915 7916 !verbose pop 7917 !endif 7918!macroend 7919 7920!macro InitHashAppModelIdCall _EXE_PATH _REG_PATH 7921 !verbose push 7922 !verbose ${_MOZFUNC_VERBOSE} 7923 Push "${_REG_PATH}" 7924 Push "${_EXE_PATH}" 7925 Call InitHashAppModelId 7926 !verbose pop 7927!macroend 7928 7929!macro un.InitHashAppModelIdCall _EXE_PATH _REG_PATH 7930 !verbose push 7931 !verbose ${_MOZFUNC_VERBOSE} 7932 Push "${_REG_PATH}" 7933 Push "${_EXE_PATH}" 7934 Call un.InitHashAppModelId 7935 !verbose pop 7936!macroend 7937 7938!macro un.InitHashAppModelId 7939 !ifndef un.InitHashAppModelId 7940 !verbose push 7941 !verbose ${_MOZFUNC_VERBOSE} 7942 !undef _MOZFUNC_UN 7943 !define _MOZFUNC_UN "un." 7944 7945 !insertmacro InitHashAppModelId 7946 7947 !undef _MOZFUNC_UN 7948 !define _MOZFUNC_UN 7949 !verbose pop 7950 !endif 7951!macroend 7952 7953/** 7954 * Try to locate the default profile of this install from AppUserModelID 7955 * using installs.ini. 7956 * FIXME This could instead use the Install<AUMID> entries in profiles.ini? 7957 * 7958 * - `SetShellVarContext current` must be called before this macro so 7959 * $APPDATA gets the current user's data. 7960 * - InitHashAppModelId must have been called before this macro to set 7961 * $AppUserModelID 7962 * 7963 * @result: Path of the profile directory (not checked for existence), 7964 * or "" if not found, left on top of the stack. 7965 */ 7966!macro FindInstallSpecificProfileMaybeUn _MOZFUNC_UN 7967 Push $R0 7968 Push $0 7969 Push $1 7970 Push $2 7971 7972 StrCpy $R0 "" 7973 ; Look for an install-specific profile, which might be listed as 7974 ; either a relative or an absolute path (installs.ini doesn't say which). 7975 ${If} ${FileExists} "$APPDATA\Mozilla\Firefox\installs.ini" 7976 ClearErrors 7977 ReadINIStr $1 "$APPDATA\Mozilla\Firefox\installs.ini" "$AppUserModelID" "Default" 7978 ${IfNot} ${Errors} 7979 ${${_MOZFUNC_UN}GetLongPath} "$APPDATA\Mozilla\Firefox\$1" $2 7980 ${If} ${FileExists} $2 7981 StrCpy $R0 $2 7982 ${Else} 7983 ${${_MOZFUNC_UN}GetLongPath} "$1" $2 7984 ${If} ${FileExists} $2 7985 StrCpy $R0 $2 7986 ${EndIf} 7987 ${EndIf} 7988 ${EndIf} 7989 ${EndIf} 7990 7991 Pop $2 7992 Pop $1 7993 Pop $0 7994 Exch $R0 7995!macroend 7996!define FindInstallSpecificProfile "!insertmacro FindInstallSpecificProfileMaybeUn ''" 7997!define un.FindInstallSpecificProfile "!insertmacro FindInstallSpecificProfileMaybeUn un." 7998 7999/** 8000 * Copy the post-signing data, which was left alongside the installer 8001 * by the self-extractor stub, into the global location for this data. 8002 * 8003 * If the post-signing data file doesn't exist, or is empty, "0" is 8004 * pushed on the stack, and nothing is copied. 8005 * Otherwise the first line of the post-signing data (including newline, 8006 * if any) is pushed on the stack. 8007 */ 8008!macro CopyPostSigningData 8009 !ifndef CopyPostSigningData 8010 !verbose push 8011 !verbose ${_MOZFUNC_VERBOSE} 8012 !define CopyPostSigningData "Call CopyPostSigningData" 8013 8014 Function CopyPostSigningData 8015 Push $0 ; Stack: old $0 8016 8017 ${LineRead} "$EXEDIR\postSigningData" "1" $0 8018 ${If} ${Errors} 8019 ClearErrors 8020 StrCpy $0 "0" 8021 ${Else} 8022 CreateDirectory "$LOCALAPPDATA\Mozilla\Firefox" 8023 CopyFiles /SILENT "$EXEDIR\postSigningData" "$LOCALAPPDATA\Mozilla\Firefox" 8024 ${Endif} 8025 8026 Exch $0 ; Stack: postSigningData 8027 FunctionEnd 8028 8029 !verbose pop 8030 !endif 8031!macroend 8032 8033################################################################################ 8034# Helpers for taskbar progress 8035 8036!ifndef CLSCTX_INPROC_SERVER 8037 !define CLSCTX_INPROC_SERVER 1 8038!endif 8039 8040!define CLSID_ITaskbarList {56fdf344-fd6d-11d0-958a-006097c9a090} 8041!define IID_ITaskbarList3 {ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf} 8042!define ITaskbarList3->SetProgressValue $ITaskbarList3->9 8043!define ITaskbarList3->SetProgressState $ITaskbarList3->10 8044 8045/** 8046 * Creates a single uninitialized object of the ITaskbarList class with a 8047 * reference to the ITaskbarList3 interface. This object can be used to set 8048 * progress and state on the installer's taskbar icon using the helper macros 8049 * in this section. 8050 */ 8051!macro ITBL3Create 8052 8053 !ifndef ${_MOZFUNC_UN}ITBL3Create 8054 Var ITaskbarList3 8055 8056 !verbose push 8057 !verbose ${_MOZFUNC_VERBOSE} 8058 !define ${_MOZFUNC_UN}ITBL3Create "!insertmacro ${_MOZFUNC_UN}ITBL3CreateCall" 8059 8060 Function ${_MOZFUNC_UN}ITBL3Create 8061 ; Setting to 0 allows the helper macros to detect when the object was not 8062 ; created. 8063 StrCpy $ITaskbarList3 0 8064 ; Don't create when running silently. 8065 ${Unless} ${Silent} 8066 ; This is only supported on Win 7 and above. 8067 ${If} ${AtLeastWin7} 8068 System::Call "ole32::CoCreateInstance(g '${CLSID_ITaskbarList}', \ 8069 i 0, \ 8070 i ${CLSCTX_INPROC_SERVER}, \ 8071 g '${IID_ITaskbarList3}', \ 8072 *i .s)" 8073 Pop $ITaskbarList3 8074 ${EndIf} 8075 ${EndUnless} 8076 FunctionEnd 8077 8078 !verbose pop 8079 !endif 8080!macroend 8081 8082!macro ITBL3CreateCall 8083 !verbose push 8084 !verbose ${_MOZFUNC_VERBOSE} 8085 Call ITBL3Create 8086 !verbose pop 8087!macroend 8088 8089!macro un.ITBL3CreateCall _PATH_TO_IMAGE 8090 !verbose push 8091 !verbose ${_MOZFUNC_VERBOSE} 8092 Call un.ITBL3Create 8093 !verbose pop 8094!macroend 8095 8096!macro un.ITBL3Create 8097 !ifndef un.ITBL3Create 8098 !verbose push 8099 !verbose ${_MOZFUNC_VERBOSE} 8100 !undef _MOZFUNC_UN 8101 !define _MOZFUNC_UN "un." 8102 8103 !insertmacro ITBL3Create 8104 8105 !undef _MOZFUNC_UN 8106 !define _MOZFUNC_UN 8107 !verbose pop 8108 !endif 8109!macroend 8110 8111/** 8112 * Sets the percentage completed on the taskbar process icon progress indicator. 8113 * 8114 * @param _COMPLETED 8115 * The proportion of the operation that has been completed in relation 8116 * to _TOTAL. 8117 * @param _TOTAL 8118 * The value _COMPLETED will have when the operation has completed. 8119 * 8120 * $R8 = _COMPLETED 8121 * $R9 = _TOTAL 8122 */ 8123!macro ITBL3SetProgressValueCall _COMPLETED _TOTAL 8124 Push ${_COMPLETED} 8125 Push ${_TOTAL} 8126 ${CallArtificialFunction} ITBL3SetProgressValue_ 8127!macroend 8128 8129!define ITBL3SetProgressValue "!insertmacro ITBL3SetProgressValueCall" 8130!define un.ITBL3SetProgressValue "!insertmacro ITBL3SetProgressValueCall" 8131 8132!macro ITBL3SetProgressValue_ 8133 Exch $R9 8134 Exch 1 8135 Exch $R8 8136 ${If} $ITaskbarList3 <> 0 8137 System::Call "${ITaskbarList3->SetProgressValue}(i$HWNDPARENT, l$R8, l$R9)" 8138 ${EndIf} 8139 Exch $R8 8140 Exch 1 8141 Exch $R9 8142!macroend 8143 8144; Normal state / no progress bar 8145!define TBPF_NOPROGRESS 0x00000000 8146; Marquee style progress bar 8147!define TBPF_INDETERMINATE 0x00000001 8148; Standard progress bar 8149!define TBPF_NORMAL 0x00000002 8150; Red taskbar button to indicate an error occurred 8151!define TBPF_ERROR 0x00000004 8152; Yellow taskbar button to indicate user attention (input) is required to 8153; resume progress 8154!define TBPF_PAUSED 0x00000008 8155 8156/** 8157 * Sets the state on the taskbar process icon progress indicator. 8158 * 8159 * @param _STATE 8160 * The state to set on the taskbar icon progress indicator. Only one of 8161 * the states defined above should be specified. 8162 * 8163 * $R9 = _STATE 8164 */ 8165!macro ITBL3SetProgressStateCall _STATE 8166 Push ${_STATE} 8167 ${CallArtificialFunction} ITBL3SetProgressState_ 8168!macroend 8169 8170!define ITBL3SetProgressState "!insertmacro ITBL3SetProgressStateCall" 8171!define un.ITBL3SetProgressState "!insertmacro ITBL3SetProgressStateCall" 8172 8173!macro ITBL3SetProgressState_ 8174 Exch $R9 8175 ${If} $ITaskbarList3 <> 0 8176 System::Call "${ITaskbarList3->SetProgressState}(i$HWNDPARENT, i$R9)" 8177 ${EndIf} 8178 Exch $R9 8179!macroend 8180 8181################################################################################ 8182# Helpers for the new user interface 8183 8184!ifndef MAXDWORD 8185 !define MAXDWORD 0xffffffff 8186!endif 8187 8188!ifndef DT_WORDBREAK 8189 !define DT_WORDBREAK 0x0010 8190!endif 8191!ifndef DT_SINGLELINE 8192 !define DT_SINGLELINE 0x0020 8193!endif 8194!ifndef DT_NOCLIP 8195 !define DT_NOCLIP 0x0100 8196!endif 8197!ifndef DT_CALCRECT 8198 !define DT_CALCRECT 0x0400 8199!endif 8200!ifndef DT_EDITCONTROL 8201 !define DT_EDITCONTROL 0x2000 8202!endif 8203!ifndef DT_RTLREADING 8204 !define DT_RTLREADING 0x00020000 8205!endif 8206!ifndef DT_NOFULLWIDTHCHARBREAK 8207 !define DT_NOFULLWIDTHCHARBREAK 0x00080000 8208!endif 8209 8210!define /ifndef GWL_STYLE -16 8211!define /ifndef GWL_EXSTYLE -20 8212 8213!ifndef WS_EX_NOINHERITLAYOUT 8214 !define WS_EX_NOINHERITLAYOUT 0x00100000 8215!endif 8216 8217!ifndef PBS_MARQUEE 8218 !define PBS_MARQUEE 0x08 8219!endif 8220 8221!ifndef PBM_SETRANGE32 8222 !define PBM_SETRANGE32 0x406 8223!endif 8224!ifndef PBM_GETRANGE 8225 !define PBM_GETRANGE 0x407 8226!endif 8227 8228!ifndef SHACF_FILESYSTEM 8229 !define SHACF_FILESYSTEM 1 8230!endif 8231 8232!define MOZ_LOADTRANSPARENT ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS} 8233 8234; Extend nsDialogs.nsh to support creating centered labels if it is already 8235; included 8236!ifmacrodef __NSD_DefineControl 8237!insertmacro __NSD_DefineControl LabelCenter 8238!define __NSD_LabelCenter_CLASS STATIC 8239!define __NSD_LabelCenter_STYLE ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_CENTER} 8240!define __NSD_LabelCenter_EXSTYLE ${WS_EX_TRANSPARENT} 8241!endif 8242 8243/** 8244 * Draws an image file (BMP, GIF, or JPG) onto a bitmap control, with scaling. 8245 * Adapted from https://stackoverflow.com/a/13405711/1508094 8246 * 8247 * @param CONTROL bitmap control created by NSD_CreateBitmap 8248 * @param IMAGE path to image file to draw to the bitmap 8249 * @param HANDLE output bitmap handle which must be freed via NSD_FreeImage 8250 * after nsDialogs::Show has been called 8251 */ 8252!macro __SetStretchedImageOLE CONTROL IMAGE HANDLE 8253 !ifndef IID_IPicture 8254 !define IID_IPicture {7BF80980-BF32-101A-8BBB-00AA00300CAB} 8255 !endif 8256 !ifndef SRCCOPY 8257 !define SRCCOPY 0xCC0020 8258 !endif 8259 !ifndef HALFTONE 8260 !define HALFTONE 4 8261 !endif 8262 !ifndef IMAGE_BITMAP 8263 !define IMAGE_BITMAP 0 8264 !endif 8265 8266 Push $0 ; HANDLE 8267 Push $1 ; memory DC 8268 Push $2 ; IPicture created from IMAGE 8269 Push $3 ; HBITMAP obtained from $2 8270 Push $4 ; BITMAPINFO obtained from $3 8271 Push $5 ; width of IMAGE 8272 Push $6 ; height of IMAGE 8273 Push $7 ; width of CONTROL 8274 Push $8 ; height of CONTROL 8275 Push $R0 ; CONTROL 8276 8277 StrCpy $R0 ${CONTROL} ; in case ${CONTROL} is $0 8278 StrCpy $7 "" 8279 StrCpy $8 "" 8280 8281 System::Call '*(i, i, i, i) i.s' 8282 Pop $0 8283 8284 ${If} $0 <> 0 8285 System::Call 'user32::GetClientRect(i R0, i r0)' 8286 System::Call '*$0(i, i, i .s, i .s)' 8287 System::Free $0 8288 Pop $7 8289 Pop $8 8290 ${EndIf} 8291 8292 ${If} $7 > 0 8293 ${AndIf} $8 > 0 8294 System::Call 'oleaut32::OleLoadPicturePath(w"${IMAGE}",i0,i0,i0,g"${IID_IPicture}",*i.r2)i.r1' 8295 ${If} $1 = 0 8296 System::Call 'user32::GetDC(i0)i.s' 8297 System::Call 'gdi32::CreateCompatibleDC(iss)i.r1' 8298 System::Call 'gdi32::CreateCompatibleBitmap(iss,ir7,ir8)i.r0' 8299 System::Call 'user32::ReleaseDC(i0,is)' 8300 System::Call '$2->3(*i.r3)i.r4' ; IPicture->get_Handle 8301 ${If} $4 = 0 8302 System::Call 'gdi32::SetStretchBltMode(ir1,i${HALFTONE})' 8303 System::Call '*(&i40,&i1024)i.r4' ; BITMAP / BITMAPINFO 8304 System::Call 'gdi32::GetObject(ir3,i24,ir4)' 8305 System::Call 'gdi32::SelectObject(ir1,ir0)i.s' 8306 System::Call '*$4(i40,i.r5,i.r6,i0,i,i.s)' ; Grab size and bits-ptr AND init as BITMAPINFOHEADER 8307 System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFOHEADER 8308 System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFO 8309 System::Call 'gdi32::StretchDIBits(ir1,i0,i0,ir7,ir8,i0,i0,ir5,ir6,is,ir4,i0,i${SRCCOPY})' 8310 System::Call 'gdi32::SelectObject(ir1,is)' 8311 System::Free $4 8312 SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0 8313 ${EndIf} 8314 System::Call 'gdi32::DeleteDC(ir1)' 8315 System::Call '$2->2()' ; IPicture->release() 8316 ${EndIf} 8317 ${EndIf} 8318 8319 Pop $R0 8320 Pop $8 8321 Pop $7 8322 Pop $6 8323 Pop $5 8324 Pop $4 8325 Pop $3 8326 Pop $2 8327 Pop $1 8328 Exch $0 8329 Pop ${HANDLE} 8330!macroend 8331!define SetStretchedImageOLE "!insertmacro __SetStretchedImageOLE" 8332 8333/** 8334 * Display a task dialog box with custom strings and button labels. 8335 * 8336 * The task dialog is highly customizable. The specific style being used here 8337 * is similar to a MessageBox except that the button text is customizable. 8338 * MessageBox-style buttons are used instead of command link buttons; this can 8339 * be made configurable if command buttons are needed. 8340 * 8341 * See https://msdn.microsoft.com/en-us/library/windows/desktop/bb760544.aspx 8342 * for the TaskDialogIndirect function's documentation, and links to definitions 8343 * of the TASKDIALOGCONFIG and TASKDIALOG_BUTTON structures it uses. 8344 * 8345 * @param INSTRUCTION Dialog header string; use empty string if unneeded 8346 * @param CONTENT Secondary message string; use empty string if unneeded 8347 * @param BUTTON1 Text for the first button, the one selected by default 8348 * @param BUTTON2 Text for the second button 8349 * 8350 * @return One of the following values will be left on the stack: 8351 * 1001 if the first button was clicked 8352 * 1002 if the second button was clicked 8353 * 2 (IDCANCEL) if the dialog was closed 8354 * 0 on error 8355 */ 8356!macro _ShowTaskDialog INSTRUCTION CONTENT BUTTON1 BUTTON2 8357 !ifndef SIZEOF_TASKDIALOGCONFIG_32BIT 8358 !define SIZEOF_TASKDIALOGCONFIG_32BIT 96 8359 !endif 8360 !ifndef TDF_ALLOW_DIALOG_CANCELLATION 8361 !define TDF_ALLOW_DIALOG_CANCELLATION 0x0008 8362 !endif 8363 !ifndef TDF_RTL_LAYOUT 8364 !define TDF_RTL_LAYOUT 0x02000 8365 !endif 8366 !ifndef TD_WARNING_ICON 8367 !define TD_WARNING_ICON 0x0FFFF 8368 !endif 8369 8370 Push $0 ; return value 8371 Push $1 ; TASKDIALOGCONFIG struct 8372 Push $2 ; TASKDIALOG_BUTTON array 8373 Push $3 ; dwFlags member of the TASKDIALOGCONFIG 8374 8375 StrCpy $3 ${TDF_ALLOW_DIALOG_CANCELLATION} 8376 !ifdef ${AB_CD}_rtl 8377 IntOp $3 $3 | ${TDF_RTL_LAYOUT} 8378 !endif 8379 8380 ; Build an array of two TASKDIALOG_BUTTON structs 8381 System::Call "*(i 1001, \ 8382 w '${BUTTON1}', \ 8383 i 1002, \ 8384 w '${BUTTON2}' \ 8385 ) p.r2" 8386 ; Build a TASKDIALOGCONFIG struct 8387 System::Call "*(i ${SIZEOF_TASKDIALOGCONFIG_32BIT}, \ 8388 p $HWNDPARENT, \ 8389 p 0, \ 8390 i $3, \ 8391 i 0, \ 8392 w '$(INSTALLER_WIN_CAPTION)', \ 8393 p ${TD_WARNING_ICON}, \ 8394 w '${INSTRUCTION}', \ 8395 w '${CONTENT}', \ 8396 i 2, \ 8397 p r2, \ 8398 i 1001, \ 8399 i 0, \ 8400 p 0, \ 8401 i 0, \ 8402 p 0, \ 8403 p 0, \ 8404 p 0, \ 8405 p 0, \ 8406 p 0, \ 8407 p 0, \ 8408 p 0, \ 8409 p 0, \ 8410 i 0 \ 8411 ) p.r1" 8412 System::Call "comctl32::TaskDialogIndirect(p r1, *i 0 r0, p 0, p 0)" 8413 System::Free $1 8414 System::Free $2 8415 8416 Pop $3 8417 Pop $2 8418 Pop $1 8419 Exch $0 8420!macroend 8421!define ShowTaskDialog "!insertmacro _ShowTaskDialog" 8422 8423/** 8424 * Removes a single style from a control. 8425 * 8426 * _HANDLE the handle of the control 8427 * _STYLE the style to remove 8428 */ 8429!macro _RemoveStyle _HANDLE _STYLE 8430 Push $0 8431 8432 System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}) i .r0' 8433 IntOp $0 $0 | ${_STYLE} 8434 IntOp $0 $0 - ${_STYLE} 8435 System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}, i r0)' 8436 8437 Pop $0 8438!macroend 8439!define RemoveStyle "!insertmacro _RemoveStyle" 8440 8441/** 8442 * Adds a single extended style to a control. 8443 * 8444 * _HANDLE the handle of the control 8445 * _EXSTYLE the extended style to add 8446 */ 8447!macro _AddExStyle _HANDLE _EXSTYLE 8448 Push $0 8449 8450 System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}) i .r0' 8451 IntOp $0 $0 | ${_EXSTYLE} 8452 System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}, i r0)' 8453 8454 Pop $0 8455!macroend 8456!define AddExStyle "!insertmacro _AddExStyle" 8457 8458/** 8459 * Removes a single extended style from a control. 8460 * 8461 * _HANDLE the handle of the control 8462 * _EXSTYLE the extended style to remove 8463 */ 8464!macro _RemoveExStyle _HANDLE _EXSTYLE 8465 Push $0 8466 8467 System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}) i .r0' 8468 IntOp $0 $0 | ${_EXSTYLE} 8469 IntOp $0 $0 - ${_EXSTYLE} 8470 System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}, i r0)' 8471 8472 Pop $0 8473!macroend 8474!define RemoveExStyle "!insertmacro _RemoveExStyle" 8475 8476/** 8477 * Set the necessary styles to configure the given window as right-to-left 8478 * 8479 * _HANDLE the handle of the control to configure 8480 */ 8481!macro _MakeWindowRTL _HANDLE 8482 !define /ifndef WS_EX_RIGHT 0x00001000 8483 !define /ifndef WS_EX_LEFT 0x00000000 8484 !define /ifndef WS_EX_RTLREADING 0x00002000 8485 !define /ifndef WS_EX_LTRREADING 0x00000000 8486 !define /ifndef WS_EX_LAYOUTRTL 0x00400000 8487 8488 ${AddExStyle} ${_HANDLE} ${WS_EX_LAYOUTRTL} 8489 ${RemoveExStyle} ${_HANDLE} ${WS_EX_RTLREADING} 8490 ${RemoveExStyle} ${_HANDLE} ${WS_EX_RIGHT} 8491 ${AddExStyle} ${_HANDLE} ${WS_EX_LEFT}|${WS_EX_LTRREADING} 8492!macroend 8493!define MakeWindowRTL "!insertmacro _MakeWindowRTL" 8494 8495/** 8496 * Gets the extent of the specified text in pixels for sizing a control. 8497 * 8498 * _TEXT the text to get the text extent for 8499 * _FONT the font to use when getting the text extent 8500 * _RES_WIDTH return value - control width for the text 8501 * _RES_HEIGHT return value - control height for the text 8502 */ 8503!macro GetTextExtentCall _TEXT _FONT _RES_WIDTH _RES_HEIGHT 8504 Push "${_TEXT}" 8505 Push "${_FONT}" 8506 ${CallArtificialFunction} GetTextExtent_ 8507 Pop ${_RES_WIDTH} 8508 Pop ${_RES_HEIGHT} 8509!macroend 8510 8511!define GetTextExtent "!insertmacro GetTextExtentCall" 8512!define un.GetTextExtent "!insertmacro GetTextExtentCall" 8513 8514!macro GetTextExtent_ 8515 Exch $0 ; font 8516 Exch 1 8517 Exch $1 ; text 8518 Push $2 8519 Push $3 8520 Push $4 8521 Push $5 8522 Push $6 8523 Push $7 8524 8525 ; Reuse the existing NSIS control which is used for BrandingText instead of 8526 ; creating a new control. 8527 GetDlgItem $2 $HWNDPARENT 1028 8528 8529 System::Call 'user32::GetDC(i r2) i .r3' 8530 System::Call 'gdi32::SelectObject(i r3, i r0)' 8531 8532 StrLen $4 "$1" 8533 8534 System::Call '*(i, i) i .r5' 8535 System::Call 'gdi32::GetTextExtentPoint32W(i r3, t$\"$1$\", i r4, i r5)' 8536 System::Call '*$5(i .r6, i .r7)' 8537 System::Free $5 8538 8539 System::Call 'user32::ReleaseDC(i r2, i r3)' 8540 8541 StrCpy $1 $7 8542 StrCpy $0 $6 8543 8544 Pop $7 8545 Pop $6 8546 Pop $5 8547 Pop $4 8548 Pop $3 8549 Pop $2 8550 Exch $1 ; return height 8551 Exch 1 8552 Exch $0 ; return width 8553!macroend 8554 8555/** 8556 * Gets the width and the height of a control in pixels. 8557 * 8558 * _HANDLE the handle of the control 8559 * _RES_WIDTH return value - control width for the text 8560 * _RES_HEIGHT return value - control height for the text 8561 */ 8562!macro GetDlgItemWidthHeightCall _HANDLE _RES_WIDTH _RES_HEIGHT 8563 Push "${_HANDLE}" 8564 ${CallArtificialFunction} GetDlgItemWidthHeight_ 8565 Pop ${_RES_WIDTH} 8566 Pop ${_RES_HEIGHT} 8567!macroend 8568 8569!define GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall" 8570!define un.GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall" 8571 8572!macro GetDlgItemWidthHeight_ 8573 Exch $0 ; handle for the control 8574 Push $1 8575 Push $2 8576 8577 System::Call '*(i, i, i, i) i .r2' 8578 ; The left and top values will always be 0 so the right and bottom values 8579 ; will be the width and height. 8580 System::Call 'user32::GetClientRect(i r0, i r2)' 8581 System::Call '*$2(i, i, i .r0, i .r1)' 8582 System::Free $2 8583 8584 Pop $2 8585 Exch $1 ; return height 8586 Exch 1 8587 Exch $0 ; return width 8588!macroend 8589 8590/** 8591 * Gets the number of pixels from the beginning of the dialog to the end of a 8592 * control in a RTL friendly manner. 8593 * 8594 * _HANDLE the handle of the control 8595 * _RES_PX return value - pixels from the beginning of the dialog to the end of 8596 * the control 8597 */ 8598!macro GetDlgItemEndPXCall _HANDLE _RES_PX 8599 Push "${_HANDLE}" 8600 ${CallArtificialFunction} GetDlgItemEndPX_ 8601 Pop ${_RES_PX} 8602!macroend 8603 8604!define GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall" 8605!define un.GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall" 8606 8607!macro GetDlgItemEndPX_ 8608 Exch $0 ; handle of the control 8609 Push $1 8610 Push $2 8611 8612 ; #32770 is the dialog class 8613 FindWindow $1 "#32770" "" $HWNDPARENT 8614 System::Call '*(i, i, i, i) i .r2' 8615 System::Call 'user32::GetWindowRect(i r0, i r2)' 8616 System::Call 'user32::MapWindowPoints(i 0, i r1,i r2, i 2)' 8617 System::Call '*$2(i, i, i .r0, i)' 8618 System::Free $2 8619 8620 Pop $2 8621 Pop $1 8622 Exch $0 ; pixels from the beginning of the dialog to the end of the control 8623!macroend 8624 8625/** 8626 * Gets the number of pixels from the top of a dialog to the bottom of a control 8627 * 8628 * _CONTROL the handle of the control 8629 * _RES_PX return value - pixels from the top of the dialog to the bottom 8630 * of the control 8631 */ 8632!macro GetDlgItemBottomPXCall _CONTROL _RES_PX 8633 Push "${_CONTROL}" 8634 ${CallArtificialFunction} GetDlgItemBottomPX_ 8635 Pop ${_RES_PX} 8636!macroend 8637 8638!define GetDlgItemBottomPX "!insertmacro GetDlgItemBottomPXCall" 8639!define un.GetDlgItemBottomPX "!insertmacro GetDlgItemBottomPXCall" 8640 8641!macro GetDlgItemBottomPX_ 8642 Exch $0 ; handle of the control 8643 Push $1 8644 Push $2 8645 8646 ; #32770 is the dialog class 8647 FindWindow $1 "#32770" "" $HWNDPARENT 8648 System::Call '*(i, i, i, i) i .r2' 8649 System::Call 'user32::GetWindowRect(i r0, i r2)' 8650 System::Call 'user32::MapWindowPoints(i 0, i r1, i r2, i 2)' 8651 System::Call '*$2(i, i, i, i .r0)' 8652 System::Free $2 8653 8654 Pop $2 8655 Pop $1 8656 Exch $0 ; pixels from the top of the dialog to the bottom of the control 8657!macroend 8658 8659/** 8660 * Gets the width and height for sizing a control that has the specified text. 8661 * The control's height and width will be dynamically determined for the maximum 8662 * width specified. 8663 * 8664 * _TEXT the text 8665 * _FONT the font to use when getting the width and height 8666 * _MAX_WIDTH the maximum width for the control in pixels 8667 * _RES_WIDTH return value - control width for the text in pixels. 8668 * This might be larger than _MAX_WIDTH if that constraint couldn't 8669 * be satisfied, e.g. a single word that couldn't be broken up is 8670 * longer than _MAX_WIDTH by itself. 8671 * _RES_HEIGHT return value - control height for the text in pixels 8672 */ 8673!macro GetTextWidthHeight 8674 8675 !ifndef ${_MOZFUNC_UN}GetTextWidthHeight 8676 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 8677 !insertmacro ${_MOZFUNC_UN_TMP}WordFind 8678 !undef _MOZFUNC_UN 8679 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 8680 !undef _MOZFUNC_UN_TMP 8681 8682 !verbose push 8683 !verbose ${_MOZFUNC_VERBOSE} 8684 !define ${_MOZFUNC_UN}GetTextWidthHeight "!insertmacro ${_MOZFUNC_UN}GetTextWidthHeightCall" 8685 8686 Function ${_MOZFUNC_UN}GetTextWidthHeight 8687 ; Stack contents after each instruction (top of the stack on the left): 8688 ; _MAX_WIDTH _FONT _TEXT 8689 Exch $0 ; $0 _FONT _TEXT 8690 Exch 1 ; _FONT $0 _TEXT 8691 Exch $1 ; $1 $0 _TEXT 8692 Exch 2 ; _TEXT $0 $1 8693 Exch $2 ; $2 $0 $1 8694 ; That's all the parameters, now save our scratch registers. 8695 Push $3 ; handle to a temporary control for drawing the text into 8696 Push $4 ; DC handle 8697 Push $5 ; string length of the text argument 8698 Push $6 ; RECT struct to call DrawText with 8699 Push $7 ; width returned from DrawText 8700 Push $8 ; height returned from DrawText 8701 Push $9 ; flags to pass to DrawText 8702 8703 StrCpy $9 "${DT_NOCLIP}|${DT_CALCRECT}|${DT_WORDBREAK}" 8704 !ifdef ${AB_CD}_rtl 8705 StrCpy $9 "$9|${DT_RTLREADING}" 8706 !endif 8707 8708 ; Reuse the existing NSIS control which is used for BrandingText instead 8709 ; of creating a new control. 8710 GetDlgItem $3 $HWNDPARENT 1028 8711 8712 System::Call 'user32::GetDC(i r3) i .r4' 8713 System::Call 'gdi32::SelectObject(i r4, i r1)' 8714 8715 StrLen $5 "$2" ; text length 8716 System::Call '*(i, i, i r0, i) i .r6' 8717 8718 System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, i r9)' 8719 System::Call '*$6(i, i, i .r7, i .r8)' 8720 System::Free $6 8721 8722 System::Call 'user32::ReleaseDC(i r3, i r4)' 8723 8724 StrCpy $1 $8 8725 StrCpy $0 $7 8726 8727 ; Restore the values that were in our scratch registers. 8728 Pop $9 8729 Pop $8 8730 Pop $7 8731 Pop $6 8732 Pop $5 8733 Pop $4 8734 Pop $3 8735 ; Restore our parameter registers and return our results. 8736 ; Stack contents after each instruction (top of the stack on the left): 8737 ; $2 $0 $1 8738 Pop $2 ; $0 $1 8739 Exch 1 ; $1 $0 8740 Exch $1 ; _RES_HEIGHT $0 8741 Exch 1 ; $0 _RES_HEIGHT 8742 Exch $0 ; _RES_WIDTH _RES_HEIGHT 8743 FunctionEnd 8744 8745 !verbose pop 8746 !endif 8747!macroend 8748 8749!macro GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT 8750 !verbose push 8751 !verbose ${_MOZFUNC_VERBOSE} 8752 Push "${_TEXT}" 8753 Push "${_FONT}" 8754 Push "${_MAX_WIDTH}" 8755 Call GetTextWidthHeight 8756 Pop ${_RES_WIDTH} 8757 Pop ${_RES_HEIGHT} 8758 !verbose pop 8759!macroend 8760 8761!macro un.GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT 8762 !verbose push 8763 !verbose ${_MOZFUNC_VERBOSE} 8764 Push "${_TEXT}" 8765 Push "${_FONT}" 8766 Push "${_MAX_WIDTH}" 8767 Call un.GetTextWidthHeight 8768 Pop ${_RES_WIDTH} 8769 Pop ${_RES_HEIGHT} 8770 !verbose pop 8771!macroend 8772 8773!macro un.GetTextWidthHeight 8774 !ifndef un.GetTextWidthHeight 8775 !verbose push 8776 !verbose ${_MOZFUNC_VERBOSE} 8777 !undef _MOZFUNC_UN 8778 !define _MOZFUNC_UN "un." 8779 8780 !insertmacro GetTextWidthHeight 8781 8782 !undef _MOZFUNC_UN 8783 !define _MOZFUNC_UN 8784 !verbose pop 8785 !endif 8786!macroend 8787 8788/** 8789 * Convert a number of dialog units to a number of pixels. 8790 * 8791 * _DU Number of dialog units to convert 8792 * _AXIS Which axis you want to convert a value along, X or Y 8793 * _RV Register or variable to return the number of pixels in 8794 */ 8795!macro _DialogUnitsToPixels _DU _AXIS _RV 8796 Push $0 8797 Push $1 8798 8799 ; The dialog units value might be a string ending with a 'u', 8800 ; so convert it to a number. 8801 IntOp $0 "${_DU}" + 0 8802 8803 !if ${_AXIS} == 'Y' 8804 System::Call '*(i 0, i 0, i 0, i r0) i .r1' 8805 System::Call 'user32::MapDialogRect(p $HWNDPARENT, p r1)' 8806 System::Call '*$1(i, i, i, i . r0)' 8807 !else if ${_AXIS} == 'X' 8808 System::Call '*(i 0, i 0, i r0, i 0) i .r1' 8809 System::Call 'user32::MapDialogRect(p $HWNDPARENT, p r1)' 8810 System::Call '*$1(i, i, i . r0, i)' 8811 !else 8812 !error "Invalid axis ${_AXIS} passed to DialogUnitsToPixels; please use X or Y" 8813 !endif 8814 System::Free $1 8815 8816 Pop $1 8817 Exch $0 8818 Pop ${_RV} 8819!macroend 8820!define DialogUnitsToPixels "!insertmacro _DialogUnitsToPixels" 8821 8822/** 8823 * Convert a given left coordinate for a dialog control to flip the control to 8824 * the other side of the dialog if we're using an RTL locale. 8825 * 8826 * _LEFT_DU Number of dialog units to convert 8827 * _WIDTH Width of the control in either pixels or DU's 8828 * If the string has a 'u' on the end, it will be interpreted as 8829 * dialog units, otherwise it will be interpreted as pixels. 8830 * _RV Register or variable to return converted coordinate, in pixels 8831 */ 8832!macro _ConvertLeftCoordForRTLCall _LEFT_DU _WIDTH _RV 8833 Push "${_LEFT_DU}" 8834 Push "${_WIDTH}" 8835 ${CallArtificialFunction} _ConvertLeftCoordForRTL 8836 Pop ${_RV} 8837!macroend 8838 8839!define ConvertLeftCoordForRTL "!insertmacro _ConvertLeftCoordForRTLCall" 8840!define un.ConvertLeftCoordForRTL "!insertmacro _ConvertLeftCoordForRTLCall" 8841 8842!macro _ConvertLeftCoordForRTL 8843 ; Stack contents after each instruction (top of the stack on the left): 8844 ; _WIDTH _LEFT_DU 8845 Exch $0 ; $0 _LEFT_DU 8846 Exch 1 ; _LEFT_DU $0 8847 Exch $1 ; $1 $0 8848 ; That's all the parameters, now save our scratch registers. 8849 Push $2 ; width of the entire dialog, in pixels 8850 Push $3 ; _LEFT_DU converted to pixels 8851 Push $4 ; temp string search result 8852 8853 !ifndef ${AB_CD}_rtl 8854 StrCpy $0 "$1" 8855 !else 8856 ${GetDlgItemWidthHeight} $HWNDPARENT $2 $3 8857 ${DialogUnitsToPixels} $1 X $3 8858 8859 ClearErrors 8860 ${${_MOZFUNC_UN}WordFind} "$0" "u" "E+1{" $4 8861 ${IfNot} ${Errors} 8862 ${DialogUnitsToPixels} $4 X $0 8863 ${EndIf} 8864 8865 IntOp $1 $2 - $3 8866 IntOp $1 $1 - $0 8867 StrCpy $0 $1 8868 !endif 8869 8870 ; Restore the values that were in our scratch registers. 8871 Pop $4 8872 Pop $3 8873 Pop $2 8874 ; Restore our parameter registers and return our result. 8875 ; Stack contents after each instruction (top of the stack on the left): 8876 ; $1 $0 8877 Pop $1 ; $0 8878 Exch $0 ; _RV 8879!macroend 8880 8881/** 8882 * Gets the elapsed time in seconds between two values in milliseconds stored as 8883 * an int64. The caller will typically get the millisecond values using 8884 * GetTickCount with a long return value as follows. 8885 * System::Call "kernel32::GetTickCount()l .s" 8886 * Pop $varname 8887 * 8888 * _START_TICK_COUNT 8889 * _FINISH_TICK_COUNT 8890 * _RES_ELAPSED_SECONDS return value - elapsed time between _START_TICK_COUNT 8891 * and _FINISH_TICK_COUNT in seconds. 8892 */ 8893!macro GetSecondsElapsedCall _START_TICK_COUNT _FINISH_TICK_COUNT _RES_ELAPSED_SECONDS 8894 Push "${_START_TICK_COUNT}" 8895 Push "${_FINISH_TICK_COUNT}" 8896 ${CallArtificialFunction} GetSecondsElapsed_ 8897 Pop ${_RES_ELAPSED_SECONDS} 8898!macroend 8899 8900!define GetSecondsElapsed "!insertmacro GetSecondsElapsedCall" 8901!define un.GetSecondsElapsed "!insertmacro GetSecondsElapsedCall" 8902 8903!macro GetSecondsElapsed_ 8904 Exch $0 ; finish tick count 8905 Exch 1 8906 Exch $1 ; start tick count 8907 8908 System::Int64Op $0 - $1 8909 Pop $0 8910 ; Discard the top bits of the int64 by bitmasking with MAXDWORD 8911 System::Int64Op $0 & ${MAXDWORD} 8912 Pop $0 8913 8914 ; Convert from milliseconds to seconds 8915 System::Int64Op $0 / 1000 8916 Pop $0 8917 8918 Pop $1 8919 Exch $0 ; return elapsed seconds 8920!macroend 8921 8922/** 8923 * Create a process to execute a command line. If it is successfully created, 8924 * wait on it with WaitForInputIdle, to avoid exiting the current process too 8925 * early (exiting early can cause the created process's windows to be opened in 8926 * the background). 8927 * 8928 * CMDLINE Is the command line to execute, like the argument to Exec 8929 */ 8930!define ExecAndWaitForInputIdle "!insertmacro ExecAndWaitForInputIdle_" 8931!define CREATE_DEFAULT_ERROR_MODE 0x04000000 8932!macro ExecAndWaitForInputIdle_ CMDLINE 8933 ; derived from https://stackoverflow.com/a/13960786/3444805 by Anders Kjersem 8934 Push $0 8935 Push $1 8936 Push $2 8937 8938 ; Command line 8939 StrCpy $0 "${CMDLINE}" 8940 8941 ; STARTUPINFO 8942 System::Alloc 68 8943 Pop $1 8944 ; fill in STARTUPINFO.cb (first field) with sizeof(STARTUPINFO) 8945 System::Call "*$1(i 68)" 8946 8947 ; PROCESS_INFORMATION 8948 System::Call "*(i, i, i, i) i . r2" 8949 8950 ; CREATE_DEFAULT_ERROR_MODE follows NSIS myCreateProcess used in Exec 8951 System::Call "kernel32::CreateProcessW(i 0, t r0, i 0, i 0, i 0, i ${CREATE_DEFAULT_ERROR_MODE}, i 0, i 0, i r1, i r2) i . r0" 8952 8953 System::Free $1 8954 ${If} $0 <> 0 8955 System::Call "*$2(i . r0, i . r1)" 8956 ; $0: hProcess, $1: hThread 8957 System::Call "user32::WaitForInputIdle(i $0, i 10000)" 8958 System::Call "kernel32::CloseHandle(i $0)" 8959 System::Call "kernel32::CloseHandle(i $1)" 8960 ${EndIf} 8961 System::Free $2 8962 8963 Pop $2 8964 Pop $1 8965 Pop $0 8966!macroend 8967 8968Function WriteRegQWORD 8969 ; Stack contents: 8970 ; VALUE, VALUE_NAME, SUBKEY, ROOTKEY 8971 Exch $3 ; $3, VALUE_NAME, SUBKEY, ROOTKEY 8972 Exch 1 ; VALUE_NAME, $3, SUBKEY, ROOTKEY 8973 Exch $2 ; $2, $3, SUBKEY, ROOTKEY 8974 Exch 2 ; SUBKEY, $3, $2, ROOTKEY 8975 Exch $1 ; $1, $3, $2, ROOTKEY 8976 Exch 3 ; ROOTKEY, $3, $2, $1 8977 Exch $0 ; $0, $3, $2, $1 8978 System::Call "advapi32::RegSetKeyValueW(p r0, w r1, w r2, i 11, *l r3, i 8) i.r0" 8979 ${IfNot} $0 = 0 8980 SetErrors 8981 ${EndIf} 8982 Pop $0 8983 Pop $3 8984 Pop $2 8985 Pop $1 8986FunctionEnd 8987!macro WriteRegQWORD ROOTKEY SUBKEY VALUE_NAME VALUE 8988 ${If} "${ROOTKEY}" == "HKCR" 8989 Push 0x80000000 8990 ${ElseIf} "${ROOTKEY}" == "HKCU" 8991 Push 0x80000001 8992 ${ElseIf} "${ROOTKEY}" == "HKLM" 8993 Push 0x80000002 8994 ${Endif} 8995 Push "${SUBKEY}" 8996 Push "${VALUE_NAME}" 8997 System::Int64Op ${VALUE} + 0 ; The result is pushed on the stack 8998 Call WriteRegQWORD 8999!macroend 9000!define WriteRegQWORD "!insertmacro WriteRegQWORD" 9001 9002Function ReadRegQWORD 9003 ; Stack contents: 9004 ; VALUE_NAME, SUBKEY, ROOTKEY 9005 Exch $2 ; $2, SUBKEY, ROOTKEY 9006 Exch 1 ; SUBKEY, $2, ROOTKEY 9007 Exch $1 ; $1, $2, ROOTKEY 9008 Exch 2 ; ROOTKEY, $2, $1 9009 Exch $0 ; $0, $2, $1 9010 System::Call "advapi32::RegGetValueW(p r0, w r1, w r2, i 0x48, p 0, *l s, *i 8) i.r0" 9011 ${IfNot} $0 = 0 9012 SetErrors 9013 ${EndIf} 9014 ; VALUE, $0, $2, $1 9015 Exch 3 ; $1, $0, $2, VALUE 9016 Pop $1 ; $0, $2, VALUE 9017 Pop $0 ; $2, VALUE 9018 Pop $2 ; VALUE 9019FunctionEnd 9020!macro ReadRegQWORD DEST ROOTKEY SUBKEY VALUE_NAME 9021 ${If} "${ROOTKEY}" == "HKCR" 9022 Push 0x80000000 9023 ${ElseIf} "${ROOTKEY}" == "HKCU" 9024 Push 0x80000001 9025 ${ElseIf} "${ROOTKEY}" == "HKLM" 9026 Push 0x80000002 9027 ${Endif} 9028 Push "${SUBKEY}" 9029 Push "${VALUE_NAME}" 9030 Call ReadRegQWORD 9031 Pop ${DEST} 9032!macroend 9033!define ReadRegQWORD "!insertmacro ReadRegQWORD" 9034 9035