From 09e7008d83cc3bd21559e961c20cdcdd8db11503 Mon Sep 17 00:00:00 2001 From: kichik Date: Sat, 9 Nov 2002 13:51:40 +0000 Subject: [PATCH] Made it so only one resource editor will be created instead of every time a resource editor is needed, and added InitPluginDir git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1639 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/build.cpp | 79 +++++++++++++++++++++++++++--------------- Source/build.h | 5 +++ Source/script.cpp | 88 +++++++++++++++++++++-------------------------- Source/tokens.cpp | 1 + Source/tokens.h | 1 + 5 files changed, 97 insertions(+), 77 deletions(-) diff --git a/Source/build.cpp b/Source/build.cpp index 7ce272e4..3409d1ff 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -295,6 +295,8 @@ CEXEBuild::CEXEBuild() build_custom_used=0; ubuild_custom_used=0; + + res_editor=0; } int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); } @@ -1253,6 +1255,7 @@ int CEXEBuild::write_output(void) #ifdef NSIS_CONFIG_VISIBLE_SUPPORT { + SCRIPT_MSG("Processing pages... "); page pg = { 0, #ifdef NSIS_SUPPORT_CODECALLBACKS @@ -1309,15 +1312,15 @@ int CEXEBuild::write_output(void) } if (license==1) { - ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "license", "LicenseData"); + ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "license", "LicenseData"); return PS_ERROR; } if (selcom==1) { - ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "components", "ComponentText"); + ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "components", "ComponentText"); return PS_ERROR; } if (dir==1) { - ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "directory selection", "DirText"); + ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "directory selection", "DirText"); return PS_ERROR; } if (!instlog) { @@ -1388,11 +1391,11 @@ int CEXEBuild::write_output(void) page *p=(page *) ubuild_pages.get(); while (i!=build_header.common.num_pages) { switch (p->id) { - #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT case NSIS_PAGE_UNINST: uninst++; break; - #endif +#endif case NSIS_PAGE_INSTFILES: instlog++; break; @@ -1402,7 +1405,7 @@ int CEXEBuild::write_output(void) } if (uninst==1) { - ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "UninstallText"); + ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "UninstallText"); return PS_ERROR; } if (!instlog) { @@ -1423,10 +1426,6 @@ int CEXEBuild::write_output(void) ubuild_pages.add(&pg,sizeof(page)); build_uninst.common.num_pages++; } - - /*case NSIS_PAGE_UNINST: - p->next=LANG_BTN_UNINST; - break;*/ page *p=(page *) ubuild_pages.get(); int noinstlogback=0; @@ -1452,41 +1451,40 @@ int CEXEBuild::write_output(void) #endif #endif main--; + + SCRIPT_MSG("Done!\n"); try { SCRIPT_MSG("Removing unused resources... "); - CResourceEditor re(header_data_new, exeheader_size_new); - #ifdef NSIS_CONFIG_LICENSEPAGE + init_res_editor(); +#ifdef NSIS_CONFIG_LICENSEPAGE if (!license) { - re.UpdateResource(RT_DIALOG, IDD_LICENSE, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_LICENSE, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } - #endif // NSIS_CONFIG_LICENSEPAGE - #ifdef NSIS_CONFIG_COMPONENTPAGE +#endif // NSIS_CONFIG_LICENSEPAGE +#ifdef NSIS_CONFIG_COMPONENTPAGE if (!selcom) { - re.UpdateResource(RT_DIALOG, IDD_SELCOM, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - re.UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_SELCOM, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } - #endif // NSIS_CONFIG_COMPONENTPAGE +#endif // NSIS_CONFIG_COMPONENTPAGE if (!dir) { - re.UpdateResource(RT_DIALOG, IDD_DIR, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_DIR, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } - #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (!uninst) { - re.UpdateResource(RT_DIALOG, IDD_UNINST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_UNINST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } - #endif // NSIS_CONFIG_UNINSTALL_SUPPORT +#endif // NSIS_CONFIG_UNINSTALL_SUPPORT if (!instlog) { - re.UpdateResource(RT_DIALOG, IDD_INSTFILES, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_INSTFILES, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } if (!main) { - re.UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); if (!build_compress_whole && !build_crcchk) - re.UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); - SCRIPT_MSG("Done!\n"); } catch (exception& err) { @@ -1496,6 +1494,15 @@ int CEXEBuild::write_output(void) } #endif // NSIS_CONFIG_VISIBLE_SUPPORT + // Save all changes to the exe header + try { + close_res_editor(); + } + catch (exception& err) { + ERROR_MSG("\nError: %s\n", err.what()); + return PS_ERROR; + } + // Pack exe header if asked for if (build_packname[0] && build_packcmd[0]) { @@ -2246,3 +2253,19 @@ again: return PS_OK; } #endif // NSIS_CONFIG_PLUGIN_SUPPORT + +void CEXEBuild::init_res_editor() +{ + build_compressor_set=true; + if (!res_editor) + res_editor=new CResourceEditor(header_data_new, exeheader_size_new); +} + +void CEXEBuild::close_res_editor() +{ + if (!res_editor) return; + free(header_data_new); + header_data_new = res_editor->Save((DWORD&)exeheader_size_new); + delete res_editor; + res_editor=0; +} \ No newline at end of file diff --git a/Source/build.h b/Source/build.h index 520b3796..51c60c8c 100644 --- a/Source/build.h +++ b/Source/build.h @@ -8,6 +8,7 @@ using namespace std; #include "strlist.h" #include "lineparse.h" #include "lang.h" +#include "ResourceEditor.h" #include "exehead/fileform.h" #include "exehead/config.h" @@ -221,6 +222,10 @@ class CEXEBuild { #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT int deflateToFile(FILE *fp, char *buf, int len); // len==0 to flush #endif + + CResourceEditor *res_editor; + void init_res_editor(); + void close_res_editor(); }; #endif //_BUILD_H_ diff --git a/Source/script.cpp b/Source/script.cpp index ec8457c1..0aa847b3 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -724,14 +724,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char case TOK_ICON: SCRIPT_MSG("Icon: \"%s\"\n",line.gettoken_str(1)); try { - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); - if (replace_icon(&re, IDI_ICON2, line.gettoken_str(1))) { + init_res_editor(); + if (replace_icon(res_editor, IDI_ICON2, line.gettoken_str(1))) { ERROR_MSG("Error: File doesn't exist or is an invalid icon file\n"); return PS_ERROR; } - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); } catch (exception& err) { ERROR_MSG("Error while replacing icon: %s\n", err.what()); @@ -743,14 +740,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char case TOK_CHECKBITMAP: SCRIPT_MSG("CheckBitmap: \"%s\"\n",line.gettoken_str(1)); try { - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); - if (update_bitmap(&re, IDB_BITMAP1, line.gettoken_str(1), 96, 16)) { + init_res_editor(); + if (update_bitmap(res_editor, IDB_BITMAP1, line.gettoken_str(1), 96, 16)) { ERROR_MSG("Error: File doesn't exist, is an invalid bitmap, or has the wrong size\n"); return PS_ERROR; } - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); } catch (exception& err) { ERROR_MSG("Error while replacing bitmap: %s\n", err.what()); @@ -1014,11 +1008,10 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char if (!k) return make_sure_not_in_secorfunc(line.gettoken_str(0)); - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); + init_res_editor(); #define REMOVE_ICON(id) { \ - BYTE* dlg = re.GetResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); \ + BYTE* dlg = res_editor->GetResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); \ if (!dlg) throw runtime_error(#id " doesn't exist!"); \ CDialogTemplate dt(dlg); \ free(dlg); \ @@ -1041,7 +1034,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char \ DWORD dwSize; \ dlg = dt.Save(dwSize); \ - re.UpdateResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); \ + res_editor->UpdateResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); \ free(dlg); \ } @@ -1059,9 +1052,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #ifdef NSIS_CONFIG_CRC_SUPPORT REMOVE_ICON(IDD_VERIFY); #endif - - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); } catch (exception& err) { ERROR_MSG("Error removing window icon: %s\n", err.what()); @@ -1188,12 +1178,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char int k=line.gettoken_enum(1,"on\0off\0"); if (k == -1) PRINTHELP() SCRIPT_MSG("XPStyle: %s\n", line.gettoken_str(1)); - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); + init_res_editor(); char* szXPManifest = k ? 0 : "Nullsoft Install System v2.0b0"; - re.UpdateResource(MAKEINTRESOURCE(24), MAKEINTRESOURCE(1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (unsigned char*)szXPManifest, k ? 0 : lstrlen(szXPManifest)); - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); + res_editor->UpdateResource(MAKEINTRESOURCE(24), MAKEINTRESOURCE(1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (unsigned char*)szXPManifest, k ? 0 : lstrlen(szXPManifest)); } catch (exception& err) { ERROR_MSG("Error while adding XP style: %s\n", err.what()); @@ -1220,12 +1207,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char return PS_ERROR; } - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); + init_res_editor(); // Search for required items #define SEARCH(x) if (!UIDlg.GetItem(x)) {ERROR_MSG("Error: Can't find %s (%u) in the custom UI!\n", #x, x);return 0;} - #define SAVE(x) if (rtl) {UIDlg.ConvertToRTL(); dlg = UIDlg.Save(dwSize);} else dwSize = UIDlg.GetSize(); re.UpdateResource(RT_DIALOG, x, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); + #define SAVE(x) if (rtl) {UIDlg.ConvertToRTL(); dlg = UIDlg.Save(dwSize);} else dwSize = UIDlg.GetSize(); res_editor->UpdateResource(RT_DIALOG, x, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); BYTE* dlg = 0; @@ -1312,12 +1298,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char SEARCH(IDC_STR); // No RTL here, pure English goes here. //SAVE(IDD_VERIFY); - re.UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, UIDlg.GetSize()); + res_editor->UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, UIDlg.GetSize()); } - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); - if (!FreeLibrary(hUIFile)) { ERROR_MSG("can't free library!\n"); } @@ -1381,8 +1364,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char int wh=line.gettoken_int(2); if (k == -1) PRINTHELP() - CResourceEditor re(header_data_new, exeheader_size_new); - BYTE* dlg = re.GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); + init_res_editor(); + BYTE* dlg = res_editor->GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); CDialogTemplate dt(dlg); delete [] dlg; @@ -1419,13 +1402,10 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char DWORD dwDlgSize; dlg = dt.Save(dwDlgSize); - re.UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwDlgSize); + res_editor->UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwDlgSize); delete [] dlg; - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); - dt.DlgUnitsToPixels(brandingCtl.sWidth, brandingCtl.sHeight); SCRIPT_MSG("AddBrandingImage: %s %ux%u\n", line.gettoken_str(1), brandingCtl.sWidth, brandingCtl.sHeight); @@ -1445,18 +1425,17 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char case TOK_SETFONT: SCRIPT_MSG("SetFont: \"%s\" %s\n", line.gettoken_str(1), line.gettoken_str(2)); try { - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); + init_res_editor(); #define SET_FONT(id) { \ - BYTE* dlg = re.GetResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); \ + BYTE* dlg = res_editor->GetResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); \ if (!dlg) throw runtime_error(#id " doesn't exist!"); \ CDialogTemplate td(dlg); \ free(dlg); \ td.SetFont(line.gettoken_str(1), line.gettoken_int(2)); \ DWORD dwSize; \ dlg = td.Save(dwSize); \ - re.UpdateResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); \ + res_editor->UpdateResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); \ free(dlg); \ } @@ -1475,9 +1454,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #ifdef NSIS_CONFIG_CRC_SUPPORT SET_FONT(IDD_VERIFY); #endif - - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); } catch (exception& err) { ERROR_MSG("Error while changing font: %s\n", err.what()); @@ -1979,10 +1955,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char if (line.getnumtokens()!=a+1 && !trim) PRINTHELP(); if (line.getnumtokens()==a+1) SetString(line.gettoken_str(a),NLF_BRANDING,0,lang); if (trim) try { - build_compressor_set=true; - CResourceEditor re(header_data_new, exeheader_size_new); + init_res_editor(); - BYTE* dlg = re.GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); + BYTE* dlg = res_editor->GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); CDialogTemplate td(dlg); free(dlg); @@ -2003,11 +1978,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char DWORD dwSize; dlg = td.Save(dwSize); - re.UpdateResource(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); + res_editor->UpdateResource(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); free(dlg); - - free(header_data_new); - header_data_new = re.Save((DWORD&)exeheader_size_new); } catch (exception& err) { ERROR_MSG("Error while triming branding text control: %s\n", err.what()); @@ -3801,9 +3773,27 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char ERROR_MSG("Error: Plugin dll for command \"%s\" not found.\n",line.gettoken_str(0)); } return PS_ERROR; + case TOK_INITPLUGINDIR: + { + int ret; + SCRIPT_MSG("%s\n",line.gettoken_str(0)); + // Call [un.]Initialize_____Plugins + ent.which=EW_CALL; + ent.offsets[0]=ns_func.add(uninstall_mode?"un.Initialize_____Plugins":"Initialize_____Plugins",0); + ret=add_entry(&ent); + if (ret != PS_OK) return ret; + // SetDetailsPrint lastused + ent.which=EW_UPDATETEXT; + ent.offsets[0]=0; + ent.offsets[1]=8; // lastused + ret=add_entry(&ent); + if (ret != PS_OK) return ret; + } + return PS_OK; #else case TOK_PLUGINDIR: case TOK__PLUGINCOMMAND: + case TOK_INITPLUGINDIR: { ERROR_MSG("Error: %s specified, NSIS_CONFIG_PLUGIN_SUPPORT not defined.\n",line.gettoken_str(0)); } diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 58855778..1508003c 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -202,6 +202,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_GETCURRENTADDR,"GetCurrentAddress",1,0,"output"}, {TOK_PLUGINDIR,"PluginDir",1,0,"new_plugin_directory"}, +{TOK_INITPLUGINDIR,"InitPluginDir",0,0,""} }; void CEXEBuild::print_help(char *commandname) diff --git a/Source/tokens.h b/Source/tokens.h index dc2609ea..04f3960b 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -196,6 +196,7 @@ enum TOK_SECTIONGETFLAGS, TOK_SETSHELLVARCONTEXT, TOK_PLUGINDIR, + TOK_INITPLUGINDIR, TOK_CREATEFONT, TOK__LAST,