Files
coder/scripts/win-installer/path.nsh
Dean Sheather 9e80322fe5 fix: do not truncate system PATH in win installer (#5243)
The path.nsh script in the NSIS installer provided methods for adding
paths to the PATH and removing them. It would do this by reading the
current PATH value from the registry, adding the new value (if it
doesn't exist) and then writing it to the registry.

Unfortunately, it would read from the user's PATH and write the updated
result to the system PATH, which would remove important PATH entries
like the following in the process:

- C:\Windows\System32
- C:\Windows
- C:\Windows\System32\wbem
- C:\Windows\System32\WindowsPowerShell\v1.0
- C:\Windows\System32\OpenSSH
- C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR
- C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common

and would copy all user environment variables in their place. The
variables listed above were the ones missing from my machine when I
compared with a friend's machine.

Recommended course of action for affected users:
1. Add the paths listed above to your system PATH if they aren't there
   already and exist on your system.
2. Remove any paths that are in your user's PATH from your system PATH.

The existing installers for the last couple of versions of Coder have
been yanked from GitHub releases and this message will be included in
the release notes for the next patch.

Thanks to @cmor for finding and reporting this bug in #5240.
2022-12-02 09:56:49 +10:00

196 lines
4.4 KiB
NSIS

# PATH utilities. Taken from:
# https://www.smartmontools.org/browser/trunk/smartmontools/os_win32/installer.nsi?rev=5310#L689
; os_win32/installer.nsi - smartmontools install NSIS script
;
; Home page of code is: https://www.smartmontools.org
;
; Copyright (C) 2006-22 Christian Franke
;
; SPDX-License-Identifier: GPL-2.0-or-later
;--------------------------------------------------------------------
; Path functions
;
; Based on example from:
; http://nsis.sourceforge.net/Path_Manipulation
;
!include "WinMessages.nsh"
; Registry Entry for system environment (NT4,2000,XP)
!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
; AddToPath - Appends dir to system PATH
; (does not work on Win9x/ME)
;
; Usage:
; Push "dir"
; Call AddToPath
Function AddToPath
Exch $0
Push $1
Push $2
Push $3
Push $4
; NSIS ReadRegStr returns empty string on string overflow
; Native calls are used here to check actual length of PATH
; $4 = RegOpenKey(HKEY_CURRENT_USER, "Environment", &$3)
System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4"
IntCmp $4 0 0 done done
; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
; RegCloseKey($3)
System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
System::Call "advapi32::RegCloseKey(i $3)"
${If} $4 = 234 ; ERROR_MORE_DATA
DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" /SD IDOK
Goto done
${EndIf}
${If} $4 <> 0 ; NO_ERROR
${If} $4 <> 2 ; ERROR_FILE_NOT_FOUND
DetailPrint "AddToPath: unexpected error code $4"
Goto done
${EndIf}
StrCpy $1 ""
${EndIf}
; Check if already in PATH
Push "$1;"
Push "$0;"
Call StrStr
Pop $2
StrCmp $2 "" 0 done
Push "$1;"
Push "$0\;"
Call StrStr
Pop $2
StrCmp $2 "" 0 done
; Prevent NSIS string overflow
StrLen $2 $0
StrLen $3 $1
IntOp $2 $2 + $3
IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
${If} $2 > ${NSIS_MAX_STRLEN}
DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}." /SD IDOK
Goto done
${EndIf}
; Append dir to PATH
DetailPrint "Add to PATH: $0"
StrCpy $2 $1 1 -1
${If} $2 == ";"
StrCpy $1 $1 -1 ; remove trailing ';'
${EndIf}
${If} $1 != "" ; no leading ';'
StrCpy $0 "$1;$0"
${EndIf}
WriteRegExpandStr ${Environ} "PATH" $0
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
done:
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; RemoveFromPath - Removes dir from system PATH
;
; Usage:
; Push "dir"
; Call RemoveFromPath
Function un.RemoveFromPath
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
ReadRegStr $1 ${Environ} "PATH"
StrCpy $5 $1 1 -1
${If} $5 != ";"
StrCpy $1 "$1;" ; ensure trailing ';'
${EndIf}
Push $1
Push "$0;"
Call un.StrStr
Pop $2 ; pos of our dir
StrCmp $2 "" done
DetailPrint "Remove from PATH: $0"
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
${If} $5 == ";"
StrCpy $3 $3 -1 ; remove trailing ';'
${EndIf}
WriteRegExpandStr ${Environ} "PATH" $3
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
done:
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; StrStr - find substring in a string
;
; Usage:
; Push "this is some string"
; Push "some"
; Call StrStr
; Pop $0 ; "some string"
!macro StrStr un
Function ${un}StrStr
Exch $R1 ; $R1=substring, stack=[old$R1,string,...]
Exch ; stack=[string,old$R1,...]
Exch $R2 ; $R2=string, stack=[old$R2,old$R1,...]
Push $R3
Push $R4
Push $R5
StrLen $R3 $R1
StrCpy $R4 0
; $R1=substring, $R2=string, $R3=strlen(substring)
; $R4=count, $R5=tmp
${Do}
StrCpy $R5 $R2 $R3 $R4
${IfThen} $R5 == $R1 ${|} ${ExitDo} ${|}
${IfThen} $R5 == "" ${|} ${ExitDo} ${|}
IntOp $R4 $R4 + 1
${Loop}
StrCpy $R1 $R2 "" $R4
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Exch $R1 ; $R1=old$R1, stack=[result,...]
FunctionEnd
!macroend
!insertmacro StrStr ""
!insertmacro StrStr "un."