refactoring:

- added CEXEBuild::update_exehead() and made everyone use it
 - renamed some variables (of the *exeheader* variety)
bug fix:
 - uninstaller CRC-check failed if !packhdr created a non-512-bytes-aligned exehead


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3695 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2004-10-02 18:04:41 +00:00
parent 60aa307741
commit ba8a64a806
12 changed files with 132 additions and 131 deletions

View file

@ -8,6 +8,10 @@
#include "build.h"
#include "util.h"
#include <stdexcept>
using namespace std;
#include "exehead/resource.h"
#include "ResourceEditor.h"
#include "DialogTemplate.h"
@ -61,8 +65,9 @@ void CEXEBuild::define(const char *p, const char *v)
CEXEBuild::~CEXEBuild()
{
free(header_data_new);
free(m_unicon_data);
delete [] m_exehead;
int nlt = lang_tables.getlen() / sizeof(LanguageTable);
LanguageTable *nla = (LanguageTable*)lang_tables.get();
@ -72,7 +77,9 @@ CEXEBuild::~CEXEBuild()
}
}
CEXEBuild::CEXEBuild()
CEXEBuild::CEXEBuild() :
m_exehead(0),
m_exehead_size(0)
{
linecnt = 0;
fp = 0;
@ -95,18 +102,8 @@ CEXEBuild::CEXEBuild()
ns_func.add("",0); // make sure offset 0 is special on these (i.e. never used by a label)
ns_label.add("",0);
header_data_new=(unsigned char*)malloc(zlib_exeheader_size);
exeheader_size_new=zlib_exeheader_size;
exeheader_size=zlib_exeheader_size;
if (!header_data_new)
{
ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",exeheader_size_new);
extern void quit(); quit();
}
// Changed by Amir Szekely 31st July 2002
memcpy(header_data_new,zlib_header_data,zlib_exeheader_size);
exeheader_size = zlib_exehead_size;
update_exehead(zlib_exehead, zlib_exehead_size);
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
// Changed by Amir Szekely 11th July 2002
@ -2318,7 +2315,7 @@ int CEXEBuild::pack_exe_header()
return PS_OK;
}
// write out exe header, pack, read back in, align to 512, and
// write out exe header, pack, read back in, and
// update the header info
FILE *tmpfile=FOPEN(build_packname,"wb");
if (!tmpfile)
@ -2326,7 +2323,7 @@ int CEXEBuild::pack_exe_header()
ERROR_MSG("Error: writing temporary file \"%s\" for pack\n",build_packname);
return PS_ERROR;
}
fwrite(header_data_new,1,exeheader_size_new,tmpfile);
fwrite(m_exehead,1,m_exehead_size,tmpfile);
fclose(tmpfile);
if (system(build_packcmd) == -1)
{
@ -2341,21 +2338,22 @@ int CEXEBuild::pack_exe_header()
ERROR_MSG("Error: reading temporary file \"%s\" after pack\n",build_packname);
return PS_ERROR;
}
// read header from file
fseek(tmpfile,0,SEEK_END);
exeheader_size_new=ftell(tmpfile);
size_t exehead_size = ftell(tmpfile);
unsigned char *exehead = new unsigned char[exehead_size];
fseek(tmpfile,0,SEEK_SET);
unsigned char *header_data_older=header_data_new;
header_data_new=(unsigned char *)malloc(exeheader_size_new);
if (!header_data_new)
{
free(header_data_older);
fclose(tmpfile);
ERROR_MSG("Error: malloc(%d) failed (exepack)\n",exeheader_size_new);
return PS_ERROR;
}
memset(header_data_new,0,exeheader_size_new);
fread(header_data_new,1,exeheader_size_new,tmpfile);
fread(exehead,1,exehead_size,tmpfile);
fclose(tmpfile);
update_exehead(exehead, exehead_size);
// cleanup
// TODO: use resource-controlling classes (e.g. Boost)
delete [] exehead;
remove(build_packname);
return PS_OK;
@ -2440,40 +2438,21 @@ int CEXEBuild::write_output(void)
return PS_ERROR;
}
if ((int)fwrite(header_data_new,1,exeheader_size_new,fp) != exeheader_size_new)
if (fwrite(m_exehead,1,m_exehead_size,fp) != m_exehead_size)
{
ERROR_MSG("Error: can't write %d bytes to output\n",exeheader_size_new);
ERROR_MSG("Error: can't write %d bytes to output\n",m_exehead_size);
fclose(fp);
return PS_ERROR;
}
#ifdef NSIS_CONFIG_CRC_SUPPORT
#ifdef NSIS_CONFIG_CRC_ANAL
crc=CRC32(crc,header_data_new,exeheader_size_new);
crc=CRC32(crc,m_exehead,m_exehead_size);
#else
crc=CRC32(crc,header_data_new+512,exeheader_size_new-512);
crc=CRC32(crc,m_exehead+512,m_exehead_size-512);
#endif
#endif
int exeheader_size_new_aligned = (exeheader_size_new + 511) & ~511;
if (exeheader_size_new_aligned != exeheader_size_new) {
// align to 512
const unsigned char z = 0;
int write_size = exeheader_size_new_aligned - exeheader_size_new;
for (int i=0; i<write_size; i++) {
if ((int)fwrite(&z,1,1,fp) != 1)
{
ERROR_MSG("Error: can't write %d bytes to output\n",write_size);
fclose(fp);
return PS_ERROR;
}
#ifdef NSIS_CONFIG_CRC_SUPPORT
crc=CRC32(crc,&z,1);
#endif
}
exeheader_size_new = exeheader_size_new_aligned;
}
firstheader fh={0,};
fh.nsinst[0]=FH_INT1;
fh.nsinst[1]=FH_INT2;
@ -2620,7 +2599,7 @@ int CEXEBuild::write_output(void)
if (db_opt_save)
{
int total_out_size_estimate=
exeheader_size_new+sizeof(fh)+build_datablock.getlen()+(build_crcchk?sizeof(int):0);
m_exehead_size+sizeof(fh)+build_datablock.getlen()+(build_crcchk?sizeof(int):0);
#ifdef _WIN32
int pc=MulDiv(db_opt_save,1000,db_opt_save+total_out_size_estimate);
#else
@ -2636,7 +2615,7 @@ int CEXEBuild::write_output(void)
int total_usize=exeheader_size;
INFO_MSG("EXE header size: %10d / %d bytes\n",exeheader_size_new,exeheader_size);
INFO_MSG("EXE header size: %10d / %d bytes\n",m_exehead_size,exeheader_size);
if (build_compress_whole) {
INFO_MSG("Install code: (%d bytes)\n",
@ -2849,7 +2828,8 @@ int CEXEBuild::uninstall_generate()
// Get offsets of icons to replace for uninstall
// Also makes sure that the icons are there and in the right size.
icon_offset = generate_unicons_offsets(header_data_new, m_unicon_data);
// TODO: fix generate_unicons_offsets to check ranges (!)
icon_offset = generate_unicons_offsets(m_exehead, m_unicon_data);
if (icon_offset == 0)
return PS_ERROR;
@ -2874,14 +2854,15 @@ int CEXEBuild::uninstall_generate()
if (add_db_data((char *)m_unicon_data,unicondata_size) < 0)
return PS_ERROR;
#ifdef NSIS_CONFIG_CRC_SUPPORT
{
// "create" the uninstaller
LPBYTE uninst_header = (LPBYTE) malloc(exeheader_size_new);
LPBYTE uninst_header = (LPBYTE) malloc(m_exehead_size);
if (!uninst_header)
return PS_ERROR;
memcpy(uninst_header, header_data_new, exeheader_size_new);
memcpy(uninst_header, m_exehead, m_exehead_size);
// patch the icons
LPBYTE seeker = m_unicon_data;
@ -2895,9 +2876,9 @@ int CEXEBuild::uninstall_generate()
}
#ifdef NSIS_CONFIG_CRC_ANAL
crc=CRC32(crc, uninst_header, exeheader_size_new);
crc=CRC32(crc, uninst_header, m_exehead_size);
#else
crc=CRC32(crc, uninst_header + 512, exeheader_size_new - 512);
crc=CRC32(crc, uninst_header + 512, m_exehead_size - 512);
#endif
free(uninst_header);
@ -3323,21 +3304,27 @@ void CEXEBuild::init_res_editor()
{
build_compressor_set = true;
if (!res_editor)
res_editor = new CResourceEditor(header_data_new, exeheader_size_new);
res_editor = new CResourceEditor(m_exehead, m_exehead_size);
}
void CEXEBuild::close_res_editor()
{
if (!res_editor) return;
DWORD newsize;
// query size
// get size
newsize = res_editor->Save(NULL, newsize);
unsigned char *new_header = (unsigned char *) malloc(newsize);
unsigned char *new_header = new unsigned char[newsize];
// save
res_editor->Save(new_header, newsize);
free(header_data_new);
header_data_new = new_header;
exeheader_size_new = (int) newsize;
int rc = res_editor->Save(new_header, newsize);
assert(rc == 0);
update_exehead(new_header, newsize);
// TODO: resource-controlling class
delete [] new_header;
delete res_editor;
res_editor=0;
}
@ -3425,3 +3412,19 @@ void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList)
}
}
}
void CEXEBuild::update_exehead(const unsigned char *new_exehead, size_t new_size) {
assert(m_exehead != new_exehead);
// align exehead to 512
m_exehead_size = align_to_512(new_size);
delete [] m_exehead;
m_exehead = new unsigned char[m_exehead_size];
// copy exehead
memcpy(m_exehead, new_exehead, new_size);
// zero rest of exehead
memset(m_exehead + new_size, 0, m_exehead_size - new_size);
}

View file

@ -1,10 +1,6 @@
#ifndef _BUILD_H_
#define _BUILD_H_
#include <stdexcept>
using namespace std;
#include "strlist.h"
#include "lineparse.h"
#include "lang.h"
@ -117,6 +113,8 @@ class CEXEBuild {
int prepare_uninstaller();
int pack_exe_header();
void update_exehead(const unsigned char *new_exehead, size_t new_size);
// tokens.cpp
int get_commandtoken(char *s, int *np, int *op, int *pos);
int IsTokenPlacedRight(int pos, char *tok);
@ -350,8 +348,9 @@ class CEXEBuild {
TinyGrowBuf verbose_stack;
unsigned char *header_data_new;
int exeheader_size_new;
unsigned char *m_exehead;
size_t m_exehead_size;
int icon_offset;
bool branding_image_found;
WORD branding_image_id;

View file

@ -20,10 +20,11 @@
#include "exehead/Debug-lzma/exehead_lzma.h"
#endif*/
int zlib_exeheader_size=sizeof(zlib_header_data);
int bzip2_exeheader_size=sizeof(bzip2_header_data);
int lzma_exeheader_size=sizeof(lzma_header_data);
int exeheader_size=0;
size_t zlib_exehead_size=sizeof(zlib_exehead);
size_t bzip2_exehead_size=sizeof(bzip2_exehead);
size_t lzma_exehead_size=sizeof(lzma_exehead);
// TODO: rename to exehead_original_size
size_t exeheader_size=0;
int icondata_size=sizeof(icon_data)-22;
int unicondata_size=sizeof(unicon_data)-22;
size_t icondata_size=sizeof(icon_data)-22;
size_t unicondata_size=sizeof(unicon_data)-22;

View file

@ -1,16 +1,19 @@
#ifndef _EXEDATA_H_
#define _EXEDATA_H_
extern int zlib_exeheader_size;
extern int bzip2_exeheader_size;
extern int lzma_exeheader_size;
extern int exeheader_size;
extern int icondata_size;
extern int unicondata_size;
#include <cstddef>
extern unsigned char zlib_header_data[];
extern unsigned char bzip2_header_data[];
extern unsigned char lzma_header_data[];
// TODO: these should live in a singleton
extern size_t zlib_exehead_size;
extern size_t bzip2_exehead_size;
extern size_t lzma_exehead_size;
extern size_t exeheader_size;
extern size_t icondata_size;
extern size_t unicondata_size;
extern unsigned char zlib_exehead[];
extern unsigned char bzip2_exehead[];
extern unsigned char lzma_exehead[];
extern unsigned char icon_data[];
extern unsigned char unicon_data[];
extern unsigned char bitmap1_data[630];

View file

@ -73,7 +73,7 @@ Release-zlib/exehead_zlib.exe : $(ZLIB_OBJS) sections_script
ifneq ($(USE_PRECOMPILED_EXEHEADS),1)
Release-zlib/exehead_zlib.h : Release-zlib/exehead_zlib.exe $(BIN2H)
$(BIN2H) $< $@ zlib_header_data
$(BIN2H) $< $@ zlib_exehead
endif
Release-zlib/%.o : %.c
@ -92,7 +92,7 @@ Release-bzip2/exehead_bzip2.exe : $(BZIP2_OBJS) sections_script
ifneq ($(USE_PRECOMPILED_EXEHEADS),1)
Release-bzip2/exehead_bzip2.h : Release-bzip2/exehead_bzip2.exe $(BIN2H)
$(BIN2H) $< $@ bzip2_header_data
$(BIN2H) $< $@ bzip2_exehead
endif
Release-bzip2/%.o : %.c
@ -108,7 +108,7 @@ Release-lzma/exehead_lzma.exe : $(LZMA_OBJS) sections_script
ifneq ($(USE_PRECOMPILED_EXEHEADS),1)
Release-lzma/exehead_lzma.h : Release-lzma/exehead_lzma.exe $(BIN2H)
$(BIN2H) $< $@ lzma_header_data
$(BIN2H) $< $@ lzma_exehead
endif
Release-lzma/%.o : %.c

View file

@ -54,7 +54,7 @@ LINK32=link.exe
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=generating include file for makenssi
PostBuild_Cmds=bin2h Release-bzip2\exehead_bzip2.exe Release-bzip2\exehead_bzip2.h bzip2_header_data
PostBuild_Cmds=bin2h Release-bzip2\exehead_bzip2.exe Release-bzip2\exehead_bzip2.h bzip2_exehead
# End Special Build Tool
# Begin Target

View file

@ -54,7 +54,7 @@ LINK32=link.exe
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=generating include file for makenssi
PostBuild_Cmds=bin2h Release-lzma\exehead_lzma.exe Release-lzma\exehead_lzma.h lzma_header_data
PostBuild_Cmds=bin2h Release-lzma\exehead_lzma.exe Release-lzma\exehead_lzma.h lzma_exehead
# End Special Build Tool
# Begin Target

View file

@ -54,7 +54,7 @@ LINK32=link.exe
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=generating include file for makenssi
PostBuild_Cmds=bin2h Release-zlib\exehead_zlib.exe Release-zlib\exehead_zlib.h zlib_header_data bin2h bitmap1.bmp Release-zlib\bitmap1.h bitmap1_data bin2h nsis.ico Release-zlib\icon.h icon_data bin2h uninst.ico Release-zlib\unicon.h unicon_data
PostBuild_Cmds=bin2h Release-zlib\exehead_zlib.exe Release-zlib\exehead_zlib.h zlib_exehead bin2h bitmap1.bmp Release-zlib\bitmap1.h bitmap1_data bin2h nsis.ico Release-zlib\icon.h icon_data bin2h uninst.ico Release-zlib\unicon.h unicon_data
# End Special Build Tool
# Begin Target

View file

@ -235,9 +235,9 @@ int main(int argc, char **argv)
{
if (build.display_info)
{
fprintf(g_output,"Size of zlib EXE header is %d bytes.\n",zlib_exeheader_size);
fprintf(g_output,"Size of bzip2 EXE header is %d bytes.\n",bzip2_exeheader_size);
fprintf(g_output,"Size of lzma EXE header is %d bytes.\n",lzma_exeheader_size);
fprintf(g_output,"Size of zlib EXE header is %d bytes.\n",zlib_exehead_size);
fprintf(g_output,"Size of bzip2 EXE header is %d bytes.\n",bzip2_exehead_size);
fprintf(g_output,"Size of lzma EXE header is %d bytes.\n",lzma_exehead_size);
fprintf(g_output,"Size of first header is %d bytes.\n",sizeof(firstheader));
fprintf(g_output,"Size of main header is %d bytes.\n",sizeof(header));
fprintf(g_output,"Size of each section is %d bytes.\n",sizeof(section));

View file

@ -205,6 +205,10 @@ SOURCE=.\exedata.cpp
# End Source File
# Begin Source File
SOURCE=.\growbuf.cpp
# End Source File
# Begin Source File
SOURCE=.\lang.cpp
# End Source File
# Begin Source File
@ -214,6 +218,10 @@ SOURCE=.\makenssi.cpp
# End Source File
# Begin Source File
SOURCE=.\mmap.cpp
# End Source File
# Begin Source File
SOURCE=.\Plugins.cpp
# End Source File
# Begin Source File
@ -232,6 +240,10 @@ SOURCE=.\script.cpp
# End Source File
# Begin Source File
SOURCE=.\strlist.cpp
# End Source File
# Begin Source File
SOURCE=.\tokens.cpp
# End Source File
# Begin Source File
@ -273,6 +285,10 @@ SOURCE=.\exedata.h
# End Source File
# Begin Source File
SOURCE=.\growbuf.h
# End Source File
# Begin Source File
SOURCE=.\lang.h
# End Source File
# Begin Source File
@ -281,6 +297,10 @@ SOURCE=.\lineparse.h
# End Source File
# Begin Source File
SOURCE=.\mmap.h
# End Source File
# Begin Source File
SOURCE=.\Platform.h
# End Source File
# Begin Source File

View file

@ -2451,64 +2451,34 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
switch (k) {
case 0: // JF> should handle the state of going from bzip2 back to zlib:
compressor = &zlib_compressor;
free(header_data_new);
header_data_new=(unsigned char*)malloc(zlib_exeheader_size);
exeheader_size_new=zlib_exeheader_size;
exeheader_size=zlib_exeheader_size;
if (!header_data_new)
{
ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",exeheader_size_new);
extern void quit(); quit();
}
memcpy(header_data_new,zlib_header_data,zlib_exeheader_size);
update_exehead(zlib_exehead, zlib_exehead_size);
#ifdef NSIS_ZLIB_COMPRESS_WHOLE
build_compress_whole=true;
#else
build_compress_whole=false;
#endif
break;
case 1:
compressor=&bzip2_compressor;
free(header_data_new);
header_data_new=(unsigned char*)malloc(bzip2_exeheader_size);
exeheader_size_new=bzip2_exeheader_size;
exeheader_size=bzip2_exeheader_size;
if (!header_data_new)
{
ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",exeheader_size_new);
extern void quit(); quit();
}
memcpy(header_data_new,bzip2_header_data,bzip2_exeheader_size);
update_exehead(bzip2_exehead, bzip2_exehead_size);
#ifdef NSIS_BZIP2_COMPRESS_WHOLE
build_compress_whole=true;
#else
build_compress_whole=false;
#endif
break;
case 2:
compressor = &lzma_compressor;
free(header_data_new);
header_data_new=(unsigned char*)malloc(lzma_exeheader_size);
exeheader_size_new=lzma_exeheader_size;
exeheader_size=lzma_exeheader_size;
if (!header_data_new)
{
ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",exeheader_size_new);
extern void quit(); quit();
}
memcpy(header_data_new, lzma_header_data, lzma_exeheader_size);
update_exehead(lzma_exehead, lzma_exehead_size);
#ifdef NSIS_LZMA_COMPRESS_WHOLE
build_compress_whole=true;
#else
build_compress_whole=false;
#endif
break;
default:
PRINTHELP();
}

View file

@ -79,4 +79,9 @@ int my_glob(const char *pattern, int flags,
#define OPEN(a, b) open(a, b)
#endif
template <class T>
inline T align_to_512(const T x) {
return (x+511) & ~511;
}
#endif //_UTIL_H_