michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: # file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: michael@0: ################################################################################ michael@0: # Helper defines and macros for toolkit applications michael@0: michael@0: /** michael@0: * Avoid creating macros / functions that overwrite registers (see the michael@0: * GetLongPath macro for one way to avoid this)! michael@0: * michael@0: * Before using the registers exchange the passed in params and save existing michael@0: * register values to the stack. michael@0: * michael@0: * Exch $R9 ; exhange the original $R9 with the top of the stack michael@0: * Exch 1 ; exchange the top of the stack with 1 below the top of the stack michael@0: * Exch $R8 ; exchange the original $R8 with the top of the stack michael@0: * Exch 2 ; exchange the top of the stack with 2 below the top of the stack michael@0: * Exch $R7 ; exchange the original $R7 with the top of the stack michael@0: * Push $R6 ; push the original $R6 onto the top of the stack michael@0: * Push $R5 ; push the original $R5 onto the top of the stack michael@0: * Push $R4 ; push the original $R4 onto the top of the stack michael@0: * michael@0: * michael@0: * michael@0: * ; Restore the values. michael@0: * Pop $R4 ; restore the value for $R4 from the top of the stack michael@0: * Pop $R5 ; restore the value for $R5 from the top of the stack michael@0: * Pop $R6 ; restore the value for $R6 from the top of the stack michael@0: * Exch $R7 ; exchange the new $R7 value with the top of the stack michael@0: * Exch 2 ; exchange the top of the stack with 2 below the top of the stack michael@0: * Exch $R8 ; exchange the new $R8 value with the top of the stack michael@0: * Exch 1 ; exchange the top of the stack with 2 below the top of the stack michael@0: * Exch $R9 ; exchange the new $R9 value with the top of the stack michael@0: * michael@0: * michael@0: * When inserting macros in common.nsh from another macro in common.nsh that michael@0: * can be used from the uninstaller _MOZFUNC_UN will be undefined when it is michael@0: * inserted. Use the following to redefine _MOZFUNC_UN with its original value michael@0: * (see the RegCleanMain macro for an example). michael@0: * michael@0: * !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: * !insertmacro ${_MOZFUNC_UN_TMP}FileJoin michael@0: * !insertmacro ${_MOZFUNC_UN_TMP}LineFind michael@0: * !insertmacro ${_MOZFUNC_UN_TMP}TextCompareNoDetails michael@0: * !insertmacro ${_MOZFUNC_UN_TMP}TrimNewLines michael@0: * !undef _MOZFUNC_UN michael@0: * !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: * !undef _MOZFUNC_UN_TMP michael@0: */ michael@0: michael@0: ; When including a file provided by NSIS check if its verbose macro is defined michael@0: ; to prevent loading the file a second time. michael@0: !ifmacrondef TEXTFUNC_VERBOSE michael@0: !include TextFunc.nsh michael@0: !endif michael@0: michael@0: !ifmacrondef FILEFUNC_VERBOSE michael@0: !include FileFunc.nsh michael@0: !endif michael@0: michael@0: !ifmacrondef LOGICLIB_VERBOSITY michael@0: !include LogicLib.nsh michael@0: !endif michael@0: michael@0: !ifndef WINMESSAGES_INCLUDED michael@0: !include WinMessages.nsh michael@0: !endif michael@0: michael@0: ; When including WinVer.nsh check if ___WINVER__NSH___ is defined to prevent michael@0: ; loading the file a second time. michael@0: !ifndef ___WINVER__NSH___ michael@0: !include WinVer.nsh michael@0: !endif michael@0: michael@0: !include x64.nsh michael@0: michael@0: ; NSIS provided macros that we have overridden. michael@0: !include overrides.nsh michael@0: michael@0: !define SHORTCUTS_LOG "shortcuts_log.ini" michael@0: !define TO_BE_DELETED "tobedeleted" michael@0: michael@0: ; !define SHCNF_DWORD 0x0003 michael@0: ; !define SHCNF_FLUSH 0x1000 michael@0: !ifndef SHCNF_DWORDFLUSH michael@0: !define SHCNF_DWORDFLUSH 0x1003 michael@0: !endif michael@0: !ifndef SHCNE_ASSOCCHANGED michael@0: !define SHCNE_ASSOCCHANGED 0x08000000 michael@0: !endif michael@0: michael@0: ################################################################################ michael@0: # Macros for debugging michael@0: michael@0: /** michael@0: * The following two macros assist with verifying that a macro doesn't michael@0: * overwrite any registers. michael@0: * michael@0: * Usage: michael@0: * ${debugSetRegisters} michael@0: * michael@0: * ${debugDisplayRegisters} michael@0: */ michael@0: michael@0: /** michael@0: * Sets all register values to their name to assist with verifying that a macro michael@0: * doesn't overwrite any registers. michael@0: */ michael@0: !macro debugSetRegisters michael@0: StrCpy $0 "$$0" michael@0: StrCpy $1 "$$1" michael@0: StrCpy $2 "$$2" michael@0: StrCpy $3 "$$3" michael@0: StrCpy $4 "$$4" michael@0: StrCpy $5 "$$5" michael@0: StrCpy $6 "$$6" michael@0: StrCpy $7 "$$7" michael@0: StrCpy $8 "$$8" michael@0: StrCpy $9 "$$9" michael@0: StrCpy $R0 "$$R0" michael@0: StrCpy $R1 "$$R1" michael@0: StrCpy $R2 "$$R2" michael@0: StrCpy $R3 "$$R3" michael@0: StrCpy $R4 "$$R4" michael@0: StrCpy $R5 "$$R5" michael@0: StrCpy $R6 "$$R6" michael@0: StrCpy $R7 "$$R7" michael@0: StrCpy $R8 "$$R8" michael@0: StrCpy $R9 "$$R9" michael@0: !macroend michael@0: !define debugSetRegisters "!insertmacro debugSetRegisters" michael@0: michael@0: /** michael@0: * Displays all register values to assist with verifying that a macro doesn't michael@0: * overwrite any registers. michael@0: */ michael@0: !macro debugDisplayRegisters michael@0: MessageBox MB_OK \ michael@0: "Register Values:$\n\ michael@0: $$0 = $0$\n$$1 = $1$\n$$2 = $2$\n$$3 = $3$\n$$4 = $4$\n\ michael@0: $$5 = $5$\n$$6 = $6$\n$$7 = $7$\n$$8 = $8$\n$$9 = $9$\n\ michael@0: $$R0 = $R0$\n$$R1 = $R1$\n$$R2 = $R2$\n$$R3 = $R3$\n$$R4 = $R4$\n\ michael@0: $$R5 = $R5$\n$$R6 = $R6$\n$$R7 = $R7$\n$$R8 = $R8$\n$$R9 = $R9" michael@0: !macroend michael@0: !define debugDisplayRegisters "!insertmacro debugDisplayRegisters" michael@0: michael@0: michael@0: ################################################################################ michael@0: # Modern User Interface (MUI) override macros michael@0: michael@0: ; Removed macros in nsis 2.33u (ported from nsis 2.22) michael@0: ; MUI_LANGUAGEFILE_DEFINE michael@0: ; MUI_LANGUAGEFILE_LANGSTRING_PAGE michael@0: ; MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE michael@0: ; MUI_LANGUAGEFILE_LANGSTRING_DEFINE michael@0: ; MUI_LANGUAGEFILE_UNLANGSTRING_PAGE michael@0: michael@0: !macro MOZ_MUI_LANGUAGEFILE_DEFINE DEFINE NAME michael@0: michael@0: !ifndef "${DEFINE}" michael@0: !define "${DEFINE}" "${${NAME}}" michael@0: !endif michael@0: !undef "${NAME}" michael@0: michael@0: !macroend michael@0: michael@0: !macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE PAGE NAME michael@0: michael@0: !ifdef MUI_${PAGE}PAGE michael@0: LangString "${NAME}" 0 "${${NAME}}" michael@0: !undef "${NAME}" michael@0: !else michael@0: !undef "${NAME}" michael@0: !endif michael@0: michael@0: !macroend michael@0: michael@0: !macro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE PAGE NAME michael@0: michael@0: !ifdef MUI_${PAGE}PAGE | MUI_UN${PAGE}PAGE michael@0: LangString "${NAME}" 0 "${${NAME}}" michael@0: !undef "${NAME}" michael@0: !else michael@0: !undef "${NAME}" michael@0: !endif michael@0: michael@0: !macroend michael@0: michael@0: !macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE DEFINE NAME michael@0: michael@0: !ifdef "${DEFINE}" michael@0: LangString "${NAME}" 0 "${${NAME}}" michael@0: !endif michael@0: !undef "${NAME}" michael@0: michael@0: !macroend michael@0: michael@0: !macro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE PAGE NAME michael@0: michael@0: !ifdef MUI_UNINSTALLER michael@0: !ifdef MUI_UN${PAGE}PAGE michael@0: LangString "${NAME}" 0 "${${NAME}}" michael@0: !undef "${NAME}" michael@0: !else michael@0: !undef "${NAME}" michael@0: !endif michael@0: !else michael@0: !undef "${NAME}" michael@0: !endif michael@0: michael@0: !macroend michael@0: michael@0: ; Modified version of the following MUI macros to support Mozilla localization. michael@0: ; MUI_LANGUAGE michael@0: ; MUI_LANGUAGEFILE_BEGIN michael@0: ; MOZ_MUI_LANGUAGEFILE_END michael@0: ; See /Contrib/Modern UI/System.nsh for more information michael@0: !define MUI_INSTALLOPTIONS_READ "!insertmacro MUI_INSTALLOPTIONS_READ" michael@0: michael@0: !macro MOZ_MUI_LANGUAGE LANGUAGE michael@0: !verbose push michael@0: !verbose ${MUI_VERBOSE} michael@0: !include "${LANGUAGE}.nsh" michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro MOZ_MUI_LANGUAGEFILE_BEGIN LANGUAGE michael@0: !insertmacro MUI_INSERT michael@0: !ifndef "MUI_LANGUAGEFILE_${LANGUAGE}_USED" michael@0: !define "MUI_LANGUAGEFILE_${LANGUAGE}_USED" michael@0: LoadLanguageFile "${LANGUAGE}.nlf" michael@0: !else michael@0: !error "Modern UI language file ${LANGUAGE} included twice!" michael@0: !endif michael@0: !macroend michael@0: michael@0: ; Custom version of MUI_LANGUAGEFILE_END. The macro to add the default MUI michael@0: ; strings and the macros for several strings that are part of the NSIS MUI and michael@0: ; not in our locale files have been commented out. michael@0: !macro MOZ_MUI_LANGUAGEFILE_END michael@0: michael@0: # !include "${NSISDIR}\Contrib\Modern UI\Language files\Default.nsh" michael@0: !ifdef MUI_LANGUAGEFILE_DEFAULT_USED michael@0: !undef MUI_LANGUAGEFILE_DEFAULT_USED michael@0: !warning "${LANGUAGE} Modern UI language file version doesn't match. Using default English texts for missing strings." michael@0: !endif michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_DEFINE "MUI_${LANGUAGE}_LANGNAME" "MUI_LANGNAME" michael@0: michael@0: !ifndef MUI_LANGDLL_PUSHLIST michael@0: !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} " michael@0: !else michael@0: !ifdef MUI_LANGDLL_PUSHLIST_TEMP michael@0: !undef MUI_LANGDLL_PUSHLIST_TEMP michael@0: !endif michael@0: !define MUI_LANGDLL_PUSHLIST_TEMP "${MUI_LANGDLL_PUSHLIST}" michael@0: !undef MUI_LANGDLL_PUSHLIST michael@0: !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} ${MUI_LANGDLL_PUSHLIST_TEMP}" michael@0: !endif michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TEXT" michael@0: michael@0: !ifdef MUI_TEXT_LICENSE_TITLE michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_TITLE" michael@0: !endif michael@0: !ifdef MUI_TEXT_LICENSE_SUBTITLE michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_SUBTITLE" michael@0: !endif michael@0: !ifdef MUI_INNERTEXT_LICENSE_TOP michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_TOP" michael@0: !endif michael@0: michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM" michael@0: michael@0: !ifdef MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX" michael@0: !endif michael@0: michael@0: !ifdef MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS" michael@0: !endif michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_SUBTITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_SUBTITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_TOP" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_CHECKBOX" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_BUTTONTEXT_FINISH" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TEXT" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_REBOOT" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTNOW" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTLATER" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_RUN" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_SHOWREADME" michael@0: michael@0: ; Support for using the existing MUI_TEXT_ABORTWARNING string michael@0: !ifdef MOZ_MUI_CUSTOM_ABORT michael@0: LangString MOZ_MUI_TEXT_ABORTWARNING 0 "${MUI_TEXT_ABORTWARNING}" michael@0: !endif michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_ABORTWARNING "MUI_TEXT_ABORTWARNING" michael@0: michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TEXT" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_SUBTITLE" michael@0: michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_TITLE" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_SUBTITLE" michael@0: michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_CHECKBOX" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS" michael@0: michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_TITLE" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_SUBTITLE" michael@0: michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_TITLE" michael@0: # !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_SUBTITLE" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TITLE" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TEXT" michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_REBOOT" michael@0: michael@0: !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_UNABORTWARNING "MUI_UNTEXT_ABORTWARNING" michael@0: michael@0: !ifndef MUI_LANGDLL_LANGUAGES michael@0: !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' " michael@0: !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' " michael@0: !else michael@0: !ifdef MUI_LANGDLL_LANGUAGES_TEMP michael@0: !undef MUI_LANGDLL_LANGUAGES_TEMP michael@0: !endif michael@0: !define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}" michael@0: !undef MUI_LANGDLL_LANGUAGES michael@0: michael@0: !ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP michael@0: !undef MUI_LANGDLL_LANGUAGES_CP_TEMP michael@0: !endif michael@0: !define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}" michael@0: !undef MUI_LANGDLL_LANGUAGES_CP michael@0: michael@0: !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}" michael@0: !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}" michael@0: !endif michael@0: michael@0: !macroend michael@0: michael@0: /** michael@0: * Creates an InstallOptions file with a UTF-16LE BOM and adds the RTL value michael@0: * to the Settings section. michael@0: * michael@0: * @param _FILE michael@0: * The name of the file to be created in $PLUGINSDIR. michael@0: */ michael@0: !macro InitInstallOptionsFile _FILE michael@0: Push $R9 michael@0: michael@0: FileOpen $R9 "$PLUGINSDIR\${_FILE}" w michael@0: FileWriteWord $R9 "65279" michael@0: FileClose $R9 michael@0: WriteIniStr "$PLUGINSDIR\${_FILE}" "Settings" "RTL" "$(^RTL)" michael@0: michael@0: Pop $R9 michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for handling files in use michael@0: michael@0: /** michael@0: * Checks for files in use in the $INSTDIR directory. To check files in michael@0: * sub-directories this macro would need to be rewritten to create michael@0: * sub-directories in the temporary directory used to backup the files that are michael@0: * checked. michael@0: * michael@0: * Example usage: michael@0: * michael@0: * ; The first string to be pushed onto the stack MUST be "end" to indicate michael@0: * ; that there are no more files in the $INSTDIR directory to check. michael@0: * Push "end" michael@0: * Push "freebl3.dll" michael@0: * ; The last file pushed should be the app's main exe so if it is in use this michael@0: * ; macro will return after the first check. michael@0: * Push "${FileMainEXE}" michael@0: * ${CheckForFilesInUse} $R9 michael@0: * michael@0: * !IMPORTANT - this macro uses the $R7, $R8, and $R9 registers and makes no michael@0: * attempt to restore their original values. michael@0: * michael@0: * @return _RESULT michael@0: * false if all of the files popped from the stack are not in use. michael@0: * True if any of the files popped from the stack are in use. michael@0: * $R7 = Temporary backup directory where the files will be copied to. michael@0: * $R8 = value popped from the stack. This will either be a file name for a file michael@0: * in the $INSTDIR directory or "end" to indicate that there are no michael@0: * additional files to check. michael@0: * $R9 = _RESULT michael@0: */ michael@0: !macro CheckForFilesInUse michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CheckForFilesInUse michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CheckForFilesInUse "!insertmacro ${_MOZFUNC_UN}CheckForFilesInUseCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CheckForFilesInUse michael@0: ; Create a temporary backup directory. michael@0: GetTempFileName $R7 "$INSTDIR" michael@0: Delete "$R7" michael@0: SetOutPath "$R7" michael@0: StrCpy $R9 "false" michael@0: michael@0: Pop $R8 michael@0: ${While} $R8 != "end" michael@0: ${Unless} ${FileExists} "$INSTDIR\$R8" michael@0: Pop $R8 ; get next file to check before continuing michael@0: ${Continue} michael@0: ${EndUnless} michael@0: michael@0: ClearErrors michael@0: CopyFiles /SILENT "$INSTDIR\$R8" "$R7\$R8" ; try to copy michael@0: ${If} ${Errors} michael@0: ; File is in use michael@0: StrCpy $R9 "true" michael@0: ${Break} michael@0: ${EndIf} michael@0: michael@0: Delete "$INSTDIR\$R8" ; delete original michael@0: ${If} ${Errors} michael@0: ; File is in use michael@0: StrCpy $R9 "true" michael@0: Delete "$R7\$R8" ; delete temp copy michael@0: ${Break} michael@0: ${EndIf} michael@0: michael@0: Pop $R8 ; get next file to check michael@0: ${EndWhile} michael@0: michael@0: ; clear stack michael@0: ${While} $R8 != "end" michael@0: Pop $R8 michael@0: ${EndWhile} michael@0: michael@0: ; restore everything michael@0: SetOutPath "$INSTDIR" michael@0: CopyFiles /SILENT "$R7\*" "$INSTDIR\" michael@0: RmDir /r "$R7" michael@0: SetOutPath "$EXEDIR" michael@0: ClearErrors michael@0: michael@0: Push $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CheckForFilesInUseCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call CheckForFilesInUse michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CheckForFilesInUseCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.CheckForFilesInUse michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CheckForFilesInUse michael@0: !ifndef un.CheckForFilesInUse michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CheckForFilesInUse michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * The macros below will automatically prepend un. to the function names when michael@0: * they are defined (e.g. !define un.RegCleanMain). michael@0: */ michael@0: !verbose push michael@0: !verbose 3 michael@0: !ifndef _MOZFUNC_VERBOSE michael@0: !define _MOZFUNC_VERBOSE 3 michael@0: !endif michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define MOZFUNC_VERBOSE "!insertmacro MOZFUNC_VERBOSE" michael@0: !define _MOZFUNC_UN michael@0: !define _MOZFUNC_S michael@0: !verbose pop michael@0: michael@0: !macro MOZFUNC_VERBOSE _VERBOSE michael@0: !verbose push michael@0: !verbose 3 michael@0: !undef _MOZFUNC_VERBOSE michael@0: !define _MOZFUNC_VERBOSE ${_VERBOSE} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Displays a MessageBox and then calls abort to prevent continuing to the michael@0: * next page when the specified Window Class is found. michael@0: * michael@0: * @param _WINDOW_CLASS michael@0: * The Window Class to search for with FindWindow. michael@0: * @param _MSG michael@0: * The message text to display in the message box. michael@0: * michael@0: * $R7 = return value from FindWindow michael@0: * $R8 = _WINDOW_CLASS michael@0: * $R9 = _MSG michael@0: */ michael@0: !macro ManualCloseAppPrompt michael@0: michael@0: !ifndef ${_MOZFUNC_UN}ManualCloseAppPrompt michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}ManualCloseAppPrompt "!insertmacro ${_MOZFUNC_UN}ManualCloseAppPromptCall" michael@0: michael@0: Function ${_MOZFUNC_UN}ManualCloseAppPrompt michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Push $R7 michael@0: michael@0: FindWindow $R7 "$R8" michael@0: ${If} $R7 <> 0 ; integer comparison michael@0: MessageBox MB_OK|MB_ICONQUESTION "$R9" michael@0: Abort michael@0: ${EndIf} michael@0: michael@0: Pop $R7 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro ManualCloseAppPromptCall _WINDOW_CLASS _MSG michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_WINDOW_CLASS}" michael@0: Push "${_MSG}" michael@0: Call ManualCloseAppPrompt michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.ManualCloseAppPromptCall _WINDOW_CLASS _MSG michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_WINDOW_CLASS}" michael@0: Push "${_MSG}" michael@0: Call un.ManualCloseAppPrompt michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.ManualCloseAppPrompt michael@0: !ifndef un.ManualCloseAppPrompt michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro ManualCloseAppPrompt michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for working with the registry michael@0: michael@0: /** michael@0: * Writes a registry string using SHCTX and the supplied params and logs the michael@0: * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1. michael@0: * michael@0: * Define NO_LOG to prevent all logging when calling this from the uninstaller. michael@0: * michael@0: * @param _ROOT michael@0: * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). michael@0: * This will only be used for logging. michael@0: * @param _KEY michael@0: * The subkey in relation to the key root. michael@0: * @param _NAME michael@0: * The key value name to write to. michael@0: * @param _STR michael@0: * The string to write to the key value name. michael@0: * @param _LOG_UNINSTALL michael@0: * 0 = don't add to uninstall log, 1 = add to uninstall log. michael@0: * michael@0: * $R5 = _ROOT michael@0: * $R6 = _KEY michael@0: * $R7 = _NAME michael@0: * $R8 = _STR michael@0: * $R9 = _LOG_UNINSTALL michael@0: */ michael@0: !macro WriteRegStr2 michael@0: michael@0: !ifndef ${_MOZFUNC_UN}WriteRegStr2 michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}WriteRegStr2 "!insertmacro ${_MOZFUNC_UN}WriteRegStr2Call" michael@0: michael@0: Function ${_MOZFUNC_UN}WriteRegStr2 michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Exch 4 michael@0: Exch $R5 michael@0: michael@0: ClearErrors michael@0: WriteRegStr SHCTX "$R6" "$R7" "$R8" michael@0: michael@0: !ifndef NO_LOG michael@0: ${If} ${Errors} michael@0: ${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **" michael@0: ${Else} michael@0: ${If} $R9 == 1 ; add to the uninstall log? michael@0: ${LogUninstall} "RegVal: $R5 | $R6 | $R7" michael@0: ${EndIf} michael@0: ${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8" michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: Exch $R5 michael@0: Exch 4 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro WriteRegStr2Call _ROOT _KEY _NAME _STR _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_NAME}" michael@0: Push "${_STR}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call WriteRegStr2 michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.WriteRegStr2Call _ROOT _KEY _NAME _STR _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_NAME}" michael@0: Push "${_STR}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call un.WriteRegStr2 michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.WriteRegStr2 michael@0: !ifndef un.WriteRegStr2 michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro WriteRegStr2 michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Writes a registry dword using SHCTX and the supplied params and logs the michael@0: * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1. michael@0: * michael@0: * Define NO_LOG to prevent all logging when calling this from the uninstaller. michael@0: * michael@0: * @param _ROOT michael@0: * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). michael@0: * This will only be used for logging. michael@0: * @param _KEY michael@0: * The subkey in relation to the key root. michael@0: * @param _NAME michael@0: * The key value name to write to. michael@0: * @param _DWORD michael@0: * The dword to write to the key value name. michael@0: * @param _LOG_UNINSTALL michael@0: * 0 = don't add to uninstall log, 1 = add to uninstall log. michael@0: * michael@0: * $R5 = _ROOT michael@0: * $R6 = _KEY michael@0: * $R7 = _NAME michael@0: * $R8 = _DWORD michael@0: * $R9 = _LOG_UNINSTALL michael@0: */ michael@0: !macro WriteRegDWORD2 michael@0: michael@0: !ifndef ${_MOZFUNC_UN}WriteRegDWORD2 michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}WriteRegDWORD2 "!insertmacro ${_MOZFUNC_UN}WriteRegDWORD2Call" michael@0: michael@0: Function ${_MOZFUNC_UN}WriteRegDWORD2 michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Exch 4 michael@0: Exch $R5 michael@0: michael@0: ClearErrors michael@0: WriteRegDWORD SHCTX "$R6" "$R7" "$R8" michael@0: michael@0: !ifndef NO_LOG michael@0: ${If} ${Errors} michael@0: ${LogMsg} "** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **" michael@0: ${Else} michael@0: ${If} $R9 == 1 ; add to the uninstall log? michael@0: ${LogUninstall} "RegVal: $R5 | $R6 | $R7" michael@0: ${EndIf} michael@0: ${LogMsg} "Added Registry DWord: $R5 | $R6 | $R7 | $R8" michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: Exch $R5 michael@0: Exch 4 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro WriteRegDWORD2Call _ROOT _KEY _NAME _DWORD _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_NAME}" michael@0: Push "${_DWORD}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call WriteRegDWORD2 michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.WriteRegDWORD2Call _ROOT _KEY _NAME _DWORD _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_NAME}" michael@0: Push "${_DWORD}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call un.WriteRegDWORD2 michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.WriteRegDWORD2 michael@0: !ifndef un.WriteRegDWORD2 michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro WriteRegDWORD2 michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Writes a registry string to HKCR using the supplied params and logs the michael@0: * action to the install log and the uninstall log if _LOG_UNINSTALL equals 1. michael@0: * michael@0: * Define NO_LOG to prevent all logging when calling this from the uninstaller. michael@0: * michael@0: * @param _ROOT michael@0: * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). michael@0: * This will only be used for logging. michael@0: * @param _KEY michael@0: * The subkey in relation to the key root. michael@0: * @param _NAME michael@0: * The key value name to write to. michael@0: * @param _STR michael@0: * The string to write to the key value name. michael@0: * @param _LOG_UNINSTALL michael@0: * 0 = don't add to uninstall log, 1 = add to uninstall log. michael@0: * michael@0: * $R5 = _ROOT michael@0: * $R6 = _KEY michael@0: * $R7 = _NAME michael@0: * $R8 = _STR michael@0: * $R9 = _LOG_UNINSTALL michael@0: */ michael@0: !macro WriteRegStrHKCR michael@0: michael@0: !ifndef ${_MOZFUNC_UN}WriteRegStrHKCR michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}WriteRegStrHKCR "!insertmacro ${_MOZFUNC_UN}WriteRegStrHKCRCall" michael@0: michael@0: Function ${_MOZFUNC_UN}WriteRegStrHKCR michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Exch 4 michael@0: Exch $R5 michael@0: michael@0: ClearErrors michael@0: WriteRegStr HKCR "$R6" "$R7" "$R8" michael@0: michael@0: !ifndef NO_LOG michael@0: ${If} ${Errors} michael@0: ${LogMsg} "** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **" michael@0: ${Else} michael@0: ${If} $R9 == 1 ; add to the uninstall log? michael@0: ${LogUninstall} "RegVal: $R5 | $R6 | $R7" michael@0: ${EndIf} michael@0: ${LogMsg} "Added Registry String: $R5 | $R6 | $R7 | $R8" michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: Exch $R5 michael@0: Exch 4 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro WriteRegStrHKCRCall _ROOT _KEY _NAME _STR _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_NAME}" michael@0: Push "${_STR}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call WriteRegStrHKCR michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.WriteRegStrHKCRCall _ROOT _KEY _NAME _STR _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_NAME}" michael@0: Push "${_STR}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call un.WriteRegStrHKCR michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.WriteRegStrHKCR michael@0: !ifndef un.WriteRegStrHKCR michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro WriteRegStrHKCR michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !ifndef KEY_SET_VALUE michael@0: !define KEY_SET_VALUE 0x0002 michael@0: !endif michael@0: !ifndef KEY_WOW64_64KEY michael@0: !define KEY_WOW64_64KEY 0x0100 michael@0: !endif michael@0: !ifndef HAVE_64BIT_OS michael@0: !define CREATE_KEY_SAM ${KEY_SET_VALUE} michael@0: !else michael@0: !define CREATE_KEY_SAM ${KEY_SET_VALUE}|${KEY_WOW64_64KEY} michael@0: !endif michael@0: michael@0: /** michael@0: * Creates a registry key. This will log the actions to the install and michael@0: * uninstall logs. Alternatively you can set a registry value to create the key michael@0: * and then delete the value. michael@0: * michael@0: * Define NO_LOG to prevent all logging when calling this from the uninstaller. michael@0: * michael@0: * @param _ROOT michael@0: * The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.). michael@0: * @param _KEY michael@0: * The subkey in relation to the key root. michael@0: * @param _LOG_UNINSTALL michael@0: * 0 = don't add to uninstall log, 1 = add to uninstall log. michael@0: * michael@0: * $R4 = [out] handle to newly created registry key. If this is not a key michael@0: * located in one of the predefined registry keys this must be closed michael@0: * with RegCloseKey (this should not be needed unless someone decides to michael@0: * do something extremely squirrelly with NSIS). michael@0: * $R5 = return value from RegCreateKeyExW (represented by R5 in the system call). michael@0: * $R6 = [in] hKey passed to RegCreateKeyExW. michael@0: * $R7 = _ROOT michael@0: * $R8 = _KEY michael@0: * $R9 = _LOG_UNINSTALL michael@0: */ michael@0: !macro CreateRegKey michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CreateRegKey michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CreateRegKey "!insertmacro ${_MOZFUNC_UN}CreateRegKeyCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CreateRegKey michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: michael@0: StrCmp $R7 "HKCR" +1 +2 michael@0: StrCpy $R6 "0x80000000" michael@0: StrCmp $R7 "HKCU" +1 +2 michael@0: StrCpy $R6 "0x80000001" michael@0: StrCmp $R7 "HKLM" +1 +2 michael@0: StrCpy $R6 "0x80000002" michael@0: michael@0: ; see definition of RegCreateKey michael@0: System::Call "Advapi32::RegCreateKeyExW(i R6, w R8, i 0, i 0, i 0,\ michael@0: i ${CREATE_KEY_SAM}, i 0, *i .R4,\ michael@0: i 0) i .R5" michael@0: michael@0: !ifndef NO_LOG michael@0: ; if $R5 is not 0 then there was an error creating the registry key. michael@0: ${If} $R5 <> 0 michael@0: ${LogMsg} "** ERROR Adding Registry Key: $R7 | $R8 **" michael@0: ${Else} michael@0: ${If} $R9 == 1 ; add to the uninstall log? michael@0: ${LogUninstall} "RegKey: $R7 | $R8" michael@0: ${EndIf} michael@0: ${LogMsg} "Added Registry Key: $R7 | $R8" michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: StrCmp $R5 0 +1 +2 michael@0: System::Call "Advapi32::RegCloseKey(iR4)" michael@0: michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CreateRegKeyCall _ROOT _KEY _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call CreateRegKey michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CreateRegKeyCall _ROOT _KEY _LOG_UNINSTALL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_ROOT}" michael@0: Push "${_KEY}" michael@0: Push "${_LOG_UNINSTALL}" michael@0: Call un.CreateRegKey michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CreateRegKey michael@0: !ifndef un.CreateRegKey michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CreateRegKey michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Helper for checking for the existence of a registry key. michael@0: * SHCTX is the root key to search. michael@0: * michael@0: * @param _MAIN_KEY michael@0: * Sub key to iterate for the key in question michael@0: * @param _KEY michael@0: * Key name to search for michael@0: * @return _RESULT michael@0: * 'true' / 'false' result michael@0: */ michael@0: !macro CheckIfRegistryKeyExists michael@0: !ifndef CheckIfRegistryKeyExists michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define CheckIfRegistryKeyExists "!insertmacro CheckIfRegistryKeyExistsCall" michael@0: michael@0: Function CheckIfRegistryKeyExists michael@0: ; stack: main key, key michael@0: Exch $R9 ; main key, stack: old R9, key michael@0: Exch 1 ; stack: key, old R9 michael@0: Exch $R8 ; key, stack: old R8, old R9 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: StrCpy $R5 "false" michael@0: StrCpy $R7 "0" # loop index michael@0: ${Do} michael@0: EnumRegKey $R6 SHCTX "$R9" "$R7" michael@0: ${If} "$R6" == "$R8" michael@0: StrCpy $R5 "true" michael@0: ${Break} michael@0: ${EndIf} michael@0: IntOp $R7 $R7 + 1 michael@0: ${LoopWhile} $R6 != "" michael@0: ClearErrors michael@0: michael@0: StrCpy $R9 $R5 michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 ; stack: old R8, old R9 michael@0: Pop $R8 ; stack: old R9 michael@0: Exch $R9 ; stack: result michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CheckIfRegistryKeyExistsCall _MAIN_KEY _KEY _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_MAIN_KEY}" michael@0: Call CheckIfRegistryKeyExists michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: ################################################################################ michael@0: # Macros for adding file and protocol handlers michael@0: michael@0: /** michael@0: * Writes common registry values for a handler using SHCTX. michael@0: * michael@0: * @param _KEY michael@0: * The subkey in relation to the key root. michael@0: * @param _VALOPEN michael@0: * The path and args to launch the application. michael@0: * @param _VALICON michael@0: * The path to the binary that contains the icon group for the default icon michael@0: * followed by a comma and either the icon group's resource index or the icon michael@0: * group's resource id prefixed with a minus sign michael@0: * @param _DISPNAME michael@0: * The display name for the handler. If emtpy no value will be set. michael@0: * @param _ISPROTOCOL michael@0: * Sets protocol handler specific registry values when "true". michael@0: * Deletes protocol handler specific registry values when "delete". michael@0: * Otherwise doesn't touch handler specific registry values. michael@0: * @param _ISDDE michael@0: * Sets DDE specific registry values when "true". michael@0: * michael@0: * $R3 = string value of the current registry key path. michael@0: * $R4 = _KEY michael@0: * $R5 = _VALOPEN michael@0: * $R6 = _VALICON michael@0: * $R7 = _DISPNAME michael@0: * $R8 = _ISPROTOCOL michael@0: * $R9 = _ISDDE michael@0: */ michael@0: !macro AddHandlerValues michael@0: michael@0: !ifndef ${_MOZFUNC_UN}AddHandlerValues michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}AddHandlerValues "!insertmacro ${_MOZFUNC_UN}AddHandlerValuesCall" michael@0: michael@0: Function ${_MOZFUNC_UN}AddHandlerValues michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Exch 4 michael@0: Exch $R5 michael@0: Exch 5 michael@0: Exch $R4 michael@0: Push $R3 michael@0: michael@0: StrCmp "$R7" "" +6 +1 michael@0: ReadRegStr $R3 SHCTX "$R4" "FriendlyTypeName" michael@0: michael@0: StrCmp "$R3" "" +1 +3 michael@0: WriteRegStr SHCTX "$R4" "" "$R7" michael@0: WriteRegStr SHCTX "$R4" "FriendlyTypeName" "$R7" michael@0: michael@0: StrCmp "$R8" "true" +1 +2 michael@0: WriteRegStr SHCTX "$R4" "URL Protocol" "" michael@0: StrCmp "$R8" "delete" +1 +2 michael@0: DeleteRegValue SHCTX "$R4" "URL Protocol" michael@0: StrCpy $R3 "" michael@0: ReadRegDWord $R3 SHCTX "$R4" "EditFlags" michael@0: StrCmp $R3 "" +1 +3 ; Only add EditFlags if a value doesn't exist michael@0: DeleteRegValue SHCTX "$R4" "EditFlags" michael@0: WriteRegDWord SHCTX "$R4" "EditFlags" 0x00000002 michael@0: michael@0: StrCmp "$R6" "" +2 +1 michael@0: WriteRegStr SHCTX "$R4\DefaultIcon" "" "$R6" michael@0: michael@0: StrCmp "$R5" "" +2 +1 michael@0: WriteRegStr SHCTX "$R4\shell\open\command" "" "$R5" michael@0: michael@0: !ifdef DDEApplication michael@0: StrCmp "$R9" "true" +1 +11 michael@0: WriteRegStr SHCTX "$R4\shell\open\ddeexec" "" "$\"%1$\",,0,0,,,," michael@0: WriteRegStr SHCTX "$R4\shell\open\ddeexec" "NoActivateHandler" "" michael@0: WriteRegStr SHCTX "$R4\shell\open\ddeexec\Application" "" "${DDEApplication}" michael@0: WriteRegStr SHCTX "$R4\shell\open\ddeexec\Topic" "" "WWW_OpenURL" michael@0: ; The ifexec key may have been added by another application so try to michael@0: ; delete it to prevent it from breaking this app's shell integration. michael@0: ; Also, IE 6 and below doesn't remove this key when it sets itself as the michael@0: ; default handler and if this key exists IE's shell integration breaks. michael@0: DeleteRegKey HKLM "$R4\shell\open\ddeexec\ifexec" michael@0: DeleteRegKey HKCU "$R4\shell\open\ddeexec\ifexec" michael@0: !endif michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R3 michael@0: Exch $R4 michael@0: Exch 5 michael@0: Exch $R5 michael@0: Exch 4 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_VALOPEN}" michael@0: Push "${_VALICON}" michael@0: Push "${_DISPNAME}" michael@0: Push "${_ISPROTOCOL}" michael@0: Push "${_ISDDE}" michael@0: Call AddHandlerValues michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_VALOPEN}" michael@0: Push "${_VALICON}" michael@0: Push "${_DISPNAME}" michael@0: Push "${_ISPROTOCOL}" michael@0: Push "${_ISDDE}" michael@0: Call un.AddHandlerValues michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.AddHandlerValues michael@0: !ifndef un.AddHandlerValues michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro AddHandlerValues michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Writes common registry values for a handler that uses DDE using SHCTX. michael@0: * michael@0: * @param _KEY michael@0: * The key name in relation to the HKCR root. SOFTWARE\Classes is michael@0: * prefixed to this value when using SHCTX. michael@0: * @param _VALOPEN michael@0: * The path and args to launch the application. michael@0: * @param _VALICON michael@0: * The path to the binary that contains the icon group for the default icon michael@0: * followed by a comma and either the icon group's resource index or the icon michael@0: * group's resource id prefixed with a minus sign michael@0: * @param _DISPNAME michael@0: * The display name for the handler. If emtpy no value will be set. michael@0: * @param _ISPROTOCOL michael@0: * Sets protocol handler specific registry values when "true". michael@0: * Deletes protocol handler specific registry values when "delete". michael@0: * Otherwise doesn't touch handler specific registry values. michael@0: * @param _DDE_APPNAME michael@0: * Sets DDE specific registry values when not an empty string. michael@0: * michael@0: * $R0 = storage for SOFTWARE\Classes michael@0: * $R1 = string value of the current registry key path. michael@0: * $R2 = _KEY michael@0: * $R3 = _VALOPEN michael@0: * $R4 = _VALICON michael@0: * $R5 = _DISPNAME michael@0: * $R6 = _ISPROTOCOL michael@0: * $R7 = _DDE_APPNAME michael@0: * $R8 = _DDE_DEFAULT michael@0: * $R9 = _DDE_TOPIC michael@0: */ michael@0: !macro AddDDEHandlerValues michael@0: michael@0: !ifndef ${_MOZFUNC_UN}AddDDEHandlerValues michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}AddDDEHandlerValues "!insertmacro ${_MOZFUNC_UN}AddDDEHandlerValuesCall" michael@0: michael@0: Function ${_MOZFUNC_UN}AddDDEHandlerValues michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Exch 4 michael@0: Exch $R5 michael@0: Exch 5 michael@0: Exch $R4 michael@0: Exch 6 michael@0: Exch $R3 michael@0: Exch 7 michael@0: Exch $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: michael@0: StrCpy $R0 "SOFTWARE\Classes" michael@0: StrCmp "$R5" "" +6 +1 michael@0: ReadRegStr $R1 SHCTX "$R2" "FriendlyTypeName" michael@0: michael@0: StrCmp "$R1" "" +1 +3 michael@0: WriteRegStr SHCTX "$R0\$R2" "" "$R5" michael@0: WriteRegStr SHCTX "$R0\$R2" "FriendlyTypeName" "$R5" michael@0: michael@0: StrCmp "$R6" "true" +1 +2 michael@0: WriteRegStr SHCTX "$R0\$R2" "URL Protocol" "" michael@0: StrCmp "$R6" "delete" +1 +2 michael@0: DeleteRegValue SHCTX "$R0\$R2" "URL Protocol" michael@0: StrCpy $R1 "" michael@0: ReadRegDWord $R1 SHCTX "$R0\$R2" "EditFlags" michael@0: StrCmp $R1 "" +1 +3 ; Only add EditFlags if a value doesn't exist michael@0: DeleteRegValue SHCTX "$R0\$R2" "EditFlags" michael@0: WriteRegDWord SHCTX "$R0\$R2" "EditFlags" 0x00000002 michael@0: michael@0: StrCmp "$R4" "" +2 +1 michael@0: WriteRegStr SHCTX "$R0\$R2\DefaultIcon" "" "$R4" michael@0: michael@0: WriteRegStr SHCTX "$R0\$R2\shell" "" "open" michael@0: WriteRegStr SHCTX "$R0\$R2\shell\open\command" "" "$R3" michael@0: michael@0: WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec" "" "$R8" michael@0: WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec" "NoActivateHandler" "" michael@0: WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec\Application" "" "$R7" michael@0: WriteRegStr SHCTX "$R0\$R2\shell\open\ddeexec\Topic" "" "$R9" michael@0: michael@0: ; The ifexec key may have been added by another application so try to michael@0: ; delete it to prevent it from breaking this app's shell integration. michael@0: ; Also, IE 6 and below doesn't remove this key when it sets itself as the michael@0: ; default handler and if this key exists IE's shell integration breaks. michael@0: DeleteRegKey HKLM "$R0\$R2\shell\open\ddeexec\ifexec" michael@0: DeleteRegKey HKCU "$R0\$R2\shell\open\ddeexec\ifexec" michael@0: ClearErrors michael@0: michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Exch $R2 michael@0: Exch 7 michael@0: Exch $R3 michael@0: Exch 6 michael@0: Exch $R4 michael@0: Exch 5 michael@0: Exch $R5 michael@0: Exch 4 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro AddDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _DDE_APPNAME _DDE_DEFAULT _DDE_TOPIC michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_VALOPEN}" michael@0: Push "${_VALICON}" michael@0: Push "${_DISPNAME}" michael@0: Push "${_ISPROTOCOL}" michael@0: Push "${_DDE_APPNAME}" michael@0: Push "${_DDE_DEFAULT}" michael@0: Push "${_DDE_TOPIC}" michael@0: Call AddDDEHandlerValues michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.AddDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _DDE_APPNAME _DDE_DEFAULT _DDE_TOPIC michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_VALOPEN}" michael@0: Push "${_VALICON}" michael@0: Push "${_DISPNAME}" michael@0: Push "${_ISPROTOCOL}" michael@0: Push "${_DDE_APPNAME}" michael@0: Push "${_DDE_DEFAULT}" michael@0: Push "${_DDE_TOPIC}" michael@0: Call un.AddDDEHandlerValues michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.AddDDEHandlerValues michael@0: !ifndef un.AddDDEHandlerValues michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro AddDDEHandlerValues michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Writes common registry values for a handler that DOES NOT use DDE using SHCTX. michael@0: * michael@0: * @param _KEY michael@0: * The key name in relation to the HKCR root. SOFTWARE\Classes is michael@0: * prefixed to this value when using SHCTX. michael@0: * @param _VALOPEN michael@0: * The path and args to launch the application. michael@0: * @param _VALICON michael@0: * The path to the binary that contains the icon group for the default icon michael@0: * followed by a comma and either the icon group's resource index or the icon michael@0: * group's resource id prefixed with a minus sign michael@0: * @param _DISPNAME michael@0: * The display name for the handler. If emtpy no value will be set. michael@0: * @param _ISPROTOCOL michael@0: * Sets protocol handler specific registry values when "true". michael@0: * Deletes protocol handler specific registry values when "delete". michael@0: * Otherwise doesn't touch handler specific registry values. michael@0: * michael@0: * $R3 = storage for SOFTWARE\Classes michael@0: * $R4 = string value of the current registry key path. michael@0: * $R5 = _KEY michael@0: * $R6 = _VALOPEN michael@0: * $R7 = _VALICON michael@0: * $R8 = _DISPNAME michael@0: * $R9 = _ISPROTOCOL michael@0: */ michael@0: !macro AddDisabledDDEHandlerValues michael@0: michael@0: !ifndef ${_MOZFUNC_UN}AddDisabledDDEHandlerValues michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}AddDisabledDDEHandlerValues "!insertmacro ${_MOZFUNC_UN}AddDisabledDDEHandlerValuesCall" michael@0: michael@0: Function ${_MOZFUNC_UN}AddDisabledDDEHandlerValues michael@0: Exch $R9 ; _ISPROTOCOL michael@0: Exch 1 michael@0: Exch $R8 ; FriendlyTypeName michael@0: Exch 2 michael@0: Exch $R7 ; icon index michael@0: Exch 3 michael@0: Exch $R6 ; shell\open\command michael@0: Exch 4 michael@0: Exch $R5 ; reg key michael@0: Push $R4 ; michael@0: Push $R3 ; base reg class michael@0: michael@0: StrCpy $R3 "SOFTWARE\Classes" michael@0: StrCmp "$R8" "" +6 +1 michael@0: ReadRegStr $R4 SHCTX "$R5" "FriendlyTypeName" michael@0: michael@0: StrCmp "$R4" "" +1 +3 michael@0: WriteRegStr SHCTX "$R3\$R5" "" "$R8" michael@0: WriteRegStr SHCTX "$R3\$R5" "FriendlyTypeName" "$R8" michael@0: michael@0: StrCmp "$R9" "true" +1 +2 michael@0: WriteRegStr SHCTX "$R3\$R5" "URL Protocol" "" michael@0: StrCmp "$R9" "delete" +1 +2 michael@0: DeleteRegValue SHCTX "$R3\$R5" "URL Protocol" michael@0: StrCpy $R4 "" michael@0: ReadRegDWord $R4 SHCTX "$R3\$R5" "EditFlags" michael@0: StrCmp $R4 "" +1 +3 ; Only add EditFlags if a value doesn't exist michael@0: DeleteRegValue SHCTX "$R3\$R5" "EditFlags" michael@0: WriteRegDWord SHCTX "$R3\$R5" "EditFlags" 0x00000002 michael@0: michael@0: StrCmp "$R7" "" +2 +1 michael@0: WriteRegStr SHCTX "$R3\$R5\DefaultIcon" "" "$R7" michael@0: michael@0: ; Main command handler for the app michael@0: WriteRegStr SHCTX "$R3\$R5\shell" "" "open" michael@0: WriteRegStr SHCTX "$R3\$R5\shell\open\command" "" "$R6" michael@0: michael@0: ; Drop support for DDE (bug 491947), and remove old dde entries if michael@0: ; they exist. michael@0: ; michael@0: ; Note, changes in SHCTX should propegate to hkey classes root when michael@0: ; current user or local machine entries are written. Windows will also michael@0: ; attempt to propegate entries when a handler is used. CR entries are a michael@0: ; combination of LM and CU, with CU taking priority. michael@0: ; michael@0: ; To disable dde, an empty shell/ddeexec key must be created in current michael@0: ; user or local machine. Unfortunately, settings have various different michael@0: ; behaviors depending on the windows version. The following code attempts michael@0: ; to address these differences. michael@0: ; michael@0: ; On XP (no SP, SP1, SP2), Vista: An empty default string michael@0: ; must be set under ddeexec. Empty strings propagate to CR. michael@0: ; michael@0: ; Win7: IE does not configure ddeexec, so issues with left over ddeexec keys michael@0: ; in LM are reduced. We configure an empty ddeexec key with an empty default michael@0: ; string in CU to be sure. michael@0: ; michael@0: DeleteRegKey SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec" michael@0: WriteRegStr SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec" "" "" michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Exch $R5 michael@0: Exch 4 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_VALOPEN}" michael@0: Push "${_VALICON}" michael@0: Push "${_DISPNAME}" michael@0: Push "${_ISPROTOCOL}" michael@0: Call AddDisabledDDEHandlerValues michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Push "${_VALOPEN}" michael@0: Push "${_VALICON}" michael@0: Push "${_DISPNAME}" michael@0: Push "${_ISPROTOCOL}" michael@0: Call un.AddDisabledDDEHandlerValues michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.AddDisabledDDEHandlerValues michael@0: !ifndef un.AddDisabledDDEHandlerValues michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro AddDisabledDDEHandlerValues michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for handling DLL registration michael@0: michael@0: !macro RegisterDLL DLL michael@0: michael@0: ; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above michael@0: ; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it michael@0: ; when installing on an x64 systems even when installing an x86 application. michael@0: ${If} ${RunningX64} michael@0: ${DisableX64FSRedirection} michael@0: ExecWait '"$SYSDIR\regsvr32.exe" /s "${DLL}"' michael@0: ${EnableX64FSRedirection} michael@0: ${Else} michael@0: RegDLL "${DLL}" michael@0: ${EndIf} michael@0: michael@0: !macroend michael@0: michael@0: !macro UnregisterDLL DLL michael@0: michael@0: ; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above michael@0: ; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it michael@0: ; when installing on an x64 systems even when installing an x86 application. michael@0: ${If} ${RunningX64} michael@0: ${DisableX64FSRedirection} michael@0: ExecWait '"$SYSDIR\regsvr32.exe" /s /u "${DLL}"' michael@0: ${EnableX64FSRedirection} michael@0: ${Else} michael@0: UnRegDLL "${DLL}" michael@0: ${EndIf} michael@0: michael@0: !macroend michael@0: michael@0: !define RegisterDLL `!insertmacro RegisterDLL` michael@0: !define UnregisterDLL `!insertmacro UnregisterDLL` michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for retrieving existing install paths michael@0: michael@0: /** michael@0: * Finds a second installation of the application so we can make informed michael@0: * decisions about registry operations. This uses SHCTX to determine the michael@0: * registry hive so you must call SetShellVarContext first. michael@0: * michael@0: * @param _KEY michael@0: * The registry subkey (typically this will be Software\Mozilla). michael@0: * @return _RESULT michael@0: * false if a second install isn't found, path to the main exe if a michael@0: * second install is found. michael@0: * michael@0: * $R3 = stores the long path to $INSTDIR michael@0: * $R4 = counter for the outer loop's EnumRegKey michael@0: * $R5 = return value from ReadRegStr and RemoveQuotesFromPath michael@0: * $R6 = return value from GetParent michael@0: * $R7 = return value from the loop's EnumRegKey michael@0: * $R8 = storage for _KEY michael@0: * $R9 = _KEY and _RESULT michael@0: */ michael@0: !macro GetSecondInstallPath michael@0: michael@0: !ifndef ${_MOZFUNC_UN}GetSecondInstallPath michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}GetSecondInstallPath "!insertmacro ${_MOZFUNC_UN}GetSecondInstallPathCall" michael@0: michael@0: Function ${_MOZFUNC_UN}GetSecondInstallPath michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R3 michael@0: michael@0: StrCpy $R4 0 ; set the counter for the loop to 0 michael@0: StrCpy $R8 "$R9" ; Registry key path to search michael@0: StrCpy $R9 "false" ; default return value michael@0: michael@0: loop: michael@0: EnumRegKey $R7 SHCTX $R8 $R4 michael@0: StrCmp $R7 "" end +1 ; if empty there are no more keys to enumerate michael@0: IntOp $R4 $R4 + 1 ; increment the loop's counter michael@0: ClearErrors michael@0: ReadRegStr $R5 SHCTX "$R8\$R7\bin" "PathToExe" michael@0: IfErrors loop michael@0: michael@0: ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R5 michael@0: michael@0: IfFileExists "$R5" +1 loop michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${${_MOZFUNC_UN}GetParent} "$R5" $R6 michael@0: StrCmp "$R6" "$R3" loop +1 michael@0: StrCmp "$R6\${FileMainEXE}" "$R5" +1 loop michael@0: StrCpy $R9 "$R5" michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro GetSecondInstallPathCall _KEY _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Call GetSecondInstallPath michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetSecondInstallPathCall _KEY _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Call un.GetSecondInstallPath michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetSecondInstallPath michael@0: !ifndef un.GetSecondInstallPath michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro GetSecondInstallPath michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Finds an existing installation path for the application based on the michael@0: * application's executable name so we can default to using this path for the michael@0: * install. If there is zero or more than one installation of the application michael@0: * then we default to the default installation path. This uses SHCTX to michael@0: * determine the registry hive to read from so you must call SetShellVarContext michael@0: * first. michael@0: * michael@0: * @param _KEY michael@0: * The registry subkey (typically this will be Software\Mozilla\App Name). michael@0: * @return _RESULT michael@0: * false if a single install location for this app name isn't found, michael@0: * path to the install directory if a single install location is found. michael@0: * michael@0: * $R5 = counter for the loop's EnumRegKey michael@0: * $R6 = return value from EnumRegKey michael@0: * $R7 = return value from ReadRegStr michael@0: * $R8 = storage for _KEY michael@0: * $R9 = _KEY and _RESULT michael@0: */ michael@0: !macro GetSingleInstallPath michael@0: michael@0: !ifndef ${_MOZFUNC_UN}GetSingleInstallPath michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}GetSingleInstallPath "!insertmacro ${_MOZFUNC_UN}GetSingleInstallPathCall" michael@0: michael@0: Function ${_MOZFUNC_UN}GetSingleInstallPath michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: StrCpy $R8 $R9 michael@0: StrCpy $R9 "false" michael@0: StrCpy $R5 0 ; set the counter for the loop to 0 michael@0: michael@0: loop: michael@0: ClearErrors michael@0: EnumRegKey $R6 SHCTX $R8 $R5 michael@0: IfErrors cleanup michael@0: StrCmp $R6 "" cleanup +1 ; if empty there are no more keys to enumerate michael@0: IntOp $R5 $R5 + 1 ; increment the loop's counter michael@0: ClearErrors michael@0: ReadRegStr $R7 SHCTX "$R8\$R6\Main" "PathToExe" michael@0: IfErrors loop michael@0: ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R7" $R7 michael@0: GetFullPathName $R7 "$R7" michael@0: IfErrors loop michael@0: michael@0: StrCmp "$R9" "false" +1 +3 michael@0: StrCpy $R9 "$R7" michael@0: GoTo Loop michael@0: michael@0: StrCpy $R9 "false" michael@0: michael@0: cleanup: michael@0: StrCmp $R9 "false" end +1 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 michael@0: ${${_MOZFUNC_UN}GetParent} "$R9" $R9 michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro GetSingleInstallPathCall _KEY _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Call GetSingleInstallPath michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetSingleInstallPathCall _KEY _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Call un.GetSingleInstallPath michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetSingleInstallPath michael@0: !ifndef un.GetSingleInstallPath michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro GetSingleInstallPath michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for working with the file system michael@0: michael@0: /** michael@0: * Attempts to delete a file if it exists. This will fail if the file is in use. michael@0: * michael@0: * @param _FILE michael@0: * The path to the file that is to be deleted. michael@0: */ michael@0: !macro DeleteFile _FILE michael@0: ${If} ${FileExists} "${_FILE}" michael@0: Delete "${_FILE}" michael@0: ${EndIf} michael@0: !macroend michael@0: !define DeleteFile "!insertmacro DeleteFile" michael@0: michael@0: /** michael@0: * Removes a directory if it exists and is empty. michael@0: * michael@0: * @param _DIR michael@0: * The path to the directory that is to be removed. michael@0: */ michael@0: !macro RemoveDir _DIR michael@0: ${If} ${FileExists} "${_DIR}" michael@0: RmDir "${_DIR}" michael@0: ${EndIf} michael@0: !macroend michael@0: !define RemoveDir "!insertmacro RemoveDir" michael@0: michael@0: /** michael@0: * Checks whether it is possible to create and delete a directory and a file in michael@0: * the install directory. Creation and deletion of files and directories are michael@0: * checked since a user may have rights for one and not the other. If creation michael@0: * and deletion of a file and a directory are successful this macro will return michael@0: * true... if not, this it return false. michael@0: * michael@0: * @return _RESULT michael@0: * true if files and directories can be created and deleted in the michael@0: * install directory otherwise false. michael@0: * michael@0: * $R8 = temporary filename in the installation directory returned from michael@0: * GetTempFileName. michael@0: * $R9 = _RESULT michael@0: */ michael@0: !macro CanWriteToInstallDir michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CanWriteToInstallDir michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CanWriteToInstallDir "!insertmacro ${_MOZFUNC_UN}CanWriteToInstallDirCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CanWriteToInstallDir michael@0: Push $R9 michael@0: Push $R8 michael@0: michael@0: StrCpy $R9 "true" michael@0: michael@0: ; IfFileExists returns false for $INSTDIR when $INSTDIR is the root of a michael@0: ; UNC path so always try to create $INSTDIR michael@0: CreateDirectory "$INSTDIR\" michael@0: GetTempFileName $R8 "$INSTDIR\" michael@0: michael@0: ${Unless} ${FileExists} $R8 ; Can files be created? michael@0: StrCpy $R9 "false" michael@0: Goto done michael@0: ${EndUnless} michael@0: michael@0: Delete $R8 michael@0: ${If} ${FileExists} $R8 ; Can files be deleted? michael@0: StrCpy $R9 "false" michael@0: Goto done michael@0: ${EndIf} michael@0: michael@0: CreateDirectory $R8 michael@0: ${Unless} ${FileExists} $R8 ; Can directories be created? michael@0: StrCpy $R9 "false" michael@0: Goto done michael@0: ${EndUnless} michael@0: michael@0: RmDir $R8 michael@0: ${If} ${FileExists} $R8 ; Can directories be deleted? michael@0: StrCpy $R9 "false" michael@0: Goto done michael@0: ${EndIf} michael@0: michael@0: done: michael@0: michael@0: RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty michael@0: ClearErrors michael@0: michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CanWriteToInstallDirCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call CanWriteToInstallDir michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CanWriteToInstallDirCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.CanWriteToInstallDir michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CanWriteToInstallDir michael@0: !ifndef un.CanWriteToInstallDir michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CanWriteToInstallDir michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Checks whether there is sufficient free space available for the installation michael@0: * directory using GetDiskFreeSpaceExW which respects disk quotas. This macro michael@0: * will calculate the size of all sections that are selected, compare that with michael@0: * the free space available, and if there is sufficient free space it will michael@0: * return true... if not, it will return false. michael@0: * michael@0: * @return _RESULT michael@0: * "true" if there is sufficient free space otherwise "false". michael@0: * michael@0: * $R5 = return value from SectionGetSize michael@0: * $R6 = return value from SectionGetFlags michael@0: * return value from an 'and' comparison of SectionGetFlags (1=selected) michael@0: * return value for lpFreeBytesAvailable from GetDiskFreeSpaceExW michael@0: * return value for System::Int64Op $R6 / 1024 michael@0: * return value for System::Int64Op $R6 > $R8 michael@0: * $R7 = the counter for enumerating the sections michael@0: * the temporary file name for the directory created under $INSTDIR passed michael@0: * to GetDiskFreeSpaceExW. michael@0: * $R8 = sum in KB of all selected sections michael@0: * $R9 = _RESULT michael@0: */ michael@0: !macro CheckDiskSpace michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CheckDiskSpace michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CheckDiskSpace "!insertmacro ${_MOZFUNC_UN}CheckDiskSpaceCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CheckDiskSpace michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: ClearErrors michael@0: michael@0: StrCpy $R9 "true" ; default return value michael@0: StrCpy $R8 "0" ; sum in KB of all selected sections michael@0: StrCpy $R7 "0" ; counter for enumerating sections michael@0: michael@0: ; Enumerate the sections and sum up the sizes of the sections that are michael@0: ; selected. michael@0: SectionGetFlags $R7 $R6 michael@0: IfErrors +7 +1 michael@0: IntOp $R6 ${SF_SELECTED} & $R6 michael@0: IntCmp $R6 0 +3 +1 +1 michael@0: SectionGetSize $R7 $R5 michael@0: IntOp $R8 $R8 + $R5 michael@0: IntOp $R7 $R7 + 1 michael@0: GoTo -7 michael@0: michael@0: ; The directory passed to GetDiskFreeSpaceExW must exist for the call to michael@0: ; succeed. Since the CanWriteToInstallDir macro is called prior to this michael@0: ; macro the call to CreateDirectory will always succeed. michael@0: michael@0: ; IfFileExists returns false for $INSTDIR when $INSTDIR is the root of a michael@0: ; UNC path so always try to create $INSTDIR michael@0: CreateDirectory "$INSTDIR\" michael@0: GetTempFileName $R7 "$INSTDIR\" michael@0: Delete "$R7" michael@0: CreateDirectory "$R7" michael@0: michael@0: System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i(R7, .R6, ., .) .' michael@0: michael@0: ; Convert to KB for comparison with $R8 which is in KB michael@0: System::Int64Op $R6 / 1024 michael@0: Pop $R6 michael@0: michael@0: System::Int64Op $R6 > $R8 michael@0: Pop $R6 michael@0: michael@0: IntCmp $R6 1 end +1 +1 michael@0: StrCpy $R9 "false" michael@0: michael@0: end: michael@0: RmDir "$R7" michael@0: RmDir "$INSTDIR\" ; Only remove $INSTDIR if it is empty michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CheckDiskSpaceCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call CheckDiskSpace michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CheckDiskSpaceCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.CheckDiskSpace michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CheckDiskSpace michael@0: !ifndef un.CheckDiskSpace michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CheckDiskSpace michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Returns the path found within a passed in string. The path is quoted or not michael@0: * with the exception of an unquoted non 8dot3 path without arguments that is michael@0: * also not a DefaultIcon path, is a 8dot3 path or not, has command line michael@0: * arguments, or is a registry DefaultIcon path (e.g. ,# where # michael@0: * is the icon's resuorce id). The string does not need to be a valid path or michael@0: * exist. It is up to the caller to pass in a string of one of the forms noted michael@0: * above and to verify existence if necessary. michael@0: * michael@0: * Examples: michael@0: * In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -flag "%1" michael@0: * In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE,0 michael@0: * In: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE michael@0: * In: "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE" michael@0: * In: "C:\PROGRA~1\MOZILL~1\FIREFOX.EXE" -flag "%1" michael@0: * Out: C:\PROGRA~1\MOZILL~1\FIREFOX.EXE michael@0: * michael@0: * In: "C:\Program Files\Mozilla Firefox\firefox.exe" -flag "%1" michael@0: * In: C:\Program Files\Mozilla Firefox\firefox.exe,0 michael@0: * In: "C:\Program Files\Mozilla Firefox\firefox.exe" michael@0: * Out: C:\Program Files\Mozilla Firefox\firefox.exe michael@0: * michael@0: * @param _IN_PATH michael@0: * The string containing the path. michael@0: * @param _OUT_PATH michael@0: * The register to store the path to. michael@0: * michael@0: * $R7 = counter for the outer loop's EnumRegKey michael@0: * $R8 = return value from ReadRegStr michael@0: * $R9 = _IN_PATH and _OUT_PATH michael@0: */ michael@0: !macro GetPathFromString michael@0: michael@0: !ifndef ${_MOZFUNC_UN}GetPathFromString michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}GetPathFromString "!insertmacro ${_MOZFUNC_UN}GetPathFromStringCall" michael@0: michael@0: Function ${_MOZFUNC_UN}GetPathFromString michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: StrCpy $R7 0 ; Set the counter to 0. michael@0: michael@0: ; Handle quoted paths with arguments. michael@0: StrCpy $R8 $R9 1 ; Copy the first char. michael@0: StrCmp $R8 '"' +2 +1 ; Is it a "? michael@0: StrCmp $R8 "'" +1 +9 ; Is it a '? michael@0: StrCpy $R9 $R9 "" 1 ; Remove the first char. michael@0: IntOp $R7 $R7 + 1 ; Increment the counter. michael@0: StrCpy $R8 $R9 1 $R7 ; Starting from the counter copy the next char. michael@0: StrCmp $R8 "" end +1 ; Are there no more chars? michael@0: StrCmp $R8 '"' +2 +1 ; Is it a " char? michael@0: StrCmp $R8 "'" +1 -4 ; Is it a ' char? michael@0: StrCpy $R9 $R9 $R7 ; Copy chars up to the counter. michael@0: GoTo end michael@0: michael@0: ; Handle DefaultIcon paths. DefaultIcon paths are not quoted and end with michael@0: ; a , and a number. michael@0: IntOp $R7 $R7 - 1 ; Decrement the counter. michael@0: StrCpy $R8 $R9 1 $R7 ; Copy one char from the end minus the counter. michael@0: StrCmp $R8 '' +4 +1 ; Are there no more chars? michael@0: StrCmp $R8 ',' +1 -3 ; Is it a , char? michael@0: StrCpy $R9 $R9 $R7 ; Copy chars up to the end minus the counter. michael@0: GoTo end michael@0: michael@0: ; Handle unquoted paths with arguments. An unquoted path with arguments michael@0: ; must be an 8dot3 path. michael@0: StrCpy $R7 -1 ; Set the counter to -1 so it will start at 0. michael@0: IntOp $R7 $R7 + 1 ; Increment the counter. michael@0: StrCpy $R8 $R9 1 $R7 ; Starting from the counter copy the next char. michael@0: StrCmp $R8 "" end +1 ; Are there no more chars? michael@0: StrCmp $R8 " " +1 -3 ; Is it a space char? michael@0: StrCpy $R9 $R9 $R7 ; Copy chars up to the counter. michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro GetPathFromStringCall _IN_PATH _OUT_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_IN_PATH}" michael@0: Call GetPathFromString michael@0: Pop ${_OUT_PATH} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetPathFromStringCall _IN_PATH _OUT_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_IN_PATH}" michael@0: Call un.GetPathFromString michael@0: Pop ${_OUT_PATH} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetPathFromString michael@0: !ifndef un.GetPathFromString michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro GetPathFromString michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Removes the quotes from each end of a string if present. michael@0: * michael@0: * @param _IN_PATH michael@0: * The string containing the path. michael@0: * @param _OUT_PATH michael@0: * The register to store the long path. michael@0: * michael@0: * $R7 = storage for single character comparison michael@0: * $R8 = storage for _IN_PATH michael@0: * $R9 = _IN_PATH and _OUT_PATH michael@0: */ michael@0: !macro RemoveQuotesFromPath michael@0: michael@0: !ifndef ${_MOZFUNC_UN}RemoveQuotesFromPath michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}RemoveQuotesFromPath "!insertmacro ${_MOZFUNC_UN}RemoveQuotesFromPathCall" michael@0: michael@0: Function ${_MOZFUNC_UN}RemoveQuotesFromPath michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: StrCpy $R7 "$R9" 1 michael@0: StrCmp $R7 "$\"" +1 +2 michael@0: StrCpy $R9 "$R9" "" 1 michael@0: michael@0: StrCpy $R7 "$R9" "" -1 michael@0: StrCmp $R7 "$\"" +1 +2 michael@0: StrCpy $R9 "$R9" -1 michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro RemoveQuotesFromPathCall _IN_PATH _OUT_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_IN_PATH}" michael@0: Call RemoveQuotesFromPath michael@0: Pop ${_OUT_PATH} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RemoveQuotesFromPathCall _IN_PATH _OUT_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_IN_PATH}" michael@0: Call un.RemoveQuotesFromPath michael@0: Pop ${_OUT_PATH} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RemoveQuotesFromPath michael@0: !ifndef un.RemoveQuotesFromPath michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro RemoveQuotesFromPath michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Returns the long path for an existing file or directory. GetLongPathNameW michael@0: * may not be available on Win95 if Microsoft Layer for Unicode is not michael@0: * installed and GetFullPathName only returns a long path for the last file or michael@0: * directory that doesn't end with a \ in the path that it is passed. If the michael@0: * path does not exist on the file system this will return an empty string. To michael@0: * provide a consistent result trailing back-slashes are always removed. michael@0: * michael@0: * Note: 1024 used by GetLongPathNameW is the maximum NSIS string length. michael@0: * michael@0: * @param _IN_PATH michael@0: * The string containing the path. michael@0: * @param _OUT_PATH michael@0: * The register to store the long path. michael@0: * michael@0: * $R4 = counter value when the previous \ was found michael@0: * $R5 = directory or file name found during loop michael@0: * $R6 = return value from GetLongPathNameW and loop counter michael@0: * $R7 = long path from GetLongPathNameW and single char from path for comparison michael@0: * $R8 = storage for _IN_PATH michael@0: * $R9 = _IN_PATH _OUT_PATH michael@0: */ michael@0: !macro GetLongPath michael@0: michael@0: !ifndef ${_MOZFUNC_UN}GetLongPath michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}GetLongPath "!insertmacro ${_MOZFUNC_UN}GetLongPathCall" michael@0: michael@0: Function ${_MOZFUNC_UN}GetLongPath michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: michael@0: ClearErrors michael@0: michael@0: GetFullPathName $R8 "$R9" michael@0: IfErrors end_GetLongPath +1 ; If the path doesn't exist return an empty string. michael@0: michael@0: System::Call 'kernel32::GetLongPathNameW(w R8, w .R7, i 1024)i .R6' michael@0: StrCmp "$R7" "" +4 +1 ; Empty string when GetLongPathNameW is not present. michael@0: StrCmp $R6 0 +3 +1 ; Should never equal 0 since the path exists. michael@0: StrCpy $R9 "$R7" michael@0: GoTo end_GetLongPath michael@0: michael@0: ; Do it the hard way. michael@0: StrCpy $R4 0 ; Stores the position in the string of the last \ found. michael@0: StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0. michael@0: michael@0: loop_GetLongPath: michael@0: IntOp $R6 $R6 + 1 ; Increment the counter. michael@0: StrCpy $R7 $R8 1 $R6 ; Starting from the counter copy the next char. michael@0: StrCmp $R7 "" +2 +1 ; Are there no more chars? michael@0: StrCmp $R7 "\" +1 -3 ; Is it a \? michael@0: michael@0: ; Copy chars starting from the previously found \ to the counter. michael@0: StrCpy $R5 $R8 $R6 $R4 michael@0: michael@0: ; If this is the first \ found we want to swap R9 with R5 so a \ will michael@0: ; be appended to the drive letter and colon (e.g. C: will become C:\). michael@0: StrCmp $R4 0 +1 +3 michael@0: StrCpy $R9 $R5 michael@0: StrCpy $R5 "" michael@0: michael@0: GetFullPathName $R9 "$R9\$R5" michael@0: michael@0: StrCmp $R7 "" end_GetLongPath +1 ; Are there no more chars? michael@0: michael@0: ; Store the counter for the current \ and prefix it for StrCpy operations. michael@0: StrCpy $R4 "+$R6" michael@0: IntOp $R6 $R6 + 1 ; Increment the counter so we skip over the \. michael@0: StrCpy $R8 $R8 "" $R6 ; Copy chars starting from the counter to the end. michael@0: StrCpy $R6 -1 ; Reset the counter to -1 so it will start over at 0. michael@0: GoTo loop_GetLongPath michael@0: michael@0: end_GetLongPath: michael@0: ; If there is a trailing slash remove it michael@0: StrCmp $R9 "" +4 +1 michael@0: StrCpy $R8 "$R9" "" -1 michael@0: StrCmp $R8 "\" +1 +2 michael@0: StrCpy $R9 "$R9" -1 michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro GetLongPathCall _IN_PATH _OUT_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_IN_PATH}" michael@0: Call GetLongPath michael@0: Pop ${_OUT_PATH} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetLongPathCall _IN_PATH _OUT_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_IN_PATH}" michael@0: Call un.GetLongPath michael@0: Pop ${_OUT_PATH} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetLongPath michael@0: !ifndef un.GetLongPath michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro GetLongPath michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for cleaning up the registry and file system michael@0: michael@0: /** michael@0: * Removes registry keys that reference this install location and for paths that michael@0: * no longer exist. This uses SHCTX to determine the registry hive so you must michael@0: * call SetShellVarContext first. michael@0: * michael@0: * @param _KEY michael@0: * The registry subkey (typically this will be Software\Mozilla). michael@0: * michael@0: * XXXrstrong - there is the potential for Key: Software/Mozilla/AppName, michael@0: * ValueName: CurrentVersion, ValueData: AppVersion to reference a key that is michael@0: * no longer available due to this cleanup. This should be no worse than prior michael@0: * to this reg cleanup since the referenced key would be for an app that is no michael@0: * longer installed on the system. michael@0: * michael@0: * $R0 = on x64 systems set to 'false' at the beginning of the macro when michael@0: * enumerating the x86 registry view and set to 'true' when enumerating michael@0: * the x64 registry view. michael@0: * $R1 = stores the long path to $INSTDIR michael@0: * $R2 = return value from the stack from the GetParent and GetLongPath macros michael@0: * $R3 = return value from the outer loop's EnumRegKey michael@0: * $R4 = return value from the inner loop's EnumRegKey michael@0: * $R5 = return value from ReadRegStr michael@0: * $R6 = counter for the outer loop's EnumRegKey michael@0: * $R7 = counter for the inner loop's EnumRegKey michael@0: * $R8 = return value from the stack from the RemoveQuotesFromPath macro michael@0: * $R9 = _KEY michael@0: */ michael@0: !macro RegCleanMain michael@0: michael@0: !ifndef ${_MOZFUNC_UN}RegCleanMain michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}RegCleanMain "!insertmacro ${_MOZFUNC_UN}RegCleanMainCall" michael@0: michael@0: Function ${_MOZFUNC_UN}RegCleanMain michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R1 michael@0: StrCpy $R6 0 ; set the counter for the outer loop to 0 michael@0: michael@0: ${If} ${RunningX64} michael@0: StrCpy $R0 "false" michael@0: ; Set the registry to the 32 bit registry for 64 bit installations or to michael@0: ; the 64 bit registry for 32 bit installations at the beginning so it can michael@0: ; easily be set back to the correct registry view when finished. michael@0: !ifdef HAVE_64BIT_OS michael@0: SetRegView 32 michael@0: !else michael@0: SetRegView 64 michael@0: !endif michael@0: ${EndIf} michael@0: michael@0: outerloop: michael@0: EnumRegKey $R3 SHCTX $R9 $R6 michael@0: StrCmp $R3 "" end +1 ; if empty there are no more keys to enumerate michael@0: IntOp $R6 $R6 + 1 ; increment the outer loop's counter michael@0: ClearErrors michael@0: ReadRegStr $R5 SHCTX "$R9\$R3\bin" "PathToExe" michael@0: IfErrors 0 outercontinue michael@0: StrCpy $R7 0 ; set the counter for the inner loop to 0 michael@0: michael@0: innerloop: michael@0: EnumRegKey $R4 SHCTX "$R9\$R3" $R7 michael@0: StrCmp $R4 "" outerloop +1 ; if empty there are no more keys to enumerate michael@0: IntOp $R7 $R7 + 1 ; increment the inner loop's counter michael@0: ClearErrors michael@0: ReadRegStr $R5 SHCTX "$R9\$R3\$R4\Main" "PathToExe" michael@0: IfErrors innerloop michael@0: michael@0: ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R8 michael@0: ${${_MOZFUNC_UN}GetParent} "$R8" $R2 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2 michael@0: IfFileExists "$R2" +1 innerloop michael@0: StrCmp "$R2" "$R1" +1 innerloop michael@0: michael@0: ClearErrors michael@0: DeleteRegKey SHCTX "$R9\$R3\$R4" michael@0: IfErrors innerloop michael@0: IntOp $R7 $R7 - 1 ; decrement the inner loop's counter when the key is deleted successfully. michael@0: ClearErrors michael@0: DeleteRegKey /ifempty SHCTX "$R9\$R3" michael@0: IfErrors innerloop outerdecrement michael@0: michael@0: outercontinue: michael@0: ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R8 michael@0: ${${_MOZFUNC_UN}GetParent} "$R8" $R2 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2 michael@0: IfFileExists "$R2" +1 outerloop michael@0: StrCmp "$R2" "$R1" +1 outerloop michael@0: michael@0: ClearErrors michael@0: DeleteRegKey SHCTX "$R9\$R3" michael@0: IfErrors outerloop michael@0: michael@0: outerdecrement: michael@0: IntOp $R6 $R6 - 1 ; decrement the outer loop's counter when the key is deleted successfully. michael@0: GoTo outerloop michael@0: michael@0: end: michael@0: ${If} ${RunningX64} michael@0: ${AndIf} "$R0" == "false" michael@0: ; Set the registry to the correct view. michael@0: !ifdef HAVE_64BIT_OS michael@0: SetRegView 64 michael@0: !else michael@0: SetRegView 32 michael@0: !endif michael@0: michael@0: StrCpy $R6 0 ; set the counter for the outer loop to 0 michael@0: StrCpy $R0 "true" michael@0: GoTo outerloop michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro RegCleanMainCall _KEY michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Call RegCleanMain michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanMainCall _KEY michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_KEY}" michael@0: Call un.RegCleanMain michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanMain michael@0: !ifndef un.RegCleanMain michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro RegCleanMain michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Removes all registry keys from \Software\Windows\CurrentVersion\Uninstall michael@0: * that reference this install location in both the 32 bit and 64 bit registry michael@0: * view. This macro uses SHCTX to determine the registry hive so you must call michael@0: * SetShellVarContext first. michael@0: * michael@0: * $R3 = on x64 systems set to 'false' at the beginning of the macro when michael@0: * enumerating the x86 registry view and set to 'true' when enumerating michael@0: * the x64 registry view. michael@0: * $R4 = stores the long path to $INSTDIR michael@0: * $R5 = return value from ReadRegStr michael@0: * $R6 = string for the base reg key (e.g. Software\Microsoft\Windows\CurrentVersion\Uninstall) michael@0: * $R7 = return value from EnumRegKey michael@0: * $R8 = counter for EnumRegKey michael@0: * $R9 = return value from the stack from the RemoveQuotesFromPath and GetLongPath macros michael@0: */ michael@0: !macro RegCleanUninstall michael@0: michael@0: !ifndef ${_MOZFUNC_UN}RegCleanUninstall michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}RegCleanUninstall "!insertmacro ${_MOZFUNC_UN}RegCleanUninstallCall" michael@0: michael@0: Function ${_MOZFUNC_UN}RegCleanUninstall michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R4 michael@0: StrCpy $R6 "Software\Microsoft\Windows\CurrentVersion\Uninstall" michael@0: StrCpy $R7 "" michael@0: StrCpy $R8 0 michael@0: michael@0: ${If} ${RunningX64} michael@0: StrCpy $R3 "false" michael@0: ; Set the registry to the 32 bit registry for 64 bit installations or to michael@0: ; the 64 bit registry for 32 bit installations at the beginning so it can michael@0: ; easily be set back to the correct registry view when finished. michael@0: !ifdef HAVE_64BIT_OS michael@0: SetRegView 32 michael@0: !else michael@0: SetRegView 64 michael@0: !endif michael@0: ${EndIf} michael@0: michael@0: loop: michael@0: EnumRegKey $R7 SHCTX $R6 $R8 michael@0: StrCmp $R7 "" end +1 michael@0: IntOp $R8 $R8 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadRegStr $R5 SHCTX "$R6\$R7" "InstallLocation" michael@0: IfErrors loop michael@0: ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R5" $R9 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 michael@0: StrCmp "$R9" "$R4" +1 loop michael@0: ClearErrors michael@0: DeleteRegKey SHCTX "$R6\$R7" michael@0: IfErrors loop +1 michael@0: IntOp $R8 $R8 - 1 ; Decrement the counter on successful deletion michael@0: GoTo loop michael@0: michael@0: end: michael@0: ${If} ${RunningX64} michael@0: ${AndIf} "$R3" == "false" michael@0: ; Set the registry to the correct view. michael@0: !ifdef HAVE_64BIT_OS michael@0: SetRegView 64 michael@0: !else michael@0: SetRegView 32 michael@0: !endif michael@0: michael@0: StrCpy $R7 "" michael@0: StrCpy $R8 0 michael@0: StrCpy $R3 "true" michael@0: GoTo loop michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro RegCleanUninstallCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call RegCleanUninstall michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanUninstallCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.RegCleanUninstall michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanUninstall michael@0: !ifndef un.RegCleanUninstall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro RegCleanUninstall michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Removes an application specific handler registry key under Software\Classes michael@0: * for both HKCU and HKLM when its open command refers to this install michael@0: * location or the install location doesn't exist. michael@0: * michael@0: * @param _HANDLER_NAME michael@0: * The registry name for the handler. michael@0: * michael@0: * $R7 = stores the long path to the $INSTDIR michael@0: * $R8 = stores the path to the open command's parent directory michael@0: * $R9 = _HANDLER_NAME michael@0: */ michael@0: !macro RegCleanAppHandler michael@0: michael@0: !ifndef ${_MOZFUNC_UN}RegCleanAppHandler michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}RegCleanAppHandler "!insertmacro ${_MOZFUNC_UN}RegCleanAppHandlerCall" michael@0: michael@0: Function ${_MOZFUNC_UN}RegCleanAppHandler michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: ClearErrors michael@0: ReadRegStr $R8 HKCU "Software\Classes\$R9\shell\open\command" "" michael@0: IfErrors next +1 michael@0: ${${_MOZFUNC_UN}GetPathFromString} "$R8" $R8 michael@0: ${${_MOZFUNC_UN}GetParent} "$R8" $R8 michael@0: IfFileExists "$R8" +3 +1 michael@0: DeleteRegKey HKCU "Software\Classes\$R9" michael@0: GoTo next michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R8" $R8 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R7 michael@0: StrCmp "$R7" "$R8" +1 next michael@0: DeleteRegKey HKCU "Software\Classes\$R9" michael@0: michael@0: next: michael@0: ReadRegStr $R8 HKLM "Software\Classes\$R9\shell\open\command" "" michael@0: IfErrors end michael@0: ${${_MOZFUNC_UN}GetPathFromString} "$R8" $R8 michael@0: ${${_MOZFUNC_UN}GetParent} "$R8" $R8 michael@0: IfFileExists "$R8" +3 +1 michael@0: DeleteRegKey HKLM "Software\Classes\$R9" michael@0: GoTo end michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R8" $R8 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R7 michael@0: StrCmp "$R7" "$R8" +1 end michael@0: DeleteRegKey HKLM "Software\Classes\$R9" michael@0: michael@0: end: michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro RegCleanAppHandlerCall _HANDLER_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_HANDLER_NAME}" michael@0: Call RegCleanAppHandler michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanAppHandlerCall _HANDLER_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_HANDLER_NAME}" michael@0: Call un.RegCleanAppHandler michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanAppHandler michael@0: !ifndef un.RegCleanAppHandler michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro RegCleanAppHandler michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Cleans up the registry for a protocol handler when its open command michael@0: * refers to this install location. For HKCU the registry key is deleted michael@0: * and for HKLM the values set by the application are deleted. michael@0: * michael@0: * @param _HANDLER_NAME michael@0: * The registry name for the handler. michael@0: * michael@0: * $R7 = stores the long path to $INSTDIR michael@0: * $R8 = stores the the long path to the open command's parent directory michael@0: * $R9 = _HANDLER_NAME michael@0: */ michael@0: !macro un.RegCleanProtocolHandler michael@0: michael@0: !ifndef un.RegCleanProtocolHandler michael@0: !insertmacro un.GetLongPath michael@0: !insertmacro un.GetParent michael@0: !insertmacro un.GetPathFromString michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define un.RegCleanProtocolHandler "!insertmacro un.RegCleanProtocolHandlerCall" michael@0: michael@0: Function un.RegCleanProtocolHandler michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: ReadRegStr $R8 HKCU "Software\Classes\$R9\shell\open\command" "" michael@0: ${un.GetLongPath} "$INSTDIR" $R7 michael@0: michael@0: StrCmp "$R8" "" next +1 michael@0: ${un.GetPathFromString} "$R8" $R8 michael@0: ${un.GetParent} "$R8" $R8 michael@0: ${un.GetLongPath} "$R8" $R8 michael@0: StrCmp "$R7" "$R8" +1 next michael@0: DeleteRegKey HKCU "Software\Classes\$R9" michael@0: michael@0: next: michael@0: ReadRegStr $R8 HKLM "Software\Classes\$R9\shell\open\command" "" michael@0: StrCmp "$R8" "" end +1 michael@0: ${un.GetLongPath} "$INSTDIR" $R7 michael@0: ${un.GetPathFromString} "$R8" $R8 michael@0: ${un.GetParent} "$R8" $R8 michael@0: ${un.GetLongPath} "$R8" $R8 michael@0: StrCmp "$R7" "$R8" +1 end michael@0: DeleteRegValue HKLM "Software\Classes\$R9\DefaultIcon" "" michael@0: DeleteRegValue HKLM "Software\Classes\$R9\shell\open" "" michael@0: DeleteRegValue HKLM "Software\Classes\$R9\shell\open\command" "" michael@0: DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec" "" michael@0: DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Application" "" michael@0: DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Topic" "" michael@0: michael@0: end: michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro un.RegCleanProtocolHandlerCall _HANDLER_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_HANDLER_NAME}" michael@0: Call un.RegCleanProtocolHandler michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Cleans up the registry for a file handler when the passed in value equals michael@0: * the default value for the file handler. For HKCU the registry key is deleted michael@0: * and for HKLM the default value is deleted. michael@0: * michael@0: * @param _HANDLER_NAME michael@0: * The registry name for the handler. michael@0: * @param _DEFAULT_VALUE michael@0: * The value to check for against the handler's default value. michael@0: * michael@0: * $R6 = stores the long path to $INSTDIR michael@0: * $R7 = _DEFAULT_VALUE michael@0: * $R9 = _HANDLER_NAME michael@0: */ michael@0: !macro RegCleanFileHandler michael@0: michael@0: !ifndef ${_MOZFUNC_UN}RegCleanFileHandler michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}RegCleanFileHandler "!insertmacro ${_MOZFUNC_UN}RegCleanFileHandlerCall" michael@0: michael@0: Function ${_MOZFUNC_UN}RegCleanFileHandler michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Push $R7 michael@0: michael@0: ReadRegStr $R7 HKCU "Software\Classes\$R9" "" michael@0: StrCmp "$R7" "$R8" +1 +2 michael@0: DeleteRegKey HKCU "Software\Classes\$R9" michael@0: michael@0: ReadRegStr $R7 HKLM "Software\Classes\$R9" "" michael@0: StrCmp "$R7" "$R8" +1 +2 michael@0: DeleteRegValue HKLM "Software\Classes\$R9" "" michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R7 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro RegCleanFileHandlerCall _HANDLER_NAME _DEFAULT_VALUE michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_DEFAULT_VALUE}" michael@0: Push "${_HANDLER_NAME}" michael@0: Call RegCleanFileHandler michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanFileHandlerCall _HANDLER_NAME _DEFAULT_VALUE michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_DEFAULT_VALUE}" michael@0: Push "${_HANDLER_NAME}" michael@0: Call un.RegCleanFileHandler michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.RegCleanFileHandler michael@0: !ifndef un.RegCleanFileHandler michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro RegCleanFileHandler michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Checks if a handler's open command points to this installation directory. michael@0: * Uses SHCTX to determine the registry hive (e.g. HKLM or HKCU) to check. michael@0: * michael@0: * @param _HANDLER_NAME michael@0: * The registry name for the handler. michael@0: * @param _RESULT michael@0: * true if it is the handler's open command points to this michael@0: * installation directory and false if it does not. michael@0: * michael@0: * $R7 = stores the value of the open command and the path macros return values michael@0: * $R8 = stores the handler's registry key name michael@0: * $R9 = _DEFAULT_VALUE and _RESULT michael@0: */ michael@0: !macro IsHandlerForInstallDir michael@0: michael@0: !ifndef ${_MOZFUNC_UN}IsHandlerForInstallDir michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetPathFromString michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}IsHandlerForInstallDir "!insertmacro ${_MOZFUNC_UN}IsHandlerForInstallDirCall" michael@0: michael@0: Function ${_MOZFUNC_UN}IsHandlerForInstallDir michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: StrCpy $R8 "$R9" michael@0: StrCpy $R9 "false" michael@0: ReadRegStr $R7 SHCTX "Software\Classes\$R8\shell\open\command" "" michael@0: michael@0: ${If} $R7 != "" michael@0: ${GetPathFromString} "$R7" $R7 michael@0: ${GetParent} "$R7" $R7 michael@0: ${GetLongPath} "$R7" $R7 michael@0: ${If} $R7 == $INSTDIR michael@0: StrCpy $R9 "true" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro IsHandlerForInstallDirCall _HANDLER_NAME _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_HANDLER_NAME}" michael@0: Call IsHandlerForInstallDir michael@0: Pop "${_RESULT}" michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.IsHandlerForInstallDirCall _HANDLER_NAME _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_HANDLER_NAME}" michael@0: Call un.IsHandlerForInstallDir michael@0: Pop "${_RESULT}" michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.IsHandlerForInstallDir michael@0: !ifndef un.IsHandlerForInstallDir michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro IsHandlerForInstallDir michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Removes the application's VirtualStore directory if present when the michael@0: * installation directory is a sub-directory of the program files directory. michael@0: * michael@0: * $R4 = $PROGRAMFILES/$PROGRAMFILES64 for CleanVirtualStore_Internal michael@0: * $R5 = various path values. michael@0: * $R6 = length of the long path to $PROGRAMFILES32 or $PROGRAMFILES64 michael@0: * $R7 = long path to $PROGRAMFILES32 or $PROGRAMFILES64 michael@0: * $R8 = length of the long path to $INSTDIR michael@0: * $R9 = long path to $INSTDIR michael@0: */ michael@0: !macro CleanVirtualStore michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CleanVirtualStore michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CleanVirtualStore "!insertmacro ${_MOZFUNC_UN}CleanVirtualStoreCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CleanVirtualStore michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R9 michael@0: ${If} "$R9" != "" michael@0: StrLen $R8 "$R9" michael@0: michael@0: StrCpy $R4 $PROGRAMFILES32 michael@0: Call ${_MOZFUNC_UN}CleanVirtualStore_Internal michael@0: michael@0: ${If} ${RunningX64} michael@0: StrCpy $R4 $PROGRAMFILES64 michael@0: Call ${_MOZFUNC_UN}CleanVirtualStore_Internal michael@0: ${EndIf} michael@0: michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: Function ${_MOZFUNC_UN}CleanVirtualStore_Internal michael@0: ${${_MOZFUNC_UN}GetLongPath} "" $R7 michael@0: ${If} "$R7" != "" michael@0: StrLen $R6 "$R7" michael@0: ${If} $R8 < $R6 michael@0: ; Copy from the start of $INSTDIR the length of $PROGRAMFILES64 michael@0: StrCpy $R5 "$R9" $R6 michael@0: ${If} "$R5" == "$R7" michael@0: ; Remove the drive letter and colon from the $INSTDIR long path michael@0: StrCpy $R5 "$R9" "" 2 michael@0: StrCpy $R5 "$LOCALAPPDATA\VirtualStore$R5" michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$R5" != "" michael@0: ${AndIf} ${FileExists} "$R5" michael@0: RmDir /r "$R5" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CleanVirtualStoreCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call CleanVirtualStore michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CleanVirtualStoreCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.CleanVirtualStore michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CleanVirtualStore michael@0: !ifndef un.CleanVirtualStore michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CleanVirtualStore michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * If present removes the updates directory located in the profile's local michael@0: * directory for this installation. michael@0: * This macro is obsolete and should no longer be used. Please see michael@0: * CleanUpdateDirectories. michael@0: * michael@0: * @param _REL_PROFILE_PATH michael@0: * The relative path to the profile directory from $LOCALAPPDATA. michael@0: * michael@0: * $R4 = various path values. michael@0: * $R5 = length of the long path to $PROGRAMFILES michael@0: * $R6 = length of the long path to $INSTDIR michael@0: * $R7 = long path to $PROGRAMFILES michael@0: * $R8 = long path to $INSTDIR michael@0: * $R9 = _REL_PROFILE_PATH michael@0: */ michael@0: !macro CleanUpdatesDir michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CleanUpdatesDir michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CleanUpdatesDir "!insertmacro ${_MOZFUNC_UN}CleanUpdatesDirCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CleanUpdatesDir michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: michael@0: StrCmp $R9 "" end +1 ; The relative path to the app's profiles is required michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R8 michael@0: StrCmp $R8 "" end +1 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R7 michael@0: StrCmp $R7 "" end +1 michael@0: michael@0: StrLen $R6 "$R8" michael@0: StrLen $R5 "$R7" michael@0: ; Only continue If the length of $INSTDIR is greater than the length of michael@0: ; $PROGRAMFILES michael@0: IntCmp $R6 $R5 end end +1 michael@0: michael@0: ; Copy from the start of $INSTDIR the length of $PROGRAMFILES michael@0: StrCpy $R4 "$R8" $R5 michael@0: StrCmp "$R4" "$R7" +1 end ; Check if $INSTDIR is under $PROGRAMFILES michael@0: michael@0: ; Copy the relative path to $INSTDIR from $PROGRAMFILES michael@0: StrCpy $R4 "$R8" "" $R5 michael@0: michael@0: ; Concatenate the path to $LOCALAPPDATA the relative profile path and the michael@0: ; relative path to $INSTDIR from $PROGRAMFILES michael@0: StrCpy $R4 "$LOCALAPPDATA\$R9$R4" michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R4" $R4 michael@0: StrCmp $R4 "" end +1 michael@0: michael@0: IfFileExists "$R4\updates" +1 end michael@0: RmDir /r "$R4" michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CleanUpdatesDirCall _REL_PROFILE_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_REL_PROFILE_PATH}" michael@0: Call CleanUpdatesDir michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CleanUpdatesDirCall _REL_PROFILE_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_REL_PROFILE_PATH}" michael@0: Call un.CleanUpdatesDir michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CleanUpdatesDir michael@0: !ifndef un.CleanUpdatesDir michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CleanUpdatesDir michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * If present removes the updates directory located in the profile's local michael@0: * directory for this installation. michael@0: * michael@0: * @param _OLD_REL_PATH michael@0: * The relative path to the profile directory from $LOCALAPPDATA. michael@0: * Calculated for the old update directory not based on a hash. michael@0: * @param _NEW_REL_PATH michael@0: * The relative path to the profile directory from $LOCALAPPDATA. michael@0: * Calculated for the new update directory based on a hash. michael@0: * michael@0: * $R8 = _NEW_REL_PATH michael@0: * $R7 = _OLD_REL_PATH michael@0: * $R1 = taskBar ID hash located in registry at SOFTWARE\_OLD_REL_PATH\TaskBarIDs michael@0: * $R2 = various path values. michael@0: * $R3 = length of the long path to $PROGRAMFILES michael@0: * $R4 = length of the long path to $INSTDIR michael@0: * $R5 = long path to $PROGRAMFILES michael@0: * $R6 = long path to $INSTDIR michael@0: * $R0 = path to the new update directory built from _NEW_REL_PATH and michael@0: * the taskbar ID. michael@0: */ michael@0: !macro CleanUpdateDirectories michael@0: michael@0: !ifndef ${_MOZFUNC_UN}CleanUpdateDirectories michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}CleanUpdateDirectories "!insertmacro ${_MOZFUNC_UN}CleanUpdateDirectoriesCall" michael@0: michael@0: Function ${_MOZFUNC_UN}CleanUpdateDirectories michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR" $R6 michael@0: StrLen $R4 "$R6" michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$PROGRAMFILES" $R5 michael@0: StrLen $R3 "$R5" michael@0: michael@0: ${If} $R7 != "" ; _OLD_REL_PATH was passed michael@0: ${AndIf} $R6 != "" ; We have the install dir path michael@0: ${AndIf} $R5 != "" ; We the program files path michael@0: ${AndIf} $R4 > $R3 ; The length of $INSTDIR > the length of $PROGRAMFILES michael@0: michael@0: ; Copy from the start of $INSTDIR the length of $PROGRAMFILES michael@0: StrCpy $R2 "$R6" $R3 michael@0: michael@0: ; Check if $INSTDIR is under $PROGRAMFILES michael@0: ${If} $R2 == $R5 michael@0: michael@0: ; Copy the relative path to $INSTDIR from $PROGRAMFILES michael@0: StrCpy $R2 "$R6" "" $R3 michael@0: michael@0: ; Concatenate the path $LOCALAPPDATA to the relative profile path and michael@0: ; the relative path to $INSTDIR from $PROGRAMFILES michael@0: StrCpy $R2 "$LOCALAPPDATA\$R7$R2" michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R2" $R2 michael@0: michael@0: ${If} $R2 != "" michael@0: ; Backup the old update directory logs and delete the directory michael@0: ${If} ${FileExists} "$R2\updates\last-update.log" michael@0: Rename "$R2\updates\last-update.log" "$TEMP\moz-update-old-last-update.log" michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$R2\updates\backup-update.log" michael@0: Rename "$R2\updates\backup-update.log" "$TEMP\moz-update-old-backup-update.log" michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$R2\updates" michael@0: RmDir /r "$R2" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ; Get the taskbar ID hash for this installation path michael@0: ReadRegStr $R1 HKLM "SOFTWARE\$R7\TaskBarIDs" $R6 michael@0: ${If} $R1 == "" michael@0: ReadRegStr $R1 HKCU "SOFTWARE\$R7\TaskBarIDs" $R6 michael@0: ${EndIf} michael@0: michael@0: ; If the taskbar ID hash exists then delete the new update directory michael@0: ; Backup its logs before deleting it. michael@0: ${If} $R1 != "" michael@0: StrCpy $R0 "$LOCALAPPDATA\$R8\$R1" michael@0: michael@0: ${If} ${FileExists} "$R0\updates\last-update.log" michael@0: Rename "$R0\updates\last-update.log" "$TEMP\moz-update-new-last-update.log" michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$R0\updates\backup-update.log" michael@0: Rename "$R0\updates\backup-update.log" "$TEMP\moz-update-new-backup-update.log" michael@0: ${EndIf} michael@0: michael@0: ; Remove the old updates directory michael@0: ${If} ${FileExists} "$R0\updates" michael@0: RmDir /r "$R0" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Exch $R7 michael@0: Exch 1 michael@0: Exch $R8 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_OLD_REL_PATH}" michael@0: Push "${_NEW_REL_PATH}" michael@0: Call CleanUpdateDirectories michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CleanUpdateDirectoriesCall _OLD_REL_PATH _NEW_REL_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_OLD_REL_PATH}" michael@0: Push "${_NEW_REL_PATH}" michael@0: Call un.CleanUpdateDirectories michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.CleanUpdateDirectories michael@0: !ifndef un.CleanUpdateDirectories michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro CleanUpdateDirectories michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Deletes all relative profiles specified in an application's profiles.ini and michael@0: * performs various other cleanup. michael@0: * michael@0: * @param _REL_PROFILE_PATH michael@0: * The relative path to the profile directory. michael@0: * michael@0: * $R6 = value of IsRelative read from profiles.ini michael@0: * $R7 = value of Path to profile read from profiles.ini michael@0: * $R8 = counter for reading profiles (e.g. Profile0, Profile1, etc.) michael@0: * $R9 = _REL_PROFILE_PATH michael@0: */ michael@0: !macro DeleteRelativeProfiles michael@0: michael@0: !ifndef ${_MOZFUNC_UN}DeleteRelativeProfiles michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}WordReplace michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}DeleteRelativeProfiles "!insertmacro ${_MOZFUNC_UN}DeleteRelativeProfilesCall" michael@0: michael@0: Function ${_MOZFUNC_UN}DeleteRelativeProfiles michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: michael@0: SetShellVarContext current michael@0: StrCpy $R8 -1 michael@0: michael@0: loop: michael@0: IntOp $R8 $R8 + 1 ; Increment the counter. michael@0: ReadINIStr $R7 "$APPDATA\$R9\profiles.ini" "Profile$R8" "Path" michael@0: IfErrors end +1 michael@0: michael@0: ; Only remove relative profiles michael@0: ReadINIStr $R6 "$APPDATA\$R9\profiles.ini" "Profile$R8" "IsRelative" michael@0: StrCmp "$R6" "1" +1 loop michael@0: michael@0: ; Relative paths in profiles.ini use / as a separator michael@0: ${${_MOZFUNC_UN}WordReplace} "$R7" "/" "\" "+" $R7 michael@0: michael@0: IfFileExists "$LOCALAPPDATA\$R9\$R7" +1 +2 michael@0: RmDir /r "$LOCALAPPDATA\$R9\$R7" michael@0: IfFileExists "$APPDATA\$R9\$R7" +1 +2 michael@0: RmDir /r "$APPDATA\$R9\$R7" michael@0: GoTo loop michael@0: michael@0: end: michael@0: ; Remove profiles directory under LOCALAPPDATA (e.g. cache, etc.) since michael@0: ; they are at times abandoned. michael@0: RmDir /r "$LOCALAPPDATA\$R9\Profiles" michael@0: RmDir /r "$APPDATA\$R9\Crash Reports" michael@0: Delete "$APPDATA\$R9\profiles.ini" michael@0: Delete "$APPDATA\$R9\console.log" michael@0: Delete "$APPDATA\$R9\pluginreg.dat" michael@0: RmDir "$APPDATA\$R9\Profiles" michael@0: RmDir "$APPDATA\$R9" michael@0: michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro DeleteRelativeProfilesCall _REL_PROFILE_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_REL_PROFILE_PATH}" michael@0: Call DeleteRelativeProfiles michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.DeleteRelativeProfilesCall _REL_PROFILE_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_REL_PROFILE_PATH}" michael@0: Call un.DeleteRelativeProfiles michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.DeleteRelativeProfiles michael@0: !ifndef un.DeleteRelativeProfiles michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro DeleteRelativeProfiles michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Deletes shortcuts and Start Menu directories under Programs as specified by michael@0: * the shortcuts log ini file and on Windows 7 unpins TaskBar and Start Menu michael@0: * shortcuts. The shortcuts will not be deleted if the shortcut target isn't for michael@0: * this install location which is determined by the shortcut having a target of michael@0: * $INSTDIR\${FileMainEXE}. The context (All Users or Current User) of the michael@0: * $DESKTOP and $SMPROGRAMS constants depends on the michael@0: * SetShellVarContext setting and must be set by the caller of this macro. There michael@0: * is no All Users context for $QUICKLAUNCH but this will not cause a problem michael@0: * since the macro will just continue past the $QUICKLAUNCH shortcut deletion michael@0: * section on subsequent calls. michael@0: * michael@0: * The ini file sections must have the following format (the order of the michael@0: * sections in the ini file is not important): michael@0: * [SMPROGRAMS] michael@0: * ; RelativePath is the directory relative from the Start Menu michael@0: * ; Programs directory. michael@0: * RelativePath=Mozilla App michael@0: * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so michael@0: * ; on. There must not be a break in the sequence of the numbers. michael@0: * Shortcut1=Mozilla App.lnk michael@0: * Shortcut2=Mozilla App (Safe Mode).lnk michael@0: * [DESKTOP] michael@0: * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so michael@0: * ; on. There must not be a break in the sequence of the numbers. michael@0: * Shortcut1=Mozilla App.lnk michael@0: * Shortcut2=Mozilla App (Safe Mode).lnk michael@0: * [QUICKLAUNCH] michael@0: * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so michael@0: * ; on. There must not be a break in the sequence of the numbers for the michael@0: * ; suffix. michael@0: * Shortcut1=Mozilla App.lnk michael@0: * Shortcut2=Mozilla App (Safe Mode).lnk michael@0: * [STARTMENU] michael@0: * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so michael@0: * ; on. There must not be a break in the sequence of the numbers for the michael@0: * ; suffix. michael@0: * Shortcut1=Mozilla App.lnk michael@0: * Shortcut2=Mozilla App (Safe Mode).lnk michael@0: * michael@0: * $R4 = counter for appending to Shortcut for enumerating the ini file entries michael@0: * $R5 = return value from ShellLink::GetShortCutTarget and michael@0: * ApplicationID::UninstallPinnedItem michael@0: * $R6 = find handle and the long path to the Start Menu Programs directory michael@0: * (e.g. $SMPROGRAMS) michael@0: * $R7 = path to the $QUICKLAUNCH\User Pinned directory and the return value michael@0: * from ReadINIStr for the relative path to the applications directory michael@0: * under the Start Menu Programs directory and the long path to this michael@0: * directory michael@0: * $R8 = return filename from FindFirst / FindNext and the return value from michael@0: * ReadINIStr for enumerating shortcuts michael@0: * $R9 = long path to the shortcuts log ini file michael@0: */ michael@0: !macro DeleteShortcuts michael@0: michael@0: !ifndef ${_MOZFUNC_UN}DeleteShortcuts michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParent michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}DeleteShortcuts "!insertmacro ${_MOZFUNC_UN}DeleteShortcutsCall" michael@0: michael@0: Function ${_MOZFUNC_UN}DeleteShortcuts michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ; Since shortcuts that are pinned can later be removed without removing michael@0: ; the pinned shortcut unpin the pinned shortcuts for the application's michael@0: ; main exe using the pinned shortcuts themselves. michael@0: StrCpy $R7 "$QUICKLAUNCH\User Pinned" michael@0: michael@0: ${If} ${FileExists} "$R7\TaskBar" michael@0: ; Delete TaskBar pinned shortcuts for the application's main exe michael@0: FindFirst $R6 $R8 "$R7\TaskBar\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$R7\TaskBar\$R8" michael@0: ShellLink::GetShortCutTarget "$R7\TaskBar\$R8" michael@0: Pop $R5 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$R5" == "$INSTDIR\${FileMainEXE}" michael@0: ApplicationID::UninstallPinnedItem "$R7\TaskBar\$R8" michael@0: Pop $R5 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R6 $R8 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R6 michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$R7\StartMenu" michael@0: ; Delete Start Menu pinned shortcuts for the application's main exe michael@0: FindFirst $R6 $R8 "$R7\StartMenu\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$R7\StartMenu\$R8" michael@0: ShellLink::GetShortCutTarget "$R7\StartMenu\$R8" michael@0: Pop $R5 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$R5" == "$INSTDIR\${FileMainEXE}" michael@0: ApplicationID::UninstallPinnedItem "$R7\StartMenu\$R8" michael@0: Pop $R5 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R6 $R8 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R6 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ; Don't call ApplicationID::UninstallPinnedItem since pinned items for michael@0: ; this application were removed above and removing them below will remove michael@0: ; the association of side by side installations. michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9 michael@0: ${If} ${FileExists} "$R9" michael@0: ; Delete Start Menu shortcuts for this application michael@0: StrCpy $R4 -1 michael@0: ${Do} michael@0: IntOp $R4 $R4 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$SMPROGRAMS\$R8" michael@0: ShellLink::GetShortCutTarget "$SMPROGRAMS\$R8" michael@0: Pop $R5 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$INSTDIR\${FileMainEXE}" == "$R5" michael@0: Delete "$SMPROGRAMS\$R8" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ; Delete Quick Launch shortcuts for this application michael@0: StrCpy $R4 -1 michael@0: ${Do} michael@0: IntOp $R4 $R4 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$QUICKLAUNCH\$R8" michael@0: ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8" michael@0: Pop $R5 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$INSTDIR\${FileMainEXE}" == "$R5" michael@0: Delete "$QUICKLAUNCH\$R8" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ; Delete Desktop shortcuts for this application michael@0: StrCpy $R4 -1 michael@0: ${Do} michael@0: IntOp $R4 $R4 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$DESKTOP\$R8" michael@0: ShellLink::GetShortCutTarget "$DESKTOP\$R8" michael@0: Pop $R5 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$INSTDIR\${FileMainEXE}" == "$R5" michael@0: Delete "$DESKTOP\$R8" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6 michael@0: michael@0: ; Delete Start Menu Programs shortcuts for this application michael@0: ClearErrors michael@0: ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir" michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7 michael@0: ${Unless} "$R7" == "" michael@0: StrCpy $R4 -1 michael@0: ${Do} michael@0: IntOp $R4 $R4 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$R7\$R8" michael@0: ShellLink::GetShortCutTarget "$R7\$R8" michael@0: Pop $R5 michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 michael@0: ${If} "$INSTDIR\${FileMainEXE}" == "$R5" michael@0: Delete "$R7\$R8" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ; Delete Start Menu Programs directories for this application michael@0: ${Do} michael@0: ClearErrors michael@0: ${If} "$R6" == "$R7" michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: RmDir "$R7" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${${_MOZFUNC_UN}GetParent} "$R7" $R7 michael@0: ${Loop} michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro DeleteShortcutsCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call DeleteShortcuts michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.DeleteShortcutsCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.DeleteShortcuts michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.DeleteShortcuts michael@0: !ifndef un.DeleteShortcuts michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro DeleteShortcuts michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for parsing and updating the uninstall.log michael@0: michael@0: /** michael@0: * Updates the uninstall.log with new files added by software update. michael@0: * michael@0: * When modifying this macro be aware that LineFind uses all registers except michael@0: * $R0-$R3 and TextCompareNoDetails uses all registers except $R0-$R9 so be michael@0: * cautious. Callers of this macro are not affected. michael@0: */ michael@0: !macro UpdateUninstallLog michael@0: michael@0: !ifndef UpdateUninstallLog michael@0: !insertmacro FileJoin michael@0: !insertmacro LineFind michael@0: !insertmacro TextCompareNoDetails michael@0: !insertmacro TrimNewLines michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define UpdateUninstallLog "!insertmacro UpdateUninstallLogCall" michael@0: michael@0: Function UpdateUninstallLog michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: michael@0: ClearErrors michael@0: michael@0: GetFullPathName $R3 "$INSTDIR\uninstall" michael@0: ${If} ${FileExists} "$R3\uninstall.update" michael@0: ${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog" michael@0: michael@0: GetTempFileName $R2 "$R3" michael@0: FileOpen $R1 "$R2" w michael@0: ${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff" michael@0: FileClose $R1 michael@0: michael@0: IfErrors +2 0 michael@0: ${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log" michael@0: michael@0: ${DeleteFile} "$R2" michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: FunctionEnd michael@0: michael@0: ; This callback MUST use labels vs. relative line numbers. michael@0: Function CleanupUpdateLog michael@0: StrCpy $R2 "$R9" 12 michael@0: StrCmp "$R2" "EXECUTE ADD " +1 skip michael@0: StrCpy $R9 "$R9" "" 12 michael@0: michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: StrCpy $R4 "" ; Initialize to an empty string. michael@0: StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0. michael@0: michael@0: loop: michael@0: IntOp $R6 $R6 + 1 ; Increment the counter. michael@0: StrCpy $R5 $R9 1 $R6 ; Starting from the counter copy the next char. michael@0: StrCmp $R5 "" copy ; Are there no more chars? michael@0: StrCmp $R5 "/" +1 +2 ; Is the char a /? michael@0: StrCpy $R5 "\" ; Replace the char with a \. michael@0: michael@0: StrCpy $R4 "$R4$R5" michael@0: GoTo loop michael@0: michael@0: copy: michael@0: StrCpy $R9 "File: \$R4" michael@0: Pop $R6 michael@0: Pop $R5 michael@0: Pop $R4 michael@0: GoTo end michael@0: michael@0: skip: michael@0: StrCpy $0 "SkipWrite" michael@0: michael@0: end: michael@0: Push $0 michael@0: FunctionEnd michael@0: michael@0: Function CreateUpdateDiff michael@0: ${TrimNewLines} "$9" $9 michael@0: ${If} $9 != "" michael@0: FileWrite $R1 "$9$\r$\n" michael@0: ${EndIf} michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro UpdateUninstallLogCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call UpdateUninstallLog michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Copies files from a source directory to a destination directory with logging michael@0: * to the uninstall.log. If any destination files are in use a reboot will be michael@0: * necessary to complete the installation and the reboot flag (see IfRebootFlag michael@0: * in the NSIS documentation). michael@0: * michael@0: * @param _PATH_TO_SOURCE michael@0: * Source path to copy the files from. This must not end with a \. michael@0: * michael@0: * @param _PATH_TO_DESTINATION michael@0: * Destination path to copy the files to. This must not end with a \. michael@0: * michael@0: * @param _PREFIX_ERROR_CREATEDIR michael@0: * Prefix for the directory creation error message. The directory path michael@0: * will be inserted below this string. michael@0: * michael@0: * @param _SUFFIX_ERROR_CREATEDIR michael@0: * Suffix for the directory creation error message. The directory path michael@0: * will be inserted above this string. michael@0: * michael@0: * $0 = destination file's parent directory used in the create_dir label michael@0: * $R0 = copied value from $R6 (e.g. _PATH_TO_SOURCE) michael@0: * $R1 = copied value from $R7 (e.g. _PATH_TO_DESTINATION) michael@0: * $R2 = string length of the path to source michael@0: * $R3 = relative path from the path to source michael@0: * $R4 = copied value from $R8 (e.g. _PREFIX_ERROR_CREATEDIR) michael@0: * $R5 = copied value from $R9 (e.g. _SUFFIX_ERROR_CREATEDIR) michael@0: * note: the LocateNoDetails macro uses these registers so we copy the values michael@0: * to other registers. michael@0: * $R6 = initially _PATH_TO_SOURCE and then set to "size" ($R6="" if directory, michael@0: * $R6="0" if file with /S=)"path\name" in callback michael@0: * $R7 = initially _PATH_TO_DESTINATION and then set to "name" in callback michael@0: * $R8 = initially _PREFIX_ERROR_CREATEDIR and then set to "path" in callback michael@0: * $R9 = initially _SUFFIX_ERROR_CREATEDIR and then set to "path\name" in michael@0: * callback michael@0: */ michael@0: !macro CopyFilesFromDir michael@0: michael@0: !ifndef CopyFilesFromDir michael@0: !insertmacro LocateNoDetails michael@0: !insertmacro OnEndCommon michael@0: !insertmacro WordReplace michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define CopyFilesFromDir "!insertmacro CopyFilesFromDirCall" michael@0: michael@0: Function CopyFilesFromDir michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: Push $0 michael@0: michael@0: StrCpy $R0 "$R6" michael@0: StrCpy $R1 "$R7" michael@0: StrCpy $R4 "$R8" michael@0: StrCpy $R5 "$R9" michael@0: michael@0: StrLen $R2 "$R0" michael@0: michael@0: ${LocateNoDetails} "$R0" "/L=FD" "CopyFileCallback" michael@0: michael@0: Pop $0 michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: Function CopyFileCallback michael@0: StrCpy $R3 $R8 "" $R2 ; $R3 always begins with a \. michael@0: michael@0: retry: michael@0: ClearErrors michael@0: StrCmp $R6 "" +1 copy_file michael@0: IfFileExists "$R1$R3\$R7" end +1 michael@0: StrCpy $0 "$R1$R3\$R7" michael@0: michael@0: create_dir: michael@0: ClearErrors michael@0: CreateDirectory "$0" michael@0: IfFileExists "$0" +1 err_create_dir ; protect against looping. michael@0: ${LogMsg} "Created Directory: $0" michael@0: StrCmp $R6 "" end copy_file michael@0: michael@0: err_create_dir: michael@0: ${LogMsg} "** ERROR Creating Directory: $0 **" michael@0: MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$R4$\r$\n$\r$\n$0$\r$\n$\r$\n$R5" IDRETRY retry michael@0: ${OnEndCommon} michael@0: Quit michael@0: michael@0: copy_file: michael@0: StrCpy $0 "$R1$R3" michael@0: StrCmp "$0" "$INSTDIR" +2 +1 michael@0: IfFileExists "$0" +1 create_dir michael@0: michael@0: ClearErrors michael@0: ${DeleteFile} "$R1$R3\$R7" michael@0: IfErrors +1 dest_clear michael@0: ClearErrors michael@0: Rename "$R1$R3\$R7" "$R1$R3\$R7.moz-delete" michael@0: IfErrors +1 reboot_delete michael@0: michael@0: ; file will replace destination file on reboot michael@0: Rename "$R9" "$R9.moz-upgrade" michael@0: CopyFiles /SILENT "$R9.moz-upgrade" "$R1$R3" michael@0: Rename /REBOOTOK "$R1$R3\$R7.moz-upgrade" "$R1$R3\$R7" michael@0: ${LogMsg} "Copied File: $R1$R3\$R7.moz-upgrade" michael@0: ${LogMsg} "Delayed Install File (Reboot Required): $R1$R3\$R7" michael@0: GoTo log_uninstall michael@0: michael@0: ; file will be deleted on reboot michael@0: reboot_delete: michael@0: CopyFiles /SILENT $R9 "$R1$R3" michael@0: Delete /REBOOTOK "$R1$R3\$R7.moz-delete" michael@0: ${LogMsg} "Installed File: $R1$R3\$R7" michael@0: ${LogMsg} "Delayed Delete File (Reboot Required): $R1$R3\$R7.moz-delete" michael@0: GoTo log_uninstall michael@0: michael@0: ; destination file doesn't exist - coast is clear michael@0: dest_clear: michael@0: CopyFiles /SILENT $R9 "$R1$R3" michael@0: ${LogMsg} "Installed File: $R1$R3\$R7" michael@0: michael@0: log_uninstall: michael@0: ; If the file is installed into the installation directory remove the michael@0: ; installation directory's path from the file path when writing to the michael@0: ; uninstall.log so it will be a relative path. This allows the same michael@0: ; helper.exe to be used with zip builds if we supply an uninstall.log. michael@0: ${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3 michael@0: ${LogUninstall} "File: $R3" michael@0: michael@0: end: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CopyFilesFromDirCall _PATH_TO_SOURCE _PATH_TO_DESTINATION \ michael@0: _PREFIX_ERROR_CREATEDIR _SUFFIX_ERROR_CREATEDIR michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_PATH_TO_SOURCE}" michael@0: Push "${_PATH_TO_DESTINATION}" michael@0: Push "${_PREFIX_ERROR_CREATEDIR}" michael@0: Push "${_SUFFIX_ERROR_CREATEDIR}" michael@0: Call CopyFilesFromDir michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Parses the uninstall.log on install to first remove a previous installation's michael@0: * files and then their directories if empty prior to installing. michael@0: * michael@0: * When modifying this macro be aware that LineFind uses all registers except michael@0: * $R0-$R3 so be cautious. Callers of this macro are not affected. michael@0: */ michael@0: !macro OnInstallUninstall michael@0: michael@0: !ifndef OnInstallUninstall michael@0: !insertmacro GetParent michael@0: !insertmacro LineFind michael@0: !insertmacro TrimNewLines michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define OnInstallUninstall "!insertmacro OnInstallUninstallCall" michael@0: michael@0: Function OnInstallUninstall michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: Push $TmpVal michael@0: michael@0: IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end michael@0: michael@0: ${LogHeader} "Removing Previous Installation" michael@0: michael@0: ; Copy the uninstall log file to a temporary file michael@0: GetTempFileName $TmpVal michael@0: CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" michael@0: michael@0: ; Delete files michael@0: ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveFilesCallback" michael@0: michael@0: ; Remove empty directories michael@0: ${LineFind} "$TmpVal" "/NUL" "1:-1" "RemoveDirsCallback" michael@0: michael@0: ; Delete the temporary uninstall log file michael@0: Delete /REBOOTOK "$TmpVal" michael@0: michael@0: ; Delete the uninstall log file michael@0: Delete "$INSTDIR\uninstall\uninstall.log" michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Pop $TmpVal michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: Function RemoveFilesCallback michael@0: ${TrimNewLines} "$R9" $R9 michael@0: StrCpy $R1 "$R9" 5 ; Copy the first five chars michael@0: michael@0: StrCmp "$R1" "File:" +1 end michael@0: StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char michael@0: StrCpy $R0 "$R9" 1 ; Copy the first char michael@0: michael@0: StrCmp "$R0" "\" +1 end ; If this isn't a relative path goto end michael@0: StrCmp "$R9" "\install.log" end +1 ; Skip the install.log michael@0: StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll michael@0: StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll michael@0: michael@0: StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string michael@0: IfFileExists "$R1" +1 end michael@0: michael@0: ClearErrors michael@0: Delete "$R1" michael@0: ${Unless} ${Errors} michael@0: ${LogMsg} "Deleted File: $R1" michael@0: Goto end michael@0: ${EndUnless} michael@0: michael@0: ClearErrors michael@0: Rename "$R1" "$R1.moz-delete" michael@0: ${Unless} ${Errors} michael@0: Delete /REBOOTOK "$R1.moz-delete" michael@0: ${LogMsg} "Delayed Delete File (Reboot Required): $R1.moz-delete" michael@0: GoTo end michael@0: ${EndUnless} michael@0: michael@0: ; Check if the file exists in the source. If it does the new file will michael@0: ; replace the existing file when the system is rebooted. If it doesn't michael@0: ; the file will be deleted when the system is rebooted. michael@0: ${Unless} ${FileExists} "$EXEDIR\core$R9" michael@0: ${AndUnless} ${FileExists} "$EXEDIR\optional$R9" michael@0: Delete /REBOOTOK "$R1" michael@0: ${LogMsg} "Delayed Delete File (Reboot Required): $R1" michael@0: ${EndUnless} michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: ; Using locate will leave file handles open to some of the directories michael@0: ; which will prevent the deletion of these directories. This parses the michael@0: ; uninstall.log and uses the file entries to find / remove empty michael@0: ; directories. michael@0: Function RemoveDirsCallback michael@0: ${TrimNewLines} "$R9" $R9 michael@0: StrCpy $R0 "$R9" 5 ; Copy the first five chars michael@0: StrCmp "$R0" "File:" +1 end michael@0: michael@0: StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char michael@0: StrCpy $R0 "$R9" 1 ; Copy the first char michael@0: michael@0: StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string michael@0: StrCmp "$R0" "\" loop end ; If this isn't a relative path goto end michael@0: michael@0: loop: michael@0: ${GetParent} "$R1" $R1 ; Get the parent directory for the path michael@0: StrCmp "$R1" "$INSTDIR" end +1 ; If the directory is the install dir goto end michael@0: michael@0: IfFileExists "$R1" +1 loop ; Only try to remove the dir if it exists michael@0: ClearErrors michael@0: RmDir "$R1" ; Remove the dir michael@0: IfErrors end +1 ; If we fail there is no use trying to remove its parent dir michael@0: ${LogMsg} "Deleted Directory: $R1" michael@0: GoTo loop michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro OnInstallUninstallCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call OnInstallUninstall michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Parses the uninstall.log for the stub installer on install to first remove a michael@0: * previous installation's files prior to installing. michael@0: * michael@0: * When modifying this macro be aware that LineFind uses all registers except michael@0: * $R0-$R3 so be cautious. Callers of this macro are not affected. michael@0: * michael@0: * @param _PROGRESSBAR michael@0: * The progress bar to update using PBM_STEPIT. Can also be "false" if michael@0: * updating a progressbar isn't needed. michael@0: * @param _INSTALL_STEP_COUNTER michael@0: * The install step counter to increment. The variable specified in michael@0: * this parameter is also updated. Can also be "false" if a counter michael@0: * isn't needed. michael@0: * michael@0: * $R2 = _INSTALL_STEP_COUNTER michael@0: * $R3 = _PROGRESSBAR michael@0: */ michael@0: !macro OnStubInstallUninstall michael@0: michael@0: !ifndef OnStubInstallUninstall michael@0: !insertmacro GetParent michael@0: !insertmacro LineFind michael@0: !insertmacro TrimNewLines michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define OnStubInstallUninstall "!insertmacro OnStubInstallUninstallCall" michael@0: michael@0: Function OnStubInstallUninstall michael@0: Exch $R2 michael@0: Exch 1 michael@0: Exch $R3 michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R1 michael@0: Push $R0 michael@0: Push $TmpVal michael@0: michael@0: IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end michael@0: michael@0: ; Copy the uninstall log file to a temporary file michael@0: GetTempFileName $TmpVal michael@0: CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" michael@0: michael@0: CreateDirectory "$INSTDIR\${TO_BE_DELETED}" michael@0: michael@0: ; Delete files michael@0: ${LineFind} "$TmpVal" "/NUL" "1:-1" "StubRemoveFilesCallback" michael@0: michael@0: ; Delete the temporary uninstall log file michael@0: Delete /REBOOTOK "$TmpVal" michael@0: michael@0: RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}" michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Pop $TmpVal michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Pop $R9 michael@0: Exch $R3 michael@0: Exch 1 michael@0: Exch $R2 michael@0: FunctionEnd michael@0: michael@0: Function StubRemoveFilesCallback michael@0: ${TrimNewLines} "$R9" $R9 michael@0: StrCpy $R1 "$R9" 5 ; Copy the first five chars michael@0: michael@0: StrCmp "$R1" "File:" +1 end michael@0: StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char michael@0: StrCpy $R0 "$R9" 1 ; Copy the first char michael@0: michael@0: StrCmp "$R0" "\" +1 end ; If this isn't a relative path goto end michael@0: StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll michael@0: StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll michael@0: michael@0: StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string michael@0: IfFileExists "$R1" +1 end michael@0: michael@0: ${Unless} "$R2" == "false" michael@0: IntOp $R2 $R2 + 2 michael@0: ${EndIf} michael@0: ${Unless} "$R3" == "false" michael@0: SendMessage $R3 ${PBM_STEPIT} 0 0 michael@0: SendMessage $R3 ${PBM_STEPIT} 0 0 michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: Delete "$R1" michael@0: ${Unless} ${Errors} michael@0: Goto end michael@0: ${EndUnless} michael@0: michael@0: GetTempFileName $R0 "$INSTDIR\${TO_BE_DELETED}" michael@0: Delete "$R0" michael@0: ClearErrors michael@0: Rename "$R1" "$R0" michael@0: ${If} ${Errors} michael@0: Delete /REBOOTOK "$R1" michael@0: ${EndUnless} michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro OnStubInstallUninstallCall _PROGRESSBAR _INSTALL_STEP_COUNTER michael@0: !verbose push michael@0: Push "${_PROGRESSBAR}" michael@0: Push "${_INSTALL_STEP_COUNTER}" michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call OnStubInstallUninstall michael@0: Pop ${_INSTALL_STEP_COUNTER} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Parses the uninstall.log to unregister dll's, remove files, and remove michael@0: * empty directories for this installation. michael@0: * michael@0: * When modifying this macro be aware that LineFind uses all registers except michael@0: * $R0-$R3 so be cautious. Callers of this macro are not affected. michael@0: */ michael@0: !macro un.ParseUninstallLog michael@0: michael@0: !ifndef un.ParseUninstallLog michael@0: !insertmacro un.GetParent michael@0: !insertmacro un.LineFind michael@0: !insertmacro un.TrimNewLines michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define un.ParseUninstallLog "!insertmacro un.ParseUninstallLogCall" michael@0: michael@0: Function un.ParseUninstallLog michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: Push $TmpVal michael@0: michael@0: IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end michael@0: michael@0: ; Copy the uninstall log file to a temporary file michael@0: GetTempFileName $TmpVal michael@0: CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal" michael@0: michael@0: ; Unregister DLL's michael@0: ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.UnRegDLLsCallback" michael@0: michael@0: ; Delete files michael@0: ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveFilesCallback" michael@0: michael@0: ; Remove empty directories michael@0: ${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.RemoveDirsCallback" michael@0: michael@0: ; Delete the temporary uninstall log file michael@0: Delete /REBOOTOK "$TmpVal" michael@0: michael@0: end: michael@0: michael@0: Pop $TmpVal michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: Function un.RemoveFilesCallback michael@0: ${un.TrimNewLines} "$R9" $R9 michael@0: StrCpy $R1 "$R9" 5 michael@0: michael@0: StrCmp "$R1" "File:" +1 end michael@0: StrCpy $R9 "$R9" "" 6 michael@0: StrCpy $R0 "$R9" 1 michael@0: michael@0: StrCpy $R1 "$INSTDIR$R9" michael@0: StrCmp "$R0" "\" +2 +1 michael@0: StrCpy $R1 "$R9" michael@0: michael@0: IfFileExists "$R1" +1 end michael@0: Delete "$R1" michael@0: IfErrors +1 end michael@0: ClearErrors michael@0: Rename "$R1" "$R1.moz-delete" michael@0: IfErrors +1 +3 michael@0: Delete /REBOOTOK "$R1" michael@0: GoTo end michael@0: michael@0: Delete /REBOOTOK "$R1.moz-delete" michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: Function un.UnRegDLLsCallback michael@0: ${un.TrimNewLines} "$R9" $R9 michael@0: StrCpy $R1 "$R9" 7 michael@0: michael@0: StrCmp $R1 "DLLReg:" +1 end michael@0: StrCpy $R9 "$R9" "" 8 michael@0: StrCpy $R0 "$R9" 1 michael@0: michael@0: StrCpy $R1 "$INSTDIR$R9" michael@0: StrCmp $R0 "\" +2 +1 michael@0: StrCpy $R1 "$R9" michael@0: michael@0: ${UnregisterDLL} $R1 michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: ; Using locate will leave file handles open to some of the directories michael@0: ; which will prevent the deletion of these directories. This parses the michael@0: ; uninstall.log and uses the file entries to find / remove empty michael@0: ; directories. michael@0: Function un.RemoveDirsCallback michael@0: ${un.TrimNewLines} "$R9" $R9 michael@0: StrCpy $R0 "$R9" 5 ; Copy the first five chars michael@0: StrCmp "$R0" "File:" +1 end michael@0: michael@0: StrCpy $R9 "$R9" "" 6 ; Copy string starting after the 6th char michael@0: StrCpy $R0 "$R9" 1 ; Copy the first char michael@0: michael@0: StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string michael@0: StrCmp "$R0" "\" loop ; If this is a relative path goto the loop michael@0: StrCpy $R1 "$R9" ; Already a full path so copy the string michael@0: michael@0: loop: michael@0: ${un.GetParent} "$R1" $R1 ; Get the parent directory for the path michael@0: StrCmp "$R1" "$INSTDIR" end ; If the directory is the install dir goto end michael@0: michael@0: ; We only try to remove empty directories but the Desktop, StartMenu, and michael@0: ; QuickLaunch directories can be empty so guard against removing them. michael@0: SetShellVarContext all ; Set context to all users michael@0: StrCmp "$R1" "$DESKTOP" end ; All users desktop michael@0: StrCmp "$R1" "$STARTMENU" end ; All users start menu michael@0: michael@0: SetShellVarContext current ; Set context to all users michael@0: StrCmp "$R1" "$DESKTOP" end ; Current user desktop michael@0: StrCmp "$R1" "$STARTMENU" end ; Current user start menu michael@0: StrCmp "$R1" "$QUICKLAUNCH" end ; Current user quick launch michael@0: michael@0: IfFileExists "$R1" +1 +3 ; Only try to remove the dir if it exists michael@0: ClearErrors michael@0: RmDir "$R1" ; Remove the dir michael@0: IfErrors end ; If we fail there is no use trying to remove its parent dir michael@0: michael@0: StrCmp "$R0" "\" loop end ; Only loop when the path is relative to the install dir michael@0: michael@0: end: michael@0: ClearErrors michael@0: michael@0: Push 0 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro un.ParseUninstallLogCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.ParseUninstallLog michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Finds a valid Start Menu shortcut in the uninstall log and returns the michael@0: * relative path from the Start Menu's Programs directory to the shortcut's michael@0: * directory. michael@0: * michael@0: * When modifying this macro be aware that LineFind uses all registers except michael@0: * $R0-$R3 so be cautious. Callers of this macro are not affected. michael@0: * michael@0: * @return _REL_PATH_TO_DIR michael@0: * The relative path to the application's Start Menu directory from the michael@0: * Start Menu's Programs directory. michael@0: */ michael@0: !macro FindSMProgramsDir michael@0: michael@0: !ifndef FindSMProgramsDir michael@0: !insertmacro GetParent michael@0: !insertmacro LineFind michael@0: !insertmacro TrimNewLines michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define FindSMProgramsDir "!insertmacro FindSMProgramsDirCall" michael@0: michael@0: Function FindSMProgramsDir michael@0: Exch $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: michael@0: StrCpy $R3 "" michael@0: ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log" michael@0: ${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath" michael@0: ${EndIf} michael@0: ClearErrors michael@0: michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Exch $R3 michael@0: FunctionEnd michael@0: michael@0: ; This callback MUST use labels vs. relative line numbers. michael@0: Function FindSMProgramsDirRelPath michael@0: Push 0 michael@0: ${TrimNewLines} "$R9" $R9 michael@0: StrCpy $R4 "$R9" 5 michael@0: michael@0: StrCmp "$R4" "File:" +1 end_FindSMProgramsDirRelPath michael@0: StrCpy $R9 "$R9" "" 6 michael@0: StrCpy $R4 "$R9" 1 michael@0: michael@0: StrCmp "$R4" "\" end_FindSMProgramsDirRelPath +1 michael@0: michael@0: SetShellVarContext all michael@0: ${GetLongPath} "$SMPROGRAMS" $R4 michael@0: StrLen $R2 "$R4" michael@0: StrCpy $R1 "$R9" $R2 michael@0: StrCmp "$R1" "$R4" +1 end_FindSMProgramsDirRelPath michael@0: IfFileExists "$R9" +1 end_FindSMProgramsDirRelPath michael@0: ShellLink::GetShortCutTarget "$R9" michael@0: Pop $R0 michael@0: StrCmp "$INSTDIR\${FileMainEXE}" "$R0" +1 end_FindSMProgramsDirRelPath michael@0: ${GetParent} "$R9" $R3 michael@0: IntOp $R2 $R2 + 1 michael@0: StrCpy $R3 "$R3" "" $R2 michael@0: michael@0: Pop $R4 ; Remove the previously pushed 0 from the stack and michael@0: push "StopLineFind" ; push StopLineFind to stop finding more lines. michael@0: michael@0: end_FindSMProgramsDirRelPath: michael@0: ClearErrors michael@0: michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro FindSMProgramsDirCall _REL_PATH_TO_DIR michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call FindSMProgramsDir michael@0: Pop ${_REL_PATH_TO_DIR} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for custom branding michael@0: michael@0: /** michael@0: * Sets BrandFullName and / or BrandShortName to values provided in the specified michael@0: * ini file and defaults to BrandShortName and BrandFullName as defined in michael@0: * branding.nsi when the associated ini file entry is not specified. michael@0: * michael@0: * ini file format: michael@0: * [Branding] michael@0: * BrandFullName=Custom Full Name michael@0: * BrandShortName=Custom Short Name michael@0: * michael@0: * @param _PATH_TO_INI michael@0: * Path to the ini file. michael@0: * michael@0: * $R6 = return value from ReadINIStr michael@0: * $R7 = stores BrandShortName michael@0: * $R8 = stores BrandFullName michael@0: * $R9 = _PATH_TO_INI michael@0: */ michael@0: !macro SetBrandNameVars michael@0: michael@0: !ifndef ${_MOZFUNC_UN}SetBrandNameVars michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}WordReplace michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: ; Prevent declaring vars twice when the SetBrandNameVars macro is michael@0: ; inserted into both the installer and uninstaller. michael@0: !ifndef SetBrandNameVars michael@0: Var BrandFullName michael@0: Var BrandFullNameDA michael@0: Var BrandShortName michael@0: !endif michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}SetBrandNameVars "!insertmacro ${_MOZFUNC_UN}SetBrandNameVarsCall" michael@0: michael@0: Function ${_MOZFUNC_UN}SetBrandNameVars michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: michael@0: StrCpy $R8 "${BrandFullName}" michael@0: StrCpy $R7 "${BrandShortName}" michael@0: michael@0: IfFileExists "$R9" +1 finish michael@0: michael@0: ClearErrors michael@0: ReadINIStr $R6 $R9 "Branding" "BrandFullName" michael@0: IfErrors +2 +1 michael@0: StrCpy $R8 "$R6" michael@0: michael@0: ClearErrors michael@0: ReadINIStr $R6 $R9 "Branding" "BrandShortName" michael@0: IfErrors +2 +1 michael@0: StrCpy $R7 "$R6" michael@0: michael@0: finish: michael@0: StrCpy $BrandFullName "$R8" michael@0: ${${_MOZFUNC_UN}WordReplace} "$R8" "&" "&&" "+" $R8 michael@0: StrCpy $BrandFullNameDA "$R8" michael@0: StrCpy $BrandShortName "$R7" michael@0: michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro SetBrandNameVarsCall _PATH_TO_INI michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_PATH_TO_INI}" michael@0: Call SetBrandNameVars michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.SetBrandNameVarsCall _PATH_TO_INI michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_PATH_TO_INI}" michael@0: Call un.SetBrandNameVars michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.SetBrandNameVars michael@0: !ifndef un.SetBrandNameVars michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro SetBrandNameVars michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Replaces the wizard's header image with the one specified. michael@0: * michael@0: * @param _PATH_TO_IMAGE michael@0: * Fully qualified path to the bitmap to use for the header image. michael@0: * michael@0: * $R8 = hwnd for the control returned from GetDlgItem. michael@0: * $R9 = _PATH_TO_IMAGE michael@0: */ michael@0: !macro ChangeMUIHeaderImage michael@0: michael@0: !ifndef ${_MOZFUNC_UN}ChangeMUIHeaderImage michael@0: Var hHeaderBitmap michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}ChangeMUIHeaderImage "!insertmacro ${_MOZFUNC_UN}ChangeMUIHeaderImageCall" michael@0: michael@0: Function ${_MOZFUNC_UN}ChangeMUIHeaderImage michael@0: Exch $R9 michael@0: Push $R8 michael@0: michael@0: GetDlgItem $R8 $HWNDPARENT 1046 michael@0: System::Call 'user32::LoadImageW(i 0, w "$R9", i 0, i 0, i 0, i 0x0010|0x2000) i.s' michael@0: Pop $hHeaderBitmap michael@0: SendMessage $R8 ${STM_SETIMAGE} 0 $hHeaderBitmap michael@0: ; There is no way to specify a show function for a custom page so hide michael@0: ; and then show the control to force the bitmap to redraw. michael@0: ShowWindow $R8 ${SW_HIDE} michael@0: ShowWindow $R8 ${SW_SHOW} michael@0: michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro ChangeMUIHeaderImageCall _PATH_TO_IMAGE michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_PATH_TO_IMAGE}" michael@0: Call ChangeMUIHeaderImage michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.ChangeMUIHeaderImageCall _PATH_TO_IMAGE michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_PATH_TO_IMAGE}" michael@0: Call un.ChangeMUIHeaderImage michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.ChangeMUIHeaderImage michael@0: !ifndef un.ChangeMUIHeaderImage michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro ChangeMUIHeaderImage michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # User interface callback helper defines and macros michael@0: michael@0: /* Install type defines */ michael@0: !ifndef INSTALLTYPE_BASIC michael@0: !define INSTALLTYPE_BASIC 1 michael@0: !endif michael@0: michael@0: !ifndef INSTALLTYPE_CUSTOM michael@0: !define INSTALLTYPE_CUSTOM 2 michael@0: !endif michael@0: michael@0: /** michael@0: * Checks whether to display the current page (e.g. if not performing a custom michael@0: * install don't display the custom pages). michael@0: */ michael@0: !macro CheckCustomCommon michael@0: michael@0: !ifndef CheckCustomCommon michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define CheckCustomCommon "!insertmacro CheckCustomCommonCall" michael@0: michael@0: Function CheckCustomCommon michael@0: michael@0: ; Abort if not a custom install michael@0: IntCmp $InstallType ${INSTALLTYPE_CUSTOM} +2 +1 +1 michael@0: Abort michael@0: michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro CheckCustomCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call CheckCustomCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Unloads dll's and releases references when the installer and uninstaller michael@0: * exit. michael@0: */ michael@0: !macro OnEndCommon michael@0: michael@0: !ifndef ${_MOZFUNC_UN}OnEndCommon michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}UnloadUAC michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}OnEndCommon "!insertmacro ${_MOZFUNC_UN}OnEndCommonCall" michael@0: michael@0: Function ${_MOZFUNC_UN}OnEndCommon michael@0: michael@0: ${${_MOZFUNC_UN}UnloadUAC} michael@0: StrCmp $hHeaderBitmap "" +3 +1 michael@0: System::Call "gdi32::DeleteObject(i s)" $hHeaderBitmap michael@0: StrCpy $hHeaderBitmap "" michael@0: michael@0: System::Free 0 michael@0: michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro OnEndCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call OnEndCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.OnEndCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.OnEndCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.OnEndCommon michael@0: !ifndef un.OnEndCommon michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro OnEndCommon michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Called from the installer's .onInit function not to be confused with the michael@0: * uninstaller's .onInit or the uninstaller's un.onInit functions. michael@0: * michael@0: * @param _WARN_UNSUPPORTED_MSG michael@0: * Message displayed when the Windows version is not supported. michael@0: * michael@0: * $R5 = return value from the GetSize macro michael@0: * $R6 = general string values, return value from GetTempFileName, return michael@0: * value from the GetSize macro michael@0: * $R7 = full path to the configuration ini file michael@0: * $R8 = used for OS Version and Service Pack detection and the return value michael@0: * from the GetParameters macro michael@0: * $R9 = _WARN_UNSUPPORTED_MSG michael@0: */ michael@0: !macro InstallOnInitCommon michael@0: michael@0: !ifndef InstallOnInitCommon michael@0: !insertmacro ElevateUAC michael@0: !insertmacro GetOptions michael@0: !insertmacro GetParameters michael@0: !insertmacro GetSize michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define InstallOnInitCommon "!insertmacro InstallOnInitCommonCall" michael@0: michael@0: Function InstallOnInitCommon michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: !ifdef HAVE_64BIT_OS michael@0: ${Unless} ${RunningX64} michael@0: ${OrUnless} ${AtLeastWinVista} michael@0: MessageBox MB_OK|MB_ICONSTOP "$R9" IDOK michael@0: ; Nothing initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndUnless} michael@0: michael@0: SetRegView 64 michael@0: !else michael@0: StrCpy $R8 "0" michael@0: ${If} ${AtMostWin2000} michael@0: StrCpy $R8 "1" michael@0: ${EndIf} michael@0: michael@0: ${If} ${IsWinXP} michael@0: ${AndIf} ${AtMostServicePack} 1 michael@0: StrCpy $R8 "1" michael@0: ${EndIf} michael@0: michael@0: ${If} $R8 == "1" michael@0: ; XXX-rstrong - some systems failed the AtLeastWin2000 test that we michael@0: ; used to use for an unknown reason and likely fail the AtMostWin2000 michael@0: ; and possibly the IsWinXP test as well. To work around this also michael@0: ; check if the Windows NT registry Key exists and if it does if the michael@0: ; first char in CurrentVersion is equal to 3 (Windows NT 3.5 and michael@0: ; 3.5.1), to 4 (Windows NT 4) or 5 (Windows 2000 and Windows XP). michael@0: StrCpy $R8 "" michael@0: ClearErrors michael@0: ReadRegStr $R8 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion" michael@0: StrCpy $R8 "$R8" 1 michael@0: ${If} ${Errors} michael@0: ${OrIf} "$R8" == "3" michael@0: ${OrIf} "$R8" == "4" michael@0: ${OrIf} "$R8" == "5" michael@0: MessageBox MB_OK|MB_ICONSTOP "$R9" IDOK michael@0: ; Nothing initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndIf} michael@0: ${EndUnless} michael@0: !endif michael@0: michael@0: ${GetParameters} $R8 michael@0: michael@0: ; Require elevation if the user can elevate michael@0: ${ElevateUAC} michael@0: michael@0: ${If} $R8 != "" michael@0: ; Default install type michael@0: StrCpy $InstallType ${INSTALLTYPE_BASIC} michael@0: michael@0: ${Unless} ${Silent} michael@0: ; Manually check for /S in the command line due to Bug 506867 michael@0: ClearErrors michael@0: ${GetOptions} "$R8" "/S" $R7 michael@0: ${Unless} ${Errors} michael@0: SetSilent silent michael@0: ${Else} michael@0: ; Support for the deprecated -ms command line argument. The new command michael@0: ; line arguments are not supported when -ms is used. michael@0: ClearErrors michael@0: ${GetOptions} "$R8" "-ms" $R7 michael@0: ${Unless} ${Errors} michael@0: SetSilent silent michael@0: ${EndUnless} michael@0: ${EndUnless} michael@0: ${EndUnless} michael@0: michael@0: ; Support for specifying an installation configuration file. michael@0: ClearErrors michael@0: ${GetOptions} "$R8" "/INI=" $R7 michael@0: ${Unless} ${Errors} michael@0: ; The configuration file must also exist michael@0: ${If} ${FileExists} "$R7" michael@0: SetSilent silent michael@0: ReadINIStr $R8 $R7 "Install" "InstallDirectoryName" michael@0: ${If} $R8 != "" michael@0: !ifdef HAVE_64BIT_OS michael@0: StrCpy $INSTDIR "$PROGRAMFILES64\$R8" michael@0: !else michael@0: StrCpy $INSTDIR "$PROGRAMFILES32\$R8" michael@0: !endif michael@0: ${Else} michael@0: ReadINIStr $R8 $R7 "Install" "InstallDirectoryPath" michael@0: ${If} $R8 != "" michael@0: StrCpy $INSTDIR "$R8" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ; Quit if we are unable to create the installation directory or we are michael@0: ; unable to write to a file in the installation directory. michael@0: ClearErrors michael@0: ${If} ${FileExists} "$INSTDIR" michael@0: GetTempFileName $R6 "$INSTDIR" michael@0: FileOpen $R5 "$R6" w michael@0: FileWrite $R5 "Write Access Test" michael@0: FileClose $R5 michael@0: Delete $R6 michael@0: ${If} ${Errors} michael@0: ; Nothing initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndIf} michael@0: ${Else} michael@0: CreateDirectory "$INSTDIR" michael@0: ${If} ${Errors} michael@0: ; Nothing initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: ReadINIStr $R8 $R7 "Install" "QuickLaunchShortcut" michael@0: ${If} $R8 == "false" michael@0: StrCpy $AddQuickLaunchSC "0" michael@0: ${Else} michael@0: StrCpy $AddQuickLaunchSC "1" michael@0: ${EndIf} michael@0: michael@0: ReadINIStr $R8 $R7 "Install" "DesktopShortcut" michael@0: ${If} $R8 == "false" michael@0: StrCpy $AddDesktopSC "0" michael@0: ${Else} michael@0: StrCpy $AddDesktopSC "1" michael@0: ${EndIf} michael@0: michael@0: ReadINIStr $R8 $R7 "Install" "StartMenuShortcuts" michael@0: ${If} $R8 == "false" michael@0: StrCpy $AddStartMenuSC "0" michael@0: ${Else} michael@0: StrCpy $AddStartMenuSC "1" michael@0: ${EndIf} michael@0: michael@0: ReadINIStr $R8 $R7 "Install" "MaintenanceService" michael@0: ${If} $R8 == "false" michael@0: StrCpy $InstallMaintenanceService "0" michael@0: ${EndIf} michael@0: michael@0: !ifndef NO_STARTMENU_DIR michael@0: ReadINIStr $R8 $R7 "Install" "StartMenuDirectoryName" michael@0: ${If} $R8 != "" michael@0: StrCpy $StartMenuDir "$R8" michael@0: ${EndIf} michael@0: !endif michael@0: ${EndIf} michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: ClearErrors michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro InstallOnInitCommonCall _WARN_UNSUPPORTED_MSG michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_WARN_UNSUPPORTED_MSG}" michael@0: Call InstallOnInitCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Called from the uninstaller's .onInit function not to be confused with the michael@0: * installer's .onInit or the uninstaller's un.onInit functions. michael@0: */ michael@0: !macro UninstallOnInitCommon michael@0: michael@0: !ifndef UninstallOnInitCommon michael@0: !insertmacro ElevateUAC michael@0: !insertmacro GetLongPath michael@0: !insertmacro GetOptions michael@0: !insertmacro GetParameters michael@0: !insertmacro GetParent michael@0: !insertmacro UnloadUAC michael@0: !insertmacro UpdateShortcutAppModelIDs michael@0: !insertmacro UpdateUninstallLog michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define UninstallOnInitCommon "!insertmacro UninstallOnInitCommonCall" michael@0: michael@0: Function UninstallOnInitCommon michael@0: ; Prevents breaking apps that don't use SetBrandNameVars michael@0: !ifdef SetBrandNameVars michael@0: ${SetBrandNameVars} "$EXEDIR\distribution\setup.ini" michael@0: !endif michael@0: michael@0: ; Prevent launching the application when a reboot is required and this michael@0: ; executable is the main application executable michael@0: IfFileExists "$EXEDIR\${FileMainEXE}.moz-upgrade" +1 +4 michael@0: MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 michael@0: Reboot michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: ${GetParent} "$EXEDIR" $INSTDIR michael@0: ${GetLongPath} "$INSTDIR" $INSTDIR michael@0: IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1 michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: !ifmacrodef InitHashAppModelId michael@0: ; setup the application model id registration value michael@0: !ifdef AppName michael@0: ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" michael@0: !endif michael@0: !endif michael@0: michael@0: ; Prevents breaking apps that don't use SetBrandNameVars michael@0: !ifdef SetBrandNameVars michael@0: ${SetBrandNameVars} "$INSTDIR\distribution\setup.ini" michael@0: !endif michael@0: michael@0: ; Application update uses a directory named tobedeleted in the $INSTDIR to michael@0: ; delete files on OS reboot when they are in use. Try to delete this michael@0: ; directory if it exists. michael@0: ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" michael@0: RmDir /r "$INSTDIR\${TO_BE_DELETED}" michael@0: ${EndIf} michael@0: michael@0: ; Prevent all operations (e.g. set as default, postupdate, etc.) when a michael@0: ; reboot is required and the executable launched is helper.exe michael@0: IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4 michael@0: MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2 michael@0: Reboot michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: !ifdef HAVE_64BIT_OS michael@0: SetRegView 64 michael@0: !endif michael@0: michael@0: ${GetParameters} $R0 michael@0: michael@0: StrCmp "$R0" "" continue +1 michael@0: michael@0: ; Update this user's shortcuts with the latest app user model id. michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/UpdateShortcutAppUserModelIds" $R2 michael@0: IfErrors hideshortcuts +1 michael@0: StrCpy $R2 "" michael@0: !ifmacrodef InitHashAppModelId michael@0: ${If} "$AppUserModelID" != "" michael@0: ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "$AppUserModelID" $R2 michael@0: ${EndIf} michael@0: !endif michael@0: StrCmp "$R2" "false" +1 finish ; true indicates that shortcuts have been updated michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: ; Require elevation if the user can elevate michael@0: hideshortcuts: michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/HideShortcuts" $R2 michael@0: IfErrors showshortcuts +1 michael@0: !ifndef NONADMIN_ELEVATE michael@0: ${ElevateUAC} michael@0: !endif michael@0: ${HideShortcuts} michael@0: GoTo finish michael@0: michael@0: ; Require elevation if the user can elevate michael@0: showshortcuts: michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/ShowShortcuts" $R2 michael@0: IfErrors defaultappuser +1 michael@0: !ifndef NONADMIN_ELEVATE michael@0: ${ElevateUAC} michael@0: !endif michael@0: ${ShowShortcuts} michael@0: GoTo finish michael@0: michael@0: ; Require elevation if the the StartMenuInternet registry keys require michael@0: ; updating and the user can elevate michael@0: defaultappuser: michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/SetAsDefaultAppUser" $R2 michael@0: IfErrors defaultappglobal +1 michael@0: ${SetAsDefaultAppUser} michael@0: GoTo finish michael@0: michael@0: ; Require elevation if the user can elevate michael@0: defaultappglobal: michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/SetAsDefaultAppGlobal" $R2 michael@0: IfErrors postupdate +1 michael@0: ${ElevateUAC} michael@0: ${SetAsDefaultAppGlobal} michael@0: GoTo finish michael@0: michael@0: ; Do not attempt to elevate. The application launching this executable is michael@0: ; responsible for elevation if it is required. michael@0: postupdate: michael@0: ${WordReplace} "$R0" "$\"" "" "+" $R0 michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/PostUpdate" $R2 michael@0: IfErrors continue +1 michael@0: ; If the uninstall.log does not exist don't perform post update michael@0: ; operations. This prevents updating the registry for zip builds. michael@0: IfFileExists "$EXEDIR\uninstall.log" +2 +1 michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: ${PostUpdate} michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/UninstallLog=" $R2 michael@0: IfErrors updateuninstalllog +1 michael@0: StrCmp "$R2" "" finish +1 michael@0: GetFullPathName $R3 "$R2" michael@0: IfFileExists "$R3" +1 finish michael@0: Delete "$INSTDIR\uninstall\*wizard*" michael@0: Delete "$INSTDIR\uninstall\uninstall.log" michael@0: CopyFiles /SILENT /FILESONLY "$R3" "$INSTDIR\uninstall\" michael@0: ${GetParent} "$R3" $R4 michael@0: Delete "$R3" michael@0: RmDir "$R4" michael@0: GoTo finish michael@0: michael@0: ; Do not attempt to elevate. The application launching this executable is michael@0: ; responsible for elevation if it is required. michael@0: updateuninstalllog: michael@0: ${UpdateUninstallLog} michael@0: michael@0: finish: michael@0: ${UnloadUAC} michael@0: System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i 0, i 0, i 0)" michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: continue: michael@0: michael@0: ; If the uninstall.log does not exist don't perform uninstall michael@0: ; operations. This prevents running the uninstaller for zip builds. michael@0: IfFileExists "$INSTDIR\uninstall\uninstall.log" +2 +1 michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: ; Require elevation if the user can elevate michael@0: ${ElevateUAC} michael@0: michael@0: ; If we made it this far then this installer is being used as an uninstaller. michael@0: WriteUninstaller "$EXEDIR\uninstaller.exe" michael@0: michael@0: ${Unless} ${Silent} michael@0: ; Manually check for /S in the command line due to Bug 506867 michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "/S" $R2 michael@0: ${Unless} ${Errors} michael@0: SetSilent silent michael@0: ${Else} michael@0: ; Support for the deprecated -ms command line argument. michael@0: ClearErrors michael@0: ${GetOptions} "$R0" "-ms" $R2 michael@0: ${Unless} ${Errors} michael@0: SetSilent silent michael@0: ${EndUnless} michael@0: ${EndUnless} michael@0: ${EndUnless} michael@0: michael@0: ${If} ${Silent} michael@0: StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\" /S" michael@0: ${Else} michael@0: StrCpy $R1 "$\"$EXEDIR\uninstaller.exe$\"" michael@0: ${EndIf} michael@0: michael@0: ; When the uninstaller is launched it copies itself to the temp directory michael@0: ; so it won't be in use so it can delete itself. michael@0: ExecWait $R1 michael@0: ${DeleteFile} "$EXEDIR\uninstaller.exe" michael@0: ${UnloadUAC} michael@0: SetErrorLevel 0 michael@0: Quit ; Nothing initialized so no need to call OnEndCommon michael@0: michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro UninstallOnInitCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call UninstallOnInitCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Called from the uninstaller's un.onInit function not to be confused with the michael@0: * installer's .onInit or the uninstaller's .onInit functions. michael@0: */ michael@0: !macro un.UninstallUnOnInitCommon michael@0: michael@0: !ifndef un.UninstallUnOnInitCommon michael@0: !insertmacro un.GetLongPath michael@0: !insertmacro un.GetParent michael@0: !insertmacro un.SetBrandNameVars michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define un.UninstallUnOnInitCommon "!insertmacro un.UninstallUnOnInitCommonCall" michael@0: michael@0: Function un.UninstallUnOnInitCommon michael@0: ${un.GetParent} "$INSTDIR" $INSTDIR michael@0: ${un.GetLongPath} "$INSTDIR" $INSTDIR michael@0: ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}" michael@0: Abort michael@0: ${EndUnless} michael@0: michael@0: !ifdef HAVE_64BIT_OS michael@0: SetRegView 64 michael@0: !endif michael@0: michael@0: ; Prevents breaking apps that don't use SetBrandNameVars michael@0: !ifdef un.SetBrandNameVars michael@0: ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini" michael@0: !endif michael@0: michael@0: ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if michael@0: ; the user clicks the back button michael@0: StrCpy $hHeaderBitmap "" michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro un.UninstallUnOnInitCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.UninstallUnOnInitCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Called from the MUI leaveOptions function to set the value of $INSTDIR. michael@0: */ michael@0: !macro LeaveOptionsCommon michael@0: michael@0: !ifndef LeaveOptionsCommon michael@0: !insertmacro CanWriteToInstallDir michael@0: !insertmacro GetLongPath michael@0: michael@0: !ifndef NO_INSTDIR_FROM_REG michael@0: !insertmacro GetSingleInstallPath michael@0: !endif michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LeaveOptionsCommon "!insertmacro LeaveOptionsCommonCall" michael@0: michael@0: Function LeaveOptionsCommon michael@0: Push $R9 michael@0: michael@0: !ifndef NO_INSTDIR_FROM_REG michael@0: SetShellVarContext all ; Set SHCTX to HKLM michael@0: ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 michael@0: michael@0: StrCmp "$R9" "false" +1 finish_get_install_dir michael@0: michael@0: SetShellVarContext current ; Set SHCTX to HKCU michael@0: ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 michael@0: michael@0: finish_get_install_dir: michael@0: StrCmp "$R9" "false" +2 +1 michael@0: StrCpy $INSTDIR "$R9" michael@0: !endif michael@0: michael@0: ; If the user doesn't have write access to the installation directory set michael@0: ; the installation directory to a subdirectory of the All Users application michael@0: ; directory and if the user can't write to that location set the installation michael@0: ; directory to a subdirectory of the users local application directory michael@0: ; (e.g. non-roaming). michael@0: ${CanWriteToInstallDir} $R9 michael@0: StrCmp "$R9" "false" +1 finish_check_install_dir michael@0: michael@0: SetShellVarContext all ; Set SHCTX to All Users michael@0: StrCpy $INSTDIR "$APPDATA\${BrandFullName}\" michael@0: ${CanWriteToInstallDir} $R9 michael@0: StrCmp "$R9" "false" +2 +1 michael@0: StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\" michael@0: michael@0: finish_check_install_dir: michael@0: IfFileExists "$INSTDIR" +3 +1 michael@0: Pop $R9 michael@0: Return michael@0: michael@0: ; Always display the long path if the path already exists. michael@0: ${GetLongPath} "$INSTDIR" $INSTDIR michael@0: michael@0: ; The call to GetLongPath returns a long path without a trailing michael@0: ; back-slash. Append a \ to the path to prevent the directory michael@0: ; name from being appended when using the NSIS create new folder. michael@0: ; http://www.nullsoft.com/free/nsis/makensis.htm#InstallDir michael@0: StrCpy $INSTDIR "$INSTDIR\" michael@0: michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LeaveOptionsCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call LeaveOptionsCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Called from the MUI preDirectory function to verify there is enough disk michael@0: * space for the installation and the installation directory is writable. michael@0: * michael@0: * $R9 = returned value from CheckDiskSpace and CanWriteToInstallDir macros michael@0: */ michael@0: !macro PreDirectoryCommon michael@0: michael@0: !ifndef PreDirectoryCommon michael@0: !insertmacro CanWriteToInstallDir michael@0: !insertmacro CheckDiskSpace michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define PreDirectoryCommon "!insertmacro PreDirectoryCommonCall" michael@0: michael@0: Function PreDirectoryCommon michael@0: Push $R9 michael@0: michael@0: IntCmp $InstallType ${INSTALLTYPE_CUSTOM} end +1 +1 michael@0: ${CanWriteToInstallDir} $R9 michael@0: StrCmp "$R9" "false" end +1 michael@0: ${CheckDiskSpace} $R9 michael@0: StrCmp "$R9" "false" end +1 michael@0: Abort michael@0: michael@0: end: michael@0: michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro PreDirectoryCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call PreDirectoryCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Called from the MUI leaveDirectory function michael@0: * michael@0: * @param _WARN_DISK_SPACE michael@0: * Message displayed when there isn't enough disk space to perform the michael@0: * installation. michael@0: * @param _WARN_WRITE_ACCESS michael@0: * Message displayed when the installer does not have write access to michael@0: * $INSTDIR. michael@0: * michael@0: * $R7 = returned value from CheckDiskSpace and CanWriteToInstallDir macros michael@0: * $R8 = _WARN_DISK_SPACE michael@0: * $R9 = _WARN_WRITE_ACCESS michael@0: */ michael@0: !macro LeaveDirectoryCommon michael@0: michael@0: !ifndef LeaveDirectoryCommon michael@0: !insertmacro CheckDiskSpace michael@0: !insertmacro CanWriteToInstallDir michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LeaveDirectoryCommon "!insertmacro LeaveDirectoryCommonCall" michael@0: michael@0: Function LeaveDirectoryCommon michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Push $R7 michael@0: michael@0: ${CanWriteToInstallDir} $R7 michael@0: ${If} $R7 == "false" michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$R9" michael@0: Abort michael@0: ${EndIf} michael@0: michael@0: ${CheckDiskSpace} $R7 michael@0: ${If} $R7 == "false" michael@0: MessageBox MB_OK|MB_ICONEXCLAMATION "$R8" michael@0: Abort michael@0: ${EndIf} michael@0: michael@0: Pop $R7 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LeaveDirectoryCommonCall _WARN_DISK_SPACE _WARN_WRITE_ACCESS michael@0: !verbose push michael@0: Push "${_WARN_DISK_SPACE}" michael@0: Push "${_WARN_WRITE_ACCESS}" michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call LeaveDirectoryCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Install Section common macros. michael@0: michael@0: /** michael@0: * Performs common cleanup operations prior to the actual installation. michael@0: * This macro should be called first when installation starts. michael@0: */ michael@0: !macro InstallStartCleanupCommon michael@0: michael@0: !ifndef InstallStartCleanupCommon michael@0: !insertmacro CleanVirtualStore michael@0: !insertmacro EndUninstallLog michael@0: !insertmacro OnInstallUninstall michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define InstallStartCleanupCommon "!insertmacro InstallStartCleanupCommonCall" michael@0: michael@0: Function InstallStartCleanupCommon michael@0: michael@0: ; Remove files not removed by parsing the uninstall.log michael@0: Delete "$INSTDIR\install_wizard.log" michael@0: Delete "$INSTDIR\install_status.log" michael@0: michael@0: RmDir /r "$INSTDIR\updates" michael@0: Delete "$INSTDIR\updates.xml" michael@0: Delete "$INSTDIR\active-update.xml" michael@0: michael@0: RmDir /r "$INSTDIR\distribution" michael@0: michael@0: ; Remove files from the uninstall directory. michael@0: ${If} ${FileExists} "$INSTDIR\uninstall" michael@0: Delete "$INSTDIR\uninstall\*wizard*" michael@0: Delete "$INSTDIR\uninstall\uninstall.ini" michael@0: Delete "$INSTDIR\uninstall\cleanup.log" michael@0: Delete "$INSTDIR\uninstall\uninstall.update" michael@0: ${OnInstallUninstall} michael@0: ${EndIf} michael@0: michael@0: ; Since we write to the uninstall.log in this directory during the michael@0: ; installation create the directory if it doesn't already exist. michael@0: IfFileExists "$INSTDIR\uninstall" +2 +1 michael@0: CreateDirectory "$INSTDIR\uninstall" michael@0: michael@0: ; Application update uses a directory named tobedeleted in the $INSTDIR to michael@0: ; delete files on OS reboot when they are in use. Try to delete this michael@0: ; directory if it exists. michael@0: ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" michael@0: RmDir /r "$INSTDIR\${TO_BE_DELETED}" michael@0: ${EndIf} michael@0: michael@0: ; Remove files that may be left behind by the application in the michael@0: ; VirtualStore directory. michael@0: ${CleanVirtualStore} michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro InstallStartCleanupCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call InstallStartCleanupCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Performs common cleanup operations after the actual installation. michael@0: * This macro should be called last during the installation. michael@0: */ michael@0: !macro InstallEndCleanupCommon michael@0: michael@0: !ifndef InstallEndCleanupCommon michael@0: !insertmacro EndUninstallLog michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define InstallEndCleanupCommon "!insertmacro InstallEndCleanupCommonCall" michael@0: michael@0: Function InstallEndCleanupCommon michael@0: michael@0: ; Close the file handle to the uninstall.log michael@0: ${EndUninstallLog} michael@0: michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro InstallEndCleanupCommonCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call InstallEndCleanupCommon michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # UAC Related Macros michael@0: michael@0: /** michael@0: * Provides UAC elevation support for Vista and above (requires the UAC plugin). michael@0: * michael@0: * $0 = return values from calls to the UAC plugin (always uses $0) michael@0: * $R9 = return values from GetParameters and GetOptions macros michael@0: */ michael@0: !macro ElevateUAC michael@0: michael@0: !ifndef ${_MOZFUNC_UN}ElevateUAC michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetOptions michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetParameters michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}ElevateUAC "!insertmacro ${_MOZFUNC_UN}ElevateUACCall" michael@0: michael@0: Function ${_MOZFUNC_UN}ElevateUAC michael@0: Push $R9 michael@0: Push $0 michael@0: michael@0: !ifndef NONADMIN_ELEVATE michael@0: ${If} ${AtLeastWinVista} michael@0: UAC::IsAdmin michael@0: ; If the user is not an admin already michael@0: ${If} "$0" != "1" michael@0: UAC::SupportsUAC michael@0: ; If the system supports UAC michael@0: ${If} "$0" == "1" michael@0: UAC::GetElevationType michael@0: ; If the user account has a split token michael@0: ${If} "$0" == "3" michael@0: UAC::RunElevated michael@0: UAC::Unload michael@0: ; Nothing besides UAC initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Else} michael@0: ${GetParameters} $R9 michael@0: ${If} $R9 != "" michael@0: ClearErrors michael@0: ${GetOptions} "$R9" "/UAC:" $0 michael@0: ; If the command line contains /UAC then we need to initialize michael@0: ; the UAC plugin to use UAC::ExecCodeSegment to execute code in michael@0: ; the non-elevated context. michael@0: ${Unless} ${Errors} michael@0: UAC::RunElevated michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: !else michael@0: ${If} ${AtLeastWinVista} michael@0: UAC::IsAdmin michael@0: ; If the user is not an admin already michael@0: ${If} "$0" != "1" michael@0: UAC::SupportsUAC michael@0: ; If the system supports UAC require that the user elevate michael@0: ${If} "$0" == "1" michael@0: UAC::GetElevationType michael@0: ; If the user account has a split token michael@0: ${If} "$0" == "3" michael@0: UAC::RunElevated michael@0: UAC::Unload michael@0: ; Nothing besides UAC initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndIf} michael@0: ${Else} michael@0: ; Check if UAC is enabled. If the user has turned UAC on or off michael@0: ; without rebooting this value will be incorrect. This is an michael@0: ; edgecase that we have to live with when trying to allow michael@0: ; installing when the user doesn't have privileges such as a public michael@0: ; computer while trying to also achieve UAC elevation. When this michael@0: ; happens the user will be presented with the runas dialog if the michael@0: ; value is 1 and won't be presented with the UAC dialog when the michael@0: ; value is 0. michael@0: ReadRegDWord $R9 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" "EnableLUA" michael@0: ${If} "$R9" == "1" michael@0: ; This will display the UAC version of the runas dialog which michael@0: ; requires a password for an existing user account. michael@0: UAC::RunElevated michael@0: ${If} "$0" == "0" ; Was elevation successful michael@0: UAC::Unload michael@0: ; Nothing besides UAC initialized so no need to call OnEndCommon michael@0: Quit michael@0: ${EndIf} michael@0: ; Unload UAC since the elevation request was not successful and michael@0: ; install anyway. michael@0: UAC::Unload michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Else} michael@0: ClearErrors michael@0: ${${_MOZFUNC_UN}GetParameters} $R9 michael@0: ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9 michael@0: ; If the command line contains /UAC then we need to initialize the UAC michael@0: ; plugin to use UAC::ExecCodeSegment to execute code in the michael@0: ; non-elevated context. michael@0: ${Unless} ${Errors} michael@0: UAC::RunElevated michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: !endif michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $0 michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro ElevateUACCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call ElevateUAC michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.ElevateUACCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.ElevateUAC michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.ElevateUAC michael@0: !ifndef un.ElevateUAC michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro ElevateUAC michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Unloads the UAC plugin so the NSIS plugins can be removed when the installer michael@0: * and uninstaller exit. michael@0: * michael@0: * $R9 = return values from GetParameters and GetOptions macros michael@0: */ michael@0: !macro UnloadUAC michael@0: michael@0: !ifndef ${_MOZFUNC_UN}UnloadUAC michael@0: !define _MOZFUNC_UN_TMP_UnloadUAC ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetOptions michael@0: !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetParameters michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP_UnloadUAC} michael@0: !undef _MOZFUNC_UN_TMP_UnloadUAC michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}UnloadUAC "!insertmacro ${_MOZFUNC_UN}UnloadUACCall" michael@0: michael@0: Function ${_MOZFUNC_UN}UnloadUAC michael@0: ${Unless} ${AtLeastWinVista} michael@0: Return michael@0: ${EndUnless} michael@0: michael@0: Push $R9 michael@0: michael@0: ClearErrors michael@0: ${${_MOZFUNC_UN}GetParameters} $R9 michael@0: ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9 michael@0: ; If the command line contains /UAC then we need to unload the UAC plugin michael@0: IfErrors +2 +1 michael@0: UAC::Unload michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro UnloadUACCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call UnloadUAC michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.UnloadUACCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call un.UnloadUAC michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.UnloadUAC michael@0: !ifndef un.UnloadUAC michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro UnloadUAC michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for uninstall.log and install.log logging michael@0: # michael@0: # Since these are used by other macros they should be inserted first. All of michael@0: # these macros can be easily inserted using the _LoggingCommon macro. michael@0: michael@0: /** michael@0: * Adds all logging macros in the correct order in one fell swoop as well as michael@0: * the vars for the install.log and uninstall.log file handles. michael@0: */ michael@0: !macro _LoggingCommon michael@0: Var /GLOBAL fhInstallLog michael@0: Var /GLOBAL fhUninstallLog michael@0: !insertmacro StartInstallLog michael@0: !insertmacro EndInstallLog michael@0: !insertmacro StartUninstallLog michael@0: !insertmacro EndUninstallLog michael@0: !macroend michael@0: !define _LoggingCommon "!insertmacro _LoggingCommon" michael@0: michael@0: /** michael@0: * Creates a file named install.log in the install directory (e.g. $INSTDIR) michael@0: * and adds the installation started message to the install.log for this michael@0: * installation. This also adds the fhInstallLog and fhUninstallLog vars used michael@0: * for logging. michael@0: * michael@0: * $fhInstallLog = filehandle for $INSTDIR\install.log michael@0: * michael@0: * @param _APP_NAME michael@0: * Typically the BrandFullName michael@0: * @param _AB_CD michael@0: * The locale identifier michael@0: * @param _APP_VERSION michael@0: * The application version michael@0: * @param _GRE_VERSION michael@0: * The Gecko Runtime Engine version michael@0: * michael@0: * $R6 = _APP_NAME michael@0: * $R7 = _AB_CD michael@0: * $R8 = _APP_VERSION michael@0: * $R9 = _GRE_VERSION michael@0: */ michael@0: !macro StartInstallLog michael@0: michael@0: !ifndef StartInstallLog michael@0: !insertmacro GetTime michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define StartInstallLog "!insertmacro StartInstallLogCall" michael@0: michael@0: Function StartInstallLog michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Exch 2 michael@0: Exch $R7 michael@0: Exch 3 michael@0: Exch $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: Push $R1 michael@0: Push $R0 michael@0: Push $9 michael@0: michael@0: ${DeleteFile} "$INSTDIR\install.log" michael@0: FileOpen $fhInstallLog "$INSTDIR\install.log" w michael@0: FileWriteWord $fhInstallLog "65279" michael@0: michael@0: ${GetTime} "" "L" $9 $R0 $R1 $R2 $R3 $R4 $R5 michael@0: FileWriteUTF16LE $fhInstallLog "$R6 Installation Started: $R1-$R0-$9 $R3:$R4:$R5" michael@0: ${WriteLogSeparator} michael@0: michael@0: ${LogHeader} "Installation Details" michael@0: ${LogMsg} "Install Dir: $INSTDIR" michael@0: ${LogMsg} "Locale : $R7" michael@0: ${LogMsg} "App Version: $R8" michael@0: ${LogMsg} "GRE Version: $R9" michael@0: michael@0: ${If} ${IsWinXP} michael@0: ${LogMsg} "OS Name : Windows XP" michael@0: ${ElseIf} ${IsWin2003} michael@0: ${LogMsg} "OS Name : Windows 2003" michael@0: ${ElseIf} ${IsWinVista} michael@0: ${LogMsg} "OS Name : Windows Vista" michael@0: ${ElseIf} ${IsWin7} michael@0: ${LogMsg} "OS Name : Windows 7" michael@0: ${ElseIf} ${IsWin8} michael@0: ${LogMsg} "OS Name : Windows 8" michael@0: ${ElseIf} ${AtLeastWin8} michael@0: ${LogMsg} "OS Name : Above Windows 8" michael@0: ${Else} michael@0: ${LogMsg} "OS Name : Unable to detect" michael@0: ${EndIf} michael@0: michael@0: !ifdef HAVE_64BIT_OS michael@0: ${LogMsg} "Target CPU : x64" michael@0: !else michael@0: ${LogMsg} "Target CPU : x86" michael@0: !endif michael@0: michael@0: Pop $9 michael@0: Pop $R0 michael@0: Pop $R1 michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Exch $R6 michael@0: Exch 3 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro StartInstallLogCall _APP_NAME _AB_CD _APP_VERSION _GRE_VERSION michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_APP_NAME}" michael@0: Push "${_AB_CD}" michael@0: Push "${_APP_VERSION}" michael@0: Push "${_GRE_VERSION}" michael@0: Call StartInstallLog michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Writes the installation finished message to the install.log and closes the michael@0: * file handles to the install.log and uninstall.log michael@0: * michael@0: * @param _APP_NAME michael@0: * michael@0: * $R9 = _APP_NAME michael@0: */ michael@0: !macro EndInstallLog michael@0: michael@0: !ifndef EndInstallLog michael@0: !insertmacro GetTime michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define EndInstallLog "!insertmacro EndInstallLogCall" michael@0: michael@0: Function EndInstallLog michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 michael@0: Push $R2 michael@0: michael@0: ${WriteLogSeparator} michael@0: ${GetTime} "" "L" $R2 $R3 $R4 $R5 $R6 $R7 $R8 michael@0: FileWriteUTF16LE $fhInstallLog "$R9 Installation Finished: $R4-$R3-$R2 $R6:$R7:$R8$\r$\n" michael@0: FileClose $fhInstallLog michael@0: michael@0: Pop $R2 michael@0: Pop $R3 michael@0: Pop $R4 michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro EndInstallLogCall _APP_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_APP_NAME}" michael@0: Call EndInstallLog michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Opens the file handle to the uninstall.log. michael@0: * michael@0: * $fhUninstallLog = filehandle for $INSTDIR\uninstall\uninstall.log michael@0: */ michael@0: !macro StartUninstallLog michael@0: michael@0: !ifndef StartUninstallLog michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define StartUninstallLog "!insertmacro StartUninstallLogCall" michael@0: michael@0: Function StartUninstallLog michael@0: FileOpen $fhUninstallLog "$INSTDIR\uninstall\uninstall.log" w michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro StartUninstallLogCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call StartUninstallLog michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Closes the file handle to the uninstall.log. michael@0: */ michael@0: !macro EndUninstallLog michael@0: michael@0: !ifndef EndUninstallLog michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define EndUninstallLog "!insertmacro EndUninstallLogCall" michael@0: michael@0: Function EndUninstallLog michael@0: FileClose $fhUninstallLog michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro EndUninstallLogCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call EndUninstallLog michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Adds a section header to the human readable log. michael@0: * michael@0: * @param _HEADER michael@0: * The header text to write to the log. michael@0: */ michael@0: !macro LogHeader _HEADER michael@0: ${WriteLogSeparator} michael@0: FileWriteUTF16LE $fhInstallLog "${_HEADER}" michael@0: ${WriteLogSeparator} michael@0: !macroend michael@0: !define LogHeader "!insertmacro LogHeader" michael@0: michael@0: /** michael@0: * Adds a section message to the human readable log. michael@0: * michael@0: * @param _MSG michael@0: * The message text to write to the log. michael@0: */ michael@0: !macro LogMsg _MSG michael@0: FileWriteUTF16LE $fhInstallLog " ${_MSG}$\r$\n" michael@0: !macroend michael@0: !define LogMsg "!insertmacro LogMsg" michael@0: michael@0: /** michael@0: * Adds an uninstall entry to the uninstall log. michael@0: * michael@0: * @param _MSG michael@0: * The message text to write to the log. michael@0: */ michael@0: !macro LogUninstall _MSG michael@0: FileWrite $fhUninstallLog "${_MSG}$\r$\n" michael@0: !macroend michael@0: !define LogUninstall "!insertmacro LogUninstall" michael@0: michael@0: /** michael@0: * Adds a section divider to the human readable log. michael@0: */ michael@0: !macro WriteLogSeparator michael@0: FileWriteUTF16LE $fhInstallLog "$\r$\n----------------------------------------\ michael@0: ---------------------------------------$\r$\n" michael@0: !macroend michael@0: !define WriteLogSeparator "!insertmacro WriteLogSeparator" michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for managing the shortcuts log ini file michael@0: michael@0: /** michael@0: * Adds the most commonly used shortcut logging macros for the installer in one michael@0: * fell swoop. michael@0: */ michael@0: !macro _LoggingShortcutsCommon michael@0: !insertmacro LogDesktopShortcut michael@0: !insertmacro LogQuickLaunchShortcut michael@0: !insertmacro LogSMProgramsShortcut michael@0: !macroend michael@0: !define _LoggingShortcutsCommon "!insertmacro _LoggingShortcutsCommon" michael@0: michael@0: /** michael@0: * Creates the shortcuts log ini file with a UTF-16LE BOM if it doesn't exist. michael@0: */ michael@0: !macro initShortcutsLog michael@0: Push $R9 michael@0: michael@0: IfFileExists "$INSTDIR\uninstall\${SHORTCUTS_LOG}" +4 +1 michael@0: FileOpen $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" w michael@0: FileWriteWord $R9 "65279" michael@0: FileClose $R9 michael@0: michael@0: Pop $R9 michael@0: !macroend michael@0: !define initShortcutsLog "!insertmacro initShortcutsLog" michael@0: michael@0: /** michael@0: * Adds shortcut entries to the shortcuts log ini file. This macro is primarily michael@0: * a helper used by the LogDesktopShortcut, LogQuickLaunchShortcut, and michael@0: * LogSMProgramsShortcut macros but it can be used by other code if desired. If michael@0: * the value already exists the the value is not written to the file. michael@0: * michael@0: * @param _SECTION_NAME michael@0: * The section name to write to in the shortcut log ini file michael@0: * @param _FILE_NAME michael@0: * The shortcut's file name michael@0: * michael@0: * $R6 = return value from ReadIniStr for the shortcut file name michael@0: * $R7 = counter for supporting multiple shortcuts in the same location michael@0: * $R8 = _SECTION_NAME michael@0: * $R9 = _FILE_NAME michael@0: */ michael@0: !macro LogShortcut michael@0: michael@0: !ifndef LogShortcut michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LogShortcut "!insertmacro LogShortcutCall" michael@0: michael@0: Function LogShortcut michael@0: Exch $R9 michael@0: Exch 1 michael@0: Exch $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: michael@0: ClearErrors michael@0: michael@0: !insertmacro initShortcutsLog michael@0: michael@0: StrCpy $R6 "" michael@0: StrCpy $R7 -1 michael@0: michael@0: StrCmp "$R6" "$R9" +5 +1 ; if the shortcut already exists don't add it michael@0: IntOp $R7 $R7 + 1 ; increment the counter michael@0: ReadIniStr $R6 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" michael@0: IfErrors +1 -3 michael@0: WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" "$R9" michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LogShortcutCall _SECTION_NAME _FILE_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_SECTION_NAME}" michael@0: Push "${_FILE_NAME}" michael@0: Call LogShortcut michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Adds a Desktop shortcut entry to the shortcuts log ini file. michael@0: * michael@0: * @param _FILE_NAME michael@0: * The shortcut file name (e.g. shortcut.lnk) michael@0: */ michael@0: !macro LogDesktopShortcut michael@0: michael@0: !ifndef LogDesktopShortcut michael@0: !insertmacro LogShortcut michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LogDesktopShortcut "!insertmacro LogDesktopShortcutCall" michael@0: michael@0: Function LogDesktopShortcut michael@0: Call LogShortcut michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LogDesktopShortcutCall _FILE_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "DESKTOP" michael@0: Push "${_FILE_NAME}" michael@0: Call LogDesktopShortcut michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Adds a QuickLaunch shortcut entry to the shortcuts log ini file. michael@0: * michael@0: * @param _FILE_NAME michael@0: * The shortcut file name (e.g. shortcut.lnk) michael@0: */ michael@0: !macro LogQuickLaunchShortcut michael@0: michael@0: !ifndef LogQuickLaunchShortcut michael@0: !insertmacro LogShortcut michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LogQuickLaunchShortcut "!insertmacro LogQuickLaunchShortcutCall" michael@0: michael@0: Function LogQuickLaunchShortcut michael@0: Call LogShortcut michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LogQuickLaunchShortcutCall _FILE_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "QUICKLAUNCH" michael@0: Push "${_FILE_NAME}" michael@0: Call LogQuickLaunchShortcut michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Adds a Start Menu shortcut entry to the shortcuts log ini file. michael@0: * michael@0: * @param _FILE_NAME michael@0: * The shortcut file name (e.g. shortcut.lnk) michael@0: */ michael@0: !macro LogStartMenuShortcut michael@0: michael@0: !ifndef LogStartMenuShortcut michael@0: !insertmacro LogShortcut michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LogStartMenuShortcut "!insertmacro LogStartMenuShortcutCall" michael@0: michael@0: Function LogStartMenuShortcut michael@0: Call LogShortcut michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LogStartMenuShortcutCall _FILE_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "STARTMENU" michael@0: Push "${_FILE_NAME}" michael@0: Call LogStartMenuShortcut michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Adds a Start Menu Programs shortcut entry to the shortcuts log ini file. michael@0: * michael@0: * @param _FILE_NAME michael@0: * The shortcut file name (e.g. shortcut.lnk) michael@0: */ michael@0: !macro LogSMProgramsShortcut michael@0: michael@0: !ifndef LogSMProgramsShortcut michael@0: !insertmacro LogShortcut michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define LogSMProgramsShortcut "!insertmacro LogSMProgramsShortcutCall" michael@0: michael@0: Function LogSMProgramsShortcut michael@0: Call LogShortcut michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro LogSMProgramsShortcutCall _FILE_NAME michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "SMPROGRAMS" michael@0: Push "${_FILE_NAME}" michael@0: Call LogSMProgramsShortcut michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Adds the relative path from the Start Menu Programs directory for the michael@0: * application's Start Menu directory if it is different from the existing value michael@0: * to the shortcuts log ini file. michael@0: * michael@0: * @param _REL_PATH_TO_DIR michael@0: * The relative path from the Start Menu Programs directory to the michael@0: * program's directory. michael@0: * michael@0: * $R9 = _REL_PATH_TO_DIR michael@0: */ michael@0: !macro LogSMProgramsDirRelPath _REL_PATH_TO_DIR michael@0: Push $R9 michael@0: michael@0: !insertmacro initShortcutsLog michael@0: michael@0: ReadINIStr $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" michael@0: StrCmp "$R9" "${_REL_PATH_TO_DIR}" +2 +1 michael@0: WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" "${_REL_PATH_TO_DIR}" michael@0: michael@0: Pop $R9 michael@0: !macroend michael@0: !define LogSMProgramsDirRelPath "!insertmacro LogSMProgramsDirRelPath" michael@0: michael@0: /** michael@0: * Copies the value for the relative path from the Start Menu programs directory michael@0: * (e.g. $SMPROGRAMS) to the Start Menu directory as it is stored in the michael@0: * shortcuts log ini file to the variable specified in the first parameter. michael@0: */ michael@0: !macro GetSMProgramsDirRelPath _VAR michael@0: ReadINIStr ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" \ michael@0: "RelativePathToDir" michael@0: !macroend michael@0: !define GetSMProgramsDirRelPath "!insertmacro GetSMProgramsDirRelPath" michael@0: michael@0: /** michael@0: * Copies the shortcuts log ini file path to the variable specified in the michael@0: * first parameter. michael@0: */ michael@0: !macro GetShortcutsLogPath _VAR michael@0: StrCpy ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" michael@0: !macroend michael@0: !define GetShortcutsLogPath "!insertmacro GetShortcutsLogPath" michael@0: michael@0: /** michael@0: * Deletes the shortcuts log ini file. michael@0: */ michael@0: !macro DeleteShortcutsLogFile michael@0: ${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" michael@0: !macroend michael@0: !define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile" michael@0: michael@0: michael@0: ################################################################################ michael@0: # Macros for managing specific Windows version features michael@0: michael@0: /** michael@0: * Sets the permitted layered service provider (LSP) categories on Windows michael@0: * Vista and above for the application. Consumers should call this after an michael@0: * installation log section has completed since this macro will log the results michael@0: * to the installation log along with a header. michael@0: * michael@0: * !IMPORTANT - When calling this macro from an uninstaller do not specify a michael@0: * parameter. The paramter is hardcoded with 0x00000000 to remove michael@0: * the LSP category for the application when performing an michael@0: * uninstall. michael@0: * michael@0: * @param _LSP_CATEGORIES michael@0: * The permitted LSP categories for the application. When called by an michael@0: * uninstaller this will always be 0x00000000. michael@0: * michael@0: * $R5 = error code popped from the stack for the WSCSetApplicationCategory call michael@0: * $R6 = return value from the WSCSetApplicationCategory call michael@0: * $R7 = string length for the long path to the main application executable michael@0: * $R8 = long path to the main application executable michael@0: * $R9 = _LSP_CATEGORIES michael@0: */ michael@0: !macro SetAppLSPCategories michael@0: michael@0: !ifndef ${_MOZFUNC_UN}SetAppLSPCategories michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}SetAppLSPCategories "!insertmacro ${_MOZFUNC_UN}SetAppLSPCategoriesCall" michael@0: michael@0: Function ${_MOZFUNC_UN}SetAppLSPCategories michael@0: ${Unless} ${AtLeastWinVista} michael@0: Return michael@0: ${EndUnless} michael@0: michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\${FileMainEXE}" $R8 michael@0: StrLen $R7 "$R8" michael@0: michael@0: ; Remove existing categories by setting the permitted categories to michael@0: ; 0x00000000 since new categories are ANDed with existing categories. If michael@0: ; the param value stored in $R9 is 0x00000000 then skip the removal since michael@0: ; the categories will be removed by the second call to michael@0: ; WSCSetApplicationCategory. michael@0: StrCmp "$R9" "0x00000000" +2 +1 michael@0: System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\ michael@0: i 0x00000000, i n, *i) i" michael@0: michael@0: ; Set the permitted LSP categories michael@0: System::Call "Ws2_32::WSCSetApplicationCategory(w R8, i R7, w n, i 0,\ michael@0: i R9, i n, *i .s) i.R6" michael@0: Pop $R5 michael@0: michael@0: !ifndef NO_LOG michael@0: ${LogHeader} "Setting Permitted LSP Categories" michael@0: StrCmp "$R6" 0 +3 +1 michael@0: ${LogMsg} "** ERROR Setting LSP Categories: $R5 **" michael@0: GoTo +2 michael@0: ${LogMsg} "Permitted LSP Categories: $R9" michael@0: !endif michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro SetAppLSPCategoriesCall _LSP_CATEGORIES michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_LSP_CATEGORIES}" michael@0: Call SetAppLSPCategories michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.SetAppLSPCategoriesCall michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "0x00000000" michael@0: Call un.SetAppLSPCategories michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.SetAppLSPCategories michael@0: !ifndef un.SetAppLSPCategories michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro SetAppLSPCategories michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Checks if any pinned TaskBar lnk files point to the executable's path passed michael@0: * to the macro. michael@0: * michael@0: * @param _EXE_PATH michael@0: * The executable path michael@0: * @return _RESULT michael@0: * false if no pinned shotcuts were found for this install location. michael@0: * true if pinned shotcuts were found for this install location. michael@0: * michael@0: * $R5 = stores whether a TaskBar lnk file has been found for the executable michael@0: * $R6 = long path returned from GetShortCutTarget and GetLongPath michael@0: * $R7 = file name returned from FindFirst and FindNext michael@0: * $R8 = find handle for FindFirst and FindNext michael@0: * $R9 = _EXE_PATH and _RESULT michael@0: */ michael@0: !macro IsPinnedToTaskBar michael@0: michael@0: !ifndef IsPinnedToTaskBar michael@0: !insertmacro GetLongPath michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define IsPinnedToTaskBar "!insertmacro IsPinnedToTaskBarCall" michael@0: michael@0: Function IsPinnedToTaskBar michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: StrCpy $R5 "false" michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" michael@0: FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" michael@0: ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\TaskBar\$R7" michael@0: Pop $R6 michael@0: ${GetLongPath} "$R6" $R6 michael@0: ${If} "$R6" == "$R9" michael@0: StrCpy $R5 "true" michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R8 $R7 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R8 michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: StrCpy $R9 $R5 michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro IsPinnedToTaskBarCall _EXE_PATH _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_EXE_PATH}" michael@0: Call IsPinnedToTaskBar michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Checks if any pinned Start Menu lnk files point to the executable's path michael@0: * passed to the macro. michael@0: * michael@0: * @param _EXE_PATH michael@0: * The executable path michael@0: * @return _RESULT michael@0: * false if no pinned shotcuts were found for this install location. michael@0: * true if pinned shotcuts were found for this install location. michael@0: * michael@0: * $R5 = stores whether a Start Menu lnk file has been found for the executable michael@0: * $R6 = long path returned from GetShortCutTarget and GetLongPath michael@0: * $R7 = file name returned from FindFirst and FindNext michael@0: * $R8 = find handle for FindFirst and FindNext michael@0: * $R9 = _EXE_PATH and _RESULT michael@0: */ michael@0: !macro IsPinnedToStartMenu michael@0: michael@0: !ifndef IsPinnedToStartMenu michael@0: !insertmacro GetLongPath michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define IsPinnedToStartMenu "!insertmacro IsPinnedToStartMenuCall" michael@0: michael@0: Function IsPinnedToStartMenu michael@0: Exch $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: StrCpy $R5 "false" michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" michael@0: FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" michael@0: ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\StartMenu\$R7" michael@0: Pop $R6 michael@0: ${GetLongPath} "$R6" $R6 michael@0: ${If} "$R6" == "$R9" michael@0: StrCpy $R5 "true" michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R8 $R7 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R8 michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: StrCpy $R9 $R5 michael@0: michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro IsPinnedToStartMenuCall _EXE_PATH _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_EXE_PATH}" michael@0: Call IsPinnedToStartMenu michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Gets the number of pinned shortcut lnk files pinned to the Task Bar. michael@0: * michael@0: * @return _RESULT michael@0: * number of pinned shortcut lnk files. michael@0: * michael@0: * $R7 = file name returned from FindFirst and FindNext michael@0: * $R8 = find handle for FindFirst and FindNext michael@0: * $R9 = _RESULT michael@0: */ michael@0: !macro PinnedToTaskBarLnkCount michael@0: michael@0: !ifndef PinnedToTaskBarLnkCount michael@0: !insertmacro GetLongPath michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define PinnedToTaskBarLnkCount "!insertmacro PinnedToTaskBarLnkCountCall" michael@0: michael@0: Function PinnedToTaskBarLnkCount michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: StrCpy $R9 0 michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" michael@0: FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" michael@0: IntOp $R9 $R9 + 1 michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R8 $R7 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R8 michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro PinnedToTaskBarLnkCountCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call PinnedToTaskBarLnkCount michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Gets the number of pinned shortcut lnk files pinned to the Start Menu. michael@0: * michael@0: * @return _RESULT michael@0: * number of pinned shortcut lnk files. michael@0: * michael@0: * $R7 = file name returned from FindFirst and FindNext michael@0: * $R8 = find handle for FindFirst and FindNext michael@0: * $R9 = _RESULT michael@0: */ michael@0: !macro PinnedToStartMenuLnkCount michael@0: michael@0: !ifndef PinnedToStartMenuLnkCount michael@0: !insertmacro GetLongPath michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define PinnedToStartMenuLnkCount "!insertmacro PinnedToStartMenuLnkCountCall" michael@0: michael@0: Function PinnedToStartMenuLnkCount michael@0: Push $R9 michael@0: Push $R8 michael@0: Push $R7 michael@0: michael@0: StrCpy $R9 0 michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" michael@0: FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" michael@0: IntOp $R9 $R9 + 1 michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R8 $R7 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R8 michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: Pop $R7 michael@0: Pop $R8 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro PinnedToStartMenuLnkCountCall _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Call PinnedToStartMenuLnkCount michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: /** michael@0: * Update Start Menu / TaskBar lnk files that point to the executable's path michael@0: * passed to the macro and all other shortcuts installed by the application with michael@0: * the current application user model ID. Requires ApplicationID. michael@0: * michael@0: * NOTE: this does not update Desktop shortcut application user model ID due to michael@0: * bug 633728. michael@0: * michael@0: * @param _EXE_PATH michael@0: * The main application executable path michael@0: * @param _APP_ID michael@0: * The application user model ID for the current install michael@0: * @return _RESULT michael@0: * false if no pinned shotcuts were found for this install location. michael@0: * true if pinned shotcuts were found for this install location. michael@0: */ michael@0: !macro UpdateShortcutAppModelIDs michael@0: michael@0: !ifndef UpdateShortcutAppModelIDs michael@0: !insertmacro GetLongPath michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define UpdateShortcutAppModelIDs "!insertmacro UpdateShortcutAppModelIDsCall" michael@0: michael@0: Function UpdateShortcutAppModelIDs michael@0: ; stack: path, appid michael@0: Exch $R9 ; stack: $R9, appid | $R9 = path michael@0: Exch 1 ; stack: appid, $R9 michael@0: Exch $R8 ; stack: $R8, $R9 | $R8 = appid michael@0: Push $R7 ; stack: $R7, $R8, $R9 michael@0: Push $R6 michael@0: Push $R5 michael@0: Push $R4 michael@0: Push $R3 ; stack: $R3, $R5, $R6, $R7, $R8, $R9 michael@0: Push $R2 michael@0: michael@0: ; $R9 = main application executable path michael@0: ; $R8 = appid michael@0: ; $R7 = path to the application's start menu programs directory michael@0: ; $R6 = path to the shortcut log ini file michael@0: ; $R5 = shortcut filename michael@0: ; $R4 = GetShortCutTarget result michael@0: michael@0: StrCpy $R3 "false" michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ; installed shortcuts michael@0: ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6 michael@0: ${If} ${FileExists} "$R6" michael@0: ; Update the Start Menu shortcuts' App ID for this application michael@0: StrCpy $R2 -1 michael@0: ${Do} michael@0: IntOp $R2 $R2 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$SMPROGRAMS\$R5" michael@0: ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5" michael@0: Pop $R4 michael@0: ${GetLongPath} "$R4" $R4 michael@0: ${If} "$R4" == "$R9" ; link path == install path michael@0: ApplicationID::Set "$SMPROGRAMS\$R5" "$R8" michael@0: Pop $R4 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ; Update the Quick Launch shortcuts' App ID for this application michael@0: StrCpy $R2 -1 michael@0: ${Do} michael@0: IntOp $R2 $R2 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R5 "$R6" "QUICKLAUNCH" "Shortcut$R2" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$QUICKLAUNCH\$R5" michael@0: ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R5" michael@0: Pop $R4 michael@0: ${GetLongPath} "$R4" $R4 michael@0: ${If} "$R4" == "$R9" ; link path == install path michael@0: ApplicationID::Set "$QUICKLAUNCH\$R5" "$R8" michael@0: Pop $R4 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: michael@0: ; Update the Start Menu Programs shortcuts' App ID for this application michael@0: ClearErrors michael@0: ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir" michael@0: ${Unless} ${Errors} michael@0: ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7 michael@0: ${Unless} "$R7" == "" michael@0: StrCpy $R2 -1 michael@0: ${Do} michael@0: IntOp $R2 $R2 + 1 ; Increment the counter michael@0: ClearErrors michael@0: ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2" michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: michael@0: ${If} ${FileExists} "$R7\$R5" michael@0: ShellLink::GetShortCutTarget "$R7\$R5" michael@0: Pop $R4 michael@0: ${GetLongPath} "$R4" $R4 michael@0: ${If} "$R4" == "$R9" ; link path == install path michael@0: ApplicationID::Set "$R7\$R5" "$R8" michael@0: Pop $R4 michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${Loop} michael@0: ${EndUnless} michael@0: ${EndUnless} michael@0: ${EndIf} michael@0: michael@0: StrCpy $R7 "$QUICKLAUNCH\User Pinned" michael@0: StrCpy $R3 "false" michael@0: michael@0: ; $R9 = main application executable path michael@0: ; $R8 = appid michael@0: ; $R7 = user pinned path michael@0: ; $R6 = find handle michael@0: ; $R5 = found filename michael@0: ; $R4 = GetShortCutTarget result michael@0: michael@0: ; TaskBar links michael@0: FindFirst $R6 $R5 "$R7\TaskBar\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$R7\TaskBar\$R5" michael@0: ShellLink::GetShortCutTarget "$R7\TaskBar\$R5" michael@0: Pop $R4 michael@0: ${If} "$R4" == "$R9" ; link path == install path michael@0: ApplicationID::Set "$R7\TaskBar\$R5" "$R8" michael@0: Pop $R4 ; pop Set result off the stack michael@0: StrCpy $R3 "true" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R6 $R5 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R6 michael@0: michael@0: ; Start menu links michael@0: FindFirst $R6 $R5 "$R7\StartMenu\*.lnk" michael@0: ${Do} michael@0: ${If} ${FileExists} "$R7\StartMenu\$R5" michael@0: ShellLink::GetShortCutTarget "$R7\StartMenu\$R5" michael@0: Pop $R4 michael@0: ${If} "$R4" == "$R9" ; link path == install path michael@0: ApplicationID::Set "$R7\StartMenu\$R5" "$R8" michael@0: Pop $R4 ; pop Set result off the stack michael@0: StrCpy $R3 "true" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ClearErrors michael@0: FindNext $R6 $R5 michael@0: ${If} ${Errors} michael@0: ${ExitDo} michael@0: ${EndIf} michael@0: ${Loop} michael@0: FindClose $R6 michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: michael@0: StrCpy $R9 $R3 michael@0: michael@0: Pop $R2 michael@0: Pop $R3 ; stack: $R4, $R5, $R6, $R7, $R8, $R9 michael@0: Pop $R4 ; stack: $R5, $R6, $R7, $R8, $R9 michael@0: Pop $R5 ; stack: $R6, $R7, $R8, $R9 michael@0: Pop $R6 ; stack: $R7, $R8, $R9 michael@0: Pop $R7 ; stack: $R8, $R9 michael@0: Exch $R8 ; stack: appid, $R9 | $R8 = old $R8 michael@0: Exch 1 ; stack: $R9, appid michael@0: Exch $R9 ; stack: path, appid | $R9 = old $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro UpdateShortcutAppModelIDsCall _EXE_PATH _APP_ID _RESULT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_APP_ID}" michael@0: Push "${_EXE_PATH}" michael@0: Call UpdateShortcutAppModelIDs michael@0: Pop ${_RESULT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro IsUserAdmin michael@0: ; Copied from: http://nsis.sourceforge.net/IsUserAdmin michael@0: Function IsUserAdmin michael@0: Push $R0 michael@0: Push $R1 michael@0: Push $R2 michael@0: michael@0: ClearErrors michael@0: UserInfo::GetName michael@0: IfErrors Win9x michael@0: Pop $R1 michael@0: UserInfo::GetAccountType michael@0: Pop $R2 michael@0: michael@0: StrCmp $R2 "Admin" 0 Continue michael@0: StrCpy $R0 "true" michael@0: Goto Done michael@0: michael@0: Continue: michael@0: michael@0: StrCmp $R2 "" Win9x michael@0: StrCpy $R0 "false" michael@0: Goto Done michael@0: michael@0: Win9x: michael@0: StrCpy $R0 "true" michael@0: michael@0: Done: michael@0: Pop $R2 michael@0: Pop $R1 michael@0: Exch $R0 michael@0: FunctionEnd michael@0: !macroend michael@0: michael@0: /** michael@0: * Retrieve if present or generate and store a 64 bit hash of an install path michael@0: * using the City Hash algorithm. On return the resulting id is saved in the michael@0: * $AppUserModelID variable declared by inserting this macro. InitHashAppModelId michael@0: * will attempt to load from HKLM/_REG_PATH first, then HKCU/_REG_PATH. If found michael@0: * in either it will return the hash it finds. If not found it will generate a michael@0: * new hash and attempt to store the hash in HKLM/_REG_PATH, then HKCU/_REG_PATH. michael@0: * Subsequent calls will then retreive the stored hash value. On any failure, michael@0: * $AppUserModelID will be set to an empty string. michael@0: * michael@0: * Registry format: root/_REG_PATH/"_EXE_PATH" = "hash" michael@0: * michael@0: * @param _EXE_PATH michael@0: * The main application executable path michael@0: * @param _REG_PATH michael@0: * The HKLM/HKCU agnostic registry path where the key hash should michael@0: * be stored. ex: "Software\Mozilla\Firefox\TaskBarIDs" michael@0: * @result (Var) $AppUserModelID contains the app model id. michael@0: */ michael@0: !macro InitHashAppModelId michael@0: !ifndef ${_MOZFUNC_UN}InitHashAppModelId michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !ifndef InitHashAppModelId michael@0: Var AppUserModelID michael@0: !endif michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}InitHashAppModelId "!insertmacro ${_MOZFUNC_UN}InitHashAppModelIdCall" michael@0: michael@0: Function ${_MOZFUNC_UN}InitHashAppModelId michael@0: ; stack: apppath, regpath michael@0: Exch $R9 ; stack: $R9, regpath | $R9 = apppath michael@0: Exch 1 ; stack: regpath, $R9 michael@0: Exch $R8 ; stack: $R8, $R9 | $R8 = regpath michael@0: Push $R7 michael@0: michael@0: ${If} ${AtLeastWin7} michael@0: ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 michael@0: ; Always create a new AppUserModelID and overwrite the existing one michael@0: ; for the current installation path. michael@0: CityHash::GetCityHash64 "$R9" michael@0: Pop $AppUserModelID michael@0: ${If} $AppUserModelID == "error" michael@0: GoTo end michael@0: ${EndIf} michael@0: ClearErrors michael@0: WriteRegStr HKLM "$R8" "$R9" "$AppUserModelID" michael@0: ${If} ${Errors} michael@0: ClearErrors michael@0: WriteRegStr HKCU "$R8" "$R9" "$AppUserModelID" michael@0: ${If} ${Errors} michael@0: StrCpy $AppUserModelID "error" michael@0: ${EndIf} michael@0: ${EndIf} michael@0: ${EndIf} michael@0: michael@0: end: michael@0: ${If} "$AppUserModelID" == "error" michael@0: StrCpy $AppUserModelID "" michael@0: ${EndIf} michael@0: michael@0: ClearErrors michael@0: Pop $R7 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro InitHashAppModelIdCall _EXE_PATH _REG_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_REG_PATH}" michael@0: Push "${_EXE_PATH}" michael@0: Call InitHashAppModelId michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.InitHashAppModelIdCall _EXE_PATH _REG_PATH michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_REG_PATH}" michael@0: Push "${_EXE_PATH}" michael@0: Call un.InitHashAppModelId michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.InitHashAppModelId michael@0: !ifndef un.InitHashAppModelId michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro InitHashAppModelId michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: michael@0: ################################################################################ michael@0: # Helpers for the new user interface michael@0: michael@0: !ifndef MAXDWORD michael@0: !define MAXDWORD 0xffffffff michael@0: !endif michael@0: michael@0: !ifndef DT_WORDBREAK michael@0: !define DT_WORDBREAK 0x0010 michael@0: !endif michael@0: !ifndef DT_SINGLELINE michael@0: !define DT_SINGLELINE 0x0020 michael@0: !endif michael@0: !ifndef DT_NOCLIP michael@0: !define DT_NOCLIP 0x0100 michael@0: !endif michael@0: !ifndef DT_CALCRECT michael@0: !define DT_CALCRECT 0x0400 michael@0: !endif michael@0: !ifndef DT_EDITCONTROL michael@0: !define DT_EDITCONTROL 0x2000 michael@0: !endif michael@0: !ifndef DT_RTLREADING michael@0: !define DT_RTLREADING 0x00020000 michael@0: !endif michael@0: !ifndef DT_NOFULLWIDTHCHARBREAK michael@0: !define DT_NOFULLWIDTHCHARBREAK 0x00080000 michael@0: !endif michael@0: michael@0: !ifndef WS_EX_NOINHERITLAYOUT michael@0: !define WS_EX_NOINHERITLAYOUT 0x00100000 michael@0: !endif michael@0: !ifndef WS_EX_LAYOUTRTL michael@0: !define WS_EX_LAYOUTRTL 0x00400000 michael@0: !endif michael@0: michael@0: !ifndef PBS_MARQUEE michael@0: !define PBS_MARQUEE 0x08 michael@0: !endif michael@0: michael@0: !ifndef PBM_SETRANGE32 michael@0: !define PBM_SETRANGE32 0x406 michael@0: !endif michael@0: !ifndef PBM_GETRANGE michael@0: !define PBM_GETRANGE 0x407 michael@0: !endif michael@0: michael@0: !ifndef SHACF_FILESYSTEM michael@0: !define SHACF_FILESYSTEM 1 michael@0: !endif michael@0: michael@0: !define MOZ_LOADTRANSPARENT ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS} michael@0: michael@0: ; Extend nsDialogs.nsh to support creating centered labels if it is already michael@0: ; included michael@0: !ifmacrodef __NSD_DefineControl michael@0: !insertmacro __NSD_DefineControl LabelCenter michael@0: !define __NSD_LabelCenter_CLASS STATIC michael@0: !define __NSD_LabelCenter_STYLE ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_CENTER} michael@0: !define __NSD_LabelCenter_EXSTYLE ${WS_EX_TRANSPARENT} michael@0: !endif michael@0: michael@0: /** michael@0: * Modified version of the __NSD_SetStretchedImage macro from nsDialogs.nsh that michael@0: * supports transparency. See nsDialogs documentation for additional info. michael@0: */ michael@0: !macro __SetStretchedTransparentImage CONTROL IMAGE HANDLE michael@0: Push $0 michael@0: Push $1 michael@0: Push $2 michael@0: Push $R0 michael@0: michael@0: StrCpy $R0 ${CONTROL} ; in case ${CONTROL} is $0 michael@0: StrCpy $1 "" michael@0: StrCpy $2 "" michael@0: michael@0: System::Call '*(i, i, i, i) i.s' michael@0: Pop $0 michael@0: michael@0: ${If} $0 <> 0 michael@0: System::Call 'user32::GetClientRect(i R0, i r0)' michael@0: System::Call '*$0(i, i, i .s, i .s)' michael@0: System::Free $0 michael@0: Pop $1 michael@0: Pop $2 michael@0: ${EndIf} michael@0: michael@0: System::Call 'user32::LoadImageW(i 0, t s, i ${IMAGE_BITMAP}, i r1, i r2, \ michael@0: i ${MOZ_LOADTRANSPARENT}) i .s' "${IMAGE}" michael@0: Pop $0 michael@0: SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0 michael@0: michael@0: SetCtlColors $R0 "" transparent michael@0: ${NSD_AddExStyle} $R0 ${WS_EX_TRANSPARENT}|${WS_EX_TOPMOST} michael@0: michael@0: Pop $R0 michael@0: Pop $2 michael@0: Pop $1 michael@0: Exch $0 michael@0: Pop ${HANDLE} michael@0: !macroend michael@0: !define SetStretchedTransparentImage `!insertmacro __SetStretchedTransparentImage` michael@0: michael@0: /** michael@0: * Removes a single style from a control. michael@0: * michael@0: * _HANDLE the handle of the control michael@0: * _STYLE the style to remove michael@0: */ michael@0: !macro _RemoveStyle _HANDLE _STYLE michael@0: Push $0 michael@0: michael@0: System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}) i .r0' michael@0: IntOp $0 $0 | ${_STYLE} michael@0: IntOp $0 $0 - ${_STYLE} michael@0: System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_STYLE}, i r0)' michael@0: michael@0: Pop $0 michael@0: !macroend michael@0: !define RemoveStyle "!insertmacro _RemoveStyle" michael@0: michael@0: /** michael@0: * Removes a single extended style from a control. michael@0: * michael@0: * _HANDLE the handle of the control michael@0: * _EXSTYLE the extended style to remove michael@0: */ michael@0: !macro _RemoveExStyle _HANDLE _EXSTYLE michael@0: Push $0 michael@0: michael@0: System::Call 'user32::GetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}) i .r0' michael@0: IntOp $0 $0 | ${_EXSTYLE} michael@0: IntOp $0 $0 - ${_EXSTYLE} michael@0: System::Call 'user32::SetWindowLongW(i ${_HANDLE}, i ${GWL_EXSTYLE}, i r0)' michael@0: michael@0: Pop $0 michael@0: !macroend michael@0: !define RemoveExStyle "!insertmacro _RemoveExStyle" michael@0: michael@0: /** michael@0: * Gets the extent of the specified text in pixels for sizing a control. michael@0: * michael@0: * _TEXT the text to get the text extent for michael@0: * _FONT the font to use when getting the text extent michael@0: * _RES_WIDTH return value - control width for the text michael@0: * _RES_HEIGHT return value - control height for the text michael@0: */ michael@0: !macro GetTextExtentCall _TEXT _FONT _RES_WIDTH _RES_HEIGHT michael@0: Push "${_TEXT}" michael@0: Push "${_FONT}" michael@0: ${CallArtificialFunction} GetTextExtent_ michael@0: Pop ${_RES_WIDTH} michael@0: Pop ${_RES_HEIGHT} michael@0: !macroend michael@0: michael@0: !define GetTextExtent "!insertmacro GetTextExtentCall" michael@0: !define un.GetTextExtent "!insertmacro GetTextExtentCall" michael@0: michael@0: !macro GetTextExtent_ michael@0: Exch $0 ; font michael@0: Exch 1 michael@0: Exch $1 ; text michael@0: Push $2 michael@0: Push $3 michael@0: Push $4 michael@0: Push $5 michael@0: Push $6 michael@0: Push $7 michael@0: michael@0: ; Reuse the existing NSIS control which is used for BrandingText instead of michael@0: ; creating a new control. michael@0: GetDlgItem $2 $HWNDPARENT 1028 michael@0: michael@0: System::Call 'user32::GetDC(i r2) i .r3' michael@0: System::Call 'gdi32::SelectObject(i r3, i r0)' michael@0: michael@0: StrLen $4 "$1" michael@0: michael@0: System::Call '*(i, i) i .r5' michael@0: System::Call 'gdi32::GetTextExtentPoint32W(i r3, t$\"$1$\", i r4, i r5)' michael@0: System::Call '*$5(i .r6, i .r7)' michael@0: System::Free $5 michael@0: michael@0: System::Call 'user32::ReleaseDC(i r2, i r3)' michael@0: michael@0: StrCpy $1 $7 michael@0: StrCpy $0 $6 michael@0: michael@0: Pop $7 michael@0: Pop $6 michael@0: Pop $5 michael@0: Pop $4 michael@0: Pop $3 michael@0: Pop $2 michael@0: Exch $1 ; return height michael@0: Exch 1 michael@0: Exch $0 ; return width michael@0: !macroend michael@0: michael@0: /** michael@0: * Gets the width and the height of a control in pixels. michael@0: * michael@0: * _HANDLE the handle of the control michael@0: * _RES_WIDTH return value - control width for the text michael@0: * _RES_HEIGHT return value - control height for the text michael@0: */ michael@0: !macro GetDlgItemWidthHeightCall _HANDLE _RES_WIDTH _RES_HEIGHT michael@0: Push "${_HANDLE}" michael@0: ${CallArtificialFunction} GetDlgItemWidthHeight_ michael@0: Pop ${_RES_WIDTH} michael@0: Pop ${_RES_HEIGHT} michael@0: !macroend michael@0: michael@0: !define GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall" michael@0: !define un.GetDlgItemWidthHeight "!insertmacro GetDlgItemWidthHeightCall" michael@0: michael@0: !macro GetDlgItemWidthHeight_ michael@0: Exch $0 ; handle for the control michael@0: Push $1 michael@0: Push $2 michael@0: michael@0: System::Call '*(i, i, i, i) i .r2' michael@0: ; The left and top values will always be 0 so the right and bottom values michael@0: ; will be the width and height. michael@0: System::Call 'user32::GetClientRect(i r0, i r2)' michael@0: System::Call '*$2(i, i, i .r0, i .r1)' michael@0: System::Free $2 michael@0: michael@0: Pop $2 michael@0: Exch $1 ; return height michael@0: Exch 1 michael@0: Exch $0 ; return width michael@0: !macroend michael@0: michael@0: /** michael@0: * Gets the number of pixels from the beginning of the dialog to the end of a michael@0: * control in a RTL friendly manner. michael@0: * michael@0: * _HANDLE the handle of the control michael@0: * _RES_PX return value - pixels from the beginning of the dialog to the end of michael@0: * the control michael@0: */ michael@0: !macro GetDlgItemEndPXCall _HANDLE _RES_PX michael@0: Push "${_HANDLE}" michael@0: ${CallArtificialFunction} GetDlgItemEndPX_ michael@0: Pop ${_RES_PX} michael@0: !macroend michael@0: michael@0: !define GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall" michael@0: !define un.GetDlgItemEndPX "!insertmacro GetDlgItemEndPXCall" michael@0: michael@0: !macro GetDlgItemEndPX_ michael@0: Exch $0 ; handle of the control michael@0: Push $1 michael@0: Push $2 michael@0: michael@0: ; #32770 is the dialog class michael@0: FindWindow $1 "#32770" "" $HWNDPARENT michael@0: System::Call '*(i, i, i, i) i .r2' michael@0: System::Call 'user32::GetWindowRect(i r0, i r2)' michael@0: System::Call 'user32::MapWindowPoints(i 0, i r1,i r2, i 2)' michael@0: System::Call '*$2(i, i, i .r0, i)' michael@0: System::Free $2 michael@0: michael@0: Pop $2 michael@0: Pop $1 michael@0: Exch $0 ; pixels from the beginning of the dialog to the end of the control michael@0: !macroend michael@0: michael@0: /** michael@0: * Gets the width and height for sizing a control that has the specified text. michael@0: * If the text has embedded newlines then the width and height will be michael@0: * determined without trying to optimize the control's width and height. If the michael@0: * text doesn't contain newlines the control's height and width will be michael@0: * dynamically determined using a minimum of 3 lines (incrementing the michael@0: * number of lines if necessary) for the height and the maximum width specified. michael@0: * michael@0: * _TEXT the text michael@0: * _FONT the font to use when getting the width and height michael@0: * _MAX_WIDTH the maximum width for the control michael@0: * _RES_WIDTH return value - control width for the text michael@0: * _RES_HEIGHT return value - control height for the text michael@0: */ michael@0: !macro GetTextWidthHeight michael@0: michael@0: !ifndef ${_MOZFUNC_UN}GetTextWidthHeight michael@0: !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} michael@0: !insertmacro ${_MOZFUNC_UN_TMP}WordFind michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} michael@0: !undef _MOZFUNC_UN_TMP michael@0: michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !define ${_MOZFUNC_UN}GetTextWidthHeight "!insertmacro ${_MOZFUNC_UN}GetTextWidthHeightCall" michael@0: michael@0: Function ${_MOZFUNC_UN}GetTextWidthHeight michael@0: Exch $0 ; maximum width use to calculate the control's width and height michael@0: Exch 1 michael@0: Exch $1 ; font michael@0: Exch 2 michael@0: Exch $2 ; text michael@0: Push $3 michael@0: Push $4 michael@0: Push $5 michael@0: Push $6 michael@0: Push $7 michael@0: Push $8 michael@0: Push $9 michael@0: Push $R0 michael@0: Push $R1 michael@0: Push $R2 michael@0: michael@0: StrCpy $R2 "${DT_NOCLIP}|${DT_CALCRECT}" michael@0: !ifdef ${AB_CD}_rtl michael@0: StrCpy $R2 "$R2|${DT_RTLREADING}" michael@0: !endif michael@0: michael@0: ; Reuse the existing NSIS control which is used for BrandingText instead michael@0: ; of creating a new control. michael@0: GetDlgItem $3 $HWNDPARENT 1028 michael@0: michael@0: System::Call 'user32::GetDC(i r3) i .r4' michael@0: System::Call 'gdi32::SelectObject(i r4, i r1)' michael@0: michael@0: StrLen $5 "$2" ; text length michael@0: System::Call '*(i, i, i, i) i .r6' michael@0: michael@0: ClearErrors michael@0: ${${_MOZFUNC_UN}WordFind} "$2" "$\n" "E#" $R0 michael@0: ${If} ${Errors} michael@0: ; When there aren't newlines in the text calculate the size of the michael@0: ; rectangle needed for the text with a minimum of three lines of text. michael@0: ClearErrors michael@0: System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, \ michael@0: i $R2|${DT_SINGLELINE})' michael@0: System::Call '*$6(i, i, i .r8, i .r7)' michael@0: System::Free $6 michael@0: michael@0: ; Get the approximate number height needed to display the text starting michael@0: ; with a minimum of 3 lines of text. michael@0: StrCpy $9 $8 michael@0: StrCpy $R1 2 ; set the number of lines initially to 2 michael@0: ${Do} michael@0: IntOp $R1 $R1 + 1 ; increment the number of lines michael@0: IntOp $9 $8 / $R1 michael@0: ${LoopUntil} $9 < $0 michael@0: IntOp $7 $7 * $R1 michael@0: michael@0: StrCpy $R0 $9 michael@0: ${Do} michael@0: IntOp $R0 $R0 + 20 michael@0: System::Call '*(i, i, i R0, i r7) i .r6' michael@0: System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, \ michael@0: i $R2|${DT_WORDBREAK}) i .R1' michael@0: System::Call '*$6(i, i, i .r8, i .r9)' michael@0: System::Free $6 michael@0: ${LoopUntil} $7 >= $R1 michael@0: ${Else} michael@0: ; When there are newlines in the text just return the size of the michael@0: ; rectangle for the text. michael@0: System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, i $R2)' michael@0: System::Call '*$6(i, i, i .r8, i .r9)' michael@0: System::Free $6 michael@0: ${EndIf} michael@0: michael@0: ; Reselect the original DC michael@0: System::Call 'gdi32::SelectObject(i r4, i r1)' michael@0: System::Call 'user32::ReleaseDC(i r3, i r4)' michael@0: michael@0: StrCpy $1 $9 michael@0: StrCpy $0 $8 michael@0: michael@0: Pop $R2 michael@0: Pop $R1 michael@0: Pop $R0 michael@0: Pop $9 michael@0: Pop $8 michael@0: Pop $7 michael@0: Pop $6 michael@0: Pop $5 michael@0: Pop $4 michael@0: Pop $3 michael@0: Exch $2 michael@0: Exch 2 michael@0: Exch $1 ; return height michael@0: Exch 1 michael@0: Exch $0 ; return width michael@0: FunctionEnd michael@0: michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: !macro GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_TEXT}" michael@0: Push "${_FONT}" michael@0: Push "${_MAX_WIDTH}" michael@0: Call GetTextWidthHeight michael@0: Pop ${_RES_WIDTH} michael@0: Pop ${_RES_HEIGHT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetTextWidthHeightCall _TEXT _FONT _MAX_WIDTH _RES_WIDTH _RES_HEIGHT michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: Push "${_TEXT}" michael@0: Push "${_FONT}" michael@0: Push "${_MAX_WIDTH}" michael@0: Call un.GetTextWidthHeight michael@0: Pop ${_RES_WIDTH} michael@0: Pop ${_RES_HEIGHT} michael@0: !verbose pop michael@0: !macroend michael@0: michael@0: !macro un.GetTextWidthHeight michael@0: !ifndef un.GetTextWidthHeight michael@0: !verbose push michael@0: !verbose ${_MOZFUNC_VERBOSE} michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN "un." michael@0: michael@0: !insertmacro GetTextWidthHeight michael@0: michael@0: !undef _MOZFUNC_UN michael@0: !define _MOZFUNC_UN michael@0: !verbose pop michael@0: !endif michael@0: !macroend michael@0: michael@0: /** michael@0: * Gets the elapsed time in seconds between two values in milliseconds stored as michael@0: * an int64. The caller will typically get the millisecond values using michael@0: * GetTickCount with a long return value as follows. michael@0: * System::Call "kernel32::GetTickCount()l .s" michael@0: * Pop $varname michael@0: * michael@0: * _START_TICK_COUNT michael@0: * _FINISH_TICK_COUNT michael@0: * _RES_ELAPSED_SECONDS return value - elapsed time between _START_TICK_COUNT michael@0: * and _FINISH_TICK_COUNT in seconds. michael@0: */ michael@0: !macro GetSecondsElapsedCall _START_TICK_COUNT _FINISH_TICK_COUNT _RES_ELAPSED_SECONDS michael@0: Push "${_START_TICK_COUNT}" michael@0: Push "${_FINISH_TICK_COUNT}" michael@0: ${CallArtificialFunction} GetSecondsElapsed_ michael@0: Pop ${_RES_ELAPSED_SECONDS} michael@0: !macroend michael@0: michael@0: !define GetSecondsElapsed "!insertmacro GetSecondsElapsedCall" michael@0: !define un.GetSecondsElapsed "!insertmacro GetSecondsElapsedCall" michael@0: michael@0: !macro GetSecondsElapsed_ michael@0: Exch $0 ; finish tick count michael@0: Exch 1 michael@0: Exch $1 ; start tick count michael@0: michael@0: System::Int64Op $0 - $1 michael@0: Pop $0 michael@0: ; Discard the top bits of the int64 by bitmasking with MAXDWORD michael@0: System::Int64Op $0 & ${MAXDWORD} michael@0: Pop $0 michael@0: michael@0: ; Convert from milliseconds to seconds michael@0: System::Int64Op $0 / 1000 michael@0: Pop $0 michael@0: michael@0: Pop $1 michael@0: Exch $0 ; return elapsed seconds michael@0: !macroend michael@0: michael@0: !ifdef MOZ_METRO michael@0: ; Removes the CEH registration if it's set to our installation directory. michael@0: ; If it's set to some other installation directory, then it should be removed michael@0: ; by that installation. michael@0: !macro RemoveDEHRegistrationIfMatchingCall un michael@0: michael@0: Function ${un}RemoveDEHRegistrationIfMatchingCall michael@0: ; Retrieve DEH ID from the stack into $R9 michael@0: Exch $R9 michael@0: Exch 1 michael@0: michael@0: ; Retrieve Protocol Activation ID from stack into $R8 michael@0: Exch $R8 michael@0: Exch 2 michael@0: michael@0: ; Retrieve File Activation ID from stack into $R7 michael@0: Exch $R7 michael@0: michael@0: ; Backup the old values of R6 and R5 on the stack michael@0: Push $R6 michael@0: Push $R5 michael@0: michael@0: ; Conditionally remove the DEH as long as we are the default (HKCU) michael@0: ReadRegStr $R6 HKCU "Software\Classes\CLSID\$R9\LocalServer32" "" michael@0: ${${un}GetLongPath} "$INSTDIR" $R5 michael@0: StrCmp "$R6" "" next +1 michael@0: IfFileExists "$R6" +1 clearHKCU michael@0: ${${un}GetParent} "$R6" $R6 michael@0: ${${un}GetLongPath} "$R6" $R6 michael@0: StrCmp "$R5" "$R6" clearHKCU next michael@0: clearHKCU: michael@0: DeleteRegKey HKCU "Software\Classes\CLSID\$R9" michael@0: DeleteRegValue HKCU "Software\Classes\$R8\shell\open\command" "DelegateExecute" michael@0: DeleteRegValue HKCU "Software\Classes\$R7\shell\open\command" "DelegateExecute" michael@0: next: michael@0: michael@0: ; Conditionally remove the DEH as long as we are the default (HKLM) michael@0: ReadRegStr $R6 HKLM "Software\Classes\CLSID\$R9\LocalServer32" "" michael@0: ${${un}GetLongPath} "$INSTDIR" $R5 michael@0: StrCmp "$R6" "" done +1 michael@0: IfFileExists "$R6" +1 clearHKLM michael@0: ${${un}GetParent} "$R6" $R6 michael@0: ${${un}GetLongPath} "$R6" $R6 michael@0: StrCmp "$R5" "$R6" clearHKLM done michael@0: clearHKLM: michael@0: DeleteRegKey HKLM "Software\Classes\CLSID\$R9" michael@0: DeleteRegValue HKLM "Software\Classes\$R8\shell\open\command" "DelegateExecute" michael@0: DeleteRegValue HKLM "Software\Classes\$R7\shell\open\command" "DelegateExecute" michael@0: done: michael@0: michael@0: ; Always remove the AppUserModelID keys for this installation michael@0: DeleteRegKey HKCU "Software\Classes\$AppUserModelID" michael@0: DeleteRegKey HKLM "Software\Classes\$AppUserModelID" michael@0: michael@0: ; Restore the registers back to their original state michael@0: Pop $R5 michael@0: Pop $R6 michael@0: Exch $R7 michael@0: Exch 2 michael@0: Exch $R8 michael@0: Exch 1 michael@0: Exch $R9 michael@0: FunctionEnd michael@0: !macroend michael@0: michael@0: !macro RemoveDEHRegistrationIfMatching michael@0: !insertmacro RemoveDEHRegistrationIfMatchingCall "" michael@0: !macroend michael@0: michael@0: !macro un.RemoveDEHRegistrationIfMatching michael@0: !insertmacro RemoveDEHRegistrationIfMatchingCall "un." michael@0: !macroend michael@0: michael@0: !macro CleanupMetroBrowserHandlerValues un DELEGATE_EXECUTE_HANDLER_ID \ michael@0: PROTOCOL_ACTIVATION_ID \ michael@0: FILE_ACTIVATION_ID michael@0: Push ${FILE_ACTIVATION_ID} michael@0: Push ${PROTOCOL_ACTIVATION_ID} michael@0: Push ${DELEGATE_EXECUTE_HANDLER_ID} michael@0: Call ${un}RemoveDEHRegistrationIfMatchingCall michael@0: !macroend michael@0: !define CleanupMetroBrowserHandlerValues '!insertmacro CleanupMetroBrowserHandlerValues ""' michael@0: !define un.CleanupMetroBrowserHandlerValues '!insertmacro CleanupMetroBrowserHandlerValues "un."' michael@0: michael@0: !macro AddMetroBrowserHandlerValues DELEGATE_EXECUTE_HANDLER_ID \ michael@0: DELEGATE_EXECUTE_HANDLER_PATH \ michael@0: APP_USER_MODEL_ID \ michael@0: PROTOCOL_ACTIVATION_ID \ michael@0: FILE_ACTIVATION_ID michael@0: ; Win8 doesn't use conventional progid command data to launch anymore. michael@0: ; Instead it uses a delegate execute handler which is a light weight COM michael@0: ; server for choosing the metro or desktop browser to launch depending michael@0: ; on the current environment (metro/desktop) it was activated in. michael@0: WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}" "" "" michael@0: WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe" "" "" michael@0: WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell" "" "open" michael@0: WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell\open" "CommandId" "open" michael@0: WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell\open\command" "" "$2" michael@0: WriteRegStr SHCTX "Software\Classes\${APP_USER_MODEL_ID}\.exe\shell\open\command" "DelegateExecute" "${DELEGATE_EXECUTE_HANDLER_ID}" michael@0: michael@0: ; Augment the url handler registrations with additional data needed for Metro michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}" "AppUserModelID" "${APP_USER_MODEL_ID}" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "AppUserModelID" "${APP_USER_MODEL_ID}" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationName" "$BrandShortName" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationIcon" "$INSTDIR\${FileMainEXE},0" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationCompany" "${CompanyName}" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\Application" "ApplicationDescription" "$(REG_APP_DESC)" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\shell" "" "open" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\shell\open" "CommandId" "open" michael@0: WriteRegStr SHCTX "Software\Classes\${PROTOCOL_ACTIVATION_ID}\shell\open\command" "DelegateExecute" "${DELEGATE_EXECUTE_HANDLER_ID}" michael@0: michael@0: ; Augment the file handler registrations with additional data needed for Metro michael@0: WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}" "AppUserModelID" "${APP_USER_MODEL_ID}" michael@0: WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}\shell" "" "open" michael@0: WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}\shell\open" "CommandId" "open" michael@0: WriteRegStr SHCTX "Software\Classes\${FILE_ACTIVATION_ID}\shell\open\command" "DelegateExecute" "${DELEGATE_EXECUTE_HANDLER_ID}" michael@0: michael@0: ; Win8 Metro delegate execute handler registration michael@0: WriteRegStr SHCTX "Software\Classes\CLSID\${DELEGATE_EXECUTE_HANDLER_ID}" "" "$BrandShortName CommandExecuteHandler" michael@0: WriteRegStr SHCTX "Software\Classes\CLSID\${DELEGATE_EXECUTE_HANDLER_ID}" "AppId" "${DELEGATE_EXECUTE_HANDLER_ID}" michael@0: WriteRegStr SHCTX "Software\Classes\CLSID\${DELEGATE_EXECUTE_HANDLER_ID}\LocalServer32" "" "${DELEGATE_EXECUTE_HANDLER_PATH}" michael@0: !macroend michael@0: !define AddMetroBrowserHandlerValues "!insertmacro AddMetroBrowserHandlerValues" michael@0: !endif ;end MOZ_METRO michael@0: