+;;;; SetAutoClose true
+${SectionEnd}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Path Manipulation functions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+!verbose 3
+!include "WinMessages.nsh"
+!verbose 4
+
+; AddToPath - Adds the given dir to the search path.
+; Input - head of the stack
+; Note - Win9x systems requires reboot
+
+${Function} SDCC.AddToPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+
+ ; don't add if the path doesn't exist
+ ${If} ${FileExists} $0
+ Call SDCC.IsNT
+ Pop $4
+ ${If} $4 != 1
+ ; Not on NT: read PATH from environment variable
+ ReadEnvStr $1 PATH
+ ${Else}
+ ; On NT: read PATH from registry
+ ReadRegStr $1 HKCU "Environment" "PATH"
+ ${EndIf}
+
+ ${StrStr} $2 "$1;" "$0;"
+ ${If} $2 == ""
+ ${StrStr} $2 "$1;" "$0\;"
+ ${If} $2 == ""
+ GetFullPathName /SHORT $3 $0
+ ${StrStr} $2 "$1;" "$3;"
+ ${If} $2 == ""
+ ${StrStr} $2 "$1;" "$03\;"
+ ${If} $2 == ""
+ ${If} $4 != 1
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" a
+ FileSeek $1 -1 END
+ FileReadByte $1 $2
+ ${If} $2 = 26 ; DOS EOF
+ FileSeek $1 -1 END ; write over EOF
+ ${Endif}
+ ${DebugMsg} "adding line $\r$\nSET PATH=%PATH%;$3$\r$\n"
+ FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
+ FileClose $1
+ ${DebugMsg} "SetRebootFlag true"
+ SetRebootFlag true
+ ${Else}
+ ;System PATH variable is at:
+ ;HKLM "/SYSTEM/CurrentControlSet/Control/Session Manager/Environment" "Path"
+ ReadRegStr $1 HKCU "Environment" "PATH"
+ StrCpy $2 $1 1 -1 ; copy last char
+ ${If} $2 == ";" ; if last char == ;
+ StrCpy $1 $1 -1 ; remove last char
+ ${Endif}
+ ${If} $1 != ""
+ StrCpy $0 "$1;$0"
+ ${Endif}
+ WriteRegExpandStr HKCU "Environment" "PATH" $0
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ ${Endif}
+ ${Endif}
+ ${Endif}
+ ${Endif}
+ ${Endif}
+ ${EndIf}
+
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+${FunctionEnd}
+
+; RemoveFromPath - Remove a given dir from the path
+; Input: head of the stack
+
+!macro SDCC.RemoveFromPath un
+${Function} ${un}SDCC.RemoveFromPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+ Push $5
+ Push $6
+
+ IntFmt $6 "%c" 26 ; DOS EOF
+
+ Call ${un}SDCC.IsNT
+ Pop $1
+ ${If} $1 != 1
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" r
+ GetTempFileName $4
+ FileOpen $2 $4 w
+ GetFullPathName /SHORT $0 $0
+ StrCpy $0 "SET PATH=%PATH%;$0"
+
+ nextLine:
+ ; copy all lines except the line containing "SET PATH=%PATH%;$0"
+ ; from autoexec.bat to the temporary file
+ ClearErrors
+ FileRead $1 $3
+ ${IfNot} ${Errors}
+ StrCpy $5 $3 1 -1 ; read last char
+ ${If} $5 == $6 ; if DOS EOF
+ StrCpy $3 $3 -1 ; remove DOS EOF so we can compare
+ ${EndIf}
+ ${If} $3 != "$0$\r$\n"
+ ${AndIf} $3 != "$0$\n"
+ ${AndIf} $3 != "$0"
+ FileWrite $2 $3
+ Goto nextLine
+ ${Else}
+ ; This is the line I'm looking for:
+ ; don't copy it
+ ${DebugMsg} "removing line $0"
+ ${DebugMsg} "SetRebootFlag true"
+ SetRebootFlag true
+ Goto nextLine
+ ${EndIf}
+ ${EndIf}
+
+ FileClose $2
+ FileClose $1
+ StrCpy $1 $WINDIR 2
+ Delete "$1\autoexec.bat"
+ CopyFiles /SILENT $4 "$1\autoexec.bat"
+ Delete $4
+ ${Else}
+ ;System PATH variable is at:
+ ;HKLM "/SYSTEM/CurrentControlSet/Control/Session Manager/Environment" "Path"
+ ReadRegStr $1 HKCU "Environment" "PATH"
+ StrCpy $5 $1 1 -1 ; copy last char
+ ${If} $5 != ";" ; if last char != ;
+ StrCpy $1 "$1;" ; append ;
+ ${EndIf}
+ Push $1
+ Push "$0;"
+ Call ${un}StrStr ; Find `$0;` in $1
+ Pop $2 ; pos of our dir
+ ${If} $2 != ""
+ ; it is in path:
+ ; $0 - path to add
+ ; $1 - path var
+ StrLen $3 "$0;"
+ StrLen $4 $2
+ StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove
+ StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
+ StrCpy $3 $5$6
+
+ StrCpy $5 $3 1 -1 ; copy last char
+ ${If} $5 == ";" ; if last char == ;
+ StrCpy $3 $3 -1 ; remove last char
+ ${EndIf}
+ ${If} $3 != ""
+ ; New PATH not empty: update the registry
+ WriteRegExpandStr HKCU "Environment" "PATH" $3
+ ${Else}
+ ; New PATH empty: remove from the registry
+ DeleteRegValue HKCU "Environment" "PATH"
+ ${EndIf}
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ ${Endif}
+ ${Endif}
+
+ Pop $6
+ Pop $5
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+${FunctionEnd}
+!macroend
+!insertmacro SDCC.RemoveFromPath ""
+!insertmacro SDCC.RemoveFromPath "un."
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Utility Functions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; IsNT
+; no input
+; output, top of the stack = 1 if NT or 0 if not
+;
+; Usage:
+; Call IsNT
+; Pop $R0
+; ($R0 at this point is 1 or 0)
+
+!macro SDCC.IsNT un
+${Function} ${un}SDCC.IsNT
+ Push $R0
+ ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
+ ${If} $R0 == ""
+ ; we are not NT.
+ Pop $R0
+ Push 0
+ ${Else}
+ ; NT!!!
+ Pop $R0
+ Push 1
+ ${EndIf}
+${FunctionEnd}
+!macroend
+!insertmacro SDCC.IsNT ""
+!insertmacro SDCC.IsNT "un."
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Uninstall/Reinstall page functions ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+!ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD
+
+Var ReinstallPageCheck
+
+${Function} SDCC.PageReinstall
+
+ ReadRegStr $R0 ${SDCC_ROOT_KEY} "Software\${PRODUCT_NAME}" ""
+
+ ${If} $R0 == ""
+ ReadRegStr $R0 ${UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString"
+ ${If} $R0 == ""
+ Abort
+ ${EndIf}
+ ${EndIf}
+
+ ReadRegDWORD $R0 ${SDCC_ROOT_KEY} "Software\${PRODUCT_NAME}" "VersionMajor"
+ ReadRegDWORD $R1 ${SDCC_ROOT_KEY} "Software\${PRODUCT_NAME}" "VersionMinor"
+ ReadRegDWORD $R2 ${SDCC_ROOT_KEY} "Software\${PRODUCT_NAME}" "VersionRevision"
+ ReadRegDWORD $R3 ${SDCC_ROOT_KEY} "Software\${PRODUCT_NAME}" "VersionBuild"
+ StrCpy $R0 $R0.$R1.$R2.$R3
+
+ ${VersionCompare} ${VER_MAJOR}.${VER_MINOR}.${VER_REVISION}.${VER_BUILD} $R0 $R0
+ ${If} $R0 == 0
+ StrCpy $R1 "${PRODUCT_NAME} ${PRODUCT_VERSION} is already installed. Select the operation you want to perform and click Next to continue."
+ StrCpy $R2 "Add/Reinstall components"
+ StrCpy $R3 "Uninstall ${PRODUCT_NAME}"
+ !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform."
+ StrCpy $R0 "2"
+ ${ElseIf} $R0 == 1
+ StrCpy $R1 "An older version of ${PRODUCT_NAME} is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
+ StrCpy $R2 "Uninstall before installing"
+ StrCpy $R3 "Do not uninstall"
+ !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install ${PRODUCT_NAME}."
+ StrCpy $R0 "1"
+ ${ElseIf} $R0 == 2
+ StrCpy $R1 "A newer version of ${PRODUCT_NAME} is already installed! It is not recommended that you install an older version. If you really want to install this older version, it's better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
+ StrCpy $R2 "Uninstall before installing"
+ StrCpy $R3 "Do not uninstall"
+ !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install ${PRODUCT_NAME}."
+ StrCpy $R0 "1"
+ ${Else}
+ Abort
+ ${EndIf}
+
+ nsDialogs::Create /NOUNLOAD 1018
+
+ ${NSD_CreateLabel} 0 0 100% 24u $R1
+ Pop $R1
+
+ ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2
+ Pop $R2
+ ${NSD_OnClick} $R2 SDCC.PageReinstallUpdateSelection
+
+ ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3
+ Pop $R3
+ ${NSD_OnClick} $R3 SDCC.PageReinstallUpdateSelection
+
+ ${If} $ReinstallPageCheck != 2
+ SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0
+ ${Else}
+ SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0
+ ${EndIf}
+
+ nsDialogs::Show
+
+${FunctionEnd}
+
+${Function} SDCC.PageReinstallUpdateSelection
+
+ Pop $R1
+
+ ${NSD_GetState} $R2 $R1
+
+ ${If} $R1 == ${BST_CHECKED}
+ StrCpy $ReinstallPageCheck 1
+ ${Else}
+ StrCpy $ReinstallPageCheck 2
+ ${EndIf}
+
+${FunctionEnd}
+
+${Function} SDCC.PageLeaveReinstall
+
+ ${NSD_GetState} $R2 $R1
+
+ ${DebugMsg} "R0 = $R0, R1 = $R1, R2 = $R2"
+
+ ${If} $R0 == "1"
+ ${AndIf} $R1 != "1"
+ Goto reinst_done
+ ${EndIf}
+
+ ${If} $R0 == "2"
+ ${AndIf} $R1 == 1
+ Goto reinst_done
+ ${EndIf}
+
+ ReadRegStr $R1 ${UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString"
+
+ ;Run uninstaller
+ HideWindow
+
+ ${If} $R0 == "2"
+ ; Uninstall only: uninstaller should be removed
+ ClearErrors
+ ; ExecWait doesn't wait if _?=$INSTDIR is not defined!
+ ExecWait '$R1'
+ Quit
+ ${Else}
+ ; Uninstal & Reinstall: uninstaller will be rewritten
+ ClearErrors
+ ; ExecWait doesn't wait if _?=$INSTDIR is not defined!
+ ExecWait '$R1 _?=$INSTDIR'
+ ${EndIf}
+
+ BringToFront
+
+reinst_done: