Fix for NSIS 3.05 by replacing the dated macro for PATH var manipulation with the very recent plugin "EnvVar".

Make sure that the certificate updater does NOTHING on anything newer than XP.
This commit is contained in:
Daniel Reimer 2019-12-26 18:55:47 +01:00
parent cf40c685ef
commit 9f4cda089c
2 changed files with 50 additions and 373 deletions

View File

@ -1,327 +0,0 @@
/**
* EnvVarUpdate.nsh
* : Environmental Variables: append, prepend, and remove entries
*
* WARNING: If you use StrFunc.nsh header then include it before this file
* with all required definitions. This is to avoid conflicts
*
* Usage:
* ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString"
*
* Credits:
* Version 1.0
* * Cal Turney (turnec2)
* * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this
* function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar,
* WriteEnvStr, and un.DeleteEnvStr
* * Diego Pedroso (deguix) for StrTok
* * Kevin English (kenglish_hi) for StrContains
* * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry
* (dandaman32) for StrReplace
*
* Version 1.1 (compatibility with StrFunc.nsh)
* * techtonik
*
* http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries
*
*/
!ifndef ENVVARUPDATE_FUNCTION
!define ENVVARUPDATE_FUNCTION
!verbose push
!verbose 3
!include "LogicLib.nsh"
!include "WinMessages.NSH"
!include "StrFunc.nsh"
; ---- Fix for conflict if StrFunc.nsh is already includes in main file -----------------------
!macro _IncludeStrFunction StrFuncName
!ifndef ${StrFuncName}_INCLUDED
${${StrFuncName}}
!endif
!ifndef Un${StrFuncName}_INCLUDED
${Un${StrFuncName}}
!endif
!define un.${StrFuncName} "${Un${StrFuncName}}"
!macroend
!insertmacro _IncludeStrFunction StrTok
!insertmacro _IncludeStrFunction StrStr
!insertmacro _IncludeStrFunction StrRep
; ---------------------------------- Macro Definitions ----------------------------------------
!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
Push "${EnvVarName}"
Push "${Action}"
Push "${RegLoc}"
Push "${PathString}"
Call EnvVarUpdate
Pop "${ResultVar}"
!macroend
!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"'
!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString
Push "${EnvVarName}"
Push "${Action}"
Push "${RegLoc}"
Push "${PathString}"
Call un.EnvVarUpdate
Pop "${ResultVar}"
!macroend
!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"'
; ---------------------------------- Macro Definitions end-------------------------------------
;----------------------------------- EnvVarUpdate start----------------------------------------
!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
!define hkcu_current_user 'HKCU "Environment"'
!macro EnvVarUpdate UN
Function ${UN}EnvVarUpdate
Push $0
Exch 4
Exch $1
Exch 3
Exch $2
Exch 2
Exch $3
Exch
Exch $4
Push $5
Push $6
Push $7
Push $8
Push $9
Push $R0
/* After this point:
-------------------------
$0 = ResultVar (returned)
$1 = EnvVarName (input)
$2 = Action (input)
$3 = RegLoc (input)
$4 = PathString (input)
$5 = Orig EnvVar (read from registry)
$6 = Len of $0 (temp)
$7 = tempstr1 (temp)
$8 = Entry counter (temp)
$9 = tempstr2 (temp)
$R0 = tempChar (temp) */
; Step 1: Read contents of EnvVarName from RegLoc
;
; Check for empty EnvVarName
${If} $1 == ""
SetErrors
DetailPrint "ERROR: EnvVarName is blank"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Check for valid Action
${If} $2 != "A"
${AndIf} $2 != "P"
${AndIf} $2 != "R"
SetErrors
DetailPrint "ERROR: Invalid Action - must be A, P, or R"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
${If} $3 == HKLM
ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5
${ElseIf} $3 == HKCU
ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5
${Else}
SetErrors
DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"'
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Check for empty PathString
${If} $4 == ""
SetErrors
DetailPrint "ERROR: PathString is blank"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Make sure we've got some work to do
${If} $5 == ""
${AndIf} $2 == "R"
SetErrors
DetailPrint "$1 is empty - Nothing to remove"
Goto EnvVarUpdate_Restore_Vars
${EndIf}
; Step 2: Scrub EnvVar
;
StrCpy $0 $5 ; Copy the contents to $0
; Remove spaces around semicolons (NOTE: spaces before the 1st entry or
; after the last one are not removed here but instead in Step 3)
${If} $0 != "" ; If EnvVar is not empty ...
${Do}
${${UN}StrStr} $7 $0 " ;"
${If} $7 == ""
${ExitDo}
${EndIf}
${${UN}StrRep} $0 $0 " ;" ";" ; Remove '<space>;'
${Loop}
${Do}
${${UN}StrStr} $7 $0 "; "
${If} $7 == ""
${ExitDo}
${EndIf}
${${UN}StrRep} $0 $0 "; " ";" ; Remove ';<space>'
${Loop}
${Do}
${${UN}StrStr} $7 $0 ";;"
${If} $7 == ""
${ExitDo}
${EndIf}
${${UN}StrRep} $0 $0 ";;" ";"
${Loop}
; Remove a leading or trailing semicolon from EnvVar
StrCpy $7 $0 1 0
${If} $7 == ";"
StrCpy $0 $0 "" 1 ; Change ';<EnvVar>' to '<EnvVar>'
${EndIf}
StrLen $6 $0
IntOp $6 $6 - 1
StrCpy $7 $0 1 $6
${If} $7 == ";"
StrCpy $0 $0 $6 ; Change ';<EnvVar>' to '<EnvVar>'
${EndIf}
; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug
${EndIf}
/* Step 3. Remove all instances of the target path/string (even if "A" or "P")
$6 = bool flag (1 = found and removed PathString)
$7 = a string (e.g. path) delimited by semicolon(s)
$8 = entry counter starting at 0
$9 = copy of $0
$R0 = tempChar */
${If} $5 != "" ; If EnvVar is not empty ...
StrCpy $9 $0
StrCpy $0 ""
StrCpy $8 0
StrCpy $6 0
${Do}
${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter
${If} $7 == "" ; If we've run out of entries,
${ExitDo} ; were done
${EndIf} ;
; Remove leading and trailing spaces from this entry (critical step for Action=Remove)
${Do}
StrCpy $R0 $7 1
${If} $R0 != " "
${ExitDo}
${EndIf}
StrCpy $7 $7 "" 1 ; Remove leading space
${Loop}
${Do}
StrCpy $R0 $7 1 -1
${If} $R0 != " "
${ExitDo}
${EndIf}
StrCpy $7 $7 -1 ; Remove trailing space
${Loop}
${If} $7 == $4 ; If string matches, remove it by not appending it
StrCpy $6 1 ; Set 'found' flag
${ElseIf} $7 != $4 ; If string does NOT match
${AndIf} $0 == "" ; and the 1st string being added to $0,
StrCpy $0 $7 ; copy it to $0 without a prepended semicolon
${ElseIf} $7 != $4 ; If string does NOT match
${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0,
StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon
${EndIf} ;
IntOp $8 $8 + 1 ; Bump counter
${Loop} ; Check for duplicates until we run out of paths
${EndIf}
; Step 4: Perform the requested Action
;
${If} $2 != "R" ; If Append or Prepend
${If} $6 == 1 ; And if we found the target
DetailPrint "Target is already present in $1. It will be removed and"
${EndIf}
${If} $0 == "" ; If EnvVar is (now) empty
StrCpy $0 $4 ; just copy PathString to EnvVar
${If} $6 == 0 ; If found flag is either 0
${OrIf} $6 == "" ; or blank (if EnvVarName is empty)
DetailPrint "$1 was empty and has been updated with the target"
${EndIf}
${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty),
StrCpy $0 $0;$4 ; append PathString
${If} $6 == 1
DetailPrint "appended to $1"
${Else}
DetailPrint "Target was appended to $1"
${EndIf}
${Else} ; If Prepend (and EnvVar is not empty),
StrCpy $0 $4;$0 ; prepend PathString
${If} $6 == 1
DetailPrint "prepended to $1"
${Else}
DetailPrint "Target was prepended to $1"
${EndIf}
${EndIf}
${Else} ; If Action = Remove
${If} $6 == 1 ; and we found the target
DetailPrint "Target was found and removed from $1"
${Else}
DetailPrint "Target was NOT found in $1 (nothing to remove)"
${EndIf}
${If} $0 == ""
DetailPrint "$1 is now empty"
${EndIf}
${EndIf}
; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change
;
ClearErrors
${If} $3 == HKLM
WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section
${ElseIf} $3 == HKCU
WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section
${EndIf}
IfErrors 0 +4
MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3"
DetailPrint "Could not write updated $1 to $3"
Goto EnvVarUpdate_Restore_Vars
; "Export" our change
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
EnvVarUpdate_Restore_Vars:
;
; Restore the user's variables and return ResultVar
Pop $R0
Pop $9
Pop $8
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Push $0 ; Push my $0 (ResultVar)
Exch
Pop $0 ; Restore his $0
FunctionEnd
!macroend ; EnvVarUpdate UN
!insertmacro EnvVarUpdate ""
!insertmacro EnvVarUpdate "un."
;----------------------------------- EnvVarUpdate end----------------------------------------
!verbose pop
!endif

View File

@ -37,8 +37,8 @@ SetCompressor /FINAL /SOLID lzma
!include "InstallOptions.nsh"
!include "RosSourceDir.nsh"
!include "LogicLib.nsh"
!include "EnvVarUpdate.nsh"
!include "AddCertificateToStore.nsh"
!include "WinVer.nsh"
;;
;; Read our custom page ini, remove previous version and make sure only
@ -226,54 +226,57 @@ Section /o "AMD64 Compiler" SEC03
SectionEnd
Section /o "Add BIN folder to PATH variable (MSVC users)" SEC04
${EnvVarUpdate} $0 "PATH" "A" "HKCU" "$INSTDIR\bin"
EnVar::SetHKCU
EnVar::AddValue "PATH" "$INSTDIR\bin"
SectionEnd
Section /o "Update for GlobalSign Certificates (ONLY FOR XP users!!)" SEC05
SetOutPath "$INSTDIR\certs"
SetOverwrite try
File /r Components\certs\Root-E46.crt
File /r Components\certs\Root-R1.crt
File /r Components\certs\Root-R3.crt
File /r Components\certs\Root-R5.crt
File /r Components\certs\Root-R6.crt
File /r Components\certs\Root-R46.crt
${IfNot} ${AtLeastWinVista}
SetOutPath "$INSTDIR\certs"
SetOverwrite try
File /r Components\certs\Root-E46.crt
File /r Components\certs\Root-R1.crt
File /r Components\certs\Root-R3.crt
File /r Components\certs\Root-R5.crt
File /r Components\certs\Root-R6.crt
File /r Components\certs\Root-R46.crt
Push "$INSTDIR\certs\Root-R1.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R1 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R3.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R3 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R5.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R5 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R6.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R6 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-E46.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of E46 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R46.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R46 GlobalSign Root Certificate failed: $0"
Push "$INSTDIR\certs\Root-R1.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R1 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R3.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R3 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R5.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R5 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R6.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R6 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-E46.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of E46 GlobalSign Root Certificate failed: $0"
${EndIf}
Push "$INSTDIR\certs\Root-R46.crt"
Call AddCertificateToStore
Pop $0
${If} $0 != success
MessageBox MB_OK "Import of R46 GlobalSign Root Certificate failed: $0"
${EndIf}
${EndIf}
SectionEnd
@ -412,7 +415,8 @@ Section Uninstall
;;
;; Clean up PATH Variable.
;;
${un.EnvVarUpdate} $0 "PATH" "R" "HKCU" "$INSTDIR\bin"
EnVar::SetHKCU
EnVar::DeleteValue "PATH" "$INSTDIR\bin"
;;
;; Clean up installed files.