Unsupported SetRegView mode must fail all registry operations
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6865 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a2aa3ed305
commit
b558dea54d
12 changed files with 186 additions and 154 deletions
|
@ -10,6 +10,8 @@ Released on ? ?th, 2017
|
|||
|
||||
\b Fixed RegTool Win9x bug
|
||||
|
||||
\b Unsupported SetRegView mode fails all registry operations
|
||||
|
||||
\b Added \R{execshellwait}{ExecShellWait}
|
||||
|
||||
\b Added \R{writeregmultistr}{WriteRegMultiStr} (\W{http://sf.net/p/nsis/feature-requests/382}{RFE #382}, \W{http://sf.net/p/nsis/patches/219}{patch #219}) and WriteRegNone
|
||||
|
|
|
@ -248,7 +248,7 @@ The compiler will check your script and give you warnings or an error. If an err
|
|||
|
||||
NSIS supports different compression methods, as explained \R{asetcompressor}{here}. ZLIB is the default compression method, which is fast and uses only a little bit of memory. LZMA is a good method for the creation of small installers for internet distribution. BZIP2 usually compresses better than ZLIB but not as good as LZMA, it is useful if you need lower memory usage or fast script compilation.
|
||||
|
||||
It it also possible to compile Windows installers on Linux, BSD or Mac OS X servers. See \R{build}{Building NSIS} for details.
|
||||
It is also possible to compile Windows installers on Linux, BSD or Mac OS X servers. See \R{build}{Building NSIS} for details.
|
||||
|
||||
\H{tutmodernui} Modern UI
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ CEXEBuild::CEXEBuild(signed char pponly) :
|
|||
m_ShellConstants.add(_T("RESOURCES_LOCALIZED"), CSIDL_RESOURCES_LOCALIZED, CSIDL_RESOURCES_LOCALIZED);
|
||||
m_ShellConstants.add(_T("CDBURN_AREA"), CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA);
|
||||
// PROGRAMFILES&COMMONFILES does a registry lookup and the required string offsets are filled in later.
|
||||
// We do this because the unicode mode has to be locked when we call add_string...
|
||||
// We do this later because the unicode mode has to be locked when we call add_string...
|
||||
m_ShellConstants.add(_T("PROGRAMFILES"), 0, 0);
|
||||
m_ShellConstants.add(_T("PROGRAMFILES32"), 0, 0);
|
||||
m_ShellConstants.add(_T("PROGRAMFILES64"), 0, 0);
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
|
||||
#ifndef LOAD_LIBRARY_SEARCH_USER_DIRS
|
||||
#define LOAD_LIBRARY_SEARCH_USER_DIRS 0x00000400
|
||||
#endif
|
||||
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
|
||||
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
#ifndef SHTDN_REASON_FLAG_PLANNED
|
||||
#define SHTDN_REASON_FLAG_PLANNED 0x80000000
|
||||
|
@ -63,6 +61,8 @@ TCHAR g_caption[NSIS_MAX_STRLEN*2]; // Why does this have to be NSIS_MAX_STRLEN*
|
|||
HWND g_hwnd;
|
||||
HANDLE g_hInstance;
|
||||
#endif
|
||||
void *g_SHGetFolderPath;
|
||||
DWORD g_WinVer;
|
||||
|
||||
void NSISCALL CleanUp();
|
||||
|
||||
|
@ -77,14 +77,12 @@ TCHAR *ValidateTempDir()
|
|||
return my_GetTempFileName(state_language, state_temp_dir);
|
||||
}
|
||||
|
||||
void *g_SHGetFolderPath;
|
||||
|
||||
NSIS_ENTRYPOINT_GUINOCRT
|
||||
EXTERN_C void NSISWinMainNOCRT()
|
||||
{
|
||||
int ret = 0;
|
||||
const TCHAR *m_Err = _LANG_ERRORWRITINGTEMP;
|
||||
|
||||
int cl_flags = 0;
|
||||
|
||||
TCHAR *realcmds;
|
||||
|
@ -92,13 +90,14 @@ EXTERN_C void NSISWinMainNOCRT()
|
|||
TCHAR *cmdline;
|
||||
|
||||
SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
|
||||
g_WinVer = GetVersion() & ~(NSIS_WINVER_WOW64FLAG); // We store a private flag in the build number bits
|
||||
|
||||
{
|
||||
// bug #1125: Don't load modules from the application nor current directory.
|
||||
// SetDefaultDllDirectories() allows us to restrict implicitly loaded and
|
||||
// dynamically loaded modules to just %windir%\System32 and directories
|
||||
// added with AddDllDirectory(). This prevents DLL search order attacks (CAPEC-471).
|
||||
DWORD winver = GetVersion();
|
||||
DWORD winver = g_WinVer;
|
||||
// CoCreateInstance(CLSID_ShellLink, ...) fails on Vista if SetDefaultDllDirectories is called
|
||||
BOOL avoidwinbug = LOWORD(winver) == MAKEWORD(6, 0);
|
||||
if (!avoidwinbug)
|
||||
|
@ -145,6 +144,16 @@ EXTERN_C void NSISWinMainNOCRT()
|
|||
#endif
|
||||
g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath); // and SHFOLDER
|
||||
|
||||
#ifndef _WIN64
|
||||
{
|
||||
// KEY_WOW64_xxKEY causes registry functions to fail on WinNT4 & Win2000.
|
||||
// We don't filter them out because all registry instructions are supposed to fail when
|
||||
// accessing a unsupported view and RegKey* takes care of that by looking at the WOW64 flag.
|
||||
FARPROC fp = myGetProcAddress(MGA_IsOS);
|
||||
enum { os_wow6432 = 30 };
|
||||
if (fp && ((BOOL(WINAPI*)(UINT))fp)(os_wow6432)) g_WinVer |= NSIS_WINVER_WOW64FLAG;
|
||||
}
|
||||
#endif
|
||||
|
||||
InitCommonControls();
|
||||
|
||||
|
|
|
@ -41,20 +41,19 @@ typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM);
|
|||
typedef struct
|
||||
{
|
||||
int autoclose;
|
||||
int all_user_var;
|
||||
int exec_error;
|
||||
int abort;
|
||||
int all_user_var; // SetShellVarContext: User context = 0, Machine context = 1
|
||||
int exec_error; // IfErrors
|
||||
int abort; // IfAbort
|
||||
int exec_reboot; // NSIS_SUPPORT_REBOOT
|
||||
int reboot_called; // NSIS_SUPPORT_REBOOT
|
||||
int XXX_cur_insttype; // Deprecated
|
||||
int plugin_api_version; // see NSISPIAPIVER_CURR
|
||||
// used to be XXX_insttype_changed
|
||||
int plugin_api_version; // See NSISPIAPIVER_CURR (Note: used to be XXX_insttype_changed)
|
||||
int silent; // NSIS_CONFIG_SILENT_SUPPORT
|
||||
int instdir_error;
|
||||
int rtl;
|
||||
int errlvl;
|
||||
int alter_reg_view;
|
||||
int status_update;
|
||||
int errlvl; // SetErrorLevel
|
||||
int alter_reg_view; // SetRegView: Default View = 0, Alternative View = (sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY)
|
||||
int status_update; // SetDetailsPrint
|
||||
} exec_flags_t;
|
||||
|
||||
#ifndef NSISCALL
|
||||
|
|
|
@ -156,30 +156,41 @@ static TCHAR * NSISCALL GetStringFromParm(int id_)
|
|||
}
|
||||
|
||||
#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
|
||||
|
||||
#define AlterRegistrySAM(sam) (sam | g_exec_flags.alter_reg_view)
|
||||
|
||||
// based loosely on code from Tim Kosse
|
||||
// in win9x this isn't necessary (RegDeleteKey() can delete a tree of keys),
|
||||
// but in win2k you need to do this manually.
|
||||
static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyifempty)
|
||||
static HKEY NSISCALL GetRegRootKey(int RootKey)
|
||||
{
|
||||
HKEY key;
|
||||
int retval=RegOpenKeyEx(thiskey,lpSubKey,0,AlterRegistrySAM(KEY_ENUMERATE_SUB_KEYS),&key);
|
||||
if (retval==ERROR_SUCCESS)
|
||||
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
|
||||
}
|
||||
static HKEY NSISCALL RegOpenScriptKey(REGSAM RS)
|
||||
{
|
||||
HKEY hKey;
|
||||
return RegKeyOpen(GetRegRootKey(g_parms[1]), GetStringFromParm(0x22), RS|KEY_FROMSCRIPT, &hKey) ? NULL : hKey;
|
||||
}
|
||||
static HKEY NSISCALL RegCreateScriptKey(int RootKey, LPCTSTR SubKey, REGSAM RS)
|
||||
{
|
||||
HKEY hKey;
|
||||
return RegKeyCreate(GetRegRootKey(RootKey), SubKey, RS|KEY_FROMSCRIPT, &hKey) ? NULL : hKey;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
if (retval == ERROR_SUCCESS)
|
||||
{
|
||||
// NB - don't change this to static (recursive function)
|
||||
TCHAR buffer[MAX_PATH+1];
|
||||
while (RegEnumKey(key,0,buffer,MAX_PATH+1)==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)
|
||||
{
|
||||
RegCloseKey(key);
|
||||
return !ERROR_SUCCESS;
|
||||
}
|
||||
if ((retval=myRegDeleteKeyEx(key,buffer,0)) != ERROR_SUCCESS) break;
|
||||
if (onlyifempty) return (RegCloseKey(hKey), !ERROR_SUCCESS);
|
||||
if ((retval = RegDeleteScriptKeyWorker(hKey, child, Flags)) != ERROR_SUCCESS) break;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
RegCloseKey(hKey);
|
||||
{
|
||||
typedef LONG (WINAPI * RegDeleteKeyExPtr)(HKEY, LPCTSTR, REGSAM, DWORD);
|
||||
RegDeleteKeyExPtr RDKE = (RegDeleteKeyExPtr)
|
||||
|
@ -189,32 +200,13 @@ static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyif
|
|||
myGetProcAddress(MGA_RegDeleteKeyEx);
|
||||
#endif
|
||||
if (RDKE)
|
||||
retval=RDKE(thiskey,lpSubKey,AlterRegistrySAM(0),0);
|
||||
retval = RDKE(hThisKey, SubKey, viewsam, 0);
|
||||
else
|
||||
retval=g_exec_flags.alter_reg_view||RegDeleteKey(thiskey,lpSubKey);
|
||||
retval = RegDeleteKey(hThisKey, SubKey);
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static HKEY NSISCALL GetRegRootKey(int hRootKey)
|
||||
{
|
||||
if (hRootKey)
|
||||
return (HKEY) (UINT_PTR) hRootKey;
|
||||
|
||||
// HKEY_LOCAL_MACHINE - HKEY_CURRENT_USER == 1
|
||||
return (HKEY) ((UINT_PTR) HKEY_CURRENT_USER + g_exec_flags.all_user_var);
|
||||
}
|
||||
|
||||
static HKEY NSISCALL myRegOpenKey(REGSAM samDesired)
|
||||
{
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyEx(GetRegRootKey(g_parms[1]), GetStringFromParm(0x22), 0, AlterRegistrySAM(samDesired), &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
return hKey;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
|
||||
|
||||
// returns EXEC_ERROR on error
|
||||
|
@ -1212,11 +1204,11 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
|
||||
case EW_DELREG:
|
||||
{
|
||||
long res=!ERROR_SUCCESS;
|
||||
const TCHAR *rkn UNUSED=RegKeyHandleToName((HKEY)parm1);
|
||||
if (!parm4)
|
||||
long res=!ERROR_SUCCESS, rootkey=parm1;
|
||||
const TCHAR *rkn UNUSED=RegKeyHandleToName((HKEY)rootkey);
|
||||
if (!parm4) // TOK_DELETEREGVALUE
|
||||
{
|
||||
HKEY hKey=myRegOpenKey(KEY_SET_VALUE);
|
||||
HKEY hKey=RegOpenScriptKey(KEY_SET_VALUE);
|
||||
if (hKey)
|
||||
{
|
||||
TCHAR *buf3=GetStringFromParm(0x33);
|
||||
|
@ -1225,11 +1217,11 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
else // TOK_DELETEREGKEY
|
||||
{
|
||||
TCHAR *buf2=GetStringFromParm(0x22);
|
||||
log_printf3(_T("DeleteRegKey: \"%s\\%s\""),rkn,buf2);
|
||||
res = myRegDeleteKeyEx(GetRegRootKey(parm1),buf2,parm4&2);
|
||||
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")
|
||||
}
|
||||
if (res != ERROR_SUCCESS)
|
||||
exec_error++;
|
||||
|
@ -1237,16 +1229,14 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
break;
|
||||
case EW_WRITEREG: // write registry value
|
||||
{
|
||||
int rootkey=parm0, type=parm4, rtype=parm5;
|
||||
const TCHAR *rkn UNUSED=RegKeyHandleToName((HKEY)rootkey);
|
||||
HKEY hKey;
|
||||
HKEY rootkey=GetRegRootKey(parm0);
|
||||
int type=parm4;
|
||||
int rtype=parm5;
|
||||
TCHAR *buf0=GetStringFromParm(0x02);
|
||||
TCHAR *buf1=GetStringFromParm(0x11);
|
||||
const TCHAR *rkn UNUSED=RegKeyHandleToName(rootkey);
|
||||
|
||||
exec_error++;
|
||||
if (RegCreateKeyEx(rootkey,buf1,0,0,0,AlterRegistrySAM(KEY_SET_VALUE),0,&hKey,0) == ERROR_SUCCESS)
|
||||
if ((hKey = RegCreateScriptKey(rootkey, buf1, KEY_SET_VALUE)))
|
||||
{
|
||||
LPBYTE data = (LPBYTE) buf2;
|
||||
DWORD size = 0;
|
||||
|
@ -1297,7 +1287,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
break;
|
||||
case EW_READREGSTR: // read registry string
|
||||
{
|
||||
HKEY hKey=myRegOpenKey(KEY_READ);
|
||||
HKEY hKey=RegOpenScriptKey(KEY_READ);
|
||||
TCHAR *p=var0;
|
||||
TCHAR *buf3=GetStringFromParm(0x33); // buf3 == key name
|
||||
p[0]=0;
|
||||
|
@ -1333,21 +1323,19 @@ static int NSISCALL ExecuteEntry(entry *entry_)
|
|||
break;
|
||||
case EW_REGENUM:
|
||||
{
|
||||
HKEY key=myRegOpenKey(KEY_READ);
|
||||
HKEY hKey=RegOpenScriptKey(KEY_READ);
|
||||
TCHAR *p=var0;
|
||||
int b=GetIntFromParm(3);
|
||||
p[0]=0;
|
||||
if (key)
|
||||
p[0]=0; // "" on error. This assumes that RegEnumKey and RegEnumValue do not party on our buffer!
|
||||
if (hKey)
|
||||
{
|
||||
DWORD d=NSIS_MAX_STRLEN-1;
|
||||
if (parm4) RegEnumKey(key,b,p,d);
|
||||
else if (RegEnumValue(key,b,p,&d,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
|
||||
{
|
||||
DWORD d=NSIS_MAX_STRLEN-1; // -1 is not required here?
|
||||
if (parm4)
|
||||
RegEnumKey(hKey,b,p,d);
|
||||
else if (RegEnumValue(hKey,b,p,&d,NULL,NULL,NULL,NULL) != ERROR_SUCCESS)
|
||||
exec_error++;
|
||||
break;
|
||||
}
|
||||
p[NSIS_MAX_STRLEN-1]=0;
|
||||
RegCloseKey(key);
|
||||
p[NSIS_MAX_STRLEN-1]=0; // Not required?
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
else exec_error++;
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ enum
|
|||
#endif
|
||||
|
||||
#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
|
||||
EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, delkeyonlyifempty]. ValueName is -1 if delete key
|
||||
EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, ActionAndFlags]
|
||||
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]
|
||||
|
@ -510,6 +510,8 @@ typedef struct {
|
|||
#define DEL_REBOOT 4
|
||||
#define DEL_SIMPLE 8
|
||||
|
||||
#define HKSHCTX ( (HKEY) 0 ) // Converted to HKCU or HKLM by GetRegRootKey
|
||||
|
||||
#ifdef NSIS_SUPPORT_CREATESHORTCUT
|
||||
#define CS_HK_MASK 0xffff0000 // HotKey
|
||||
#define CS_HK_SHIFT 16
|
||||
|
|
|
@ -539,7 +539,7 @@ void RenameViaWininit(const TCHAR* prevName, const TCHAR* newName)
|
|||
|
||||
int spn; // length of the short path name in TCHARs.
|
||||
|
||||
lstrcpy(tmpbuf, _T("NUL"));
|
||||
mystrcpy(tmpbuf, _T("NUL"));
|
||||
|
||||
if (newName) {
|
||||
// create the file if it's not already there to prevent GetShortPathName from failing
|
||||
|
@ -643,22 +643,38 @@ void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
|
|||
}
|
||||
#endif
|
||||
|
||||
// The value of registry->sub->name is stored in out. If failure, then out becomes
|
||||
// an empty string "".
|
||||
void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR *out, int altview)
|
||||
#define GetAltViewREGSAM() ( sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY )
|
||||
static HKEY 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;
|
||||
*pRS = sam & ~(NSIS_REGSAM_PRIVATEMASK); // Filter away internal flags
|
||||
return (incompatsam & sam) ? NULL : hKey; // Fail if the requested view is not supported
|
||||
}
|
||||
LONG NSISCALL RegKeyOpen(HKEY hBase, LPCTSTR SubKey, REGSAM RS, HKEY*phKey)
|
||||
{
|
||||
if (!(hBase = GetRegKeyAndSAM(hBase, &RS))) return ERROR_INVALID_HANDLE; // ERROR_CANTOPEN?
|
||||
return RegOpenKeyEx(hBase, SubKey, 0, RS, phKey);
|
||||
}
|
||||
LONG NSISCALL RegKeyCreate(HKEY hBase, LPCTSTR SubKey, REGSAM RS, HKEY*phKey)
|
||||
{
|
||||
if (!(hBase = GetRegKeyAndSAM(hBase, &RS))) return ERROR_INVALID_HANDLE; // ERROR_CANTOPEN?
|
||||
return RegCreateKeyEx(hBase, SubKey, 0, 0, 0, RS, 0, phKey, 0);
|
||||
}
|
||||
|
||||
void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR *out, UINT altview)
|
||||
{
|
||||
HKEY hKey;
|
||||
const REGSAM wowsam = altview ? (sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY) : 0;
|
||||
*out=0;
|
||||
if (RegOpenKeyEx(root,sub,0,KEY_READ|wowsam,&hKey) == ERROR_SUCCESS)
|
||||
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)
|
||||
{
|
||||
DWORD l = NSIS_MAX_STRLEN*sizeof(TCHAR), t;
|
||||
// Note that RegQueryValueEx returns Unicode strings if _UNICODE is defined for the
|
||||
// REG_SZ type.
|
||||
if (RegQueryValueEx(hKey,name,NULL,&t,(LPBYTE)out,&l ) != ERROR_SUCCESS || (t != REG_SZ && t != REG_EXPAND_SZ)) *out=0;
|
||||
out[NSIS_MAX_STRLEN-1]=0;
|
||||
ec = RegQueryValueEx(hKey, name, NULL, &rt, (LPBYTE)out, &cb);
|
||||
RegCloseKey(hKey);
|
||||
out[NSIS_MAX_STRLEN-1] = 0; // Make sure the string is terminated. This could potentially truncate a long string by 1 character!
|
||||
}
|
||||
if (ec != ERROR_SUCCESS || (rt != REG_SZ && rt != REG_EXPAND_SZ)) *out = 0; // Empty string on failure
|
||||
}
|
||||
|
||||
void NSISCALL iptrtostr(TCHAR *s, INT_PTR d)
|
||||
|
@ -764,8 +780,10 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab)
|
|||
int fldrs[4];
|
||||
if (nVarIdx < NS_SKIP_CODE)
|
||||
{
|
||||
// the next 2 BYTEs in the string might be coding either a value 0..MAX_CODED (nData), or 2 CSIDL of Special folders (for NS_SHELL_CODE)
|
||||
// The next 2 BYTEs in the string might be coding either a value 0..MAX_CODED (nData), or 2 CSIDL of Special folders (for NS_SHELL_CODE)
|
||||
nData = DECODE_SHORT(in);
|
||||
// There are 2 CSIDL parameters for each context and query must be used before create
|
||||
// because of bug #820 (CSIDL_FLAG_CREATE failures on root paths are cached in Vista).
|
||||
#ifdef _UNICODE
|
||||
fldrs[1] = LOBYTE(*in); // current user
|
||||
fldrs[0] = fldrs[1] | CSIDL_FLAG_CREATE;
|
||||
|
@ -777,7 +795,6 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab)
|
|||
fldrs[2] = in[1] | CSIDL_FLAG_CREATE; // all users
|
||||
fldrs[3] = in[1];
|
||||
#endif
|
||||
//TODO: are fldrs[1] and fldrs[3] really useful? why not force folder creation directly?
|
||||
in += sizeof(SHORT)/sizeof(TCHAR);
|
||||
|
||||
if (nVarIdx == NS_SHELL_CODE)
|
||||
|
@ -785,10 +802,8 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab)
|
|||
LPITEMIDLIST idl;
|
||||
|
||||
int x = 2;
|
||||
DWORD ver = GetVersion();
|
||||
|
||||
DWORD ver = sizeof(void*) > 4 ? MAKEWORD(5, 2) : g_WinVer; // We only care about 95/98 vs ME/NT4+
|
||||
/*
|
||||
|
||||
SHGetFolderPath as provided by shfolder.dll is used to get special folders
|
||||
unless the installer is running on Windows 95/98. For 95/98 shfolder.dll is
|
||||
only used for the Application Data and Documents folder (if the DLL exists).
|
||||
|
@ -802,9 +817,7 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab)
|
|||
SHGetFolderPath in shell32.dll could be called directly for Windows versions
|
||||
later than 95/98 but there is no need to do so, because shfolder.dll is still
|
||||
provided and calls shell32.dll.
|
||||
|
||||
*/
|
||||
|
||||
BOOL use_shfolder =
|
||||
// Use shfolder if not on 95/98
|
||||
!((ver & 0x80000000) && (LOWORD(ver) != 0x5A04)) ||
|
||||
|
@ -819,7 +832,7 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab)
|
|||
|
||||
if (g_exec_flags.all_user_var)
|
||||
{
|
||||
x = 4;
|
||||
x = 4; // Get common folder > Create common folder > Get user folder > Create user folder
|
||||
}
|
||||
|
||||
if (fldrs[1] & 0x80)
|
||||
|
@ -829,12 +842,12 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab)
|
|||
GetNSISString(out, fldrs[3]);
|
||||
x = 0;
|
||||
}
|
||||
else if (fldrs[1] == CSIDL_SYSTEM)
|
||||
else if (fldrs[1] == CSIDL_SYSTEM) // Does not work on 95, 98 nor NT4. Works on ME and 2000+.
|
||||
{
|
||||
GetSystemDirectory(out, NSIS_MAX_STRLEN);
|
||||
x = 0;
|
||||
}
|
||||
else if (fldrs[1] == CSIDL_WINDOWS)
|
||||
else if (fldrs[1] == CSIDL_WINDOWS) // Does not work on 95, 98 nor NT4. Works on ME and 2000+.
|
||||
{
|
||||
GetWindowsDirectory(out, NSIS_MAX_STRLEN);
|
||||
x = 0;
|
||||
|
@ -982,22 +995,14 @@ void NSISCALL log_write(int close)
|
|||
|
||||
const TCHAR * _RegKeyHandleToName(HKEY hKey)
|
||||
{
|
||||
if (hKey == HKEY_CLASSES_ROOT)
|
||||
return _T("HKEY_CLASSES_ROOT");
|
||||
else if (hKey == HKEY_CURRENT_USER)
|
||||
return _T("HKEY_CURRENT_USER");
|
||||
else if (hKey == HKEY_LOCAL_MACHINE)
|
||||
return _T("HKEY_LOCAL_MACHINE");
|
||||
else if (hKey == HKEY_USERS)
|
||||
return _T("HKEY_USERS");
|
||||
else if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
return _T("HKEY_PERFORMANCE_DATA");
|
||||
else if (hKey == HKEY_CURRENT_CONFIG)
|
||||
return _T("HKEY_CURRENT_CONFIG");
|
||||
else if (hKey == HKEY_DYN_DATA)
|
||||
return _T("HKEY_DYN_DATA");
|
||||
else
|
||||
return _T("invalid registry key");
|
||||
if (hKey == HKEY_CLASSES_ROOT) return _T("HKEY_CLASSES_ROOT");
|
||||
if (hKey == HKEY_CURRENT_USER) return _T("HKEY_CURRENT_USER");
|
||||
if (hKey == HKEY_LOCAL_MACHINE) return _T("HKEY_LOCAL_MACHINE");
|
||||
if (hKey == HKEY_USERS) return _T("HKEY_USERS");
|
||||
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");
|
||||
return _T("HK??");
|
||||
}
|
||||
|
||||
void _LogData2Hex(TCHAR *buf, size_t cchbuf, BYTE *data, size_t cbdata)
|
||||
|
@ -1103,6 +1108,9 @@ struct MGA_FUNC MGA_FUNCS[] = {
|
|||
#endif
|
||||
{"ADVAPI32", "InitiateShutdownW"},
|
||||
{"SHELL32", (CHAR*) 680}, // IsUserAnAdmin
|
||||
#ifndef _WIN64
|
||||
{"SHLWAPI", (CHAR*) 437}, // IsOS
|
||||
#endif
|
||||
{"SHLWAPI", "SHAutoComplete"},
|
||||
{"SHFOLDER", "SHGetFolderPathW"},
|
||||
#ifdef NSIS_SUPPORT_GETDLLVERSION
|
||||
|
@ -1118,6 +1126,9 @@ struct MGA_FUNC MGA_FUNCS[] = {
|
|||
{"ADVAPI32", "RegDeleteKeyExA"},
|
||||
{"ADVAPI32", "InitiateShutdownA"},
|
||||
{"SHELL32", (CHAR*) 680}, // IsUserAnAdmin
|
||||
#ifndef _WIN64
|
||||
{"SHLWAPI", (CHAR*) 437}, // IsOS
|
||||
#endif
|
||||
{"SHLWAPI", "SHAutoComplete"},
|
||||
{"SHFOLDER", "SHGetFolderPathA"},
|
||||
#ifdef NSIS_SUPPORT_GETDLLVERSION
|
||||
|
|
|
@ -32,7 +32,6 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab);
|
|||
// use the LANG_STR_TAB() macro to decode it.
|
||||
#define GetNSISTab(strtab) (strtab < 0 ? LANG_STR_TAB(strtab) : strtab)
|
||||
|
||||
void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR *out, int altview);
|
||||
#define myatoi(s) ( (int)strtoiptr(s) )
|
||||
INT_PTR NSISCALL strtoiptr(const TCHAR *s);
|
||||
#define myitoa iptrtostr
|
||||
|
@ -41,6 +40,22 @@ TCHAR * NSISCALL mystrcpy(TCHAR *out, const TCHAR *in);
|
|||
int NSISCALL mystrlen(const TCHAR *in);
|
||||
TCHAR * NSISCALL mystrcat(TCHAR *out, const TCHAR *concat);
|
||||
TCHAR * NSISCALL mystrstr(TCHAR *a, TCHAR *b);
|
||||
|
||||
|
||||
#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)
|
||||
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);
|
||||
|
||||
|
||||
extern DWORD g_WinVer; // GetVersion()
|
||||
#define NSIS_WINVER_WOW64FLAG ( sizeof(void*) > 4 ? ( 0 ) : ( 0x40000000 ) )
|
||||
#define IsWow64() ( sizeof(void*) > 4 ? ( FALSE ) : ( g_WinVer & NSIS_WINVER_WOW64FLAG ) )
|
||||
#define SystemSupportsAltRegView() ( sizeof(void*) > 4 ? ( TRUE ) : ( IsWow64() ) )
|
||||
|
||||
|
||||
WIN32_FIND_DATA * NSISCALL file_exists(TCHAR *buf);
|
||||
TCHAR * NSISCALL my_GetTempFileName(TCHAR *buf, const TCHAR *dir);
|
||||
BOOL NSISCALL myReadFile(HANDLE h, LPVOID buf, DWORD cb);
|
||||
|
@ -134,6 +149,9 @@ enum myGetProcAddressFunctions {
|
|||
#endif
|
||||
MGA_InitiateShutdown,
|
||||
MGA_IsUserAnAdmin,
|
||||
#ifndef _WIN64
|
||||
MGA_IsOS,
|
||||
#endif
|
||||
MGA_SHAutoComplete, // x64 can link to shlwapi directly but as long as MGA_SHGetFolderPath is used we can stick with myGetProcAddress
|
||||
MGA_SHGetFolderPath, // TODO: This can probably call something else directly on x64
|
||||
#ifdef NSIS_SUPPORT_GETDLLVERSION
|
||||
|
|
|
@ -704,8 +704,10 @@ int main(int argc, char **argv)
|
|||
int wargc = 0;
|
||||
wchar_t term[1], *p, **wargv = (wchar_t **) malloc((argc+1) * sizeof(void*));
|
||||
if (wargv)
|
||||
{
|
||||
for ( ; wargc < argc; ++wargc )
|
||||
if ((p = NSISRT_mbtowc(argv[wargc]))) { wargv[wargc] = p; } else { break; }
|
||||
if ((p = NSISRT_mbtowc(argv[wargc]))) wargv[wargc] = p; else break;
|
||||
}
|
||||
if (wargc == argc)
|
||||
*term = L'\0', wargv[wargc] = term, errno = _tmain(wargc,wargv);
|
||||
else
|
||||
|
|
|
@ -845,16 +845,23 @@ int CEXEBuild::process_jump(LineParser &line, int wt, int *offs)
|
|||
#define SECTION_FIELD_GET(field) (FIELD_OFFSET(section, field)/sizeof(int))
|
||||
#define SECTION_FIELD_SET(field) (-1 - (int)(FIELD_OFFSET(section, field)/sizeof(int)))
|
||||
|
||||
int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||
#define INVALIDREGROOT ( (HKEY) 0x8000baad )
|
||||
static HKEY ParseRegRootKey(LineParser &line, int tok)
|
||||
{
|
||||
static const TCHAR *rootkeys[2] = {
|
||||
_T("HKCR\0HKLM\0HKCU\0HKU\0HKCC\0HKDD\0HKPD\0SHCTX\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,0
|
||||
HKEY_CLASSES_ROOT,HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER,HKEY_USERS,HKEY_CURRENT_CONFIG,HKEY_DYN_DATA,HKEY_PERFORMANCE_DATA,HKSHCTX
|
||||
};
|
||||
int k = line.gettoken_enum(tok, rootkeys[0]);
|
||||
if (k == -1) k = line.gettoken_enum(tok, rootkeys[1]);
|
||||
return k == -1 ? INVALIDREGROOT : rootkey_tab[k];
|
||||
}
|
||||
|
||||
int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||
{
|
||||
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
||||
if (PS_OK != initialize_default_plugins()) return PS_ERROR;
|
||||
#endif
|
||||
|
@ -1680,11 +1687,10 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
if (build_header.install_reg_key_ptr)
|
||||
warning_fl(DW_STRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0));
|
||||
|
||||
int k=line.gettoken_enum(1,rootkeys[0]);
|
||||
if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
|
||||
if (k == -1) PRINTHELP()
|
||||
build_header.install_reg_rootkey=REGROOTKEYTOINT(rootkey_tab[k]);
|
||||
if (!build_header.install_reg_rootkey) PRINTHELP() // SHCTX is invalid here
|
||||
HKEY hRK = ParseRegRootKey(line,1);
|
||||
if (INVALIDREGROOT == hRK) PRINTHELP()
|
||||
if (HKSHCTX == hRK) PRINTHELP() // SHCTX is invalid here
|
||||
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('\\'))
|
||||
warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0));
|
||||
|
@ -2875,12 +2881,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
{
|
||||
ent.which=EW_SETFLAG;
|
||||
ent.offsets[0]=FLAG_OFFSET(alter_reg_view);
|
||||
int k=line.gettoken_enum(1,_T("32\0") _T("64\0default\0lastused\0")); // TODO: Can we support "native" without OS sniffing? Must verify on 9x, NT4 and 2000!
|
||||
if (k<0) PRINTHELP()
|
||||
int k=line.gettoken_enum(1,_T("32\0") _T("64\0default\0lastused\0"));
|
||||
if (k == 0) ent.offsets[1]=add_intstring(is_target_64bit() ? KEY_WOW64_32KEY : 0); // 32
|
||||
else if (k == 1) ent.offsets[1]=add_intstring(KEY_WOW64_64KEY); // 64
|
||||
else if (k == 2) ent.offsets[1]=add_intstring(0); // default
|
||||
else if (k == 3) ent.offsets[2]=1; // last used
|
||||
else PRINTHELP()
|
||||
SCRIPT_MSG(_T("SetRegView: %") NPRIs _T("\n"),line.gettoken_str(1));
|
||||
}
|
||||
return add_entry(&ent);
|
||||
|
@ -4163,10 +4169,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
{
|
||||
ent.which=EW_READREGSTR;
|
||||
ent.offsets[0]=GetUserVarIndex(line, 1);
|
||||
int k=line.gettoken_enum(2,rootkeys[0]);
|
||||
if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
|
||||
if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
|
||||
ent.offsets[1]=REGROOTKEYTOINT(rootkey_tab[k]);
|
||||
HKEY hRK = ParseRegRootKey(line,2);
|
||||
if (ent.offsets[0] == -1 || INVALIDREGROOT == hRK) PRINTHELP()
|
||||
ent.offsets[1]=REGROOTKEYTOINT(hRK);
|
||||
ent.offsets[2]=add_string(line.gettoken_str(3));
|
||||
ent.offsets[3]=add_string(line.gettoken_str(4));
|
||||
if (which_token == TOK_READREGDWORD) ent.offsets[4]=1;
|
||||
|
@ -4181,29 +4186,27 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
case TOK_DELETEREGVALUE:
|
||||
case TOK_DELETEREGKEY:
|
||||
{
|
||||
int a=1;
|
||||
if (which_token==TOK_DELETEREGKEY)
|
||||
int a=1, iskeyop, delkeyflag=1, onlyifemptyflag=2;
|
||||
if ((iskeyop = which_token == TOK_DELETEREGKEY))
|
||||
{
|
||||
ent.offsets[4]=1;
|
||||
ent.offsets[4]=(delkeyflag);
|
||||
TCHAR *s=line.gettoken_str(a);
|
||||
if (s[0] == _T('/'))
|
||||
{
|
||||
if (_tcsicmp(s,_T("/ifempty"))) PRINTHELP()
|
||||
a++;
|
||||
ent.offsets[4]=3;
|
||||
a++, ent.offsets[4]=(delkeyflag|onlyifemptyflag);
|
||||
}
|
||||
if (line.gettoken_str(a+2)[0]) PRINTHELP()
|
||||
}
|
||||
int k=line.gettoken_enum(a,rootkeys[0]);
|
||||
if (k == -1) k=line.gettoken_enum(a,rootkeys[1]);
|
||||
if (k == -1) PRINTHELP()
|
||||
HKEY hRK=ParseRegRootKey(line,a);
|
||||
if (INVALIDREGROOT == hRK) PRINTHELP()
|
||||
ent.which=EW_DELREG;
|
||||
ent.offsets[1]=REGROOTKEYTOINT(rootkey_tab[k]);
|
||||
ent.offsets[1]=REGROOTKEYTOINT(hRK);
|
||||
ent.offsets[2]=add_string(line.gettoken_str(a+1));
|
||||
ent.offsets[3]=(which_token==TOK_DELETEREGKEY)?0:add_string(line.gettoken_str(a+2));
|
||||
ent.offsets[3]=iskeyop ? 0 : add_string(line.gettoken_str(a+2));
|
||||
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 (which_token==TOK_DELETEREGKEY)
|
||||
if (iskeyop)
|
||||
SCRIPT_MSG(_T("DeleteRegKey: %") NPRIs _T("\\%") NPRIs _T("\n"),line.gettoken_str(a),line.gettoken_str(a+1));
|
||||
else
|
||||
SCRIPT_MSG(_T("DeleteRegValue: %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("\n"),line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2));
|
||||
|
@ -4217,11 +4220,10 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
const TCHAR*cmdname=get_commandtoken_name(which_token);
|
||||
int reg5=0==line.gettoken_enum(1,_T("/REGEDIT5\0")), multisz=which_token == TOK_WRITEREGMULTISZ;
|
||||
if (reg5) line.eattoken();
|
||||
int k=line.gettoken_enum(1,rootkeys[0]);
|
||||
if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
|
||||
if (k == -1 || reg5 != multisz) PRINTHELPEX(cmdname); // WriteRegMultiStr only supports the /REGEDIT5 serialized format right now but we really should allow variables at some point.
|
||||
HKEY hRK=ParseRegRootKey(line,1);
|
||||
if (INVALIDREGROOT == hRK || reg5 != multisz) PRINTHELPEX(cmdname); // WriteRegMultiStr only supports the /REGEDIT5 serialized format right now but we really should allow variables at some point.
|
||||
ent.which=EW_WRITEREG;
|
||||
ent.offsets[0]=REGROOTKEYTOINT(rootkey_tab[k]);
|
||||
ent.offsets[0]=REGROOTKEYTOINT(hRK);
|
||||
ent.offsets[1]=add_string(line.gettoken_str(2));
|
||||
if (line.gettoken_str(2)[0] == _T('\\'))
|
||||
warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),cmdname);
|
||||
|
@ -4268,10 +4270,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
{
|
||||
ent.which=EW_REGENUM;
|
||||
ent.offsets[0]=GetUserVarIndex(line, 1);
|
||||
int k=line.gettoken_enum(2,rootkeys[0]);
|
||||
if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
|
||||
if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
|
||||
ent.offsets[1]=REGROOTKEYTOINT(rootkey_tab[k]);
|
||||
HKEY hRK=ParseRegRootKey(line,2);
|
||||
if (ent.offsets[0] == -1 || INVALIDREGROOT == hRK) PRINTHELP()
|
||||
ent.offsets[1]=REGROOTKEYTOINT(hRK);
|
||||
ent.offsets[2]=add_string(line.gettoken_str(3));
|
||||
ent.offsets[3]=add_string(line.gettoken_str(4));
|
||||
ent.offsets[4]=which_token == TOK_ENUMREGKEY;
|
||||
|
|
|
@ -241,7 +241,7 @@ static tokenType tokenlist[TOK__LAST] =
|
|||
{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_WRITEREGNONE,_T("WriteRegNone"),3,1,_T("rootkey subkey entry_name [hex_data]\n root_key=(HKCR|HKLM|HKCU|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},
|
||||
{TOK_PESUBSYSVER, _T("PESubsysVer"),1,0,_T("major.minor"),TP_GLOBAL},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue