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