Added the HKCR32, HKCR64, HKCU32, HKCU64, HKLM32 and HKLM64 root keys and the experimental HK*ANY root keys.

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6871 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2017-06-06 19:51:43 +00:00
parent bcef20b32d
commit 94dd438510
9 changed files with 125 additions and 46 deletions

View file

@ -971,7 +971,7 @@ void ParamsIn(SystemProc *proc)
#endif
case PAT_CALLBACK:
// Generate new or use old callback
if (lstrlen(realbuf) > 0)
if (realbuf[0])
par->Value = (INT_PTR) CreateCallback((SystemProc*) StrToIntPtr(realbuf));
break;
case PAT_REGMEM:

View file

@ -8,9 +8,11 @@ Released on ? ?th, 2017
\S2{} Major Changes
\b Fixed RegTool Win9x bug
\b Fixed NSIS3 RegTool Win9x bug
\b Unsupported SetRegView mode fails all registry operations
\b Added the HKCR32, HKCR64, HKCU32, HKCU64, HKLM32 and HKLM64 root keys
\b Unsupported SetRegView mode now fails all registry operations
\b Added \R{execshellwait}{ExecShellWait}

View file

@ -182,6 +182,12 @@ Write a string to the registry. \e{root_key} must be one of:
\b \e{SHCTX} or \e{SHELL_CONTEXT}
\b \e{HKCR32} or \e{HKCR64}
\b \e{HKCU32} or \e{HKCU64}
\b \e{HKLM32} or \e{HKLM64}
If \e{root_key} is \e{SHCTX} or \e{SHELL_CONTEXT}, it will be replaced with \e{HKLM} if \R{setshellvarcontext}{SetShellVarContext} is set to \e{all} and with \e{HKCU} if \R{setshellvarcontext}{SetShellVarContext} is set to \e{current}.
The error flag is set if the string could not be written to the registry. The type of the string will be REG_SZ for \R{writeregstr}{WriteRegStr}, or REG_EXPAND_STR for \R{writeregexpandstr}{WriteRegExpandStr}. If the registry key doesn't exist it will be created.
@ -200,7 +206,7 @@ Writes a multi-string value. The /REGEDIT5 switch must be used and specifies tha
\c 32|64|\\<b\\>default\\</b\\>|lastused
Sets the registry view affected by \R{registry}{registry commands}. On 64-bit versions of Windows there are two views; one for 32-bit applications and one for 64-bit applications. By default, 32-bit applications running on 64-bit systems (WOW64) only have access to the 32-bit view. Using \c{SetRegView 64} allows the installer to access keys in the 64-bit view of the registry.
Sets the registry view affected by \R{registry}{registry commands} (root keys with a 32/64 suffix are not affected). On 64-bit versions of Windows there are two views; one for 32-bit applications and one for 64-bit applications. By default, 32-bit applications running on 64-bit systems (WOW64) only have access to the 32-bit view. Using \c{SetRegView 64} allows the installer to access keys in the 64-bit view of the registry. Registry operations will fail if the selected view is not supported by Windows.
Affects \R{deleteregkey}{DeleteRegKey}, \R{deleteregvalue}{DeleteRegValue}, \R{enumregkey}{EnumRegKey}, \R{enumregvalue}{EnumRegValue}, \R{readregdword}{ReadRegDWORD}, \R{readregstr}{ReadRegStr}, \R{writeregbin}{WriteRegBin}, \R{writeregdword}{WriteRegDWORD}, \R{writeregstr}{WriteRegStr} and \R{writeregexpandstr}{WriteRegExpandStr}.
@ -209,12 +215,17 @@ Does not affect \R{ainstalldirregkey}{InstallDirRegKey}. Instead, the registry m
\c SetRegView 32
\c ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir
\c DetailPrint $0 # prints C:\Program Files (x86)
\c SetRegView 64
\c ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir
\c DetailPrint $0 # prints C:\Program Files
\c !include x64.nsh
\c ${If} ${RunningX64}
\c SetRegView 64
\c ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir
\c DetailPrint $0 # prints C:\Program Files
\c ${EndIf}
\c Function .onInit
\c SetRegView 64
\c ReadRegStr $INSTDIR HKLM Software\NSIS ""
\c SetRegView 32
\c ${If} ${RunningX64}
\c SetRegView 64
\c ReadRegStr $INSTDIR HKLM Software\NSIS ""
\c SetRegView Default
\c ${EndIf}
\c FunctionEnd

View file

@ -158,8 +158,8 @@ static TCHAR * NSISCALL GetStringFromParm(int id_)
#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
static HKEY NSISCALL GetRegRootKey(int RootKey)
{
if (RootKey != (int) HKSHCTX) return (HKEY) (UINT_PTR) RootKey;
return (HKEY) ((UINT_PTR) HKEY_CURRENT_USER + g_exec_flags.all_user_var); // SHCTX: HKEY_CURRENT_USER + 1 == HKEY_LOCAL_MACHINE
if (RootKey < 0) return (HKEY) (UINT_PTR) RootKey;
return (HKEY) ((UINT_PTR) HKEY_CURRENT_USER + RootKey + g_exec_flags.all_user_var); // SHCTX[32|64|ANY]: HKEY_CURRENT_USER + 1 == HKEY_LOCAL_MACHINE
}
static HKEY NSISCALL RegOpenScriptKey(REGSAM RS)
{
@ -175,20 +175,20 @@ static HKEY NSISCALL RegCreateScriptKey(int RootKey, LPCTSTR SubKey, REGSAM RS)
// RegDeleteKey on Win9x will delete a tree of keys, WinNT will only delete a key without subkeys.
// RegDeleteKeyEx on 32-bit Windows accepts but ignores the KEY_WOW64_xxKEY flags and always uses the
// one and only native key. Our RegKeyOpen will intentionally fail if a incompatible WoW64 flag is used.
#define RegDeleteScriptKey(RootKey, SubKey, Flags) RegDeleteScriptKeyWorker(GetRegRootKey(RootKey), (SubKey), (Flags))
static LONG NSISCALL RegDeleteScriptKeyWorker(HKEY hThisKey, LPCTSTR SubKey, UINT Flags)
#define DRTF_ONLYIFNOSUBKEYS DELREGKEY_ONLYIFNOSUBKEYS
static LONG NSISCALL DeleteRegTree(HKEY hThisKey, LPCTSTR SubKey, REGSAM SamviewAndFlags)
{
HKEY hKey;
UINT onlyifempty = Flags;
REGSAM viewsam = g_exec_flags.alter_reg_view; // Not using KEY_ALTERVIEW here because viewsam is also passed to RegDeleteKeyEx.
LONG retval = RegKeyOpen(hThisKey, SubKey, KEY_ENUMERATE_SUB_KEYS|viewsam, &hKey);
UINT onlyifempty = SamviewAndFlags & DRTF_ONLYIFNOSUBKEYS;
REGSAM samview = SamviewAndFlags & (KEY_WOW64_32KEY|KEY_WOW64_64KEY);
LONG retval = RegKeyOpen(hThisKey, SubKey, KEY_ENUMERATE_SUB_KEYS|samview, &hKey);
if (retval == ERROR_SUCCESS)
{
TCHAR child[MAX_PATH+1]; // NB - don't change this to static (recursive function)
while (RegEnumKey(hKey, 0, child, COUNTOF(child)) == ERROR_SUCCESS)
{
if (onlyifempty) return (RegCloseKey(hKey), !ERROR_SUCCESS);
if ((retval = RegDeleteScriptKeyWorker(hKey, child, Flags)) != ERROR_SUCCESS) break;
if ((retval = DeleteRegTree(hKey, child, SamviewAndFlags)) != ERROR_SUCCESS) break;
}
RegCloseKey(hKey);
{
@ -200,13 +200,20 @@ static LONG NSISCALL RegDeleteScriptKeyWorker(HKEY hThisKey, LPCTSTR SubKey, UIN
myGetProcAddress(MGA_RegDeleteKeyEx);
#endif
if (RDKE)
retval = RDKE(hThisKey, SubKey, viewsam, 0);
retval = RDKE(hThisKey, SubKey, samview, 0);
else
retval = RegDeleteKey(hThisKey, SubKey);
}
}
return retval;
}
static LONG NSISCALL RegDeleteScriptKey(int RootKey, LPCTSTR SubKey, REGSAM SamviewAndFlags)
{
HKEY hKey;
SamviewAndFlags |= KEY_FROMSCRIPT;
hKey = GetRegKeyAndSAM(GetRegRootKey(RootKey), &SamviewAndFlags);
return hKey ? DeleteRegTree(hKey, SubKey, SamviewAndFlags) : ERROR_INVALID_HANDLE; // ERROR_CANTOPEN?
}
#endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
// returns EXEC_ERROR on error
@ -1219,7 +1226,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
{
TCHAR *buf2=GetStringFromParm(0x22);
log_printf3(_T("DeleteRegKey: \"%s\\%s\""),rkn,buf2);
res = RegDeleteScriptKey(rootkey,buf2,parm4 >> 1); // Shifting away the TOK_DELETEREGKEY bit, onlyifempty is now the bottom bit (">> 1" is 1 byte smaller than "& 2")
res = RegDeleteScriptKey(rootkey,buf2,parm4 >> DELREGKEYFLAGSSHIFT); // SHR is 1 byte smaller than AND
}
if (res != ERROR_SUCCESS)
exec_error++;

View file

@ -155,7 +155,7 @@ enum
#endif
#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, ActionAndFlags]
EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, ActionAndFlags(DELREG*)]
EW_WRITEREG, // Write Registry value: 5, [RootKey(int),KeyName,ItemName,ItemData,typelen]
// typelen=1 for str, 2 for dword, 3 for binary, 0 for expanded str
EW_READREGSTR, // ReadRegStr: 5 [output, rootkey(int), keyname, itemname, ==1?int::str]
@ -504,13 +504,37 @@ typedef struct {
# define ctlcolors ctlcolors32
#endif
// constants for myDelete (util.c)
#define DEL_DIR 1
#define DEL_RECURSE 2
#define DEL_REBOOT 4
#define DEL_SIMPLE 8
#define REGROOTVIEW32 0x40000000
#define REGROOTVIEW64 0x20000000
#define REGROOTVIEWTOSAMVIEW(rv) ( ((UINT_PTR)(rv)&(REGROOTVIEW32|REGROOTVIEW64)) >> 21 ) // REGROOTVIEWxx to KEY_WOW64_xxKEY
#define IsRegRootkeyForcedView(hKey) ( ((UINT_PTR) (hKey) & (REGROOTVIEW32|REGROOTVIEW64)) )
#define MAKEREGROOTVIEW(r, fv) ( (HKEY) ((UINT_PTR)(r) | (fv)) )
#define HKSHCTX ( (HKEY) 0 ) // Converted to HKCU or HKLM by GetRegRootKey
#define HKSHCTX32 MAKEREGROOTVIEW(HKSHCTX, REGROOTVIEW32)
#define HKSHCTX64 MAKEREGROOTVIEW(HKSHCTX, REGROOTVIEW64)
#define HKCR32 MAKEREGROOTVIEW(HKEY_CLASSES_ROOT, REGROOTVIEW32)
#define HKCR64 MAKEREGROOTVIEW(HKEY_CLASSES_ROOT, REGROOTVIEW64)
#define HKCU32 MAKEREGROOTVIEW(HKEY_CURRENT_USER, REGROOTVIEW32)
#define HKCU64 MAKEREGROOTVIEW(HKEY_CURRENT_USER, REGROOTVIEW64)
#define HKLM32 MAKEREGROOTVIEW(HKEY_LOCAL_MACHINE, REGROOTVIEW32)
#define HKLM64 MAKEREGROOTVIEW(HKEY_LOCAL_MACHINE, REGROOTVIEW64)
#define HKSHCTXANY MAKEREGROOTVIEW(HKSHCTX, REGROOTVIEW32|REGROOTVIEW64)
#define HKCRANY MAKEREGROOTVIEW(HKEY_CLASSES_ROOT, REGROOTVIEW32|REGROOTVIEW64)
#define HKCUANY MAKEREGROOTVIEW(HKEY_CURRENT_USER, REGROOTVIEW32|REGROOTVIEW64)
#define HKLMANY MAKEREGROOTVIEW(HKEY_LOCAL_MACHINE, REGROOTVIEW32|REGROOTVIEW64)
#define DELREG_VALUE 0 // TOK_DELETEREGVALUE
#define DELREG_KEY 1 // TOK_DELETEREGKEY
#define DELREGKEY_ONLYIFNOSUBKEYS 1 // Shifted and stored as 2 in the binary for compatibility with <= 3.1
#define DELREGKEYFLAGSSHIFT 1 // parm4 is shifted so exehead can remove the DELREG_KEY bit
#ifdef NSIS_SUPPORT_CREATESHORTCUT
#define CS_HK_MASK 0xffff0000 // HotKey
@ -523,6 +547,7 @@ typedef struct {
#define CS_II_MAX (CS_II_MASK >> CS_II_SHIFT)
#endif
// special escape characters used in strings: (we use control codes in order to minimize conflicts with normal characters)
#define NS_LANG_CODE _T('\x01') // for a langstring
#define NS_SHELL_CODE _T('\x02') // for a shell folder path

View file

@ -655,11 +655,25 @@ void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
#endif
#define GetAltViewREGSAM() ( sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY )
static HKEY GetRegKeyAndSAM(HKEY hKey, REGSAM*pRS)
HKEY NSISCALL GetRegKeyAndSAM(HKEY hKey, REGSAM*pRS)
{
REGSAM sam = *pRS, otherview = GetAltViewREGSAM();
REGSAM incompatsam = SystemSupportsAltRegView() ? 0 : otherview;
if (sam & KEY_ALTERVIEW) sam |= g_exec_flags.alter_reg_view;
const REGSAM samviewmask = (KEY_WOW64_32KEY|KEY_WOW64_64KEY);
const REGSAM incompatsamview = SystemSupportsAltRegView() ? 0 : GetAltViewREGSAM();
REGSAM sam = *pRS, incompatsam = incompatsamview;
#ifdef C_ASSERT
{C_ASSERT(REGROOTVIEWTOSAMVIEW(REGROOTVIEW32|REGROOTVIEW64) == (KEY_WOW64_32KEY|KEY_WOW64_64KEY));}
#endif
if ((sam & KEY_FORCEVIEW) && IsRegRootkeyForcedView(hKey))
{
REGSAM keysamview = REGROOTVIEWTOSAMVIEW(hKey);
if (keysamview == samviewmask) keysamview = (g_exec_flags.alter_reg_view & ~incompatsamview); // HKxxANY tries to honor SetRegView
sam &= ~samviewmask, sam |= (keysamview & ~(sizeof(void*) > 4 ? 0 : KEY_WOW64_32KEY)); // HKxx32 has the *_32KEY bit set but WinNT4&2000 cannot handle any KEY_WOW64_xxKEY flags.
hKey = (HKEY) ( (UINT_PTR) hKey & ~(REGROOTVIEW32|REGROOTVIEW64) );
}
else if (sam & KEY_ALTERVIEW)
{
sam |= g_exec_flags.alter_reg_view; // We don't mask away the incompatsamview bits because the operation is supposed to fail if the view is not supported.
}
*pRS = sam & ~(NSIS_REGSAM_PRIVATEMASK); // Filter away internal flags
return (incompatsam & sam) ? NULL : hKey; // Fail if the requested view is not supported
}
@ -678,8 +692,8 @@ void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR
{
HKEY hKey;
DWORD cb = NSIS_MAX_STRLEN*sizeof(TCHAR), rt, ec;
REGSAM viewsam = altview ? GetAltViewREGSAM() : 0;
if ((ec = RegKeyOpen(root, sub, KEY_READ|viewsam, &hKey)) == ERROR_SUCCESS)
REGSAM samview = altview ? GetAltViewREGSAM() : 0;
if ((ec = RegKeyOpen(root, sub, KEY_READ|samview, &hKey)) == ERROR_SUCCESS)
{
ec = RegQueryValueEx(hKey, name, NULL, &rt, (LPBYTE)out, &cb);
RegCloseKey(hKey);
@ -1013,6 +1027,19 @@ const TCHAR * _RegKeyHandleToName(HKEY hKey)
if (hKey == HKEY_PERFORMANCE_DATA) return _T("HKEY_PERFORMANCE_DATA");
if (hKey == HKEY_CURRENT_CONFIG) return _T("HKEY_CURRENT_CONFIG");
if (hKey == HKEY_DYN_DATA) return _T("HKEY_DYN_DATA");
if (hKey == HKSHCTX) return _T("HKSHCTX");
if (hKey == HKSHCTX32) return _T("HKSHCTX32");
if (hKey == HKSHCTX64) return _T("HKSHCTX64");
if (hKey == HKCR32) return _T("HKCR32");
if (hKey == HKCR64) return _T("HKCR64");
if (hKey == HKCU32) return _T("HKCU32");
if (hKey == HKCU64) return _T("HKCU64");
if (hKey == HKLM32) return _T("HKLM32");
if (hKey == HKLM64) return _T("HKLM64");
if (hKey == HKSHCTXANY) return _T("HKSHCTXANY");
if (hKey == HKCRANY) return _T("HKCRANY");
if (hKey == HKCUANY) return _T("HKCUANY");
if (hKey == HKLMANY) return _T("HKLMANY");
return _T("HK??");
}

View file

@ -42,9 +42,14 @@ TCHAR * NSISCALL mystrcat(TCHAR *out, const TCHAR *concat);
TCHAR * NSISCALL mystrstr(TCHAR *a, TCHAR *b);
#ifndef KEY_CREATE_LINK
#define KEY_CREATE_LINK 0x0020
#endif
#define KEY_FORCEVIEW KEY_CREATE_LINK // Our private flag used by RegKey* to indicate that we want it to handle HKLM[32|64] style root keys. Cannot be set if the HKEY is a real handle!
#define KEY_ALTERVIEW SYNCHRONIZE // Our private flag used by RegKey* to indicate that we want it to apply g_exec_flags.alter_reg_view. (MSDN:"Registry keys do not support the SYNCHRONIZE standard access right")
#define KEY_FROMSCRIPT (KEY_ALTERVIEW) // Use this flag for registry operations from a .nsi script
#define NSIS_REGSAM_PRIVATEMASK (KEY_FROMSCRIPT|KEY_ALTERVIEW)
#define KEY_FROMSCRIPT (KEY_FORCEVIEW|KEY_ALTERVIEW) // Use this flag for registry operations from a .nsi script
#define NSIS_REGSAM_PRIVATEMASK (KEY_FROMSCRIPT|KEY_FORCEVIEW|KEY_ALTERVIEW)
HKEY NSISCALL GetRegKeyAndSAM(HKEY hKey, REGSAM*pRS);
LONG NSISCALL RegKeyOpen(HKEY hBase, LPCTSTR SubKey, REGSAM RS, HKEY*phKey);
LONG NSISCALL RegKeyCreate(HKEY hBase, LPCTSTR SubKey, REGSAM RS, HKEY*phKey);
void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR *out, UINT altview);

View file

@ -47,6 +47,7 @@ using namespace std;
#endif
#define REGROOTKEYTOINT(hk) ( (INT) (((INT_PTR)(hk)) & 0xffffffff) ) // Masking off non-existing top bits to make GCC happy
#define REGROOTKEYTOINTEX(hk, removeviewbits) ( REGROOTKEYTOINT(hk) & ~(removeviewbits ? (REGROOTVIEW32|REGROOTVIEW64) : 0) )
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
static bool LookupWinSysColorId(const TCHAR*Str, UINT&Clr)
@ -849,11 +850,11 @@ int CEXEBuild::process_jump(LineParser &line, int wt, int *offs)
static HKEY ParseRegRootKey(LineParser &line, int tok)
{
static const TCHAR *rootkeys[2] = {
_T("HKCR\0HKLM\0HKCU\0HKU\0HKCC\0HKDD\0HKPD\0SHCTX\0"),
_T("HKCR\0HKLM\0HKCU\0HKU\0HKCC\0HKDD\0HKPD\0SHCTX\0HKCR32\0HKCR64\0HKCU32\0HKCU64\0HKLM32\0HKLM64\0HKCRANY\0HKCUANY\0HKLMANY\0SHCTX32\0SHCTX64\0SHCTXANY\0"),
_T("HKEY_CLASSES_ROOT\0HKEY_LOCAL_MACHINE\0HKEY_CURRENT_USER\0HKEY_USERS\0HKEY_CURRENT_CONFIG\0HKEY_DYN_DATA\0HKEY_PERFORMANCE_DATA\0SHELL_CONTEXT\0")
};
static const HKEY rootkey_tab[] = {
HKEY_CLASSES_ROOT,HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER,HKEY_USERS,HKEY_CURRENT_CONFIG,HKEY_DYN_DATA,HKEY_PERFORMANCE_DATA,HKSHCTX
HKEY_CLASSES_ROOT,HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER,HKEY_USERS,HKEY_CURRENT_CONFIG,HKEY_DYN_DATA,HKEY_PERFORMANCE_DATA,HKSHCTX,HKCR32,HKCR64,HKCU32,HKCU64,HKLM32,HKLM64,HKCRANY,HKCUANY,HKLMANY,HKSHCTX32,HKSHCTX64,HKSHCTXANY
};
int k = line.gettoken_enum(tok, rootkeys[0]);
if (k == -1) k = line.gettoken_enum(tok, rootkeys[1]);
@ -1690,6 +1691,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
HKEY hRK = ParseRegRootKey(line,1);
if (INVALIDREGROOT == hRK) PRINTHELP()
if (HKSHCTX == hRK) PRINTHELP() // SHCTX is invalid here
if (IsRegRootkeyForcedView(hRK)) PRINTHELP() // 32|64 views are also invalid
build_header.install_reg_rootkey=REGROOTKEYTOINT(hRK);
build_header.install_reg_key_ptr = add_string(line.gettoken_str(2),0);
if (line.gettoken_str(2)[0] == _T('\\'))
@ -4186,24 +4188,24 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_DELETEREGVALUE:
case TOK_DELETEREGKEY:
{
int a=1, iskeyop, delkeyflag=1, onlyifemptyflag=2;
int a=1, iskeyop;
if ((iskeyop = which_token == TOK_DELETEREGKEY))
{
ent.offsets[4]=(delkeyflag);
TCHAR *s=line.gettoken_str(a);
if (s[0] == _T('/'))
{
if (_tcsicmp(s,_T("/ifempty"))) PRINTHELP()
a++, ent.offsets[4]=(delkeyflag|onlyifemptyflag);
a++, ent.offsets[4]|=(DELREGKEY_ONLYIFNOSUBKEYS<<DELREGKEYFLAGSSHIFT);
}
if (line.gettoken_str(a+2)[0]) PRINTHELP()
}
HKEY hRK=ParseRegRootKey(line,a);
if (INVALIDREGROOT == hRK) PRINTHELP()
ent.which=EW_DELREG;
ent.offsets[1]=REGROOTKEYTOINT(hRK);
ent.offsets[1]=REGROOTKEYTOINTEX(hRK, iskeyop); // DELETEREGKEY needs the REGSAM view bits in parm4 and NOT in HKEY while DELETEREGVALUE needs them in HKEY.
ent.offsets[2]=add_string(line.gettoken_str(a+1));
ent.offsets[3]=iskeyop ? 0 : add_string(line.gettoken_str(a+2));
ent.offsets[4]|=iskeyop ? DELREG_KEY|(REGROOTVIEWTOSAMVIEW(hRK)<<DELREGKEYFLAGSSHIFT) : DELREG_VALUE;
if (line.gettoken_str(a+1)[0] == _T('\\'))
warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0));
if (iskeyop)

View file

@ -62,8 +62,8 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_DBOPTIMIZE,_T("SetDatablockOptimize"),1,0,_T("(off|on)"),TP_ALL},
{TOK_DELETEINISEC,_T("DeleteINISec"),2,0,_T("ini_file section_name"),TP_CODE},
{TOK_DELETEINISTR,_T("DeleteINIStr"),3,0,_T("ini_file section_name entry_name"),TP_CODE},
{TOK_DELETEREGKEY,_T("DeleteRegKey"),2,1,_T("[/ifempty] root_key subkey\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_DELETEREGVALUE,_T("DeleteRegValue"),3,0,_T("root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_DELETEREGKEY,_T("DeleteRegKey"),2,1,_T("[/ifempty] root_key subkey\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_DELETEREGVALUE,_T("DeleteRegValue"),3,0,_T("root_key subkey entry_name\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_DELETE,_T("Delete"),1,1,_T("[/REBOOTOK] filespec"),TP_CODE},
{TOK_DETAILPRINT,_T("DetailPrint"),1,0,_T("message"),TP_CODE},
{TOK_DIRTEXT,_T("DirText"),0,4,_T("[directory_page_description] [directory_page_subtext] [browse_button_text] [browse_dlg_text]"),TP_PG},
@ -75,8 +75,8 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_ROOTDIRINST,_T("AllowRootDirInstall"),1,0,_T("(true|false)"),TP_GLOBAL},
{TOK_CHECKBITMAP,_T("CheckBitmap"),1,0,_T("local_bitmap.bmp"),TP_GLOBAL},
{TOK_ENABLEWINDOW,_T("EnableWindow"),2,0,_T("hwnd state(1|0)"),TP_CODE},
{TOK_ENUMREGKEY,_T("EnumRegKey"),4,0,_T("$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_ENUMREGVAL,_T("EnumRegValue"),4,0,_T("$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_ENUMREGKEY,_T("EnumRegKey"),4,0,_T("$(user_var: output) rootkey subkey index\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_ENUMREGVAL,_T("EnumRegValue"),4,0,_T("$(user_var: output) rootkey subkey index\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_EXCH,_T("Exch"),0,1,_T("[$(user_var)] | [stack_item_index]"),TP_CODE},
{TOK_EXEC,_T("Exec"),1,0,_T("command_line"),TP_CODE},
{TOK_EXECWAIT,_T("ExecWait"),1,1,_T("command_line [$(user_var: return value)]"),TP_CODE},
@ -155,8 +155,8 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_PUSH,_T("Push"),1,0,_T("string"),TP_CODE},
{TOK_QUIT,_T("Quit"),0,0,_T(""),TP_CODE},
{TOK_READINISTR,_T("ReadINIStr"),4,0,_T("$(user_var: output) ini_file section entry_name"),TP_CODE},
{TOK_READREGDWORD,_T("ReadRegDWORD"),4,0,_T("$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_READREGSTR,_T("ReadRegStr"),4,0,_T("$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_READREGDWORD,_T("ReadRegDWORD"),4,0,_T("$(user_var: output) rootkey subkey entry\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_READREGSTR,_T("ReadRegStr"),4,0,_T("$(user_var: output) rootkey subkey entry\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_READENVSTR,_T("ReadEnvStr"),2,0,_T("$(user_var: output) name"),TP_CODE},
{TOK_REBOOT,_T("Reboot"),0,0,_T(""),TP_CODE},
{TOK_REGDLL,_T("RegDLL"),1,1,_T("dll_path_on_target.dll [entrypoint_symbol]"),TP_CODE},
@ -236,11 +236,11 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_UNREGDLL,_T("UnRegDLL"),1,0,_T("dll_path_on_target.dll"),TP_CODE},
{TOK_WINDOWICON,_T("WindowIcon"),1,0,_T("on|off"),TP_GLOBAL},
{TOK_WRITEINISTR,_T("WriteINIStr"),4,0,_T("ini_file section_name entry_name new_value"),TP_CODE},
{TOK_WRITEREGBIN,_T("WriteRegBin"),4,0,_T("rootkey subkey entry_name hex_string_like_12848412AB\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGMULTISZ, _T("WriteRegMultiStr"),5,0,_T("/REGEDIT5 rootkey subkey entry_name hex_string_like_660000000000\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGDWORD,_T("WriteRegDWORD"),4,0,_T("rootkey subkey entry_name new_value_dword\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGSTR,_T("WriteRegStr"),4,0,_T("rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGEXPANDSTR,_T("WriteRegExpandStr"),4,0,_T("rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGBIN,_T("WriteRegBin"),4,0,_T("rootkey subkey entry_name hex_string_like_12848412AB\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGMULTISZ, _T("WriteRegMultiStr"),5,0,_T("/REGEDIT5 rootkey subkey entry_name hex_string_like_660000000000\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGDWORD,_T("WriteRegDWORD"),4,0,_T("rootkey subkey entry_name new_value_dword\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGSTR,_T("WriteRegStr"),4,0,_T("rootkey subkey entry_name new_value_string\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGEXPANDSTR,_T("WriteRegExpandStr"),4,0,_T("rootkey subkey entry_name new_value_string\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGNONE,_T("WriteRegNone"),3,1,_T("rootkey subkey entry_name [hex_data]"),TP_CODE},
{TOK_WRITEUNINSTALLER,_T("WriteUninstaller"),1,0,_T("uninstall_exe_name"),TP_CODE},
{TOK_PEDLLCHARACTERISTICS, _T("PEDllCharacteristics"),2,0,_T("addbits removebits"),TP_GLOBAL},