From 357c44ac38636d1c3cc0619184d99cee84f6ac48 Mon Sep 17 00:00:00 2001 From: kichik Date: Sat, 14 Apr 2007 12:50:32 +0000 Subject: [PATCH] added SetRegView to allows access to the x64 registry view this method was chosen over a new switch for all regsitry commands to allow easy transition of existing scripts git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5070 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/ExDLL/exdll.h | 1 + Docs/src/misc.but | 23 +++++++++++++++++++++++ Source/exehead/exec.c | 26 ++++++++++++++++++++++---- Source/exehead/fileform.h | 1 + Source/script.cpp | 11 +++++++++++ Source/tokens.cpp | 1 + Source/tokens.h | 1 + 7 files changed, 60 insertions(+), 4 deletions(-) diff --git a/Contrib/ExDLL/exdll.h b/Contrib/ExDLL/exdll.h index f16cf047..a4ca50a3 100644 --- a/Contrib/ExDLL/exdll.h +++ b/Contrib/ExDLL/exdll.h @@ -80,6 +80,7 @@ typedef struct { int instdir_error; int rtl; int errlvl; + int alter_reg_view; } exec_flags_type; typedef struct { diff --git a/Docs/src/misc.but b/Docs/src/misc.but index bc2cd07d..ed3b823e 100644 --- a/Docs/src/misc.but +++ b/Docs/src/misc.but @@ -65,6 +65,29 @@ Sets the error level of the installer or uninstaller to \e{error_level}. See \R{ \c IfRebootFlag 0 +2 \c SetErrorLevel 4 +\S2{setregview} SetRegView + +\c \\32\\|64 + +Sets the registry view affected by \R{registry}{registry commands}. On Windows x64 there are two views. One for 32-bit applications and one for x64 applications. By default, 32-bit applications running on x64 systems under WOW64 have access only to the 32-bit view. Using \c{SetRegView 64} allows the installer to access keys in the x64 view of the registry. + +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}. + +Does not affect \R{ainstalldirregkey}{InstallDirRegKey}. Instead, the registry can be read using \R{readregstr}{ReadRegStr} in \R{oninit}{.onInit}. + +\c SetRegView 32 +\c ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir +\c DetailPrit $0 # prints C:\Program Files (x86) +\c SetRegView 64 +\c ReadRegStr $0 HKLM Software\Microsoft\Windows\CurrentVersion ProgramFilesDir +\c DetailPrit $0 # prints C:\Program Files + +\c Function .onInit +\c SetRegView 64 +\c ReadRegStr $INSTDIR HKLM Software\NSIS "" +\c SetRegView 32 +\c FunctionEnd + \S2{setshellvarcontext} SetShellVarContext \c \\current\\|all diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index 408662d5..8f2097ab 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -125,13 +125,22 @@ static char * NSISCALL GetStringFromParm(int id_) } #ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS +REGSAM NSISCALL AlterRegistrySAM(REGSAM sam) +{ + if (g_exec_flags.alter_reg_view) + { + return sam | KEY_WOW64_64KEY; + } + return sam; +} + // 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) { HKEY key; - int retval=RegOpenKeyEx(thiskey,lpSubKey,0,KEY_ENUMERATE_SUB_KEYS,&key); + int retval=RegOpenKeyEx(thiskey,lpSubKey,0,AlterRegistrySAM(KEY_ENUMERATE_SUB_KEYS),&key); if (retval==ERROR_SUCCESS) { // NB - don't change this to static (recursive function) @@ -146,7 +155,16 @@ static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyif if ((retval=myRegDeleteKeyEx(key,buffer,0)) != ERROR_SUCCESS) break; } RegCloseKey(key); - retval=RegDeleteKey(thiskey,lpSubKey); + { + typedef (WINAPI * RegDeleteKeyExAPtr)(HKEY, LPCTSTR, REGSAM, DWORD); + RegDeleteKeyExAPtr RDKE = (RegDeleteKeyExAPtr) + myGetProcAddress("ADVAPI32.dll","RegDeleteKeyExA"); + + if (RDKE) + retval=RDKE(thiskey,lpSubKey,AlterRegistrySAM(0),0); + else + retval=RegDeleteKey(thiskey,lpSubKey); + } } return retval; } @@ -163,7 +181,7 @@ static HKEY NSISCALL GetRegRootKey(int hRootKey) static HKEY NSISCALL myRegOpenKey(REGSAM samDesired) { HKEY hKey; - if (RegOpenKeyEx(GetRegRootKey(parms[1]), GetStringFromParm(0x22), 0, samDesired, &hKey) == ERROR_SUCCESS) + if (RegOpenKeyEx(GetRegRootKey(parms[1]), GetStringFromParm(0x22), 0, AlterRegistrySAM(samDesired), &hKey) == ERROR_SUCCESS) { return hKey; } @@ -1190,7 +1208,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) const char *rkn UNUSED=RegKeyHandleToName(rootkey); exec_error++; - if (RegCreateKeyEx(rootkey,buf1,0,0,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,0,&hKey,0) == ERROR_SUCCESS) + if (RegCreateKeyEx(rootkey,buf1,0,0,0,AlterRegistrySAM(KEY_SET_VALUE),0,&hKey,0) == ERROR_SUCCESS) { LPBYTE data = (LPBYTE) buf2; DWORD size = 0; diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 00cc8357..3a143f23 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -509,6 +509,7 @@ typedef struct int instdir_error; int rtl; int errlvl; + int alter_reg_view; } exec_flags; #define FIELDN(x, y) (((int *)&x)[y]) diff --git a/Source/script.cpp b/Source/script.cpp index a9fca69c..8cf62405 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -3555,6 +3555,17 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (process_jump(line,1,&ent.offsets[0])) PRINTHELP() SCRIPT_MSG("Goto: %s\n",line.gettoken_str(1)); return add_entry(&ent); + case TOK_SETREGVIEW: + { + ent.which=EW_SETFLAG; + ent.offsets[0]=FLAG_OFFSET(alter_reg_view); + // "64" results in setting the flag to 1 which alters the view + int k=line.gettoken_enum(1,"32\0" "64\0"); + if (k<0) PRINTHELP() + ent.offsets[1]=add_intstring(k); + SCRIPT_MSG("SetRegView: %s\n",line.gettoken_str(1)); + } + return add_entry(&ent); case TOK_SETSHELLVARCONTEXT: { ent.which=EW_SETFLAG; diff --git a/Source/tokens.cpp b/Source/tokens.cpp index f1610dde..d4366637 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -194,6 +194,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_SETOVERWRITE,"SetOverwrite",1,0,"on|off|try|ifnewer|ifdiff",TP_ALL}, {TOK_SETPLUGINUNLOAD,"SetPluginUnload",1,0,"(manual|alwaysoff)",TP_ALL}, {TOK_SETREBOOTFLAG,"SetRebootFlag",1,0,"true|false",TP_CODE}, +{TOK_SETREGVIEW,"SetRegView",1,0,"32|64",TP_CODE}, {TOK_SETSHELLVARCONTEXT,"SetShellVarContext",1,0,"all|current",TP_CODE}, {TOK_SETSILENT,"SetSilent",1,0,"silent|normal",TP_CODE}, {TOK_SHOWDETAILS,"ShowInstDetails",1,0,"(hide|show|nevershow)",TP_GLOBAL}, diff --git a/Source/tokens.h b/Source/tokens.h index 5b507f5f..65c415ad 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -254,6 +254,7 @@ enum TOK_INSTTYPEGETTEXT, TOK_GETCURINSTTYPE, TOK_SETCURINSTTYPE, + TOK_SETREGVIEW, TOK_SETSHELLVARCONTEXT, TOK_PLUGINDIR, TOK_INITPLUGINSDIR,