NSIS Header RegOps2Submitted by wraithdu on April 2, 2008 - 11:22pm
Two registry functions. First is a RegKeyExists function that will determine if a reg key exists without using the Registry plugin. The next one builds on that function, and can use SetACL to reset permissions on a key to allow you to delete it, ie the Enum\Root\LEGACY_ keys. Should be self-explanatory how to use them. They use the same format as the Registry plugin, ie a full key path. Release Notes:
/**************************************************************
* Copyright Erik Pilsits 2008
***************************************************************
* ${RegKeyExists} "[full key path]" $var
*
* $var 0 - key does not exist
* 1 - key exists
***************************************************************
* Var setacl
* StrCpy $setacl "X:\path\to\SetACL.exe"
*
* ${SetACL_DeleteKey} "[full key path]" $var1 $var2
*
* $var1 [number] - nsExec return code
* "fail" - operation failed (key does not exist)
* $var2 0 - delete succeeded
* non-zero | "fail" - delete failed
***************************************************************
* LONG WINAPI RegOpenKeyEx(
* __in HKEY hKey,
* __in_opt LPCTSTR lpSubKey,
* __reserved DWORD ulOptions,
* __in REGSAM samDesired,
* __out PHKEY phkResult
* );
*
* LONG WINAPI RegCloseKey(
* __in HKEY hKey
* );
*
* LSTATUS SHDeleteKey(
* __in HKEY hkey,
* __in LPCTSTR pszSubKey
* );
***************************************************************/
!include LogicLib.nsh
!include WordFunc.nsh
!insertmacro WordFind
!define KEY_ALL_ACCESS "0xF003F"
!define KEY_CREATE_SUB_KEY "0x0004"
!define KEY_ENUMERATE_SUB_KEYS "0x0008"
!define KEY_QUERY_VALUE "0x0001"
!define KEY_READ "0x20019"
!define KEY_SET_VALUE "0x0002"
!define KEY_WRITE "0x20006"
!define HKCR "0x80000000"
!define HKCU "0x80000001"
!define HKLM "0x80000002"
!define HKU "0x80000003"
!define HKPD "0x80000004"
!define HKCC "0x80000005"
!define HKDD "0x80000006"
!define RegKeyExists "!insertmacro _RegKeyExists"
!define SetACL_DeleteKey "!insertmacro _SetACL_DeleteKey"
Function SplitKeyPath
Exch $0 ; save $0, Pop keypath
Push $1
${WordFind} $0 "\" "+1" $1 ; key root
Push $1
Exch 2
${WordFind} $0 "\" "+1}" $1 ; subkey
Pop $0 ; put root key and subkey on stack
Exch $1
FunctionEnd
Function GetRootHandle
Exch $0 ; save $0, Pop root key
${Select} $0
${Case2} "HKCR" "HKEY_CLASSES_ROOT"
StrCpy $0 ${HKCR}
${Case2} "HKCU" "HKEY_CURRENT_USER"
StrCpy $0 ${HKCU}
${Case2} "HKLM" "HKEY_LOCAL_MACHINE"
StrCpy $0 ${HKLM}
${Case2} "HKU" "HKEY_USERS"
StrCpy $0 ${HKU}
${Case2} "HKPD" "HKEY_PERFORMANCE_DATA"
StrCpy $0 ${HKPD}
${Case2} "HKCC" "HKEY_CURRENT_CONFIG"
StrCpy $0 ${HKCC}
${Case2} "HKDD" "HKEY_DYN_DATA"
StrCpy $0 ${HKDD}
${EndSelect}
Exch $0 ; put handle on stack
FunctionEnd
!macro _RegKeyExists keypath outVar
Push $0
Push $1
Push "${keypath}"
Call SplitKeyPath
Pop $1 ; subkey
; stack already has root key
Call GetRootHandle
Pop $0 ; root key handle
; try to open key
System::Call /NOUNLOAD 'Advapi32::RegOpenKeyEx(i r0, t r1, i 0, i ${KEY_READ}, *i .r1) i .r0'
; return values
${If} $0 = 0 ; success
Push 1
System::Call 'Advapi32::RegCloseKey(i r1)' ; close handle
${Else}
Push 0
System::Free 0 ; unload system dll
${EndIf}
Exch 2
Pop $0
Pop $1
Pop ${outVar}
!macroend
!macro _SetACL_DeleteKey keypath outVar1 outVar2
Push $0
Push $1
${RegKeyExists} "${keypath}" $0
${If} $0 = 1
; set permissions on key
nsExec::Exec '"$setacl" -on "${keypath}" -ot reg -rec yes \
-actn clear -clr "dacl" \
-actn setowner -ownr "n:Administrators" \
-actn ace -ace "n:Everyone;p:full"'
Push "${keypath}"
Call SplitKeyPath
Pop $1 ; subkey
; stack already has root key
Call GetRootHandle
Pop $0 ; root key handle
; delete key
System::Call 'shlwapi::SHDeleteKey(i r0, t r1)i .s'
${Else}
Push "fail"
Push "fail"
${EndIf}
Exch 3
Pop $0
Exch
Pop $1
Pop ${outVar1}
Pop ${outVar2}
!macroend
( categories: )
|

Updated.
Updated.