From 2589a5fc852db0d5b626c5aaf4a4dec24ef416da Mon Sep 17 00:00:00 2001 From: ramon18 Date: Mon, 22 Dec 2003 00:28:30 +0000 Subject: [PATCH] Code clean up, removed NSIS_SUPPORT_NAMED_USERVARS and NSIS_SUPPORT_LANG_IN_STRINGS Added support for many new constants which get shell folders path without using the registry git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3296 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/build.cpp | 217 ++++++++++++++---------------- Source/build.h | 5 +- Source/exehead/Ui.c | 11 +- Source/exehead/config.h | 19 ++- Source/exehead/fileform.h | 25 +--- Source/exehead/state.h | 8 +- Source/exehead/util.c | 268 +++++++++++++++----------------------- Source/exehead/util.h | 2 + Source/script.cpp | 7 - Source/uservars.h | 3 - 10 files changed, 227 insertions(+), 338 deletions(-) diff --git a/Source/build.cpp b/Source/build.cpp index 4cb53501..1eb4823d 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -12,6 +12,7 @@ #include "ResourceEditor.h" #include "DialogTemplate.h" #include "ResourceVersionInfo.h" +#include int MMapFile::m_iAllocationGranularity = 0; @@ -240,15 +241,17 @@ CEXEBuild::CEXEBuild() // Added by Sunil Kamath 11 June 2003 definedlist.add("NSIS_SUPPORT_STANDARD_PREDEFINES"); #endif -#ifdef NSIS_SUPPORT_NAMED_USERVARS - definedlist.add("NSIS_SUPPORT_NAMED_USERVARS"); -#endif + +// no more optional +definedlist.add("NSIS_SUPPORT_NAMED_USERVARS"); + #ifdef NSIS_SUPPORT_VERSION_INFO definedlist.add("NSIS_SUPPORT_VERSION_INFO"); #endif -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - definedlist.add("NSIS_SUPPORT_LANG_IN_STRINGS"); -#endif + +// no more optional +definedlist.add("NSIS_SUPPORT_LANG_IN_STRINGS"); + #ifdef NSIS_FIX_DEFINES_IN_STRINGS definedlist.add("NSIS_FIX_DEFINES_IN_STRINGS"); #endif @@ -393,8 +396,7 @@ CEXEBuild::CEXEBuild() InitLangTables(); -#ifdef NSIS_SUPPORT_NAMED_USERVARS - // Register static user variables $0, $1 and so one + // Register static user variables $0, $1 and so on // with ONE of reference count, to avoid warning on this vars char Aux[3]; for ( int i = 0; i < 10; i++ ) // 0 - 9 @@ -415,15 +417,49 @@ CEXEBuild::CEXEBuild() m_UserVarNames.add("TEMP",-1); // 25 m_UserVarNames.add("_CLICK",-1); // 26 m_UserVarNames.add("PLUGINSDIR",-1); // 27 + +#ifndef NSIS_SUPPORT_SHELLFOLDERS_CONST m_UserVarNames.add("PROGRAMFILES",-1); // 28 m_UserVarNames.add("SMPROGRAMS",-1); // 29 m_UserVarNames.add("SMSTARTUP",-1); // 30 m_UserVarNames.add("DESKTOP",-1); // 31 m_UserVarNames.add("STARTMENU",-1); // 32 m_UserVarNames.add("QUICKLAUNCH",-1); // 33 - m_UserVarNames.add("WINDIR",-1); // 34 - m_UserVarNames.add("SYSDIR",-1); // 35 everything after here doesn't have trailing slash removal - m_UserVarNames.add("HWNDPARENT",-1); // 36 +#endif + // (if not using shell codes) + m_UserVarNames.add("WINDIR",-1); // 34 (28) + m_UserVarNames.add("SYSDIR",-1); // 35 (29) everything after here doesn't have trailing slash removal + m_UserVarNames.add("HWNDPARENT",-1); // 36 (30) + +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + m_ShellConstants.add("PROGRAMFILES",CSIDL_CONTROLS, CSIDL_CONTROLS); // Special for virtual "Program Files" + m_ShellConstants.add("SMPROGRAMS",CSIDL_PROGRAMS, CSIDL_COMMON_PROGRAMS ); + m_ShellConstants.add("SMSTARTUP",CSIDL_STARTUP, CSIDL_COMMON_STARTUP ); + m_ShellConstants.add("DESKTOP",CSIDL_DESKTOPDIRECTORY, CSIDL_COMMON_DESKTOPDIRECTORY); + m_ShellConstants.add("STARTMENU",CSIDL_STARTMENU, CSIDL_COMMON_STARTMENU ); + m_ShellConstants.add("QUICKLAUNCH", CSIDL_DESKTOP, CSIDL_DESKTOP ); // Special for virtual quick launch (needed for compatibility) + m_ShellConstants.add("COMMONFILES",CSIDL_BITBUCKET, CSIDL_BITBUCKET ); // Special for virtual "Commmon Files" + m_ShellConstants.add("DOCUMENTS",CSIDL_PERSONAL, CSIDL_COMMON_DOCUMENTS ); + m_ShellConstants.add("SENDTO",CSIDL_SENDTO, CSIDL_SENDTO ); + m_ShellConstants.add("RECENT",CSIDL_RECENT, CSIDL_RECENT ); + m_ShellConstants.add("FAVORITES",CSIDL_FAVORITES, CSIDL_COMMON_FAVORITES ); + m_ShellConstants.add("MUSIC",CSIDL_MYMUSIC, CSIDL_COMMON_MUSIC ); + m_ShellConstants.add("PICTURES",CSIDL_MYPICTURES, CSIDL_COMMON_PICTURES ); + m_ShellConstants.add("VIDEOS",CSIDL_MYVIDEO, CSIDL_COMMON_VIDEO ); + m_ShellConstants.add("NETHOOD", CSIDL_NETHOOD, CSIDL_NETHOOD ); + m_ShellConstants.add("FONTS", CSIDL_FONTS, CSIDL_FONTS ); + m_ShellConstants.add("TEMPLATES", CSIDL_TEMPLATES, CSIDL_COMMON_TEMPLATES ); + m_ShellConstants.add("APPDATA", CSIDL_APPDATA, CSIDL_COMMON_APPDATA ); + m_ShellConstants.add("PRINTHOOD", CSIDL_PRINTHOOD, CSIDL_PRINTHOOD ); + //m_ShellConstants.add("ALTSTARTUP", CSIDL_ALTSTARTUP, CSIDL_COMMON_ALTSTARTUP ); + m_ShellConstants.add("INTERNET_CACHE", CSIDL_INTERNET_CACHE, CSIDL_INTERNET_CACHE); + m_ShellConstants.add("COOKIES", CSIDL_COOKIES, CSIDL_COOKIES); + m_ShellConstants.add("HISTORY", CSIDL_HISTORY, CSIDL_HISTORY); + m_ShellConstants.add("PROFILE", CSIDL_PROFILE, CSIDL_PROFILE); + m_ShellConstants.add("ADMINTOOLS", CSIDL_ADMINTOOLS, CSIDL_COMMON_ADMINTOOLS); + m_ShellConstants.add("RESOURCES", CSIDL_RESOURCES, CSIDL_RESOURCES); + m_ShellConstants.add("RESOURCES_LOCALIZED", CSIDL_RESOURCES_LOCALIZED, CSIDL_RESOURCES_LOCALIZED); + m_ShellConstants.add("CDBURN_AREA", CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA); #endif } @@ -438,11 +474,7 @@ int CEXEBuild::add_string(const char *string, int process/*=1*/, WORD codepage/* int idx = 0; char *cp = strdup(string+2); char *p = strchr(cp, ')'); -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS if (p && p[1] == '\0' ) { // if string is only a language str identifier -#else - if (p) { -#endif *p = 0; idx = DefineLangString(cp, process); } @@ -467,49 +499,6 @@ int CEXEBuild::add_intstring(const int i) // returns offset in stringblock // based on Dave Laundon's code int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_ACP*/) { -#ifndef NSIS_SUPPORT_NAMED_USERVARS - static const char VarNames[] = - "HWNDPARENT\0" // 0 - "0\0" // 1 - "1\0" // 2 - "2\0" // 3 - "3\0" // 4 - "4\0" // 5 - "5\0" // 6 - "6\0" // 7 - "7\0" // 8 - "8\0" // 9 - "9\0" // 10 - "R0\0" // 11 - "R1\0" // 12 - "R2\0" // 13 - "R3\0" // 14 - "R4\0" // 15 - "R5\0" // 16 - "R6\0" // 17 - "R7\0" // 18 - "R8\0" // 19 - "R9\0" // 20 - "CMDLINE\0" // 21 everything before here doesn't have trailing slash removal - - "INSTDIR\0" // 22 - "OUTDIR\0" // 23 - "EXEDIR\0" // 24 - "LANGUAGE\0" // 25 - "TEMP\0" // 26 - "_CLICK\0" // 27 - "PLUGINSDIR\0" // 28 - "PROGRAMFILES\0" // 29 - "SMPROGRAMS\0" // 30 - "SMSTARTUP\0" // 31 - "DESKTOP\0" // 32 - "STARTMENU\0" // 33 - "QUICKLAUNCH\0" // 34 - "WINDIR\0" // 35 - "SYSDIR\0" // 36 - ; -#endif - const char *p=in; while (*p) { @@ -543,32 +532,8 @@ int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_A p++; // Can simply convert $$ to $ now else { -#ifndef NSIS_SUPPORT_NAMED_USERVARS - - const char *pVarName; - for ( - pVarName = VarNames, i = VAR_CODES_START; - strncmp(pVarName, p, strlen(pVarName)); - pVarName += strlen(pVarName) + 1, i++ - ); - // Found? - if (*pVarName -#ifndef NSIS_CONFIG_PLUGIN_SUPPORT - && i != VAR_CODES_START + USER_VARS_COUNT -#endif - ) { - p += strlen(pVarName); - } - else // warning should go here -#endif // not NSIS_SUPPORT_NAMED_USERVARS - { - -#if defined(NSIS_SUPPORT_NAMED_USERVARS) || defined(NSIS_SUPPORT_LANG_IN_STRINGS) bool bProceced=false; -#endif - -#ifdef NSIS_SUPPORT_NAMED_USERVARS if ( *p ) { const char *pUserVarName = p; @@ -577,6 +542,11 @@ int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_A while ( pUserVarName > p ) { +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + if ( m_ShellConstants.get((char*)p, pUserVarName-p) >= 0 ) + break; // Upps it's a shell constant +#endif + int idxUserVar = m_UserVarNames.get((char*)p, pUserVarName-p); if ( idxUserVar >= 0 ) { @@ -595,8 +565,33 @@ int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_A pUserVarName--; } } -#endif -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + if ( !bProceced && *p ) + { + const char *pShellConstName = p; + while ( isSimpleChar(*pShellConstName) ) + pShellConstName++; + + while ( pShellConstName > p ) + { + int idxConst = m_ShellConstants.get((char*)p, pShellConstName-p); + if ( idxConst >= 0 ) + { + int CSIDL_Value_current = m_ShellConstants.get_value1(idxConst); + int CSIDL_Value_all = m_ShellConstants.get_value2(idxConst); + *out++=(unsigned int)SHELL_CODES_START; // Constant code identifier + *(WORD*)out=((WORD)CSIDL_Value_current+1) | 0xF000; + out += sizeof(WORD); + *(WORD*)out=((WORD)CSIDL_Value_all+1) | 0xF000; + out += sizeof(WORD); + p += pShellConstName-p; + bProceced = true; + break; + } + pShellConstName--; + } + } +#endif //NSIS_SUPPORT_SHELLFOLDERS_CONST if ( !bProceced && *p == '(' ) { int idx = -1; @@ -617,12 +612,9 @@ int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_A } free(cp); } -#endif -#if defined(NSIS_SUPPORT_NAMED_USERVARS) || defined(NSIS_SUPPORT_LANG_IN_STRINGS) if ( bProceced ) continue; else -#endif { char tbuf[64]; char cBracket = '\0'; @@ -653,7 +645,7 @@ int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_A if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0; } if ( bDoWarning ) - warning_fl("unknown variable \"%s\" detected, ignoring",tbuf); + warning_fl("unknown variable/constant \"%s\" detected, ignoring",tbuf); i = '$'; } } @@ -2268,7 +2260,6 @@ int CEXEBuild::write_output(void) if (err != PS_OK) return err; -#ifdef NSIS_SUPPORT_NAMED_USERVARS init_res_editor(); VerifyDeclaredUserVarRefs(&m_UserVarNames); int MaxUserVars = m_UserVarNames.getnum(); @@ -2277,7 +2268,6 @@ int CEXEBuild::write_output(void) ERROR_MSG("Internal compiler error #12346: invalid exehead cannot find section \"%s\"!\n", VARS_SECTION_NAME); return PS_ERROR; } -#endif // Save all changes to the exe header try { @@ -3129,10 +3119,8 @@ int CEXEBuild::add_plugins_dir_initializer(void) int ret; int zero_offset; -#ifdef NSIS_SUPPORT_NAMED_USERVARS int var_zero; var_zero=m_UserVarNames.get("0"); -#endif again: // Function [un.]Initialize_____Plugins @@ -3156,11 +3144,7 @@ again: ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(exec_error)); if (ret != PS_OK) return ret; // GetTempFileName $0 -#ifdef NSIS_SUPPORT_NAMED_USERVARS ret=add_entry_direct(EW_GETTEMPFILENAME, var_zero, add_string("$TEMP")); -#else - ret=add_entry_direct(EW_GETTEMPFILENAME, 0, add_string("$TEMP")); -#endif if (ret != PS_OK) return ret; // Delete $0 - the temp file created ret=add_entry_direct(EW_DELETEFILE, zero_offset); @@ -3172,18 +3156,10 @@ again: ret=add_entry_direct(EW_IFFLAG, ns_label.add("Initialize_____Plugins_error",0), 0, FLAG_OFFSET(exec_error)); if (ret != PS_OK) return ret; // Copy $0 to $PLUGINSDIR -#ifdef NSIS_SUPPORT_NAMED_USERVARS ret=add_entry_direct(EW_ASSIGNVAR, m_UserVarNames.get("PLUGINSDIR"), zero_offset); -#else - ret=add_entry_direct(EW_ASSIGNVAR, 25, zero_offset); -#endif if (ret != PS_OK) return ret; // Pop $0 -#ifdef NSIS_SUPPORT_NAMED_USERVARS ret=add_entry_direct(EW_PUSHPOP, var_zero, 1); -#else - ret=add_entry_direct(EW_PUSHPOP, 0, 1); -#endif if (ret != PS_OK) return ret; // done @@ -3233,12 +3209,18 @@ void CEXEBuild::close_res_editor() res_editor=0; } -// Added by ramon 3 jun 2003 -#ifdef NSIS_SUPPORT_NAMED_USERVARS int CEXEBuild::DeclaredUserVar(const char *szVarName) { +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + if ( m_ShellConstants.get((char*)szVarName) >= 0 ) + { + ERROR_MSG("Error: name \"%s\" in use by constant\n", szVarName); + return PS_ERROR; + } +#endif + int idxUserVar = m_UserVarNames.get((char*)szVarName); - if ( idxUserVar > 0 ) + if ( idxUserVar >= 0 ) { ERROR_MSG("Error: variable \"%s\" already declared\n", szVarName); return PS_ERROR; @@ -3277,11 +3259,10 @@ int CEXEBuild::DeclaredUserVar(const char *szVarName) } return PS_OK; } -#endif + int CEXEBuild::GetUserVarIndex(LineParser &line, int token) { -#ifdef NSIS_SUPPORT_NAMED_USERVARS char *p = line.gettoken_str(token); if ( *p == '$' && *(p+1) ) { @@ -3291,17 +3272,20 @@ int CEXEBuild::GetUserVarIndex(LineParser &line, int token) m_UserVarNames.inc_reference(idxUserVar); return idxUserVar; } +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + else + { + int idxConst = m_ShellConstants.get((char *)p+1); + if ( idxConst >= 0 ) + { + ERROR_MSG("Error: cannot change constants : %s\n", p); + } + } +#endif } return -1; -#else - static const char *usrvars="$0\0$1\0$2\0$3\0$4\0$5\0$6\0$7\0$8\0$9\0" - "$R0\0$R1\0$R2\0$R3\0$R4\0$R5\0$R6\0$R7\0$R8\0$R9\0" - "$CMDLINE\0$INSTDIR\0$OUTDIR\0$EXEDIR\0$LANGUAGE\0"; - return line.gettoken_enum(token, usrvars); -#endif } -#ifdef NSIS_SUPPORT_NAMED_USERVARS void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList) { for ( int i = TOTAL_COMPATIBLE_STATIC_VARS_COUNT; i < pVarsStringList->getnum(); i++ ) @@ -3312,4 +3296,3 @@ void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList) } } } -#endif \ No newline at end of file diff --git a/Source/build.h b/Source/build.h index de9cd5da..ba5711ab 100644 --- a/Source/build.h +++ b/Source/build.h @@ -11,6 +11,7 @@ using namespace std; #include "ResourceEditor.h" #include "ResourceVersionInfo.h" #include "uservars.h" +#include "constants.h" #include "exehead/fileform.h" #include "exehead/config.h" @@ -253,10 +254,12 @@ class CEXEBuild { // User variables stuff int GetUserVarIndex(LineParser &line, int token); // Added by ramon 3 jun 2003 -#ifdef NSIS_SUPPORT_NAMED_USERVARS UserVarsStringList m_UserVarNames; int DeclaredUserVar(const char *VarName); void VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList); + +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + ConstantsStringList m_ShellConstants; #endif // a whole bunch O data. diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 70a86db4..dec52086 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -353,7 +353,7 @@ static int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lPara hwnd, BFFM_ENABLEOK, 0, - SHGetPathFromIDList((LPITEMIDLIST)lParam,(char*)lpData) + my_PIDL2Path((char*)lpData, (LPITEMIDLIST)lParam, 0) #ifdef NSIS_SUPPORT_CODECALLBACKS && !ExecuteCodeSegment(g_header->code_onVerifyInstDir,NULL) #endif @@ -806,13 +806,8 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar idlist = SHBrowseForFolder(&bi); if (idlist) { - IMalloc *m; - SHGetMalloc(&m); - if (m) - { - m->lpVtbl->Free(m,idlist); - m->lpVtbl->Release(m); - } + // Get and free idlist + my_PIDL2Path(name, idlist, 1); if (g_header->install_directory_auto_append) { diff --git a/Source/exehead/config.h b/Source/exehead/config.h index c8451c89..4081b066 100644 --- a/Source/exehead/config.h +++ b/Source/exehead/config.h @@ -209,20 +209,16 @@ // NSIS_SUPPORT_MESSAGEBOX enables support for MessageBox #define NSIS_SUPPORT_MESSAGEBOX -// Added by ramon 3 jun 2003 -// NSIS_SUPPORT_NAMED_USERVARS enables support for user variables -#define NSIS_SUPPORT_NAMED_USERVARS - // Added by ramon 5 jun 2003 // NSIS_SUPPORT_VERSION_INFO enables support for version information on final exe #define NSIS_SUPPORT_VERSION_INFO -// NSIS_SUPPORT_LANG_IN_STRINGS enables support for language strings inside other strings -#define NSIS_SUPPORT_LANG_IN_STRINGS - // NSIS_FIX_DEFINES_IN_STRINGS fixes defines inside defines and handles chars $ perfectly // #define NSIS_FIX_DEFINES_IN_STRINGS +// NSIS_SUPPORT_SHELLFOLDERS_CONST enable support for common shell folder codes +#define NSIS_SUPPORT_SHELLFOLDERS_CONST + // NSIS_SUPPORT_STANDARD_PREDEFINES enables standard predefines in NSIS. // The defines enabled are: // __FILE__ - current script name @@ -402,10 +398,13 @@ // From $0 to $PLUGINSDIR, $_CLICK #define USER_VARS_COUNT 28 -#ifdef NSIS_SUPPORT_NAMED_USERVARS // This is the total number of old static var // From $0 to $HWNDPARENT -#define TOTAL_COMPATIBLE_STATIC_VARS_COUNT 37 +#ifdef NSIS_CONFIG_PLUGIN_SUPPORT + #define TOTAL_COMPATIBLE_STATIC_VARS_COUNT 32 +#else + #define TOTAL_COMPATIBLE_STATIC_VARS_COUNT 31 +#endif #define VARS_SECTION_NAME ".ndata" @@ -416,8 +415,6 @@ typedef char NSIS_STRING[NSIS_MAX_STRLEN]; // The real maximum is (0x0FFF - USER_VARS_COUNT) = 4068 #define MAX_NAMED_USER_VARS (0x0FFF - USER_VARS_COUNT) -#endif //NSIS_SUPPORT_NAMED_USERVARS - #endif//!APSTUDIO_INVOKED #endif // NSIS_CONFIG_H diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 0fc8f70e..1346452a 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -426,28 +426,9 @@ DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove); // $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. // Added by ramon 3 jun 2003 -#ifdef NSIS_SUPPORT_NAMED_USERVARS - #ifdef NSIS_SUPPORT_LANG_IN_STRINGS - #define VAR_CODES_START 253 - #else - #define VAR_CODES_START 254 - #endif - #ifdef NSIS_SUPPORT_LANG_IN_STRINGS - #define LANG_CODES_START 254 - #endif -#else - #ifdef NSIS_SUPPORT_LANG_IN_STRINGS - #define LANG_CODES_START 254 - #else - #define LANG_CODES_START 255 - #endif - - #ifdef NSIS_CONFIG_PLUGIN_SUPPORT - #define VAR_CODES_START (LANG_CODES_START - 37) - #else - #define VAR_CODES_START (LANG_CODES_START - 36) - #endif -#endif +#define VAR_CODES_START 252 +#define SHELL_CODES_START 253 +#define LANG_CODES_START 254 #define NSIS_INSTDIR_INVALID 1 #define NSIS_INSTDIR_NOT_ENOUGH_SPACE 2 diff --git a/Source/exehead/state.h b/Source/exehead/state.h index 52a3822c..a3107773 100644 --- a/Source/exehead/state.h +++ b/Source/exehead/state.h @@ -1,8 +1,4 @@ -#ifdef NSIS_SUPPORT_NAMED_USERVARS - extern NSIS_STRING g_usrvars[TOTAL_COMPATIBLE_STATIC_VARS_COUNT]; -#else - extern char g_usrvars[USER_VARS_COUNT][NSIS_MAX_STRLEN]; -#endif +extern NSIS_STRING g_usrvars[TOTAL_COMPATIBLE_STATIC_VARS_COUNT]; #define state_command_line g_usrvars[20] #define state_install_directory g_usrvars[21] @@ -12,7 +8,7 @@ #define state_temp_dir g_usrvars[25] #define state_click_next g_usrvars[26] #ifdef NSIS_CONFIG_PLUGIN_SUPPORT - #define state_plugins_dir g_usrvars[27] +#define state_plugins_dir g_usrvars[27] #endif extern char g_caption[NSIS_MAX_STRLEN*2]; diff --git a/Source/exehead/util.c b/Source/exehead/util.c index 1047493f..78b47789 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -1,5 +1,4 @@ #include -#include #include #include "util.h" #include "state.h" @@ -16,36 +15,36 @@ char g_log_file[1024]; #endif #endif -#ifdef NSIS_SUPPORT_NAMED_USERVARS - // *** DO NOT DECLARE MORE VARIABLES INSIDE THIS PRAGMAS *** - // This will produce a special section called ".ndata" (stands for nsis data) - // this way makensis during build time, can search for this section by name - // and change the virtual size of this section - // which result in extra memory for extra variables without code to do allocation :) - // nsis then removes the "DISCARDABLE" style from section (for safe) - #pragma bss_seg( VARS_SECTION_NAME ) - NSIS_STRING g_usrvars[TOTAL_COMPATIBLE_STATIC_VARS_COUNT]; - #pragma bss_seg() - #define SECTION_VARS_RWD "/section:" ## VARS_SECTION_NAME ## ",rwd" - #pragma comment(linker, SECTION_VARS_RWD) -#else - char temp_directory[NSIS_MAX_STRLEN]; - char g_usrvars[USER_VARS_COUNT][NSIS_MAX_STRLEN]; - char *state_command_line=g_usrvars[20]; - char *state_install_directory=g_usrvars[21]; - char *state_output_directory=g_usrvars[22]; - char *state_exe_directory=g_usrvars[23]; - char *state_language=g_usrvars[24]; - #ifdef NSIS_CONFIG_PLUGIN_SUPPORT - char *state_plugins_dir=g_usrvars[25]; - #endif - char *state_plugins_dir=g_usrvars[36]; -#endif +// *** DO NOT DECLARE MORE VARIABLES INSIDE THIS PRAGMAS *** +// This will produce a special section called ".ndata" (stands for nsis data) +// this way makensis during build time, can search for this section by name +// and change the virtual size of this section +// which result in extra memory for extra variables without code to do allocation :) +// nsis then removes the "DISCARDABLE" style from section (for safe) +#pragma bss_seg( VARS_SECTION_NAME ) +NSIS_STRING g_usrvars[TOTAL_COMPATIBLE_STATIC_VARS_COUNT]; +#pragma bss_seg() +#define SECTION_VARS_RWD "/section:" ## VARS_SECTION_NAME ## ",rwd" +#pragma comment(linker, SECTION_VARS_RWD) #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif +int my_PIDL2Path(char *out, LPITEMIDLIST idl, int bFree) +{ + int Res; + IMalloc *m; + SHGetMalloc(&m); + Res = SHGetPathFromIDList(idl, out); + if (m && bFree) + { + m->lpVtbl->Free(m,idl); + m->lpVtbl->Release(m); + } + return Res; +} + HANDLE NSISCALL myCreateProcess(char *cmd, char *dir) { DWORD d; @@ -462,6 +461,12 @@ char ps_tmpbuf[NSIS_MAX_STRLEN*2]; // Based on Dave Laundon's simplified process_string char * NSISCALL GetNSISString(char *outbuf, int strtab) { +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + static char smwcvesf[]="Software\\Microsoft\\Windows\\CurrentVersion"; +#else + static char smwcvesf[]="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; +#endif + char *in = (char*)GetNSISStringNP(GetNSISTab(strtab)); char *out; if (outbuf >= ps_tmpbuf && outbuf < ps_tmpbuf+sizeof(ps_tmpbuf)) @@ -474,149 +479,73 @@ char * NSISCALL GetNSISString(char *outbuf, int strtab) while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN) { int nVarIdx = (unsigned char)*in++; -#ifndef NSIS_SUPPORT_NAMED_USERVARS - if (nVarIdx < VAR_CODES_START) - { - *out++ = nVarIdx; - } - else if (nVarIdx == 255) - { - *out++ = *in++; - } -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - else if (nVarIdx == LANG_CODES_START) - { - nVarIdx = *(short*)in; in+=sizeof(short); - GetNSISString(out, nVarIdx); - out+=mystrlen(out); - } -#endif - else - { - DWORD f; - static char smwcvesf[]="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; - switch (nVarIdx) // The order of this list must match that in ..\strlist.cpp (err, build.cpp -J) - { - case VAR_CODES_START + 0: // HWNDPARENT - myitoa(out, (unsigned int)g_hwnd); - break; - case VAR_CODES_START + 1: // 0 - case VAR_CODES_START + 2: // 1 - case VAR_CODES_START + 3: // 2 - case VAR_CODES_START + 4: // 3 - case VAR_CODES_START + 5: // 4 - case VAR_CODES_START + 6: // 5 - case VAR_CODES_START + 7: // 6 - case VAR_CODES_START + 8: // 7 - case VAR_CODES_START + 9: // 8 - case VAR_CODES_START + 10: // 9 - case VAR_CODES_START + 11: // R0 - case VAR_CODES_START + 12: // R1 - case VAR_CODES_START + 13: // R2 - case VAR_CODES_START + 14: // R3 - case VAR_CODES_START + 15: // R4 - case VAR_CODES_START + 16: // R5 - case VAR_CODES_START + 17: // R6 - case VAR_CODES_START + 18: // R7 - case VAR_CODES_START + 19: // R8 - case VAR_CODES_START + 20: // R9 - case VAR_CODES_START + 21: // CMDLINE - case VAR_CODES_START + 22: // INSTDIR - case VAR_CODES_START + 23: // OUTDIR - case VAR_CODES_START + 24: // EXEDIR - case VAR_CODES_START + 25: // LANGUAGE - case VAR_CODES_START + 26: // TEMP - case VAR_CODES_START + 27: // _CLICK - case VAR_CODES_START + 28: // PLUGINSDIR - mystrcpy(out, g_usrvars[nVarIdx - (VAR_CODES_START + 1)]); - break; - - case VAR_CODES_START + 29: // PROGRAMFILES - smwcvesf[41]=0; - myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out); - if (!*out) - mystrcpy(out, "C:\\Program Files"); - break; - - case VAR_CODES_START + 30: // SMPROGRAMS - case VAR_CODES_START + 31: // SMSTARTUP - case VAR_CODES_START + 32: // DESKTOP - case VAR_CODES_START + 33: // STARTMENU - case VAR_CODES_START + 34: // QUICKLAUNCH - { - static const char *tab[]={ - "Programs", - "Startup", - "Desktop", - "Start Menu", - "AppData" - }; - static char name[20]="Common "; - const char *name_=tab[nVarIdx-(VAR_CODES_START+30)]; - mystrcpy(name+7,name_); - f=g_exec_flags.all_user_var & (nVarIdx != VAR_CODES_START + 34); - - again: - - smwcvesf[41]='\\'; - myRegGetStr(f?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER, - smwcvesf, - f?name:name_,out); - if (!out[0]) - { - if (f) - { - f=0; goto again; - } - mystrcpy(out,temp_directory); - } - - if (nVarIdx == VAR_CODES_START + 34) { - lstrcat(out, "\\Microsoft\\Internet Explorer\\Quick Launch"); - f = GetFileAttributes(out); - if (f != (DWORD)-1 && (f & FILE_ATTRIBUTE_DIRECTORY)) - break; - } - else break; - } - - case VAR_CODES_START + 35: // TEMP - mystrcpy(out,temp_directory); - break; - - case VAR_CODES_START + 36: // WINDIR - GetWindowsDirectory(out, NSIS_MAX_STRLEN); - break; - - case VAR_CODES_START + 37: // SYSDIR - GetSystemDirectory(out, NSIS_MAX_STRLEN); - break; - - #if VAR_CODES_START + 37 >= 255 - #error "Too many variables! Extend VAR_CODES_START!" - #endif - } // switch - // validate the directory name - if (nVarIdx > 21+VAR_CODES_START && nVarIdx != VAR_CODES_START+27) { - // only if not $0 to $R9, $CMDLINE, $HWNDPARENT, or $_CLICK - // ($LANGUAGE can't have trailing backslash anyway...) - validate_filename(out); - } - out+=mystrlen(out); - } // >= VAR_CODES_START -#else - if (nVarIdx == 255) { *out++ = *in++; } +#ifdef NSIS_SUPPORT_SHELLFOLDERS_CONST + else if (nVarIdx == SHELL_CODES_START) + { + // NOTE 1: the code CSIDL_DESKTOP, is used for QUICKLAUNCH + // NOTE 2: the code CSIDL_BITBUCKET is used for COMMONFILES + // NOTE 3: the code CSIDL_CONTROLS is used for PROGRAMFILES + LPITEMIDLIST idl; + int qLaunch=0; + + nVarIdx = (*(WORD*)in & 0x0FFF)-1; in+=sizeof(WORD); // Read code for current user + if ( g_exec_flags.all_user_var ) + nVarIdx = (*(WORD*)in & 0x0FFF)-1; in+=sizeof(WORD); // Use code for All users instead + + nVarIdx |= CSIDL_FLAG_CREATE; + *out=0; + + while (TRUE) + { + switch ( nVarIdx ) + { + case CSIDL_BITBUCKET: // COMMONFILES + myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "CommonFilesDir", out); + break; + case CSIDL_CONTROLS: // PROGRAMFILES + myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out); + if (!*out) + mystrcpy(out, "C:\\Program Files"); + break; + case CSIDL_DESKTOP: // QUICKLAUNCH + nVarIdx = CSIDL_APPDATA; + qLaunch = 1; + // dont break + default: + // Get and force path creation + if ( !SHGetSpecialFolderLocation(g_hwnd, nVarIdx, &idl) ) + { + if (my_PIDL2Path(out, idl, 1)) + { + if (qLaunch) + lstrcat(out,"\\Microsoft\\Internet Explorer\\Quick Launch"); + } + } + else + *out=0; + break; + } + + if ( *out || ((nVarIdx & CSIDL_FLAG_CREATE) != CSIDL_FLAG_CREATE) ) + break; + else + nVarIdx &= ~CSIDL_FLAG_CREATE; + } + + validate_filename(out); + out+=mystrlen(out); + } +#endif else if (nVarIdx == VAR_CODES_START) { - DWORD f; - static char smwcvesf[]="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; nVarIdx = (*(WORD*)in & 0x0FFF)-1; in+=sizeof(WORD); switch (nVarIdx) // The order of this list must match that in ..\strlist.cpp (err, build.cpp -J) { +#ifndef NSIS_SUPPORT_SHELLFOLDERS_CONST case 28: // PROGRAMFILES smwcvesf[41]=0; myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out); @@ -630,6 +559,7 @@ char * NSISCALL GetNSISString(char *outbuf, int strtab) case 32: // STARTMENU case 33: // QUICKLAUNCH { + DWORD f; static const char *tab[]={ "Programs", "Startup", @@ -678,6 +608,21 @@ char * NSISCALL GetNSISString(char *outbuf, int strtab) myitoa(out, (unsigned int)g_hwnd); break; +#else // when NSIS_SUPPORT_SHELLFOLDERS_CONST is defined + + case 28: // WINDIR + GetWindowsDirectory(out, NSIS_MAX_STRLEN); + break; + + case 29: // SYSDIR + GetSystemDirectory(out, NSIS_MAX_STRLEN); + break; + + case 30: // HWNDPARENT + myitoa(out, (unsigned int)g_hwnd); + break; + +#endif default: mystrcpy(out, g_usrvars[nVarIdx]); } // switch @@ -689,19 +634,16 @@ char * NSISCALL GetNSISString(char *outbuf, int strtab) } out+=mystrlen(out); } // == VAR_CODES_START -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS else if (nVarIdx == LANG_CODES_START) { nVarIdx = *(short*)in; in+=sizeof(short); GetNSISString(out, nVarIdx); out+=mystrlen(out); } -#endif else // Normal char { *out++ = nVarIdx; } -#endif } // while *out = 0; if (outbuf) diff --git a/Source/exehead/util.h b/Source/exehead/util.h index e4d08ec4..4ed6fb77 100644 --- a/Source/exehead/util.h +++ b/Source/exehead/util.h @@ -1,4 +1,5 @@ #include "config.h" +#include extern char ps_tmpbuf[NSIS_MAX_STRLEN*2]; char * NSISCALL GetNSISString(char *outbuf, int strtab); @@ -13,6 +14,7 @@ int NSISCALL mystrlen(const char *in); char * NSISCALL mystrstr(char *a, char *b); WIN32_FIND_DATA * NSISCALL file_exists(char *buf); char * NSISCALL my_GetTempFileName(char *buf, const char *dir); +int my_PIDL2Path(char *out, LPITEMIDLIST idl, int bFree); //BOOL NSISCALL my_SetWindowText(HWND hWnd, const char *val); #define my_SetWindowText SetWindowText diff --git a/Source/script.cpp b/Source/script.cpp index de3fd0de..0a93ec56 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -4984,7 +4984,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #endif//!NSIS_SUPPORT_CREATEFONT // Added by ramon 3 jun 2003 -#ifdef NSIS_SUPPORT_NAMED_USERVARS case TOK_DEFVAR: { SCRIPT_MSG("VAR \"%s\"\n",line.gettoken_str(1)); @@ -4994,12 +4993,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } return make_sure_not_in_secorfunc(line.gettoken_str(0)); -#else //NSIS_SUPPORT_NAMED_USERVARS - case TOK_DEFVAR: - ERROR_MSG("Error: %s specified, case NSIS_SUPPORT_NAMED_USERVARS not defined.\n",line.gettoken_str(0)); - return PS_ERROR; -#endif //NSIS_SUPPORT_NAMED_USERVARS - // Added by ramon 6 jun 2003 #ifdef NSIS_SUPPORT_VERSION_INFO case TOK_VI_ADDKEY: diff --git a/Source/uservars.h b/Source/uservars.h index d5617642..0d087776 100644 --- a/Source/uservars.h +++ b/Source/uservars.h @@ -3,8 +3,6 @@ #ifndef ___USERVARS___H_____ #define ___USERVARS___H_____ -#ifdef NSIS_SUPPORT_NAMED_USERVARS - #include "Lang.h" struct uservarstring { @@ -87,6 +85,5 @@ class UserVarsStringList : public SortedStringListND return -1; } }; -#endif //NSIS_SUPPORT_NAMED_USERVARS #endif