2019. 2. 16. 09:54

How to make a volatile registry using NSIS script

There is no native way to make a volatile registry key in NSIS, so we have to call WINAPI directly.

 !define REG_OPTION_VOLATILE             1

Function MakeVolatileKey

    System::Call 'advapi32::RegCreateKeyEx(i ${HKEY_LOCAL_MACHINE}, t "Software\volatile", i0, i0, i ${REG_OPTION_VOLATILE}, i ${GENERIC_WRITE}, i0, *i.r1, *i)i.r0'
    ${If} $0 = 0
            System::Call 'advapi32::RegCloseKey(ir1)'
            WriteRegDWORD HKLM "Software\volatile" test 1
    ${EndIf}
 
FunctionEnd

But, there is one thing we have to consider on 64bit Windows.
If we add a code 'SetRegView 64' in order to avoid registry redirection, two registry keys are made:
    1. HKEY_LOCAL_MACHINE\SOFTWARE\Volatile (by WriteRegDWORD)
    2, HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\volatile (by RegCreateKeyEx)
 
SetRegView can not affect native registry APIs; then we should apply a KEY_WOW64_64KEY option to RegCreateKeyEx API.


!include WinCore.nsh
!include LogicLib.nsh
!include x64.nsh

!define REG_OPTION_VOLATILE             1
!define KEY_WOW64_64KEY                 0x0100


Function MakeVolatileKey

    ${If} ${RunningX64}
        IntOp $R0 ${GENERIC_WRITE} + ${KEY_WOW64_64KEY}
        SetRegView 64
    ${Else}
        Strcpy $R0 ${GENERIC_WRITE}       
        SetRegView 32
    ${EndIf}
 
    System::Call 'advapi32::RegCreateKeyEx(i ${HKEY_LOCAL_MACHINE}, t "Software\volatile", i0, i0, i ${REG_OPTION_VOLATILE}, i $R0, i0, *i.r1, *i)i.r0'
    ${If} $0 = 0
            System::Call 'advapi32::RegCloseKey(ir1)'
            WriteRegDWORD HKLM "Software\Volatile" test 1
    ${EndIf}
 
FunctionEnd