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
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue