Bug 470182 - (Win32 only) Create separate log file for shortcuts. r=jmathies
authorRobert Strong <robert.bugzilla@gmail.com>
Mon, 12 Jan 2009 22:17:49 -0800
changeset 23583 db430def4ce64c30173d27b77bf1c2cb0621e3b9
parent 23582 98b0d2b220c7e4aec238c1b63688bc022e854118
child 23584 efc8e32bfe59015539b551762db6f32a44ae7af2
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs470182
milestone1.9.2a1pre
Bug 470182 - (Win32 only) Create separate log file for shortcuts. r=jmathies
browser/installer/windows/nsis/installer.nsi
browser/installer/windows/nsis/shared.nsh
browser/installer/windows/nsis/uninstaller.nsi
toolkit/mozapps/installer/windows/nsis/common.nsh
toolkit/mozapps/installer/windows/nsis/overrides.nsh
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -47,25 +47,16 @@
 SetDatablockOptimize on
 SetCompress off
 CRCCheck on
 
 RequestExecutionLevel user
 
 !addplugindir ./
 
-; empty files - except for the comment line - for generating custom pages.
-!system 'echo ; > options.ini'
-!system 'echo ; > shortcuts.ini'
-!system 'echo ; > summary.ini'
-
-; USE_UAC_PLUGIN is temporary until all applications have been updated to use
-; the UAC plugin
-!define USE_UAC_PLUGIN
-
 Var TmpVal
 Var StartMenuDir
 Var InstallType
 Var AddStartMenuSC
 Var AddQuickLaunchSC
 Var AddDesktopSC
 
 ; Other included files may depend upon these includes!
@@ -91,22 +82,26 @@ Var AddDesktopSC
 !include version.nsh
 
 VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
 VIAddVersionKey "OriginalFilename" "setup.exe"
 
 ; Must be inserted before other macros that use logging
 !insertmacro _LoggingCommon
 
+; Most commonly used macros for managing shortcuts
+!insertmacro _LoggingShortcutsCommon
+
 !insertmacro AddDDEHandlerValues
 !insertmacro ChangeMUIHeaderImage
 !insertmacro CheckForFilesInUse
 !insertmacro CleanUpdatesDir
 !insertmacro CopyFilesFromDir
 !insertmacro CreateRegKey
+!insertmacro FindSMProgramsDir
 !insertmacro GetPathFromString
 !insertmacro GetParent
 !insertmacro IsHandlerForInstallDir
 !insertmacro ManualCloseAppPrompt
 !insertmacro RegCleanAppHandler
 !insertmacro RegCleanMain
 !insertmacro RegCleanUninstall
 !insertmacro SetBrandNameVars
@@ -126,20 +121,16 @@ VIAddVersionKey "OriginalFilename" "setu
 !insertmacro PreDirectoryCommon
 
 Name "${BrandFullName}"
 OutFile "setup.exe"
 InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
 InstallDir "$PROGRAMFILES\${BrandFullName}\"
 ShowInstDetails nevershow
 
-ReserveFile options.ini
-ReserveFile shortcuts.ini
-ReserveFile summary.ini
-
 ################################################################################
 # Modern User Interface - MUI
 
 !define MUI_ABORTWARNING
 !define MUI_ICON setup.ico
 !define MUI_UNICON setup.ico
 !define MUI_WELCOMEPAGE_TITLE_3LINES
 !define MUI_HEADERIMAGE
@@ -171,19 +162,16 @@ Page custom preOptions leaveOptions
 
 ; Custom Shortcuts Page
 Page custom preShortcuts leaveShortcuts
 
 ; Start Menu Folder Page Configuration
 !define MUI_PAGE_CUSTOMFUNCTION_PRE preStartMenu
 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE leaveStartMenu
 !define MUI_STARTMENUPAGE_NODISABLE
-!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
-!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
-!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
 !insertmacro MUI_PAGE_STARTMENU Application $StartMenuDir
 
 ; Custom Summary Page
 Page custom preSummary leaveSummary
 
 ; Install Files Page
 !insertmacro MUI_PAGE_INSTFILES
 
@@ -250,17 +238,17 @@ Section "-Application" APP_IDX
   RegDLL "$INSTDIR\AccessibleMarshal.dll"
   ${If} ${Errors}
     ${LogMsg} "** ERROR Registering: $INSTDIR\AccessibleMarshal.dll **"
   ${Else}
     ${LogUninstall} "DLLReg: \AccessibleMarshal.dll"
     ${LogMsg} "Registered: $INSTDIR\AccessibleMarshal.dll"
   ${EndIf}
 
-  ; Write extra files created by the application to the uninstall.log so they
+  ; Write extra files created by the application to the uninstall log so they
   ; will be removed when the application is uninstalled. To remove an empty
   ; directory write a bogus filename to the deepest directory and all empty
   ; parent directories will be removed.
   ${LogUninstall} "File: \components\compreg.dat"
   ${LogUninstall} "File: \components\xpti.dat"
   ${LogUninstall} "File: \.autoreg"
   ${LogUninstall} "File: \active-update.xml"
   ${LogUninstall} "File: \install.log"
@@ -348,21 +336,16 @@ Section "-Application" APP_IDX
 
   ; The order that reg keys and values are added is important if you use the
   ; uninstall log to remove them on uninstall. When using the uninstall log you
   ; MUST add children first so they will be removed first on uninstall so they
   ; will be empty when the key is deleted. This allows the uninstaller to
   ; specify that only empty keys will be deleted.
   ${SetAppKeys}
 
-  ; XXXrstrong - this should be set in shared.nsh along with "Create Quick
-  ; Launch Shortcut" and Create Desktop Shortcut.
-  StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
-  ${WriteRegDWORD2} $TmpVal "$0" "Create Start Menu Shortcut" $AddStartMenuSC 0
-
   ${FixClassKeys}
 
   ; On install always add the FirefoxHTML and FirefoxURL keys.
   ; An empty string is used for the 5th param because FirefoxHTML and FirefoxURL
   ; are not protocol handlers.
   ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
   StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
   StrCpy $3 "$\"%1$\",,0,0,,,,"
@@ -401,41 +384,47 @@ Section "-Application" APP_IDX
   ${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0
   ${WriteRegStr2} $TmpVal "$0" "Path" "$INSTDIR" 0
 
   StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9"
   ${CreateRegKey} "$TmpVal" "$0" 0
 
   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
 
-  ; Create Start Menu shortcuts
+  ; Create shortcuts
   ${LogHeader} "Adding Shortcuts"
+
+  ; Always add the relative path to the application's Start Menu directory and
+  ; the application's shortcuts to the shortcuts log ini file. The
+  ; DeleteShortcuts macro will do the right thing on uninstall if they don't
+  ; exist.
+  ${LogSMProgramsDirRelPath} "$StartMenuDir"
+  ${LogSMProgramsShortcut} "${BrandFullName}.lnk"
+  ${LogSMProgramsShortcut} "${BrandFullName} ($(SAFE_MODE)).lnk"
+  ${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
+  ${LogDesktopShortcut} "${BrandFullName}.lnk"
+
   ${If} $AddStartMenuSC == 1
     ${Unless} ${FileExists} "$SMPROGRAMS\$StartMenuDir"
       CreateDirectory "$SMPROGRAMS\$StartMenuDir"
       ${LogMsg} "Added Start Menu Directory: $SMPROGRAMS\$StartMenuDir"
     ${EndUnless}
-    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal}.lnk"
-    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal}.lnk"
-    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal} ($(SAFE_MODE)).lnk" "$INSTDIR\${FileMainEXE}" "-safe-mode" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal} ($(SAFE_MODE)).lnk"
-    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullNameInternal} ($(SAFE_MODE)).lnk"
+    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
+    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk"
+    CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk" "$INSTDIR\${FileMainEXE}" "-safe-mode" "$INSTDIR\${FileMainEXE}" 0
+    ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk"
   ${EndIf}
 
-  ; perhaps use the uninstall keys
   ${If} $AddQuickLaunchSC == 1
     CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $QUICKLAUNCH\${BrandFullName}.lnk"
     ${LogMsg} "Added Shortcut: $QUICKLAUNCH\${BrandFullName}.lnk"
   ${EndIf}
 
   ${If} $AddDesktopSC == 1
     CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
-    ${LogUninstall} "File: $DESKTOP\${BrandFullName}.lnk"
     ${LogMsg} "Added Shortcut: $DESKTOP\${BrandFullName}.lnk"
   ${EndIf}
 
   !insertmacro MUI_STARTMENU_WRITE_END
 SectionEnd
 
 ; Cleanup operations to perform at the end of the installation.
 Section "-InstallEndCleanup"
@@ -643,16 +632,42 @@ Function leaveShortcuts
     Abort
   ${EndIf}
   ${MUI_INSTALLOPTIONS_READ} $AddDesktopSC "shortcuts.ini" "Field 2" "State"
   ${MUI_INSTALLOPTIONS_READ} $AddStartMenuSC "shortcuts.ini" "Field 3" "State"
   ${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State"
 FunctionEnd
 
 Function preStartMenu
+  ; With the Unicode installer the path to the application's Start Menu
+  ; directory relative to the Start Menu's Programs directory is written to the
+  ; shortcuts log ini file and is used to set the default Start Menu directory.
+  ${GetSMProgramsDirRelPath} $0
+  ${If} "$0" != ""
+    StrCpy $StartMenuDir "$0"
+  ${Else}
+    ; Prior to the Unicode installer the path to the application's Start Menu
+    ; directory relative to the Start Menu's Programs directory was written to
+    ; the registry and use this value to set the default Start Menu directory.
+    ClearErrors
+    ReadRegStr $0 HKLM "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main" "Start Menu Folder"
+    ${If} ${Errors}
+      ; Use the FindSMProgramsDir macro to find a previously used path to the
+      ; application's Start Menu directory relative to the Start Menu's Programs
+      ; directory in the uninstall log and use this value to set the default
+      ; Start Menu directory.
+      ${FindSMProgramsDir} $0
+      ${If} "$0" != ""
+        StrCpy $StartMenuDir "$0"
+      ${EndIf}
+    ${Else}
+      StrCpy $StartMenuDir "$0"
+    ${EndUnless}
+  ${EndIf}
+
   ${CheckCustomCommon}
   ${If} $AddStartMenuSC != 1
     Abort
   ${EndIf}
 FunctionEnd
 
 Function leaveStartMenu
   ${If} $InstallType == ${INSTALLTYPE_CUSTOM}
@@ -757,19 +772,19 @@ FunctionEnd
 # Initialization Functions
 
 Function .onInit
   StrCpy $LANGUAGE 0
   ${SetBrandNameVars} "$EXEDIR\localized\distribution\setup.ini"
 
   ${InstallOnInitCommon} "$(WARN_MIN_SUPPORTED_OS_MSG)"
 
-  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "options.ini"
-  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "shortcuts.ini"
-  !insertmacro MUI_INSTALLOPTIONS_EXTRACT "summary.ini"
+  !insertmacro InitInstallOptionsFile "options.ini"
+  !insertmacro InitInstallOptionsFile "shortcuts.ini"
+  !insertmacro InitInstallOptionsFile "summary.ini"
 
   ; Setup the options.ini file for the Custom Options Page
   WriteINIStr "$PLUGINSDIR\options.ini" "Settings" NumFields "6"
 
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Type   "label"
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Text   "$(OPTIONS_SUMMARY)"
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Left   "0"
   WriteINIStr "$PLUGINSDIR\options.ini" "Field 1" Right  "-1"
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -30,16 +30,18 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 !macro PostUpdate
+  ${CreateShortcutsLog}
+
   ; Remove registry entries for non-existent apps and for apps that point to our
   ; install location in the Software\Mozilla key and uninstall registry entries
   ; that point to our install location for both HKCU and HKLM.
   SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   ${RegCleanMain} "Software\Mozilla"
   ${RegCleanUninstall}
   ${UpdateProtocolHandlers}
 
@@ -348,61 +350,16 @@
 
 !macro SetAppKeys
   ${GetLongPath} "$INSTDIR" $8
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
   ${WriteRegStr2} $TmpVal "$0" "Install Directory" "$8" 0
   ${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0
   ${WriteRegStr2} $TmpVal "$0" "Program Folder Path" "$SMPROGRAMS\$StartMenuDir" 0
 
-  SetShellVarContext all  ; Set $DESKTOP to All Users
-  ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
-    SetShellVarContext current  ; Set $DESKTOP to the current user's desktop
-  ${EndUnless}
-
-  ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
-    ShellLink::GetShortCutArgs "$DESKTOP\${BrandFullName}.lnk"
-    Pop $1
-    ${If} "$1" == ""
-      ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
-      Pop $1
-      ${GetLongPath} "$1" $1
-      ${If} "$1" == "$8\${FileMainEXE}"
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" 1 0
-      ${Else}
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" 0 0
-      ${EndIf}
-    ${EndIf}
-  ${EndIf}
-
-  ; XXXrstrong - need a cleaner way to prevent unsetting SHCTX from HKLM when
-  ; trying to find the desktop shortcut.
-  ${If} "$TmpVal" == "HKCU"
-    SetShellVarContext current ; Set SHCTX to the current user (e.g. HKCU)
-  ${Else}
-    SetShellVarContext all     ; Set SHCTX to all users (e.g. HKLM)
-  ${EndIf}
-
-  ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
-    ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk"
-    Pop $1
-    ${If} "$1" == ""
-      ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk"
-      Pop $1
-      ${GetLongPath} "$1" $1
-      ${If} "$1" == "$8\${FileMainEXE}"
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" 1 0
-      ${Else}
-        ${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" 0 0
-      ${EndIf}
-    ${EndIf}
-  ${EndIf}
-  ; XXXrstrong - "Create Start Menu Shortcut" and "Start Menu Folder" are only
-  ; set in the installer and should also be set here for software update.
-
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
   ${WriteRegStr2} $TmpVal "$0" "Uninstall Log Folder" "$8\uninstall" 0
   ${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} (${AppVersion})" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})"
   ${WriteRegStr2} $TmpVal  "$0" "" "${AppVersion} (${AB_CD})" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\bin"
@@ -544,16 +501,45 @@
   StrCpy $0 "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\gopher"
   ReadRegStr $2 HKCU "$0\UserChoice" "Progid"
   ${If} "$2" == "FirefoxURL"
     DeleteRegKey HKCU "$0"
   ${EndIf}
 !macroend
 !define RemoveDeprecatedKeys "!insertmacro RemoveDeprecatedKeys"
 
+; Creates the shortcuts log ini file with the appropriate entries if it doesn't
+; already exist.
+!macro CreateShortcutsLog
+  ${GetShortcutsLogPath} $0
+  ${Unless} ${FileExists} "$0"
+    ; Default to ${BrandFullName} for the Start Menu Folder
+    StrCpy $TmpVal ${BrandFullName}
+    ; Prior to Firefox 3.1 the Start Menu directory was written to the registry and
+    ; this value can be used to set the Start Menu directory.
+    ClearErrors
+    ReadRegStr $0 SHCTX "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main" "Start Menu Folder"
+    ${If} ${Errors}
+      ${FindSMProgramsDir} $0
+      ${If} "$0" != ""
+        StrCpy $TmpVal "$0"
+      ${EndIf}
+    ${Else}
+      StrCpy $TmpVal "$0"
+    ${EndUnless}
+
+    ${LogSMProgramsDirRelPath} "$TmpVal"
+    ${LogSMProgramsShortcut} "${BrandFullName}.lnk"
+    ${LogSMProgramsShortcut} "${BrandFullName} ($(SAFE_MODE)).lnk"
+    ${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
+    ${LogDesktopShortcut} "${BrandFullName}.lnk"
+  ${EndUnless}
+!macroend
+!define CreateShortcutsLog "!insertmacro CreateShortcutsLog"
+
 ; The files to check if they are in use during (un)install so the restart is
 ; required message is displayed. All files must be located in the $INSTDIR
 ; directory.
 !macro PushFilesToCheck
   ; The first string to be pushed onto the stack MUST be "end" to indicate
   ; that there are no more files to check in $INSTDIR and the last string
   ; should be ${FileMainEXE} so if it is in use the CheckForFilesInUse macro
   ; returns after the first check.
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -47,20 +47,16 @@
 SetDatablockOptimize on
 SetCompress off
 CRCCheck on
 
 RequestExecutionLevel user
 
 !addplugindir ./
 
-; USE_UAC_PLUGIN is temporary until all applications have been updated to use
-; the UAC plugin
-!define USE_UAC_PLUGIN
-
 ; prevents compiling of the reg write logging.
 !define NO_LOG
 
 Var TmpVal
 
 ; Other included files may depend upon these includes!
 ; The following includes are provided by NSIS.
 !include FileFunc.nsh
@@ -82,34 +78,39 @@ Var TmpVal
 !include locales.nsi
 !include version.nsh
 
 ; This is named BrandShortName helper because we use this for software update
 ; post update cleanup.
 VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
 VIAddVersionKey "OriginalFilename" "helper.exe"
 
+; Most commonly used macros for managing shortcuts
+!insertmacro _LoggingShortcutsCommon
+
 !insertmacro AddDDEHandlerValues
 !insertmacro CleanVirtualStore
+!insertmacro FindSMProgramsDir
 !insertmacro GetLongPath
 !insertmacro GetPathFromString
 !insertmacro IsHandlerForInstallDir
 !insertmacro RegCleanAppHandler
 !insertmacro RegCleanMain
 !insertmacro RegCleanUninstall
 !insertmacro SetBrandNameVars
 !insertmacro UnloadUAC
 !insertmacro WriteRegDWORD2
 !insertmacro WriteRegStr2
 
 !insertmacro un.ChangeMUIHeaderImage
 !insertmacro un.CheckForFilesInUse
 !insertmacro un.CleanUpdatesDir
 !insertmacro un.CleanVirtualStore
 !insertmacro un.DeleteRelativeProfiles
+!insertmacro un.DeleteShortcuts
 !insertmacro un.GetLongPath
 !insertmacro un.GetSecondInstallPath
 !insertmacro un.ManualCloseAppPrompt
 !insertmacro un.ParseUninstallLog
 !insertmacro un.RegCleanAppHandler
 !insertmacro un.RegCleanFileHandler
 !insertmacro un.RegCleanMain
 !insertmacro un.RegCleanUninstall
@@ -212,27 +213,29 @@ Section "Uninstall"
     RmDir "$APPDATA\Mozilla\Extensions\{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
     RmDir "$APPDATA\Mozilla\Extensions"
     RmDir "$APPDATA\Mozilla"
   ${EndIf}
 
   SetShellVarContext current  ; Set SHCTX to HKCU
   ${un.RegCleanMain} "Software\Mozilla"
   ${un.RegCleanUninstall}
+  ${un.DeleteShortcuts}
 
   ClearErrors
   WriteRegStr HKLM "Software\Mozilla\InstallerTest" "InstallerTest" "Test"
   ${If} ${Errors}
     StrCpy $TmpVal "HKCU" ; used primarily for logging
   ${Else}
     SetShellVarContext all  ; Set SHCTX to HKLM
     DeleteRegKey HKLM "Software\Mozilla\InstallerTest"
     StrCpy $TmpVal "HKLM" ; used primarily for logging
     ${un.RegCleanMain} "Software\Mozilla"
     ${un.RegCleanUninstall}
+    ${un.DeleteShortcuts}
   ${EndIf}
 
   ${un.RegCleanAppHandler} "FirefoxURL"
   ${un.RegCleanAppHandler} "FirefoxHTML"
   ${un.RegCleanProtocolHandler} "ftp"
   ${un.RegCleanProtocolHandler} "http"
   ${un.RegCleanProtocolHandler} "https"
 
@@ -563,16 +566,18 @@ Function un.onInit
   ${EndUnless}
 
   StrCpy $LANGUAGE 0
   ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
 
   ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
   ; the user clicks the back button
   StrCpy $hHeaderBitmap ""
+
+  !insertmacro InitInstallOptionsFile "unconfirm.ini"
 FunctionEnd
 
 Function .onGUIEnd
   ${OnEndCommon}
 FunctionEnd
 
 Function un.onGUIEnd
   ${un.OnEndCommon}
--- a/toolkit/mozapps/installer/windows/nsis/common.nsh
+++ b/toolkit/mozapps/installer/windows/nsis/common.nsh
@@ -14,16 +14,17 @@
 # The Original Code is the Mozilla Installer code.
 #
 # The Initial Developer of the Original Code is Mozilla Foundation
 # Portions created by the Initial Developer are Copyright (C) 2006
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #  Robert Strong <robert.bugzilla@gmail.com>
+#  Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -108,16 +109,18 @@
 ; WinVer.nsh so include it with the /NOFATAL option.
 !ifndef ___WINVER__NSH___
   !include /NONFATAL WinVer.nsh
 !endif
 
 ; NSIS provided macros that we have overridden.
 !include overrides.nsh
 
+!define SHORTCUTS_LOG "shortcuts_log.ini"
+
 ################################################################################
 # Macros for debugging
 
 /**
  * The following two macros assist with verifying that a macro doesn't
  * overwrite any registers.
  *
  * Usage:
@@ -167,35 +170,94 @@
        $$R5 = $R5$\n$$R6 = $R6$\n$$R7 = $R7$\n$$R8 = $R8$\n$$R9 = $R9"
 !macroend
 !define debugDisplayRegisters "!insertmacro debugDisplayRegisters"
 
 
 ################################################################################
 # Modern User Interface (MUI) override macros
 
+; Removed macros in nsis 2.33u (ported from nsis 2.22)
+;  MUI_LANGUAGEFILE_DEFINE
+;  MUI_LANGUAGEFILE_LANGSTRING_PAGE
+;  MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE
+;  MUI_LANGUAGEFILE_LANGSTRING_DEFINE
+;  MUI_LANGUAGEFILE_UNLANGSTRING_PAGE
+
+!macro MOZ_MUI_LANGUAGEFILE_DEFINE DEFINE NAME
+
+  !ifndef "${DEFINE}"
+    !define "${DEFINE}" "${${NAME}}"
+  !endif
+  !undef "${NAME}"
+
+!macroend
+
+!macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE PAGE NAME
+
+  !ifdef MUI_${PAGE}PAGE
+    LangString "${NAME}" 0 "${${NAME}}"
+    !undef "${NAME}"
+  !else
+    !undef "${NAME}"
+  !endif
+
+!macroend
+
+!macro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE PAGE NAME
+
+  !ifdef MUI_${PAGE}PAGE | MUI_UN${PAGE}PAGE
+    LangString "${NAME}" 0 "${${NAME}}"
+    !undef "${NAME}"
+  !else
+    !undef "${NAME}"
+  !endif
+
+!macroend
+
+!macro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE DEFINE NAME
+
+  !ifdef "${DEFINE}"
+    LangString "${NAME}" 0 "${${NAME}}"
+  !endif
+  !undef "${NAME}"
+
+!macroend
+
+!macro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE PAGE NAME
+
+  !ifdef MUI_UNINSTALLER
+    !ifdef MUI_UN${PAGE}PAGE
+      LangString "${NAME}" 0 "${${NAME}}"
+      !undef "${NAME}"
+    !else
+      !undef "${NAME}"
+    !endif
+  !else
+    !undef "${NAME}"
+  !endif
+
+!macroend
+
 ; Modified version of the following MUI macros to support Mozilla localization.
 ; MUI_LANGUAGE
 ; MUI_LANGUAGEFILE_BEGIN
 ; MOZ_MUI_LANGUAGEFILE_END
 ; See <NSIS App Dir>/Contrib/Modern UI/System.nsh for more information
 !define MUI_INSTALLOPTIONS_READ "!insertmacro MUI_INSTALLOPTIONS_READ"
 
 !macro MOZ_MUI_LANGUAGE LANGUAGE
   !verbose push
   !verbose ${MUI_VERBOSE}
   !include "${LANGUAGE}.nsh"
   !verbose pop
 !macroend
 
 !macro MOZ_MUI_LANGUAGEFILE_BEGIN LANGUAGE
-  !ifndef MUI_INSERT
-    !define MUI_INSERT
-    !insertmacro MUI_INSERT
-  !endif
+  !insertmacro MUI_INSERT
   !ifndef "MUI_LANGUAGEFILE_${LANGUAGE}_USED"
     !define "MUI_LANGUAGEFILE_${LANGUAGE}_USED"
     LoadLanguageFile "${LANGUAGE}.nlf"
   !else
     !error "Modern UI language file ${LANGUAGE} included twice!"
   !endif
 !macroend
 
@@ -205,120 +267,158 @@
 !macro MOZ_MUI_LANGUAGEFILE_END
 
 #  !include "${NSISDIR}\Contrib\Modern UI\Language files\Default.nsh"
   !ifdef MUI_LANGUAGEFILE_DEFAULT_USED
     !undef MUI_LANGUAGEFILE_DEFAULT_USED
     !warning "${LANGUAGE} Modern UI language file version doesn't match. Using default English texts for missing strings."
   !endif
 
-  !insertmacro MUI_LANGUAGEFILE_DEFINE "MUI_${LANGUAGE}_LANGNAME" "MUI_LANGNAME"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_DEFINE "MUI_${LANGUAGE}_LANGNAME" "MUI_LANGNAME"
 
   !ifndef MUI_LANGDLL_PUSHLIST
     !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} "
   !else
     !ifdef MUI_LANGDLL_PUSHLIST_TEMP
       !undef MUI_LANGDLL_PUSHLIST_TEMP
     !endif
     !define MUI_LANGDLL_PUSHLIST_TEMP "${MUI_LANGDLL_PUSHLIST}"
     !undef MUI_LANGDLL_PUSHLIST
     !define MUI_LANGDLL_PUSHLIST "'${MUI_${LANGUAGE}_LANGNAME}' ${LANG_${LANGUAGE}} ${MUI_LANGDLL_PUSHLIST_TEMP}"
   !endif
 
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TEXT"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE WELCOME "MUI_TEXT_WELCOME_INFO_TEXT"
 
 !ifdef MUI_TEXT_LICENSE_TITLE
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_TITLE"
 !endif
 !ifdef MUI_TEXT_LICENSE_SUBTITLE
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_SUBTITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_TEXT_LICENSE_SUBTITLE"
 !endif
 !ifdef MUI_INNERTEXT_LICENSE_TOP
-  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_TOP"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_TOP"
 !endif
 
-#  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM"
 
 !ifdef MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX"
 !endif
 
 !ifdef MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE LICENSE "MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS"
 !endif
 
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_SUBTITLE"
-  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_SUBTITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_TOP"
-#  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_CHECKBOX"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_BUTTONTEXT_FINISH"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TEXT"
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_REBOOT"
-  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTNOW"
-  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTLATER"
-#  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_RUN"
-#  !insertmacro MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_SHOWREADME"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_ABORTWARNING "MUI_TEXT_ABORTWARNING"
-
-
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TEXT"
-
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_SUBTITLE"
-
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_TITLE"
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_SUBTITLE"
-
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM"
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_CHECKBOX"
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS"
-
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_TITLE"
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_SUBTITLE"
-
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_TITLE"
-#  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY  "MUI_UNTEXT_DIRECTORY_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_SUBTITLE"
-
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TITLE"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TEXT"
-  !insertmacro MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_REBOOT"
-
-  !insertmacro MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_UNABORTWARNING "MUI_UNTEXT_ABORTWARNING"
-
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE COMPONENTS "MUI_TEXT_COMPONENTS_SUBTITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE COMPONENTS "MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE DIRECTORY "MUI_TEXT_DIRECTORY_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_TEXT_STARTMENU_SUBTITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_TOP"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE STARTMENU "MUI_INNERTEXT_STARTMENU_CHECKBOX"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_INSTALLING_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_FINISH_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE INSTFILES "MUI_TEXT_ABORT_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_BUTTONTEXT_FINISH"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_TEXT"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_INFO_REBOOT"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTNOW"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_REBOOTLATER"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_RUN"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_MULTILANGSTRING_PAGE FINISH "MUI_TEXT_FINISH_SHOWREADME"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_ABORTWARNING "MUI_TEXT_ABORTWARNING"
+
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE WELCOME "MUI_UNTEXT_WELCOME_INFO_TEXT"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE CONFIRM "MUI_UNTEXT_CONFIRM_SUBTITLE"
+
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_TITLE"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNTEXT_LICENSE_SUBTITLE"
+
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_CHECKBOX"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE LICENSE "MUI_UNINNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS"
+
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_TITLE"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE COMPONENTS "MUI_UNTEXT_COMPONENTS_SUBTITLE"
+
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY "MUI_UNTEXT_DIRECTORY_TITLE"
+#  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE DIRECTORY  "MUI_UNTEXT_DIRECTORY_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_UNINSTALLING_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_FINISH_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE INSTFILES "MUI_UNTEXT_ABORT_SUBTITLE"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TITLE"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_TEXT"
+  !insertmacro MOZ_MUI_LANGUAGEFILE_UNLANGSTRING_PAGE FINISH "MUI_UNTEXT_FINISH_INFO_REBOOT"
+
+  !insertmacro MOZ_MUI_LANGUAGEFILE_LANGSTRING_DEFINE MUI_UNABORTWARNING "MUI_UNTEXT_ABORTWARNING"
+
+  !ifndef MUI_LANGDLL_LANGUAGES
+    !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' "
+    !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' "
+  !else
+    !ifdef MUI_LANGDLL_LANGUAGES_TEMP
+      !undef MUI_LANGDLL_LANGUAGES_TEMP
+    !endif
+    !define MUI_LANGDLL_LANGUAGES_TEMP "${MUI_LANGDLL_LANGUAGES}"
+    !undef MUI_LANGDLL_LANGUAGES
+
+    !ifdef MUI_LANGDLL_LANGUAGES_CP_TEMP
+      !undef MUI_LANGDLL_LANGUAGES_CP_TEMP
+    !endif
+    !define MUI_LANGDLL_LANGUAGES_CP_TEMP "${MUI_LANGDLL_LANGUAGES_CP}"
+    !undef MUI_LANGDLL_LANGUAGES_CP
+
+    !define MUI_LANGDLL_LANGUAGES "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' ${MUI_LANGDLL_LANGUAGES_TEMP}"
+    !define MUI_LANGDLL_LANGUAGES_CP "'${LANGFILE_${LANGUAGE}_NAME}' '${LANG_${LANGUAGE}}' '${LANG_${LANGUAGE}_CP}' ${MUI_LANGDLL_LANGUAGES_CP_TEMP}"
+  !endif
+
+!macroend
+
+/**
+ * Creates an InstallOptions file with a UTF-16LE BOM and adds the RTL value
+ * to the Settings section.
+ *
+ * @param   _FILE
+ *          The name of the file to be created in $PLUGINSDIR.
+ */
+!macro InitInstallOptionsFile _FILE
+  Push $R9
+
+  FileOpen $R9 "$PLUGINSDIR\${_FILE}" w
+  FileWriteWord $R9 "65279"
+  FileClose $R9
+  WriteIniStr "$PLUGINSDIR\${_FILE}" "Settings" "RTL" "$(^RTL)"
+
+  Pop $R9
 !macroend
 
 
 ################################################################################
 # Macros for creating Install Options ini files
 #
 # DEPRECATED - all ini creation code should be added to the application's
 # installer and uninstaller files.
@@ -1085,21 +1185,21 @@
       Exch 4
       Exch $R5
 
       ClearErrors
       WriteRegStr SHCTX "$R6" "$R7" "$R8"
 
       !ifndef NO_LOG
         IfErrors 0 +3
-        FileWrite $fhInstallLog "  ** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  ** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **$\r$\n"
         GoTo +4
         StrCmp "$R9" "1" +1 +2
         FileWrite $fhUninstallLog "RegVal: $R5 | $R6 | $R7$\r$\n"
-        FileWrite $fhInstallLog "  Added Registry String: $R5 | $R6 | $R7 | $R8$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  Added Registry String: $R5 | $R6 | $R7 | $R8$\r$\n"
       !endif
 
       Exch $R5
       Exch 4
       Exch $R6
       Exch 3
       Exch $R7
       Exch 2
@@ -1193,21 +1293,21 @@
       Exch 4
       Exch $R5
 
       ClearErrors
       WriteRegDWORD SHCTX "$R6" "$R7" "$R8"
 
       !ifndef NO_LOG
         IfErrors 0 +3
-        FileWrite $fhInstallLog "  ** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  ** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **$\r$\n"
         GoTo +4
         StrCmp "$R9" "1" +1 +2
         FileWrite $fhUninstallLog "RegVal: $R5 | $R6 | $R7$\r$\n"
-        FileWrite $fhInstallLog "  Added Registry DWord: $R5 | $R6 | $R7 | $R8$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  Added Registry DWord: $R5 | $R6 | $R7 | $R8$\r$\n"
       !endif
 
       Exch $R5
       Exch 4
       Exch $R6
       Exch 3
       Exch $R7
       Exch 2
@@ -1301,21 +1401,21 @@
       Exch 4
       Exch $R5
 
       ClearErrors
       WriteRegStr HKCR "$R6" "$R7" "$R8"
 
       !ifndef NO_LOG
         IfErrors 0 +3
-        FileWrite $fhInstallLog "  ** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  ** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **$\r$\n"
         GoTo +4
         StrCmp "$R9" "1" +1 +2
         FileWrite $fhUninstallLog "RegVal: $R5 | $R6 | $R7$\r$\n"
-        FileWrite $fhInstallLog "  Added Registry String: $R5 | $R6 | $R7 | $R8$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  Added Registry String: $R5 | $R6 | $R7 | $R8$\r$\n"
       !endif
 
       Exch $R5
       Exch 4
       Exch $R6
       Exch 3
       Exch $R7
       Exch 2
@@ -1366,22 +1466,22 @@
     !verbose pop
   !endif
 !macroend
 
 /**
  * Creates a registry key. NSIS doesn't supply a RegCreateKey method and instead
  * will auto create keys when a reg key name value pair is set.
  * i - int (includes char, byte, short, handles, pointers and so on)
- * t - text, string (LPCSTR, pointer to first character)
+ * w - wide-char text, string (LPCWSTR, pointer to first character)
  * * - pointer specifier -> the proc needs the pointer to type, affects next
  *     char (parameter) [ex: '*i' - pointer to int]
  * see the NSIS documentation for additional information.
  */
-!define RegCreateKey "Advapi32::RegCreateKeyA(i, t, *i) i"
+!define RegCreateKey "Advapi32::RegCreateKeyW(i, w, *i) i"
 
 /**
  * Creates a registry key. This will log the actions to the install and
  * uninstall logs. Alternatively you can set a registry value to create the key
  * and then delete the value.
  *
  * Define NO_LOG to prevent all logging when calling this from the uninstaller.
  *
@@ -1427,21 +1527,21 @@
       StrCpy $R6 "0x80000002"
 
       ; see definition of RegCreateKey
       System::Call "${RegCreateKey}($R6, '$R8', .r14) .r15"
 
       !ifndef NO_LOG
         ; if $R5 is not 0 then there was an error creating the registry key.
         IntCmp $R5 0 +3 +3
-        FileWrite $fhInstallLog "  ** ERROR Adding Registry Key: $R7 | $R8 **$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  ** ERROR Adding Registry Key: $R7 | $R8 **$\r$\n"
         GoTo +4
         StrCmp "$R9" "1" +1 +2
         FileWrite $fhUninstallLog "RegKey: $R7 | $R8$\r$\n"
-        FileWrite $fhInstallLog "  Added Registry Key: $R7 | $R8$\r$\n"
+        FileWriteUTF16LE $fhInstallLog "  Added Registry Key: $R7 | $R8$\r$\n"
       !endif
 
       Pop $R4
       Pop $R5
       Pop $R6
       Exch $R7
       Exch 2
       Exch $R8
@@ -2080,17 +2180,17 @@
     Function ${_MOZFUNC_UN}CanWriteToInstallDir
       Push $R9
       Push $R8
       Push $R7
 
       StrCpy $R9 "true"
       IfFileExists "$INSTDIR" +1 checkCreateDir
       GetTempFileName $R7 "$INSTDIR"
-      FileOpen $R8 $R7 w
+      FileOpen $R8 "$R7" w
       FileWrite $R8 "Write Access Test"
       FileClose $R8
       IfFileExists "$R7" +3 +1
       StrCpy $R9 "false"
       GoTo end
 
       Delete $R7
       GoTo end
@@ -2451,34 +2551,34 @@
 
     !undef _MOZFUNC_UN
     !define _MOZFUNC_UN
     !verbose pop
   !endif
 !macroend
 
 /**
- * Returns the long path for an existing file or directory. GetLongPathNameA
+ * Returns the long path for an existing file or directory. GetLongPathNameW
  * may not be available on Win95 if Microsoft Layer for Unicode is not
  * installed and GetFullPathName only returns a long path for the last file or
  * directory that doesn't end with a \ in the path that it is passed. If the
  * path does not exist on the file system this will return an empty string. To
  * provide a consistent result trailing back-slashes are always removed.
  *
- * Note: 1024 used by GetLongPathNameA is the maximum NSIS string length.
+ * Note: 1024 used by GetLongPathNameW is the maximum NSIS string length.
  *
  * @param   _IN_PATH
  *          The string containing the path.
  * @param   _OUT_PATH
  *          The register to store the long path.
  *
  * $R4 = counter value when the previous \ was found
  * $R5 = directory or file name found during loop
- * $R6 = return value from GetLongPathNameA and loop counter
- * $R7 = long path from GetLongPathNameA and single char from path for comparison
+ * $R6 = return value from GetLongPathNameW and loop counter
+ * $R7 = long path from GetLongPathNameW and single char from path for comparison
  * $R8 = storage for _IN_PATH
  * $R9 = _IN_PATH _OUT_PATH
  */
 !macro GetLongPath
 
   !ifndef ${_MOZFUNC_UN}GetLongPath
     !verbose push
     !verbose ${_MOZFUNC_VERBOSE}
@@ -2499,18 +2599,18 @@
       GetFullPathName $R8 "$R8"
       IfErrors end_GetLongPath +1 ; If the path doesn't exist return an empty string.
 
       ; Remove trailing \'s from the path.
       StrCpy $R6 "$R8" "" -1
       StrCmp $R6 "\" +1 +2
       StrCpy $R9 "$R8" -1
 
-      System::Call 'kernel32::GetLongPathNameA(t r18, t .r17, i 1024)i .r16'
-      StrCmp "$R7" "" +4 +1 ; Empty string when GetLongPathNameA is not present.
+      System::Call 'kernel32::GetLongPathNameW(w r18, w .r17, i 1024)i .r16'
+      StrCmp "$R7" "" +4 +1 ; Empty string when GetLongPathNameW is not present.
       StrCmp $R6 0 +3 +1    ; Should never equal 0 since the path exists.
       StrCpy $R9 "$R7"
       GoTo end_GetLongPath
 
       ; Do it the hard way.
       StrCpy $R4 0     ; Stores the position in the string of the last \ found.
       StrCpy $R6 -1    ; Set the counter to -1 so it will start at 0.
 
@@ -3502,25 +3602,214 @@
     !insertmacro DeleteRelativeProfiles
 
     !undef _MOZFUNC_UN
     !define _MOZFUNC_UN
     !verbose pop
   !endif
 !macroend
 
+/**
+ * Deletes shortcuts and Start Menu directories under Programs as specified by
+ * the shortcuts log ini file. The shortcuts will not be deleted if the shortcut
+ * target isn't for this install location which is determined by the shortcut
+ * having a target of $INSTDIR\${FileMainEXE}. The context (All Users or Current
+ * User) of the $DESKTOP, $STARTMENU, and $SMPROGRAMS constants depends on the
+ * SetShellVarContext setting and must be set by the caller of this macro. There
+ * is no All Users context for $QUICKLAUNCH but this will not cause a problem
+ * since the macro will just continue past the $QUICKLAUNCH shortcut deletion
+ * section on subsequent calls.
+ *
+ * The ini file sections must have the following format (the order of the
+ * sections in the ini file is not important):
+ * [SMPROGRAMS]
+ * ; RelativePath is the directory relative from the Start Menu
+ * ; Programs directory.
+ * RelativePath=Mozilla App
+ * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
+ * ; on. There must not be a break in the sequence of the numbers.
+ * Shortcut1=Mozilla App.lnk
+ * Shortcut2=Mozilla App (Safe Mode).lnk
+ * [DESKTOP]
+ * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
+ * ; on. There must not be a break in the sequence of the numbers.
+ * Shortcut1=Mozilla App.lnk
+ * Shortcut2=Mozilla App (Safe Mode).lnk
+ * [QUICKLAUNCH]
+ * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
+ * ; on. There must not be a break in the sequence of the numbers for the
+ * ; suffix.
+ * Shortcut1=Mozilla App.lnk
+ * Shortcut2=Mozilla App (Safe Mode).lnk
+ * [STARTMENU]
+ * ; Shortcut1 is the first shortcut, Shortcut2 is the second shortcut, and so
+ * ; on. There must not be a break in the sequence of the numbers for the
+ * ; suffix.
+ * Shortcut1=Mozilla App.lnk
+ * Shortcut2=Mozilla App (Safe Mode).lnk
+ *
+ * $R4 = counter for appending to Shortcut for enumerating the ini file entries
+ * $R5 = return value from ShellLink::GetShortCutTarget
+ * $R6 = long path to the Start Menu Programs directory (e.g. $SMPROGRAMS)
+ * $R7 = return value from ReadINIStr for the relative path to the applications
+ *       directory under the Start Menu Programs directory and the long path to
+ *       this directory
+ * $R8 = return value from ReadINIStr for enumerating shortcuts
+ * $R9 = long path to the shortcuts log ini file
+ */
+!macro DeleteShortcuts
+
+  !ifndef ${_MOZFUNC_UN}DeleteShortcuts
+    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
+    !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath
+    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
+    !undef _MOZFUNC_UN_TMP
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define ${_MOZFUNC_UN}DeleteShortcuts "!insertmacro ${_MOZFUNC_UN}DeleteShortcutsCall"
+
+    Function ${_MOZFUNC_UN}DeleteShortcuts
+      Push $R9
+      Push $R8
+      Push $R7
+      Push $R6
+      Push $R5
+      Push $R4
+
+      ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9
+      IfFileExists $R9 +1 end_DeleteShortcuts
+
+      ; Delete Start Menu shortcuts for this application
+      StrCpy $R4 -1
+
+      IntOp $R4 $R4 + 1 ; Increment the counter
+      ClearErrors
+      ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4"
+      IfErrors +7 +1
+      IfFileExists "$STARTMENU\$R8" +1 -4
+      ShellLink::GetShortCutTarget "$STARTMENU\$R8"
+      Pop $R5
+      StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7
+      Delete "$STARTMENU\$R8"
+      GoTo -9
+
+      ; Delete Quick Launch shortcuts for this application
+      StrCpy $R4 -1
+
+      IntOp $R4 $R4 + 1 ; Increment the counter
+      ClearErrors
+      ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4"
+      IfErrors +7 +1
+      IfFileExists "$QUICKLAUNCH\$R8" +1 -4
+      ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8"
+      Pop $R5
+      StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7
+      Delete "$QUICKLAUNCH\$R8"
+      GoTo -9
+
+      ; Delete Desktop shortcuts for this application
+      StrCpy $R4 -1
+
+      IntOp $R4 $R4 + 1 ; Increment the counter
+      ClearErrors
+      ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4"
+      IfErrors +7 +1
+      IfFileExists "$DESKTOP\$R8" +1 -4
+      ShellLink::GetShortCutTarget "$DESKTOP\$R8"
+      Pop $R5
+      StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7
+      Delete "$DESKTOP\$R8"
+      GoTo -9
+
+      ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6
+
+      ; Delete Start Menu Programs shortcuts for this application
+      ClearErrors
+      ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir"
+      ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7
+      StrCmp "$R7" "" end_DeleteShortcuts +1
+      StrCpy $R4 -1
+
+      IntOp $R4 $R4 + 1 ; Increment the counter
+      ClearErrors
+      ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4"
+      IfErrors +7 +1
+      IfFileExists "$R7\$R8" +1 -4
+      ShellLink::GetShortCutTarget "$R7\$R8"
+      Pop $R5
+      StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7
+      Delete "$R7\$R8"
+      GoTo -9
+
+      ; Delete Start Menu Programs directories for this application
+      start_RemoveSMProgramsDir:
+      ClearErrors
+      StrCmp "$R6" "$R7" end_DeleteShortcuts +1
+      RmDir "$R7"
+      IfErrors end_DeleteShortcuts +1
+      ${${_MOZFUNC_UN}GetParent} "$R7" $R7
+      GoTo start_RemoveSMProgramsDir
+
+      end_DeleteShortcuts:
+      ClearErrors
+
+      Pop $R4
+      Pop $R5
+      Pop $R6
+      Pop $R7
+      Pop $R8
+      Pop $R9
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro DeleteShortcutsCall
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Call DeleteShortcuts
+  !verbose pop
+!macroend
+
+!macro un.DeleteShortcutsCall
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Call un.DeleteShortcuts
+  !verbose pop
+!macroend
+
+!macro un.DeleteShortcuts
+  !ifndef un.DeleteShortcuts
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN "un."
+
+    !insertmacro DeleteShortcuts
+
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN
+    !verbose pop
+  !endif
+!macroend
+
 
 ################################################################################
 # Macros for parsing and updating the uninstall.log and removed-files.log
 
 /**
  * Updates the uninstall.log with new files added by software update.
  *
  * When modifying this macro be aware that LineFind uses all registers except
- * $R0-$R3 so be cautious. Callers of this macro are not affected.
+ * $R0-$R3 and TextCompareNoDetails uses all registers except $R0-$R9 so be
+ * cautious. Callers of this macro are not affected.
  */
 !macro UpdateUninstallLog
 
   !ifndef UpdateUninstallLog
     !insertmacro FileJoin
     !insertmacro LineFind
     !insertmacro TextCompareNoDetails
     !insertmacro TrimNewLines
@@ -3533,31 +3822,31 @@
       Push $R3
       Push $R2
       Push $R1
       Push $R0
 
       ClearErrors
 
       GetFullPathName $R3 "$INSTDIR\uninstall"
-      IfFileExists "$R3\uninstall.update" +2 0
-      Return
+      IfFileExists "$R3\uninstall.update" +1 end_UpdateUninstallLog
 
       ${LineFind} "$R3\uninstall.update" "" "1:-1" "CleanupUpdateLog"
 
       GetTempFileName $R2 "$R3"
-      FileOpen $R1 $R2 w
+      FileOpen $R1 "$R2" w
       ${TextCompareNoDetails} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "CreateUpdateDiff"
       FileClose $R1
 
       IfErrors +2 0
       ${FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log"
 
       ${DeleteFile} "$R2"
 
+      end_UpdateUninstallLog:
       ClearErrors
 
       Pop $R0
       Pop $R1
       Pop $R2
       Pop $R3
     FunctionEnd
 
@@ -3616,24 +3905,25 @@
   !verbose pop
 !macroend
 
 /**
  * Updates the uninstall.log with entries from uninstall.bak. The uninstall.bak
  * is the uninstall.log renamed to uninstall.bak at the beginning of the
  * installation
  *
- * When modifying this macro be aware that LineFind uses all registers except
- * $R0-$R3 so be cautious. Callers of this macro are not affected.
+ * When modifying this macro be aware that TextCompareNoDetails uses all
+ * registers except $R0-$R9 so be cautious. Callers of this macro are not
+ * affected.
  */
 !macro UpdateFromPreviousLog
 
   !ifndef UpdateFromPreviousLog
     !insertmacro FileJoin
-    !insertmacro GetTime
+    !insertmacro GetLongPath
     !insertmacro TextCompareNoDetails
     !insertmacro TrimNewLines
 
     !verbose push
     !verbose ${_MOZFUNC_VERBOSE}
     !define UpdateFromPreviousLog "!insertmacro UpdateFromPreviousLogCall"
 
     Function UpdateFromPreviousLog
@@ -3646,27 +3936,25 @@
       Push $R3
       Push $R2
       Push $R1
       Push $R0
       Push $9
 
       ; Diff and add missing entries from the previous file log if it exists
       IfFileExists "$INSTDIR\uninstall\uninstall.bak" +1 end
-      StrCpy $R0 "$INSTDIR\uninstall\uninstall.log"
-      StrCpy $R1 "$INSTDIR\uninstall\uninstall.bak"
-      GetTempFileName $R2
-      FileOpen $R3 $R2 w
-      ${TextCompareNoDetails} "$R1" "$R0" "SlowDiff" "UpdateFromPreviousLog_AddToLog"
+      ${DeleteFile} "$INSTDIR\uninstall\uninstall.tmp"
+      FileOpen $R3 "$INSTDIR\uninstall\uninstall.tmp" w
+      ${TextCompareNoDetails} "$INSTDIR\uninstall\uninstall.bak" "$INSTDIR\uninstall\uninstall.log" "SlowDiff" "UpdateFromPreviousLog_AddToLog"
       FileClose $R3
       IfErrors +2
-      ${FileJoin} "$INSTDIR\uninstall\uninstall.log" "$R2" "$INSTDIR\uninstall\uninstall.log"
+      ${FileJoin} "$INSTDIR\uninstall\uninstall.log" "$INSTDIR\uninstall\uninstall.tmp" "$INSTDIR\uninstall\uninstall.log"
 
       ${DeleteFile} "$INSTDIR\uninstall\uninstall.bak"
-      ${DeleteFile} "$R2"
+      ${DeleteFile} "$INSTDIR\uninstall\uninstall.tmp"
 
       end:
 
       Pop $9
       Pop $R0
       Pop $R1
       Pop $R2
       Pop $R3
@@ -3883,17 +4171,17 @@
       Push $R0
       Push $0
 
       StrCpy $R0 "$R6"
       StrCpy $R1 "$R7"
       StrCpy $R4 "$R8"
       StrCpy $R5 "$R9"
 
-      StrLen $R2 $R0
+      StrLen $R2 "$R0"
 
       ${LocateNoDetails} "$R0" "/L=FD" "CopyFileCallback"
 
       Pop $0
       Pop $R0
       Pop $R1
       Pop $R2
       Pop $R3
@@ -3995,16 +4283,17 @@
  * empty directories for this installation.
  *
  * When modifying this macro be aware that LineFind uses all registers except
  * $R0-$R3 so be cautious. Callers of this macro are not affected.
  */
 !macro un.ParseUninstallLog
 
   !ifndef un.ParseUninstallLog
+    !insertmacro un.GetParent
     !insertmacro un.LineFind
     !insertmacro un.TrimNewLines
 
     !verbose push
     !verbose ${_MOZFUNC_VERBOSE}
     !define un.ParseUninstallLog "!insertmacro un.ParseUninstallLogCall"
 
     Function un.ParseUninstallLog
@@ -4152,16 +4441,103 @@
 
 !macro un.ParseUninstallLogCall
   !verbose push
   !verbose ${_MOZFUNC_VERBOSE}
   Call un.ParseUninstallLog
   !verbose pop
 !macroend
 
+/**
+ * Finds a valid Start Menu shortcut in the uninstall log and returns the
+ * relative path from the Start Menu's Programs directory to the shortcut's
+ * directory.
+ *
+ * When modifying this macro be aware that LineFind uses all registers except
+ * $R0-$R3 so be cautious. Callers of this macro are not affected.
+ *
+ * @return  _REL_PATH_TO_DIR
+ *          The relative path to the application's Start Menu directory from the
+ *          Start Menu's Programs directory.
+ */
+!macro FindSMProgramsDir
+
+  !ifndef FindSMProgramsDir
+    !insertmacro GetParent
+    !insertmacro LineFind
+    !insertmacro TrimNewLines
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define FindSMProgramsDir "!insertmacro FindSMProgramsDirCall"
+
+    Function FindSMProgramsDir
+      Exch $R3
+      Push $R2
+      Push $R1
+      Push $R0
+
+      StrCpy $R3 ""
+      IfFileExists "$INSTDIR\uninstall\uninstall.log" +1 end_FindSMProgramsDir
+      ${LineFind} "$INSTDIR\uninstall\uninstall.log" "/NUL" "1:-1" "FindSMProgramsDirRelPath"
+
+      end_FindSMProgramsDir:
+      ClearErrors
+
+      Pop $R0
+      Pop $R1
+      Pop $R2
+      Exch $R3
+    FunctionEnd
+
+    ; This callback MUST use labels vs. relative line numbers.
+    Function FindSMProgramsDirRelPath
+      Push 0
+      ${TrimNewLines} "$R9" $R9
+      StrCpy $R4 "$R9" 5
+
+      StrCmp "$R4" "File:" +1 end_FindSMProgramsDirRelPath
+      StrCpy $R9 "$R9" "" 6
+      StrCpy $R4 "$R9" 1
+
+      StrCmp "$R4" "\" end_FindSMProgramsDirRelPath +1
+
+      SetShellVarContext all
+      ${GetLongPath} "$SMPROGRAMS" $R4
+      StrLen $R2 "$R4"
+      StrCpy $R1 "$R9" $R2
+      StrCmp "$R1" "$R4" +1 end_FindSMProgramsDirRelPath
+      IfFileExists "$R9" +1 end_FindSMProgramsDirRelPath
+      ShellLink::GetShortCutTarget "$R9"
+      Pop $R0
+      StrCmp "$INSTDIR\${FileMainEXE}" "$R0" +1 end_FindSMProgramsDirRelPath
+      ${GetParent} "$R9" $R3
+      IntOp $R2 $R2 + 1
+      StrCpy $R3 "$R3" "" $R2
+
+      Pop $R4             ; Remove the previously pushed 0 from the stack and
+      push "StopLineFind" ; push StopLineFind to stop finding more lines.
+
+      end_FindSMProgramsDirRelPath:
+      ClearErrors
+
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro FindSMProgramsDirCall _REL_PATH_TO_DIR
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Call FindSMProgramsDir
+  Pop ${_REL_PATH_TO_DIR}
+  !verbose pop
+!macroend
+
 
 ################################################################################
 # Macros for custom branding
 
 /**
  * Sets BrandFullName and / or BrandShortName to values provided in the specified
  * ini file and defaults to BrandShortName and BrandFullName as defined in
  * branding.nsi when the associated ini file entry is not specified.
@@ -4286,17 +4662,17 @@
     !verbose ${_MOZFUNC_VERBOSE}
     !define ${_MOZFUNC_UN}ChangeMUIHeaderImage "!insertmacro ${_MOZFUNC_UN}ChangeMUIHeaderImageCall"
 
     Function ${_MOZFUNC_UN}ChangeMUIHeaderImage
       Exch $R9
       Push $R8
 
       GetDlgItem $R8 $HWNDPARENT 1046
-      System::Call 'user32::LoadImage(i 0, t "$R9", i 0, i 0, i 0, i 0x0010|0x2000) i.s'
+      System::Call 'user32::LoadImageW(i 0, w "$R9", i 0, i 0, i 0, i 0x0010|0x2000) i.s'
       Pop $hHeaderBitmap
       SendMessage $R8 ${STM_SETIMAGE} 0 $hHeaderBitmap
       ; There is no way to specify a show function for a custom page so hide
       ; and then show the control to force the bitmap to redraw.
       ShowWindow $R8 ${SW_HIDE}
       ShowWindow $R8 ${SW_SHOW}
 
       Pop $R8
@@ -4544,17 +4920,17 @@
                 ${EndIf}
               ${EndIf}
 
               ; Quit if we are unable to create the installation directory or we are
               ; unable to write to a file in the installation directory.
               ClearErrors
               ${If} ${FileExists} "$INSTDIR"
                 GetTempFileName $R6 "$INSTDIR"
-                FileOpen $R5 $R6 w
+                FileOpen $R5 "$R6" w
                 FileWrite $R5 "Write Access Test"
                 FileClose $R5
                 Delete $R6
                 ${If} ${Errors}
                   ; Nothing initialized so no need to call OnEndCommon
                   Quit
                 ${EndIf}
               ${Else}
@@ -4659,34 +5035,34 @@
     !insertmacro UnloadUAC
     !insertmacro UpdateUninstallLog
 
     !verbose push
     !verbose ${_MOZFUNC_VERBOSE}
     !define UninstallOnInitCommon "!insertmacro UninstallOnInitCommonCall"
 
     Function UninstallOnInitCommon
-; Prevents breaking Thunderbird
+; Prevents breaking apps that don't use SetBrandNameVars
 !ifdef SetBrandNameVars
       ${SetBrandNameVars} "$EXEDIR\distribution\setup.ini"
 !endif
 
       ; Prevent launching the application when a reboot is required and this
       ; executable is the main application executable
       IfFileExists "$EXEDIR\${FileMainEXE}.moz-upgrade" +1 +4
       MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
       Reboot
       Quit ; Nothing initialized so no need to call OnEndCommon
 
       GetFullPathName $INSTDIR "$EXEDIR\.."
       ${GetLongPath} "$INSTDIR" $INSTDIR
       IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1
       Quit ; Nothing initialized so no need to call OnEndCommon
 
-; Prevents breaking Thunderbird
+; Prevents breaking apps that don't use SetBrandNameVars
 !ifdef SetBrandNameVars
       ${SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
 !endif
 
       ; Prevent all operations (e.g. set as default, postupdate, etc.) when a
       ; reboot is required and the executable launched is helper.exe
       IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4
       MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
@@ -5043,72 +5419,67 @@
  * Provides UAC elevation support for Vista and above (requires the UAC plugin).
  *
  * $0 = return values from calls to the UAC plugin (always uses $0)
  * $R9 = return values from GetParameters and GetOptions macros
  */
 !macro ElevateUAC
 
   !ifndef ${_MOZFUNC_UN}ElevateUAC
-    !ifdef USE_UAC_PLUGIN
-      !ifdef ___WINVER__NSH___
-        !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
-        !insertmacro ${_MOZFUNC_UN_TMP}GetOptions
-        !insertmacro ${_MOZFUNC_UN_TMP}GetParameters
-        !undef _MOZFUNC_UN
-        !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
-        !undef _MOZFUNC_UN_TMP
-      !endif
+    !ifdef ___WINVER__NSH___
+      !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
+      !insertmacro ${_MOZFUNC_UN_TMP}GetOptions
+      !insertmacro ${_MOZFUNC_UN_TMP}GetParameters
+      !undef _MOZFUNC_UN
+      !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
+      !undef _MOZFUNC_UN_TMP
     !endif
 
     !verbose push
     !verbose ${_MOZFUNC_VERBOSE}
     !define ${_MOZFUNC_UN}ElevateUAC "!insertmacro ${_MOZFUNC_UN}ElevateUACCall"
 
     Function ${_MOZFUNC_UN}ElevateUAC
-      ; USE_UAC_PLUGIN is temporary until Thunderbird has been updated to use the UAC plugin
-      !ifdef USE_UAC_PLUGIN
-        !ifdef ___WINVER__NSH___
-          Push $R9
-          Push $0
-
-          ${If} ${AtLeastWinVista}
-            UAC::IsAdmin
-            ; If the user is not an admin already
-            ${If} "$0" != "1"
-              UAC::SupportsUAC
-              ; If the system supports UAC
-              ${If} "$0" == "1"
-                UAC::GetElevationType
-                ; If the user account has a split token
-                ${If} "$0" == "3"
-                  UAC::RunElevated
-                  UAC::Unload
-                  ; Nothing besides UAC initialized so no need to call OnEndCommon
-                  Quit
-                ${EndIf}
-              ${EndIf}
-            ${Else}
-              ${GetParameters} $R9
-              ${If} $R9 != ""
-                ClearErrors
-                ${GetOptions} "$R9" "/UAC:" $0
-                ; If the command line contains /UAC then we need to initialize
-                ; the UAC plugin to use UAC::ExecCodeSegment to execute code in
-                ; the non-elevated context.
-                ${Unless} ${Errors}
-                  UAC::RunElevated 
-                ${EndUnless}
+      !ifdef ___WINVER__NSH___
+        Push $R9
+        Push $0
+
+        ${If} ${AtLeastWinVista}
+          UAC::IsAdmin
+          ; If the user is not an admin already
+          ${If} "$0" != "1"
+            UAC::SupportsUAC
+            ; If the system supports UAC
+            ${If} "$0" == "1"
+              UAC::GetElevationType
+              ; If the user account has a split token
+              ${If} "$0" == "3"
+                UAC::RunElevated
+                UAC::Unload
+                ; Nothing besides UAC initialized so no need to call OnEndCommon
+                Quit
               ${EndIf}
             ${EndIf}
+          ${Else}
+            ${GetParameters} $R9
+            ${If} $R9 != ""
+              ClearErrors
+              ${GetOptions} "$R9" "/UAC:" $0
+              ; If the command line contains /UAC then we need to initialize
+              ; the UAC plugin to use UAC::ExecCodeSegment to execute code in
+              ; the non-elevated context.
+              ${Unless} ${Errors}
+                UAC::RunElevated 
+              ${EndUnless}
+            ${EndIf}
           ${EndIf}
-
-          Pop $0
-          Pop $R9
-        !endif
+        ${EndIf}
+
+        Pop $0
+        Pop $R9
       !endif
     FunctionEnd
 
     !verbose pop
   !endif
 !macroend
 
 !macro ElevateUACCall
@@ -5144,51 +5515,47 @@
  * Unloads the UAC plugin so the NSIS plugins can be removed when the installer
  * and uninstaller exit.
  *
  * $R9 = return values from GetParameters and GetOptions macros
  */
 !macro UnloadUAC
 
   !ifndef ${_MOZFUNC_UN}UnloadUAC
-    !ifdef USE_UAC_PLUGIN
-      !ifdef ___WINVER__NSH___
-        !define _MOZFUNC_UN_TMP_UnloadUAC ${_MOZFUNC_UN}
-        !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetOptions
-        !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetParameters
-        !undef _MOZFUNC_UN
-        !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP_UnloadUAC}
-        !undef _MOZFUNC_UN_TMP_UnloadUAC
-      !endif
+    !ifdef ___WINVER__NSH___
+      !define _MOZFUNC_UN_TMP_UnloadUAC ${_MOZFUNC_UN}
+      !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetOptions
+      !insertmacro ${_MOZFUNC_UN_TMP_UnloadUAC}GetParameters
+      !undef _MOZFUNC_UN
+      !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP_UnloadUAC}
+      !undef _MOZFUNC_UN_TMP_UnloadUAC
     !endif
 
     !verbose push
     !verbose ${_MOZFUNC_VERBOSE}
     !define ${_MOZFUNC_UN}UnloadUAC "!insertmacro ${_MOZFUNC_UN}UnloadUACCall"
 
     Function ${_MOZFUNC_UN}UnloadUAC
-      !ifdef USE_UAC_PLUGIN
-        !ifdef ___WINVER__NSH___
-          Push $R9
-
-          ${Unless} ${AtLeastWinVista}
-            Return
-          ${EndUnless}
-
-          ClearErrors
-          ${${_MOZFUNC_UN}GetParameters} $R9
-          ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9
-          ; If the command line contains /UAC then we need to unload the UAC plugin
-          IfErrors +2 +1
-          UAC::Unload
-
-          ClearErrors
-
-          Pop $R9
-        !endif
+      !ifdef ___WINVER__NSH___
+        ${Unless} ${AtLeastWinVista}
+          Return
+        ${EndUnless}
+
+        Push $R9
+
+        ClearErrors
+        ${${_MOZFUNC_UN}GetParameters} $R9
+        ${${_MOZFUNC_UN}GetOptions} "$R9" "/UAC:" $R9
+        ; If the command line contains /UAC then we need to unload the UAC plugin
+        IfErrors +2 +1
+        UAC::Unload
+
+        ClearErrors
+
+        Pop $R9
       !endif
     FunctionEnd
 
     !verbose pop
   !endif
 !macroend
 
 !macro UnloadUACCall
@@ -5217,17 +5584,17 @@
     !undef _MOZFUNC_UN
     !define _MOZFUNC_UN
     !verbose pop
   !endif
 !macroend
 
 
 ################################################################################
-# Macros for logging
+# Macros for uninstall.log and install.log logging
 #
 # Since these are used by other macros they should be inserted first. All of
 # these macros can be easily inserted using the _LoggingCommon macro.
 
 /**
  * Adds all logging macros in the correct order in one fell swoop as well as
  * the vars for the install.log and uninstall.log file handles.
  */
@@ -5283,20 +5650,22 @@
       Push $R5
       Push $R4
       Push $R3
       Push $R2
       Push $R1
       Push $R0
       Push $9
 
+      ${DeleteFile} "$INSTDIR\install.log"
       FileOpen $fhInstallLog "$INSTDIR\install.log" w
+      FileWriteWord $fhInstallLog "65279"
 
       ${GetTime} "" "L" $9 $R0 $R1 $R2 $R3 $R4 $R5
-      FileWrite $fhInstallLog "$R6 Installation Started: $R1-$R0-$9 $R3:$R4:$R5"
+      FileWriteUTF16LE $fhInstallLog "$R6 Installation Started: $R1-$R0-$9 $R3:$R4:$R5"
       ${WriteLogSeparator}
 
       ${LogHeader} "Installation Details"
       ${LogMsg} "Install Dir: $INSTDIR"
       ${LogMsg} "Locale     : $R7"
       ${LogMsg} "App Version: $R8"
       ${LogMsg} "GRE Version: $R9"
 
@@ -5355,17 +5724,17 @@
       Push $R6
       Push $R5
       Push $R4
       Push $R3
       Push $R2
       
       ${WriteLogSeparator}
       ${GetTime} "" "L" $R2 $R3 $R4 $R5 $R6 $R7 $R8
-      FileWrite $fhInstallLog "$R9 Installation Finished: $R4-$R3-$R2 $R6:$R7:$R8$\r$\n"
+      FileWriteUTF16LE $fhInstallLog "$R9 Installation Finished: $R4-$R3-$R2 $R6:$R7:$R8$\r$\n"
       FileClose $fhInstallLog
 
       Pop $R2
       Pop $R3
       Pop $R4
       Pop $R5
       Pop $R6
       Pop $R7
@@ -5441,29 +5810,29 @@
 /**
  * Adds a section header to the human readable log.
  *
  * @param   _HEADER
  *          The header text to write to the log.
  */
 !macro LogHeader _HEADER
   ${WriteLogSeparator}
-  FileWrite $fhInstallLog "${_HEADER}"
+  FileWriteUTF16LE $fhInstallLog "${_HEADER}"
   ${WriteLogSeparator}
 !macroend
 !define LogHeader "!insertmacro LogHeader"
 
 /**
  * Adds a section message to the human readable log.
  *
  * @param   _MSG
  *          The message text to write to the log.
  */
 !macro LogMsg _MSG
-  FileWrite $fhInstallLog "  ${_MSG}$\r$\n"
+  FileWriteUTF16LE $fhInstallLog "  ${_MSG}$\r$\n"
 !macroend
 !define LogMsg "!insertmacro LogMsg"
 
 /**
  * Adds an uninstall entry to the uninstall log.
  *
  * @param   _MSG
  *          The message text to write to the log.
@@ -5472,12 +5841,286 @@
   FileWrite $fhUninstallLog "${_MSG}$\r$\n"
 !macroend
 !define LogUninstall "!insertmacro LogUninstall"
 
 /**
  * Adds a section divider to the human readable log.
  */
 !macro WriteLogSeparator
-  FileWrite $fhInstallLog "$\r$\n----------------------------------------\
-                           ---------------------------------------$\r$\n"
+  FileWriteUTF16LE $fhInstallLog "$\r$\n----------------------------------------\
+                                  ---------------------------------------$\r$\n"
 !macroend
 !define WriteLogSeparator "!insertmacro WriteLogSeparator"
+
+
+################################################################################
+# Macros for managing the shortcuts log ini file
+
+/**
+ * Adds the most commonly used shortcut logging macros for the installer in one
+ * fell swoop.
+ */
+!macro _LoggingShortcutsCommon
+  !insertmacro LogDesktopShortcut
+  !insertmacro LogQuickLaunchShortcut
+  !insertmacro LogSMProgramsShortcut
+!macroend
+!define _LoggingShortcutsCommon "!insertmacro _LoggingShortcutsCommon"
+
+/**
+ * Creates the shortcuts log ini file with a UTF-16LE BOM if it doesn't exist.
+ */
+!macro initShortcutsLog
+  Push $R9
+
+  IfFileExists "$INSTDIR\uninstall\${SHORTCUTS_LOG}" +4 +1
+  FileOpen $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" w
+  FileWriteWord $R9 "65279"
+  FileClose $R9
+
+  Pop $R9
+!macroend
+!define initShortcutsLog "!insertmacro initShortcutsLog"
+
+/**
+ * Adds shortcut entries to the shortcuts log ini file. This macro is primarily
+ * a helper used by the LogDesktopShortcut, LogQuickLaunchShortcut, and
+ * LogSMProgramsShortcut macros but it can be used by other code if desired. If
+ * the value already exists the the value is not written to the file.
+ *
+ * @param   _SECTION_NAME
+ *          The section name to write to in the shortcut log ini file
+ * @param   _FILE_NAME
+ *          The 
+ *
+ * $R6 = 
+ * $R7 = 
+ * $R8 = _SECTION_NAME
+ * $R9 = _FILE_NAME
+ */
+!macro LogShortcut
+
+  !ifndef LogShortcut
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define LogShortcut "!insertmacro LogShortcutCall"
+
+    Function LogShortcut
+      Exch $R9
+      Exch 1
+      Exch $R8
+      Push $R7
+      Push $R6
+
+      ClearErrors
+
+      !insertmacro initShortcutsLog
+
+      StrCpy $R6 ""
+      StrCpy $R7 -1
+
+      StrCmp "$R6" "$R9" +5 +1 ; if the shortcut already exists don't add it
+      IntOp $R7 $R7 + 1 ; increment the counter
+      ReadIniStr $R6 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7"
+      IfErrors +1 -3
+      WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "$R8" "Shortcut$R7" "$R9"
+
+      ClearErrors
+
+      Pop $R6
+      Pop $R7
+      Exch $R8
+      Exch 1
+      Exch $R9
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro LogShortcutCall _SECTION_NAME _FILE_NAME
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "${_SECTION_NAME}"
+  Push "${_FILE_NAME}"
+  Call LogShortcut
+  !verbose pop
+!macroend
+
+/**
+ * Adds a Desktop shortcut entry to the shortcuts log ini file.
+ *
+ * @param   _FILE_NAME
+ *          The shortcut file name (e.g. shortcut.lnk)
+ */
+!macro LogDesktopShortcut
+
+  !ifndef LogDesktopShortcut
+    !insertmacro LogShortcut
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define LogDesktopShortcut "!insertmacro LogDesktopShortcutCall"
+
+    Function LogDesktopShortcut
+      Call LogShortcut
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro LogDesktopShortcutCall _FILE_NAME
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "DESKTOP"
+  Push "${_FILE_NAME}"
+  Call LogDesktopShortcut
+  !verbose pop
+!macroend
+
+/**
+ * Adds a QuickLaunch shortcut entry to the shortcuts log ini file.
+ *
+ * @param   _FILE_NAME
+ *          The shortcut file name (e.g. shortcut.lnk)
+ */
+!macro LogQuickLaunchShortcut
+
+  !ifndef LogQuickLaunchShortcut
+    !insertmacro LogShortcut
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define LogQuickLaunchShortcut "!insertmacro LogQuickLaunchShortcutCall"
+
+    Function LogQuickLaunchShortcut
+      Call LogShortcut
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro LogQuickLaunchShortcutCall _FILE_NAME
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "QUICKLAUNCH"
+  Push "${_FILE_NAME}"
+  Call LogQuickLaunchShortcut
+  !verbose pop
+!macroend
+
+/**
+ * Adds a Start Menu shortcut entry to the shortcuts log ini file.
+ *
+ * @param   _FILE_NAME
+ *          The shortcut file name (e.g. shortcut.lnk)
+ */
+!macro LogStartMenuShortcut
+
+  !ifndef LogStartMenuShortcut
+    !insertmacro LogShortcut
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define LogStartMenuShortcut "!insertmacro LogStartMenuShortcutCall"
+
+    Function LogStartMenuShortcut
+      Call LogShortcut
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro LogStartMenuShortcutCall _FILE_NAME
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "STARTMENU"
+  Push "${_FILE_NAME}"
+  Call LogStartMenuShortcut
+  !verbose pop
+!macroend
+
+/**
+ * Adds a Start Menu Programs shortcut entry to the shortcuts log ini file.
+ *
+ * @param   _FILE_NAME
+ *          The shortcut file name (e.g. shortcut.lnk)
+ */
+!macro LogSMProgramsShortcut
+
+  !ifndef LogSMProgramsShortcut
+    !insertmacro LogShortcut
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define LogSMProgramsShortcut "!insertmacro LogSMProgramsShortcutCall"
+
+    Function LogSMProgramsShortcut
+      Call LogShortcut
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro LogSMProgramsShortcutCall _FILE_NAME
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "SMPROGRAMS"
+  Push "${_FILE_NAME}"
+  Call LogSMProgramsShortcut
+  !verbose pop
+!macroend
+
+/**
+ * Adds the relative path from the Start Menu Programs directory for the
+ * application's Start Menu directory if it is different from the existing value
+ * to the shortcuts log ini file.
+ *
+ * @param   _REL_PATH_TO_DIR
+ *          The 
+ *
+ * $R9 = _REL_PATH_TO_DIR
+ */
+!macro LogSMProgramsDirRelPath _REL_PATH_TO_DIR
+  Push $R9
+
+  !insertmacro initShortcutsLog
+
+  ReadINIStr $R9 "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir"
+  StrCmp "$R9" "${_REL_PATH_TO_DIR}" +2 +1
+  WriteINIStr "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" "RelativePathToDir" "${_REL_PATH_TO_DIR}"
+
+  Pop $R9
+!macroend
+!define LogSMProgramsDirRelPath "!insertmacro LogSMProgramsDirRelPath"
+
+/**
+ * Copies the value for the relative path from the Start Menu programs directory
+ * (e.g. $SMPROGRAMS) to the Start Menu directory as it is stored in the
+ * shortcuts log ini file to the variable specified in the first parameter.
+ */
+!macro GetSMProgramsDirRelPath _VAR
+  ReadINIStr ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" "SMPROGRAMS" \
+             "RelativePathToDir"
+!macroend
+!define GetSMProgramsDirRelPath "!insertmacro GetSMProgramsDirRelPath"
+
+/**
+ * Copies the shortcuts log ini file path to the variable specified in the
+ * first parameter.
+ */
+!macro GetShortcutsLogPath _VAR
+  StrCpy ${_VAR} "$INSTDIR\uninstall\${SHORTCUTS_LOG}"
+!macroend
+!define GetShortcutsLogPath "!insertmacro GetShortcutsLogPath"
+
+/**
+ * Deletes the shortcuts log ini file.
+ */
+!macro DeleteShortcutsLogFile
+  ${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}"
+!macroend
+!define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile"
--- a/toolkit/mozapps/installer/windows/nsis/overrides.nsh
+++ b/toolkit/mozapps/installer/windows/nsis/overrides.nsh
@@ -9,17 +9,17 @@
 !ifmacrondef TEXTFUNC_VERBOSE
 !include TextFunc.nsh
 !endif
 
 !ifmacrondef FILEFUNC_VERBOSE
 !include FileFunc.nsh
 !endif
 
-; Modified version of Locate from the NSIS File Functions Header v3.2
+; Modified version of Locate from the NSIS File Functions Header v3.4
 ; This version has the calls to SetDetailsPrint and DetailsPrint commented out.
 ; See <NSIS App Dir>/include/FileFunc.nsh for more information
 !macro LocateNoDetails
   !ifndef ${_FILEFUNC_UN}LocateNoDetails
     !verbose push
     !verbose ${_FILEFUNC_VERBOSE}
     !define ${_FILEFUNC_UN}LocateNoDetails `!insertmacro ${_FILEFUNC_UN}LocateNoDetailsCall`
 
@@ -166,21 +166,23 @@
       StrCmp $9 'B0' +3
       GetLabelAddress $9 findfirst
       goto call
 ;      DetailPrint 'Search in: $R8'
 
       findfirst:
       FindFirst $0 $R7 '$R8\$4'
       IfErrors subdir
-      StrCmp $R7 '.' 0 +5
+      StrCmp $R7 '.' 0 dir
+      FindNext $0 $R7
+      StrCmp $R7 '..' 0 dir
       FindNext $0 $R7
-      StrCmp $R7 '..' 0 +3
-      FindNext $0 $R7
-      IfErrors subdir
+      IfErrors 0 dir
+      FindClose $0
+      goto subdir
 
       dir:
       IfFileExists '$R8\$R7\*.*' 0 file
       StrCpy $R6 ''
       StrCmp $3 'DE' +4
       StrCmp $3 'FDE' +3
       StrCmp $3 'FD' precall
       StrCmp $3 'F' findnext precall
@@ -239,41 +241,48 @@
       Pop $7
       Pop $6
       Pop $5
       Pop $4
       Pop $3
       Pop $2
       Pop $1
       Pop $0
-      IfErrors error
 
-      StrCmp $R9 'StopLocate' clearstack
+      IfErrors 0 +3
+      FindClose $0
+      goto error
+      StrCmp $R9 'StopLocate' 0 +3
+      FindClose $0
+      goto clearstack
       goto $9
 
       findnext:
       FindNext $0 $R7
       IfErrors 0 dir
       FindClose $0
 
       subdir:
       StrCpy $9 $7 2
       StrCmp $9 'G0' end
       FindFirst $0 $R7 '$R8\*.*'
-      StrCmp $R7 '.' 0 +5
+      StrCmp $R7 '.' 0 pushdir
+      FindNext $0 $R7
+      StrCmp $R7 '..' 0 pushdir
       FindNext $0 $R7
-      StrCmp $R7 '..' 0 +3
-      FindNext $0 $R7
-      IfErrors +7
+      IfErrors 0 pushdir
+      FindClose $0
+      StrCmp $8 0 end nextdir
 
+      pushdir:
       IfFileExists '$R8\$R7\*.*' 0 +3
       Push '$R8\$R7'
       IntOp $8 $8 + 1
       FindNext $0 $R7
-      IfErrors 0 -4
+      IfErrors 0 pushdir
       FindClose $0
       StrCmp $8 0 end nextdir
 
       error:
       SetErrors
 
       clearstack:
       StrCmp $8 0 end