AddToPath safe
From NSIS Wiki
Jump to navigationJump to search
Author: ChrFranke (talk, contrib) |
Description
Version: 1.0
This function adds a directory to the %PATH% variable. It is a safe version of AddToPath from Path Manipulation. It prevents truncation or corruption of %PATH% if string length exceeds ${NSIS_MAX_STRLEN}. It does not change the %PATH% in this case. No plugin is required.
The code was extracted from the smartmontools installer. Provided here separately by its author to allow usage without the GPLv2+ restrictions.
For a RemoveFromPath function, see Path Manipulation.
Usage
Example
Push "$INSTDIR\bin" Call AddToPath
Dependencies
!include "LogicLib.nsh" !include "WinMessages.nsh" Function StrStr ... FunctionEnd
For possible code of StrStr, see this page.
Function code
; Registry Entry for environment ; All users (Warning: length often exceeds 1024 if many packages are installed): ;!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' ; Current user only: !define Environ 'HKCU "Environment"' ; AddToPath - Appends dir to 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 0x80000001, t'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