Fixed SetRegView and $ProgramFiles[32|64] in 64-bit installers
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6841 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a9b56a63fd
commit
c1c2ccb4a6
7 changed files with 33 additions and 36 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
In all of the below registry instructions use an empty string (just two quotes with nothing between them - "") as the key name to specify the default key which is shown as (Default) in regedit.exe.
|
||||
|
||||
Use \R{setregview}{SetRegView} on Windows x64 to choose which registry view is used.
|
||||
Use \R{setregview}{SetRegView} on 64-bit Windows to choose which registry view is used.
|
||||
|
||||
If a full path is not specified for any of the INI handling instructions, the Windows directory will be used.
|
||||
|
||||
|
@ -198,7 +198,7 @@ Writes a multi-string value. The /REGEDIT5 switch must be used and specifies tha
|
|||
|
||||
\S2{setregview} SetRegView
|
||||
|
||||
\c \\<b\\>32\\</b\\>|64|lastused
|
||||
\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.
|
||||
|
||||
|
|
|
@ -642,6 +642,9 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
|
|||
# define HKEY_DYN_DATA ((HKEY)0x80000006)
|
||||
#endif
|
||||
|
||||
#ifndef KEY_WOW64_32KEY
|
||||
# define KEY_WOW64_32KEY 0x200
|
||||
#endif
|
||||
#ifndef KEY_WOW64_64KEY
|
||||
# define KEY_WOW64_64KEY 0x100
|
||||
#endif
|
||||
|
|
|
@ -426,24 +426,25 @@ void CEXEBuild::init_shellconstantvalues()
|
|||
static bool done = false;
|
||||
if (done) return ; else done = true;
|
||||
|
||||
const int orgunmode = uninstall_mode;
|
||||
const int orgunmode = uninstall_mode, t64 = is_target_64bit(), reg = 0x80, r32 = t64 ? 0xC0 : reg, r64 = r32 ^ 0x40;
|
||||
set_uninstall_mode(0);
|
||||
// Note: The order matters because some of the strings are preprocessed and cf must be <= 0x40
|
||||
unsigned int pf = add_asciistring(_T("ProgramFilesDir"), 0);
|
||||
unsigned int cf = add_asciistring(_T("CommonFilesDir"), 0);
|
||||
unsigned int pf_def = add_asciistring(_T("C:\\Program Files"));
|
||||
m_ShellConstants.set_values(_T("PROGRAMFILES"), 0x80 | pf, pf_def);
|
||||
unsigned int pf64_def = add_asciistring(_T("$PROGRAMFILES"));
|
||||
m_ShellConstants.set_values(_T("PROGRAMFILES32"), 0x80 | pf, pf_def);
|
||||
m_ShellConstants.set_values(_T("PROGRAMFILES64"), 0xC0 | pf, pf64_def);
|
||||
unsigned int pf_def = add_asciistring(_T("C:\\Program Files")); // Ultimate fallback
|
||||
// TODO: 64-bit targets could use CSIDL_PROGRAM_FILES+CSIDL_PROGRAM_FILESX86?
|
||||
m_ShellConstants.set_values(_T("PROGRAMFILES"), reg | pf, pf_def);
|
||||
unsigned int pf_var = add_asciistring(_T("$PROGRAMFILES")); // Fallback for the 32/64 specific constants if the WOW registry view fails
|
||||
m_ShellConstants.set_values(_T("PROGRAMFILES32"), r32 | pf, reg != r32 ? pf_var : pf_def);
|
||||
m_ShellConstants.set_values(_T("PROGRAMFILES64"), r64 | pf, reg != r64 ? pf_var : pf_def);
|
||||
unsigned int cf_def = add_asciistring(_T("$PROGRAMFILES\\Common Files"));
|
||||
m_ShellConstants.set_values(_T("COMMONFILES"), 0x80 | cf, cf_def);
|
||||
unsigned int cf64_def = add_asciistring(_T("$COMMONFILES"));
|
||||
m_ShellConstants.set_values(_T("COMMONFILES32"), 0x80 | cf, cf_def);
|
||||
m_ShellConstants.set_values(_T("COMMONFILES64"), 0xC0 | cf, cf64_def);
|
||||
m_ShellConstants.set_values(_T("COMMONFILES"), reg | cf, cf_def);
|
||||
unsigned int cf_var = add_asciistring(_T("$COMMONFILES"));
|
||||
m_ShellConstants.set_values(_T("COMMONFILES32"), r32 | cf, reg != r32 ? cf_var : cf_def);
|
||||
m_ShellConstants.set_values(_T("COMMONFILES64"), r64 | cf, reg != r64 ? cf_var : cf_def);
|
||||
|
||||
if ( (pf >= 0x40 || pf_def >= 0xFF || pf64_def > 0xFF) // BUGBUG: pf_def should be ">"?
|
||||
|| (cf > 0x40 || cf_def > 0xFF || cf64_def > 0xFF) )
|
||||
if ( (pf >= 0x40 || pf_def >= 0xFF || pf_var > 0xFF) // BUGBUG: pf_def should be ">"?
|
||||
|| (cf > 0x40 || cf_def > 0xFF || cf_var > 0xFF) )
|
||||
{
|
||||
// see Source\exehead\util.c for implementation details
|
||||
// basically, it knows it needs to get folders from the registry when the 0x80 is on
|
||||
|
@ -456,17 +457,13 @@ void CEXEBuild::init_shellconstantvalues()
|
|||
unsigned int unpf = add_asciistring(_T("ProgramFilesDir"), 0);
|
||||
unsigned int uncf = add_asciistring(_T("CommonFilesDir"), 0);
|
||||
unsigned int unpf_def = add_asciistring(_T("C:\\Program Files"));
|
||||
unsigned int unpf64_def = add_asciistring(_T("$PROGRAMFILES"));
|
||||
unsigned int unpf_var = add_asciistring(_T("$PROGRAMFILES"));
|
||||
unsigned int uncf_def = add_asciistring(_T("$PROGRAMFILES\\Common Files"));
|
||||
unsigned int uncf64_def = add_asciistring(_T("$COMMONFILES"));
|
||||
unsigned int uncf_var = add_asciistring(_T("$COMMONFILES"));
|
||||
set_uninstall_mode(orgunmode);
|
||||
|
||||
if ( unpf != pf
|
||||
|| unpf_def != pf_def
|
||||
|| unpf64_def != pf64_def
|
||||
|| uncf != cf
|
||||
|| uncf_def != cf_def
|
||||
|| uncf64_def != cf64_def)
|
||||
if ( unpf != pf || unpf_def != pf_def || unpf_var != pf_var
|
||||
|| uncf != cf || uncf_def != cf_def || uncf_var != cf_var )
|
||||
{
|
||||
const char* msg = "Internal compiler error: installer's shell constants are different than uninstallers!";
|
||||
ERROR_MSG(_T("%") NPRIns, msg);
|
||||
|
|
|
@ -645,14 +645,14 @@ void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
|
|||
|
||||
// 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 x64)
|
||||
void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR *out, int 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|(x64?KEY_WOW64_64KEY:0),&hKey) == ERROR_SUCCESS)
|
||||
if (RegOpenKeyEx(root,sub,0,KEY_READ|wowsam,&hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD l = NSIS_MAX_STRLEN*sizeof(TCHAR);
|
||||
DWORD t;
|
||||
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;
|
||||
|
|
|
@ -32,7 +32,7 @@ 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 x64);
|
||||
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
|
||||
|
|
|
@ -4023,15 +4023,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
|||
{
|
||||
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,_T("32\0") _T("64\0lastused\0"));
|
||||
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()
|
||||
if (k == 0) // 32
|
||||
ent.offsets[1]=add_intstring(0);
|
||||
else if (k == 1) // 64
|
||||
ent.offsets[1]=add_intstring(KEY_WOW64_64KEY);
|
||||
else if (k == 2) // last used
|
||||
ent.offsets[2]=1;
|
||||
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
|
||||
SCRIPT_MSG(_T("SetRegView: %") NPRIs _T("\n"),line.gettoken_str(1));
|
||||
}
|
||||
return add_entry(&ent);
|
||||
|
|
|
@ -203,7 +203,7 @@ static tokenType tokenlist[TOK__LAST] =
|
|||
{TOK_SETOVERWRITE,_T("SetOverwrite"),1,0,_T("on|off|try|ifnewer|ifdiff"),TP_ALL},
|
||||
{TOK_SETPLUGINUNLOAD,_T("SetPluginUnload"),1,0,_T("deprecated - plug-ins should handle this on their own"),TP_ALL},
|
||||
{TOK_SETREBOOTFLAG,_T("SetRebootFlag"),1,0,_T("true|false"),TP_CODE},
|
||||
{TOK_SETREGVIEW,_T("SetRegView"),1,0,_T("32|64|lastused"),TP_CODE},
|
||||
{TOK_SETREGVIEW,_T("SetRegView"),1,0,_T("32|64|default|lastused"),TP_CODE},
|
||||
{TOK_SETSHELLVARCONTEXT,_T("SetShellVarContext"),1,0,_T("all|current"),TP_CODE},
|
||||
{TOK_SETSILENT,_T("SetSilent"),1,0,_T("silent|normal"),TP_CODE},
|
||||
{TOK_SHOWDETAILS,_T("ShowInstDetails"),1,0,_T("(hide|show|nevershow)"),TP_GLOBAL},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue