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 ; The update directory is shared across all users of this 3698 ; installation, and it contains a number of things. Which files we 3699 ; want to keep and which we want to delete depends on if we are 3700 ; installing or uninstalling. 3701 ; If we are installing, we want to clear out any in-progress updates. 3702 ; Otherwise we could potentially install an old, pending update when 3703 ; Firefox first launches. The updates themselves live in the "updates" 3704 ; subdirectory, and the update metadata lives in active-update.xml. 3705 ; If we are uninstalling, we want to clear out the updates, the 3706 ; update history, and the per-installation update configuration data. 3707 ; In this case, we can just delete the whole update directory. 3708 !if "${_MOZFUNC_UN}" == "un." 3709 ${If} ${FileExists} "$R0" 3710 RmDir /r "$R0" 3711 ${EndIf} 3712 !else 3713 ${If} ${FileExists} "$R0\updates" 3714 RmDir /r "$R0\updates" 3715 ${EndIf} 3716 Delete "$R0\active-update.xml" 3717 !endif 3718 3719 ; Also remove the secure log files that our updater may have created 3720 ; inside the maintenance service path. There are several files named 3721 ; with the install hash and an extension indicating the kind of file. 3722 ; so use a wildcard to delete them all. 3723 Delete "$PROGRAMFILES32\Mozilla Maintenance Service\UpdateLogs\$R1.*" 3724 3725 ; If the UpdateLogs directory is now empty, then delete it. 3726 ; The Maintenance Service uninstaller should do this, but it may not 3727 ; be up to date enough because of bug 1665193, so doing this here as 3728 ; well lets us make sure it really happens. 3729 RmDir "$PROGRAMFILES32\Mozilla Maintenance Service\UpdateLogs" 3730 ${EndIf} 3731 ${EndIf} 3732 3733 ClearErrors 3734 3735 Pop $R0 3736 Pop $R1 3737 Pop $R2 3738 Pop $R3 3739 Pop $R4 3740 Pop $R5 3741 Pop $R6 3742 Exch $R7 3743 Exch 1 3744 Exch $R8 3745 FunctionEnd 3746 3747 !verbose pop 3748 !endif 3749!macroend 3750 3751!macro CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH 3752 !verbose push 3753 !verbose ${_MOZFUNC_VERBOSE} 3754 Push "${_OLD_REL_PATH}" 3755 Push "${_NEW_REL_PATH}" 3756 Call CleanUpdateDirectories 3757 !verbose pop 3758!macroend 3759 3760!macro un.CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH 3761 !verbose push 3762 !verbose ${_MOZFUNC_VERBOSE} 3763 Push "${_OLD_REL_PATH}" 3764 Push "${_NEW_REL_PATH}" 3765 Call un.CleanUpdateDirectories 3766 !verbose pop 3767!macroend 3768 3769!macro un.CleanUpdateDirectories 3770 !ifndef un.CleanUpdateDirectories 3771 !verbose push 3772 !verbose ${_MOZFUNC_VERBOSE} 3773 !undef _MOZFUNC_UN 3774 !define _MOZFUNC_UN "un." 3775 3776 !insertmacro CleanUpdateDirectories 3777 3778 !undef _MOZFUNC_UN 3779 !define _MOZFUNC_UN 3780 !verbose pop 3781 !endif 3782!macroend 3783 3784/** 3785 * Create the update directory and sets the permissions correctly 3786 * 3787 * @param ROOT_DIR_NAME 3788 * The name of the update directory to be created in the common 3789 * application directory. For example, if ROOT_DIR_NAME is "Mozilla", 3790 * the created directory will be "C:\ProgramData\Mozilla". 3791 * 3792 * $R0 = Used for checking errors 3793 * $R1 = The common application directory path 3794 * $R9 = An error message to be returned on the stack 3795 */ 3796!macro CreateUpdateDir ROOT_DIR_NAME 3797 Push $R9 3798 Push $R0 3799 Push $R1 3800 3801 ; The update directory is in the Program Data directory 3802 ; (currently C:\ProgramData). 3803 ; This system call gets that directory path. The arguments are: 3804 ; A null ptr for hwnd 3805 ; $R1 for the output string 3806 ; CSIDL_COMMON_APPDATA == 0x0023 == 35 for the csidl indicating which dir to get 3807 ; true for fCreate (i.e. Do create the folder if it doesn't exist) 3808 ; We could use %APPDATA% for this instead, but that requires state: the shell 3809 ; var context would need to be saved, set, and reset. It is easier just to use 3810 ; the system call. 3811 System::Call "Shell32::SHGetSpecialFolderPathW(p 0, t.R1, i 35, i 1)" 3812 StrCpy $R1 "$R1\${ROOT_DIR_NAME}" 3813 3814 ClearErrors 3815 ${IfNot} ${FileExists} "$R1" 3816 CreateDirectory "$R1" 3817 ${If} ${Errors} 3818 StrCpy $R9 "Unable to create directory: $R1" 3819 GoTo end 3820 ${EndIf} 3821 ${EndIf} 3822 3823 ; Grant Full Access to the Builtin User group 3824 AccessControl::SetOnFile "$R1" "(BU)" "FullAccess" 3825 Pop $R0 3826 ${If} $R0 == error 3827 Pop $R9 ; Get AccessControl's Error Message 3828 SetErrors 3829 GoTo end 3830 ${EndIf} 3831 3832 ; Grant Full Access to the Builtin Administrator group 3833 AccessControl::SetOnFile "$R1" "(BA)" "FullAccess" 3834 Pop $R0 3835 ${If} $R0 == error 3836 Pop $R9 ; Get AccessControl's Error Message 3837 SetErrors 3838 GoTo end 3839 ${EndIf} 3840 3841 ; Grant Full Access to the SYSTEM user 3842 AccessControl::SetOnFile "$R1" "(SY)" "FullAccess" 3843 Pop $R0 3844 ${If} $R0 == error 3845 Pop $R9 ; Get AccessControl's Error Message 3846 SetErrors 3847 GoTo end 3848 ${EndIf} 3849 3850 ; Remove inherited permissions 3851 AccessControl::DisableFileInheritance "$R1" 3852 Pop $R0 3853 ${If} $R0 == error 3854 Pop $R9 ; Get AccessControl's Error Message 3855 SetErrors 3856 GoTo end 3857 ${EndIf} 3858 3859end: 3860 Pop $R1 3861 Pop $R0 3862 ${If} ${Errors} 3863 Exch $R9 3864 ${Else} 3865 Pop $R9 3866 ${EndIf} 3867!macroend 3868!define CreateUpdateDir "!insertmacro CreateUpdateDir" 3869 3870/** 3871 * Deletes all relative profiles specified in an application's profiles.ini and 3872 * performs various other cleanup. 3873 * 3874 * @param _REL_PROFILE_PATH 3875 * The relative path to the profile directory. 3876 * 3877 * $R6 = value of IsRelative read from profiles.ini 3878 * $R7 = value of Path to profile read from profiles.ini 3879 * $R8 = counter for reading profiles (e.g. Profile0, Profile1, etc.) 3880 * $R9 = _REL_PROFILE_PATH 3881 */ 3882!macro DeleteRelativeProfiles 3883 3884 !ifndef ${_MOZFUNC_UN}DeleteRelativeProfiles 3885 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 3886 !insertmacro ${_MOZFUNC_UN_TMP}WordReplace 3887 !undef _MOZFUNC_UN 3888 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 3889 !undef _MOZFUNC_UN_TMP 3890 3891 !verbose push 3892 !verbose ${_MOZFUNC_VERBOSE} 3893 !define ${_MOZFUNC_UN}DeleteRelativeProfiles "!insertmacro ${_MOZFUNC_UN}DeleteRelativeProfilesCall" 3894 3895 Function ${_MOZFUNC_UN}DeleteRelativeProfiles 3896 Exch $R9 3897 Push $R8 3898 Push $R7 3899 Push $R6 3900 3901 SetShellVarContext current 3902 StrCpy $R8 -1 3903 3904 loop: 3905 IntOp $R8 $R8 + 1 ; Increment the counter. 3906 ReadINIStr $R7 "$APPDATA\$R9\profiles.ini" "Profile$R8" "Path" 3907 IfErrors end +1 3908 3909 ; Only remove relative profiles 3910 ReadINIStr $R6 "$APPDATA\$R9\profiles.ini" "Profile$R8" "IsRelative" 3911 StrCmp "$R6" "1" +1 loop 3912 3913 ; Relative paths in profiles.ini use / as a separator 3914 ${${_MOZFUNC_UN}WordReplace} "$R7" "/" "\" "+" $R7 3915 3916 IfFileExists "$LOCALAPPDATA\$R9\$R7" +1 +2 3917 RmDir /r "$LOCALAPPDATA\$R9\$R7" 3918 IfFileExists "$APPDATA\$R9\$R7" +1 +2 3919 RmDir /r "$APPDATA\$R9\$R7" 3920 GoTo loop 3921 3922 end: 3923 ; Remove profiles directory under LOCALAPPDATA (e.g. cache, etc.) since 3924 ; they are at times abandoned. 3925 RmDir /r "$LOCALAPPDATA\$R9\Profiles" 3926 RmDir /r "$APPDATA\$R9\Crash Reports" 3927 Delete "$APPDATA\$R9\profiles.ini" 3928 Delete "$APPDATA\$R9\console.log" 3929 Delete "$APPDATA\$R9\pluginreg.dat" 3930 RmDir "$APPDATA\$R9\Profiles" 3931 RmDir "$APPDATA\$R9" 3932 3933 Pop $R6 3934 Pop $R7 3935 Pop $R8 3936 Exch $R9 3937 FunctionEnd 3938 3939 !verbose pop 3940 !endif 3941!macroend 3942 3943!macro DeleteRelativeProfilesCall _REL_PROFILE_PATH 3944 !verbose push 3945 !verbose ${_MOZFUNC_VERBOSE} 3946 Push "${_REL_PROFILE_PATH}" 3947 Call DeleteRelativeProfiles 3948 !verbose pop 3949!macroend 3950 3951!macro un.DeleteRelativeProfilesCall _REL_PROFILE_PATH 3952 !verbose push 3953 !verbose ${_MOZFUNC_VERBOSE} 3954 Push "${_REL_PROFILE_PATH}" 3955 Call un.DeleteRelativeProfiles 3956 !verbose pop 3957!macroend 3958 3959!macro un.DeleteRelativeProfiles 3960 !ifndef un.DeleteRelativeProfiles 3961 !verbose push 3962 !verbose ${_MOZFUNC_VERBOSE} 3963 !undef _MOZFUNC_UN 3964 !define _MOZFUNC_UN "un." 3965 3966 !insertmacro DeleteRelativeProfiles 3967 3968 !undef _MOZFUNC_UN 3969 !define _MOZFUNC_UN 3970 !verbose pop 3971 !endif 3972!macroend 3973 3974/** 3975 * Deletes shortcuts and Start Menu directories under Programs as specified by 3976 * the shortcuts log ini file and on Windows 7 unpins TaskBar and Start Menu 3977 * shortcuts. The shortcuts will not be deleted if the shortcut target isn't for 3978 * this install location which is determined by the shortcut having a target of 3979 * $INSTDIR\${FileMainEXE}. The context (All Users or Current User) of the 3980 * $DESKTOP and $SMPROGRAMS constants depends on the 3981 * SetShellVarContext setting and must be set by the caller of this macro. There 3982 * is no All Users context for $QUICKLAUNCH but this will not cause a problem 3983 * since the macro will just continue past the $QUICKLAUNCH shortcut deletion 3984 * section on subsequent calls. 3985 * 3986 * The ini file sections must have the following format (the order of the 3987 * sections in the ini file is not important): 3988 * [SMPROGRAMS] 3989 * ; RelativePath is the directory relative from the Start Menu 3990 * ; Programs directory. 3991 * RelativePath=Mozilla App 3992 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 3993 * ; on. There must not be a break in the sequence of the numbers. 3994 * Shortcut1=Mozilla App.lnk 3995 * Shortcut2=Mozilla App (Safe Mode).lnk 3996 * [DESKTOP] 3997 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 3998 * ; on. There must not be a break in the sequence of the numbers. 3999 * Shortcut1=Mozilla App.lnk 4000 * Shortcut2=Mozilla App (Safe Mode).lnk 4001 * [QUICKLAUNCH] 4002 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 4003 * ; on. There must not be a break in the sequence of the numbers for the 4004 * ; suffix. 4005 * Shortcut1=Mozilla App.lnk 4006 * Shortcut2=Mozilla App (Safe Mode).lnk 4007 * [STARTMENU] 4008 * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so 4009 * ; on. There must not be a break in the sequence of the numbers for the 4010 * ; suffix. 4011 * Shortcut1=Mozilla App.lnk 4012 * Shortcut2=Mozilla App (Safe Mode).lnk 4013 * 4014 * $R4 = counter for appending to Shortcut for enumerating the ini file entries 4015 * $R5 = return value from ShellLink::GetShortCutTarget and 4016 * ApplicationID::UninstallPinnedItem 4017 * $R6 = find handle and the long path to the Start Menu Programs directory 4018 * (e.g. $SMPROGRAMS) 4019 * $R7 = path to the $QUICKLAUNCH\User Pinned directory and the return value 4020 * from ReadINIStr for the relative path to the applications directory 4021 * under the Start Menu Programs directory and the long path to this 4022 * directory 4023 * $R8 = return filename from FindFirst / FindNext and the return value from 4024 * ReadINIStr for enumerating shortcuts 4025 * $R9 = long path to the shortcuts log ini file 4026 */ 4027!macro DeleteShortcuts 4028 4029 !ifndef ${_MOZFUNC_UN}DeleteShortcuts 4030 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 4031 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 4032 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 4033 !undef _MOZFUNC_UN 4034 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 4035 !undef _MOZFUNC_UN_TMP 4036 4037 !verbose push 4038 !verbose ${_MOZFUNC_VERBOSE} 4039 !define ${_MOZFUNC_UN}DeleteShortcuts "!insertmacro ${_MOZFUNC_UN}DeleteShortcutsCall" 4040 4041 Function ${_MOZFUNC_UN}DeleteShortcuts 4042 Push $R9 4043 Push $R8 4044 Push $R7 4045 Push $R6 4046 Push $R5 4047 Push $R4 4048 4049 ${If} ${AtLeastWin7} 4050 ; Since shortcuts that are pinned can later be removed without removing 4051 ; the pinned shortcut unpin the pinned shortcuts for the application's 4052 ; main exe using the pinned shortcuts themselves. 4053 StrCpy $R7 "$QUICKLAUNCH\User Pinned" 4054 4055 ${If} ${FileExists} "$R7\TaskBar" 4056 ; Delete TaskBar pinned shortcuts for the application's main exe 4057 FindFirst $R6 $R8 "$R7\TaskBar\*.lnk" 4058 ${Do} 4059 ${If} ${FileExists} "$R7\TaskBar\$R8" 4060 ShellLink::GetShortCutTarget "$R7\TaskBar\$R8" 4061 Pop $R5 4062 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4063 ${If} "$R5" == "$INSTDIR\${FileMainEXE}" 4064 ApplicationID::UninstallPinnedItem "$R7\TaskBar\$R8" 4065 Pop $R5 4066 ${EndIf} 4067 ${EndIf} 4068 ClearErrors 4069 FindNext $R6 $R8 4070 ${If} ${Errors} 4071 ${ExitDo} 4072 ${EndIf} 4073 ${Loop} 4074 FindClose $R6 4075 ${EndIf} 4076 4077 ${If} ${FileExists} "$R7\StartMenu" 4078 ; Delete Start Menu pinned shortcuts for the application's main exe 4079 FindFirst $R6 $R8 "$R7\StartMenu\*.lnk" 4080 ${Do} 4081 ${If} ${FileExists} "$R7\StartMenu\$R8" 4082 ShellLink::GetShortCutTarget "$R7\StartMenu\$R8" 4083 Pop $R5 4084 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4085 ${If} "$R5" == "$INSTDIR\${FileMainEXE}" 4086 ApplicationID::UninstallPinnedItem "$R7\StartMenu\$R8" 4087 Pop $R5 4088 ${EndIf} 4089 ${EndIf} 4090 ClearErrors 4091 FindNext $R6 $R8 4092 ${If} ${Errors} 4093 ${ExitDo} 4094 ${EndIf} 4095 ${Loop} 4096 FindClose $R6 4097 ${EndIf} 4098 ${EndIf} 4099 4100 ; Don't call ApplicationID::UninstallPinnedItem since pinned items for 4101 ; this application were removed above and removing them below will remove 4102 ; the association of side by side installations. 4103 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9 4104 ${If} ${FileExists} "$R9" 4105 ; Delete Start Menu shortcuts for this application 4106 StrCpy $R4 -1 4107 ${Do} 4108 IntOp $R4 $R4 + 1 ; Increment the counter 4109 ClearErrors 4110 ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4" 4111 ${If} ${Errors} 4112 ${ExitDo} 4113 ${EndIf} 4114 4115 ${If} ${FileExists} "$SMPROGRAMS\$R8" 4116 ShellLink::GetShortCutTarget "$SMPROGRAMS\$R8" 4117 Pop $R5 4118 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4119 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4120 Delete "$SMPROGRAMS\$R8" 4121 ${EndIf} 4122 ${EndIf} 4123 ${Loop} 4124 ; There might also be a shortcut with a different name created by a 4125 ; previous version of the installer. 4126 ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" 4127 ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandFullName}.lnk" 4128 Pop $R5 4129 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4130 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4131 Delete "$SMPROGRAMS\${BrandFullName}.lnk" 4132 ${EndIf} 4133 ${EndIf} 4134 4135 ; Delete Quick Launch shortcuts for this application 4136 StrCpy $R4 -1 4137 ${Do} 4138 IntOp $R4 $R4 + 1 ; Increment the counter 4139 ClearErrors 4140 ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4" 4141 ${If} ${Errors} 4142 ${ExitDo} 4143 ${EndIf} 4144 4145 ${If} ${FileExists} "$QUICKLAUNCH\$R8" 4146 ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8" 4147 Pop $R5 4148 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4149 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4150 Delete "$QUICKLAUNCH\$R8" 4151 ${EndIf} 4152 ${EndIf} 4153 ${Loop} 4154 ; There might also be a shortcut with a different name created by a 4155 ; previous version of the installer. 4156 ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" 4157 ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk" 4158 Pop $R5 4159 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4160 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4161 Delete "$QUICKLAUNCH\${BrandFullName}.lnk" 4162 ${EndIf} 4163 ${EndIf} 4164 4165 ; Delete Desktop shortcuts for this application 4166 StrCpy $R4 -1 4167 ${Do} 4168 IntOp $R4 $R4 + 1 ; Increment the counter 4169 ClearErrors 4170 ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4" 4171 ${If} ${Errors} 4172 ${ExitDo} 4173 ${EndIf} 4174 4175 ${If} ${FileExists} "$DESKTOP\$R8" 4176 ShellLink::GetShortCutTarget "$DESKTOP\$R8" 4177 Pop $R5 4178 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4179 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4180 Delete "$DESKTOP\$R8" 4181 ${EndIf} 4182 ${EndIf} 4183 ${Loop} 4184 ; There might also be a shortcut with a different name created by a 4185 ; previous version of the installer. 4186 ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" 4187 ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk" 4188 Pop $R5 4189 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4190 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4191 Delete "$DESKTOP\${BrandFullName}.lnk" 4192 ${EndIf} 4193 ${EndIf} 4194 4195 ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6 4196 4197 ; Delete Start Menu Programs shortcuts for this application 4198 ClearErrors 4199 ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir" 4200 ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7 4201 ${Unless} "$R7" == "" 4202 StrCpy $R4 -1 4203 ${Do} 4204 IntOp $R4 $R4 + 1 ; Increment the counter 4205 ClearErrors 4206 ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4" 4207 ${If} ${Errors} 4208 ${ExitDo} 4209 ${EndIf} 4210 4211 ${If} ${FileExists} "$R7\$R8" 4212 ShellLink::GetShortCutTarget "$R7\$R8" 4213 Pop $R5 4214 ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 4215 ${If} "$INSTDIR\${FileMainEXE}" == "$R5" 4216 Delete "$R7\$R8" 4217 ${EndIf} 4218 ${EndIf} 4219 ${Loop} 4220 4221 ; Delete Start Menu Programs directories for this application 4222 ${Do} 4223 ClearErrors 4224 ${If} "$R6" == "$R7" 4225 ${ExitDo} 4226 ${EndIf} 4227 RmDir "$R7" 4228 ${If} ${Errors} 4229 ${ExitDo} 4230 ${EndIf} 4231 ${${_MOZFUNC_UN}GetParent} "$R7" $R7 4232 ${Loop} 4233 ${EndUnless} 4234 ${EndIf} 4235 4236 ClearErrors 4237 4238 Pop $R4 4239 Pop $R5 4240 Pop $R6 4241 Pop $R7 4242 Pop $R8 4243 Pop $R9 4244 FunctionEnd 4245 4246 !verbose pop 4247 !endif 4248!macroend 4249 4250!macro DeleteShortcutsCall 4251 !verbose push 4252 !verbose ${_MOZFUNC_VERBOSE} 4253 Call DeleteShortcuts 4254 !verbose pop 4255!macroend 4256 4257!macro un.DeleteShortcutsCall 4258 !verbose push 4259 !verbose ${_MOZFUNC_VERBOSE} 4260 Call un.DeleteShortcuts 4261 !verbose pop 4262!macroend 4263 4264!macro un.DeleteShortcuts 4265 !ifndef un.DeleteShortcuts 4266 !verbose push 4267 !verbose ${_MOZFUNC_VERBOSE} 4268 !undef _MOZFUNC_UN 4269 !define _MOZFUNC_UN "un." 4270 4271 !insertmacro DeleteShortcuts 4272 4273 !undef _MOZFUNC_UN 4274 !define _MOZFUNC_UN 4275 !verbose pop 4276 !endif 4277!macroend 4278 4279 4280################################################################################ 4281# Macros for parsing and updating the uninstall.log 4282 4283/** 4284 * Updates the uninstall.log with new files added by software update. 4285 * 4286 * When modifying this macro be aware that LineFind uses all registers except 4287 * $R0-$R3 and TextCompareNoDetails uses all registers except $R0-$R9 so be 4288 * cautious. Callers of this macro are not affected. 4289 */ 4290!macro UpdateUninstallLog 4291 4292 !ifndef UpdateUninstallLog 4293 !insertmacro FileJoin 4294 !insertmacro LineFind 4295 !insertmacro TextCompareNoDetails 4296 !insertmacro TrimNewLines 4297 4298 !verbose push 4299 !verbose ${_MOZFUNC_VERBOSE} 4300 !define UpdateUninstallLog "!insertmacro UpdateUninstallLogCall" 4301 4302 Function UpdateUninstallLog 4303 Push $R3 4304 Push $R2 4305 Push $R1 4306 Push $R0 4307 4308 ClearErrors 4309 4310 GetFullPathName $R3 "$INSTDIR\uninstall" 4311 ${If} ${FileExists} "$R3\uninstall.update" 4312 ${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog" 4313 4314 GetTempFileName $R2 "$R3" 4315 FileOpen $R1 "$R2" w 4316 ${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff" 4317 FileClose $R1 4318 4319 IfErrors +2 0 4320 ${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log" 4321 4322 ${DeleteFile} "$R2" 4323 ${EndIf} 4324 4325 ClearErrors 4326 4327 Pop $R0 4328 Pop $R1 4329 Pop $R2 4330 Pop $R3 4331 FunctionEnd 4332 4333 ; This callback MUST use labels vs. relative line numbers. 4334 Function CleanupUpdateLog 4335 StrCpy $R2 "$R9" 12 4336 StrCmp "$R2" "EXECUTE ADD " +1 skip 4337 StrCpy $R9 "$R9" "" 12 4338 4339 Push $R6 4340 Push $R5 4341 Push $R4 4342 StrCpy $R4 "" ; Initialize to an empty string. 4343 StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0. 4344 4345 loop: 4346 IntOp $R6 $R6 + 1 ; Increment the counter. 4347 StrCpy $R5 $R9 1 $R6 ; Starting from the counter copy the next char. 4348 StrCmp $R5 "" copy ; Are there no more chars? 4349 StrCmp $R5 "/" +1 +2 ; Is the char a /? 4350 StrCpy $R5 "\" ; Replace the char with a \. 4351 4352 StrCpy $R4 "$R4$R5" 4353 GoTo loop 4354 4355 copy: 4356 StrCpy $R9 "File: \$R4" 4357 Pop $R6 4358 Pop $R5 4359 Pop $R4 4360 GoTo end 4361 4362 skip: 4363 StrCpy $0 "SkipWrite" 4364 4365 end: 4366 Push $0 4367 FunctionEnd 4368 4369 Function CreateUpdateDiff 4370 ${TrimNewLines} "$9" $9 4371 ${If} $9 != "" 4372 FileWrite $R1 "$9$\r$\n" 4373 ${EndIf} 4374 4375 Push 0 4376 FunctionEnd 4377 4378 !verbose pop 4379 !endif 4380!macroend 4381 4382!macro UpdateUninstallLogCall 4383 !verbose push 4384 !verbose ${_MOZFUNC_VERBOSE} 4385 Call UpdateUninstallLog 4386 !verbose pop 4387!macroend 4388 4389/** 4390 * Copies files from a source directory to a destination directory with logging 4391 * to the uninstall.log. If any destination files are in use a reboot will be 4392 * necessary to complete the installation and the reboot flag (see IfRebootFlag 4393 * in the NSIS documentation). 4394 * 4395 * @param _PATH_TO_SOURCE 4396 * Source path to copy the files from. This must not end with a \. 4397 * 4398 * @param _PATH_TO_DESTINATION 4399 * Destination path to copy the files to. This must not end with a \. 4400 * 4401 * @param _PREFIX_ERROR_CREATEDIR 4402 * Prefix for the directory creation error message. The directory path 4403 * will be inserted below this string. 4404 * 4405 * @param _SUFFIX_ERROR_CREATEDIR 4406 * Suffix for the directory creation error message. The directory path 4407 * will be inserted above this string. 4408 * 4409 * $0 = destination file's parent directory used in the create_dir label 4410 * $R0 = copied value from $R6 (e.g. _PATH_TO_SOURCE) 4411 * $R1 = copied value from $R7 (e.g. _PATH_TO_DESTINATION) 4412 * $R2 = string length of the path to source 4413 * $R3 = relative path from the path to source 4414 * $R4 = copied value from $R8 (e.g. _PREFIX_ERROR_CREATEDIR) 4415 * $R5 = copied value from $R9 (e.g. _SUFFIX_ERROR_CREATEDIR) 4416 * note: the LocateNoDetails macro uses these registers so we copy the values 4417 * to other registers. 4418 * $R6 = initially _PATH_TO_SOURCE and then set to "size" ($R6="" if directory, 4419 * $R6="0" if file with /S=)"path\name" in callback 4420 * $R7 = initially _PATH_TO_DESTINATION and then set to "name" in callback 4421 * $R8 = initially _PREFIX_ERROR_CREATEDIR and then set to "path" in callback 4422 * $R9 = initially _SUFFIX_ERROR_CREATEDIR and then set to "path\name" in 4423 * callback 4424 */ 4425!macro CopyFilesFromDir 4426 4427 !ifndef CopyFilesFromDir 4428 !insertmacro LocateNoDetails 4429 !insertmacro OnEndCommon 4430 !insertmacro WordReplace 4431 4432 !verbose push 4433 !verbose ${_MOZFUNC_VERBOSE} 4434 !define CopyFilesFromDir "!insertmacro CopyFilesFromDirCall" 4435 4436 Function CopyFilesFromDir 4437 Exch $R9 4438 Exch 1 4439 Exch $R8 4440 Exch 2 4441 Exch $R7 4442 Exch 3 4443 Exch $R6 4444 Push $R5 4445 Push $R4 4446 Push $R3 4447 Push $R2 4448 Push $R1 4449 Push $R0 4450 Push $0 4451 4452 StrCpy $R0 "$R6" 4453 StrCpy $R1 "$R7" 4454 StrCpy $R4 "$R8" 4455 StrCpy $R5 "$R9" 4456 4457 StrLen $R2 "$R0" 4458 4459 ${LocateNoDetails} "$R0" "/L=FD" "CopyFileCallback" 4460 4461 Pop $0 4462 Pop $R0 4463 Pop $R1 4464 Pop $R2 4465 Pop $R3 4466 Pop $R4 4467 Pop $R5 4468 Exch $R6 4469 Exch 3 4470 Exch $R7 4471 Exch 2 4472 Exch $R8 4473 Exch 1 4474 Exch $R9 4475 FunctionEnd 4476 4477 Function CopyFileCallback 4478 StrCpy $R3 $R8 "" $R2 ; $R3 always begins with a \. 4479 4480 retry: 4481 ClearErrors 4482 StrCmp $R6 "" +1 copy_file 4483 IfFileExists "$R1$R3\$R7" end +1 4484 StrCpy $0 "$R1$R3\$R7" 4485 4486 create_dir: 4487 ClearErrors 4488 CreateDirectory "$0" 4489 IfFileExists "$0" +1 err_create_dir ; protect against looping. 4490 ${LogMsg} "Created Directory: $0" 4491 StrCmp $R6 "" end copy_file 4492 4493 err_create_dir: 4494 ${LogMsg} "** ERROR Creating Directory: $0 **" 4495 MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$R4$\r$\n$\r$\n$0$\r$\n$\r$\n$R5" IDRETRY retry 4496 ${OnEndCommon} 4497 Quit 4498 4499 copy_file: 4500 StrCpy $0 "$R1$R3" 4501 StrCmp "$0" "$INSTDIR" +2 +1 4502 IfFileExists "$0" +1 create_dir 4503 4504 ClearErrors 4505 ${DeleteFile} "$R1$R3\$R7" 4506 IfErrors +1 dest_clear 4507 ClearErrors 4508 Rename "$R1$R3\$R7" "$R1$R3\$R7.moz-delete" 4509 IfErrors +1 reboot_delete 4510 4511 ; file will replace destination file on reboot 4512 Rename "$R9" "$R9.moz-upgrade" 4513 CopyFiles /SILENT "$R9.moz-upgrade" "$R1$R3" 4514 Rename /REBOOTOK "$R1$R3\$R7.moz-upgrade" "$R1$R3\$R7" 4515 ${LogMsg} "Copied File: $R1$R3\$R7.moz-upgrade" 4516 ${LogMsg} "Delayed Install File (Reboot Required): $R1$R3\$R7" 4517 GoTo log_uninstall 4518 4519 ; file will be deleted on reboot 4520 reboot_delete: 4521 CopyFiles /SILENT $R9 "$R1$R3" 4522 Delete /REBOOTOK "$R1$R3\$R7.moz-delete" 4523 ${LogMsg} "Installed File: $R1$R3\$R7" 4524 ${LogMsg} "Delayed Delete File (Reboot Required): $R1$R3\$R7.moz-delete" 4525 GoTo log_uninstall 4526 4527 ; destination file doesn't exist - coast is clear 4528 dest_clear: 4529 CopyFiles /SILENT $R9 "$R1$R3" 4530 ${LogMsg} "Installed File: $R1$R3\$R7" 4531 4532 log_uninstall: 4533 ; If the file is installed into the installation directory remove the 4534 ; installation directory's path from the file path when writing to the 4535 ; uninstall.log so it will be a relative path. This allows the same 4536 ; helper.exe to be used with zip builds if we supply an uninstall.log. 4537 ${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3 4538 ${LogUninstall} "File: $R3" 4539 4540 end: 4541 Push 0 4542 FunctionEnd 4543 4544 !verbose pop 4545 !endif 4546!macroend 4547 4548!macro CopyFilesFromDirCall _PATH_TO_SOURCE _PATH_TO_DESTINATION \ 4549 _PREFIX_ERROR_CREATEDIR _SUFFIX_ERROR_CREATEDIR 4550 !verbose push 4551 !verbose ${_MOZFUNC_VERBOSE} 4552 Push "${_PATH_TO_SOURCE}" 4553 Push "${_PATH_TO_DESTINATION}" 4554 Push "${_PREFIX_ERROR_CREATEDIR}" 4555 Push "${_SUFFIX_ERROR_CREATEDIR}" 4556 Call CopyFilesFromDir 4557 !verbose pop 4558!macroend 4559 4560/** 4561 * Parses the uninstall.log on install to first remove a previous installation's 4562 * files and then their directories if empty prior to installing. 4563 * 4564 * When modifying this macro be aware that LineFind uses all registers except 4565 * $R0-$R3 so be cautious. Callers of this macro are not affected. 4566 */ 4567!macro OnInstallUninstall 4568 4569 !ifndef OnInstallUninstall 4570 !insertmacro GetParent 4571 !insertmacro LineFind 4572 !insertmacro TrimNewLines 4573 4574 !verbose push 4575 !verbose ${_MOZFUNC_VERBOSE} 4576 !define OnInstallUninstall "!insertmacro OnInstallUninstallCall" 4577 4578 Function OnInstallUninstall 4579 Push $R9 4580 Push $R8 4581 Push $R7 4582 Push $R6 4583 Push $R5 4584 Push $R4 4585 Push $R3 4586 Push $R2 4587 Push $R1 4588 Push $R0 4589 Push $TmpVal 4590 4591 IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end 4592 4593 ${LogHeader} "Removing Previous Installation" 4594 4595 ; Copy the uninstall log file to a temporary file 4596 GetTempFileName $TmpVal 4597 CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" 4598 4599 ; Delete files 4600 ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveFilesCallback" 4601 4602 ; Remove empty directories 4603 ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveDirsCallback" 4604 4605 ; Delete the temporary uninstall log file 4606 Delete /REBOOTOK "$TmpVal" 4607 4608 ; Delete the uninstall log file 4609 Delete "$INSTDIR\uninstall\uninstall.log" 4610 4611 end: 4612 ClearErrors 4613 4614 Pop $TmpVal 4615 Pop $R0 4616 Pop $R1 4617 Pop $R2 4618 Pop $R3 4619 Pop $R4 4620 Pop $R5 4621 Pop $R6 4622 Pop $R7 4623 Pop $R8 4624 Pop $R9 4625 FunctionEnd 4626 4627 Function RemoveFilesCallback 4628 ${TrimNewLines} "$R9" $R9 4629 StrCpy $R1 "$R9" 5 ; Copy the first five chars 4630 4631 StrCmp "$R1" "File:" +1 end 4632 StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char 4633 StrCpy $R0 "$R9" 1 ; Copy the first char 4634 4635 StrCmp "$R0" "\" +1 end ; If this isn't a relative path goto end 4636 StrCmp "$R9" "\install.log" end +1 ; Skip the install.log 4637 StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll 4638 StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll 4639 4640 StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string 4641 IfFileExists "$R1" +1 end 4642 4643 ClearErrors 4644 Delete "$R1" 4645 ${Unless} ${Errors} 4646 ${LogMsg} "Deleted File: $R1" 4647 Goto end 4648 ${EndUnless} 4649 4650 ClearErrors 4651 Rename "$R1" "$R1.moz-delete" 4652 ${Unless} ${Errors} 4653 Delete /REBOOTOK "$R1.moz-delete" 4654 ${LogMsg} "Delayed Delete File (Reboot Required): $R1.moz-delete" 4655 GoTo end 4656 ${EndUnless} 4657 4658 ; Check if the file exists in the source. If it does the new file will 4659 ; replace the existing file when the system is rebooted. If it doesn't 4660 ; the file will be deleted when the system is rebooted. 4661 ${Unless} ${FileExists} "$EXEDIR\core$R9" 4662 ${AndUnless} ${FileExists} "$EXEDIR\optional$R9" 4663 Delete /REBOOTOK "$R1" 4664 ${LogMsg} "Delayed Delete File (Reboot Required): $R1" 4665 ${EndUnless} 4666 4667 end: 4668 ClearErrors 4669 4670 Push 0 4671 FunctionEnd 4672 4673 ; Using locate will leave file handles open to some of the directories 4674 ; which will prevent the deletion of these directories. This parses the 4675 ; uninstall.log and uses the file entries to find / remove empty 4676 ; directories. 4677 Function RemoveDirsCallback 4678 ${TrimNewLines} "$R9" $R9 4679 StrCpy $R0 "$R9" 5 ; Copy the first five chars 4680 StrCmp "$R0" "File:" +1 end 4681 4682 StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char 4683 StrCpy $R0 "$R9" 1 ; Copy the first char 4684 4685 StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string 4686 StrCmp "$R0" "\" loop end ; If this isn't a relative path goto end 4687 4688 loop: 4689 ${GetParent} "$R1" $R1 ; Get the parent directory for the path 4690 StrCmp "$R1" "$INSTDIR" end +1 ; If the directory is the install dir goto end 4691 4692 IfFileExists "$R1" +1 loop ; Only try to remove the dir if it exists 4693 ClearErrors 4694 RmDir "$R1" ; Remove the dir 4695 IfErrors end +1 ; If we fail there is no use trying to remove its parent dir 4696 ${LogMsg} "Deleted Directory: $R1" 4697 GoTo loop 4698 4699 end: 4700 ClearErrors 4701 4702 Push 0 4703 FunctionEnd 4704 4705 !verbose pop 4706 !endif 4707!macroend 4708 4709!macro OnInstallUninstallCall 4710 !verbose push 4711 !verbose ${_MOZFUNC_VERBOSE} 4712 Call OnInstallUninstall 4713 !verbose pop 4714!macroend 4715 4716/** 4717 * Parses the precomplete file to remove an installation's files and 4718 * directories. 4719 * 4720 * @param _CALLBACK 4721 * The function address of a callback function for progress or "false" 4722 * if there is no callback function. 4723 * 4724 * $R3 = false if all files were deleted or moved to the tobedeleted directory. 4725 * true if file(s) could not be moved to the tobedeleted directory. 4726 * $R4 = Path to temporary precomplete file. 4727 * $R5 = File handle for the temporary precomplete file. 4728 * $R6 = String returned from FileRead. 4729 * $R7 = First seven characters of the string returned from FileRead. 4730 * $R8 = Temporary file path used to rename files that are in use. 4731 * $R9 = _CALLBACK 4732 */ 4733!macro RemovePrecompleteEntries 4734 4735 !ifndef ${_MOZFUNC_UN}RemovePrecompleteEntries 4736 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 4737 !insertmacro ${_MOZFUNC_UN_TMP}GetParent 4738 !insertmacro ${_MOZFUNC_UN_TMP}TrimNewLines 4739 !insertmacro ${_MOZFUNC_UN_TMP}WordReplace 4740 !undef _MOZFUNC_UN 4741 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 4742 !undef _MOZFUNC_UN_TMP 4743 4744 !verbose push 4745 !verbose ${_MOZFUNC_VERBOSE} 4746 !define ${_MOZFUNC_UN}RemovePrecompleteEntries "!insertmacro ${_MOZFUNC_UN}RemovePrecompleteEntriesCall" 4747 4748 Function ${_MOZFUNC_UN}RemovePrecompleteEntries 4749 Exch $R9 4750 Push $R8 4751 Push $R7 4752 Push $R6 4753 Push $R5 4754 Push $R4 4755 Push $R3 4756 4757 ${If} ${FileExists} "$INSTDIR\precomplete" 4758 StrCpy $R3 "false" 4759 4760 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 4761 CreateDirectory "$INSTDIR\${TO_BE_DELETED}" 4762 GetTempFileName $R4 "$INSTDIR\${TO_BE_DELETED}" 4763 Delete "$R4" 4764 Rename "$INSTDIR\precomplete" "$R4" 4765 4766 ClearErrors 4767 ; Rename and then remove files 4768 FileOpen $R5 "$R4" r 4769 ${Do} 4770 FileRead $R5 $R6 4771 ${If} ${Errors} 4772 ${Break} 4773 ${EndIf} 4774 4775 ${${_MOZFUNC_UN}TrimNewLines} "$R6" $R6 4776 ; Replace all occurrences of "/" with "\". 4777 ${${_MOZFUNC_UN}WordReplace} "$R6" "/" "\" "+" $R6 4778 4779 ; Copy the first 7 chars 4780 StrCpy $R7 "$R6" 7 4781 ${If} "$R7" == "remove " 4782 ; Copy the string starting after the 8th char 4783 StrCpy $R6 "$R6" "" 8 4784 ; Copy all but the last char to remove the double quote. 4785 StrCpy $R6 "$R6" -1 4786 ${If} ${FileExists} "$INSTDIR\$R6" 4787 ${Unless} "$R9" == "false" 4788 Call $R9 4789 ${EndUnless} 4790 4791 ClearErrors 4792 Delete "$INSTDIR\$R6" 4793 ${If} ${Errors} 4794 GetTempFileName $R8 "$INSTDIR\${TO_BE_DELETED}" 4795 Delete "$R8" 4796 ClearErrors 4797 Rename "$INSTDIR\$R6" "$R8" 4798 ${Unless} ${Errors} 4799 Delete /REBOOTOK "$R8" 4800 4801 ClearErrors 4802 ${EndUnless} 4803!ifdef __UNINSTALL__ 4804 ${If} ${Errors} 4805 Delete /REBOOTOK "$INSTDIR\$R6" 4806 StrCpy $R3 "true" 4807 ClearErrors 4808 ${EndIf} 4809!endif 4810 ${EndIf} 4811 ${EndIf} 4812 ${ElseIf} "$R7" == "rmdir $\"" 4813 ; Copy the string starting after the 7th char. 4814 StrCpy $R6 "$R6" "" 7 4815 ; Copy all but the last two chars to remove the slash and the double quote. 4816 StrCpy $R6 "$R6" -2 4817 ${If} ${FileExists} "$INSTDIR\$R6" 4818 ; Ignore directory removal errors 4819 RmDir "$INSTDIR\$R6" 4820 ClearErrors 4821 ${EndIf} 4822 ${EndIf} 4823 ${Loop} 4824 FileClose $R5 4825 4826 ; Delete the temporary precomplete file 4827 Delete /REBOOTOK "$R4" 4828 4829 RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}" 4830 4831 ${If} ${RebootFlag} 4832 ${AndIf} "$R3" == "false" 4833 ; Clear the reboot flag if all files were deleted or moved to the 4834 ; tobedeleted directory. 4835 SetRebootFlag false 4836 ${EndIf} 4837 ${EndIf} 4838 4839 ClearErrors 4840 4841 Pop $R3 4842 Pop $R4 4843 Pop $R5 4844 Pop $R6 4845 Pop $R7 4846 Pop $R8 4847 Exch $R9 4848 FunctionEnd 4849 4850 !verbose pop 4851 !endif 4852!macroend 4853 4854!macro RemovePrecompleteEntriesCall _CALLBACK 4855 !verbose push 4856 Push "${_CALLBACK}" 4857 !verbose ${_MOZFUNC_VERBOSE} 4858 Call RemovePrecompleteEntries 4859 !verbose pop 4860!macroend 4861 4862!macro un.RemovePrecompleteEntriesCall _CALLBACK 4863 !verbose push 4864 !verbose ${_MOZFUNC_VERBOSE} 4865 Push "${_CALLBACK}" 4866 Call un.RemovePrecompleteEntries 4867 !verbose pop 4868!macroend 4869 4870!macro un.RemovePrecompleteEntries 4871 !ifndef un.RemovePrecompleteEntries 4872 !verbose push 4873 !verbose ${_MOZFUNC_VERBOSE} 4874 !undef _MOZFUNC_UN 4875 !define _MOZFUNC_UN "un." 4876 4877 !insertmacro RemovePrecompleteEntries 4878 4879 !undef _MOZFUNC_UN 4880 !define _MOZFUNC_UN 4881 !verbose pop 4882 !endif 4883!macroend 4884 4885/** 4886 * Parses the uninstall.log to unregister dll's, remove files, and remove 4887 * empty directories for this installation. 4888 * 4889 * When modifying this macro be aware that LineFind uses all registers except 4890 * $R0-$R3 so be cautious. Callers of this macro are not affected. 4891 */ 4892!macro un.ParseUninstallLog 4893 4894 !ifndef un.ParseUninstallLog 4895 !insertmacro un.GetParent 4896 !insertmacro un.LineFind 4897 !insertmacro un.TrimNewLines 4898 4899 !verbose push 4900 !verbose ${_MOZFUNC_VERBOSE} 4901 !define un.ParseUninstallLog "!insertmacro un.ParseUninstallLogCall" 4902 4903 Function un.ParseUninstallLog 4904 Push $R9 4905 Push $R8 4906 Push $R7 4907 Push $R6 4908 Push $R5 4909 Push $R4 4910 Push $R3 4911 Push $R2 4912 Push $R1 4913 Push $R0 4914 Push $TmpVal 4915 4916 IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end 4917 4918 ; Copy the uninstall log file to a temporary file 4919 GetTempFileName $TmpVal 4920 CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" 4921 4922 ; Unregister DLL's 4923 ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.UnRegDLLsCallback" 4924 4925 ; Delete files 4926 ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveFilesCallback" 4927 4928 ; Remove empty directories 4929 ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveDirsCallback" 4930 4931 ; Delete the temporary uninstall log file 4932 Delete /REBOOTOK "$TmpVal" 4933 4934 end: 4935 4936 Pop $TmpVal 4937 Pop $R0 4938 Pop $R1 4939 Pop $R2 4940 Pop $R3 4941 Pop $R4 4942 Pop $R5 4943 Pop $R6 4944 Pop $R7 4945 Pop $R8 4946 Pop $R9 4947 FunctionEnd 4948 4949 Function un.RemoveFilesCallback 4950 ${un.TrimNewLines} "$R9" $R9 4951 StrCpy $R1 "$R9" 5 4952 4953 StrCmp "$R1" "File:" +1 end 4954 StrCpy $R9 "$R9" "" 6 4955 StrCpy $R0 "$R9" 1 4956 4957 StrCpy $R1 "$INSTDIR$R9" 4958 StrCmp "$R0" "\" +2 +1 4959 StrCpy $R1 "$R9" 4960 4961 IfFileExists "$R1" +1 end 4962 Delete "$R1" 4963 IfErrors +1 end 4964 ClearErrors 4965 Rename "$R1" "$R1.moz-delete" 4966 IfErrors +1 +3 4967 Delete /REBOOTOK "$R1" 4968 GoTo end 4969 4970 Delete /REBOOTOK "$R1.moz-delete" 4971 4972 end: 4973 ClearErrors 4974 4975 Push 0 4976 FunctionEnd 4977 4978 Function un.UnRegDLLsCallback 4979 ${un.TrimNewLines} "$R9" $R9 4980 StrCpy $R1 "$R9" 7 4981 4982 StrCmp $R1 "DLLReg:" +1 end 4983 StrCpy $R9 "$R9" "" 8 4984 StrCpy $R0 "$R9" 1 4985 4986 StrCpy $R1 "$INSTDIR$R9" 4987 StrCmp $R0 "\" +2 +1 4988 StrCpy $R1 "$R9" 4989 4990 ${UnregisterDLL} $R1 4991 4992 end: 4993 ClearErrors 4994 4995 Push 0 4996 FunctionEnd 4997 4998 ; Using locate will leave file handles open to some of the directories 4999 ; which will prevent the deletion of these directories. This parses the 5000 ; uninstall.log and uses the file entries to find / remove empty 5001 ; directories. 5002 Function un.RemoveDirsCallback 5003 ${un.TrimNewLines} "$R9" $R9 5004 StrCpy $R0 "$R9" 5 ; Copy the first five chars 5005 StrCmp "$R0" "File:" +1 end 5006 5007 StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char 5008 StrCpy $R0 "$R9" 1 ; Copy the first char 5009 5010 StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string 5011 StrCmp "$R0" "\" loop ; If this is a relative path goto the loop 5012 StrCpy $R1 "$R9" ; Already a full path so copy the string 5013 5014 loop: 5015 ${un.GetParent} "$R1" $R1 ; Get the parent directory for the path 5016 StrCmp "$R1" "$INSTDIR" end ; If the directory is the install dir goto end 5017 5018 ; We only try to remove empty directories but the Desktop, StartMenu, and 5019 ; QuickLaunch directories can be empty so guard against removing them. 5020 SetShellVarContext all ; Set context to all users 5021 StrCmp "$R1" "$DESKTOP" end ; All users desktop 5022 StrCmp "$R1" "$STARTMENU" end ; All users start menu 5023 5024 SetShellVarContext current ; Set context to all users 5025 StrCmp "$R1" "$DESKTOP" end ; Current user desktop 5026 StrCmp "$R1" "$STARTMENU" end ; Current user start menu 5027 StrCmp "$R1" "$QUICKLAUNCH" end ; Current user quick launch 5028 5029 IfFileExists "$R1" +1 +3 ; Only try to remove the dir if it exists 5030 ClearErrors 5031 RmDir "$R1" ; Remove the dir 5032 IfErrors end ; If we fail there is no use trying to remove its parent dir 5033 5034 StrCmp "$R0" "\" loop end ; Only loop when the path is relative to the install dir 5035 5036 end: 5037 ClearErrors 5038 5039 Push 0 5040 FunctionEnd 5041 5042 !verbose pop 5043 !endif 5044!macroend 5045 5046!macro un.ParseUninstallLogCall 5047 !verbose push 5048 !verbose ${_MOZFUNC_VERBOSE} 5049 Call un.ParseUninstallLog 5050 !verbose pop 5051!macroend 5052 5053/** 5054 * Finds a valid Start Menu shortcut in the uninstall log and returns the 5055 * relative path from the Start Menu's Programs directory to the shortcut's 5056 * directory. 5057 * 5058 * When modifying this macro be aware that LineFind uses all registers except 5059 * $R0-$R3 so be cautious. Callers of this macro are not affected. 5060 * 5061 * @return _REL_PATH_TO_DIR 5062 * The relative path to the application's Start Menu directory from the 5063 * Start Menu's Programs directory. 5064 */ 5065!macro FindSMProgramsDir 5066 5067 !ifndef FindSMProgramsDir 5068 !insertmacro GetParent 5069 !insertmacro LineFind 5070 !insertmacro TrimNewLines 5071 5072 !verbose push 5073 !verbose ${_MOZFUNC_VERBOSE} 5074 !define FindSMProgramsDir "!insertmacro FindSMProgramsDirCall" 5075 5076 Function FindSMProgramsDir 5077 Exch $R3 5078 Push $R2 5079 Push $R1 5080 Push $R0 5081 5082 StrCpy $R3 "" 5083 ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log" 5084 ${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath" 5085 ${EndIf} 5086 ClearErrors 5087 5088 Pop $R0 5089 Pop $R1 5090 Pop $R2 5091 Exch $R3 5092 FunctionEnd 5093 5094 ; This callback MUST use labels vs. relative line numbers. 5095 Function FindSMProgramsDirRelPath 5096 Push 0 5097 ${TrimNewLines} "$R9" $R9 5098 StrCpy $R4 "$R9" 5 5099 5100 StrCmp "$R4" "File:" +1 end_FindSMProgramsDirRelPath 5101 StrCpy $R9 "$R9" "" 6 5102 StrCpy $R4 "$R9" 1 5103 5104 StrCmp "$R4" "\" end_FindSMProgramsDirRelPath +1 5105 5106 SetShellVarContext all 5107 ${GetLongPath} "$SMPROGRAMS" $R4 5108 StrLen $R2 "$R4" 5109 StrCpy $R1 "$R9" $R2 5110 StrCmp "$R1" "$R4" +1 end_FindSMProgramsDirRelPath 5111 IfFileExists "$R9" +1 end_FindSMProgramsDirRelPath 5112 ShellLink::GetShortCutTarget "$R9" 5113 Pop $R0 5114 StrCmp "$INSTDIR\${FileMainEXE}" "$R0" +1 end_FindSMProgramsDirRelPath 5115 ${GetParent} "$R9" $R3 5116 IntOp $R2 $R2 + 1 5117 StrCpy $R3 "$R3" "" $R2 5118 5119 Pop $R4 ; Remove the previously pushed 0 from the stack and 5120 push "StopLineFind" ; push StopLineFind to stop finding more lines. 5121 5122 end_FindSMProgramsDirRelPath: 5123 ClearErrors 5124 5125 FunctionEnd 5126 5127 !verbose pop 5128 !endif 5129!macroend 5130 5131!macro FindSMProgramsDirCall _REL_PATH_TO_DIR 5132 !verbose push 5133 !verbose ${_MOZFUNC_VERBOSE} 5134 Call FindSMProgramsDir 5135 Pop ${_REL_PATH_TO_DIR} 5136 !verbose pop 5137!macroend 5138 5139 5140################################################################################ 5141# Macros for custom branding 5142 5143/** 5144 * Sets BrandFullName and / or BrandShortName to values provided in the specified 5145 * ini file and defaults to BrandShortName and BrandFullName as defined in 5146 * branding.nsi when the associated ini file entry is not specified. 5147 * 5148 * ini file format: 5149 * [Branding] 5150 * BrandFullName=Custom Full Name 5151 * BrandShortName=Custom Short Name 5152 * 5153 * @param _PATH_TO_INI 5154 * Path to the ini file. 5155 * 5156 * $R6 = return value from ReadINIStr 5157 * $R7 = stores BrandShortName 5158 * $R8 = stores BrandFullName 5159 * $R9 = _PATH_TO_INI 5160 */ 5161!macro SetBrandNameVars 5162 5163 !ifndef ${_MOZFUNC_UN}SetBrandNameVars 5164 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 5165 !insertmacro ${_MOZFUNC_UN_TMP}WordReplace 5166 !undef _MOZFUNC_UN 5167 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 5168 !undef _MOZFUNC_UN_TMP 5169 5170 ; Prevent declaring vars twice when the SetBrandNameVars macro is 5171 ; inserted into both the installer and uninstaller. 5172 !ifndef SetBrandNameVars 5173 Var BrandFullName 5174 Var BrandFullNameDA 5175 Var BrandShortName 5176 Var BrandProductName 5177 !endif 5178 5179 !verbose push 5180 !verbose ${_MOZFUNC_VERBOSE} 5181 !define ${_MOZFUNC_UN}SetBrandNameVars "!insertmacro ${_MOZFUNC_UN}SetBrandNameVarsCall" 5182 5183 Function ${_MOZFUNC_UN}SetBrandNameVars 5184 Exch $R9 5185 Push $R8 5186 Push $R7 5187 Push $R6 5188 Push $R5 5189 5190 StrCpy $R8 "${BrandFullName}" 5191 StrCpy $R7 "${BrandShortName}" 5192 StrCpy $R6 "${BrandProductName}" 5193 5194 IfFileExists "$R9" +1 finish 5195 5196 ClearErrors 5197 ReadINIStr $R5 $R9 "Branding" "BrandFullName" 5198 IfErrors +2 +1 5199 StrCpy $R8 "$R5" 5200 5201 ClearErrors 5202 ReadINIStr $R5 $R9 "Branding" "BrandShortName" 5203 IfErrors +2 +1 5204 StrCpy $R7 "$R5" 5205 5206 ClearErrors 5207 ReadINIStr $R5 $R9 "Branding" "BrandProductName" 5208 IfErrors +2 +1 5209 StrCpy $R6 "$R5" 5210 5211 finish: 5212 StrCpy $BrandFullName "$R8" 5213 ${${_MOZFUNC_UN}WordReplace} "$R8" "&" "&&" "+" $R8 5214 StrCpy $BrandFullNameDA "$R8" 5215 StrCpy $BrandShortName "$R7" 5216 StrCpy $BrandProductName "$R6" 5217 5218 Pop $R5 5219 Pop $R6 5220 Pop $R7 5221 Pop $R8 5222 Exch $R9 5223 FunctionEnd 5224 5225 !verbose pop 5226 !endif 5227!macroend 5228 5229!macro SetBrandNameVarsCall _PATH_TO_INI 5230 !verbose push 5231 !verbose ${_MOZFUNC_VERBOSE} 5232 Push "${_PATH_TO_INI}" 5233 Call SetBrandNameVars 5234 !verbose pop 5235!macroend 5236 5237!macro un.SetBrandNameVarsCall _PATH_TO_INI 5238 !verbose push 5239 !verbose ${_MOZFUNC_VERBOSE} 5240 Push "${_PATH_TO_INI}" 5241 Call un.SetBrandNameVars 5242 !verbose pop 5243!macroend 5244 5245!macro un.SetBrandNameVars 5246 !ifndef un.SetBrandNameVars 5247 !verbose push 5248 !verbose ${_MOZFUNC_VERBOSE} 5249 !undef _MOZFUNC_UN 5250 !define _MOZFUNC_UN "un." 5251 5252 !insertmacro SetBrandNameVars 5253 5254 !undef _MOZFUNC_UN 5255 !define _MOZFUNC_UN 5256 !verbose pop 5257 !endif 5258!macroend 5259 5260/** 5261 * Replaces the wizard's header image with the one specified. 5262 * 5263 * @param _PATH_TO_IMAGE 5264 * Fully qualified path to the bitmap to use for the header image. 5265 * 5266 * $R8 = hwnd for the control returned from GetDlgItem. 5267 * $R9 = _PATH_TO_IMAGE 5268 */ 5269!macro ChangeMUIHeaderImage 5270 5271 !ifndef ${_MOZFUNC_UN}ChangeMUIHeaderImage 5272 Var hHeaderBitmap 5273 5274 !verbose push 5275 !verbose ${_MOZFUNC_VERBOSE} 5276 !define ${_MOZFUNC_UN}ChangeMUIHeaderImage "!insertmacro ${_MOZFUNC_UN}ChangeMUIHeaderImageCall" 5277 5278 Function ${_MOZFUNC_UN}ChangeMUIHeaderImage 5279 Exch $R9 5280 Push $R8 5281 5282 GetDlgItem $R8 $HWNDPARENT 1046 5283 ${SetStretchedImageOLE} $R8 "$R9" $hHeaderBitmap 5284 ; There is no way to specify a show function for a custom page so hide 5285 ; and then show the control to force the bitmap to redraw. 5286 ShowWindow $R8 ${SW_HIDE} 5287 ShowWindow $R8 ${SW_SHOW} 5288 5289 Pop $R8 5290 Exch $R9 5291 FunctionEnd 5292 5293 !verbose pop 5294 !endif 5295!macroend 5296 5297!macro ChangeMUIHeaderImageCall _PATH_TO_IMAGE 5298 !verbose push 5299 !verbose ${_MOZFUNC_VERBOSE} 5300 Push "${_PATH_TO_IMAGE}" 5301 Call ChangeMUIHeaderImage 5302 !verbose pop 5303!macroend 5304 5305!macro un.ChangeMUIHeaderImageCall _PATH_TO_IMAGE 5306 !verbose push 5307 !verbose ${_MOZFUNC_VERBOSE} 5308 Push "${_PATH_TO_IMAGE}" 5309 Call un.ChangeMUIHeaderImage 5310 !verbose pop 5311!macroend 5312 5313!macro un.ChangeMUIHeaderImage 5314 !ifndef un.ChangeMUIHeaderImage 5315 !verbose push 5316 !verbose ${_MOZFUNC_VERBOSE} 5317 !undef _MOZFUNC_UN 5318 !define _MOZFUNC_UN "un." 5319 5320 !insertmacro ChangeMUIHeaderImage 5321 5322 !undef _MOZFUNC_UN 5323 !define _MOZFUNC_UN 5324 !verbose pop 5325 !endif 5326!macroend 5327 5328/** 5329 * Replaces the sidebar image on the wizard's welcome and finish pages. 5330 * 5331 * @param _PATH_TO_IMAGE 5332 * Fully qualified path to the bitmap to use for the header image. 5333 * 5334 * $R8 = hwnd for the bitmap control 5335 * $R9 = _PATH_TO_IMAGE 5336 */ 5337!macro ChangeMUISidebarImage 5338 5339 !ifndef ${_MOZFUNC_UN}ChangeMUISidebarImage 5340 Var hSidebarBitmap 5341 5342 !verbose push 5343 !verbose ${_MOZFUNC_VERBOSE} 5344 !define ${_MOZFUNC_UN}ChangeMUISidebarImage "!insertmacro ${_MOZFUNC_UN}ChangeMUISidebarImageCall" 5345 5346 Function ${_MOZFUNC_UN}ChangeMUISidebarImage 5347 Exch $R9 5348 Push $R8 5349 5350 ; Make sure we're not about to leak an existing handle. 5351 ${If} $hSidebarBitmap <> 0 5352 System::Call "gdi32::DeleteObject(p $hSidebarBitmap)" 5353 StrCpy $hSidebarBitmap 0 5354 ${EndIf} 5355 ; The controls on the welcome and finish pages aren't in the dialog 5356 ; template, they're always created manually from the INI file, so we need 5357 ; to query it to find the right HWND. 5358 ReadINIStr $R8 "$PLUGINSDIR\ioSpecial.ini" "Field 1" "HWND" 5359 ${SetStretchedImageOLE} $R8 "$R9" $hSidebarBitmap 5360 5361 Pop $R8 5362 Exch $R9 5363 FunctionEnd 5364 5365 !verbose pop 5366 !endif 5367!macroend 5368 5369!macro ChangeMUISidebarImageCall _PATH_TO_IMAGE 5370 !verbose push 5371 !verbose ${_MOZFUNC_VERBOSE} 5372 Push "${_PATH_TO_IMAGE}" 5373 Call ChangeMUISidebarImage 5374 !verbose pop 5375!macroend 5376 5377!macro un.ChangeMUISidebarImageCall _PATH_TO_IMAGE 5378 !verbose push 5379 !verbose ${_MOZFUNC_VERBOSE} 5380 Push "${_PATH_TO_IMAGE}" 5381 Call un.ChangeMUISidebarImage 5382 !verbose pop 5383!macroend 5384 5385!macro un.ChangeMUISidebarImage 5386 !ifndef un.ChangeMUISidebarImage 5387 !verbose push 5388 !verbose ${_MOZFUNC_VERBOSE} 5389 !undef _MOZFUNC_UN 5390 !define _MOZFUNC_UN "un." 5391 5392 !insertmacro ChangeMUISidebarImage 5393 5394 !undef _MOZFUNC_UN 5395 !define _MOZFUNC_UN 5396 !verbose pop 5397 !endif 5398!macroend 5399 5400################################################################################ 5401# User interface callback helper defines and macros 5402 5403/* Install type defines */ 5404!ifndef INSTALLTYPE_BASIC 5405 !define INSTALLTYPE_BASIC 1 5406!endif 5407 5408!ifndef INSTALLTYPE_CUSTOM 5409 !define INSTALLTYPE_CUSTOM 2 5410!endif 5411 5412/** 5413 * Checks whether to display the current page (e.g. if not performing a custom 5414 * install don't display the custom pages). 5415 */ 5416!macro CheckCustomCommon 5417 5418 !ifndef CheckCustomCommon 5419 !verbose push 5420 !verbose ${_MOZFUNC_VERBOSE} 5421 !define CheckCustomCommon "!insertmacro CheckCustomCommonCall" 5422 5423 Function CheckCustomCommon 5424 5425 ; Abort if not a custom install 5426 IntCmp $InstallType ${INSTALLTYPE_CUSTOM} +2 +1 +1 5427 Abort 5428 5429 FunctionEnd 5430 5431 !verbose pop 5432 !endif 5433!macroend 5434 5435!macro CheckCustomCommonCall 5436 !verbose push 5437 !verbose ${_MOZFUNC_VERBOSE} 5438 Call CheckCustomCommon 5439 !verbose pop 5440!macroend 5441 5442/** 5443 * Unloads dll's and releases references when the installer and uninstaller 5444 * exit. 5445 */ 5446!macro OnEndCommon 5447 5448 !ifndef ${_MOZFUNC_UN}OnEndCommon 5449 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 5450 !insertmacro ${_MOZFUNC_UN_TMP}UnloadUAC 5451 !undef _MOZFUNC_UN 5452 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 5453 !undef _MOZFUNC_UN_TMP 5454 5455 !verbose push 5456 !verbose ${_MOZFUNC_VERBOSE} 5457 !define ${_MOZFUNC_UN}OnEndCommon "!insertmacro ${_MOZFUNC_UN}OnEndCommonCall" 5458 5459 Function ${_MOZFUNC_UN}OnEndCommon 5460 5461 ${${_MOZFUNC_UN}UnloadUAC} 5462 StrCmp $hHeaderBitmap "" +3 +1 5463 System::Call "gdi32::DeleteObject(i s)" $hHeaderBitmap 5464 StrCpy $hHeaderBitmap "" 5465 ; If ChangeMUISidebarImage was called, then we also need to clean up the 5466 ; GDI bitmap handle that it would have created. 5467 !ifdef ${_MOZFUNC_UN}ChangeMUISidebarImage 5468 StrCmp $hSidebarBitmap "" +3 +1 5469 System::Call "gdi32::DeleteObject(i s)" $hSidebarBitmap 5470 StrCpy $hSidebarBitmap "" 5471 !endif 5472 5473 System::Free 0 5474 5475 FunctionEnd 5476 5477 !verbose pop 5478 !endif 5479!macroend 5480 5481!macro OnEndCommonCall 5482 !verbose push 5483 !verbose ${_MOZFUNC_VERBOSE} 5484 Call OnEndCommon 5485 !verbose pop 5486!macroend 5487 5488!macro un.OnEndCommonCall 5489 !verbose push 5490 !verbose ${_MOZFUNC_VERBOSE} 5491 Call un.OnEndCommon 5492 !verbose pop 5493!macroend 5494 5495!macro un.OnEndCommon 5496 !ifndef un.OnEndCommon 5497 !verbose push 5498 !verbose ${_MOZFUNC_VERBOSE} 5499 !undef _MOZFUNC_UN 5500 !define _MOZFUNC_UN "un." 5501 5502 !insertmacro OnEndCommon 5503 5504 !undef _MOZFUNC_UN 5505 !define _MOZFUNC_UN 5506 !verbose pop 5507 !endif 5508!macroend 5509 5510/** 5511 * Reads a flag option from the command line and sets a variable with its state, 5512 * if the option is present on the command line. 5513 * 5514 * @param FULL_COMMAND_LINE 5515 * The entire installer command line, such as from ${GetParameters} 5516 * @param OPTION 5517 * Name of the option to look for 5518 * @param OUTPUT 5519 * Variable/register to write the output to. Will be set to "0" if the 5520 * option was present with the value "false", will be set to "1" if the 5521 * option was present with another value, and will be untouched if the 5522 * option was not on the command line at all. 5523 */ 5524!macro InstallGetOption FULL_COMMAND_LINE OPTION OUTPUT 5525 Push $0 5526 ClearErrors 5527 ${GetOptions} ${FULL_COMMAND_LINE} "/${OPTION}" $0 5528 ${IfNot} ${Errors} 5529 ; Any valid command-line option triggers a silent installation. 5530 SetSilent silent 5531 5532 ${If} $0 == "=false" 5533 StrCpy ${OUTPUT} "0" 5534 ${Else} 5535 StrCpy ${OUTPUT} "1" 5536 ${EndIf} 5537 ${EndIf} 5538 Pop $0 5539!macroend 5540!define InstallGetOption "!insertmacro InstallGetOption" 5541 5542/** 5543 * Called from the installer's .onInit function not to be confused with the 5544 * uninstaller's .onInit or the uninstaller's un.onInit functions. 5545 * 5546 * @param _WARN_UNSUPPORTED_MSG 5547 * Message displayed when the Windows version is not supported. 5548 * 5549 * $R4 = keeps track of whether a custom install path was specified on either 5550 * the command line or in an INI file 5551 * $R5 = return value from the GetSize macro 5552 * $R6 = general string values, return value from GetTempFileName, return 5553 * value from the GetSize macro 5554 * $R7 = full path to the configuration ini file 5555 * $R8 = used for OS Version and Service Pack detection and the return value 5556 * from the GetParameters macro 5557 * $R9 = _WARN_UNSUPPORTED_MSG 5558 */ 5559!macro InstallOnInitCommon 5560 5561 !ifndef InstallOnInitCommon 5562 !insertmacro ElevateUAC 5563 !insertmacro GetOptions 5564 !insertmacro GetParameters 5565 !insertmacro GetSize 5566 5567 !verbose push 5568 !verbose ${_MOZFUNC_VERBOSE} 5569 !define InstallOnInitCommon "!insertmacro InstallOnInitCommonCall" 5570 5571 Function InstallOnInitCommon 5572 Exch $R9 5573 Push $R8 5574 Push $R7 5575 Push $R6 5576 Push $R5 5577 Push $R4 5578 5579 ; Don't install on systems that don't support SSE2. The parameter value of 5580 ; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the 5581 ; SSE2 instruction set is available. 5582 System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R8" 5583 ${If} "$R8" == "0" 5584 MessageBox MB_OK|MB_ICONSTOP "$R9" 5585 ; Nothing initialized so no need to call OnEndCommon 5586 Quit 5587 ${EndIf} 5588 5589 ; Windows NT 6.0 (Vista/Server 2008) and lower are not supported. 5590 ${Unless} ${AtLeastWin7} 5591 MessageBox MB_OK|MB_ICONSTOP "$R9" 5592 ; Nothing initialized so no need to call OnEndCommon 5593 Quit 5594 ${EndUnless} 5595 5596 !ifdef HAVE_64BIT_BUILD 5597 SetRegView 64 5598 !endif 5599 5600 StrCpy $R4 0 ; will be set to 1 if a custom install path is set 5601 5602 ${GetParameters} $R8 5603 ${If} $R8 != "" 5604 ; Default install type 5605 StrCpy $InstallType ${INSTALLTYPE_BASIC} 5606 5607 ${Unless} ${Silent} 5608 ; NSIS should check for /S for us, but we've had issues with it such 5609 ; as bug 506867 in the past, so we'll check for it ourselves also. 5610 ClearErrors 5611 ${GetOptions} "$R8" "/S" $R7 5612 ${Unless} ${Errors} 5613 SetSilent silent 5614 ${Else} 5615 ; NSIS dropped support for the deprecated -ms argument, but we don't 5616 ; want to break backcompat, so we'll check for it here too. 5617 ClearErrors 5618 ${GetOptions} "$R8" "-ms" $R7 5619 ${Unless} ${Errors} 5620 SetSilent silent 5621 ${EndUnless} 5622 ${EndUnless} 5623 ${EndUnless} 5624 5625 ; Support for specifying an installation configuration file. 5626 ClearErrors 5627 ${GetOptions} "$R8" "/INI=" $R7 5628 ${Unless} ${Errors} 5629 ; The configuration file must also exist 5630 ${If} ${FileExists} "$R7" 5631 ; Any valid command-line option triggers a silent installation. 5632 SetSilent silent 5633 5634 ReadINIStr $R8 $R7 "Install" "InstallDirectoryName" 5635 ${If} $R8 != "" 5636 StrCpy $R4 1 5637 !ifdef HAVE_64BIT_BUILD 5638 StrCpy $INSTDIR "$PROGRAMFILES64\$R8" 5639 !else 5640 StrCpy $INSTDIR "$PROGRAMFILES32\$R8" 5641 !endif 5642 ${Else} 5643 ReadINIStr $R8 $R7 "Install" "InstallDirectoryPath" 5644 ${If} $R8 != "" 5645 StrCpy $R4 1 5646 StrCpy $INSTDIR "$R8" 5647 ${EndIf} 5648 ${EndIf} 5649 5650 ReadINIStr $R8 $R7 "Install" "QuickLaunchShortcut" 5651 ${If} $R8 == "false" 5652 StrCpy $AddQuickLaunchSC "0" 5653 ${Else} 5654 StrCpy $AddQuickLaunchSC "1" 5655 ${EndIf} 5656 5657 ReadINIStr $R8 $R7 "Install" "DesktopShortcut" 5658 ${If} $R8 == "false" 5659 StrCpy $AddDesktopSC "0" 5660 ${Else} 5661 StrCpy $AddDesktopSC "1" 5662 ${EndIf} 5663 5664 ReadINIStr $R8 $R7 "Install" "StartMenuShortcuts" 5665 ${If} $R8 == "false" 5666 StrCpy $AddStartMenuSC "0" 5667 ${Else} 5668 StrCpy $AddStartMenuSC "1" 5669 ${EndIf} 5670 5671 ; We still accept the plural version for backwards compatibility, 5672 ; but the singular version takes priority. 5673 ClearErrors 5674 ReadINIStr $R8 $R7 "Install" "StartMenuShortcut" 5675 ${If} $R8 == "false" 5676 StrCpy $AddStartMenuSC "0" 5677 ${ElseIfNot} ${Errors} 5678 StrCpy $AddStartMenuSC "1" 5679 ${EndIf} 5680 5681 ReadINIStr $R8 $R7 "Install" "TaskbarShortcut" 5682 ${If} $R8 == "false" 5683 StrCpy $AddTaskbarSC "0" 5684 ${Else} 5685 StrCpy $AddTaskbarSC "1" 5686 ${EndIf} 5687 5688 ReadINIStr $R8 $R7 "Install" "MaintenanceService" 5689 ${If} $R8 == "false" 5690 StrCpy $InstallMaintenanceService "0" 5691 ${Else} 5692 StrCpy $InstallMaintenanceService "1" 5693 ${EndIf} 5694 5695 ReadINIStr $R8 $R7 "Install" "RegisterDefaultAgent" 5696 ${If} $R8 == "false" 5697 StrCpy $RegisterDefaultAgent "0" 5698 ${Else} 5699 StrCpy $RegisterDefaultAgent "1" 5700 ${EndIf} 5701 5702 !ifdef MOZ_OPTIONAL_EXTENSIONS 5703 ReadINIStr $R8 $R7 "Install" "OptionalExtensions" 5704 ${If} $R8 == "false" 5705 StrCpy $InstallOptionalExtensions "0" 5706 ${Else} 5707 StrCpy $InstallOptionalExtensions "1" 5708 ${EndIf} 5709 !endif 5710 5711 !ifndef NO_STARTMENU_DIR 5712 ReadINIStr $R8 $R7 "Install" "StartMenuDirectoryName" 5713 ${If} $R8 != "" 5714 StrCpy $StartMenuDir "$R8" 5715 ${EndIf} 5716 !endif 5717 ${EndIf} 5718 ${EndUnless} 5719 5720 ; Check for individual command line parameters after evaluating the INI 5721 ; file, because these should override the INI entires. 5722 ${GetParameters} $R8 5723 ${GetOptions} $R8 "/InstallDirectoryName=" $R7 5724 ${If} $R7 != "" 5725 StrCpy $R4 1 5726 !ifdef HAVE_64BIT_BUILD 5727 StrCpy $INSTDIR "$PROGRAMFILES64\$R7" 5728 !else 5729 StrCpy $INSTDIR "$PROGRAMFILES32\$R7" 5730 !endif 5731 ${Else} 5732 ${GetOptions} $R8 "/InstallDirectoryPath=" $R7 5733 ${If} $R7 != "" 5734 StrCpy $R4 1 5735 StrCpy $INSTDIR "$R7" 5736 ${EndIf} 5737 ${EndIf} 5738 5739 ${InstallGetOption} $R8 "QuickLaunchShortcut" $AddQuickLaunchSC 5740 ${InstallGetOption} $R8 "DesktopShortcut" $AddDesktopSC 5741 ${InstallGetOption} $R8 "StartMenuShortcuts" $AddStartMenuSC 5742 ; We still accept the plural version for backwards compatibility, 5743 ; but the singular version takes priority. 5744 ${InstallGetOption} $R8 "StartMenuShortcut" $AddStartMenuSC 5745 ${InstallGetOption} $R8 "TaskbarShortcut" $AddTaskbarSC 5746 ${InstallGetOption} $R8 "MaintenanceService" $InstallMaintenanceService 5747 ${InstallGetOption} $R8 "RegisterDefaultAgent" $RegisterDefaultAgent 5748 !ifdef MOZ_OPTIONAL_EXTENSIONS 5749 ${InstallGetOption} $R8 "OptionalExtensions" $InstallOptionalExtensions 5750 !endif 5751 5752 ; Installing the service always requires elevated privileges. 5753 ${If} $InstallMaintenanceService == "1" 5754 ${ElevateUAC} 5755 ${EndIf} 5756 ${EndIf} 5757 5758 ${If} $R4 == 1 5759 ; Any valid command-line option triggers a silent installation. 5760 SetSilent silent 5761 5762 ; Quit if we are unable to create the installation directory or we are 5763 ; unable to write to a file in the installation directory. 5764 ClearErrors 5765 ${If} ${FileExists} "$INSTDIR" 5766 GetTempFileName $R6 "$INSTDIR" 5767 FileOpen $R5 "$R6" w 5768 FileWrite $R5 "Write Access Test" 5769 FileClose $R5 5770 Delete $R6 5771 ${If} ${Errors} 5772 ; Attempt to elevate and then try again. 5773 ${ElevateUAC} 5774 GetTempFileName $R6 "$INSTDIR" 5775 FileOpen $R5 "$R6" w 5776 FileWrite $R5 "Write Access Test" 5777 FileClose $R5 5778 Delete $R6 5779 ${If} ${Errors} 5780 ; Nothing initialized so no need to call OnEndCommon 5781 Quit 5782 ${EndIf} 5783 ${EndIf} 5784 ${Else} 5785 CreateDirectory "$INSTDIR" 5786 ${If} ${Errors} 5787 ; Attempt to elevate and then try again. 5788 ${ElevateUAC} 5789 CreateDirectory "$INSTDIR" 5790 ${If} ${Errors} 5791 ; Nothing initialized so no need to call OnEndCommon 5792 Quit 5793 ${EndIf} 5794 ${EndIf} 5795 ${EndIf} 5796 ${Else} 5797 ; If we weren't given a custom path parameter, then try to elevate now. 5798 ; We'll check the user's permission level later on to determine the 5799 ; default install path (which will be the real install path for /S). 5800 ; If an INI file is used, we try to elevate down that path when needed. 5801 ${ElevateUAC} 5802 ${EndIf} 5803 5804 Pop $R4 5805 Pop $R5 5806 Pop $R6 5807 Pop $R7 5808 Pop $R8 5809 Exch $R9 5810 FunctionEnd 5811 5812 !verbose pop 5813 !endif 5814!macroend 5815 5816!macro InstallOnInitCommonCall _WARN_UNSUPPORTED_MSG 5817 !verbose push 5818 !verbose ${_MOZFUNC_VERBOSE} 5819 Push "${_WARN_UNSUPPORTED_MSG}" 5820 Call InstallOnInitCommon 5821 !verbose pop 5822!macroend 5823 5824/** 5825 * Called from the uninstaller's .onInit function not to be confused with the 5826 * installer's .onInit or the uninstaller's un.onInit functions. 5827 */ 5828!macro UninstallOnInitCommon 5829 5830 !ifndef UninstallOnInitCommon 5831 !insertmacro ElevateUAC 5832 !insertmacro GetLongPath 5833 !insertmacro GetOptions 5834 !insertmacro GetParameters 5835 !insertmacro GetParent 5836 !insertmacro UnloadUAC 5837 !insertmacro UpdateShortcutAppModelIDs 5838 !insertmacro UpdateUninstallLog 5839 5840 !verbose push 5841 !verbose ${_MOZFUNC_VERBOSE} 5842 !define UninstallOnInitCommon "!insertmacro UninstallOnInitCommonCall" 5843 5844 Function UninstallOnInitCommon 5845 ; Prevents breaking apps that don't use SetBrandNameVars 5846 !ifdef SetBrandNameVars 5847 ${SetBrandNameVars} "$EXEDIR\distribution\setup.ini" 5848 !endif 5849 5850 ; Prevent launching the application when a reboot is required and this 5851 ; executable is the main application executable 5852 IfFileExists "$EXEDIR\${FileMainEXE}.moz-upgrade" +1 +4 5853 MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 5854 Reboot 5855 Quit ; Nothing initialized so no need to call OnEndCommon 5856 5857 ${GetParent} "$EXEDIR" $INSTDIR 5858 ${GetLongPath} "$INSTDIR" $INSTDIR 5859 IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1 5860 Quit ; Nothing initialized so no need to call OnEndCommon 5861 5862!ifmacrodef InitHashAppModelId 5863 ; setup the application model id registration value 5864 !ifdef AppName 5865 ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" 5866 !endif 5867!endif 5868 5869 ; Prevents breaking apps that don't use SetBrandNameVars 5870 !ifdef SetBrandNameVars 5871 ${SetBrandNameVars} "$INSTDIR\distribution\setup.ini" 5872 !endif 5873 5874 ; Application update uses a directory named tobedeleted in the $INSTDIR to 5875 ; delete files on OS reboot when they are in use. Try to delete this 5876 ; directory if it exists. 5877 ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" 5878 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 5879 ${EndIf} 5880 5881 ; Prevent all operations (e.g. set as default, postupdate, etc.) when a 5882 ; reboot is required and the executable launched is helper.exe 5883 IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4 5884 MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 5885 Reboot 5886 Quit ; Nothing initialized so no need to call OnEndCommon 5887 5888 !ifdef HAVE_64BIT_BUILD 5889 SetRegView 64 5890 !endif 5891 5892 ${GetParameters} $R0 5893 5894 ${Unless} ${Silent} 5895 ; Manually check for /S in the command line due to Bug 506867 5896 ClearErrors 5897 ${GetOptions} "$R0" "/S" $R2 5898 ${Unless} ${Errors} 5899 SetSilent silent 5900 ${Else} 5901 ; Support for the deprecated -ms command line argument. 5902 ClearErrors 5903 ${GetOptions} "$R0" "-ms" $R2 5904 ${Unless} ${Errors} 5905 SetSilent silent 5906 ${EndUnless} 5907 ${EndUnless} 5908 ${EndUnless} 5909 5910 StrCmp "$R0" "" continue +1 5911 5912 ; Require elevation if the user can elevate 5913 hideshortcuts: 5914 ClearErrors 5915 ${GetOptions} "$R0" "/HideShortcuts" $R2 5916 IfErrors showshortcuts +1 5917!ifndef NONADMIN_ELEVATE 5918 ${ElevateUAC} 5919!endif 5920 ${HideShortcuts} 5921 GoTo finish 5922 5923 ; Require elevation if the user can elevate 5924 showshortcuts: 5925 ClearErrors 5926 ${GetOptions} "$R0" "/ShowShortcuts" $R2 5927 IfErrors defaultappuser +1 5928!ifndef NONADMIN_ELEVATE 5929 ${ElevateUAC} 5930!endif 5931 ${ShowShortcuts} 5932 GoTo finish 5933 5934 ; Require elevation if the the StartMenuInternet registry keys require 5935 ; updating and the user can elevate 5936 defaultappuser: 5937 ClearErrors 5938 ${GetOptions} "$R0" "/SetAsDefaultAppUser" $R2 5939 IfErrors defaultappglobal +1 5940 ${SetAsDefaultAppUser} 5941 GoTo finish 5942 5943 ; Require elevation if the user can elevate 5944 defaultappglobal: 5945 ClearErrors 5946 ${GetOptions} "$R0" "/SetAsDefaultAppGlobal" $R2 5947 IfErrors postupdate +1 5948 ${ElevateUAC} 5949 ${SetAsDefaultAppGlobal} 5950 GoTo finish 5951 5952 ; Do not attempt to elevate. The application launching this executable is 5953 ; responsible for elevation if it is required. 5954 postupdate: 5955 ${WordReplace} "$R0" "$\"" "" "+" $R0 5956 ClearErrors 5957 ${GetOptions} "$R0" "/PostUpdate" $R2 5958 IfErrors continue +1 5959 ; If the uninstall.log does not exist don't perform post update 5960 ; operations. This prevents updating the registry for zip builds. 5961 IfFileExists "$EXEDIR\uninstall.log" +2 +1 5962 Quit ; Nothing initialized so no need to call OnEndCommon 5963 ${PostUpdate} 5964 ClearErrors 5965 ${GetOptions} "$R0" "/UninstallLog=" $R2 5966 IfErrors updateuninstalllog +1 5967 StrCmp "$R2" "" finish +1 5968 GetFullPathName $R3 "$R2" 5969 IfFileExists "$R3" +1 finish 5970 Delete "$INSTDIR\uninstall\*wizard*" 5971 Delete "$INSTDIR\uninstall\uninstall.log" 5972 CopyFiles /SILENT /FILESONLY "$R3" "$INSTDIR\uninstall\" 5973 ${GetParent} "$R3" $R4 5974 Delete "$R3" 5975 RmDir "$R4" 5976 GoTo finish 5977 5978 ; Do not attempt to elevate. The application launching this executable is 5979 ; responsible for elevation if it is required. 5980 updateuninstalllog: 5981 ${UpdateUninstallLog} 5982 5983 finish: 5984 ${UnloadUAC} 5985 ${RefreshShellIcons} 5986 Quit ; Nothing initialized so no need to call OnEndCommon 5987 5988 continue: 5989 5990 ; If the uninstall.log does not exist don't perform uninstall 5991 ; operations. This prevents running the uninstaller for zip builds. 5992 IfFileExists "$INSTDIR\uninstall\uninstall.log" +2 +1 5993 Quit ; Nothing initialized so no need to call OnEndCommon 5994 5995 ; When silent, try to avoid elevation if we have a chance to succeed. We 5996 ; can succeed when we can write to (hence delete from) the install 5997 ; directory and when we can clean up all registry entries. Now, the 5998 ; installer when elevated writes privileged registry entries for the use 5999 ; of the Maintenance Service, even when the service is not and will not be 6000 ; installed. (In fact, even when a service installed in the future will 6001 ; never update the installation, for example due to not being in a 6002 ; privileged location.) In practice this means we can only truly silently 6003 ; remove an unelevated install: an elevated installer writing to an 6004 ; unprivileged install directory will still write privileged registry 6005 ; entries, requiring an elevated uninstaller to completely clean up. 6006 ; 6007 ; This avoids a wrinkle, whereby an uninstaller which runs unelevated will 6008 ; never itself launch the Maintenance Service uninstaller, because it will 6009 ; fail to remove its own service registration (removing the relevant 6010 ; registry key would require elevation). Therefore the check for the 6011 ; service being unused will fail, which will prevent running the service 6012 ; uninstaller. That's both subtle and possibly leaves the service 6013 ; registration hanging around, which might be a security risk. 6014 ; 6015 ; That is why we look for a privileged service registration for this 6016 ; installation when deciding to elevate, and elevate unconditionally if we 6017 ; find one, regardless of the result of the write check that would avoid 6018 ; elevation. 6019 6020 ; The reason for requiring elevation, or "" for not required. 6021 StrCpy $R4 "" 6022 6023 ${IfNot} ${Silent} 6024 ; In normal operation, require elevation if the user can elevate so that 6025 ; we are most likely to succeed. 6026 StrCpy $R4 "not silent" 6027 ${EndIf} 6028 6029 GetTempFileName $R6 "$INSTDIR" 6030 FileOpen $R5 "$R6" w 6031 FileWrite $R5 "Write Access Test" 6032 FileClose $R5 6033 Delete $R6 6034 ${If} ${Errors} 6035 StrCpy $R4 "write" 6036 ${EndIf} 6037 6038 !ifdef MOZ_MAINTENANCE_SERVICE 6039 ; We don't necessarily have $MaintCertKey, so use temporary registers. 6040 ServicesHelper::PathToUniqueRegistryPath "$INSTDIR" 6041 Pop $R5 6042 6043 ${If} $R5 != "" 6044 ; Always use the 64bit registry for certs on 64bit systems. 6045 ${If} ${RunningX64} 6046 ${OrIf} ${IsNativeARM64} 6047 SetRegView 64 6048 ${EndIf} 6049 6050 EnumRegKey $R6 HKLM $R5 0 6051 ClearErrors 6052 6053 ${If} ${RunningX64} 6054 ${OrIf} ${IsNativeARM64} 6055 SetRegView lastused 6056 ${EndIf} 6057 6058 ${IfNot} "$R6" == "" 6059 StrCpy $R4 "mms" 6060 ${EndIf} 6061 ${EndIf} 6062 !endif 6063 6064 ${If} "$R4" != "" 6065 ; In the future, we might not try to elevate to remain truly silent. Or 6066 ; we might add a command line arguments to specify behaviour. One 6067 ; reason to not do that immediately is that we have no great way to 6068 ; signal that we exited without taking action. 6069 ${ElevateUAC} 6070 ${EndIf} 6071 6072 ; Now we've elevated, try the write access test again. 6073 ClearErrors 6074 GetTempFileName $R6 "$INSTDIR" 6075 FileOpen $R5 "$R6" w 6076 FileWrite $R5 "Write Access Test" 6077 FileClose $R5 6078 Delete $R6 6079 ${If} ${Errors} 6080 ; Nothing initialized so no need to call OnEndCommon 6081 Quit 6082 ${EndIf} 6083 6084 !ifdef MOZ_MAINTENANCE_SERVICE 6085 ; And verify that if we need to, we're going to clean up the registry 6086 ; correctly. 6087 ${If} "$R4" == "mms" 6088 WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" 6089 ${If} ${Errors} 6090 ; Nothing initialized so no need to call OnEndCommon 6091 Quit 6092 ${Endif} 6093 DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" 6094 ${EndIf} 6095 !endif 6096 6097 ; If we made it this far then this installer is being used as an uninstaller. 6098 WriteUninstaller "$EXEDIR\uninstaller.exe" 6099 6100 ${If} ${Silent} 6101 StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\" /S" 6102 ${Else} 6103 StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\"" 6104 ${EndIf} 6105 6106 ; When the uninstaller is launched it copies itself to the temp directory 6107 ; so it won't be in use so it can delete itself. 6108 ExecWait $R1 6109 ${DeleteFile} "$EXEDIR\uninstaller.exe" 6110 ${UnloadUAC} 6111 SetErrorLevel 0 6112 Quit ; Nothing initialized so no need to call OnEndCommon 6113 6114 FunctionEnd 6115 6116 !verbose pop 6117 !endif 6118!macroend 6119 6120!macro UninstallOnInitCommonCall 6121 !verbose push 6122 !verbose ${_MOZFUNC_VERBOSE} 6123 Call UninstallOnInitCommon 6124 !verbose pop 6125!macroend 6126 6127/** 6128 * Called from the uninstaller's un.onInit function not to be confused with the 6129 * installer's .onInit or the uninstaller's .onInit functions. 6130 */ 6131!macro un.UninstallUnOnInitCommon 6132 6133 !ifndef un.UninstallUnOnInitCommon 6134 !insertmacro un.GetLongPath 6135 !insertmacro un.GetParent 6136 !insertmacro un.SetBrandNameVars 6137 6138 !verbose push 6139 !verbose ${_MOZFUNC_VERBOSE} 6140 !define un.UninstallUnOnInitCommon "!insertmacro un.UninstallUnOnInitCommonCall" 6141 6142 Function un.UninstallUnOnInitCommon 6143 ${un.GetParent} "$INSTDIR" $INSTDIR 6144 ${un.GetLongPath} "$INSTDIR" $INSTDIR 6145 ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}" 6146 Abort 6147 ${EndUnless} 6148 6149 !ifdef HAVE_64BIT_BUILD 6150 SetRegView 64 6151 !endif 6152 6153 ; Prevents breaking apps that don't use SetBrandNameVars 6154 !ifdef un.SetBrandNameVars 6155 ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini" 6156 !endif 6157 6158 ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if 6159 ; the user clicks the back button 6160 StrCpy $hHeaderBitmap "" 6161 FunctionEnd 6162 6163 !verbose pop 6164 !endif 6165!macroend 6166 6167!macro un.UninstallUnOnInitCommonCall 6168 !verbose push 6169 !verbose ${_MOZFUNC_VERBOSE} 6170 Call un.UninstallUnOnInitCommon 6171 !verbose pop 6172!macroend 6173 6174/** 6175 * Called from the MUI leaveOptions function to set the value of $INSTDIR. 6176 */ 6177!macro LeaveOptionsCommon 6178 6179 !ifndef LeaveOptionsCommon 6180 !insertmacro CanWriteToInstallDir 6181 !insertmacro GetLongPath 6182 6183!ifndef NO_INSTDIR_FROM_REG 6184 !insertmacro GetSingleInstallPath 6185!endif 6186 6187 !verbose push 6188 !verbose ${_MOZFUNC_VERBOSE} 6189 !define LeaveOptionsCommon "!insertmacro LeaveOptionsCommonCall" 6190 6191 Function LeaveOptionsCommon 6192 Push $R9 6193 6194 StrCpy $R9 "false" 6195 6196!ifndef NO_INSTDIR_FROM_REG 6197 SetShellVarContext all ; Set SHCTX to HKLM 6198 6199 ${If} ${IsNativeAMD64} 6200 ${OrIf} ${IsNativeARM64} 6201 SetRegView 64 6202 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 6203 SetRegView lastused 6204 ${EndIf} 6205 6206 StrCmp "$R9" "false" +1 finish_get_install_dir 6207 6208 SetRegView 32 6209 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 6210 SetRegView lastused 6211 6212 StrCmp "$R9" "false" +1 finish_get_install_dir 6213 6214 SetShellVarContext current ; Set SHCTX to HKCU 6215 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 6216 6217 finish_get_install_dir: 6218 StrCmp "$R9" "false" +2 +1 6219 StrCpy $INSTDIR "$R9" 6220!endif 6221 6222 ; If the user doesn't have write access to the installation directory set 6223 ; the installation directory to a subdirectory of the All Users application 6224 ; directory and if the user can't write to that location set the installation 6225 ; directory to a subdirectory of the users local application directory 6226 ; (e.g. non-roaming). 6227 ${CanWriteToInstallDir} $R9 6228 StrCmp "$R9" "false" +1 finish_check_install_dir 6229 6230 SetShellVarContext all ; Set SHCTX to All Users 6231 StrCpy $INSTDIR "$APPDATA\${BrandFullName}\" 6232 ${CanWriteToInstallDir} $R9 6233 StrCmp "$R9" "false" +2 +1 6234 StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\" 6235 6236 finish_check_install_dir: 6237 IfFileExists "$INSTDIR" +3 +1 6238 Pop $R9 6239 Return 6240 6241 ; Always display the long path if the path already exists. 6242 ${GetLongPath} "$INSTDIR" $INSTDIR 6243 6244 ; The call to GetLongPath returns a long path without a trailing 6245 ; back-slash. Append a \ to the path to prevent the directory 6246 ; name from being appended when using the NSIS create new folder. 6247 ; http://www.nullsoft.com/free/nsis/makensis.htm#InstallDir 6248 StrCpy $INSTDIR "$INSTDIR\" 6249 6250 Pop $R9 6251 FunctionEnd 6252 6253 !verbose pop 6254 !endif 6255!macroend 6256 6257!macro LeaveOptionsCommonCall 6258 !verbose push 6259 !verbose ${_MOZFUNC_VERBOSE} 6260 Call LeaveOptionsCommon 6261 !verbose pop 6262!macroend 6263 6264/** 6265 * Called from the MUI preDirectory function to verify there is enough disk 6266 * space for the installation and the installation directory is writable. 6267 * 6268 * $R9 = returned value from CheckDiskSpace and CanWriteToInstallDir macros 6269 */ 6270!macro PreDirectoryCommon 6271 6272 !ifndef PreDirectoryCommon 6273 !insertmacro CanWriteToInstallDir 6274 !insertmacro CheckDiskSpace 6275 6276 !verbose push 6277 !verbose ${_MOZFUNC_VERBOSE} 6278 !define PreDirectoryCommon "!insertmacro PreDirectoryCommonCall" 6279 6280 Function PreDirectoryCommon 6281 Push $R9 6282 6283 IntCmp $InstallType ${INSTALLTYPE_CUSTOM} end +1 +1 6284 ${CanWriteToInstallDir} $R9 6285 StrCmp "$R9" "false" end +1 6286 ${CheckDiskSpace} $R9 6287 StrCmp "$R9" "false" end +1 6288 Abort 6289 6290 end: 6291 6292 Pop $R9 6293 FunctionEnd 6294 6295 !verbose pop 6296 !endif 6297!macroend 6298 6299!macro PreDirectoryCommonCall 6300 !verbose push 6301 !verbose ${_MOZFUNC_VERBOSE} 6302 Call PreDirectoryCommon 6303 !verbose pop 6304!macroend 6305 6306/** 6307 * Called from the MUI leaveDirectory function 6308 * 6309 * @param _WARN_DISK_SPACE 6310 * Message displayed when there isn't enough disk space to perform the 6311 * installation. 6312 * @param _WARN_WRITE_ACCESS 6313 * Message displayed when the installer does not have write access to 6314 * $INSTDIR. 6315 * 6316 * $R7 = returned value from CheckDiskSpace and CanWriteToInstallDir macros 6317 * $R8 = _WARN_DISK_SPACE 6318 * $R9 = _WARN_WRITE_ACCESS 6319 */ 6320!macro LeaveDirectoryCommon 6321 6322 !ifndef LeaveDirectoryCommon 6323 !insertmacro CheckDiskSpace 6324 !insertmacro CanWriteToInstallDir 6325 6326 !verbose push 6327 !verbose ${_MOZFUNC_VERBOSE} 6328 !define LeaveDirectoryCommon "!insertmacro LeaveDirectoryCommonCall" 6329 6330 Function LeaveDirectoryCommon 6331 Exch $R9 6332 Exch 1 6333 Exch $R8 6334 Push $R7 6335 6336 ${CanWriteToInstallDir} $R7 6337 ${If} $R7 == "false" 6338 MessageBox MB_OK|MB_ICONEXCLAMATION "$R9" 6339 Abort 6340 ${EndIf} 6341 6342 ${CheckDiskSpace} $R7 6343 ${If} $R7 == "false" 6344 MessageBox MB_OK|MB_ICONEXCLAMATION "$R8" 6345 Abort 6346 ${EndIf} 6347 6348 Pop $R7 6349 Exch $R8 6350 Exch 1 6351 Exch $R9 6352 FunctionEnd 6353 6354 !verbose pop 6355 !endif 6356!macroend 6357 6358!macro LeaveDirectoryCommonCall _WARN_DISK_SPACE _WARN_WRITE_ACCESS 6359 !verbose push 6360 Push "${_WARN_DISK_SPACE}" 6361 Push "${_WARN_WRITE_ACCESS}" 6362 !verbose ${_MOZFUNC_VERBOSE} 6363 Call LeaveDirectoryCommon 6364 !verbose pop 6365!macroend 6366 6367 6368################################################################################ 6369# Install Section common macros. 6370 6371/** 6372 * Performs common cleanup operations prior to the actual installation. 6373 * This macro should be called first when installation starts. 6374 */ 6375!macro InstallStartCleanupCommon 6376 6377 !ifndef InstallStartCleanupCommon 6378 !insertmacro CleanVirtualStore 6379 !insertmacro EndUninstallLog 6380 !insertmacro OnInstallUninstall 6381 6382 !verbose push 6383 !verbose ${_MOZFUNC_VERBOSE} 6384 !define InstallStartCleanupCommon "!insertmacro InstallStartCleanupCommonCall" 6385 6386 Function InstallStartCleanupCommon 6387 6388 ; Remove files not removed by parsing the uninstall.log 6389 Delete "$INSTDIR\install_wizard.log" 6390 Delete "$INSTDIR\install_status.log" 6391 6392 RmDir /r "$INSTDIR\updates" 6393 Delete "$INSTDIR\updates.xml" 6394 Delete "$INSTDIR\active-update.xml" 6395 6396 ; Remove files from the uninstall directory. 6397 ${If} ${FileExists} "$INSTDIR\uninstall" 6398 Delete "$INSTDIR\uninstall\*wizard*" 6399 Delete "$INSTDIR\uninstall\uninstall.ini" 6400 Delete "$INSTDIR\uninstall\cleanup.log" 6401 Delete "$INSTDIR\uninstall\uninstall.update" 6402 ${OnInstallUninstall} 6403 ${EndIf} 6404 6405 ; Since we write to the uninstall.log in this directory during the 6406 ; installation create the directory if it doesn't already exist. 6407 IfFileExists "$INSTDIR\uninstall" +2 +1 6408 CreateDirectory "$INSTDIR\uninstall" 6409 6410 ; Application update uses a directory named tobedeleted in the $INSTDIR to 6411 ; delete files on OS reboot when they are in use. Try to delete this 6412 ; directory if it exists. 6413 ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" 6414 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 6415 ${EndIf} 6416 6417 ; Remove files that may be left behind by the application in the 6418 ; VirtualStore directory. 6419 ${CleanVirtualStore} 6420 FunctionEnd 6421 6422 !verbose pop 6423 !endif 6424!macroend 6425 6426!macro InstallStartCleanupCommonCall 6427 !verbose push 6428 !verbose ${_MOZFUNC_VERBOSE} 6429 Call InstallStartCleanupCommon 6430 !verbose pop 6431!macroend 6432 6433/** 6434 * Performs common cleanup operations after the actual installation. 6435 * This macro should be called last during the installation. 6436 */ 6437!macro InstallEndCleanupCommon 6438 6439 !ifndef InstallEndCleanupCommon 6440 !insertmacro EndUninstallLog 6441 6442 !verbose push 6443 !verbose ${_MOZFUNC_VERBOSE} 6444 !define InstallEndCleanupCommon "!insertmacro InstallEndCleanupCommonCall" 6445 6446 Function InstallEndCleanupCommon 6447 6448 ; Close the file handle to the uninstall.log 6449 ${EndUninstallLog} 6450 6451 FunctionEnd 6452 6453 !verbose pop 6454 !endif 6455!macroend 6456 6457!macro InstallEndCleanupCommonCall 6458 !verbose push 6459 !verbose ${_MOZFUNC_VERBOSE} 6460 Call InstallEndCleanupCommon 6461 !verbose pop 6462!macroend 6463 6464 6465################################################################################ 6466# UAC Related Macros 6467 6468/** 6469 * Provides UAC elevation support (requires the UAC plugin). 6470 * 6471 * $0 = return values from calls to the UAC plugin (always uses $0) 6472 * $R9 = return values from GetParameters and GetOptions macros 6473 */ 6474!macro ElevateUAC 6475 6476 !ifndef ${_MOZFUNC_UN}ElevateUAC 6477 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 6478 !insertmacro ${_MOZFUNC_UN_TMP}GetOptions 6479 !insertmacro ${_MOZFUNC_UN_TMP}GetParameters 6480 !undef _MOZFUNC_UN 6481 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 6482 !undef _MOZFUNC_UN_TMP 6483 6484 !verbose push 6485 !verbose ${_MOZFUNC_VERBOSE} 6486 !define ${_MOZFUNC_UN}ElevateUAC "!insertmacro ${_MOZFUNC_UN}ElevateUACCall" 6487 6488 Function ${_MOZFUNC_UN}ElevateUAC 6489 Push $R9 6490 Push $0 6491 6492!ifndef NONADMIN_ELEVATE 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 6498 ${If} "$0" == "1" 6499 UAC::GetElevationType 6500 ; If the user account has a split token 6501 ${If} "$0" == "3" 6502 UAC::RunElevated 6503 UAC::Unload 6504 ; Nothing besides UAC initialized so no need to call OnEndCommon 6505 Quit 6506 ${EndIf} 6507 ${EndIf} 6508 ${Else} 6509 ${GetParameters} $R9 6510 ${If} $R9 != "" 6511 ClearErrors 6512 ${GetOptions} "$R9" "/UAC:" $0 6513 ; If the command line contains /UAC then we need to initialize 6514 ; the UAC plugin to use UAC::ExecCodeSegment to execute code in 6515 ; the non-elevated context. 6516 ${Unless} ${Errors} 6517 UAC::RunElevated 6518 ${EndUnless} 6519 ${EndIf} 6520 ${EndIf} 6521!else 6522 UAC::IsAdmin 6523 ; If the user is not an admin already 6524 ${If} "$0" != "1" 6525 UAC::SupportsUAC 6526 ; If the system supports UAC require that the user elevate 6527 ${If} "$0" == "1" 6528 UAC::GetElevationType 6529 ; If the user account has a split token 6530 ${If} "$0" == "3" 6531 UAC::RunElevated 6532 ${If} "$0" == "0" ; Was elevation successful 6533 UAC::Unload 6534 ; Nothing besides UAC initialized so no need to call OnEndCommon 6535 Quit 6536 ${EndIf} 6537 ; Unload UAC since the elevation request was not successful and 6538 ; install anyway. 6539 UAC::Unload 6540 ${EndIf} 6541 ${Else} 6542 ; Check if UAC is enabled. If the user has turned UAC on or off 6543 ; without rebooting this value will be incorrect. This is an 6544 ; edgecase that we have to live with when trying to allow 6545 ; installing when the user doesn't have privileges such as a public 6546 ; computer while trying to also achieve UAC elevation. When this 6547 ; happens the user will be presented with the runas dialog if the 6548 ; value is 1 and won't be presented with the UAC dialog when the 6549 ; value is 0. 6550 ReadRegDWord $R9 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "EnableLUA" 6551 ${If} "$R9" == "1" 6552 ; This will display the UAC version of the runas dialog which 6553 ; requires a password for an existing user account. 6554 UAC::RunElevated 6555 ${If} "$0" == "0" ; Was elevation successful 6556 UAC::Unload 6557 ; Nothing besides UAC initialized so no need to call OnEndCommon 6558 Quit 6559 ${EndIf} 6560 ; Unload UAC since the elevation request was not successful and 6561 ; install anyway. 6562 UAC::Unload 6563 ${EndIf} 6564 ${EndIf} 6565 ${Else} 6566 ClearErrors 6567 ${${_MOZFUNC_UN}GetParameters} $R9 6568 ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9 6569 ; If the command line contains /UAC then we need to initialize the UAC 6570 ; plugin to use UAC::ExecCodeSegment to execute code in the 6571 ; non-elevated context. 6572 ${Unless} ${Errors} 6573 UAC::RunElevated 6574 ${EndUnless} 6575 ${EndIf} 6576!endif 6577 6578 ClearErrors 6579 6580 Pop $0 6581 Pop $R9 6582 FunctionEnd 6583 6584 !verbose pop 6585 !endif 6586!macroend 6587 6588!macro ElevateUACCall 6589 !verbose push 6590 !verbose ${_MOZFUNC_VERBOSE} 6591 Call ElevateUAC 6592 !verbose pop 6593!macroend 6594 6595!macro un.ElevateUACCall 6596 !verbose push 6597 !verbose ${_MOZFUNC_VERBOSE} 6598 Call un.ElevateUAC 6599 !verbose pop 6600!macroend 6601 6602!macro un.ElevateUAC 6603 !ifndef un.ElevateUAC 6604 !verbose push 6605 !verbose ${_MOZFUNC_VERBOSE} 6606 !undef _MOZFUNC_UN 6607 !define _MOZFUNC_UN "un." 6608 6609 !insertmacro ElevateUAC 6610 6611 !undef _MOZFUNC_UN 6612 !define _MOZFUNC_UN 6613 !verbose pop 6614 !endif 6615!macroend 6616 6617/** 6618 * Unloads the UAC plugin so the NSIS plugins can be removed when the installer 6619 * and uninstaller exit. 6620 * 6621 * $R9 = return values from GetParameters and GetOptions macros 6622 */ 6623!macro UnloadUAC 6624 6625 !ifndef ${_MOZFUNC_UN}UnloadUAC 6626 !define _MOZFUNC_UN_TMP_UnloadUAC ${_MOZFUNC_UN} 6627 !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetOptions 6628 !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetParameters 6629 !undef _MOZFUNC_UN 6630 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP_UnloadUAC} 6631 !undef _MOZFUNC_UN_TMP_UnloadUAC 6632 6633 !verbose push 6634 !verbose ${_MOZFUNC_VERBOSE} 6635 !define ${_MOZFUNC_UN}UnloadUAC "!insertmacro ${_MOZFUNC_UN}UnloadUACCall" 6636 6637 Function ${_MOZFUNC_UN}UnloadUAC 6638 Push $R9 6639 6640 ClearErrors 6641 ${${_MOZFUNC_UN}GetParameters} $R9 6642 ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9 6643 ; If the command line contains /UAC then we need to unload the UAC plugin 6644 IfErrors +2 +1 6645 UAC::Unload 6646 6647 ClearErrors 6648 6649 Pop $R9 6650 FunctionEnd 6651 6652 !verbose pop 6653 !endif 6654!macroend 6655 6656!macro UnloadUACCall 6657 !verbose push 6658 !verbose ${_MOZFUNC_VERBOSE} 6659 Call UnloadUAC 6660 !verbose pop 6661!macroend 6662 6663!macro un.UnloadUACCall 6664 !verbose push 6665 !verbose ${_MOZFUNC_VERBOSE} 6666 Call un.UnloadUAC 6667 !verbose pop 6668!macroend 6669 6670!macro un.UnloadUAC 6671 !ifndef un.UnloadUAC 6672 !verbose push 6673 !verbose ${_MOZFUNC_VERBOSE} 6674 !undef _MOZFUNC_UN 6675 !define _MOZFUNC_UN "un." 6676 6677 !insertmacro UnloadUAC 6678 6679 !undef _MOZFUNC_UN 6680 !define _MOZFUNC_UN 6681 !verbose pop 6682 !endif 6683!macroend 6684 6685 6686################################################################################ 6687# Macros for uninstall.log and install.log logging 6688# 6689# Since these are used by other macros they should be inserted first. All of 6690# these macros can be easily inserted using the _LoggingCommon macro. 6691 6692/** 6693 * Adds all logging macros in the correct order in one fell swoop as well as 6694 * the vars for the install.log and uninstall.log file handles. 6695 */ 6696!macro _LoggingCommon 6697 Var /GLOBAL fhInstallLog 6698 Var /GLOBAL fhUninstallLog 6699 !insertmacro StartInstallLog 6700 !insertmacro EndInstallLog 6701 !insertmacro StartUninstallLog 6702 !insertmacro EndUninstallLog 6703!macroend 6704!define _LoggingCommon "!insertmacro _LoggingCommon" 6705 6706/** 6707 * Creates a file named install.log in the install directory (e.g. $INSTDIR) 6708 * and adds the installation started message to the install.log for this 6709 * installation. This also adds the fhInstallLog and fhUninstallLog vars used 6710 * for logging. 6711 * 6712 * $fhInstallLog = filehandle for $INSTDIR\install.log 6713 * 6714 * @param _APP_NAME 6715 * Typically the BrandFullName 6716 * @param _AB_CD 6717 * The locale identifier 6718 * @param _APP_VERSION 6719 * The application version 6720 * @param _GRE_VERSION 6721 * The Gecko Runtime Engine version 6722 * 6723 * $R6 = _APP_NAME 6724 * $R7 = _AB_CD 6725 * $R8 = _APP_VERSION 6726 * $R9 = _GRE_VERSION 6727 */ 6728!macro StartInstallLog 6729 6730 !ifndef StartInstallLog 6731 !insertmacro GetTime 6732 6733 !verbose push 6734 !verbose ${_MOZFUNC_VERBOSE} 6735 !define StartInstallLog "!insertmacro StartInstallLogCall" 6736 6737 Function StartInstallLog 6738 Exch $R9 6739 Exch 1 6740 Exch $R8 6741 Exch 2 6742 Exch $R7 6743 Exch 3 6744 Exch $R6 6745 Push $R5 6746 Push $R4 6747 Push $R3 6748 Push $R2 6749 Push $R1 6750 Push $R0 6751 Push $9 6752 6753 ${DeleteFile} "$INSTDIR\install.log" 6754 FileOpen $fhInstallLog "$INSTDIR\install.log" w 6755 FileWriteWord $fhInstallLog "65279" 6756 6757 ${GetTime} "" "L" $9 $R0 $R1 $R2 $R3 $R4 $R5 6758 FileWriteUTF16LE $fhInstallLog "$R6 Installation Started: $R1-$R0-$9 $R3:$R4:$R5" 6759 ${WriteLogSeparator} 6760 6761 ${LogHeader} "Installation Details" 6762 ${LogMsg} "Install Dir: $INSTDIR" 6763 ${LogMsg} "Locale : $R7" 6764 ${LogMsg} "App Version: $R8" 6765 ${LogMsg} "GRE Version: $R9" 6766 6767 ${If} ${IsWin7} 6768 ${LogMsg} "OS Name : Windows 7" 6769 ${ElseIf} ${IsWin8} 6770 ${LogMsg} "OS Name : Windows 8" 6771 ${ElseIf} ${IsWin8.1} 6772 ${LogMsg} "OS Name : Windows 8.1" 6773 ${ElseIf} ${IsWin10} 6774 ${LogMsg} "OS Name : Windows 10" 6775 ${ElseIf} ${AtLeastWin10} 6776 ${LogMsg} "OS Name : Above Windows 10" 6777 ${Else} 6778 ${LogMsg} "OS Name : Unable to detect" 6779 ${EndIf} 6780 6781 ${LogMsg} "Target CPU : ${ARCH}" 6782 6783 Pop $9 6784 Pop $R0 6785 Pop $R1 6786 Pop $R2 6787 Pop $R3 6788 Pop $R4 6789 Pop $R5 6790 Exch $R6 6791 Exch 3 6792 Exch $R7 6793 Exch 2 6794 Exch $R8 6795 Exch 1 6796 Exch $R9 6797 FunctionEnd 6798 6799 !verbose pop 6800 !endif 6801!macroend 6802 6803!macro StartInstallLogCall _APP_NAME _AB_CD _APP_VERSION _GRE_VERSION 6804 !verbose push 6805 !verbose ${_MOZFUNC_VERBOSE} 6806 Push "${_APP_NAME}" 6807 Push "${_AB_CD}" 6808 Push "${_APP_VERSION}" 6809 Push "${_GRE_VERSION}" 6810 Call StartInstallLog 6811 !verbose pop 6812!macroend 6813 6814/** 6815 * Writes the installation finished message to the install.log and closes the 6816 * file handles to the install.log and uninstall.log 6817 * 6818 * @param _APP_NAME 6819 * 6820 * $R9 = _APP_NAME 6821 */ 6822!macro EndInstallLog 6823 6824 !ifndef EndInstallLog 6825 !insertmacro GetTime 6826 6827 !verbose push 6828 !verbose ${_MOZFUNC_VERBOSE} 6829 !define EndInstallLog "!insertmacro EndInstallLogCall" 6830 6831 Function EndInstallLog 6832 Exch $R9 6833 Push $R8 6834 Push $R7 6835 Push $R6 6836 Push $R5 6837 Push $R4 6838 Push $R3 6839 Push $R2 6840 6841 ${WriteLogSeparator} 6842 ${GetTime} "" "L" $R2 $R3 $R4 $R5 $R6 $R7 $R8 6843 FileWriteUTF16LE $fhInstallLog "$R9 Installation Finished: $R4-$R3-$R2 $R6:$R7:$R8$\r$\n" 6844 FileClose $fhInstallLog 6845 6846 Pop $R2 6847 Pop $R3 6848 Pop $R4 6849 Pop $R5 6850 Pop $R6 6851 Pop $R7 6852 Pop $R8 6853 Exch $R9 6854 FunctionEnd 6855 6856 !verbose pop 6857 !endif 6858!macroend 6859 6860!macro EndInstallLogCall _APP_NAME 6861 !verbose push 6862 !verbose ${_MOZFUNC_VERBOSE} 6863 Push "${_APP_NAME}" 6864 Call EndInstallLog 6865 !verbose pop 6866!macroend 6867 6868/** 6869 * Opens the file handle to the uninstall.log. 6870 * 6871 * $fhUninstallLog = filehandle for $INSTDIR\uninstall\uninstall.log 6872 */ 6873!macro StartUninstallLog 6874 6875 !ifndef StartUninstallLog 6876 !verbose push 6877 !verbose ${_MOZFUNC_VERBOSE} 6878 !define StartUninstallLog "!insertmacro StartUninstallLogCall" 6879 6880 Function StartUninstallLog 6881 FileOpen $fhUninstallLog "$INSTDIR\uninstall\uninstall.log" w 6882 FunctionEnd 6883 6884 !verbose pop 6885 !endif 6886!macroend 6887 6888!macro StartUninstallLogCall 6889 !verbose push 6890 !verbose ${_MOZFUNC_VERBOSE} 6891 Call StartUninstallLog 6892 !verbose pop 6893!macroend 6894 6895/** 6896 * Closes the file handle to the uninstall.log. 6897 */ 6898!macro EndUninstallLog 6899 6900 !ifndef EndUninstallLog 6901 6902 !verbose push 6903 !verbose ${_MOZFUNC_VERBOSE} 6904 !define EndUninstallLog "!insertmacro EndUninstallLogCall" 6905 6906 Function EndUninstallLog 6907 FileClose $fhUninstallLog 6908 FunctionEnd 6909 6910 !verbose pop 6911 !endif 6912!macroend 6913 6914!macro EndUninstallLogCall 6915 !verbose push 6916 !verbose ${_MOZFUNC_VERBOSE} 6917 Call EndUninstallLog 6918 !verbose pop 6919!macroend 6920 6921/** 6922 * Adds a section header to the human readable log. 6923 * 6924 * @param _HEADER 6925 * The header text to write to the log. 6926 */ 6927!macro LogHeader _HEADER 6928 ${WriteLogSeparator} 6929 FileWriteUTF16LE $fhInstallLog "${_HEADER}" 6930 ${WriteLogSeparator} 6931!macroend 6932!define LogHeader "!insertmacro LogHeader" 6933 6934/** 6935 * Adds a section message to the human readable log. 6936 * 6937 * @param _MSG 6938 * The message text to write to the log. 6939 */ 6940!macro LogMsg _MSG 6941 FileWriteUTF16LE $fhInstallLog " ${_MSG}$\r$\n" 6942!macroend 6943!define LogMsg "!insertmacro LogMsg" 6944 6945/** 6946 * Adds an uninstall entry to the uninstall log. 6947 * 6948 * @param _MSG 6949 * The message text to write to the log. 6950 */ 6951!macro LogUninstall _MSG 6952 FileWrite $fhUninstallLog "${_MSG}$\r$\n" 6953!macroend 6954!define LogUninstall "!insertmacro LogUninstall" 6955 6956/** 6957 * Adds a section divider to the human readable log. 6958 */ 6959!macro WriteLogSeparator 6960 FileWriteUTF16LE $fhInstallLog "$\r$\n----------------------------------------\ 6961 ---------------------------------------$\r$\n" 6962!macroend 6963!define WriteLogSeparator "!insertmacro WriteLogSeparator" 6964 6965 6966################################################################################ 6967# Macros for managing the shortcuts log ini file 6968 6969/** 6970 * Adds the most commonly used shortcut logging macros for the installer in one 6971 * fell swoop. 6972 */ 6973!macro _LoggingShortcutsCommon 6974 !insertmacro LogDesktopShortcut 6975 !insertmacro LogQuickLaunchShortcut 6976 !insertmacro LogSMProgramsShortcut 6977!macroend 6978!define _LoggingShortcutsCommon "!insertmacro _LoggingShortcutsCommon" 6979 6980/** 6981 * Creates the shortcuts log ini file with a UTF-16LE BOM if it doesn't exist. 6982 */ 6983!macro initShortcutsLog 6984 Push $R9 6985 6986 IfFileExists "$INSTDIR\uninstall\${SHORTCUTS_LOG}" +4 +1 6987 FileOpen $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" w 6988 FileWriteWord $R9 "65279" 6989 FileClose $R9 6990 6991 Pop $R9 6992!macroend 6993!define initShortcutsLog "!insertmacro initShortcutsLog" 6994 6995/** 6996 * Adds shortcut entries to the shortcuts log ini file. This macro is primarily 6997 * a helper used by the LogDesktopShortcut, LogQuickLaunchShortcut, and 6998 * LogSMProgramsShortcut macros but it can be used by other code if desired. If 6999 * the value already exists the the value is not written to the file. 7000 * 7001 * @param _SECTION_NAME 7002 * The section name to write to in the shortcut log ini file 7003 * @param _FILE_NAME 7004 * The shortcut's file name 7005 * 7006 * $R6 = return value from ReadIniStr for the shortcut file name 7007 * $R7 = counter for supporting multiple shortcuts in the same location 7008 * $R8 = _SECTION_NAME 7009 * $R9 = _FILE_NAME 7010 */ 7011!macro LogShortcut 7012 7013 !ifndef LogShortcut 7014 !verbose push 7015 !verbose ${_MOZFUNC_VERBOSE} 7016 !define LogShortcut "!insertmacro LogShortcutCall" 7017 7018 Function LogShortcut 7019 Exch $R9 7020 Exch 1 7021 Exch $R8 7022 Push $R7 7023 Push $R6 7024 7025 ClearErrors 7026 7027 !insertmacro initShortcutsLog 7028 7029 StrCpy $R6 "" 7030 StrCpy $R7 -1 7031 7032 StrCmp "$R6" "$R9" +5 +1 ; if the shortcut already exists don't add it 7033 IntOp $R7 $R7 + 1 ; increment the counter 7034 ReadIniStr $R6 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" 7035 IfErrors +1 -3 7036 WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" "$R9" 7037 7038 ClearErrors 7039 7040 Pop $R6 7041 Pop $R7 7042 Exch $R8 7043 Exch 1 7044 Exch $R9 7045 FunctionEnd 7046 7047 !verbose pop 7048 !endif 7049!macroend 7050 7051!macro LogShortcutCall _SECTION_NAME _FILE_NAME 7052 !verbose push 7053 !verbose ${_MOZFUNC_VERBOSE} 7054 Push "${_SECTION_NAME}" 7055 Push "${_FILE_NAME}" 7056 Call LogShortcut 7057 !verbose pop 7058!macroend 7059 7060/** 7061 * Adds a Desktop shortcut entry to the shortcuts log ini file. 7062 * 7063 * @param _FILE_NAME 7064 * The shortcut file name (e.g. shortcut.lnk) 7065 */ 7066!macro LogDesktopShortcut 7067 7068 !ifndef LogDesktopShortcut 7069 !insertmacro LogShortcut 7070 7071 !verbose push 7072 !verbose ${_MOZFUNC_VERBOSE} 7073 !define LogDesktopShortcut "!insertmacro LogDesktopShortcutCall" 7074 7075 Function LogDesktopShortcut 7076 Call LogShortcut 7077 FunctionEnd 7078 7079 !verbose pop 7080 !endif 7081!macroend 7082 7083!macro LogDesktopShortcutCall _FILE_NAME 7084 !verbose push 7085 !verbose ${_MOZFUNC_VERBOSE} 7086 Push "DESKTOP" 7087 Push "${_FILE_NAME}" 7088 Call LogDesktopShortcut 7089 !verbose pop 7090!macroend 7091 7092/** 7093 * Adds a QuickLaunch shortcut entry to the shortcuts log ini file. 7094 * 7095 * @param _FILE_NAME 7096 * The shortcut file name (e.g. shortcut.lnk) 7097 */ 7098!macro LogQuickLaunchShortcut 7099 7100 !ifndef LogQuickLaunchShortcut 7101 !insertmacro LogShortcut 7102 7103 !verbose push 7104 !verbose ${_MOZFUNC_VERBOSE} 7105 !define LogQuickLaunchShortcut "!insertmacro LogQuickLaunchShortcutCall" 7106 7107 Function LogQuickLaunchShortcut 7108 Call LogShortcut 7109 FunctionEnd 7110 7111 !verbose pop 7112 !endif 7113!macroend 7114 7115!macro LogQuickLaunchShortcutCall _FILE_NAME 7116 !verbose push 7117 !verbose ${_MOZFUNC_VERBOSE} 7118 Push "QUICKLAUNCH" 7119 Push "${_FILE_NAME}" 7120 Call LogQuickLaunchShortcut 7121 !verbose pop 7122!macroend 7123 7124/** 7125 * Adds a Start Menu shortcut entry to the shortcuts log ini file. 7126 * 7127 * @param _FILE_NAME 7128 * The shortcut file name (e.g. shortcut.lnk) 7129 */ 7130!macro LogStartMenuShortcut 7131 7132 !ifndef LogStartMenuShortcut 7133 !insertmacro LogShortcut 7134 7135 !verbose push 7136 !verbose ${_MOZFUNC_VERBOSE} 7137 !define LogStartMenuShortcut "!insertmacro LogStartMenuShortcutCall" 7138 7139 Function LogStartMenuShortcut 7140 Call LogShortcut 7141 FunctionEnd 7142 7143 !verbose pop 7144 !endif 7145!macroend 7146 7147!macro LogStartMenuShortcutCall _FILE_NAME 7148 !verbose push 7149 !verbose ${_MOZFUNC_VERBOSE} 7150 Push "STARTMENU" 7151 Push "${_FILE_NAME}" 7152 Call LogStartMenuShortcut 7153 !verbose pop 7154!macroend 7155 7156/** 7157 * Adds a Start Menu Programs shortcut entry to the shortcuts log ini file. 7158 * 7159 * @param _FILE_NAME 7160 * The shortcut file name (e.g. shortcut.lnk) 7161 */ 7162!macro LogSMProgramsShortcut 7163 7164 !ifndef LogSMProgramsShortcut 7165 !insertmacro LogShortcut 7166 7167 !verbose push 7168 !verbose ${_MOZFUNC_VERBOSE} 7169 !define LogSMProgramsShortcut "!insertmacro LogSMProgramsShortcutCall" 7170 7171 Function LogSMProgramsShortcut 7172 Call LogShortcut 7173 FunctionEnd 7174 7175 !verbose pop 7176 !endif 7177!macroend 7178 7179!macro LogSMProgramsShortcutCall _FILE_NAME 7180 !verbose push 7181 !verbose ${_MOZFUNC_VERBOSE} 7182 Push "SMPROGRAMS" 7183 Push "${_FILE_NAME}" 7184 Call LogSMProgramsShortcut 7185 !verbose pop 7186!macroend 7187 7188/** 7189 * Adds the relative path from the Start Menu Programs directory for the 7190 * application's Start Menu directory if it is different from the existing value 7191 * to the shortcuts log ini file. 7192 * 7193 * @param _REL_PATH_TO_DIR 7194 * The relative path from the Start Menu Programs directory to the 7195 * program's directory. 7196 * 7197 * $R9 = _REL_PATH_TO_DIR 7198 */ 7199!macro LogSMProgramsDirRelPath _REL_PATH_TO_DIR 7200 Push $R9 7201 7202 !insertmacro initShortcutsLog 7203 7204 ReadINIStr $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" 7205 StrCmp "$R9" "${_REL_PATH_TO_DIR}" +2 +1 7206 WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" "${_REL_PATH_TO_DIR}" 7207 7208 Pop $R9 7209!macroend 7210!define LogSMProgramsDirRelPath "!insertmacro LogSMProgramsDirRelPath" 7211 7212/** 7213 * Copies the value for the relative path from the Start Menu programs directory 7214 * (e.g. $SMPROGRAMS) to the Start Menu directory as it is stored in the 7215 * shortcuts log ini file to the variable specified in the first parameter. 7216 */ 7217!macro GetSMProgramsDirRelPath _VAR 7218 ReadINIStr ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" \ 7219 "RelativePathToDir" 7220!macroend 7221!define GetSMProgramsDirRelPath "!insertmacro GetSMProgramsDirRelPath" 7222 7223/** 7224 * Copies the shortcuts log ini file path to the variable specified in the 7225 * first parameter. 7226 */ 7227!macro GetShortcutsLogPath _VAR 7228 StrCpy ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" 7229!macroend 7230!define GetShortcutsLogPath "!insertmacro GetShortcutsLogPath" 7231 7232/** 7233 * Deletes the shortcuts log ini file. 7234 */ 7235!macro DeleteShortcutsLogFile 7236 ${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" 7237!macroend 7238!define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile" 7239 7240 7241################################################################################ 7242# Macros for managing specific Windows version features 7243 7244/** 7245 * Sets the permitted layered service provider (LSP) categories 7246 * for the application. Consumers should call this after an 7247 * installation log section has completed since this macro will log the results 7248 * to the installation log along with a header. 7249 * 7250 * !IMPORTANT - When calling this macro from an uninstaller do not specify a 7251 * parameter. The paramter is hardcoded with 0x00000000 to remove 7252 * the LSP category for the application when performing an 7253 * uninstall. 7254 * 7255 * @param _LSP_CATEGORIES 7256 * The permitted LSP categories for the application. When called by an 7257 * uninstaller this will always be 0x00000000. 7258 * 7259 * $R5 = error code popped from the stack for the WSCSetApplicationCategory call 7260 * $R6 = return value from the WSCSetApplicationCategory call 7261 * $R7 = string length for the long path to the main application executable 7262 * $R8 = long path to the main application executable 7263 * $R9 = _LSP_CATEGORIES 7264 */ 7265!macro SetAppLSPCategories 7266 7267 !ifndef ${_MOZFUNC_UN}SetAppLSPCategories 7268 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 7269 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 7270 !undef _MOZFUNC_UN 7271 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 7272 !undef _MOZFUNC_UN_TMP 7273 7274 !verbose push 7275 !verbose ${_MOZFUNC_VERBOSE} 7276 !define ${_MOZFUNC_UN}SetAppLSPCategories "!insertmacro ${_MOZFUNC_UN}SetAppLSPCategoriesCall" 7277 7278 Function ${_MOZFUNC_UN}SetAppLSPCategories 7279 Exch $R9 7280 Push $R8 7281 Push $R7 7282 Push $R6 7283 Push $R5 7284 7285 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\${FileMainEXE}" $R8 7286 StrLen $R7 "$R8" 7287 7288 ; Remove existing categories by setting the permitted categories to 7289 ; 0x00000000 since new categories are ANDed with existing categories. If 7290 ; the param value stored in $R9 is 0x00000000 then skip the removal since 7291 ; the categories will be removed by the second call to 7292 ; WSCSetApplicationCategory. 7293 StrCmp "$R9" "0x00000000" +2 +1 7294 System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\ 7295 i 0x00000000, i n, *i) i" 7296 7297 ; Set the permitted LSP categories 7298 System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\ 7299 i R9, i n, *i .s) i.R6" 7300 Pop $R5 7301 7302!ifndef NO_LOG 7303 ${LogHeader} "Setting Permitted LSP Categories" 7304 StrCmp "$R6" 0 +3 +1 7305 ${LogMsg} "** ERROR Setting LSP Categories: $R5 **" 7306 GoTo +2 7307 ${LogMsg} "Permitted LSP Categories: $R9" 7308!endif 7309 7310 ClearErrors 7311 7312 Pop $R5 7313 Pop $R6 7314 Pop $R7 7315 Pop $R8 7316 Exch $R9 7317 FunctionEnd 7318 7319 !verbose pop 7320 !endif 7321!macroend 7322 7323!macro SetAppLSPCategoriesCall _LSP_CATEGORIES 7324 !verbose push 7325 !verbose ${_MOZFUNC_VERBOSE} 7326 Push "${_LSP_CATEGORIES}" 7327 Call SetAppLSPCategories 7328 !verbose pop 7329!macroend 7330 7331!macro un.SetAppLSPCategoriesCall 7332 !verbose push 7333 !verbose ${_MOZFUNC_VERBOSE} 7334 Push "0x00000000" 7335 Call un.SetAppLSPCategories 7336 !verbose pop 7337!macroend 7338 7339!macro un.SetAppLSPCategories 7340 !ifndef un.SetAppLSPCategories 7341 !verbose push 7342 !verbose ${_MOZFUNC_VERBOSE} 7343 !undef _MOZFUNC_UN 7344 !define _MOZFUNC_UN "un." 7345 7346 !insertmacro SetAppLSPCategories 7347 7348 !undef _MOZFUNC_UN 7349 !define _MOZFUNC_UN 7350 !verbose pop 7351 !endif 7352!macroend 7353 7354/** 7355 * Checks if any pinned TaskBar lnk files point to the executable's path passed 7356 * to the macro. 7357 * 7358 * @param _EXE_PATH 7359 * The executable path 7360 * @return _RESULT 7361 * false if no pinned shotcuts were found for this install location. 7362 * true if pinned shotcuts were found for this install location. 7363 * 7364 * $R5 = stores whether a TaskBar lnk file has been found for the executable 7365 * $R6 = long path returned from GetShortCutTarget and GetLongPath 7366 * $R7 = file name returned from FindFirst and FindNext 7367 * $R8 = find handle for FindFirst and FindNext 7368 * $R9 = _EXE_PATH and _RESULT 7369 */ 7370!macro IsPinnedToTaskBar 7371 7372 !ifndef IsPinnedToTaskBar 7373 !insertmacro GetLongPath 7374 7375 !verbose push 7376 !verbose ${_MOZFUNC_VERBOSE} 7377 !define IsPinnedToTaskBar "!insertmacro IsPinnedToTaskBarCall" 7378 7379 Function IsPinnedToTaskBar 7380 Exch $R9 7381 Push $R8 7382 Push $R7 7383 Push $R6 7384 Push $R5 7385 7386 StrCpy $R5 "false" 7387 7388 ${If} ${AtLeastWin7} 7389 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" 7390 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" 7391 ${Do} 7392 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" 7393 ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\TaskBar\$R7" 7394 Pop $R6 7395 ${GetLongPath} "$R6" $R6 7396 ${If} "$R6" == "$R9" 7397 StrCpy $R5 "true" 7398 ${ExitDo} 7399 ${EndIf} 7400 ${EndIf} 7401 ClearErrors 7402 FindNext $R8 $R7 7403 ${If} ${Errors} 7404 ${ExitDo} 7405 ${EndIf} 7406 ${Loop} 7407 FindClose $R8 7408 ${EndIf} 7409 7410 ClearErrors 7411 7412 StrCpy $R9 $R5 7413 7414 Pop $R5 7415 Pop $R6 7416 Pop $R7 7417 Pop $R8 7418 Exch $R9 7419 FunctionEnd 7420 7421 !verbose pop 7422 !endif 7423!macroend 7424 7425!macro IsPinnedToTaskBarCall _EXE_PATH _RESULT 7426 !verbose push 7427 !verbose ${_MOZFUNC_VERBOSE} 7428 Push "${_EXE_PATH}" 7429 Call IsPinnedToTaskBar 7430 Pop ${_RESULT} 7431 !verbose pop 7432!macroend 7433 7434/** 7435 * Checks if any pinned Start Menu lnk files point to the executable's path 7436 * passed to the macro. 7437 * 7438 * @param _EXE_PATH 7439 * The executable path 7440 * @return _RESULT 7441 * false if no pinned shotcuts were found for this install location. 7442 * true if pinned shotcuts were found for this install location. 7443 * 7444 * $R5 = stores whether a Start Menu lnk file has been found for the executable 7445 * $R6 = long path returned from GetShortCutTarget and GetLongPath 7446 * $R7 = file name returned from FindFirst and FindNext 7447 * $R8 = find handle for FindFirst and FindNext 7448 * $R9 = _EXE_PATH and _RESULT 7449 */ 7450!macro IsPinnedToStartMenu 7451 7452 !ifndef IsPinnedToStartMenu 7453 !insertmacro GetLongPath 7454 7455 !verbose push 7456 !verbose ${_MOZFUNC_VERBOSE} 7457 !define IsPinnedToStartMenu "!insertmacro IsPinnedToStartMenuCall" 7458 7459 Function IsPinnedToStartMenu 7460 Exch $R9 7461 Push $R8 7462 Push $R7 7463 Push $R6 7464 Push $R5 7465 7466 StrCpy $R5 "false" 7467 7468 ${If} ${AtLeastWin7} 7469 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" 7470 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" 7471 ${Do} 7472 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" 7473 ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\StartMenu\$R7" 7474 Pop $R6 7475 ${GetLongPath} "$R6" $R6 7476 ${If} "$R6" == "$R9" 7477 StrCpy $R5 "true" 7478 ${ExitDo} 7479 ${EndIf} 7480 ${EndIf} 7481 ClearErrors 7482 FindNext $R8 $R7 7483 ${If} ${Errors} 7484 ${ExitDo} 7485 ${EndIf} 7486 ${Loop} 7487 FindClose $R8 7488 ${EndIf} 7489 7490 ClearErrors 7491 7492 StrCpy $R9 $R5 7493 7494 Pop $R5 7495 Pop $R6 7496 Pop $R7 7497 Pop $R8 7498 Exch $R9 7499 FunctionEnd 7500 7501 !verbose pop 7502 !endif 7503!macroend 7504 7505!macro IsPinnedToStartMenuCall _EXE_PATH _RESULT 7506 !verbose push 7507 !verbose ${_MOZFUNC_VERBOSE} 7508 Push "${_EXE_PATH}" 7509 Call IsPinnedToStartMenu 7510 Pop ${_RESULT} 7511 !verbose pop 7512!macroend 7513 7514/** 7515 * Gets the number of pinned shortcut lnk files pinned to the Task Bar. 7516 * 7517 * @return _RESULT 7518 * number of pinned shortcut lnk files. 7519 * 7520 * $R7 = file name returned from FindFirst and FindNext 7521 * $R8 = find handle for FindFirst and FindNext 7522 * $R9 = _RESULT 7523 */ 7524!macro PinnedToTaskBarLnkCount 7525 7526 !ifndef PinnedToTaskBarLnkCount 7527 !insertmacro GetLongPath 7528 7529 !verbose push 7530 !verbose ${_MOZFUNC_VERBOSE} 7531 !define PinnedToTaskBarLnkCount "!insertmacro PinnedToTaskBarLnkCountCall" 7532 7533 Function PinnedToTaskBarLnkCount 7534 Push $R9 7535 Push $R8 7536 Push $R7 7537 7538 StrCpy $R9 0 7539 7540 ${If} ${AtLeastWin7} 7541 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" 7542 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" 7543 ${Do} 7544 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" 7545 IntOp $R9 $R9 + 1 7546 ${EndIf} 7547 ClearErrors 7548 FindNext $R8 $R7 7549 ${If} ${Errors} 7550 ${ExitDo} 7551 ${EndIf} 7552 ${Loop} 7553 FindClose $R8 7554 ${EndIf} 7555 7556 ClearErrors 7557 7558 Pop $R7 7559 Pop $R8 7560 Exch $R9 7561 FunctionEnd 7562 7563 !verbose pop 7564 !endif 7565!macroend 7566 7567!macro PinnedToTaskBarLnkCountCall _RESULT 7568 !verbose push 7569 !verbose ${_MOZFUNC_VERBOSE} 7570 Call PinnedToTaskBarLnkCount 7571 Pop ${_RESULT} 7572 !verbose pop 7573!macroend 7574 7575/** 7576 * Gets the number of pinned shortcut lnk files pinned to the Start Menu. 7577 * 7578 * @return _RESULT 7579 * number of pinned shortcut lnk files. 7580 * 7581 * $R7 = file name returned from FindFirst and FindNext 7582 * $R8 = find handle for FindFirst and FindNext 7583 * $R9 = _RESULT 7584 */ 7585!macro PinnedToStartMenuLnkCount 7586 7587 !ifndef PinnedToStartMenuLnkCount 7588 !insertmacro GetLongPath 7589 7590 !verbose push 7591 !verbose ${_MOZFUNC_VERBOSE} 7592 !define PinnedToStartMenuLnkCount "!insertmacro PinnedToStartMenuLnkCountCall" 7593 7594 Function PinnedToStartMenuLnkCount 7595 Push $R9 7596 Push $R8 7597 Push $R7 7598 7599 StrCpy $R9 0 7600 7601 ${If} ${AtLeastWin7} 7602 ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" 7603 FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" 7604 ${Do} 7605 ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" 7606 IntOp $R9 $R9 + 1 7607 ${EndIf} 7608 ClearErrors 7609 FindNext $R8 $R7 7610 ${If} ${Errors} 7611 ${ExitDo} 7612 ${EndIf} 7613 ${Loop} 7614 FindClose $R8 7615 ${EndIf} 7616 7617 ClearErrors 7618 7619 Pop $R7 7620 Pop $R8 7621 Exch $R9 7622 FunctionEnd 7623 7624 !verbose pop 7625 !endif 7626!macroend 7627 7628!macro PinnedToStartMenuLnkCountCall _RESULT 7629 !verbose push 7630 !verbose ${_MOZFUNC_VERBOSE} 7631 Call PinnedToStartMenuLnkCount 7632 Pop ${_RESULT} 7633 !verbose pop 7634!macroend 7635 7636/** 7637 * Update Start Menu / TaskBar lnk files that point to the executable's path 7638 * passed to the macro and all other shortcuts installed by the application with 7639 * the current application user model ID. Requires ApplicationID. 7640 * 7641 * NOTE: this does not update Desktop shortcut application user model ID due to 7642 * bug 633728. 7643 * 7644 * @param _EXE_PATH 7645 * The main application executable path 7646 * @param _APP_ID 7647 * The application user model ID for the current install 7648 * @return _RESULT 7649 * false if no pinned shotcuts were found for this install location. 7650 * true if pinned shotcuts were found for this install location. 7651 */ 7652!macro UpdateShortcutAppModelIDs 7653 7654 !ifndef UpdateShortcutAppModelIDs 7655 !insertmacro GetLongPath 7656 7657 !verbose push 7658 !verbose ${_MOZFUNC_VERBOSE} 7659 !define UpdateShortcutAppModelIDs "!insertmacro UpdateShortcutAppModelIDsCall" 7660 7661 Function UpdateShortcutAppModelIDs 7662 ; stack: path, appid 7663 Exch $R9 ; stack: $R9, appid | $R9 = path 7664 Exch 1 ; stack: appid, $R9 7665 Exch $R8 ; stack: $R8, $R9 | $R8 = appid 7666 Push $R7 ; stack: $R7, $R8, $R9 7667 Push $R6 7668 Push $R5 7669 Push $R4 7670 Push $R3 ; stack: $R3, $R5, $R6, $R7, $R8, $R9 7671 Push $R2 7672 7673 ; $R9 = main application executable path 7674 ; $R8 = appid 7675 ; $R7 = path to the application's start menu programs directory 7676 ; $R6 = path to the shortcut log ini file 7677 ; $R5 = shortcut filename 7678 ; $R4 = GetShortCutTarget result 7679 7680 StrCpy $R3 "false" 7681 7682 ${If} ${AtLeastWin7} 7683 ; installed shortcuts 7684 ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6 7685 ${If} ${FileExists} "$R6" 7686 ; Update the Start Menu shortcuts' App ID for this application 7687 StrCpy $R2 -1 7688 ${Do} 7689 IntOp $R2 $R2 + 1 ; Increment the counter 7690 ClearErrors 7691 ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2" 7692 ${If} ${Errors} 7693 ${ExitDo} 7694 ${EndIf} 7695 7696 ${If} ${FileExists} "$SMPROGRAMS\$R5" 7697 ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5" 7698 Pop $R4 7699 ${GetLongPath} "$R4" $R4 7700 ${If} "$R4" == "$R9" ; link path == install path 7701 ApplicationID::Set "$SMPROGRAMS\$R5" "$R8" "true" 7702 Pop $R4 7703 ${EndIf} 7704 ${EndIf} 7705 ${Loop} 7706 7707 ; Update the Quick Launch shortcuts' App ID for this application 7708 StrCpy $R2 -1 7709 ${Do} 7710 IntOp $R2 $R2 + 1 ; Increment the counter 7711 ClearErrors 7712 ReadINIStr $R5 "$R6" "QUICKLAUNCH" "Shortcut$R2" 7713 ${If} ${Errors} 7714 ${ExitDo} 7715 ${EndIf} 7716 7717 ${If} ${FileExists} "$QUICKLAUNCH\$R5" 7718 ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R5" 7719 Pop $R4 7720 ${GetLongPath} "$R4" $R4 7721 ${If} "$R4" == "$R9" ; link path == install path 7722 ApplicationID::Set "$QUICKLAUNCH\$R5" "$R8" "true" 7723 Pop $R4 7724 ${EndIf} 7725 ${EndIf} 7726 ${Loop} 7727 7728 ; Update the Start Menu Programs shortcuts' App ID for this application 7729 ClearErrors 7730 ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir" 7731 ${Unless} ${Errors} 7732 ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7 7733 ${Unless} "$R7" == "" 7734 StrCpy $R2 -1 7735 ${Do} 7736 IntOp $R2 $R2 + 1 ; Increment the counter 7737 ClearErrors 7738 ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2" 7739 ${If} ${Errors} 7740 ${ExitDo} 7741 ${EndIf} 7742 7743 ${If} ${FileExists} "$R7\$R5" 7744 ShellLink::GetShortCutTarget "$R7\$R5" 7745 Pop $R4 7746 ${GetLongPath} "$R4" $R4 7747 ${If} "$R4" == "$R9" ; link path == install path 7748 ApplicationID::Set "$R7\$R5" "$R8" "true" 7749 Pop $R4 7750 ${EndIf} 7751 ${EndIf} 7752 ${Loop} 7753 ${EndUnless} 7754 ${EndUnless} 7755 ${EndIf} 7756 7757 StrCpy $R7 "$QUICKLAUNCH\User Pinned" 7758 StrCpy $R3 "false" 7759 7760 ; $R9 = main application executable path 7761 ; $R8 = appid 7762 ; $R7 = user pinned path 7763 ; $R6 = find handle 7764 ; $R5 = found filename 7765 ; $R4 = GetShortCutTarget result 7766 7767 ; TaskBar links 7768 FindFirst $R6 $R5 "$R7\TaskBar\*.lnk" 7769 ${Do} 7770 ${If} ${FileExists} "$R7\TaskBar\$R5" 7771 ShellLink::GetShortCutTarget "$R7\TaskBar\$R5" 7772 Pop $R4 7773 ${If} "$R4" == "$R9" ; link path == install path 7774 ApplicationID::Set "$R7\TaskBar\$R5" "$R8" "true" 7775 Pop $R4 ; pop Set result off the stack 7776 StrCpy $R3 "true" 7777 ${EndIf} 7778 ${EndIf} 7779 ClearErrors 7780 FindNext $R6 $R5 7781 ${If} ${Errors} 7782 ${ExitDo} 7783 ${EndIf} 7784 ${Loop} 7785 FindClose $R6 7786 7787 ; Start menu links 7788 FindFirst $R6 $R5 "$R7\StartMenu\*.lnk" 7789 ${Do} 7790 ${If} ${FileExists} "$R7\StartMenu\$R5" 7791 ShellLink::GetShortCutTarget "$R7\StartMenu\$R5" 7792 Pop $R4 7793 ${If} "$R4" == "$R9" ; link path == install path 7794 ApplicationID::Set "$R7\StartMenu\$R5" "$R8" "true" 7795 Pop $R4 ; pop Set result off the stack 7796 StrCpy $R3 "true" 7797 ${EndIf} 7798 ${EndIf} 7799 ClearErrors 7800 FindNext $R6 $R5 7801 ${If} ${Errors} 7802 ${ExitDo} 7803 ${EndIf} 7804 ${Loop} 7805 FindClose $R6 7806 ${EndIf} 7807 7808 ClearErrors 7809 7810 StrCpy $R9 $R3 7811 7812 Pop $R2 7813 Pop $R3 ; stack: $R4, $R5, $R6, $R7, $R8, $R9 7814 Pop $R4 ; stack: $R5, $R6, $R7, $R8, $R9 7815 Pop $R5 ; stack: $R6, $R7, $R8, $R9 7816 Pop $R6 ; stack: $R7, $R8, $R9 7817 Pop $R7 ; stack: $R8, $R9 7818 Exch $R8 ; stack: appid, $R9 | $R8 = old $R8 7819 Exch 1 ; stack: $R9, appid 7820 Exch $R9 ; stack: path, appid | $R9 = old $R9 7821 FunctionEnd 7822 7823 !verbose pop 7824 !endif 7825!macroend 7826 7827!macro UpdateShortcutAppModelIDsCall _EXE_PATH _APP_ID _RESULT 7828 !verbose push 7829 !verbose ${_MOZFUNC_VERBOSE} 7830 Push "${_APP_ID}" 7831 Push "${_EXE_PATH}" 7832 Call UpdateShortcutAppModelIDs 7833 Pop ${_RESULT} 7834 !verbose pop 7835!macroend 7836 7837!macro IsUserAdmin 7838 ; Copied from: http://nsis.sourceforge.net/IsUserAdmin 7839 Function IsUserAdmin 7840 Push $R0 7841 Push $R1 7842 Push $R2 7843 7844 ClearErrors 7845 UserInfo::GetName 7846 IfErrors Win9x 7847 Pop $R1 7848 UserInfo::GetAccountType 7849 Pop $R2 7850 7851 StrCmp $R2 "Admin" 0 Continue 7852 StrCpy $R0 "true" 7853 Goto Done 7854 7855 Continue: 7856 7857 StrCmp $R2 "" Win9x 7858 StrCpy $R0 "false" 7859 Goto Done 7860 7861 Win9x: 7862 StrCpy $R0 "true" 7863 7864 Done: 7865 Pop $R2 7866 Pop $R1 7867 Exch $R0 7868 FunctionEnd 7869!macroend 7870 7871/** 7872 * Retrieve if present or generate and store a 64 bit hash of an install path 7873 * using the City Hash algorithm. On return the resulting id is saved in the 7874 * $AppUserModelID variable declared by inserting this macro. InitHashAppModelId 7875 * will attempt to load from HKLM/_REG_PATH first, then HKCU/_REG_PATH. If found 7876 * in either it will return the hash it finds. If not found it will generate a 7877 * new hash and attempt to store the hash in HKLM/_REG_PATH, then HKCU/_REG_PATH. 7878 * Subsequent calls will then retreive the stored hash value. On any failure, 7879 * $AppUserModelID will be set to an empty string. 7880 * 7881 * Registry format: root/_REG_PATH/"_EXE_PATH" = "hash" 7882 * 7883 * @param _EXE_PATH 7884 * The main application executable path 7885 * @param _REG_PATH 7886 * The HKLM/HKCU agnostic registry path where the key hash should 7887 * be stored. ex: "Software\Mozilla\Firefox\TaskBarIDs" 7888 * @result (Var) $AppUserModelID contains the app model id. 7889 */ 7890!macro InitHashAppModelId 7891 !ifndef ${_MOZFUNC_UN}InitHashAppModelId 7892 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 7893 !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath 7894 !undef _MOZFUNC_UN 7895 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 7896 !undef _MOZFUNC_UN_TMP 7897 7898 !ifndef InitHashAppModelId 7899 Var AppUserModelID 7900 !endif 7901 7902 !verbose push 7903 !verbose ${_MOZFUNC_VERBOSE} 7904 !define ${_MOZFUNC_UN}InitHashAppModelId "!insertmacro ${_MOZFUNC_UN}InitHashAppModelIdCall" 7905 7906 Function ${_MOZFUNC_UN}InitHashAppModelId 7907 ; stack: apppath, regpath 7908 Exch $R9 ; stack: $R9, regpath | $R9 = apppath 7909 Exch 1 ; stack: regpath, $R9 7910 Exch $R8 ; stack: $R8, $R9 | $R8 = regpath 7911 Push $R7 7912 7913 ${If} ${AtLeastWin7} 7914 ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 7915 ; Always create a new AppUserModelID and overwrite the existing one 7916 ; for the current installation path. 7917 CityHash::GetCityHash64 "$R9" 7918 Pop $AppUserModelID 7919 ${If} $AppUserModelID == "error" 7920 GoTo end 7921 ${EndIf} 7922 ClearErrors 7923 WriteRegStr HKLM "$R8" "$R9" "$AppUserModelID" 7924 ${If} ${Errors} 7925 ClearErrors 7926 WriteRegStr HKCU "$R8" "$R9" "$AppUserModelID" 7927 ${If} ${Errors} 7928 StrCpy $AppUserModelID "error" 7929 ${EndIf} 7930 ${EndIf} 7931 ${EndIf} 7932 7933 end: 7934 ${If} "$AppUserModelID" == "error" 7935 StrCpy $AppUserModelID "" 7936 ${EndIf} 7937 7938 ClearErrors 7939 Pop $R7 7940 Exch $R8 7941 Exch 1 7942 Exch $R9 7943 FunctionEnd 7944 7945 !verbose pop 7946 !endif 7947!macroend 7948 7949!macro InitHashAppModelIdCall _EXE_PATH _REG_PATH 7950 !verbose push 7951 !verbose ${_MOZFUNC_VERBOSE} 7952 Push "${_REG_PATH}" 7953 Push "${_EXE_PATH}" 7954 Call InitHashAppModelId 7955 !verbose pop 7956!macroend 7957 7958!macro un.InitHashAppModelIdCall _EXE_PATH _REG_PATH 7959 !verbose push 7960 !verbose ${_MOZFUNC_VERBOSE} 7961 Push "${_REG_PATH}" 7962 Push "${_EXE_PATH}" 7963 Call un.InitHashAppModelId 7964 !verbose pop 7965!macroend 7966 7967!macro un.InitHashAppModelId 7968 !ifndef un.InitHashAppModelId 7969 !verbose push 7970 !verbose ${_MOZFUNC_VERBOSE} 7971 !undef _MOZFUNC_UN 7972 !define _MOZFUNC_UN "un." 7973 7974 !insertmacro InitHashAppModelId 7975 7976 !undef _MOZFUNC_UN 7977 !define _MOZFUNC_UN 7978 !verbose pop 7979 !endif 7980!macroend 7981 7982/** 7983 * Try to locate the default profile of this install from AppUserModelID 7984 * using installs.ini. 7985 * FIXME This could instead use the Install<AUMID> entries in profiles.ini? 7986 * 7987 * - `SetShellVarContext current` must be called before this macro so 7988 * $APPDATA gets the current user's data. 7989 * - InitHashAppModelId must have been called before this macro to set 7990 * $AppUserModelID 7991 * 7992 * @result: Path of the profile directory (not checked for existence), 7993 * or "" if not found, left on top of the stack. 7994 */ 7995!macro FindInstallSpecificProfileMaybeUn _MOZFUNC_UN 7996 Push $R0 7997 Push $0 7998 Push $1 7999 Push $2 8000 8001 StrCpy $R0 "" 8002 ; Look for an install-specific profile, which might be listed as 8003 ; either a relative or an absolute path (installs.ini doesn't say which). 8004 ${If} ${FileExists} "$APPDATA\Mozilla\Firefox\installs.ini" 8005 ClearErrors 8006 ReadINIStr $1 "$APPDATA\Mozilla\Firefox\installs.ini" "$AppUserModelID" "Default" 8007 ${IfNot} ${Errors} 8008 ${${_MOZFUNC_UN}GetLongPath} "$APPDATA\Mozilla\Firefox\$1" $2 8009 ${If} ${FileExists} $2 8010 StrCpy $R0 $2 8011 ${Else} 8012 ${${_MOZFUNC_UN}GetLongPath} "$1" $2 8013 ${If} ${FileExists} $2 8014 StrCpy $R0 $2 8015 ${EndIf} 8016 ${EndIf} 8017 ${EndIf} 8018 ${EndIf} 8019 8020 Pop $2 8021 Pop $1 8022 Pop $0 8023 Exch $R0 8024!macroend 8025!define FindInstallSpecificProfile "!insertmacro FindInstallSpecificProfileMaybeUn ''" 8026!define un.FindInstallSpecificProfile "!insertmacro FindInstallSpecificProfileMaybeUn un." 8027 8028/** 8029 * Copy the post-signing data, which was left alongside the installer 8030 * by the self-extractor stub, into the global location for this data. 8031 * 8032 * If the post-signing data file doesn't exist, or is empty, "0" is 8033 * pushed on the stack, and nothing is copied. 8034 * Otherwise the first line of the post-signing data (including newline, 8035 * if any) is pushed on the stack. 8036 */ 8037!macro CopyPostSigningData 8038 !ifndef CopyPostSigningData 8039 !verbose push 8040 !verbose ${_MOZFUNC_VERBOSE} 8041 !define CopyPostSigningData "Call CopyPostSigningData" 8042 8043 Function CopyPostSigningData 8044 Push $0 ; Stack: old $0 8045 8046 ${LineRead} "$EXEDIR\postSigningData" "1" $0 8047 ${If} ${Errors} 8048 ClearErrors 8049 StrCpy $0 "0" 8050 ${Else} 8051 CreateDirectory "$LOCALAPPDATA\Mozilla\Firefox" 8052 CopyFiles /SILENT "$EXEDIR\postSigningData" "$LOCALAPPDATA\Mozilla\Firefox" 8053 ${Endif} 8054 8055 Exch $0 ; Stack: postSigningData 8056 FunctionEnd 8057 8058 !verbose pop 8059 !endif 8060!macroend 8061 8062################################################################################ 8063# Helpers for taskbar progress 8064 8065!ifndef CLSCTX_INPROC_SERVER 8066 !define CLSCTX_INPROC_SERVER 1 8067!endif 8068 8069!define CLSID_ITaskbarList {56fdf344-fd6d-11d0-958a-006097c9a090} 8070!define IID_ITaskbarList3 {ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf} 8071!define ITaskbarList3->SetProgressValue $ITaskbarList3->9 8072!define ITaskbarList3->SetProgressState $ITaskbarList3->10 8073 8074/** 8075 * Creates a single uninitialized object of the ITaskbarList class with a 8076 * reference to the ITaskbarList3 interface. This object can be used to set 8077 * progress and state on the installer's taskbar icon using the helper macros 8078 * in this section. 8079 */ 8080!macro ITBL3Create 8081 8082 !ifndef ${_MOZFUNC_UN}ITBL3Create 8083 Var ITaskbarList3 8084 8085 !verbose push 8086 !verbose ${_MOZFUNC_VERBOSE} 8087 !define ${_MOZFUNC_UN}ITBL3Create "!insertmacro ${_MOZFUNC_UN}ITBL3CreateCall" 8088 8089 Function ${_MOZFUNC_UN}ITBL3Create 8090 ; Setting to 0 allows the helper macros to detect when the object was not 8091 ; created. 8092 StrCpy $ITaskbarList3 0 8093 ; Don't create when running silently. 8094 ${Unless} ${Silent} 8095 ; This is only supported on Win 7 and above. 8096 ${If} ${AtLeastWin7} 8097 System::Call "ole32::CoCreateInstance(g '${CLSID_ITaskbarList}', \ 8098 i 0, \ 8099 i ${CLSCTX_INPROC_SERVER}, \ 8100 g '${IID_ITaskbarList3}', \ 8101 *i .s)" 8102 Pop $ITaskbarList3 8103 ${EndIf} 8104 ${EndUnless} 8105 FunctionEnd 8106 8107 !verbose pop 8108 !endif 8109!macroend 8110 8111!macro ITBL3CreateCall 8112 !verbose push 8113 !verbose ${_MOZFUNC_VERBOSE} 8114 Call ITBL3Create 8115 !verbose pop 8116!macroend 8117 8118!macro un.ITBL3CreateCall _PATH_TO_IMAGE 8119 !verbose push 8120 !verbose ${_MOZFUNC_VERBOSE} 8121 Call un.ITBL3Create 8122 !verbose pop 8123!macroend 8124 8125!macro un.ITBL3Create 8126 !ifndef un.ITBL3Create 8127 !verbose push 8128 !verbose ${_MOZFUNC_VERBOSE} 8129 !undef _MOZFUNC_UN 8130 !define _MOZFUNC_UN "un." 8131 8132 !insertmacro ITBL3Create 8133 8134 !undef _MOZFUNC_UN 8135 !define _MOZFUNC_UN 8136 !verbose pop 8137 !endif 8138!macroend 8139 8140/** 8141 * Sets the percentage completed on the taskbar process icon progress indicator. 8142 * 8143 * @param _COMPLETED 8144 * The proportion of the operation that has been completed in relation 8145 * to _TOTAL. 8146 * @param _TOTAL 8147 * The value _COMPLETED will have when the operation has completed. 8148 * 8149 * $R8 = _COMPLETED 8150 * $R9 = _TOTAL 8151 */ 8152!macro ITBL3SetProgressValueCall _COMPLETED _TOTAL 8153 Push ${_COMPLETED} 8154 Push ${_TOTAL} 8155 ${CallArtificialFunction} ITBL3SetProgressValue_ 8156!macroend 8157 8158!define ITBL3SetProgressValue "!insertmacro ITBL3SetProgressValueCall" 8159!define un.ITBL3SetProgressValue "!insertmacro ITBL3SetProgressValueCall" 8160 8161!macro ITBL3SetProgressValue_ 8162 Exch $R9 8163 Exch 1 8164 Exch $R8 8165 ${If} $ITaskbarList3 <> 0 8166 System::Call "${ITaskbarList3->SetProgressValue}(i$HWNDPARENT, l$R8, l$R9)" 8167 ${EndIf} 8168 Exch $R8 8169 Exch 1 8170 Exch $R9 8171!macroend 8172 8173; Normal state / no progress bar 8174!define TBPF_NOPROGRESS 0x00000000 8175; Marquee style progress bar 8176!define TBPF_INDETERMINATE 0x00000001 8177; Standard progress bar 8178!define TBPF_NORMAL 0x00000002 8179; Red taskbar button to indicate an error occurred 8180!define TBPF_ERROR 0x00000004 8181; Yellow taskbar button to indicate user attention (input) is required to 8182; resume progress 8183!define TBPF_PAUSED 0x00000008 8184 8185/** 8186 * Sets the state on the taskbar process icon progress indicator. 8187 * 8188 * @param _STATE 8189 * The state to set on the taskbar icon progress indicator. Only one of 8190 * the states defined above should be specified. 8191 * 8192 * $R9 = _STATE 8193 */ 8194!macro ITBL3SetProgressStateCall _STATE 8195 Push ${_STATE} 8196 ${CallArtificialFunction} ITBL3SetProgressState_ 8197!macroend 8198 8199!define ITBL3SetProgressState "!insertmacro ITBL3SetProgressStateCall" 8200!define un.ITBL3SetProgressState "!insertmacro ITBL3SetProgressStateCall" 8201 8202!macro ITBL3SetProgressState_ 8203 Exch $R9 8204 ${If} $ITaskbarList3 <> 0 8205 System::Call "${ITaskbarList3->SetProgressState}(i$HWNDPARENT, i$R9)" 8206 ${EndIf} 8207 Exch $R9 8208!macroend 8209 8210################################################################################ 8211# Helpers for the new user interface 8212 8213!ifndef MAXDWORD 8214 !define MAXDWORD 0xffffffff 8215!endif 8216 8217!ifndef DT_WORDBREAK 8218 !define DT_WORDBREAK 0x0010 8219!endif 8220!ifndef DT_SINGLELINE 8221 !define DT_SINGLELINE 0x0020 8222!endif 8223!ifndef DT_NOCLIP 8224 !define DT_NOCLIP 0x0100 8225!endif 8226!ifndef DT_CALCRECT 8227 !define DT_CALCRECT 0x0400 8228!endif 8229!ifndef DT_EDITCONTROL 8230 !define DT_EDITCONTROL 0x2000 8231!endif 8232!ifndef DT_RTLREADING 8233 !define DT_RTLREADING 0x00020000 8234!endif 8235!ifndef DT_NOFULLWIDTHCHARBREAK 8236 !define DT_NOFULLWIDTHCHARBREAK 0x00080000 8237!endif 8238 8239!define /ifndef GWL_STYLE -16 8240!define /ifndef GWL_EXSTYLE -20 8241 8242!ifndef WS_EX_NOINHERITLAYOUT 8243 !define WS_EX_NOINHERITLAYOUT 0x00100000 8244!endif 8245 8246!ifndef PBS_MARQUEE 8247 !define PBS_MARQUEE 0x08 8248!endif 8249 8250!ifndef PBM_SETRANGE32 8251 !define PBM_SETRANGE32 0x406 8252!endif 8253!ifndef PBM_GETRANGE 8254 !define PBM_GETRANGE 0x407 8255!endif 8256 8257!ifndef SHACF_FILESYSTEM 8258 !define SHACF_FILESYSTEM 1 8259!endif 8260 8261!define MOZ_LOADTRANSPARENT ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS} 8262 8263; Extend nsDialogs.nsh to support creating centered labels if it is already 8264; included 8265!ifmacrodef __NSD_DefineControl 8266!insertmacro __NSD_DefineControl LabelCenter 8267!define __NSD_LabelCenter_CLASS STATIC 8268!define __NSD_LabelCenter_STYLE ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_CENTER} 8269!define __NSD_LabelCenter_EXSTYLE ${WS_EX_TRANSPARENT} 8270!endif 8271 8272/** 8273 * Draws an image file (BMP, GIF, or JPG) onto a bitmap control, with scaling. 8274 * Adapted from https://stackoverflow.com/a/13405711/1508094 8275 * 8276 * @param CONTROL bitmap control created by NSD_CreateBitmap 8277 * @param IMAGE path to image file to draw to the bitmap 8278 * @param HANDLE output bitmap handle which must be freed via NSD_FreeImage 8279 * after nsDialogs::Show has been called 8280 */ 8281!macro __SetStretchedImageOLE CONTROL IMAGE HANDLE 8282 !ifndef IID_IPicture 8283 !define IID_IPicture {7BF80980-BF32-101A-8BBB-00AA00300CAB} 8284 !endif 8285 !ifndef SRCCOPY 8286 !define SRCCOPY 0xCC0020 8287 !endif 8288 !ifndef HALFTONE 8289 !define HALFTONE 4 8290 !endif 8291 !ifndef IMAGE_BITMAP 8292 !define IMAGE_BITMAP 0 8293 !endif 8294 8295 Push $0 ; HANDLE 8296 Push $1 ; memory DC 8297 Push $2 ; IPicture created from IMAGE 8298 Push $3 ; HBITMAP obtained from $2 8299 Push $4 ; BITMAPINFO obtained from $3 8300 Push $5 ; width of IMAGE 8301 Push $6 ; height of IMAGE 8302 Push $7 ; width of CONTROL 8303 Push $8 ; height of CONTROL 8304 Push $R0 ; CONTROL 8305 8306 StrCpy $R0 ${CONTROL} ; in case ${CONTROL} is $0 8307 StrCpy $7 "" 8308 StrCpy $8 "" 8309 8310 System::Call '*(i, i, i, i) i.s' 8311 Pop $0 8312 8313 ${If} $0 <> 0 8314 System::Call 'user32::GetClientRect(i R0, i r0)' 8315 System::Call '*$0(i, i, i .s, i .s)' 8316 System::Free $0 8317 Pop $7 8318 Pop $8 8319 ${EndIf} 8320 8321 ${If} $7 > 0 8322 ${AndIf} $8 > 0 8323 System::Call 'oleaut32::OleLoadPicturePath(w"${IMAGE}",i0,i0,i0,g"${IID_IPicture}",*i.r2)i.r1' 8324 ${If} $1 = 0 8325 System::Call 'user32::GetDC(i0)i.s' 8326 System::Call 'gdi32::CreateCompatibleDC(iss)i.r1' 8327 System::Call 'gdi32::CreateCompatibleBitmap(iss,ir7,ir8)i.r0' 8328 System::Call 'user32::ReleaseDC(i0,is)' 8329 System::Call '$2->3(*i.r3)i.r4' ; IPicture->get_Handle 8330 ${If} $4 = 0 8331 System::Call 'gdi32::SetStretchBltMode(ir1,i${HALFTONE})' 8332 System::Call '*(&i40,&i1024)i.r4' ; BITMAP / BITMAPINFO 8333 System::Call 'gdi32::GetObject(ir3,i24,ir4)' 8334 System::Call 'gdi32::SelectObject(ir1,ir0)i.s' 8335 System::Call '*$4(i40,i.r5,i.r6,i0,i,i.s)' ; Grab size and bits-ptr AND init as BITMAPINFOHEADER 8336 System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFOHEADER 8337 System::Call 'gdi32::GetDIBits(ir1,ir3,i0,i0,i0,ir4,i0)' ; init BITMAPINFO 8338 System::Call 'gdi32::StretchDIBits(ir1,i0,i0,ir7,ir8,i0,i0,ir5,ir6,is,ir4,i0,i${SRCCOPY})' 8339 System::Call 'gdi32::SelectObject(ir1,is)' 8340 System::Free $4 8341 SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0 8342 ${EndIf} 8343 System::Call 'gdi32::DeleteDC(ir1)' 8344 System::Call '$2->2()' ; IPicture->release() 8345 ${EndIf} 8346 ${EndIf} 8347 8348 Pop $R0 8349 Pop $8 8350 Pop $7 8351 Pop $6 8352 Pop $5 8353 Pop $4 8354 Pop $3 8355 Pop $2 8356 Pop $1 8357 Exch $0 8358 Pop ${HANDLE} 8359!macroend 8360!define SetStretchedImageOLE "!insertmacro __SetStretchedImageOLE" 8361 8362/** 8363 * Display a task dialog box with custom strings and button labels. 8364 * 8365 * The task dialog is highly customizable. The specific style being used here 8366 * is similar to a MessageBox except that the button text is customizable. 8367 * MessageBox-style buttons are used instead of command link buttons; this can 8368 * be made configurable if command buttons are needed. 8369 * 8370 * See https://msdn.microsoft.com/en-us/library/windows/desktop/bb760544.aspx 8371 * for the TaskDialogIndirect function's documentation, and links to definitions 8372 * of the TASKDIALOGCONFIG and TASKDIALOG_BUTTON structures it uses. 8373 * 8374 * @param INSTRUCTION Dialog header string; use empty string if unneeded 8375 * @param CONTENT Secondary message string; use empty string if unneeded 8376 * @param BUTTON1 Text for the first button, the one selected by default 8377 * @param BUTTON2 Text for the second button 8378 * 8379 * @return One of the following values will be left on the stack: 8380 * 1001 if the first button was clicked 8381 * 1002 if the second button was clicked 8382 * 2 (IDCANCEL) if the dialog was closed 8383 * 0 on error 8384 */ 8385!macro _ShowTaskDialog INSTRUCTION CONTENT BUTTON1 BUTTON2 8386 !ifndef SIZEOF_TASKDIALOGCONFIG_32BIT 8387 !define SIZEOF_TASKDIALOGCONFIG_32BIT 96 8388 !endif 8389 !ifndef TDF_ALLOW_DIALOG_CANCELLATION 8390 !define TDF_ALLOW_DIALOG_CANCELLATION 0x0008 8391 !endif 8392 !ifndef TDF_RTL_LAYOUT 8393 !define TDF_RTL_LAYOUT 0x02000 8394 !endif 8395 !ifndef TD_WARNING_ICON 8396 !define TD_WARNING_ICON 0x0FFFF 8397 !endif 8398 8399 Push $0 ; return value 8400 Push $1 ; TASKDIALOGCONFIG struct 8401 Push $2 ; TASKDIALOG_BUTTON array 8402 Push $3 ; dwFlags member of the TASKDIALOGCONFIG 8403 8404 StrCpy $3 ${TDF_ALLOW_DIALOG_CANCELLATION} 8405 !ifdef ${AB_CD}_rtl 8406 IntOp $3 $3 | ${TDF_RTL_LAYOUT} 8407 !endif 8408 8409 ; Build an array of two TASKDIALOG_BUTTON structs 8410 System::Call "*(i 1001, \ 8411 w '${BUTTON1}', \ 8412 i 1002, \ 8413 w '${BUTTON2}' \ 8414 ) p.r2" 8415 ; Build a TASKDIALOGCONFIG struct 8416 System::Call "*(i ${SIZEOF_TASKDIALOGCONFIG_32BIT}, \ 8417 p $HWNDPARENT, \ 8418 p 0, \ 8419 i $3, \ 8420 i 0, \ 8421 w '$(INSTALLER_WIN_CAPTION)', \ 8422 p ${TD_WARNING_ICON}, \ 8423 w '${INSTRUCTION}', \ 8424 w '${CONTENT}', \ 8425 i 2, \ 8426 p r2, \ 8427 i 1001, \ 8428 i 0, \ 8429 p 0, \ 8430 i 0, \ 8431 p 0, \ 8432 p 0, \ 8433 p 0, \ 8434 p 0, \ 8435 p 0, \ 8436 p 0, \ 8437 p 0, \ 8438 p 0, \ 8439 i 0 \ 8440 ) p.r1" 8441 System::Call "comctl32::TaskDialogIndirect(p r1, *i 0 r0, p 0, p 0)" 8442 System::Free $1 8443 System::Free $2 8444 8445 Pop $3 8446 Pop $2 8447 Pop $1 8448 Exch $0 8449!macroend 8450!define ShowTaskDialog "!insertmacro _ShowTaskDialog" 8451 8452/** 8453 * Removes a single style from a control. 8454 * 8455 * _HANDLE the handle of the control 8456 * _STYLE the style to remove 8457 */ 8458!macro _RemoveStyle _HANDLE _STYLE 8459 Push $0 8460 8461 System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}) i .r0' 8462 IntOp $0 $0 | ${_STYLE} 8463 IntOp $0 $0 - ${_STYLE} 8464 System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}, i r0)' 8465 8466 Pop $0 8467!macroend 8468!define RemoveStyle "!insertmacro _RemoveStyle" 8469 8470/** 8471 * Adds a single extended style to a control. 8472 * 8473 * _HANDLE the handle of the control 8474 * _EXSTYLE the extended style to add 8475 */ 8476!macro _AddExStyle _HANDLE _EXSTYLE 8477 Push $0 8478 8479 System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}) i .r0' 8480 IntOp $0 $0 | ${_EXSTYLE} 8481 System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}, i r0)' 8482 8483 Pop $0 8484!macroend 8485!define AddExStyle "!insertmacro _AddExStyle" 8486 8487/** 8488 * Removes a single extended style from a control. 8489 * 8490 * _HANDLE the handle of the control 8491 * _EXSTYLE the extended style to remove 8492 */ 8493!macro _RemoveExStyle _HANDLE _EXSTYLE 8494 Push $0 8495 8496 System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}) i .r0' 8497 IntOp $0 $0 | ${_EXSTYLE} 8498 IntOp $0 $0 - ${_EXSTYLE} 8499 System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}, i r0)' 8500 8501 Pop $0 8502!macroend 8503!define RemoveExStyle "!insertmacro _RemoveExStyle" 8504 8505/** 8506 * Set the necessary styles to configure the given window as right-to-left 8507 * 8508 * _HANDLE the handle of the control to configure 8509 */ 8510!macro _MakeWindowRTL _HANDLE 8511 !define /ifndef WS_EX_RIGHT 0x00001000 8512 !define /ifndef WS_EX_LEFT 0x00000000 8513 !define /ifndef WS_EX_RTLREADING 0x00002000 8514 !define /ifndef WS_EX_LTRREADING 0x00000000 8515 !define /ifndef WS_EX_LAYOUTRTL 0x00400000 8516 8517 ${AddExStyle} ${_HANDLE} ${WS_EX_LAYOUTRTL} 8518 ${RemoveExStyle} ${_HANDLE} ${WS_EX_RTLREADING} 8519 ${RemoveExStyle} ${_HANDLE} ${WS_EX_RIGHT} 8520 ${AddExStyle} ${_HANDLE} ${WS_EX_LEFT}|${WS_EX_LTRREADING} 8521!macroend 8522!define MakeWindowRTL "!insertmacro _MakeWindowRTL" 8523 8524/** 8525 * Gets the extent of the specified text in pixels for sizing a control. 8526 * 8527 * _TEXT the text to get the text extent for 8528 * _FONT the font to use when getting the text extent 8529 * _RES_WIDTH return value - control width for the text 8530 * _RES_HEIGHT return value - control height for the text 8531 */ 8532!macro GetTextExtentCall _TEXT _FONT _RES_WIDTH _RES_HEIGHT 8533 Push "${_TEXT}" 8534 Push "${_FONT}" 8535 ${CallArtificialFunction} GetTextExtent_ 8536 Pop ${_RES_WIDTH} 8537 Pop ${_RES_HEIGHT} 8538!macroend 8539 8540!define GetTextExtent "!insertmacro GetTextExtentCall" 8541!define un.GetTextExtent "!insertmacro GetTextExtentCall" 8542 8543!macro GetTextExtent_ 8544 Exch $0 ; font 8545 Exch 1 8546 Exch $1 ; text 8547 Push $2 8548 Push $3 8549 Push $4 8550 Push $5 8551 Push $6 8552 Push $7 8553 8554 ; Reuse the existing NSIS control which is used for BrandingText instead of 8555 ; creating a new control. 8556 GetDlgItem $2 $HWNDPARENT 1028 8557 8558 System::Call 'user32::GetDC(i r2) i .r3' 8559 System::Call 'gdi32::SelectObject(i r3, i r0)' 8560 8561 StrLen $4 "$1" 8562 8563 System::Call '*(i, i) i .r5' 8564 System::Call 'gdi32::GetTextExtentPoint32W(i r3, t$\"$1$\", i r4, i r5)' 8565 System::Call '*$5(i .r6, i .r7)' 8566 System::Free $5 8567 8568 System::Call 'user32::ReleaseDC(i r2, i r3)' 8569 8570 StrCpy $1 $7 8571 StrCpy $0 $6 8572 8573 Pop $7 8574 Pop $6 8575 Pop $5 8576 Pop $4 8577 Pop $3 8578 Pop $2 8579 Exch $1 ; return height 8580 Exch 1 8581 Exch $0 ; return width 8582!macroend 8583 8584/** 8585 * Gets the width and the height of a control in pixels. 8586 * 8587 * _HANDLE the handle of the control 8588 * _RES_WIDTH return value - control width for the text 8589 * _RES_HEIGHT return value - control height for the text 8590 */ 8591!macro GetDlgItemWidthHeightCall _HANDLE _RES_WIDTH _RES_HEIGHT 8592 Push "${_HANDLE}" 8593 ${CallArtificialFunction} GetDlgItemWidthHeight_ 8594 Pop ${_RES_WIDTH} 8595 Pop ${_RES_HEIGHT} 8596!macroend 8597 8598!define GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall" 8599!define un.GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall" 8600 8601!macro GetDlgItemWidthHeight_ 8602 Exch $0 ; handle for the control 8603 Push $1 8604 Push $2 8605 8606 System::Call '*(i, i, i, i) i .r2' 8607 ; The left and top values will always be 0 so the right and bottom values 8608 ; will be the width and height. 8609 System::Call 'user32::GetClientRect(i r0, i r2)' 8610 System::Call '*$2(i, i, i .r0, i .r1)' 8611 System::Free $2 8612 8613 Pop $2 8614 Exch $1 ; return height 8615 Exch 1 8616 Exch $0 ; return width 8617!macroend 8618 8619/** 8620 * Gets the number of pixels from the beginning of the dialog to the end of a 8621 * control in a RTL friendly manner. 8622 * 8623 * _HANDLE the handle of the control 8624 * _RES_PX return value - pixels from the beginning of the dialog to the end of 8625 * the control 8626 */ 8627!macro GetDlgItemEndPXCall _HANDLE _RES_PX 8628 Push "${_HANDLE}" 8629 ${CallArtificialFunction} GetDlgItemEndPX_ 8630 Pop ${_RES_PX} 8631!macroend 8632 8633!define GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall" 8634!define un.GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall" 8635 8636!macro GetDlgItemEndPX_ 8637 Exch $0 ; handle of the control 8638 Push $1 8639 Push $2 8640 8641 ; #32770 is the dialog class 8642 FindWindow $1 "#32770" "" $HWNDPARENT 8643 System::Call '*(i, i, i, i) i .r2' 8644 System::Call 'user32::GetWindowRect(i r0, i r2)' 8645 System::Call 'user32::MapWindowPoints(i 0, i r1,i r2, i 2)' 8646 System::Call '*$2(i, i, i .r0, i)' 8647 System::Free $2 8648 8649 Pop $2 8650 Pop $1 8651 Exch $0 ; pixels from the beginning of the dialog to the end of the control 8652!macroend 8653 8654/** 8655 * Gets the number of pixels from the top of a dialog to the bottom of a control 8656 * 8657 * _CONTROL the handle of the control 8658 * _RES_PX return value - pixels from the top of the dialog to the bottom 8659 * of the control 8660 */ 8661!macro GetDlgItemBottomPXCall _CONTROL _RES_PX 8662 Push "${_CONTROL}" 8663 ${CallArtificialFunction} GetDlgItemBottomPX_ 8664 Pop ${_RES_PX} 8665!macroend 8666 8667!define GetDlgItemBottomPX "!insertmacro GetDlgItemBottomPXCall" 8668!define un.GetDlgItemBottomPX "!insertmacro GetDlgItemBottomPXCall" 8669 8670!macro GetDlgItemBottomPX_ 8671 Exch $0 ; handle of the control 8672 Push $1 8673 Push $2 8674 8675 ; #32770 is the dialog class 8676 FindWindow $1 "#32770" "" $HWNDPARENT 8677 System::Call '*(i, i, i, i) i .r2' 8678 System::Call 'user32::GetWindowRect(i r0, i r2)' 8679 System::Call 'user32::MapWindowPoints(i 0, i r1, i r2, i 2)' 8680 System::Call '*$2(i, i, i, i .r0)' 8681 System::Free $2 8682 8683 Pop $2 8684 Pop $1 8685 Exch $0 ; pixels from the top of the dialog to the bottom of the control 8686!macroend 8687 8688/** 8689 * Gets the width and height for sizing a control that has the specified text. 8690 * The control's height and width will be dynamically determined for the maximum 8691 * width specified. 8692 * 8693 * _TEXT the text 8694 * _FONT the font to use when getting the width and height 8695 * _MAX_WIDTH the maximum width for the control in pixels 8696 * _RES_WIDTH return value - control width for the text in pixels. 8697 * This might be larger than _MAX_WIDTH if that constraint couldn't 8698 * be satisfied, e.g. a single word that couldn't be broken up is 8699 * longer than _MAX_WIDTH by itself. 8700 * _RES_HEIGHT return value - control height for the text in pixels 8701 */ 8702!macro GetTextWidthHeight 8703 8704 !ifndef ${_MOZFUNC_UN}GetTextWidthHeight 8705 !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} 8706 !insertmacro ${_MOZFUNC_UN_TMP}WordFind 8707 !undef _MOZFUNC_UN 8708 !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} 8709 !undef _MOZFUNC_UN_TMP 8710 8711 !verbose push 8712 !verbose ${_MOZFUNC_VERBOSE} 8713 !define ${_MOZFUNC_UN}GetTextWidthHeight "!insertmacro ${_MOZFUNC_UN}GetTextWidthHeightCall" 8714 8715 Function ${_MOZFUNC_UN}GetTextWidthHeight 8716 ; Stack contents after each instruction (top of the stack on the left): 8717 ; _MAX_WIDTH _FONT _TEXT 8718 Exch $0 ; $0 _FONT _TEXT 8719 Exch 1 ; _FONT $0 _TEXT 8720 Exch $1 ; $1 $0 _TEXT 8721 Exch 2 ; _TEXT $0 $1 8722 Exch $2 ; $2 $0 $1 8723 ; That's all the parameters, now save our scratch registers. 8724 Push $3 ; handle to a temporary control for drawing the text into 8725 Push $4 ; DC handle 8726 Push $5 ; string length of the text argument 8727 Push $6 ; RECT struct to call DrawText with 8728 Push $7 ; width returned from DrawText 8729 Push $8 ; height returned from DrawText 8730 Push $9 ; flags to pass to DrawText 8731 8732 StrCpy $9 "${DT_NOCLIP}|${DT_CALCRECT}|${DT_WORDBREAK}" 8733 !ifdef ${AB_CD}_rtl 8734 StrCpy $9 "$9|${DT_RTLREADING}" 8735 !endif 8736 8737 ; Reuse the existing NSIS control which is used for BrandingText instead 8738 ; of creating a new control. 8739 GetDlgItem $3 $HWNDPARENT 1028 8740 8741 System::Call 'user32::GetDC(i r3) i .r4' 8742 System::Call 'gdi32::SelectObject(i r4, i r1)' 8743 8744 StrLen $5 "$2" ; text length 8745 System::Call '*(i, i, i r0, i) i .r6' 8746 8747 System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, i r9)' 8748 System::Call '*$6(i, i, i .r7, i .r8)' 8749 System::Free $6 8750 8751 System::Call 'user32::ReleaseDC(i r3, i r4)' 8752 8753 StrCpy $1 $8 8754 StrCpy $0 $7 8755 8756 ; Restore the values that were in our scratch registers. 8757 Pop $9 8758 Pop $8 8759 Pop $7 8760 Pop $6 8761 Pop $5 8762 Pop $4 8763 Pop $3 8764 ; Restore our parameter registers and return our results. 8765 ; Stack contents after each instruction (top of the stack on the left): 8766 ; $2 $0 $1 8767 Pop $2 ; $0 $1 8768 Exch 1 ; $1 $0 8769 Exch $1 ; _RES_HEIGHT $0 8770 Exch 1 ; $0 _RES_HEIGHT 8771 Exch $0 ; _RES_WIDTH _RES_HEIGHT 8772 FunctionEnd 8773 8774 !verbose pop 8775 !endif 8776!macroend 8777 8778!macro GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT 8779 !verbose push 8780 !verbose ${_MOZFUNC_VERBOSE} 8781 Push "${_TEXT}" 8782 Push "${_FONT}" 8783 Push "${_MAX_WIDTH}" 8784 Call GetTextWidthHeight 8785 Pop ${_RES_WIDTH} 8786 Pop ${_RES_HEIGHT} 8787 !verbose pop 8788!macroend 8789 8790!macro un.GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT 8791 !verbose push 8792 !verbose ${_MOZFUNC_VERBOSE} 8793 Push "${_TEXT}" 8794 Push "${_FONT}" 8795 Push "${_MAX_WIDTH}" 8796 Call un.GetTextWidthHeight 8797 Pop ${_RES_WIDTH} 8798 Pop ${_RES_HEIGHT} 8799 !verbose pop 8800!macroend 8801 8802!macro un.GetTextWidthHeight 8803 !ifndef un.GetTextWidthHeight 8804 !verbose push 8805 !verbose ${_MOZFUNC_VERBOSE} 8806 !undef _MOZFUNC_UN 8807 !define _MOZFUNC_UN "un." 8808 8809 !insertmacro GetTextWidthHeight 8810 8811 !undef _MOZFUNC_UN 8812 !define _MOZFUNC_UN 8813 !verbose pop 8814 !endif 8815!macroend 8816 8817/** 8818 * Convert a number of dialog units to a number of pixels. 8819 * 8820 * _DU Number of dialog units to convert 8821 * _AXIS Which axis you want to convert a value along, X or Y 8822 * _RV Register or variable to return the number of pixels in 8823 */ 8824!macro _DialogUnitsToPixels _DU _AXIS _RV 8825 Push $0 8826 Push $1 8827 8828 ; The dialog units value might be a string ending with a 'u', 8829 ; so convert it to a number. 8830 IntOp $0 "${_DU}" + 0 8831 8832 !if ${_AXIS} == 'Y' 8833 System::Call '*(i 0, i 0, i 0, i r0) i .r1' 8834 System::Call 'user32::MapDialogRect(p $HWNDPARENT, p r1)' 8835 System::Call '*$1(i, i, i, i . r0)' 8836 !else if ${_AXIS} == 'X' 8837 System::Call '*(i 0, i 0, i r0, i 0) i .r1' 8838 System::Call 'user32::MapDialogRect(p $HWNDPARENT, p r1)' 8839 System::Call '*$1(i, i, i . r0, i)' 8840 !else 8841 !error "Invalid axis ${_AXIS} passed to DialogUnitsToPixels; please use X or Y" 8842 !endif 8843 System::Free $1 8844 8845 Pop $1 8846 Exch $0 8847 Pop ${_RV} 8848!macroend 8849!define DialogUnitsToPixels "!insertmacro _DialogUnitsToPixels" 8850 8851/** 8852 * Convert a given left coordinate for a dialog control to flip the control to 8853 * the other side of the dialog if we're using an RTL locale. 8854 * 8855 * _LEFT_DU Number of dialog units to convert 8856 * _WIDTH Width of the control in either pixels or DU's 8857 * If the string has a 'u' on the end, it will be interpreted as 8858 * dialog units, otherwise it will be interpreted as pixels. 8859 * _RV Register or variable to return converted coordinate, in pixels 8860 */ 8861!macro _ConvertLeftCoordForRTLCall _LEFT_DU _WIDTH _RV 8862 Push "${_LEFT_DU}" 8863 Push "${_WIDTH}" 8864 ${CallArtificialFunction} _ConvertLeftCoordForRTL 8865 Pop ${_RV} 8866!macroend 8867 8868!define ConvertLeftCoordForRTL "!insertmacro _ConvertLeftCoordForRTLCall" 8869!define un.ConvertLeftCoordForRTL "!insertmacro _ConvertLeftCoordForRTLCall" 8870 8871!macro _ConvertLeftCoordForRTL 8872 ; Stack contents after each instruction (top of the stack on the left): 8873 ; _WIDTH _LEFT_DU 8874 Exch $0 ; $0 _LEFT_DU 8875 Exch 1 ; _LEFT_DU $0 8876 Exch $1 ; $1 $0 8877 ; That's all the parameters, now save our scratch registers. 8878 Push $2 ; width of the entire dialog, in pixels 8879 Push $3 ; _LEFT_DU converted to pixels 8880 Push $4 ; temp string search result 8881 8882 !ifndef ${AB_CD}_rtl 8883 StrCpy $0 "$1" 8884 !else 8885 ${GetDlgItemWidthHeight} $HWNDPARENT $2 $3 8886 ${DialogUnitsToPixels} $1 X $3 8887 8888 ClearErrors 8889 ${${_MOZFUNC_UN}WordFind} "$0" "u" "E+1{" $4 8890 ${IfNot} ${Errors} 8891 ${DialogUnitsToPixels} $4 X $0 8892 ${EndIf} 8893 8894 IntOp $1 $2 - $3 8895 IntOp $1 $1 - $0 8896 StrCpy $0 $1 8897 !endif 8898 8899 ; Restore the values that were in our scratch registers. 8900 Pop $4 8901 Pop $3 8902 Pop $2 8903 ; Restore our parameter registers and return our result. 8904 ; Stack contents after each instruction (top of the stack on the left): 8905 ; $1 $0 8906 Pop $1 ; $0 8907 Exch $0 ; _RV 8908!macroend 8909 8910/** 8911 * Gets the elapsed time in seconds between two values in milliseconds stored as 8912 * an int64. The caller will typically get the millisecond values using 8913 * GetTickCount with a long return value as follows. 8914 * System::Call "kernel32::GetTickCount()l .s" 8915 * Pop $varname 8916 * 8917 * _START_TICK_COUNT 8918 * _FINISH_TICK_COUNT 8919 * _RES_ELAPSED_SECONDS return value - elapsed time between _START_TICK_COUNT 8920 * and _FINISH_TICK_COUNT in seconds. 8921 */ 8922!macro GetSecondsElapsedCall _START_TICK_COUNT _FINISH_TICK_COUNT _RES_ELAPSED_SECONDS 8923 Push "${_START_TICK_COUNT}" 8924 Push "${_FINISH_TICK_COUNT}" 8925 ${CallArtificialFunction} GetSecondsElapsed_ 8926 Pop ${_RES_ELAPSED_SECONDS} 8927!macroend 8928 8929!define GetSecondsElapsed "!insertmacro GetSecondsElapsedCall" 8930!define un.GetSecondsElapsed "!insertmacro GetSecondsElapsedCall" 8931 8932!macro GetSecondsElapsed_ 8933 Exch $0 ; finish tick count 8934 Exch 1 8935 Exch $1 ; start tick count 8936 8937 System::Int64Op $0 - $1 8938 Pop $0 8939 ; Discard the top bits of the int64 by bitmasking with MAXDWORD 8940 System::Int64Op $0 & ${MAXDWORD} 8941 Pop $0 8942 8943 ; Convert from milliseconds to seconds 8944 System::Int64Op $0 / 1000 8945 Pop $0 8946 8947 Pop $1 8948 Exch $0 ; return elapsed seconds 8949!macroend 8950 8951/** 8952 * Create a process to execute a command line. If it is successfully created, 8953 * wait on it with WaitForInputIdle, to avoid exiting the current process too 8954 * early (exiting early can cause the created process's windows to be opened in 8955 * the background). 8956 * 8957 * CMDLINE Is the command line to execute, like the argument to Exec 8958 */ 8959!define ExecAndWaitForInputIdle "!insertmacro ExecAndWaitForInputIdle_" 8960!define CREATE_DEFAULT_ERROR_MODE 0x04000000 8961!macro ExecAndWaitForInputIdle_ CMDLINE 8962 ; derived from https://stackoverflow.com/a/13960786/3444805 by Anders Kjersem 8963 Push $0 8964 Push $1 8965 Push $2 8966 8967 ; Command line 8968 StrCpy $0 "${CMDLINE}" 8969 8970 ; STARTUPINFO 8971 System::Alloc 68 8972 Pop $1 8973 ; fill in STARTUPINFO.cb (first field) with sizeof(STARTUPINFO) 8974 System::Call "*$1(i 68)" 8975 8976 ; PROCESS_INFORMATION 8977 System::Call "*(i, i, i, i) i . r2" 8978 8979 ; CREATE_DEFAULT_ERROR_MODE follows NSIS myCreateProcess used in Exec 8980 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" 8981 8982 System::Free $1 8983 ${If} $0 <> 0 8984 System::Call "*$2(i . r0, i . r1)" 8985 ; $0: hProcess, $1: hThread 8986 System::Call "user32::WaitForInputIdle(i $0, i 10000)" 8987 System::Call "kernel32::CloseHandle(i $0)" 8988 System::Call "kernel32::CloseHandle(i $1)" 8989 ${EndIf} 8990 System::Free $2 8991 8992 Pop $2 8993 Pop $1 8994 Pop $0 8995!macroend 8996 8997Function WriteRegQWORD 8998 ; Stack contents: 8999 ; VALUE, VALUE_NAME, SUBKEY, ROOTKEY 9000 Exch $3 ; $3, VALUE_NAME, SUBKEY, ROOTKEY 9001 Exch 1 ; VALUE_NAME, $3, SUBKEY, ROOTKEY 9002 Exch $2 ; $2, $3, SUBKEY, ROOTKEY 9003 Exch 2 ; SUBKEY, $3, $2, ROOTKEY 9004 Exch $1 ; $1, $3, $2, ROOTKEY 9005 Exch 3 ; ROOTKEY, $3, $2, $1 9006 Exch $0 ; $0, $3, $2, $1 9007 System::Call "advapi32::RegSetKeyValueW(p r0, w r1, w r2, i 11, *l r3, i 8) i.r0" 9008 ${IfNot} $0 = 0 9009 SetErrors 9010 ${EndIf} 9011 Pop $0 9012 Pop $3 9013 Pop $2 9014 Pop $1 9015FunctionEnd 9016!macro WriteRegQWORD ROOTKEY SUBKEY VALUE_NAME VALUE 9017 ${If} "${ROOTKEY}" == "HKCR" 9018 Push 0x80000000 9019 ${ElseIf} "${ROOTKEY}" == "HKCU" 9020 Push 0x80000001 9021 ${ElseIf} "${ROOTKEY}" == "HKLM" 9022 Push 0x80000002 9023 ${Endif} 9024 Push "${SUBKEY}" 9025 Push "${VALUE_NAME}" 9026 System::Int64Op ${VALUE} + 0 ; The result is pushed on the stack 9027 Call WriteRegQWORD 9028!macroend 9029!define WriteRegQWORD "!insertmacro WriteRegQWORD" 9030 9031Function ReadRegQWORD 9032 ; Stack contents: 9033 ; VALUE_NAME, SUBKEY, ROOTKEY 9034 Exch $2 ; $2, SUBKEY, ROOTKEY 9035 Exch 1 ; SUBKEY, $2, ROOTKEY 9036 Exch $1 ; $1, $2, ROOTKEY 9037 Exch 2 ; ROOTKEY, $2, $1 9038 Exch $0 ; $0, $2, $1 9039 System::Call "advapi32::RegGetValueW(p r0, w r1, w r2, i 0x48, p 0, *l s, *i 8) i.r0" 9040 ${IfNot} $0 = 0 9041 SetErrors 9042 ${EndIf} 9043 ; VALUE, $0, $2, $1 9044 Exch 3 ; $1, $0, $2, VALUE 9045 Pop $1 ; $0, $2, VALUE 9046 Pop $0 ; $2, VALUE 9047 Pop $2 ; VALUE 9048FunctionEnd 9049!macro ReadRegQWORD DEST ROOTKEY SUBKEY VALUE_NAME 9050 ${If} "${ROOTKEY}" == "HKCR" 9051 Push 0x80000000 9052 ${ElseIf} "${ROOTKEY}" == "HKCU" 9053 Push 0x80000001 9054 ${ElseIf} "${ROOTKEY}" == "HKLM" 9055 Push 0x80000002 9056 ${Endif} 9057 Push "${SUBKEY}" 9058 Push "${VALUE_NAME}" 9059 Call ReadRegQWORD 9060 Pop ${DEST} 9061!macroend 9062!define ReadRegQWORD "!insertmacro ReadRegQWORD" 9063 9064