2004-01-30 22:04:10 +00:00
# include "Platform.h"
2002-08-02 10:01:35 +00:00
# include <stdio.h>
# include "exehead/config.h"
2006-02-24 19:14:18 +00:00
# include "version.h"
2002-08-02 10:01:35 +00:00
# include "build.h"
# include "util.h"
2006-03-11 11:21:04 +00:00
# include "fileform.h"
# include "writer.h"
2002-08-02 10:01:35 +00:00
2004-10-02 18:04:41 +00:00
# include <stdexcept>
2002-08-02 10:01:35 +00:00
# include "exehead/resource.h"
2003-09-06 09:59:02 +00:00
# include "ResourceEditor.h"
# include "DialogTemplate.h"
2003-06-09 18:59:14 +00:00
# include "ResourceVersionInfo.h"
2004-03-29 20:21:00 +00:00
# ifndef _WIN32
# include <locale.h>
# include <unistd.h>
# include <limits.h>
# include <stdlib.h>
2004-05-01 12:41:49 +00:00
# include <stdarg.h>
2004-03-29 20:21:00 +00:00
# endif
2002-08-02 10:01:35 +00:00
2004-10-02 15:17:00 +00:00
# include <cassert> // for assert
2004-09-30 20:25:33 +00:00
# define RET_UNLESS_OK( function_rc ) do { \
int rc = ( function_rc ) ; \
if ( rc ! = PS_OK ) \
return rc ; \
} while ( false )
2005-08-27 19:56:00 +00:00
using namespace std ;
2004-09-30 20:25:33 +00:00
namespace { // begin anonymous namespace
2003-06-12 00:06:23 +00:00
bool isSimpleChar ( char ch )
{
2003-06-17 23:59:13 +00:00
return ( ch = = ' . ' ) | | ( ch = = ' _ ' ) | | ( ch > = ' 0 ' & & ch < = ' 9 ' ) | | ( ch > = ' A ' & & ch < = ' Z ' ) | | ( ch > = ' a ' & & ch < = ' z ' ) ;
2003-06-12 00:06:23 +00:00
}
2004-09-30 20:25:33 +00:00
} // end of anonymous namespace
2002-08-31 23:44:58 +00:00
void CEXEBuild : : define ( const char * p , const char * v )
{
definedlist . add ( p , v ) ;
2002-08-02 10:01:35 +00:00
}
CEXEBuild : : ~ CEXEBuild ( )
{
free ( m_unicon_data ) ;
2004-10-02 18:04:41 +00:00
delete [ ] m_exehead ;
2005-10-16 05:37:13 +00:00
2003-09-04 18:25:57 +00:00
int nlt = lang_tables . getlen ( ) / sizeof ( LanguageTable ) ;
LanguageTable * nla = ( LanguageTable * ) lang_tables . get ( ) ;
for ( int i = 0 ; i < nlt ; i + + ) {
DeleteLangTable ( nla + i ) ;
}
2002-08-02 10:01:35 +00:00
}
2004-10-02 18:04:41 +00:00
CEXEBuild : : CEXEBuild ( ) :
m_exehead ( 0 ) ,
m_exehead_size ( 0 )
2002-08-02 10:01:35 +00:00
{
2003-06-05 21:55:40 +00:00
linecnt = 0 ;
fp = 0 ;
curfilename = 0 ;
2002-08-02 10:01:35 +00:00
display_info = 1 ;
display_script = 1 ;
display_errors = 1 ;
display_warnings = 1 ;
2003-09-04 18:25:57 +00:00
cur_ifblock = NULL ;
last_line_had_slash = 0 ;
inside_comment = false ;
2004-09-25 13:35:03 +00:00
multiple_entries_instruction = 0 ;
2003-09-04 18:25:57 +00:00
2003-09-05 22:05:53 +00:00
build_include_depth = 0 ;
2004-09-30 20:25:33 +00:00
has_called_write_output = false ;
2002-08-02 10:01:35 +00:00
ns_func . add ( " " , 0 ) ; // make sure offset 0 is special on these (i.e. never used by a label)
ns_label . add ( " " , 0 ) ;
2006-02-24 19:14:18 +00:00
definedlist . add ( " NSIS_VERSION " , NSIS_VERSION ) ;
2003-09-12 21:40:33 +00:00
2006-04-05 18:42:30 +00:00
// automatically generated header file containing all defines
# include "defines.h"
2003-12-22 00:28:30 +00:00
2006-04-05 18:42:30 +00:00
// no longer optional
definedlist . add ( " NSIS_SUPPORT_STANDARD_PREDEFINES " ) ;
definedlist . add ( " NSIS_SUPPORT_NAMED_USERVARS " ) ;
definedlist . add ( " NSIS_SUPPORT_LANG_IN_STRINGS " ) ;
2006-01-21 09:54:23 +00:00
2006-03-17 12:14:00 +00:00
# ifdef _WIN32
definedlist . add ( " NSIS_WIN32_MAKENSIS " ) ;
# endif
2002-08-02 10:01:35 +00:00
db_opt_save = db_comp_save = db_full_size = db_opt_save_u = db_comp_save_u = db_full_size_u = 0 ;
// Added by Amir Szekely 31st July 2002
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2002-08-21 16:23:29 +00:00
compressor = & zlib_compressor ;
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
build_compressor_set = false ;
2003-09-05 11:46:48 +00:00
build_compressor_final = false ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_ZLIB_COMPRESS_WHOLE
build_compress_whole = true ;
# else
build_compress_whole = false ;
# endif
2003-11-24 00:08:58 +00:00
build_compress = 1 ;
build_compress_level = 9 ;
build_compress_dict_size = 1 < < 23 ;
2002-08-02 10:01:35 +00:00
cur_entries = & build_entries ;
2004-09-25 13:35:03 +00:00
cur_instruction_entry_map = & build_instruction_entry_map ;
2002-08-02 10:01:35 +00:00
cur_datablock = & build_datablock ;
2004-09-25 10:09:53 +00:00
cur_datablock_cache = & build_datablock_cache ;
2002-08-02 10:01:35 +00:00
cur_functions = & build_functions ;
cur_labels = & build_labels ;
2003-09-04 18:25:57 +00:00
cur_sections = & build_sections ;
cur_header = & build_header ;
cur_strlist = & build_strlist ;
cur_langtables = & build_langtables ;
cur_ctlcolors = & build_ctlcolors ;
cur_pages = & build_pages ;
cur_page = 0 ;
cur_page_type = - 1 ;
2002-08-02 10:01:35 +00:00
2003-09-15 22:05:06 +00:00
build_filebuflen = 32 < < 20 ; // 32mb
2005-01-10 12:43:52 +00:00
sectiongroup_open_cnt = 0 ;
2002-08-02 10:01:35 +00:00
build_cursection_isfunc = 0 ;
build_cursection = NULL ;
// init public data.
build_packname [ 0 ] = build_packcmd [ 0 ] = build_output_filename [ 0 ] = 0 ;
2003-05-26 17:55:15 +00:00
// Added by ramon 23 May 2003
build_allowskipfiles = 1 ;
2003-06-09 18:59:14 +00:00
// Added by ramon 6 jun 2003
# ifdef NSIS_SUPPORT_VERSION_INFO
2003-06-10 04:35:09 +00:00
version_product_v [ 0 ] = 0 ;
2003-06-09 18:59:14 +00:00
# endif
2003-09-05 11:46:48 +00:00
build_overwrite = build_last_overwrite = 0 ;
2002-08-31 23:44:58 +00:00
build_crcchk = 1 ;
2002-08-02 10:01:35 +00:00
build_datesave = 1 ;
build_optimize_datablock = 1 ;
memset ( & build_header , - 1 , sizeof ( build_header ) ) ;
build_header . install_reg_rootkey = 0 ;
2003-09-04 18:25:57 +00:00
build_header . flags = CH_FLAGS_NO_ROOT_DIR ;
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
build_header . lb_bg = RGB ( 0 , 0 , 0 ) ;
build_header . lb_fg = RGB ( 0 , 255 , 0 ) ;
# endif
# ifdef NSIS_CONFIG_LICENSEPAGE
build_header . license_bg = - COLOR_BTNFACE ;
# endif
build_header . install_directory_ptr = 0 ;
build_header . install_directory_auto_append = 0 ;
build_header . install_reg_key_ptr = 0 ;
build_header . install_reg_value_ptr = 0 ;
# ifdef NSIS_CONFIG_COMPONENTPAGE
memset ( build_header . install_types , 0 , sizeof ( build_header . install_types ) ) ;
# endif
memset ( & build_header . blocks , 0 , sizeof ( build_header . blocks ) ) ;
2002-08-02 10:01:35 +00:00
uninstall_mode = 0 ;
uninstall_size_full = 0 ;
uninstall_size = - 1 ;
memset ( & build_uninst , - 1 , sizeof ( build_uninst ) ) ;
2003-09-04 18:25:57 +00:00
build_header . install_reg_rootkey = 0 ;
build_uninst . flags = 0 ;
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
build_uninst . lb_bg = RGB ( 0 , 0 , 0 ) ;
build_uninst . lb_fg = RGB ( 0 , 255 , 0 ) ;
# endif
# ifdef NSIS_CONFIG_LICENSEPAGE
build_uninst . license_bg = - COLOR_BTNFACE ;
# endif
build_uninst . install_directory_ptr = 0 ;
build_uninst . install_directory_auto_append = 0 ;
build_uninst . install_reg_key_ptr = 0 ;
build_uninst . install_reg_value_ptr = 0 ;
# ifdef NSIS_CONFIG_COMPONENTPAGE
memset ( build_uninst . install_types , 0 , sizeof ( build_uninst . install_types ) ) ;
# endif
memset ( & build_uninst . blocks , 0 , sizeof ( build_uninst . blocks ) ) ;
2002-08-02 10:01:35 +00:00
uninstaller_writes_used = 0 ;
2002-09-29 20:25:15 +00:00
build_strlist . add ( " " , 0 ) ;
ubuild_strlist . add ( " " , 0 ) ;
2003-09-04 18:25:57 +00:00
build_langstring_num = 0 ;
ubuild_langstring_num = 0 ;
2004-03-12 20:43:54 +00:00
build_font [ 0 ] = 0 ;
2003-09-06 09:59:02 +00:00
build_font_size = 0 ;
2005-04-02 12:04:07 +00:00
m_unicon_data = NULL ;
m_unicon_size = 0 ;
2002-08-02 10:01:35 +00:00
2003-03-26 17:47:46 +00:00
branding_image_found = false ;
2002-08-31 23:44:58 +00:00
2002-08-03 23:06:10 +00:00
no_space_texts = false ;
2002-08-21 16:23:29 +00:00
2002-11-01 20:34:55 +00:00
# ifdef NSIS_CONFIG_PLUGIN_SUPPORT
2002-10-04 22:54:49 +00:00
build_plugin_unload = 0 ;
2003-11-30 18:00:39 +00:00
plugins_processed = 0 ;
2002-11-01 20:34:55 +00:00
# endif
2002-10-04 22:54:49 +00:00
2004-03-29 20:21:00 +00:00
last_used_lang = NSIS_DEFAULT_LANG ;
2002-11-01 20:34:55 +00:00
2002-11-09 13:51:40 +00:00
res_editor = 0 ;
2002-11-11 17:30:55 +00:00
2003-03-06 21:24:19 +00:00
enable_last_page_cancel = 0 ;
uenable_last_page_cancel = 0 ;
2002-12-24 20:35:26 +00:00
2003-09-04 18:25:57 +00:00
license_res_id = IDD_LICENSE ;
2003-03-26 17:47:46 +00:00
2003-09-06 09:59:02 +00:00
disable_window_icon = 0 ;
2004-03-29 20:21:00 +00:00
# ifdef _WIN32
2002-12-24 20:35:26 +00:00
notify_hwnd = 0 ;
2004-03-29 20:21:00 +00:00
# endif
2003-04-21 13:32:34 +00:00
2004-06-12 15:34:34 +00:00
# ifdef NSIS_SUPPORT_BGBG
2004-06-11 15:33:00 +00:00
bg_default_font . lfHeight = 40 ;
bg_default_font . lfWidth = 0 ;
bg_default_font . lfEscapement = 0 ;
bg_default_font . lfOrientation = 0 ;
bg_default_font . lfWeight = FW_BOLD ;
bg_default_font . lfItalic = TRUE ;
bg_default_font . lfUnderline = FALSE ;
bg_default_font . lfStrikeOut = FALSE ;
bg_default_font . lfCharSet = DEFAULT_CHARSET ;
bg_default_font . lfOutPrecision = OUT_DEFAULT_PRECIS ;
bg_default_font . lfClipPrecision = CLIP_DEFAULT_PRECIS ;
bg_default_font . lfQuality = DEFAULT_QUALITY ;
bg_default_font . lfPitchAndFamily = DEFAULT_PITCH ;
strncpy ( bg_default_font . lfFaceName , " Times New Roman " , LF_FACESIZE ) ;
memcpy ( & bg_font , & bg_default_font , sizeof ( LOGFONT ) ) ;
2004-06-12 15:34:34 +00:00
# endif
2004-06-11 15:33:00 +00:00
2003-09-04 18:25:57 +00:00
defcodepage_set = false ;
2003-04-21 13:32:34 +00:00
uDefCodePage = CP_ACP ;
2003-05-24 13:50:24 +00:00
2003-09-04 18:25:57 +00:00
InitLangTables ( ) ;
2003-06-12 00:06:23 +00:00
2003-12-22 00:28:30 +00:00
// Register static user variables $0, $1 and so on
2003-06-23 22:40:11 +00:00
// with ONE of reference count, to avoid warning on this vars
2003-06-12 00:06:23 +00:00
char Aux [ 3 ] ;
2004-03-12 20:43:54 +00:00
int i ;
for ( i = 0 ; i < 10 ; i + + ) // 0 - 9
2003-06-12 00:06:23 +00:00
{
2005-10-16 05:37:13 +00:00
sprintf ( Aux , " %d " , i ) ;
2003-06-23 22:40:11 +00:00
m_UserVarNames . add ( Aux , 1 ) ;
2003-06-12 00:06:23 +00:00
}
2004-03-12 20:43:54 +00:00
for ( i = 0 ; i < 10 ; i + + ) // 10 - 19
2003-06-12 00:06:23 +00:00
{
2005-10-16 05:37:13 +00:00
sprintf ( Aux , " R%d " , i ) ;
2003-06-23 22:40:11 +00:00
m_UserVarNames . add ( Aux , 1 ) ;
}
m_UserVarNames . add ( " CMDLINE " , 1 ) ; // 20 everything before here doesn't have trailing slash removal
m_UserVarNames . add ( " INSTDIR " , 1 ) ; // 21
m_UserVarNames . add ( " OUTDIR " , 1 ) ; // 22
m_UserVarNames . add ( " EXEDIR " , 1 ) ; // 23
m_UserVarNames . add ( " LANGUAGE " , 1 ) ; // 24
2003-09-04 18:25:57 +00:00
m_UserVarNames . add ( " TEMP " , - 1 ) ; // 25
2003-12-22 18:50:47 +00:00
m_UserVarNames . add ( " PLUGINSDIR " , - 1 ) ; // 26
m_UserVarNames . add ( " HWNDPARENT " , - 1 ) ; // 27
m_UserVarNames . add ( " _CLICK " , - 1 ) ; // 28
2005-01-05 13:40:42 +00:00
m_UserVarNames . add ( " _OUTDIR " , 1 ) ; // 29
2003-12-22 18:50:47 +00:00
2004-01-04 17:05:03 +00:00
m_iBaseVarsNum = m_UserVarNames . getnum ( ) ;
2003-12-22 18:50:47 +00:00
m_ShellConstants . add ( " WINDIR " , CSIDL_WINDOWS , CSIDL_WINDOWS ) ;
m_ShellConstants . add ( " SYSDIR " , CSIDL_SYSTEM , CSIDL_SYSTEM ) ;
m_ShellConstants . add ( " PROGRAMFILES " , CSIDL_PROGRAM_FILES , CSIDL_PROGRAM_FILES ) ;
m_ShellConstants . add ( " SMPROGRAMS " , CSIDL_PROGRAMS , CSIDL_COMMON_PROGRAMS ) ;
m_ShellConstants . add ( " SMSTARTUP " , CSIDL_STARTUP , CSIDL_COMMON_STARTUP ) ;
2003-12-22 00:28:30 +00:00
m_ShellConstants . add ( " DESKTOP " , CSIDL_DESKTOPDIRECTORY , CSIDL_COMMON_DESKTOPDIRECTORY ) ;
2003-12-22 18:50:47 +00:00
m_ShellConstants . add ( " STARTMENU " , CSIDL_STARTMENU , CSIDL_COMMON_STARTMENU ) ;
m_ShellConstants . add ( " QUICKLAUNCH " , CSIDL_APPDATA , CSIDL_PRINTERS ) ;
m_ShellConstants . add ( " COMMONFILES " , CSIDL_PROGRAM_FILES_COMMON , CSIDL_PROGRAM_FILES_COMMON ) ;
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 ) ;
2005-05-07 05:33:55 +00:00
m_ShellConstants . add ( " LOCALAPPDATA " , CSIDL_LOCAL_APPDATA , CSIDL_LOCAL_APPDATA ) ;
2003-12-22 18:50:47 +00:00
m_ShellConstants . add ( " PRINTHOOD " , CSIDL_PRINTHOOD , CSIDL_PRINTHOOD ) ;
//m_ShellConstants.add("ALTSTARTUP", CSIDL_ALTSTARTUP, CSIDL_COMMON_ALTSTARTUP);
2003-12-22 00:28:30 +00:00
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 ) ;
2002-08-02 10:01:35 +00:00
}
2005-04-02 12:04:07 +00:00
void CEXEBuild : : initialize ( const char * makensis_path )
2004-09-30 20:25:33 +00:00
{
2006-01-21 09:54:23 +00:00
string nsis_dir ;
const char * dir = getenv ( " NSISDIR " ) ;
if ( dir ) nsis_dir = dir ;
else {
# ifndef NSIS_CONFIG_CONST_DATA_PATH
nsis_dir = get_executable_dir ( makensis_path ) ;
# else
2006-02-24 19:19:49 +00:00
nsis_dir = PREFIX_DATA ;
2006-01-21 09:54:23 +00:00
# endif
}
definedlist . add ( " NSISDIR " , nsis_dir . c_str ( ) ) ;
2004-09-30 20:25:33 +00:00
2005-04-02 12:04:07 +00:00
string includes_dir = nsis_dir ;
2006-01-21 09:54:23 +00:00
includes_dir + = PLATFORM_PATH_SEPARATOR_STR " Include " ;
2005-04-02 12:04:07 +00:00
include_dirs . add ( includes_dir . c_str ( ) , 0 ) ;
stubs_dir = nsis_dir ;
2006-01-21 09:54:23 +00:00
stubs_dir + = PLATFORM_PATH_SEPARATOR_STR " Stubs " ;
2005-04-02 12:04:07 +00:00
if ( set_compressor ( " zlib " , false ) ! = PS_OK )
{
throw runtime_error ( " error setting default stub " ) ;
}
string uninst = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + " uninst " ;
m_unicon_data = generate_uninstall_icon_data ( uninst . c_str ( ) , m_unicon_size ) ;
if ( ! m_unicon_data )
{
throw runtime_error ( " invalid default uninstall icon " ) ;
}
2004-03-29 20:21:00 +00:00
}
2002-08-02 10:01:35 +00:00
int CEXEBuild : : getcurdbsize ( ) { return cur_datablock - > getlen ( ) ; }
2003-11-25 05:55:18 +00:00
// returns offset in stringblock
int CEXEBuild : : add_string ( const char * string , int process /*=1*/ , WORD codepage /*=CP_ACP*/ )
2002-08-02 10:01:35 +00:00
{
2003-09-12 11:16:33 +00:00
if ( ! string | | ! * string ) return 0 ;
2003-09-04 18:25:57 +00:00
2003-09-05 14:55:50 +00:00
if ( * string = = ' $ ' & & * ( string + 1 ) = = ' ( ' ) {
2003-09-04 18:25:57 +00:00
int idx = 0 ;
char * cp = strdup ( string + 2 ) ;
char * p = strchr ( cp , ' ) ' ) ;
if ( p & & p [ 1 ] = = ' \0 ' ) { // if string is only a language str identifier
* p = 0 ;
idx = DefineLangString ( cp , process ) ;
}
free ( cp ) ;
if ( idx < 0 ) return idx ;
}
if ( ! process ) return cur_strlist - > add ( string , 2 ) ;
2004-05-07 11:16:18 +00:00
char buf [ NSIS_MAX_STRLEN * 4 ] ;
2003-11-25 05:55:18 +00:00
preprocess_string ( buf , string , codepage ) ;
2003-09-04 18:25:57 +00:00
return cur_strlist - > add ( buf , 2 ) ;
2002-08-02 10:01:35 +00:00
}
2003-05-24 13:50:24 +00:00
int CEXEBuild : : add_intstring ( const int i ) // returns offset in stringblock
{
2004-03-29 20:21:00 +00:00
char i_str [ 128 ] ;
# ifdef _WIN32
2003-05-24 13:50:24 +00:00
wsprintf ( i_str , " %d " , i ) ;
2004-03-29 20:21:00 +00:00
# else
snprintf ( i_str , 128 , " %d " , i ) ;
# endif
2003-05-24 13:50:24 +00:00
return add_string ( i_str ) ;
}
2002-08-02 10:01:35 +00:00
// based on Dave Laundon's code
2003-11-25 05:55:18 +00:00
int CEXEBuild : : preprocess_string ( char * out , const char * in , WORD codepage /*=CP_ACP*/ )
2002-08-02 10:01:35 +00:00
{
const char * p = in ;
2002-08-31 23:44:58 +00:00
while ( * p )
2002-08-02 10:01:35 +00:00
{
2004-03-29 20:21:00 +00:00
const char * np ;
# ifdef _WIN32
np = CharNextExA ( codepage , p , 0 ) ;
# else
2002-08-02 10:01:35 +00:00
{
2004-03-29 20:21:00 +00:00
char buf [ 1024 ] ;
snprintf ( buf , 1024 , " CP%d " , codepage ) ;
setlocale ( LC_CTYPE , buf ) ;
int len = mblen ( p , strlen ( p ) ) ;
if ( len > 0 )
np = p + len ;
else
np = p + 1 ;
setlocale ( LC_CTYPE , " " ) ;
}
# endif
if ( np - p > 1 ) // multibyte char
{
int l = np - p ;
2002-08-02 10:01:35 +00:00
while ( l - - )
{
int i = ( unsigned char ) * p + + ;
2004-01-04 17:05:03 +00:00
if ( i > = NS_CODES_START ) {
* out + + = ( char ) NS_SKIP_CODE ;
2002-08-02 10:01:35 +00:00
}
* out + + = i ;
}
continue ;
}
2004-03-29 20:21:00 +00:00
2002-08-02 10:01:35 +00:00
int i = ( unsigned char ) * p ;
2004-03-29 20:21:00 +00:00
2002-08-02 10:01:35 +00:00
p = np ;
2005-10-16 05:37:13 +00:00
2002-08-02 10:01:35 +00:00
// Test for characters extending into the variable codes
2004-01-04 17:05:03 +00:00
if ( i > = NS_CODES_START ) {
* out + + = ( char ) NS_SKIP_CODE ;
2002-08-02 10:01:35 +00:00
}
2002-08-31 23:44:58 +00:00
else if ( i = = ' $ ' )
2002-08-02 10:01:35 +00:00
{
2002-08-31 23:44:58 +00:00
if ( * p = = ' $ ' )
2002-08-02 10:01:35 +00:00
p + + ; // Can simply convert $$ to $ now
2002-08-31 23:44:58 +00:00
else
2002-08-02 10:01:35 +00:00
{
{
2003-06-09 18:59:14 +00:00
bool bProceced = false ;
2003-06-12 00:06:23 +00:00
if ( * p )
2003-06-09 18:59:14 +00:00
{
2003-06-12 00:06:23 +00:00
const char * pUserVarName = p ;
2003-12-22 18:50:47 +00:00
while ( isSimpleChar ( * pUserVarName ) )
2003-06-12 00:06:23 +00:00
pUserVarName + + ;
2003-12-22 18:50:47 +00:00
while ( pUserVarName > p )
2003-06-09 18:59:14 +00:00
{
2003-12-22 18:50:47 +00:00
if ( m_ShellConstants . get ( ( char * ) p , pUserVarName - p ) > = 0 )
break ; // Upps it's a shell constant
int idxUserVar = m_UserVarNames . get ( ( char * ) p , pUserVarName - p ) ;
if ( idxUserVar > = 0 )
{
2005-10-16 05:37:13 +00:00
// Well, using variables inside string formating doens't mean
2003-12-22 18:50:47 +00:00
// using the variable, beacuse it will be always an empty string
// which is also memory wasting
// So the line below must be commented !??
//m_UserVarNames.inc_reference(idxUserVar);
2004-01-04 17:05:03 +00:00
* out + + = ( unsigned int ) NS_VAR_CODE ; // Named user variable;
2006-03-11 11:22:02 +00:00
* ( WORD * ) out = FIX_ENDIAN_INT16 ( CODE_SHORT ( idxUserVar ) ) ;
2003-12-22 18:50:47 +00:00
out + = sizeof ( WORD ) ;
p + = pUserVarName - p ;
bProceced = true ;
break ;
}
pUserVarName - - ;
2003-06-09 18:59:14 +00:00
}
}
2003-12-22 18:50:47 +00:00
if ( ! bProceced & & * p )
2003-12-22 00:28:30 +00:00
{
const char * pShellConstName = p ;
2003-12-22 18:50:47 +00:00
while ( isSimpleChar ( * pShellConstName ) )
2003-12-22 00:28:30 +00:00
pShellConstName + + ;
2003-12-22 18:50:47 +00:00
while ( pShellConstName > p )
2003-12-22 00:28:30 +00:00
{
2003-12-22 18:50:47 +00:00
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 ) ;
2004-01-04 17:05:03 +00:00
* out + + = ( unsigned int ) NS_SHELL_CODE ; // Constant code identifier
2003-12-22 18:50:47 +00:00
* out + + = ( char ) CSIDL_Value_current ;
* out + + = ( char ) CSIDL_Value_all ;
p = pShellConstName ;
bProceced = true ;
break ;
}
pShellConstName - - ;
2003-12-22 00:28:30 +00:00
}
}
2003-06-16 19:58:29 +00:00
if ( ! bProceced & & * p = = ' ( ' )
{
int idx = - 1 ;
char * cp = strdup ( p + 1 ) ;
char * pos = strchr ( cp , ' ) ' ) ;
2005-10-16 05:37:13 +00:00
if ( pos )
2003-06-16 19:58:29 +00:00
{
* pos = 0 ;
2003-11-25 05:55:18 +00:00
idx = DefineLangString ( cp ) ;
2003-12-22 18:50:47 +00:00
if ( idx < 0 )
2003-06-16 19:58:29 +00:00
{
2004-01-04 17:05:03 +00:00
* out + + = ( unsigned int ) NS_LANG_CODE ; // Next word is lang-string Identifier
2006-03-11 11:22:02 +00:00
* ( WORD * ) out = FIX_ENDIAN_INT16 ( CODE_SHORT ( - idx - 1 ) ) ;
2003-11-25 05:55:18 +00:00
out + = sizeof ( WORD ) ;
2003-12-22 18:50:47 +00:00
p + = strlen ( cp ) + 2 ;
2003-11-25 05:55:18 +00:00
bProceced = true ;
2003-06-16 19:58:29 +00:00
}
}
2005-10-16 05:37:13 +00:00
free ( cp ) ;
2003-06-16 19:58:29 +00:00
}
2003-06-09 18:59:14 +00:00
if ( bProceced )
continue ;
else
{
char tbuf [ 64 ] ;
char cBracket = ' \0 ' ;
2003-06-16 19:58:29 +00:00
bool bDoWarning = true ;
2003-06-09 18:59:14 +00:00
if ( * p = = ' [ ' )
cBracket = ' ] ' ;
else if ( * p = = ' ( ' )
cBracket = ' ) ' ;
else if ( * p = = ' { ' )
cBracket = ' } ' ;
2005-10-16 05:37:13 +00:00
2003-06-09 18:59:14 +00:00
strncpy ( tbuf , p , 63 ) ;
tbuf [ 63 ] = 0 ;
2005-10-16 05:37:13 +00:00
2003-06-09 18:59:14 +00:00
if ( cBracket ! = 0 )
{
if ( strchr ( tbuf , cBracket ) ) ( strchr ( tbuf , cBracket ) + 1 ) [ 0 ] = 0 ;
2003-06-16 19:58:29 +00:00
if ( tbuf [ 0 ] = = ' { ' & & tbuf [ strlen ( tbuf ) - 1 ] = = ' } ' )
{
char * tstIfDefine = strdup ( tbuf + 1 ) ;
tstIfDefine [ strlen ( tstIfDefine ) - 1 ] = ' \0 ' ;
bDoWarning = definedlist . find ( tstIfDefine ) = = NULL ;
}
2003-06-09 18:59:14 +00:00
}
else
{
if ( strstr ( tbuf , " " ) ) strstr ( tbuf , " " ) [ 0 ] = 0 ;
}
2003-06-16 19:58:29 +00:00
if ( bDoWarning )
2003-12-22 00:28:30 +00:00
warning_fl ( " unknown variable/constant \" %s \" detected, ignoring " , tbuf ) ;
2003-06-09 18:59:14 +00:00
i = ' $ ' ;
}
2002-08-02 10:01:35 +00:00
}
}
}
* out + + = i ;
}
* out = 0 ;
return 0 ;
}
2002-08-31 23:44:58 +00:00
// what it does is, when you pass it the offset of the last item added, it will determine if
2002-08-02 10:01:35 +00:00
// that data is already present in the datablock, and if so, reference it instead (and shorten
// the datablock as necessary). Reduces overhead if you want to add files to a couple places.
// Woo, an optimizing installer generator, now we're styling.
2004-09-25 10:09:53 +00:00
int CEXEBuild : : datablock_optimize ( int start_offset , int first_int )
2002-08-02 10:01:35 +00:00
{
2003-09-15 22:05:06 +00:00
int this_len = cur_datablock - > getlen ( ) - start_offset ;
2004-09-25 10:09:53 +00:00
cached_db_size this_size = { first_int , start_offset } ;
cur_datablock_cache - > add ( & this_size , sizeof ( cached_db_size ) ) ;
2003-09-15 22:05:06 +00:00
2004-03-12 20:43:54 +00:00
if ( ! build_optimize_datablock | | this_len < ( int ) sizeof ( int ) )
2003-09-15 22:05:06 +00:00
return start_offset ;
2002-08-02 10:01:35 +00:00
2003-09-15 22:05:06 +00:00
MMapBuf * db = ( MMapBuf * ) cur_datablock ;
db - > setro ( TRUE ) ;
2002-08-02 10:01:35 +00:00
2004-09-25 10:09:53 +00:00
cached_db_size * db_sizes = ( cached_db_size * ) cur_datablock_cache - > get ( ) ;
int db_sizes_num = cur_datablock_cache - > getlen ( ) / sizeof ( cached_db_size ) ;
db_sizes_num - - ; // don't compare with the one we just added
2003-09-15 22:05:06 +00:00
2004-09-25 10:09:53 +00:00
for ( int i = 0 ; i < db_sizes_num ; i + + )
2002-08-02 10:01:35 +00:00
{
2004-09-25 10:09:53 +00:00
if ( db_sizes [ i ] . first_int = = first_int )
2002-08-02 10:01:35 +00:00
{
2004-09-25 10:09:53 +00:00
int pos = db_sizes [ i ] . start_offset ;
2003-09-15 22:05:06 +00:00
int left = this_len ;
while ( left > 0 )
{
int l = min ( left , build_filebuflen ) ;
2004-03-29 20:21:00 +00:00
int la = l ;
2003-09-15 22:05:06 +00:00
void * newstuff = db - > get ( start_offset + this_len - left , l ) ;
2004-03-29 20:21:00 +00:00
void * oldstuff = db - > getmore ( pos + this_len - left , & la ) ;
2003-09-15 22:05:06 +00:00
int res = memcmp ( newstuff , oldstuff , l ) ;
2004-03-29 20:21:00 +00:00
db - > release ( oldstuff , la ) ;
2003-09-15 22:05:06 +00:00
db - > release ( ) ;
if ( res )
{
break ;
}
left - = l ;
}
if ( ! left )
{
db_opt_save + = this_len ;
db - > resize ( max ( start_offset , pos + this_len ) ) ;
2003-09-16 19:07:29 +00:00
db - > setro ( FALSE ) ;
2004-09-25 10:09:53 +00:00
cur_datablock_cache - > resize ( cur_datablock_cache - > getlen ( ) - sizeof ( cached_db_size ) ) ;
2003-09-15 22:05:06 +00:00
return pos ;
}
2002-08-02 10:01:35 +00:00
}
}
2003-09-15 22:05:06 +00:00
db - > setro ( FALSE ) ;
2002-08-02 10:01:35 +00:00
return start_offset ;
}
2005-08-30 16:30:48 +00:00
int CEXEBuild : : add_db_data ( IMMap * mmap ) // returns offset
2003-09-15 22:05:06 +00:00
{
build_compressor_set = true ;
int done = 0 ;
2005-08-30 16:30:48 +00:00
if ( ! mmap )
2003-09-15 22:05:06 +00:00
{
ERROR_MSG ( " Error: add_db_data() called with invalid mapped file \n " ) ;
return - 1 ;
}
2005-08-30 16:30:48 +00:00
int length = mmap - > getsize ( ) ;
2003-09-15 22:05:06 +00:00
if ( length < 0 )
{
ERROR_MSG ( " Error: add_db_data() called with length=%d \n " , length ) ;
return - 1 ;
}
MMapBuf * db = ( MMapBuf * ) cur_datablock ;
int st = db - > getlen ( ) ;
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2004-01-06 00:53:12 +00:00
if ( length & & ! build_compress_whole & & build_compress )
2003-09-15 22:05:06 +00:00
{
// grow datablock so that there is room to compress into
int bufferlen = length + 1024 + length / 4 ; // give a nice 25% extra space
db - > resize ( st + bufferlen + sizeof ( int ) ) ;
2004-10-11 14:26:13 +00:00
int n = compressor - > Init ( build_compress_level , build_compress_dict_size ) ;
2003-11-24 00:08:58 +00:00
if ( n ! = C_OK )
2003-09-15 22:05:06 +00:00
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Internal compiler error #12345: deflateInit() failed(%s [%d]). \n " , compressor - > GetErrStr ( n ) , n ) ;
2003-09-15 22:05:06 +00:00
extern void quit ( ) ; quit ( ) ;
}
int avail_in = length ;
int avail_out = bufferlen ;
int ret ;
while ( avail_in > 0 )
{
int in_len = min ( build_filebuflen , avail_in ) ;
int out_len = min ( build_filebuflen , avail_out ) ;
2005-10-16 05:37:13 +00:00
2005-08-30 16:30:48 +00:00
compressor - > SetNextIn ( ( char * ) mmap - > get ( length - avail_in , in_len ) , in_len ) ;
2003-09-15 22:05:06 +00:00
compressor - > SetNextOut ( ( char * ) db - > get ( st + sizeof ( int ) + bufferlen - avail_out , out_len ) , out_len ) ;
if ( ( ret = compressor - > Compress ( 0 ) ) < 0 )
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Error: add_db_data() - compress() failed(%s [%d]) \n " , compressor - > GetErrStr ( ret ) , ret ) ;
2003-09-15 22:05:06 +00:00
return - 1 ;
}
2005-08-30 16:30:48 +00:00
mmap - > release ( ) ;
2003-09-15 22:05:06 +00:00
db - > flush ( out_len ) ;
db - > release ( ) ;
avail_in - = in_len - compressor - > GetAvailIn ( ) ;
avail_out - = out_len - compressor - > GetAvailOut ( ) ;
if ( ! avail_out )
// not enough space in the output buffer - no compression is better
break ;
}
// if not enough space in the output buffer - no compression is better
if ( avail_out )
{
char * out ;
2003-09-16 09:19:39 +00:00
char a ;
compressor - > SetNextIn ( & a , 0 ) ;
2003-09-15 22:05:06 +00:00
do
{
int out_len = min ( build_filebuflen , avail_out ) ;
out = ( char * ) db - > get ( st + sizeof ( int ) + bufferlen - avail_out , out_len ) ;
compressor - > SetNextOut ( out , out_len ) ;
if ( ( ret = compressor - > Compress ( C_FINISH ) ) < 0 )
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Error: add_db_data() - compress() failed(%s [%d]) \n " , compressor - > GetErrStr ( ret ) , ret ) ;
2003-09-15 22:05:06 +00:00
return - 1 ;
}
db - > flush ( out_len ) ;
db - > release ( ) ;
avail_out - = out_len - compressor - > GetAvailOut ( ) ;
}
2004-01-06 00:53:12 +00:00
while ( compressor - > GetNextOut ( ) - out > 0 & & avail_out > 0 ) ;
2003-09-15 22:05:06 +00:00
2003-09-23 19:56:58 +00:00
compressor - > End ( ) ;
2003-09-15 22:05:06 +00:00
int used = bufferlen - avail_out ;
// never store compressed if output buffer is full (compression increased the size...)
if ( avail_out & & ( build_compress = = 2 | | used < length ) )
{
done = 1 ;
db - > resize ( st + used + sizeof ( int ) ) ;
2006-03-11 11:22:02 +00:00
* ( int * ) db - > get ( st , sizeof ( int ) ) = FIX_ENDIAN_INT32 ( used | 0x80000000 ) ;
2003-09-15 22:05:06 +00:00
db - > release ( ) ;
2004-09-25 10:09:53 +00:00
int nst = datablock_optimize ( st , used | 0x80000000 ) ;
2003-09-15 22:05:06 +00:00
if ( nst = = st ) db_comp_save + = length - used ;
else st = nst ;
}
}
2004-01-06 00:53:12 +00:00
else
compressor - > End ( ) ;
2003-09-15 22:05:06 +00:00
}
# endif // NSIS_CONFIG_COMPRESSION_SUPPORT
if ( ! done )
{
db - > resize ( st + length + sizeof ( int ) ) ;
int * plen = ( int * ) db - > get ( st , sizeof ( int ) ) ;
2006-03-11 11:22:02 +00:00
* plen = FIX_ENDIAN_INT32 ( length ) ;
2003-09-15 22:05:06 +00:00
db - > release ( ) ;
int left = length ;
while ( left > 0 )
{
int l = min ( build_filebuflen , left ) ;
int * p = ( int * ) db - > get ( st + sizeof ( int ) + length - left , l ) ;
2005-08-30 16:30:48 +00:00
memcpy ( p , mmap - > get ( length - left , l ) , l ) ;
2003-09-15 22:05:06 +00:00
db - > flush ( l ) ;
db - > release ( ) ;
2005-08-30 16:30:48 +00:00
mmap - > release ( ) ;
2003-09-15 22:05:06 +00:00
left - = l ;
}
2004-09-25 10:09:53 +00:00
st = datablock_optimize ( st , length ) ;
2003-09-15 22:05:06 +00:00
}
db_full_size + = length + sizeof ( int ) ;
return st ;
}
int CEXEBuild : : add_db_data ( const char * data , int length ) // returns offset
{
MMapFake fakemap ;
fakemap . set ( data , length ) ;
return add_db_data ( & fakemap ) ;
}
2002-08-02 10:01:35 +00:00
int CEXEBuild : : add_data ( const char * data , int length , IGrowBuf * dblock ) // returns offset
{
build_compressor_set = true ;
int done = 0 ;
if ( length < 0 )
{
ERROR_MSG ( " Error: add_data() called with length=%d \n " , length ) ;
return - 1 ;
}
int st = dblock - > getlen ( ) ;
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
if ( ! build_compress_whole & & build_compress )
{
// grow datablock so that there is room to compress into
int bufferlen = length + 1024 + length / 4 ; // give a nice 25% extra space
dblock - > resize ( st + bufferlen + sizeof ( int ) ) ;
2004-10-11 14:26:13 +00:00
int n = compressor - > Init ( build_compress_level , build_compress_dict_size ) ;
2003-11-24 00:08:58 +00:00
if ( n ! = C_OK )
2002-08-02 10:01:35 +00:00
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Internal compiler error #12345: deflateInit() failed(%s [%d]). \n " , compressor - > GetErrStr ( n ) , n ) ;
2002-08-02 10:01:35 +00:00
extern void quit ( ) ; quit ( ) ;
}
compressor - > SetNextIn ( ( char * ) data , length ) ;
compressor - > SetNextOut ( ( char * ) dblock - > get ( ) + st + sizeof ( int ) , bufferlen ) ;
compressor - > Compress ( C_FINISH ) ;
int used = bufferlen - compressor - > GetAvailOut ( ) ;
// never store compressed if output buffer is full
if ( compressor - > GetAvailOut ( ) & & ( build_compress = = 2 | | used < length ) )
{
done = 1 ;
dblock - > resize ( st + used + sizeof ( int ) ) ;
2006-03-11 11:22:02 +00:00
* ( ( int * ) ( ( char * ) dblock - > get ( ) + st ) ) = FIX_ENDIAN_INT32 ( used | 0x80000000 ) ;
2002-08-02 10:01:35 +00:00
}
compressor - > End ( ) ;
}
# endif // NSIS_CONFIG_COMPRESSION_SUPPORT
if ( ! done )
{
dblock - > resize ( st ) ;
2006-03-11 11:22:02 +00:00
int rl = FIX_ENDIAN_INT32 ( length ) ;
dblock - > add ( & rl , sizeof ( int ) ) ;
2002-08-02 10:01:35 +00:00
dblock - > add ( data , length ) ;
}
return st ;
}
int CEXEBuild : : add_label ( const char * name )
{
2003-09-04 18:25:57 +00:00
if ( ! build_cursection )
2002-08-02 10:01:35 +00:00
{
2002-08-31 23:44:58 +00:00
ERROR_MSG ( " Error: Label declaration not valid outside of function/section \n " ) ;
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
}
if ( ( name [ 0 ] > = ' 0 ' & & name [ 0 ] < = ' 9 ' ) | | name [ 0 ] = = ' - ' | | name [ 0 ] = = ' ' | | name [ 0 ] = = ' : ' )
{
2002-08-31 23:44:58 +00:00
ERROR_MSG ( " Error: labels must not begin with 0-9, -, :, or a space. \n " ) ;
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
int cs = build_cursection - > code ;
int ce = cs + build_cursection - > code_size ;
2002-08-02 10:01:35 +00:00
char * p = strdup ( name ) ;
if ( p [ strlen ( p ) - 1 ] = = ' : ' ) p [ strlen ( p ) - 1 ] = 0 ;
int offs = ns_label . add ( p , 0 ) ;
free ( p ) ;
int n = cur_labels - > getlen ( ) / sizeof ( section ) ;
if ( n )
{
section * t = ( section * ) cur_labels - > get ( ) ;
while ( n - - )
{
2002-08-31 23:44:58 +00:00
if ( ( * name = = ' . ' | | ( t - > code > = cs & & t - > code < = ce ) ) & &
2002-08-02 10:01:35 +00:00
t - > name_ptr = = offs )
{
if ( * name = = ' . ' ) ERROR_MSG ( " Error: global label \" %s \" already declared \n " , name ) ;
2005-12-09 13:15:21 +00:00
else
{
char * t = " section " ;
if ( build_cursection_isfunc )
t = " function " ;
ERROR_MSG ( " Error: label \" %s \" already declared in %s \n " , name , t ) ;
}
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
}
t + + ;
}
}
2002-08-31 23:44:58 +00:00
2004-05-01 12:41:49 +00:00
section s = { 0 } ;
2002-08-02 10:01:35 +00:00
s . name_ptr = offs ;
s . code = ce ;
cur_labels - > add ( & s , sizeof ( s ) ) ;
return PS_OK ;
}
int CEXEBuild : : add_function ( const char * funname )
{
if ( build_cursection_isfunc )
{
ERROR_MSG ( " Error: Function open when creating function (use FunctionEnd first) \n " ) ;
return PS_ERROR ;
}
if ( build_cursection )
{
ERROR_MSG ( " Error: Section open when creating function (use SectionEnd first) \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
if ( cur_page )
{
ERROR_MSG ( " Error: PageEx open when creating function (use PageExEnd first) \n " ) ;
return PS_ERROR ;
}
2002-08-02 10:01:35 +00:00
if ( ! funname [ 0 ] )
{
ERROR_MSG ( " Error: Function must have a name \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
set_uninstall_mode ( ! strnicmp ( funname , " un. " , 3 ) ) ;
2002-08-02 10:01:35 +00:00
int addr = ns_func . add ( funname , 0 ) ;
int x ;
int n = cur_functions - > getlen ( ) / sizeof ( section ) ;
section * tmp = ( section * ) cur_functions - > get ( ) ;
for ( x = 0 ; x < n ; x + + )
{
if ( tmp [ x ] . name_ptr = = addr )
2003-04-17 15:27:12 +00:00
{
ERROR_MSG ( " Error: Function named \" %s \" already exists. \n " , funname ) ;
return PS_ERROR ;
}
2002-08-02 10:01:35 +00:00
}
cur_functions - > resize ( ( n + 1 ) * sizeof ( section ) ) ;
build_cursection = ( ( section * ) cur_functions - > get ( ) ) + n ;
build_cursection_isfunc = 1 ;
build_cursection - > name_ptr = addr ;
build_cursection - > code = cur_entries - > getlen ( ) / sizeof ( entry ) ;
build_cursection - > code_size = 0 ;
2002-10-02 15:01:06 +00:00
build_cursection - > install_types = 0 ;
build_cursection - > flags = 0 ;
2002-08-02 10:01:35 +00:00
build_cursection - > size_kb = 0 ;
2005-01-14 15:11:56 +00:00
memset ( build_cursection - > name , 0 , sizeof ( build_cursection - > name ) ) ;
2002-08-02 10:01:35 +00:00
return PS_OK ;
}
int CEXEBuild : : function_end ( )
{
if ( ! build_cursection_isfunc )
{
ERROR_MSG ( " Error: No function open, FunctionEnd called \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
// add ret.
2003-09-05 22:22:56 +00:00
add_entry_direct ( EW_RET ) ;
2003-09-04 18:25:57 +00:00
2002-08-02 10:01:35 +00:00
build_cursection_isfunc = 0 ;
build_cursection = NULL ;
set_uninstall_mode ( 0 ) ;
return PS_OK ;
}
int CEXEBuild : : section_add_flags ( int flags )
{
if ( ! build_cursection | | build_cursection_isfunc )
{
ERROR_MSG ( " Error: can't modify flags when no section is open \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
build_cursection - > flags | = flags ;
2002-10-02 15:01:06 +00:00
return PS_OK ;
}
int CEXEBuild : : section_add_install_type ( int inst_type )
{
if ( ! build_cursection | | build_cursection_isfunc )
{
ERROR_MSG ( " Error: can't modify flags when no section is open \n " ) ;
return PS_ERROR ;
}
2003-06-08 14:45:56 +00:00
if ( build_cursection - > install_types = = ~ 0 )
2002-10-19 12:02:18 +00:00
build_cursection - > install_types = 0 ;
2003-09-04 18:25:57 +00:00
build_cursection - > install_types | = inst_type ;
2002-08-02 10:01:35 +00:00
return PS_OK ;
}
void CEXEBuild : : section_add_size_kb ( int kb )
{
if ( build_cursection )
{
build_cursection - > size_kb + = kb ;
}
}
int CEXEBuild : : section_end ( )
{
if ( build_cursection_isfunc )
{
ERROR_MSG ( " Error: SectionEnd specified in function (not section) \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
if ( ! build_cursection )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Error: SectionEnd specified and no sections open \n " ) ;
return PS_ERROR ;
}
2003-09-05 22:22:56 +00:00
add_entry_direct ( EW_RET ) ;
2003-09-04 18:25:57 +00:00
build_cursection - > code_size - - ;
2002-08-02 10:01:35 +00:00
build_cursection = NULL ;
2005-01-10 12:43:52 +00:00
if ( ! sectiongroup_open_cnt )
2003-09-04 18:25:57 +00:00
set_uninstall_mode ( 0 ) ;
2002-08-02 10:01:35 +00:00
return PS_OK ;
}
2003-06-05 21:53:52 +00:00
int CEXEBuild : : add_section ( const char * secname , const char * defname , int expand /*=0*/ )
2002-08-02 10:01:35 +00:00
{
if ( build_cursection_isfunc )
{
ERROR_MSG ( " Error: Section can't create section (already in function, use FunctionEnd first) \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
if ( cur_page ) {
ERROR_MSG ( " Error: PageEx already open, call PageExEnd first \n " ) ;
return PS_ERROR ;
}
if ( build_cursection )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Error: Section already open, call SectionEnd first \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
section new_section ;
new_section . flags = SF_SELECTED ;
new_section . flags | = expand ? SF_EXPAND : 0 ;
new_section . code_size = 0 ;
new_section . size_kb = 0 ;
char * name = ( char * ) secname ;
if ( secname [ 0 ] = = ' - ' )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
if ( secname [ 1 ] )
2002-08-02 10:01:35 +00:00
{
2005-01-10 12:43:52 +00:00
new_section . flags | = SF_SECGRP ;
2003-09-04 18:25:57 +00:00
name + + ;
2002-08-02 10:01:35 +00:00
}
2003-09-04 18:25:57 +00:00
else
2005-01-10 12:43:52 +00:00
new_section . flags | = SF_SECGRPEND ;
2003-09-04 18:25:57 +00:00
}
if ( name [ 0 ] = = ' ! ' )
{
name + + ;
new_section . flags | = SF_BOLD ;
}
int old_uninstall_mode = uninstall_mode ;
set_uninstall_mode ( 0 ) ;
if ( ! strnicmp ( name , " un. " , 3 ) )
{
set_uninstall_mode ( 1 ) ;
name + = 3 ;
}
if ( ! stricmp ( name , " uninstall " ) )
{
set_uninstall_mode ( 1 ) ;
}
2005-01-10 12:43:52 +00:00
if ( ( new_section . flags & SF_SECGRPEND ) & & sectiongroup_open_cnt & & old_uninstall_mode )
2003-11-19 13:11:07 +00:00
{
set_uninstall_mode ( 1 ) ;
}
2005-01-10 12:43:52 +00:00
if ( sectiongroup_open_cnt )
2003-09-04 18:25:57 +00:00
{
if ( uninstall_mode ! = old_uninstall_mode )
2002-08-02 10:01:35 +00:00
{
2005-01-10 12:43:52 +00:00
ERROR_MSG ( " Error: Can't create %s section in %s section group (use SectionGroupEnd first) \n " , uninstall_mode ? " uninstaller " : " installer " , old_uninstall_mode ? " uninstaller " : " installer " ) ;
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
}
}
2003-09-04 18:25:57 +00:00
new_section . code = cur_entries - > getlen ( ) / sizeof ( entry ) ;
2002-10-02 21:31:35 +00:00
2003-09-04 18:25:57 +00:00
new_section . install_types = * name ? 0 : ~ 0 ;
new_section . name_ptr = add_string ( name ) ;
2005-01-14 15:11:56 +00:00
memset ( & new_section . name , 0 , sizeof ( new_section . name ) ) ;
2003-09-04 18:25:57 +00:00
cur_sections - > add ( & new_section , sizeof ( section ) ) ;
build_cursection = ( section * ) cur_sections - > get ( ) + cur_header - > blocks [ NB_SECTIONS ] . num ;
2002-08-02 10:01:35 +00:00
2003-11-19 13:11:07 +00:00
if ( defname [ 0 ] )
{
2004-03-29 20:21:00 +00:00
char buf [ 128 ] ;
# ifdef _WIN32
2003-11-19 13:11:07 +00:00
wsprintf ( buf , " %d " , cur_header - > blocks [ NB_SECTIONS ] . num ) ;
2004-03-29 20:21:00 +00:00
# else
snprintf ( buf , 128 , " %d " , cur_header - > blocks [ NB_SECTIONS ] . num ) ;
# endif
2003-11-19 13:11:07 +00:00
if ( definedlist . add ( defname , buf ) )
{
ERROR_MSG ( " Error: \" %s \" already defined, can't assign section index! \n " , defname ) ;
return PS_ERROR ;
}
}
cur_header - > blocks [ NB_SECTIONS ] . num + + ;
2005-01-10 12:43:52 +00:00
if ( new_section . flags & ( SF_SECGRP | SF_SECGRPEND ) )
2002-08-02 10:01:35 +00:00
{
2003-11-19 13:11:07 +00:00
add_entry_direct ( EW_RET ) ;
build_cursection - > code_size = 0 ;
build_cursection = 0 ;
2005-01-10 12:43:52 +00:00
if ( new_section . flags & SF_SECGRPEND )
2003-09-04 18:25:57 +00:00
{
2005-01-10 12:43:52 +00:00
sectiongroup_open_cnt - - ;
if ( sectiongroup_open_cnt < 0 )
2003-09-04 18:25:57 +00:00
{
2005-01-10 12:43:52 +00:00
ERROR_MSG ( " SectionGroupEnd: no SectionGroups are open \n " ) ;
2003-09-04 18:25:57 +00:00
return PS_ERROR ;
}
2005-01-10 12:43:52 +00:00
if ( ! sectiongroup_open_cnt )
2003-11-19 13:11:07 +00:00
{
2003-09-04 18:25:57 +00:00
set_uninstall_mode ( 0 ) ;
2003-11-19 13:11:07 +00:00
}
2003-09-04 18:25:57 +00:00
}
else
2005-01-10 12:43:52 +00:00
sectiongroup_open_cnt + + ;
2002-08-02 10:01:35 +00:00
}
return PS_OK ;
}
int CEXEBuild : : add_entry ( const entry * ent )
{
2002-08-31 23:44:58 +00:00
if ( ! build_cursection & & ! uninstall_mode )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Error: Can't add entry, no section or function is open! \n " ) ;
return PS_ERROR ;
}
cur_entries - > add ( ent , sizeof ( entry ) ) ;
2004-09-25 13:35:03 +00:00
cur_instruction_entry_map - > add ( & multiple_entries_instruction , sizeof ( int ) ) ;
2003-09-04 18:25:57 +00:00
build_cursection - > code_size + + ;
cur_header - > blocks [ NB_ENTRIES ] . num + + ;
2002-08-02 10:01:35 +00:00
2004-09-25 13:35:03 +00:00
multiple_entries_instruction = 1 ;
2002-08-02 10:01:35 +00:00
return PS_OK ;
}
2003-09-05 22:22:56 +00:00
int CEXEBuild : : add_entry_direct ( int which , int o0 , int o1 , int o2 , int o3 , int o4 , int o5 /*o#=0*/ )
2003-04-02 15:49:13 +00:00
{
entry ent ;
ent . which = which ;
ent . offsets [ 0 ] = o0 ;
ent . offsets [ 1 ] = o1 ;
ent . offsets [ 2 ] = o2 ;
ent . offsets [ 3 ] = o3 ;
ent . offsets [ 4 ] = o4 ;
ent . offsets [ 5 ] = o5 ;
return add_entry ( & ent ) ;
}
2002-08-02 10:01:35 +00:00
int CEXEBuild : : resolve_jump_int ( const char * fn , int * a , int offs , int start , int end )
{
2002-08-31 23:44:58 +00:00
if ( * a > 0 )
2002-08-02 10:01:35 +00:00
{
char * lname = ( char * ) ns_label . get ( ) + * a ;
if ( lname [ 0 ] = = ' - ' | | lname [ 0 ] = = ' + ' )
{
2004-09-25 13:35:03 +00:00
int jump = atoi ( lname ) ;
int * skip_map = ( int * ) cur_instruction_entry_map - > get ( ) ;
2004-11-19 15:02:08 +00:00
int maxoffs = cur_instruction_entry_map - > getlen ( ) / ( int ) sizeof ( int ) ;
2004-09-25 13:35:03 +00:00
int direction = 1 ;
if ( jump < 0 )
direction = - 1 ;
for ( ; jump ! = 0 ; jump - = direction )
{
offs + = direction ;
2004-11-19 15:02:08 +00:00
if ( offs > = 0 & & offs < maxoffs )
2004-09-25 13:35:03 +00:00
{
while ( skip_map [ offs ] )
{
offs + = direction ;
}
}
}
* a = offs + 1 ;
2002-08-02 10:01:35 +00:00
}
2002-08-31 23:44:58 +00:00
else
2002-08-02 10:01:35 +00:00
{
section * s = ( section * ) cur_labels - > get ( ) ;
int n = cur_labels - > getlen ( ) / sizeof ( section ) ;
while ( n - - > 0 )
{
if ( ( * lname = = ' . ' | | ( s - > code > = start & & s - > code < = end ) ) & & s - > name_ptr = = * a )
{
* a = s - > code + 1 ; // jumps are to the absolute position, +1 (to differentiate between no jump, and jumping to offset 0)
2002-10-02 15:01:06 +00:00
s - > flags + + ;
2002-08-02 10:01:35 +00:00
return 0 ;
}
s + + ;
}
ERROR_MSG ( " Error: could not resolve label \" %s \" in %s \n " , lname , fn ) ;
return 1 ;
}
}
else if ( * a < 0 ) // to jump to a user variable target, -variable_index-1 is already stored.
{
}
// otherwise, *a is 0, which means no jump and we also leave it intact
return 0 ;
}
int CEXEBuild : : resolve_call_int ( const char * fn , const char * str , int fptr , int * ofs )
{
if ( fptr < 0 ) return 0 ;
int nf = cur_functions - > getlen ( ) / sizeof ( section ) ;
section * sec = ( section * ) cur_functions - > get ( ) ;
while ( nf - - > 0 )
{
if ( sec - > name_ptr > 0 & & sec - > name_ptr = = fptr )
{
ofs [ 0 ] = sec - > code ;
2002-10-02 15:01:06 +00:00
sec - > flags + + ;
2002-08-02 10:01:35 +00:00
return 0 ;
}
sec + + ;
}
ERROR_MSG ( " Error: resolving %s function \" %s \" in %s \n " , str , ( char * ) ns_func . get ( ) + fptr , fn ) ;
2003-09-04 18:25:57 +00:00
ERROR_MSG ( " Note: uninstall functions must begin with \" un. \" , and install functions must not \n " ) ;
return 1 ;
}
2002-08-02 10:01:35 +00:00
int CEXEBuild : : resolve_instruction ( const char * fn , const char * str , entry * w , int offs , int start , int end )
{
if ( w - > which = = EW_NOP )
{
if ( resolve_jump_int ( fn , & w - > offsets [ 0 ] , offs , start , end ) ) return 1 ;
}
2002-09-18 19:08:53 +00:00
# ifdef NSIS_SUPPORT_MESSAGEBOX
2002-08-02 10:01:35 +00:00
else if ( w - > which = = EW_MESSAGEBOX )
{
if ( resolve_jump_int ( fn , & w - > offsets [ 3 ] , offs , start , end ) ) return 1 ;
2003-03-29 17:16:09 +00:00
if ( resolve_jump_int ( fn , & w - > offsets [ 5 ] , offs , start , end ) ) return 1 ;
2002-08-02 10:01:35 +00:00
}
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
else if ( w - > which = = EW_IFFILEEXISTS )
{
if ( resolve_jump_int ( fn , & w - > offsets [ 1 ] , offs , start , end ) ) return 1 ;
if ( resolve_jump_int ( fn , & w - > offsets [ 2 ] , offs , start , end ) ) return 1 ;
}
2003-04-02 19:54:53 +00:00
else if ( w - > which = = EW_IFFLAG )
2002-08-02 10:01:35 +00:00
{
if ( resolve_jump_int ( fn , & w - > offsets [ 0 ] , offs , start , end ) ) return 1 ;
if ( resolve_jump_int ( fn , & w - > offsets [ 1 ] , offs , start , end ) ) return 1 ;
}
2002-09-18 19:08:53 +00:00
# ifdef NSIS_SUPPORT_STROPTS
2002-08-02 10:01:35 +00:00
else if ( w - > which = = EW_STRCMP )
{
if ( resolve_jump_int ( fn , & w - > offsets [ 2 ] , offs , start , end ) ) return 1 ;
if ( resolve_jump_int ( fn , & w - > offsets [ 3 ] , offs , start , end ) ) return 1 ;
}
2002-09-18 19:08:53 +00:00
# endif
# ifdef NSIS_SUPPORT_INTOPTS
2003-03-20 20:49:13 +00:00
else if ( w - > which = = EW_INTCMP )
2002-08-02 10:01:35 +00:00
{
if ( resolve_jump_int ( fn , & w - > offsets [ 2 ] , offs , start , end ) ) return 1 ;
if ( resolve_jump_int ( fn , & w - > offsets [ 3 ] , offs , start , end ) ) return 1 ;
if ( resolve_jump_int ( fn , & w - > offsets [ 4 ] , offs , start , end ) ) return 1 ;
}
2002-09-18 19:08:53 +00:00
# endif
# ifdef NSIS_SUPPORT_HWNDS
2002-08-02 10:01:35 +00:00
else if ( w - > which = = EW_ISWINDOW )
{
if ( resolve_jump_int ( fn , & w - > offsets [ 1 ] , offs , start , end ) ) return 1 ;
if ( resolve_jump_int ( fn , & w - > offsets [ 2 ] , offs , start , end ) ) return 1 ;
}
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
else if ( w - > which = = EW_CALL )
{
if ( w - > offsets [ 0 ] > = 0 & & w - > offsets [ 1 ] ) // get as jump
{
if ( resolve_jump_int ( fn , & w - > offsets [ 0 ] , offs , start , end ) ) return 1 ;
}
else
{
if ( w - > offsets [ 0 ] > = 0 & & resolve_call_int ( fn , str , w - > offsets [ 0 ] , w - > offsets ) ) return 1 ;
// if w->offsets[0] >= 0, EW_CALL requires that it 1-based.
2002-08-31 23:44:58 +00:00
// otherwise, if < 0, it needs an increment anyway (since it
2002-08-02 10:01:35 +00:00
// was encoded with a -2 base, to prevent it looking like an
// empty string "")
2002-08-31 23:44:58 +00:00
w - > offsets [ 0 ] + + ;
2002-08-02 10:01:35 +00:00
}
}
2002-09-18 19:08:53 +00:00
# ifdef NSIS_SUPPORT_STROPTS
2002-08-02 10:01:35 +00:00
else if ( w - > which = = EW_GETFUNCTIONADDR )
{
if ( w - > offsets [ 1 ] < 0 )
{
ERROR_MSG ( " Error: GetFunctionAddress requires a real function to get address of. \n " ) ;
return 1 ;
}
2002-08-31 23:44:58 +00:00
2002-08-02 10:01:35 +00:00
if ( resolve_call_int ( fn , str , w - > offsets [ 1 ] , & w - > offsets [ 1 ] ) ) return 1 ;
w - > which = EW_ASSIGNVAR ;
2004-03-29 20:21:00 +00:00
w - > offsets [ 1 ] = add_intstring ( w - > offsets [ 1 ] + 1 ) ; // +1 here to make 1-based.
2002-08-02 10:01:35 +00:00
}
else if ( w - > which = = EW_GETLABELADDR )
{
if ( resolve_jump_int ( fn , & w - > offsets [ 1 ] , offs , start , end ) ) return 1 ;
w - > which = EW_ASSIGNVAR ;
2004-03-29 20:21:00 +00:00
w - > offsets [ 1 ] = add_intstring ( w - > offsets [ 1 ] ) ;
2002-08-02 10:01:35 +00:00
}
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
return 0 ;
}
int CEXEBuild : : resolve_coderefs ( const char * str )
{
// resolve jumps&calls
{
2002-08-31 23:44:58 +00:00
section * sec = ( section * ) cur_functions - > get ( ) ;
2002-08-02 10:01:35 +00:00
int l = cur_functions - > getlen ( ) / sizeof ( section ) ;
2002-11-01 20:34:55 +00:00
entry * w = ( entry * ) cur_entries - > get ( ) ;
2002-08-02 10:01:35 +00:00
while ( l - - > 0 )
{
int x ;
for ( x = sec - > code ; x < sec - > code + sec - > code_size ; x + + )
{
char fname [ 1024 ] ;
wsprintf ( fname , " function \" %s \" " , ns_func . get ( ) + sec - > name_ptr ) ;
if ( resolve_instruction ( fname , str , w + x , x , sec - > code , sec - > code + sec - > code_size ) ) return 1 ;
}
sec + + ;
}
2002-11-01 20:34:55 +00:00
2003-09-04 18:25:57 +00:00
int cnt = 0 ;
sec = ( section * ) cur_sections - > get ( ) ;
l = cur_sections - > getlen ( ) / sizeof ( section ) ;
while ( l - - > 0 )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
int x = sec - > name_ptr ;
char fname [ 1024 ] ;
2004-10-02 15:17:00 +00:00
const char * section_name ;
2003-09-04 18:25:57 +00:00
if ( x < 0 )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
// lang string
2004-10-02 15:17:00 +00:00
section_name = " $(lang string) " ;
2003-09-04 18:25:57 +00:00
}
else
{
// normal string
2004-10-02 15:17:00 +00:00
section_name = cur_strlist - > get ( ) + x ;
2003-09-04 18:25:57 +00:00
}
2004-10-02 15:17:00 +00:00
if ( x ) wsprintf ( fname , " %s section \" %s \" (%d) " , str , section_name , cnt ) ;
2003-09-04 18:25:57 +00:00
else wsprintf ( fname , " unnamed %s section (%d) " ,str,cnt) ;
for ( x = sec - > code ; x < sec - > code + sec - > code_size ; x + + )
{
if ( resolve_instruction ( fname , str , w + x , x , sec - > code , sec - > code + sec - > code_size ) )
return 1 ;
2002-08-02 10:01:35 +00:00
}
2003-09-04 18:25:57 +00:00
sec + + ;
cnt + + ;
}
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2002-11-01 20:34:55 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2003-09-04 18:25:57 +00:00
if ( cur_pages - > getlen ( ) ) {
page * p = ( page * ) cur_pages - > get ( ) ;
int i = 0 ;
while ( i < cur_header - > blocks [ NB_PAGES ] . num ) {
char pagestr [ 1024 ] ;
wsprintf ( pagestr , " %s pages " , str ) ;
2003-12-14 22:09:18 +00:00
if ( resolve_call_int ( pagestr , p - > dlg_id ? " pre-page " : " create-page " , p - > prefunc , & p - > prefunc ) ) return 1 ;
if ( resolve_call_int ( pagestr , " show-page " , p - > showfunc , & p - > showfunc ) ) return 1 ;
2003-09-04 18:25:57 +00:00
if ( resolve_call_int ( pagestr , " leave-page " , p - > leavefunc , & p - > leavefunc ) ) return 1 ;
p + + ;
i + + ;
2002-11-01 20:34:55 +00:00
}
2003-09-04 18:25:57 +00:00
}
# endif
2002-11-01 20:34:55 +00:00
# endif
2003-09-04 18:25:57 +00:00
}
# ifdef NSIS_SUPPORT_CODECALLBACKS
// resolve callbacks
{
struct {
char * name ;
int * p ;
} callbacks [ ] = {
{ " %s.onInit " , & cur_header - > code_onInit } ,
{ " %s.on%sInstSuccess " , & cur_header - > code_onInstSuccess } ,
{ " %s.on%sInstFailed " , & cur_header - > code_onInstFailed } ,
{ " %s.onUserAbort " , & cur_header - > code_onUserAbort } ,
{ " %s.onVerifyInstDir " , & cur_header - > code_onVerifyInstDir } ,
# ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
{ " %s.onGUIInit " , & cur_header - > code_onGUIInit } ,
{ " %s.onGUIEnd " , & cur_header - > code_onGUIEnd } ,
{ " %s.onMouseOverSection " , & cur_header - > code_onMouseOverSection } ,
2004-10-14 13:56:02 +00:00
# endif //NSIS_CONFIG_ENHANCEDUI_SUPPORT
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_COMPONENTPAGE
{ " %s.onSelChange " , & cur_header - > code_onSelChange } ,
2004-10-14 13:56:02 +00:00
# endif //NSIS_CONFIG_COMPONENTPAGE
# ifdef NSIS_SUPPORT_REBOOT
{ " %s.onRebootFailed " , & cur_header - > code_onRebootFailed } ,
# endif //NSIS_SUPPORT_REBOOT
2003-09-04 18:25:57 +00:00
{ 0 , 0 }
} ;
for ( int i = 0 ; callbacks [ i ] . name ; i + + ) {
2004-03-12 20:43:54 +00:00
const char * un = uninstall_mode ? " un " : " " ;
2003-09-04 18:25:57 +00:00
char fname [ 1024 ] ;
wsprintf ( fname , callbacks [ i ] . name , un , un ) ;
char cbstr [ 1024 ] ;
wsprintf ( cbstr , " %s callback " , str ) ;
char cbstr2 [ 1024 ] ;
wsprintf ( cbstr2 , " %s.callbacks " , un ) ;
if ( resolve_call_int ( cbstr , cbstr2 , ns_func . find ( fname , 0 ) , callbacks [ i ] . p ) )
return PS_ERROR ;
2002-08-02 10:01:35 +00:00
}
}
2003-09-04 18:25:57 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2002-08-02 10:01:35 +00:00
// optimize unused functions
{
2002-08-31 23:44:58 +00:00
section * sec = ( section * ) cur_functions - > get ( ) ;
2002-08-02 10:01:35 +00:00
int l = cur_functions - > getlen ( ) / sizeof ( section ) ;
entry * w = ( entry * ) cur_entries - > get ( ) ;
while ( l - - > 0 )
{
if ( sec - > name_ptr )
{
2002-10-02 15:01:06 +00:00
if ( ! sec - > flags )
2002-08-02 10:01:35 +00:00
{
if ( sec - > code_size > 0 )
{
warning ( " %s function \" %s \" not referenced - zeroing code (%d-%d) out \n " , str ,
ns_func . get ( ) + sec - > name_ptr ,
sec - > code , sec - > code + sec - > code_size ) ;
memset ( w + sec - > code , 0 , sec - > code_size * sizeof ( entry ) ) ;
}
}
}
sec + + ;
}
}
// give warnings on unused labels
{
section * t = ( section * ) cur_labels - > get ( ) ;
int n = cur_labels - > getlen ( ) / sizeof ( section ) ;
while ( n - - > 0 )
{
2002-10-02 15:01:06 +00:00
if ( ! t - > flags )
2002-08-02 10:01:35 +00:00
{
char * n = ( char * ) ns_label . get ( ) + t - > name_ptr ;
if ( * n = = ' . ' ) warning ( " global label \" %s \" not used " , n ) ;
else warning ( " label \" %s \" not used " , n ) ;
}
t + + ;
}
}
2002-08-31 23:44:58 +00:00
2002-08-02 10:01:35 +00:00
return 0 ;
}
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
int CEXEBuild : : add_page ( int type )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
page pg = {
0 ,
0 ,
# ifdef NSIS_SUPPORT_CODECALLBACKS
- 1 ,
- 1 ,
- 1 ,
# endif
0 ,
} ;
# ifndef NSIS_CONFIG_LICENSEPAGE
if ( type = = PAGE_LICENSE )
{
ERROR_MSG ( " Error: can't add license page, NSIS_CONFIG_LICENSEPAGE not defined. \n " ) ;
return PS_ERROR ;
}
# endif
# ifndef NSIS_CONFIG_COMPONENTPAGE
if ( type = = PAGE_COMPONENTS )
{
ERROR_MSG ( " Error: can't add components page, NSIS_CONFIG_COMPONENTPAGE not defined. \n " ) ;
return PS_ERROR ;
}
# endif
# ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( type = = PAGE_COMPONENTS )
{
ERROR_MSG ( " Error: can't add uninstConfirm page, NSIS_CONFIG_UNINSTALL_SUPPORT not defined. \n " ) ;
return PS_ERROR ;
}
# endif
struct {
int wndproc_id ;
int dlg_id ;
} ids [ ] = {
{ PWP_CUSTOM , 0 } , // custom
# ifdef NSIS_CONFIG_LICENSEPAGE
{ PWP_LICENSE , IDD_LICENSE } , // license
# else
{ 0 , IDD_LICENSE } , // license
# endif
# ifdef NSIS_CONFIG_COMPONENTPAGE
{ PWP_SELCOM , IDD_SELCOM } , // components
# else
{ 0 , IDD_SELCOM } , // components
# endif
{ PWP_DIR , IDD_DIR } , // directory
{ PWP_INSTFILES , IDD_INSTFILES } , // instfiles
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
{ PWP_UNINST , IDD_UNINST } , // uninstConfirm
# else
{ 0 , IDD_UNINST } , // uninstConfirm
# endif
{ PWP_COMPLETED , - 1 } // completed
} ;
pg . wndproc_id = ids [ type ] . wndproc_id ;
pg . dlg_id = ids [ type ] . dlg_id ;
cur_pages - > add ( & pg , sizeof ( page ) ) ;
cur_page = ( page * ) cur_pages - > get ( ) + cur_header - > blocks [ NB_PAGES ] . num + + ;
cur_page_type = type ;
return PS_OK ;
}
int CEXEBuild : : page_end ( )
{
cur_page = 0 ;
return PS_OK ;
}
# endif
# ifdef NSIS_SUPPORT_VERSION_INFO
int CEXEBuild : : AddVersionInfo ( )
{
GrowBuf VerInfoStream ;
2003-06-09 18:59:14 +00:00
2003-06-12 00:06:23 +00:00
if ( rVersionInfo . GetStringTablesCount ( ) > 0 )
2003-06-09 18:59:14 +00:00
{
2003-06-10 04:35:09 +00:00
if ( ! version_product_v [ 0 ] )
2003-09-04 18:25:57 +00:00
{
2003-06-09 18:59:14 +00:00
ERROR_MSG ( " Error: VIProductVersion is required when other version information functions are used. \n " ) ;
return PS_ERROR ;
}
else
{
int imm , iml , ilm , ill ;
2003-06-10 04:35:09 +00:00
if ( sscanf ( version_product_v , " %d.%d.%d.%d " , & imm , & iml , & ilm , & ill ) ! = 4 )
2005-10-16 05:37:13 +00:00
{
2003-06-09 18:59:14 +00:00
ERROR_MSG ( " Error: invalid VIProductVersion format, should be X.X.X.X \n " ) ;
return PS_ERROR ;
}
2003-06-10 04:35:09 +00:00
rVersionInfo . SetFileVersion ( MAKELONG ( iml , imm ) , MAKELONG ( ill , ilm ) ) ;
rVersionInfo . SetProductVersion ( MAKELONG ( iml , imm ) , MAKELONG ( ill , ilm ) ) ;
2006-03-11 18:19:10 +00:00
try
2003-06-12 00:06:23 +00:00
{
2006-03-11 18:19:10 +00:00
init_res_editor ( ) ;
for ( int i = 0 ; i < rVersionInfo . GetStringTablesCount ( ) ; i + + )
{
LANGID lang_id = rVersionInfo . GetLangID ( i ) ;
int code_page = rVersionInfo . GetCodePage ( i ) ;
LanguageTable * Table = GetLangTable ( lang_id ) ;
if ( ! rVersionInfo . FindKey ( lang_id , code_page , " FileVersion " ) )
warning ( " Generating version information for language \" %04d-%s \" without standard key \" FileVersion \" " , lang_id , Table - > nlf . m_bLoaded ? Table - > nlf . m_szName : lang_id = = 1033 ? " English " : " ??? " ) ;
if ( ! rVersionInfo . FindKey ( lang_id , code_page , " FileDescription " ) )
warning ( " Generating version information for language \" %04d-%s \" without standard key \" FileDescription \" " , lang_id , Table - > nlf . m_bLoaded ? Table - > nlf . m_szName : lang_id = = 1033 ? " English " : " ??? " ) ;
if ( ! rVersionInfo . FindKey ( lang_id , code_page , " LegalCopyright " ) )
warning ( " Generating version information for language \" %04d-%s \" without standard key \" LegalCopyright \" " , lang_id , Table - > nlf . m_bLoaded ? Table - > nlf . m_szName : lang_id = = 1033 ? " English " : " ??? " ) ;
rVersionInfo . ExportToStream ( VerInfoStream , i ) ;
res_editor - > UpdateResource ( RT_VERSION , 1 , lang_id , ( BYTE * ) VerInfoStream . get ( ) , VerInfoStream . getlen ( ) ) ;
}
}
catch ( exception & err ) {
ERROR_MSG ( " Error adding version information: %s \n " , err . what ( ) ) ;
return PS_ERROR ;
2003-06-12 00:06:23 +00:00
}
2003-06-09 18:59:14 +00:00
}
}
2005-10-16 05:37:13 +00:00
2003-09-04 18:25:57 +00:00
return PS_OK ;
}
2003-06-09 18:59:14 +00:00
# endif // NSIS_SUPPORT_VERSION_INFO
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
int CEXEBuild : : ProcessPages ( )
{
SCRIPT_MSG ( " Processing pages... " ) ;
int license_normal = 0 ;
int license_fsrb = 0 ;
int license_fscb = 0 ;
int selcom = 0 ;
int dir = 0 , dir_used ;
int uninstconfirm = 0 ;
int instlog = 0 , instlog_used ;
int main = 0 ;
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
again :
# endif
dir_used = 0 ;
instlog_used = 0 ;
# ifdef NSIS_CONFIG_SILENT_SUPPORT
if ( ( cur_header - > flags & ( CH_FLAGS_SILENT | CH_FLAGS_SILENT_LOG ) ) = = 0 )
# endif
{
main + + ;
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
# define LS(inst, uninst) (uninstall_mode ? uninst : inst)
# else
# define LS(inst, uninst) inst
# endif
DefineInnerLangString ( NLF_BRANDING ) ;
if ( ! cur_pages - > getlen ( ) ) {
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( uninstall_mode ) {
if ( HasUserDefined ( NLF_UNINST_TEXT ) ) {
add_page ( PAGE_UNINSTCONFIRM ) ;
page_end ( ) ;
}
add_page ( PAGE_INSTFILES ) ;
page_end ( ) ;
add_page ( PAGE_COMPLETED ) ;
page_end ( ) ;
}
else
# endif
{
# ifdef NSIS_CONFIG_LICENSEPAGE
if ( HasUserDefined ( NLF_LICENSE_TEXT ) & & HasUserDefined ( NLF_LICENSE_DATA ) ) {
add_page ( PAGE_LICENSE ) ;
page_end ( ) ;
}
# endif
# ifdef NSIS_CONFIG_COMPONENTPAGE
if ( HasUserDefined ( NLF_COMP_TEXT ) ) {
add_page ( PAGE_COMPONENTS ) ;
page_end ( ) ;
}
# endif
if ( HasUserDefined ( NLF_DIR_TEXT ) ) {
add_page ( PAGE_DIRECTORY ) ;
page_end ( ) ;
}
add_page ( PAGE_INSTFILES ) ;
page_end ( ) ;
add_page ( PAGE_COMPLETED ) ;
page_end ( ) ;
}
}
// start processing the pages
{
int i = 0 ;
page * p = ( page * ) cur_pages - > get ( ) ;
2005-10-16 05:37:13 +00:00
2003-09-04 18:25:57 +00:00
for ( i = 0 ; i < cur_header - > blocks [ NB_PAGES ] . num ; i + + , p + + ) {
page * pp = 0 ;
if ( i ) {
pp = p - 1 ;
// set back button
p - > flags | = PF_BACK_SHOW ;
if ( pp - > wndproc_id ! = PWP_COMPLETED & & p - > wndproc_id ! = PWP_COMPLETED & & p - > wndproc_id ! = PWP_INSTFILES )
p - > flags | = PF_BACK_ENABLE ;
if ( ! p - > back )
p - > back = DefineInnerLangString ( NLF_BTN_BACK ) ;
// set previous page's next button
if ( ! pp - > next ) {
int str = 0 ;
# ifdef NSIS_CONFIG_LICENSEPAGE
if ( pp - > wndproc_id = = PWP_LICENSE & & ( ! ( pp - > flags & PF_LICENSE_FORCE_SELECTION ) | | HasUserDefined ( NLF_BTN_LICENSE ) ) )
str = NLF_BTN_LICENSE ;
else
# endif
if ( p - > wndproc_id = = PWP_INSTFILES )
str = LS ( NLF_BTN_INSTALL , NLF_BTN_UNINSTALL ) ;
else
str = NLF_BTN_NEXT ;
pp - > next = DefineInnerLangString ( str ) ;
}
// set previous page's click next text
if ( ! pp - > clicknext ) {
int str = 0 ;
if ( p - > wndproc_id = = PWP_INSTFILES )
str = LS ( NLF_CLICK_INSTALL , NLF_CLICK_UNINSTALL ) ;
else
str = NLF_CLICK_NEXT ;
pp - > clicknext = DefineInnerLangString ( str ) ;
}
}
// enable next button
if ( p - > wndproc_id ! = PWP_INSTFILES )
p - > flags | = PF_NEXT_ENABLE ;
// set cancel button
if ( ! p - > cancel )
p - > cancel = DefineInnerLangString ( NLF_BTN_CANCEL ) ;
if ( p - > wndproc_id ! = PWP_INSTFILES & & p - > wndproc_id ! = PWP_COMPLETED )
p - > flags | = PF_CANCEL_ENABLE ;
// set caption
struct {
int caption ;
int ucaption ;
} captions [ ] = {
# ifdef NSIS_CONFIG_LICENSEPAGE
{ NLF_SUBCAPTION_LICENSE , NLF_SUBCAPTION_LICENSE } ,
# endif
# ifdef NSIS_CONFIG_COMPONENTPAGE
{ NLF_SUBCAPTION_OPTIONS , NLF_SUBCAPTION_OPTIONS } ,
# endif
{ NLF_SUBCAPTION_DIR , NLF_SUBCAPTION_DIR } ,
{ NLF_SUBCAPTION_INSTFILES , NLF_USUBCAPTION_INSTFILES } ,
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
{ NLF_USUBCAPTION_CONFIRM , NLF_USUBCAPTION_CONFIRM } ,
# endif
{ NLF_SUBCAPTION_COMPLETED , NLF_USUBCAPTION_COMPLETED }
} ;
if ( ! p - > caption & & p - > wndproc_id ! = PWP_CUSTOM ) {
p - > caption = DefineInnerLangString ( LS ( captions [ p - > wndproc_id ] . caption , captions [ p - > wndproc_id ] . ucaption ) ) ;
}
// set texts
switch ( p - > dlg_id ) {
# ifdef NSIS_CONFIG_LICENSEPAGE
case IDD_LICENSE :
case IDD_LICENSE_FSRB :
case IDD_LICENSE_FSCB :
{
if ( ! ( p - > flags & PF_PAGE_EX ) )
p - > dlg_id = license_res_id ;
if ( ! ( p - > flags & ( PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION ) ) )
p - > dlg_id = license_res_id ;
p - > flags | = PF_NO_NEXT_FOCUS ;
if ( ! p - > parms [ 1 ] )
p - > parms [ 1 ] = DefineInnerLangString ( NLF_LICENSE_DATA , 0 ) ;
if ( p - > dlg_id = = IDD_LICENSE ) {
if ( ! p - > parms [ 0 ] )
p - > parms [ 0 ] = DefineInnerLangString ( LS ( NLF_LICENSE_TEXT , NLF_ULICENSE_TEXT ) ) ;
license_normal + + ;
}
else if ( p - > dlg_id = = IDD_LICENSE_FSCB ) {
p - > flags | = PF_LICENSE_FORCE_SELECTION ;
if ( ! p - > parms [ 0 ] )
p - > parms [ 0 ] = DefineInnerLangString ( LS ( NLF_LICENSE_TEXT_FSCB , NLF_ULICENSE_TEXT_FSCB ) ) ;
if ( ! p - > parms [ 2 ] )
p - > parms [ 2 ] = DefineInnerLangString ( NLF_BTN_LICENSE_AGREE ) ;
license_fscb + + ;
}
else if ( p - > dlg_id = = IDD_LICENSE_FSRB ) {
p - > flags | = PF_LICENSE_FORCE_SELECTION ;
if ( ! p - > parms [ 0 ] )
p - > parms [ 0 ] = DefineInnerLangString ( LS ( NLF_LICENSE_TEXT_FSRB , NLF_ULICENSE_TEXT_FSRB ) ) ;
if ( ! p - > parms [ 2 ] )
p - > parms [ 2 ] = DefineInnerLangString ( NLF_BTN_LICENSE_AGREE ) ;
if ( ! p - > parms [ 3 ] )
p - > parms [ 3 ] = DefineInnerLangString ( NLF_BTN_LICENSE_DISAGREE ) ;
license_fsrb + + ;
}
break ;
}
# endif
# ifdef NSIS_CONFIG_COMPONENTPAGE
case IDD_SELCOM :
{
if ( ! p - > parms [ 0 ] )
p - > parms [ 0 ] = DefineInnerLangString ( LS ( NLF_COMP_TEXT , NLF_UCOMP_TEXT ) ) ;
if ( ! p - > parms [ 1 ] )
p - > parms [ 1 ] = DefineInnerLangString ( LS ( NLF_COMP_SUBTEXT1 , NLF_UCOMP_SUBTEXT1 ) ) ;
if ( ! p - > parms [ 2 ] )
p - > parms [ 2 ] = DefineInnerLangString ( LS ( NLF_COMP_SUBTEXT2 , NLF_UCOMP_SUBTEXT2 ) ) ;
2003-09-23 19:01:19 +00:00
if ( ! p - > parms [ 3 ] & & ! uninstall_mode & & HasUserDefined ( NLF_COMP_SUBTEXT1 ) )
p - > parms [ 3 ] = p - > parms [ 1 ] ;
if ( ! p - > parms [ 4 ] & & ! uninstall_mode & & HasUserDefined ( NLF_COMP_SUBTEXT2 ) )
p - > parms [ 4 ] = p - > parms [ 2 ] ;
else if ( ! p - > parms [ 4 ] )
2003-09-04 18:25:57 +00:00
p - > parms [ 4 ] = DefineInnerLangString ( LS ( NLF_COMP_SUBTEXT1_NO_INST_TYPES , NLF_UCOMP_SUBTEXT1_NO_INST_TYPES ) ) ;
DefineInnerLangString ( NLF_SPACE_REQ ) ;
DefineInnerLangString ( NLF_BYTE ) ;
DefineInnerLangString ( NLF_KILO ) ;
DefineInnerLangString ( NLF_MEGA ) ;
DefineInnerLangString ( NLF_GIGA ) ;
selcom + + ;
break ;
}
# endif
case IDD_DIR :
{
if ( ! p - > parms [ 0 ] )
p - > parms [ 0 ] = DefineInnerLangString ( LS ( NLF_DIR_TEXT , NLF_UDIR_TEXT ) ) ;
if ( ! p - > parms [ 1 ] )
p - > parms [ 1 ] = DefineInnerLangString ( LS ( NLF_DIR_SUBTEXT , NLF_UDIR_SUBTEXT ) ) ;
if ( ! p - > parms [ 2 ] )
p - > parms [ 2 ] = DefineInnerLangString ( NLF_BTN_BROWSE ) ;
if ( ! p - > parms [ 3 ] )
p - > parms [ 3 ] = DefineInnerLangString ( LS ( NLF_DIR_BROWSETEXT , NLF_UDIR_BROWSETEXT ) ) ;
if ( ! p - > parms [ 4 ] )
p - > parms [ 4 ] = m_UserVarNames . get ( " INSTDIR " ) ;
else
p - > parms [ 4 ] - - ;
2003-09-05 10:40:31 +00:00
DefineInnerLangString ( NLF_SPACE_AVAIL ) ;
DefineInnerLangString ( NLF_SPACE_REQ ) ;
DefineInnerLangString ( NLF_BYTE ) ;
DefineInnerLangString ( NLF_KILO ) ;
DefineInnerLangString ( NLF_MEGA ) ;
2003-09-04 18:25:57 +00:00
DefineInnerLangString ( NLF_GIGA ) ;
# ifdef NSIS_CONFIG_LOG
DefineInnerLangString ( NLF_LOG_INSTALL_PROCESS ) ;
# endif
dir + + ;
break ;
}
case IDD_INSTFILES :
{
if ( ! p - > parms [ 1 ] )
p - > parms [ 1 ] = DefineInnerLangString ( NLF_BTN_DETAILS ) ;
if ( ! p - > parms [ 2 ] )
p - > parms [ 2 ] = DefineInnerLangString ( NLF_COMPLETED ) ;
DefineInnerLangString ( NLF_COPY_DETAILS ) ;
instlog + + ;
instlog_used + + ;
break ;
}
case IDD_UNINST :
{
if ( ! p - > parms [ 0 ] )
p - > parms [ 0 ] = DefineInnerLangString ( NLF_UNINST_TEXT ) ;
if ( ! p - > parms [ 1 ] )
p - > parms [ 1 ] = DefineInnerLangString ( NLF_UNINST_SUBTEXT ) ;
if ( ! p - > parms [ 4 ] )
p - > parms [ 4 ] = m_UserVarNames . get ( " INSTDIR " ) ;
else
p - > parms [ 4 ] - - ;
uninstconfirm + + ;
break ;
}
}
p - > flags & = ~ PF_PAGE_EX ;
}
p - - ;
if ( ! p - > next )
p - > next = DefineInnerLangString ( NLF_BTN_CLOSE ) ;
if ( p - > wndproc_id = = PWP_COMPLETED )
( p - 1 ) - > next = DefineInnerLangString ( NLF_BTN_CLOSE ) ;
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( uninstall_mode ) {
if ( ! uenable_last_page_cancel & & instlog_used )
p - > flags & = ~ PF_CANCEL_ENABLE ;
}
else
# endif
{
if ( ! enable_last_page_cancel & & instlog_used )
p - > flags & = ~ PF_CANCEL_ENABLE ;
}
if ( ! instlog_used ) {
warning ( " %sage instfiles not used, no sections will be executed! " , uninstall_mode ? " Uninstall p " : " P " ) ;
}
}
2003-09-08 13:54:01 +00:00
}
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( ! uninstall_mode ) {
set_uninstall_mode ( 1 ) ;
goto again ;
}
else
set_uninstall_mode ( 0 ) ;
# endif //NSIS_CONFIG_UNINSTALL_SUPPORT
2003-09-08 13:54:01 +00:00
2003-09-04 18:25:57 +00:00
SCRIPT_MSG ( " Done! \n " ) ;
2003-09-06 09:59:02 +00:00
# define REMOVE_ICON(id) if (disable_window_icon) { \
2004-03-29 20:21:00 +00:00
BYTE * dlg = res_editor - > GetResource ( RT_DIALOG , MAKEINTRESOURCE ( id ) , NSIS_DEFAULT_LANG ) ; \
2003-09-06 09:59:02 +00:00
if ( dlg ) { \
CDialogTemplate dt ( dlg , uDefCodePage ) ; \
2005-04-08 16:57:08 +00:00
res_editor - > FreeResource ( dlg ) ; \
2003-09-06 09:59:02 +00:00
if ( dt . RemoveItem ( IDC_ULICON ) ) { \
DialogItemTemplate * text = dt . GetItem ( IDC_INTROTEXT ) ; \
DialogItemTemplate * prog = dt . GetItem ( IDC_PROGRESS ) ; \
if ( text ) { \
text - > sWidth + = text - > sX ; \
text - > sX = 0 ; \
} \
if ( prog ) { \
prog - > sWidth + = prog - > sX ; \
prog - > sX = 0 ; \
} \
\
DWORD dwSize ; \
dlg = dt . Save ( dwSize ) ; \
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , MAKEINTRESOURCE ( id ) , NSIS_DEFAULT_LANG , dlg , dwSize ) ; \
2005-04-08 16:57:08 +00:00
delete [ ] dlg ; \
2003-09-06 09:59:02 +00:00
} \
} \
}
2003-09-04 18:25:57 +00:00
try {
SCRIPT_MSG ( " Removing unused resources... " ) ;
init_res_editor ( ) ;
# ifdef NSIS_CONFIG_LICENSEPAGE
if ( ! license_normal ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_LICENSE , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_LICENSE ) ;
2003-09-04 18:25:57 +00:00
if ( ! license_fsrb ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_LICENSE_FSRB , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_LICENSE_FSRB ) ;
2003-09-04 18:25:57 +00:00
if ( ! license_fscb ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_LICENSE_FSCB , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_LICENSE_FSCB ) ;
2003-09-04 18:25:57 +00:00
# endif // NSIS_CONFIG_LICENSEPAGE
# ifdef NSIS_CONFIG_COMPONENTPAGE
if ( ! selcom ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_SELCOM , NSIS_DEFAULT_LANG , 0 , 0 ) ;
res_editor - > UpdateResource ( RT_BITMAP , IDB_BITMAP1 , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_SELCOM ) ;
2003-09-04 18:25:57 +00:00
# endif // NSIS_CONFIG_COMPONENTPAGE
if ( ! dir ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_DIR , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_DIR ) ;
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( ! uninstconfirm ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_UNINST , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_UNINST ) ;
2003-09-04 18:25:57 +00:00
# endif // NSIS_CONFIG_UNINSTALL_SUPPORT
if ( ! instlog ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_INSTFILES , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
2003-09-06 09:59:02 +00:00
else REMOVE_ICON ( IDD_INSTFILES ) ;
2003-09-04 18:25:57 +00:00
if ( ! main ) {
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_INST , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
if ( ! build_compress_whole & & ! build_crcchk )
2004-03-29 20:21:00 +00:00
res_editor - > UpdateResource ( RT_DIALOG , IDD_VERIFY , NSIS_DEFAULT_LANG , 0 , 0 ) ;
2003-09-04 18:25:57 +00:00
}
SCRIPT_MSG ( " Done! \n " ) ;
}
catch ( exception & err ) {
ERROR_MSG ( " \n Error: %s \n " , err . what ( ) ) ;
return PS_ERROR ;
}
return PS_OK ;
}
# endif // NSIS_CONFIG_VISIBLE_SUPPORT
# ifdef NSIS_CONFIG_COMPONENTPAGE
2004-09-30 18:48:03 +00:00
void CEXEBuild : : PrepareInstTypes ( )
2003-09-04 18:25:57 +00:00
{
if ( ! ( cur_header - > flags & CH_FLAGS_NO_CUSTOM ) )
cur_header - > install_types [ NSIS_MAX_INST_TYPES ] = DefineInnerLangString ( NLF_COMP_CUSTOM ) ;
2003-11-24 19:36:15 +00:00
// set insttype list for RO sections that didn't use SectionIn
int i = cur_header - > blocks [ NB_SECTIONS ] . num ;
section * sections = ( section * ) cur_sections - > get ( ) ;
while ( i - - )
{
if ( sections [ i ] . flags & SF_RO & & ! sections [ i ] . install_types )
sections [ i ] . install_types = ~ 0 ;
}
// set selection to first insttype
2003-09-04 18:25:57 +00:00
if ( cur_header - > install_types [ 0 ] )
{
int i = cur_header - > blocks [ NB_SECTIONS ] . num ;
section * sections = ( section * ) cur_sections - > get ( ) ;
2003-11-24 19:36:15 +00:00
// if /o was used abort since the user did his manual choice
2003-09-04 18:25:57 +00:00
while ( i - - )
if ( ( sections [ i ] . flags & SF_SELECTED ) = = 0 )
return ;
i = cur_header - > blocks [ NB_SECTIONS ] . num ;
while ( i - - )
if ( ( sections [ i ] . install_types & 1 ) = = 0 )
sections [ i ] . flags & = ~ SF_SELECTED ;
}
}
# endif
2004-09-30 18:48:03 +00:00
void CEXEBuild : : PrepareHeaders ( IGrowBuf * hdrbuf )
2003-09-04 18:25:57 +00:00
{
2006-03-11 11:21:04 +00:00
GrowBuf blocks_buf ;
growbuf_writer_sink sink ( & blocks_buf ) ;
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2006-03-11 11:21:04 +00:00
cur_header - > blocks [ NB_PAGES ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
page_writer : : write_block ( cur_pages , & sink ) ;
# endif
cur_header - > blocks [ NB_SECTIONS ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
section_writer : : write_block ( cur_sections , & sink ) ;
cur_header - > blocks [ NB_ENTRIES ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
entry_writer : : write_block ( cur_entries , & sink ) ;
cur_header - > blocks [ NB_STRINGS ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
blocks_buf . add ( cur_strlist - > get ( ) , cur_strlist - > getlen ( ) ) ;
cur_header - > blocks [ NB_LANGTABLES ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
lang_table_writer : : write_block ( cur_langtables , & sink , cur_header - > langtable_size ) ;
cur_header - > blocks [ NB_CTLCOLORS ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
ctlcolors_writer : : write_block ( cur_ctlcolors , & sink ) ;
2004-06-11 15:33:00 +00:00
# ifdef NSIS_SUPPORT_BGBG
if ( cur_header - > bg_color1 ! = - 1 )
{
2006-03-11 11:21:04 +00:00
bg_font . lfFaceName [ LF_FACESIZE - 1 ] = 0 ;
cur_header - > blocks [ NB_BGFONT ] . offset = sizeof ( header ) + blocks_buf . getlen ( ) ;
LOGFONT_writer w ( & sink ) ;
w . write ( & bg_font ) ;
2004-06-11 15:33:00 +00:00
}
# endif
2003-09-04 18:25:57 +00:00
2006-03-11 11:21:04 +00:00
growbuf_writer_sink sink2 ( hdrbuf ) ;
header_writer header ( & sink2 ) ;
header . write ( cur_header ) ;
sink2 . write_growbuf ( & blocks_buf ) ;
2003-09-04 18:25:57 +00:00
}
2004-09-30 18:48:03 +00:00
int CEXEBuild : : check_write_output_errors ( ) const
2003-09-04 18:25:57 +00:00
{
2002-08-02 10:01:35 +00:00
if ( has_called_write_output )
{
ERROR_MSG ( " Error (write_output): write_output already called, can't continue \n " ) ;
return PS_ERROR ;
}
2004-09-30 18:48:03 +00:00
2002-08-02 10:01:35 +00:00
if ( ! build_output_filename [ 0 ] )
{
ERROR_MSG ( " Error: invalid script: never had OutFile command \n " ) ;
return PS_ERROR ;
}
2004-10-01 19:52:56 +00:00
if ( ! build_sections . getlen ( ) )
2002-08-02 10:01:35 +00:00
{
2004-10-01 19:52:56 +00:00
ERROR_MSG ( " Error: invalid script: no sections specified \n " ) ;
return PS_ERROR ;
2002-09-29 20:25:15 +00:00
}
2002-08-02 10:01:35 +00:00
if ( ! build_entries . getlen ( ) )
{
ERROR_MSG ( " Error: invalid script: no entries specified \n " ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
if ( build_cursection )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Error: Section left open at EOF \n " ) ;
return PS_ERROR ;
2002-08-31 23:44:58 +00:00
}
2002-08-02 10:01:35 +00:00
2005-01-10 12:43:52 +00:00
if ( sectiongroup_open_cnt )
2002-08-02 10:01:35 +00:00
{
2005-01-10 12:43:52 +00:00
ERROR_MSG ( " Error: SectionGroup left open at EOF \n " ) ;
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
if ( cur_page )
{
ERROR_MSG ( " Error: PageEx still open at EOF, cannot proceed \n " ) ;
2004-09-30 18:48:03 +00:00
return PS_ERROR ;
2003-09-04 18:25:57 +00:00
}
2002-08-02 10:01:35 +00:00
// deal with functions, for both install and uninstall modes.
if ( build_cursection_isfunc )
{
ERROR_MSG ( " Error: Function still open at EOF, cannot proceed \n " ) ;
2004-09-30 18:48:03 +00:00
return PS_ERROR ;
2002-08-02 10:01:35 +00:00
}
2004-09-30 18:48:03 +00:00
return PS_OK ;
}
2004-09-30 20:25:33 +00:00
int CEXEBuild : : prepare_uninstaller ( ) {
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( ubuild_entries . getlen ( ) )
{
if ( ! uninstaller_writes_used )
{
2002-08-21 16:23:29 +00:00
warning ( " Uninstall section found but WriteUninstaller never used - no uninstaller will be created. " ) ;
2004-09-30 20:25:33 +00:00
return PS_OK ;
2002-08-02 10:01:35 +00:00
}
2002-08-31 23:44:58 +00:00
2004-09-30 20:25:33 +00:00
build_uninst . flags | = build_header . flags & ( CH_FLAGS_PROGRESS_COLORED | CH_FLAGS_NO_ROOT_DIR ) ;
set_uninstall_mode ( 1 ) ;
DefineInnerLangString ( NLF_UCAPTION ) ;
if ( resolve_coderefs ( " uninstall " ) )
return PS_ERROR ;
2005-10-16 05:37:13 +00:00
# ifdef NSIS_CONFIG_COMPONENTPAGE
2004-09-30 20:25:33 +00:00
// set sections to the first insttype
PrepareInstTypes ( ) ;
2003-09-04 18:25:57 +00:00
# endif
2004-09-30 20:25:33 +00:00
set_uninstall_mode ( 0 ) ;
2002-08-02 10:01:35 +00:00
}
else if ( uninstaller_writes_used )
{
ERROR_MSG ( " Error: no Uninstall section specified, but WriteUninstaller used %d time(s) \n " , uninstaller_writes_used ) ;
return PS_ERROR ;
}
2004-09-30 20:25:33 +00:00
# endif //NSIS_CONFIG_UNINSTALL_SUPPORT
return PS_OK ;
}
int CEXEBuild : : pack_exe_header ( )
{
if ( ! ( build_packname [ 0 ] & & build_packcmd [ 0 ] ) ) {
// header not asked to be packed
return PS_OK ;
}
2004-10-02 18:04:41 +00:00
// write out exe header, pack, read back in, and
2004-09-30 20:25:33 +00:00
// update the header info
FILE * tmpfile = FOPEN ( build_packname , " wb " ) ;
if ( ! tmpfile )
{
ERROR_MSG ( " Error: writing temporary file \" %s \" for pack \n " , build_packname ) ;
return PS_ERROR ;
}
2004-10-02 18:04:41 +00:00
fwrite ( m_exehead , 1 , m_exehead_size , tmpfile ) ;
2004-09-30 20:25:33 +00:00
fclose ( tmpfile ) ;
if ( system ( build_packcmd ) = = - 1 )
{
remove ( build_packname ) ;
ERROR_MSG ( " Error: calling packer on \" %s \" \n " , build_packname ) ;
return PS_ERROR ;
}
2005-04-02 12:04:07 +00:00
int result = update_exehead ( build_packname ) ;
remove ( build_packname ) ;
if ( result ! = PS_OK )
2004-09-30 20:25:33 +00:00
{
ERROR_MSG ( " Error: reading temporary file \" %s \" after pack \n " , build_packname ) ;
2005-04-02 12:04:07 +00:00
return result ;
2004-09-30 20:25:33 +00:00
}
2004-10-02 18:04:41 +00:00
2004-09-30 20:25:33 +00:00
return PS_OK ;
}
int CEXEBuild : : write_output ( void )
{
# ifndef NSIS_CONFIG_CRC_SUPPORT
build_crcchk = 0 ;
2002-08-02 10:01:35 +00:00
# endif
2004-09-30 20:25:33 +00:00
RET_UNLESS_OK ( check_write_output_errors ( ) ) ;
has_called_write_output = true ;
# ifdef NSIS_CONFIG_PLUGIN_SUPPORT
RET_UNLESS_OK ( add_plugins_dir_initializer ( ) ) ;
# endif //NSIS_CONFIG_PLUGIN_SUPPORT
# ifdef NSIS_SUPPORT_VERSION_INFO
RET_UNLESS_OK ( AddVersionInfo ( ) ) ;
# endif //NSIS_SUPPORT_VERSION_INFO
RET_UNLESS_OK ( prepare_uninstaller ( ) ) ;
2003-09-20 10:03:02 +00:00
DefineInnerLangString ( NLF_CAPTION ) ;
2003-09-04 18:25:57 +00:00
if ( resolve_coderefs ( " install " ) )
return PS_ERROR ;
2003-05-24 13:50:24 +00:00
2004-01-04 17:25:59 +00:00
# ifdef NSIS_CONFIG_COMPONENTPAGE
2003-09-04 18:25:57 +00:00
// set sections to the first insttype
2004-09-30 18:48:03 +00:00
PrepareInstTypes ( ) ;
2002-11-01 20:34:55 +00:00
# endif
2002-08-02 10:01:35 +00:00
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2004-09-30 20:25:33 +00:00
RET_UNLESS_OK ( ProcessPages ( ) ) ;
2003-09-04 18:25:57 +00:00
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
2002-08-02 16:51:42 +00:00
2003-04-21 13:32:34 +00:00
// Generate language tables
2004-09-30 20:25:33 +00:00
RET_UNLESS_OK ( GenerateLangTables ( ) ) ;
2003-04-21 13:32:34 +00:00
2002-11-09 13:51:40 +00:00
try {
2006-03-11 18:19:10 +00:00
init_res_editor ( ) ;
VerifyDeclaredUserVarRefs ( & m_UserVarNames ) ;
int MaxUserVars = m_UserVarNames . getnum ( ) ;
// -1 because the default size is 1
if ( ! res_editor - > AddExtraVirtualSize2PESection ( NSIS_VARS_SECTION , ( MaxUserVars - 1 ) * sizeof ( NSIS_STRING ) ) )
{
ERROR_MSG ( " Internal compiler error #12346: invalid exehead cannot find section \" %s \" ! \n " , NSIS_VARS_SECTION ) ;
return PS_ERROR ;
}
// Save all changes to the exe header
2003-06-23 22:40:11 +00:00
close_res_editor ( ) ;
2002-11-09 13:51:40 +00:00
}
catch ( exception & err ) {
ERROR_MSG ( " \n Error: %s \n " , err . what ( ) ) ;
return PS_ERROR ;
}
2004-09-30 20:25:33 +00:00
RET_UNLESS_OK ( pack_exe_header ( ) ) ;
2002-08-02 10:01:35 +00:00
build_optimize_datablock = 0 ;
2003-07-19 12:15:10 +00:00
int data_block_size_before_uninst = build_datablock . getlen ( ) ;
2004-09-30 20:25:33 +00:00
RET_UNLESS_OK ( uninstall_generate ( ) ) ;
2002-08-02 10:01:35 +00:00
int crc = 0 ;
{
2004-09-30 20:25:33 +00:00
string full_path = get_full_path ( build_output_filename ) ;
notify ( MAKENSIS_NOTIFY_OUTPUT , full_path . c_str ( ) ) ;
INFO_MSG ( " \n Output: \" %s \" \n " , full_path . c_str ( ) ) ;
2002-08-02 10:01:35 +00:00
}
2004-09-30 20:25:33 +00:00
2004-08-20 15:40:38 +00:00
FILE * fp = FOPEN ( build_output_filename , " w+b " ) ;
2002-08-31 23:44:58 +00:00
if ( ! fp )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Can't open output file \n " ) ;
return PS_ERROR ;
}
2004-10-02 18:04:41 +00:00
if ( fwrite ( m_exehead , 1 , m_exehead_size , fp ) ! = m_exehead_size )
2002-08-02 10:01:35 +00:00
{
2004-10-02 18:04:41 +00:00
ERROR_MSG ( " Error: can't write %d bytes to output \n " , m_exehead_size ) ;
2002-08-02 10:01:35 +00:00
fclose ( fp ) ;
return PS_ERROR ;
}
2003-09-04 18:25:57 +00:00
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
# ifdef NSIS_CONFIG_CRC_ANAL
2004-10-02 18:04:41 +00:00
crc = CRC32 ( crc , m_exehead , m_exehead_size ) ;
2002-08-02 10:01:35 +00:00
# else
2004-10-02 18:04:41 +00:00
crc = CRC32 ( crc , m_exehead + 512 , m_exehead_size - 512 ) ;
2002-08-02 10:01:35 +00:00
# endif
# endif
firstheader fh = { 0 , } ;
fh . nsinst [ 0 ] = FH_INT1 ;
fh . nsinst [ 1 ] = FH_INT2 ;
fh . nsinst [ 2 ] = FH_INT3 ;
2004-01-29 01:23:24 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
2003-07-18 14:22:17 +00:00
fh . flags = ( build_crcchk ? ( build_crcchk = = 2 ? FH_FLAGS_FORCE_CRC : 0 ) : FH_FLAGS_NO_CRC ) ;
2004-01-29 01:23:24 +00:00
# else
fh . flags = 0 ;
# endif
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_SILENT_SUPPORT
2003-09-04 18:25:57 +00:00
if ( build_header . flags & ( CH_FLAGS_SILENT | CH_FLAGS_SILENT_LOG ) ) fh . flags | = FH_FLAGS_SILENT ;
2002-08-02 10:01:35 +00:00
# endif
fh . siginfo = FH_SIG ;
int installinfo_compressed ;
2004-03-12 20:43:54 +00:00
int fd_start = 0 ;
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2002-08-02 10:01:35 +00:00
if ( build_compress_whole )
{
2004-10-11 14:26:13 +00:00
int n = compressor - > Init ( build_compress_level , build_compress_dict_size ) ;
2003-11-24 00:08:58 +00:00
if ( n ! = C_OK )
2002-08-02 10:01:35 +00:00
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Internal compiler error #12345: deflateInit() failed(%s [%d]). \n " , compressor - > GetErrStr ( n ) , n ) ;
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
}
}
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
{
GrowBuf ihd ;
{
GrowBuf hdrcomp ;
2004-09-30 18:48:03 +00:00
PrepareHeaders ( & hdrcomp ) ;
2003-09-04 18:25:57 +00:00
if ( add_data ( ( char * ) hdrcomp . get ( ) , hdrcomp . getlen ( ) , & ihd ) < 0 )
return PS_ERROR ;
2002-08-31 23:44:58 +00:00
2002-08-02 10:01:35 +00:00
fh . length_of_header = hdrcomp . getlen ( ) ;
2003-09-04 18:25:57 +00:00
installinfo_compressed = ihd . getlen ( ) ;
2002-08-02 10:01:35 +00:00
}
if ( ! build_compress_whole )
fh . length_of_all_following_data = ihd . getlen ( ) + build_datablock . getlen ( ) + ( int ) sizeof ( firstheader ) + ( build_crcchk ? sizeof ( int ) : 0 ) ;
else
fd_start = ftell ( fp ) ;
2006-03-11 11:21:04 +00:00
try
{
file_writer_sink sink ( fp ) ;
firstheader_writer w ( & sink ) ;
w . write ( & fh ) ;
}
catch ( . . . )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Error: can't write %d bytes to output \n " , sizeof ( fh ) ) ;
fclose ( fp ) ;
return PS_ERROR ;
}
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2002-08-02 10:01:35 +00:00
if ( build_compress_whole ) {
if ( deflateToFile ( fp , ( char * ) ihd . get ( ) , ihd . getlen ( ) ) )
{
fclose ( fp ) ;
return PS_ERROR ;
}
}
2005-10-16 05:37:13 +00:00
else
2002-09-18 19:08:53 +00:00
# endif
{
2002-08-02 10:01:35 +00:00
if ( fwrite ( ihd . get ( ) , 1 , ihd . getlen ( ) , fp ) ! = ( unsigned int ) ihd . getlen ( ) )
{
ERROR_MSG ( " Error: can't write %d bytes to output \n " , ihd . getlen ( ) ) ;
fclose ( fp ) ;
return PS_ERROR ;
}
# ifdef NSIS_CONFIG_CRC_SUPPORT
2006-03-11 11:21:04 +00:00
crc_writer_sink crc_sink ( ( unsigned long * ) & crc ) ;
firstheader_writer w ( & crc_sink ) ;
w . write ( & fh ) ;
2002-08-02 10:01:35 +00:00
crc = CRC32 ( crc , ( unsigned char * ) ihd . get ( ) , ihd . getlen ( ) ) ;
# endif
}
}
2003-07-19 12:15:10 +00:00
INFO_MSG ( " Install: " ) ;
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
int np = build_header . blocks [ NB_PAGES ] . num ;
INFO_MSG ( " %d page%s (%d bytes), " , np , np = = 1 ? " " : " s " , np * sizeof ( page ) ) ;
# endif
2002-08-02 10:01:35 +00:00
{
int ns = build_sections . getlen ( ) / sizeof ( section ) ;
section * s = ( section * ) build_sections . get ( ) ;
int x ;
2002-08-22 21:06:07 +00:00
int req = 0 ;
2002-08-02 10:01:35 +00:00
for ( x = 1 ; x < ns ; x + + )
{
2002-10-02 15:01:06 +00:00
if ( ! s [ x ] . name_ptr | | s [ x ] . flags & SF_RO ) req + + ;
2002-08-02 10:01:35 +00:00
}
2003-07-19 12:15:10 +00:00
INFO_MSG ( " %d section%s " , ns , ns = = 1 ? " " : " s " ) ;
2002-08-22 21:06:07 +00:00
if ( req )
2002-08-02 10:01:35 +00:00
{
2002-08-22 21:06:07 +00:00
INFO_MSG ( " (%d required) " , req ) ;
2002-08-02 10:01:35 +00:00
}
2003-07-19 12:15:10 +00:00
INFO_MSG ( " (%d bytes), " , build_sections . getlen ( ) ) ;
2002-08-02 10:01:35 +00:00
}
2003-09-04 18:25:57 +00:00
int ne = build_header . blocks [ NB_ENTRIES ] . num ;
2003-07-19 12:15:10 +00:00
INFO_MSG ( " %d instruction%s (%d bytes), " , ne , ne = = 1 ? " " : " s " , ne * sizeof ( entry ) ) ;
2002-11-09 13:08:45 +00:00
int ns = build_strlist . getnum ( ) ;
INFO_MSG ( " %d string%s (%d bytes), " , ns , ns = = 1 ? " " : " s " , build_strlist . getlen ( ) ) ;
2003-09-04 18:25:57 +00:00
int nlt = build_header . blocks [ NB_LANGTABLES ] . num ;
INFO_MSG ( " %d language table%s (%d bytes). \n " , nlt , nlt = = 1 ? " " : " s " , build_langtables . getlen ( ) ) ;
2002-08-31 23:44:58 +00:00
if ( ubuild_entries . getlen ( ) )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
INFO_MSG ( " Uninstall: " ) ;
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
np = build_uninst . blocks [ NB_PAGES ] . num ;
INFO_MSG ( " %d page%s (%d bytes), \n " , np , np = = 1 ? " " : " s " , ubuild_pages . getlen ( ) ) ;
# endif
{
int ns = ubuild_sections . getlen ( ) / sizeof ( section ) ;
section * s = ( section * ) ubuild_sections . get ( ) ;
int x ;
int req = 0 ;
for ( x = 1 ; x < ns ; x + + )
{
if ( ! s [ x ] . name_ptr | | s [ x ] . flags & SF_RO ) req + + ;
}
INFO_MSG ( " %d section%s " , ns , ns = = 1 ? " " : " s " ) ;
if ( req )
{
INFO_MSG ( " (%d required) " , req ) ;
}
INFO_MSG ( " (%d bytes), " , ubuild_sections . getlen ( ) ) ;
}
ne = build_uninst . blocks [ NB_ENTRIES ] . num ;
INFO_MSG ( " %d instruction%s (%d bytes), " , ne , ne = = 1 ? " " : " s " , ubuild_entries . getlen ( ) ) ;
2002-11-09 13:08:45 +00:00
ns = ubuild_strlist . getnum ( ) ;
INFO_MSG ( " %d string%s (%d bytes), " , ns , ns = = 1 ? " " : " s " , ubuild_strlist . getlen ( ) ) ;
2003-09-04 18:25:57 +00:00
nlt = build_uninst . blocks [ NB_LANGTABLES ] . num ;
INFO_MSG ( " %d language table%s (%d bytes). \n " , nlt , nlt = = 1 ? " " : " s " , ubuild_langtables . getlen ( ) ) ;
2002-08-02 10:01:35 +00:00
}
2002-08-31 23:44:58 +00:00
if ( db_opt_save )
2002-08-02 10:01:35 +00:00
{
int total_out_size_estimate =
2004-10-02 18:04:41 +00:00
m_exehead_size + sizeof ( fh ) + build_datablock . getlen ( ) + ( build_crcchk ? sizeof ( int ) : 0 ) ;
2004-03-29 20:21:00 +00:00
# ifdef _WIN32
2002-08-02 10:01:35 +00:00
int pc = MulDiv ( db_opt_save , 1000 , db_opt_save + total_out_size_estimate ) ;
2004-03-29 20:21:00 +00:00
# else
int pc = ( int ) ( ( ( long long ) db_opt_save * 1000 ) / ( db_opt_save + total_out_size_estimate ) ) ;
# endif
2002-08-02 10:01:35 +00:00
INFO_MSG ( " Datablock optimizer saved %d bytes (~%d.%d%%). \n " , db_opt_save ,
pc / 10 , pc % 10 ) ;
}
2003-02-10 18:43:40 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2003-02-07 23:04:25 +00:00
INFO_MSG ( " \n Using %s%s compression. \n \n " , compressor - > GetName ( ) , build_compress_whole ? " (compress whole) " : " " ) ;
2003-02-10 18:43:40 +00:00
# endif
2002-08-02 10:01:35 +00:00
2005-04-02 12:04:07 +00:00
int total_usize = m_exehead_original_size ;
2002-08-02 10:01:35 +00:00
2005-04-02 12:04:07 +00:00
INFO_MSG ( " EXE header size: %10d / %d bytes \n " , m_exehead_size , m_exehead_original_size ) ;
2002-08-02 10:01:35 +00:00
if ( build_compress_whole ) {
2002-10-02 04:32:10 +00:00
INFO_MSG ( " Install code: (%d bytes) \n " ,
2003-07-19 12:15:10 +00:00
sizeof ( fh ) + fh . length_of_header ) ;
2002-08-02 10:01:35 +00:00
}
else {
2002-10-02 04:32:10 +00:00
INFO_MSG ( " Install code: %10d / %d bytes \n " ,
2002-08-02 10:01:35 +00:00
sizeof ( fh ) + installinfo_compressed ,
2003-07-19 12:15:10 +00:00
sizeof ( fh ) + fh . length_of_header ) ;
2002-08-02 10:01:35 +00:00
}
2003-07-19 12:15:10 +00:00
total_usize + = sizeof ( fh ) + fh . length_of_header ;
2002-08-02 10:01:35 +00:00
{
int dbsize , dbsizeu ;
dbsize = build_datablock . getlen ( ) ;
if ( uninstall_size > 0 ) dbsize - = uninstall_size ;
if ( build_compress_whole ) {
dbsizeu = dbsize ;
INFO_MSG ( " Install data: (%d bytes) \n " , dbsizeu ) ;
}
else {
dbsizeu = db_full_size - uninstall_size_full ;
INFO_MSG ( " Install data: %10d / %d bytes \n " , dbsize , dbsizeu ) ;
}
total_usize + = dbsizeu ;
}
2002-08-31 23:44:58 +00:00
if ( uninstall_size > = 0 )
2002-08-02 10:01:35 +00:00
{
if ( build_compress_whole )
2002-10-02 04:32:10 +00:00
INFO_MSG ( " Uninstall code+data: (%d bytes) \n " , uninstall_size_full ) ;
2002-08-02 10:01:35 +00:00
else
2002-10-02 04:32:10 +00:00
INFO_MSG ( " Uninstall code+data: %6d / %d bytes \n " , uninstall_size , uninstall_size_full ) ;
2002-08-02 10:01:35 +00:00
total_usize + = uninstall_size_full ;
}
2003-07-19 12:15:10 +00:00
if ( build_compress_whole ) {
INFO_MSG ( " Compressed data: " ) ;
}
2002-08-02 10:01:35 +00:00
if ( build_datablock . getlen ( ) )
{
2003-09-15 22:05:06 +00:00
build_datablock . setro ( TRUE ) ;
int dbl = build_datablock . getlen ( ) ;
int left = dbl ;
while ( left > 0 )
2002-08-02 10:01:35 +00:00
{
2003-09-15 22:05:06 +00:00
int l = min ( build_filebuflen , left ) ;
char * dbptr = ( char * ) build_datablock . get ( dbl - left , l ) ;
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2003-11-24 00:08:58 +00:00
if ( build_compress_whole )
{
2002-08-02 10:01:35 +00:00
if ( deflateToFile ( fp , dbptr , l ) )
{
fclose ( fp ) ;
return PS_ERROR ;
}
}
2005-10-16 05:37:13 +00:00
else
2002-09-18 19:08:53 +00:00
# endif
{
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
crc = CRC32 ( crc , ( unsigned char * ) dbptr , l ) ;
# endif
if ( ( int ) fwrite ( dbptr , 1 , l , fp ) ! = l )
{
ERROR_MSG ( " Error: can't write %d bytes to output \n " , l ) ;
fclose ( fp ) ;
return PS_ERROR ;
}
2003-09-15 22:05:06 +00:00
fflush ( fp ) ;
2002-08-02 10:01:35 +00:00
}
2003-09-15 22:05:06 +00:00
build_datablock . release ( ) ;
left - = l ;
2002-08-02 10:01:35 +00:00
}
2003-09-15 22:05:06 +00:00
build_datablock . setro ( FALSE ) ;
build_datablock . clear ( ) ;
2002-08-02 10:01:35 +00:00
}
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2005-10-16 05:37:13 +00:00
if ( build_compress_whole )
2002-09-18 19:08:53 +00:00
{
2002-08-02 10:01:35 +00:00
if ( deflateToFile ( fp , NULL , 0 ) )
{
fclose ( fp ) ;
return PS_ERROR ;
}
compressor - > End ( ) ;
2004-02-03 13:44:03 +00:00
unsigned fend = ftell ( fp ) ;
2003-07-19 12:15:10 +00:00
fh . length_of_all_following_data = ftell ( fp ) - fd_start + ( build_crcchk ? sizeof ( int ) : 0 ) ;
INFO_MSG (
" %10d / %d bytes \n " ,
ftell ( fp ) - fd_start ,
data_block_size_before_uninst + fh . length_of_header + sizeof ( firstheader ) + uninstall_size_full
) ;
2002-08-02 10:01:35 +00:00
fseek ( fp , fd_start , SEEK_SET ) ;
2006-03-11 11:21:04 +00:00
try
{
file_writer_sink sink ( fp ) ;
firstheader_writer w ( & sink ) ;
w . write ( & fh ) ;
}
catch ( . . . )
{
ERROR_MSG ( " Error: can't write %d bytes to output \n " , sizeof ( fh ) ) ;
fclose ( fp ) ;
return PS_ERROR ;
}
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
if ( build_crcchk )
{
// check rest of CRC
fseek ( fp , fd_start , SEEK_SET ) ;
for ( ; ; )
{
char buf [ 32768 ] ;
int l = fread ( buf , 1 , sizeof ( buf ) , fp ) ;
if ( ! l ) break ;
crc = CRC32 ( crc , ( unsigned char * ) buf , l ) ;
}
}
# endif
2004-02-03 13:44:03 +00:00
fseek ( fp , fend , SEEK_SET ) ; // reset eof flag
2002-08-02 10:01:35 +00:00
}
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
2002-08-31 23:44:58 +00:00
if ( build_crcchk )
2002-08-02 10:01:35 +00:00
{
total_usize + = sizeof ( int ) ;
2006-03-11 11:22:02 +00:00
int rcrc = FIX_ENDIAN_INT32 ( crc ) ;
if ( fwrite ( & rcrc , 1 , sizeof ( int ) , fp ) ! = sizeof ( int ) )
2002-08-02 10:01:35 +00:00
{
ERROR_MSG ( " Error: can't write %d bytes to output \n " , sizeof ( int ) ) ;
fclose ( fp ) ;
return PS_ERROR ;
}
INFO_MSG ( " CRC (0x%08X): 4 / 4 bytes \n " , crc ) ;
}
INFO_MSG ( " \n " ) ;
{
2004-03-29 20:21:00 +00:00
# ifdef _WIN32
2002-08-02 10:01:35 +00:00
int pc = MulDiv ( ftell ( fp ) , 1000 , total_usize ) ;
2004-03-29 20:21:00 +00:00
# else
int pc = ( int ) ( ( ( long long ) ftell ( fp ) * 1000 ) / ( total_usize ) ) ;
# endif
2002-08-02 10:01:35 +00:00
INFO_MSG ( " Total size: %10d / %d bytes (%d.%d%%) \n " ,
ftell ( fp ) , total_usize , pc / 10 , pc % 10 ) ;
}
fclose ( fp ) ;
print_warnings ( ) ;
return PS_OK ;
}
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2002-08-02 10:01:35 +00:00
int CEXEBuild : : deflateToFile ( FILE * fp , char * buf , int len ) // len==0 to flush
{
build_compressor_set = true ;
2003-09-15 22:05:06 +00:00
char obuf [ 65536 ] ;
2004-10-10 20:58:33 +00:00
bool flush = false ;
2002-08-02 10:01:35 +00:00
compressor - > SetNextIn ( buf , len ) ;
2002-08-31 23:44:58 +00:00
if ( ! buf | | ! len )
2002-08-02 10:01:35 +00:00
{
char a ;
compressor - > SetNextIn ( & a , 0 ) ;
flush = C_FINISH ;
}
for ( ; ; )
{
compressor - > SetNextOut ( obuf , sizeof ( obuf ) ) ;
int ret = compressor - > Compress ( flush ) ;
if ( ret < 0 & & ( ret ! = - 1 | | ! flush ) )
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Error: deflateToFile: deflate() failed(%s [%d]) \n " , compressor - > GetErrStr ( ret ) , ret ) ;
2002-08-02 10:01:35 +00:00
return 1 ;
}
int l = compressor - > GetNextOut ( ) - obuf ;
if ( l )
{
if ( fwrite ( obuf , 1 , l , fp ) ! = ( unsigned ) l )
{
ERROR_MSG ( " Error: deflateToFile fwrite(%d) failed \n " , l ) ;
return 1 ;
}
2003-09-15 22:05:06 +00:00
fflush ( fp ) ;
2002-08-02 10:01:35 +00:00
}
if ( ! compressor - > GetAvailIn ( ) & & ( ! flush | | ! l ) ) break ;
}
return 0 ;
}
2002-09-18 19:08:53 +00:00
# endif
2002-08-02 10:01:35 +00:00
int CEXEBuild : : uninstall_generate ( )
{
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
2002-08-31 23:44:58 +00:00
if ( ubuild_entries . getlen ( ) & & uninstaller_writes_used )
2002-08-02 10:01:35 +00:00
{
2003-09-15 22:05:06 +00:00
SCRIPT_MSG ( " Generating uninstaller... " ) ;
2002-08-02 10:01:35 +00:00
firstheader fh = { 0 , } ;
GrowBuf uhd ;
{
GrowBuf udata ;
set_uninstall_mode ( 1 ) ;
2003-09-04 18:25:57 +00:00
2004-09-30 18:48:03 +00:00
PrepareHeaders ( & udata ) ;
2003-09-04 18:25:57 +00:00
2002-08-02 10:01:35 +00:00
fh . length_of_header = udata . getlen ( ) ;
2002-08-31 23:44:58 +00:00
int err = add_data ( ( char * ) udata . get ( ) , udata . getlen ( ) , & uhd ) ;
2002-08-02 10:01:35 +00:00
set_uninstall_mode ( 0 ) ;
if ( err < 0 ) return PS_ERROR ;
}
2002-08-31 23:44:58 +00:00
2002-08-02 10:01:35 +00:00
int crc = 0 ;
2003-09-15 22:05:06 +00:00
// Get offsets of icons to replace for uninstall
// Also makes sure that the icons are there and in the right size.
2006-03-25 19:31:54 +00:00
if ( generate_unicons_offsets ( m_exehead , m_exehead_size , m_unicon_data ) = = 0 )
2003-09-15 22:05:06 +00:00
return PS_ERROR ;
2003-11-24 13:11:35 +00:00
entry * ent = ( entry * ) build_entries . get ( ) ;
if ( ! ent )
return PS_ERROR ;
int ents = build_header . blocks [ NB_ENTRIES ] . num ;
int uns = uninstaller_writes_used ;
int uninstdata_offset = build_datablock . getlen ( ) ;
while ( ents - - )
{
if ( ent - > which = = EW_WRITEUNINSTALLER )
{
ent - > offsets [ 1 ] = uninstdata_offset ;
2005-04-02 12:04:07 +00:00
ent - > offsets [ 2 ] = m_unicon_size ;
2003-11-24 13:11:35 +00:00
uns - - ;
if ( ! uns )
break ;
}
ent + + ;
}
2002-08-02 10:01:35 +00:00
2005-04-02 12:04:07 +00:00
if ( add_db_data ( ( char * ) m_unicon_data , m_unicon_size ) < 0 )
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
2004-10-02 18:04:41 +00:00
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
2003-12-08 09:32:30 +00:00
{
// "create" the uninstaller
2004-10-02 18:04:41 +00:00
LPBYTE uninst_header = ( LPBYTE ) malloc ( m_exehead_size ) ;
2003-12-08 09:32:30 +00:00
if ( ! uninst_header )
return PS_ERROR ;
2004-10-02 18:04:41 +00:00
memcpy ( uninst_header , m_exehead , m_exehead_size ) ;
2003-12-08 09:32:30 +00:00
// patch the icons
LPBYTE seeker = m_unicon_data ;
while ( * seeker ) {
2006-03-25 19:31:54 +00:00
DWORD dwSize = FIX_ENDIAN_INT32 ( * ( LPDWORD ) seeker ) ;
2003-12-08 09:32:30 +00:00
seeker + = sizeof ( DWORD ) ;
2006-03-25 19:31:54 +00:00
DWORD dwOffset = FIX_ENDIAN_INT32 ( * ( LPDWORD ) seeker ) ;
2003-12-08 09:32:30 +00:00
seeker + = sizeof ( DWORD ) ;
memcpy ( uninst_header + dwOffset , seeker , dwSize ) ;
seeker + = dwSize ;
2002-08-02 10:01:35 +00:00
}
2003-12-08 09:32:30 +00:00
# ifdef NSIS_CONFIG_CRC_ANAL
2004-10-02 18:04:41 +00:00
crc = CRC32 ( crc , uninst_header , m_exehead_size ) ;
2003-12-08 09:32:30 +00:00
# else
2004-10-02 18:04:41 +00:00
crc = CRC32 ( crc , uninst_header + 512 , m_exehead_size - 512 ) ;
2003-12-08 09:32:30 +00:00
# endif
free ( uninst_header ) ;
2002-08-02 10:01:35 +00:00
}
# endif
fh . nsinst [ 0 ] = FH_INT1 ;
fh . nsinst [ 1 ] = FH_INT2 ;
fh . nsinst [ 2 ] = FH_INT3 ;
2003-09-04 18:25:57 +00:00
fh . flags = FH_FLAGS_UNINSTALL ;
2005-03-05 16:56:41 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
2003-09-04 18:25:57 +00:00
fh . flags | = ( build_crcchk ? ( build_crcchk = = 2 ? FH_FLAGS_FORCE_CRC : 0 ) : FH_FLAGS_NO_CRC ) ;
2005-03-05 16:56:41 +00:00
# endif
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_SILENT_SUPPORT
2003-09-04 18:25:57 +00:00
if ( build_uninst . flags & ( CH_FLAGS_SILENT | CH_FLAGS_SILENT_LOG ) ) fh . flags | = FH_FLAGS_SILENT ;
2002-08-02 10:01:35 +00:00
# endif
fh . siginfo = FH_SIG ;
fh . length_of_all_following_data =
uhd . getlen ( ) + ubuild_datablock . getlen ( ) + ( int ) sizeof ( firstheader ) + ( build_crcchk ? sizeof ( int ) : 0 ) ;
2003-09-15 22:05:06 +00:00
MMapBuf udata ;
2006-03-25 19:43:25 +00:00
{
growbuf_writer_sink sink ( & udata ) ;
firstheader_writer w ( & sink ) ;
w . write ( & fh ) ;
}
2003-09-15 22:05:06 +00:00
ubuild_datablock . setro ( TRUE ) ;
2002-08-02 10:01:35 +00:00
2002-09-22 18:48:58 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2002-08-02 10:01:35 +00:00
if ( build_compress_whole ) {
// compress uninstaller too
{
2003-09-15 22:05:06 +00:00
char obuf [ 65536 ] ;
2004-10-11 14:26:13 +00:00
int n = compressor - > Init ( build_compress_level , build_compress_dict_size ) ;
2003-11-24 00:08:58 +00:00
if ( n ! = C_OK )
2002-08-02 10:01:35 +00:00
{
2005-01-18 17:56:58 +00:00
ERROR_MSG ( " Internal compiler error #12345: deflateInit() failed(%s [%d]). \n " , compressor - > GetErrStr ( n ) , n ) ;
2003-11-24 00:08:58 +00:00
extern void quit ( ) ; quit ( ) ;
2002-08-02 10:01:35 +00:00
}
2003-09-15 22:05:06 +00:00
compressor - > SetNextIn ( ( char * ) uhd . get ( ) , uhd . getlen ( ) ) ;
while ( compressor - > GetAvailIn ( ) )
2002-08-02 10:01:35 +00:00
{
2003-09-15 22:05:06 +00:00
compressor - > SetNextOut ( obuf , sizeof ( obuf ) ) ;
compressor - > Compress ( 0 ) ;
if ( compressor - > GetNextOut ( ) - obuf > 0 )
{
udata . add ( obuf , compressor - > GetNextOut ( ) - obuf ) ;
}
}
int avail_in = ubuild_datablock . getlen ( ) ;
int in_pos = 0 ;
while ( avail_in > 0 ) {
int l = min ( avail_in , build_filebuflen ) ;
char * p = ( char * ) ubuild_datablock . get ( in_pos , l ) ;
compressor - > SetNextIn ( p , l ) ;
2002-08-02 10:01:35 +00:00
while ( compressor - > GetAvailIn ( ) )
{
2003-09-15 22:05:06 +00:00
compressor - > SetNextOut ( obuf , sizeof ( obuf ) ) ;
2002-08-02 10:01:35 +00:00
compressor - > Compress ( 0 ) ;
2003-09-15 22:05:06 +00:00
if ( compressor - > GetNextOut ( ) - obuf > 0 )
udata . add ( obuf , compressor - > GetNextOut ( ) - obuf ) ;
2002-08-02 10:01:35 +00:00
}
2003-09-15 22:05:06 +00:00
ubuild_datablock . release ( ) ;
avail_in - = l ;
in_pos + = l ;
2002-08-02 10:01:35 +00:00
}
2003-09-15 22:05:06 +00:00
2002-08-02 10:01:35 +00:00
for ( ; ; )
{
2003-09-15 22:05:06 +00:00
compressor - > SetNextOut ( obuf , sizeof ( obuf ) ) ;
2002-08-02 10:01:35 +00:00
compressor - > Compress ( C_FINISH ) ;
2003-09-15 22:05:06 +00:00
if ( compressor - > GetNextOut ( ) - obuf > 0 )
udata . add ( obuf , compressor - > GetNextOut ( ) - obuf ) ;
2002-08-02 10:01:35 +00:00
else break ;
2002-08-31 23:44:58 +00:00
}
2002-08-02 10:01:35 +00:00
compressor - > End ( ) ;
}
2003-09-19 11:57:09 +00:00
firstheader * _fh = ( firstheader * ) udata . get ( 0 , sizeof ( firstheader ) ) ;
2006-03-25 19:43:25 +00:00
_fh - > length_of_all_following_data = FIX_ENDIAN_INT32 ( udata . getlen ( ) + ( build_crcchk ? sizeof ( int ) : 0 ) ) ;
2003-09-19 11:57:09 +00:00
udata . release ( ) ;
2002-08-02 10:01:35 +00:00
}
2003-02-07 23:04:25 +00:00
else
2002-09-22 18:48:58 +00:00
# endif //NSIS_CONFIG_COMPRESSION_SUPPORT
{
2003-09-15 22:05:06 +00:00
udata . add ( uhd . get ( ) , uhd . getlen ( ) ) ;
int st = udata . getlen ( ) ;
int length = ubuild_datablock . getlen ( ) ;
int left = length ;
udata . resize ( st + left ) ;
while ( left > 0 )
{
int l = min ( build_filebuflen , left ) ;
void * p = ubuild_datablock . get ( length - left , l ) ;
memcpy ( udata . get ( st + length - left , l ) , p , l ) ;
udata . flush ( l ) ;
udata . release ( ) ;
ubuild_datablock . release ( ) ;
left - = l ;
}
2002-08-02 10:01:35 +00:00
}
2003-09-15 22:05:06 +00:00
ubuild_datablock . clear ( ) ;
2003-09-19 11:57:09 +00:00
udata . setro ( TRUE ) ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_CRC_SUPPORT
if ( build_crcchk )
2003-09-19 11:57:09 +00:00
{
int pos = 0 ;
int left = udata . getlen ( ) ;
while ( left > 0 )
{
int l = min ( build_filebuflen , left ) ;
crc = CRC32 ( crc , ( unsigned char * ) udata . get ( pos , l ) , l ) ;
udata . release ( ) ;
pos + = l ;
left - = l ;
}
2005-03-05 12:07:13 +00:00
udata . setro ( FALSE ) ;
2006-03-25 19:43:25 +00:00
FIX_ENDIAN_INT32_INPLACE ( crc ) ;
2003-09-15 22:05:06 +00:00
udata . add ( & crc , sizeof ( crc ) ) ;
2005-03-05 12:07:13 +00:00
udata . setro ( TRUE ) ;
2003-09-19 11:57:09 +00:00
}
2002-08-02 10:01:35 +00:00
# endif
2003-09-15 22:05:06 +00:00
if ( add_db_data ( & udata ) < 0 )
2002-08-02 10:01:35 +00:00
return PS_ERROR ;
2003-09-15 22:05:06 +00:00
udata . clear ( ) ;
2003-07-19 12:15:10 +00:00
//uninstall_size_full=fh.length_of_all_following_data + sizeof(int) + unicondata_size - 32 + sizeof(int);
2005-04-02 12:04:07 +00:00
uninstall_size_full = fh . length_of_all_following_data + m_unicon_size ;
2002-08-02 10:01:35 +00:00
// compressed size
2003-11-24 13:11:35 +00:00
uninstall_size = build_datablock . getlen ( ) - uninstdata_offset ;
2003-09-15 22:05:06 +00:00
SCRIPT_MSG ( " Done! \n " ) ;
2002-08-02 10:01:35 +00:00
}
# endif
return PS_OK ;
}
# define SWAP(x,y,i) { i _ii; _ii=x; x=y; y=_ii; }
void CEXEBuild : : set_uninstall_mode ( int un )
{
if ( un ! = uninstall_mode )
{
uninstall_mode = un ;
2002-09-29 20:25:15 +00:00
if ( un )
{
cur_datablock = & ubuild_datablock ;
2004-09-25 10:09:53 +00:00
cur_datablock_cache = & ubuild_datablock_cache ;
2002-09-29 20:25:15 +00:00
cur_entries = & ubuild_entries ;
2004-09-25 13:35:03 +00:00
cur_instruction_entry_map = & ubuild_instruction_entry_map ;
2002-09-29 20:25:15 +00:00
cur_functions = & ubuild_functions ;
cur_labels = & ubuild_labels ;
2003-09-04 18:25:57 +00:00
cur_pages = & ubuild_pages ;
cur_sections = & ubuild_sections ;
cur_header = & build_uninst ;
cur_strlist = & ubuild_strlist ;
cur_langtables = & ubuild_langtables ;
cur_ctlcolors = & ubuild_ctlcolors ;
2002-09-29 20:25:15 +00:00
}
else
{
cur_datablock = & build_datablock ;
2004-09-25 10:09:53 +00:00
cur_datablock_cache = & build_datablock_cache ;
2002-09-29 20:25:15 +00:00
cur_entries = & build_entries ;
2004-09-25 13:35:03 +00:00
cur_instruction_entry_map = & build_instruction_entry_map ;
2002-09-29 20:25:15 +00:00
cur_functions = & build_functions ;
cur_labels = & build_labels ;
2003-09-04 18:25:57 +00:00
cur_pages = & build_pages ;
cur_sections = & build_sections ;
cur_header = & build_header ;
cur_strlist = & build_strlist ;
cur_langtables = & build_langtables ;
cur_ctlcolors = & build_ctlcolors ;
2002-09-29 20:25:15 +00:00
}
2002-08-02 10:01:35 +00:00
SWAP ( db_opt_save_u , db_opt_save , int ) ;
SWAP ( db_comp_save_u , db_comp_save , int ) ;
SWAP ( db_full_size_u , db_full_size , int ) ;
}
}
extern FILE * g_output ;
void CEXEBuild : : warning ( const char * s , . . . )
{
2004-06-25 19:53:05 +00:00
char buf [ NSIS_MAX_STRLEN * 10 ] ;
2002-08-02 10:01:35 +00:00
va_list val ;
va_start ( val , s ) ;
2004-06-25 19:53:05 +00:00
# ifdef _WIN32
2002-08-02 10:01:35 +00:00
vsprintf ( buf , s , val ) ;
2004-06-25 19:53:05 +00:00
# else
vsnprintf ( buf , NSIS_MAX_STRLEN * 10 , s , val ) ;
# endif
2002-08-02 10:01:35 +00:00
va_end ( val ) ;
2003-09-04 18:25:57 +00:00
m_warnings . add ( buf , 0 ) ;
notify ( MAKENSIS_NOTIFY_WARNING , buf ) ;
if ( display_warnings )
{
fprintf ( g_output , " warning: %s \n " , buf ) ;
fflush ( g_output ) ;
}
}
void CEXEBuild : : warning_fl ( const char * s , . . . )
{
2004-06-25 19:53:05 +00:00
char buf [ NSIS_MAX_STRLEN * 10 ] ;
2003-09-04 18:25:57 +00:00
va_list val ;
va_start ( val , s ) ;
2004-06-25 19:53:05 +00:00
# ifdef _WIN32
2003-09-04 18:25:57 +00:00
vsprintf ( buf , s , val ) ;
2004-06-25 19:53:05 +00:00
# else
vsnprintf ( buf , NSIS_MAX_STRLEN * 10 , s , val ) ;
# endif
2003-09-04 18:25:57 +00:00
va_end ( val ) ;
sprintf ( buf + strlen ( buf ) , " (%s:%d) " , curfilename , linecnt ) ;
m_warnings . add ( buf , 0 ) ;
2002-12-24 20:35:26 +00:00
notify ( MAKENSIS_NOTIFY_WARNING , buf ) ;
2002-08-31 23:44:58 +00:00
if ( display_warnings )
2002-08-02 10:01:35 +00:00
{
fprintf ( g_output , " warning: %s \n " , buf ) ;
fflush ( g_output ) ;
}
}
2004-09-30 18:48:03 +00:00
void CEXEBuild : : ERROR_MSG ( const char * s , . . . ) const
2002-08-02 10:01:35 +00:00
{
2004-03-29 20:21:00 +00:00
# ifdef _WIN32
2002-12-24 20:35:26 +00:00
if ( display_errors | | notify_hwnd )
2004-03-29 20:21:00 +00:00
# else
if ( display_errors )
# endif
2002-08-02 10:01:35 +00:00
{
2004-06-25 19:53:05 +00:00
char buf [ NSIS_MAX_STRLEN * 10 ] ;
2002-08-02 10:01:35 +00:00
va_list val ;
va_start ( val , s ) ;
2004-06-25 19:53:05 +00:00
# ifdef _WIN32
2002-08-02 10:01:35 +00:00
vsprintf ( buf , s , val ) ;
2004-06-25 19:53:05 +00:00
# else
vsnprintf ( buf , NSIS_MAX_STRLEN * 10 , s , val ) ;
# endif
2002-08-02 10:01:35 +00:00
va_end ( val ) ;
2002-12-24 20:35:26 +00:00
notify ( MAKENSIS_NOTIFY_ERROR , buf ) ;
if ( display_errors )
{
fprintf ( g_output , " %s " , buf ) ;
fflush ( g_output ) ;
}
2002-08-02 10:01:35 +00:00
}
}
2004-09-30 18:48:03 +00:00
void CEXEBuild : : SCRIPT_MSG ( const char * s , . . . ) const
2002-08-02 10:01:35 +00:00
{
if ( display_script )
{
va_list val ;
va_start ( val , s ) ;
2004-06-25 19:53:05 +00:00
vfprintf ( g_output , s , val ) ;
2002-08-02 10:01:35 +00:00
va_end ( val ) ;
fflush ( g_output ) ;
}
}
2004-09-30 18:48:03 +00:00
void CEXEBuild : : INFO_MSG ( const char * s , . . . ) const
2002-08-02 10:01:35 +00:00
{
if ( display_info )
{
va_list val ;
va_start ( val , s ) ;
2004-06-25 19:53:05 +00:00
vfprintf ( g_output , s , val ) ;
2002-08-02 10:01:35 +00:00
va_end ( val ) ;
fflush ( g_output ) ;
}
}
void CEXEBuild : : print_warnings ( )
{
int nw = 0 , x = m_warnings . getlen ( ) ;
if ( ! x | | ! display_warnings ) return ;
char * p = m_warnings . get ( ) ;
while ( x > 0 ) if ( ! p [ - - x ] ) nw + + ;
fprintf ( g_output , " \n %d warning%s: \n " , nw , nw = = 1 ? " " : " s " ) ;
for ( x = 0 ; x < nw ; x + + )
{
fprintf ( g_output , " %s \n " , p ) ;
p + = strlen ( p ) + 1 ;
}
fflush ( g_output ) ;
}
2002-08-05 02:05:00 +00:00
2004-03-29 20:21:00 +00:00
# ifdef _WIN32
2004-09-30 20:25:33 +00:00
void CEXEBuild : : notify ( notify_e code , const char * data ) const
2002-12-24 20:35:26 +00:00
{
if ( notify_hwnd )
{
2004-09-30 20:25:33 +00:00
COPYDATASTRUCT cds = { ( DWORD ) code , strlen ( data ) + 1 , ( void * ) data } ;
2002-12-24 20:35:26 +00:00
SendMessage ( notify_hwnd , WM_COPYDATA , 0 , ( LPARAM ) & cds ) ;
}
}
2004-03-29 20:21:00 +00:00
# endif
2002-12-24 20:35:26 +00:00
2002-08-05 02:05:00 +00:00
// Added by Ximon Eighteen 5th August 2002
# ifdef NSIS_CONFIG_PLUGIN_SUPPORT
2002-08-05 19:13:52 +00:00
void CEXEBuild : : build_plugin_table ( void )
2002-08-05 02:05:00 +00:00
{
2003-11-30 18:00:39 +00:00
if ( plugins_processed )
return ;
plugins_processed = 1 ;
2002-08-08 15:04:45 +00:00
plugin_used = false ;
2002-08-29 10:25:45 +00:00
uninst_plugin_used = false ;
2006-01-21 09:54:23 +00:00
string searchPath = definedlist . find ( " NSISDIR " ) ;
searchPath + = PLATFORM_PATH_SEPARATOR_STR " Plugins " ;
INFO_MSG ( " Processing plugin dlls: \" %s " PLATFORM_PATH_SEPARATOR_STR " *.dll \" \n " , searchPath . c_str ( ) ) ;
m_plugins . FindCommands ( searchPath , display_info ? true : false ) ;
INFO_MSG ( " \n " ) ;
2002-08-05 02:05:00 +00:00
}
2002-08-09 22:12:10 +00:00
2003-09-04 18:25:57 +00:00
# define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags, flag) / sizeof(int))
2003-05-24 13:50:24 +00:00
2002-09-21 13:11:28 +00:00
int CEXEBuild : : add_plugins_dir_initializer ( void )
2002-08-09 22:12:10 +00:00
{
2002-11-21 22:59:11 +00:00
if ( ! plugin_used & & ! uninst_plugin_used ) return PS_OK ;
2002-08-09 22:12:10 +00:00
2002-09-21 13:11:28 +00:00
SCRIPT_MSG ( " Adding plug-ins initializing function... " ) ;
2002-08-09 22:12:10 +00:00
2002-11-21 22:59:11 +00:00
bool uninstall = ! plugin_used ;
2002-08-09 22:12:10 +00:00
2002-09-21 13:11:28 +00:00
int ret ;
2002-08-09 22:12:10 +00:00
int zero_offset ;
2003-06-12 00:06:23 +00:00
int var_zero ;
var_zero = m_UserVarNames . get ( " 0 " ) ;
2002-08-09 22:12:10 +00:00
again :
2003-04-02 15:49:13 +00:00
// Function [un.]Initialize_____Plugins
2002-11-21 22:59:11 +00:00
ret = add_function ( uninstall ? " un.Initialize_____Plugins " : " Initialize_____Plugins " ) ;
if ( ret ! = PS_OK ) return ret ;
2002-10-01 17:16:49 +00:00
2003-04-02 15:49:13 +00:00
// don't move this, depends on [un.]
2002-08-09 22:12:10 +00:00
zero_offset = add_string ( " $0 " ) ;
2003-04-02 15:49:13 +00:00
// SetDetailsPrint none
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_UPDATETEXT , 0 , 16 ) ;
2003-04-02 15:49:13 +00:00
if ( ret ! = PS_OK ) return ret ;
2002-08-09 22:12:10 +00:00
// StrCmp $PLUGINSDIR ""
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_STRCMP , add_string ( " $PLUGINSDIR " ) , 0 , 0 , ns_label . add ( " Initialize_____Plugins_done " , 0 ) ) ;
2002-08-09 22:12:10 +00:00
if ( ret ! = PS_OK ) return ret ;
// Push $0
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_PUSHPOP , zero_offset ) ;
2003-04-02 15:49:13 +00:00
if ( ret ! = PS_OK ) return ret ;
// ClearErrors
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_SETFLAG , FLAG_OFFSET ( exec_error ) ) ;
2002-08-09 22:12:10 +00:00
if ( ret ! = PS_OK ) return ret ;
2003-04-02 15:49:13 +00:00
// GetTempFileName $0
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_GETTEMPFILENAME , var_zero , add_string ( " $TEMP " ) ) ;
2002-08-09 22:12:10 +00:00
if ( ret ! = PS_OK ) return ret ;
2005-02-18 13:39:42 +00:00
// Delete $0 [simple, nothing that could clash with special temp permissions]
ret = add_entry_direct ( EW_DELETEFILE , zero_offset , DEL_SIMPLE ) ;
2002-08-09 22:12:10 +00:00
if ( ret ! = PS_OK ) return ret ;
2003-04-02 15:49:13 +00:00
// CraeteDirectory $0 - a dir instead of that temp file
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_CREATEDIR , zero_offset ) ;
2003-04-01 18:07:32 +00:00
if ( ret ! = PS_OK ) return ret ;
2003-04-02 15:49:13 +00:00
// IfErrors Initialize_____Plugins_error - detect errors
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_IFFLAG , ns_label . add ( " Initialize_____Plugins_error " , 0 ) , 0 , FLAG_OFFSET ( exec_error ) ) ;
2003-04-01 18:07:32 +00:00
if ( ret ! = PS_OK ) return ret ;
2002-08-09 22:12:10 +00:00
// Copy $0 to $PLUGINSDIR
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_ASSIGNVAR , m_UserVarNames . get ( " PLUGINSDIR " ) , zero_offset ) ;
2002-08-09 22:12:10 +00:00
if ( ret ! = PS_OK ) return ret ;
// Pop $0
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_PUSHPOP , var_zero , 1 ) ;
2002-08-09 22:12:10 +00:00
if ( ret ! = PS_OK ) return ret ;
2003-04-01 18:07:32 +00:00
// done
2002-08-09 22:12:10 +00:00
if ( add_label ( " Initialize_____Plugins_done " ) ) return PS_ERROR ;
2003-04-02 15:49:13 +00:00
// Return
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_RET ) ;
2003-04-01 18:07:32 +00:00
if ( ret ! = PS_OK ) return ret ;
// error
if ( add_label ( " Initialize_____Plugins_error " ) ) return PS_ERROR ;
// error message box
2005-03-17 20:44:31 +00:00
ret = add_entry_direct ( EW_MESSAGEBOX , MB_OK | MB_ICONSTOP | ( IDOK < < 21 ) , add_string ( " Error! Can't initialize plug-ins directory. Please try again later. " ) ) ;
2003-04-01 18:07:32 +00:00
if ( ret ! = PS_OK ) return ret ;
2003-04-02 15:49:13 +00:00
// Quit
2003-09-05 22:22:56 +00:00
ret = add_entry_direct ( EW_QUIT ) ;
2003-04-01 18:07:32 +00:00
if ( ret ! = PS_OK ) return ret ;
2002-08-09 22:12:10 +00:00
2003-04-02 15:49:13 +00:00
// FunctionEnd
2002-08-09 22:12:10 +00:00
ret = function_end ( ) ;
if ( ret ! = PS_OK ) return ret ;
2002-08-29 10:25:45 +00:00
if ( uninst_plugin_used & & ! uninstall ) {
2002-08-09 22:12:10 +00:00
uninstall = true ;
goto again ;
}
SCRIPT_MSG ( " Done! \n " ) ;
return PS_OK ;
}
2002-08-31 23:44:58 +00:00
# endif // NSIS_CONFIG_PLUGIN_SUPPORT
2002-11-09 13:51:40 +00:00
void CEXEBuild : : init_res_editor ( )
{
2004-02-05 12:19:02 +00:00
build_compressor_set = true ;
2002-11-09 13:51:40 +00:00
if ( ! res_editor )
2004-10-02 18:04:41 +00:00
res_editor = new CResourceEditor ( m_exehead , m_exehead_size ) ;
2002-11-09 13:51:40 +00:00
}
void CEXEBuild : : close_res_editor ( )
{
if ( ! res_editor ) return ;
2004-02-05 12:19:02 +00:00
DWORD newsize ;
2004-10-02 18:04:41 +00:00
// get size
2004-02-05 12:19:02 +00:00
newsize = res_editor - > Save ( NULL , newsize ) ;
2004-10-02 18:04:41 +00:00
unsigned char * new_header = new unsigned char [ newsize ] ;
2004-02-05 12:19:02 +00:00
// save
2004-10-02 18:04:41 +00:00
int rc = res_editor - > Save ( new_header , newsize ) ;
assert ( rc = = 0 ) ;
update_exehead ( new_header , newsize ) ;
// TODO: resource-controlling class
delete [ ] new_header ;
2002-11-09 13:51:40 +00:00
delete res_editor ;
res_editor = 0 ;
2003-04-17 15:27:12 +00:00
}
2003-06-09 18:59:14 +00:00
int CEXEBuild : : DeclaredUserVar ( const char * szVarName )
{
2004-03-12 20:43:54 +00:00
if ( m_ShellConstants . get ( ( char * ) szVarName ) > = 0 )
2003-12-22 00:28:30 +00:00
{
ERROR_MSG ( " Error: name \" %s \" in use by constant \n " , szVarName ) ;
2005-10-16 05:37:13 +00:00
return PS_ERROR ;
2003-12-22 00:28:30 +00:00
}
2003-07-12 15:19:49 +00:00
int idxUserVar = m_UserVarNames . get ( ( char * ) szVarName ) ;
2004-03-12 20:43:54 +00:00
if ( idxUserVar > = 0 )
2003-07-12 15:19:49 +00:00
{
ERROR_MSG ( " Error: variable \" %s \" already declared \n " , szVarName ) ;
2005-10-16 05:37:13 +00:00
return PS_ERROR ;
2003-07-12 15:19:49 +00:00
}
const char * pVarName = szVarName ;
int iVarLen = strlen ( szVarName ) ;
2004-03-12 20:43:54 +00:00
if ( iVarLen > 60 )
2003-07-12 15:19:49 +00:00
{
ERROR_MSG ( " Error: variable name too long! \n " ) ;
return PS_ERROR ;
}
2004-03-12 20:43:54 +00:00
else if ( ! iVarLen )
2003-07-12 15:19:49 +00:00
{
ERROR_MSG ( " Error: variable with empty name! \n " ) ;
return PS_ERROR ;
}
else
{
2004-03-12 20:43:54 +00:00
while ( * pVarName )
2003-07-12 15:19:49 +00:00
{
2004-03-12 20:43:54 +00:00
if ( ! isSimpleChar ( * pVarName ) )
2003-07-12 15:19:49 +00:00
{
2006-04-14 10:05:01 +00:00
ERROR_MSG ( " Error: invalid characters in variable name \" %s \" , use only characters [a-z][A-Z][0-9] and '_' \n " , szVarName ) ;
2003-07-12 15:19:49 +00:00
return PS_ERROR ;
}
pVarName + + ;
}
}
2003-07-15 23:40:34 +00:00
m_UserVarNames . add ( szVarName ) ;
2004-01-04 17:05:03 +00:00
if ( m_UserVarNames . getnum ( ) > MAX_CODED )
2003-07-12 15:19:49 +00:00
{
2004-01-04 17:05:03 +00:00
ERROR_MSG ( " Error: too many user variables declared. Maximum allowed is %u. \n " , MAX_CODED - m_iBaseVarsNum ) ;
2003-06-09 18:59:14 +00:00
return PS_ERROR ;
}
2003-07-12 15:19:49 +00:00
return PS_OK ;
2003-06-09 18:59:14 +00:00
}
2003-12-22 00:28:30 +00:00
2003-06-09 18:59:14 +00:00
int CEXEBuild : : GetUserVarIndex ( LineParser & line , int token )
{
2003-09-04 18:25:57 +00:00
char * p = line . gettoken_str ( token ) ;
if ( * p = = ' $ ' & & * ( p + 1 ) )
{
int idxUserVar = m_UserVarNames . get ( ( char * ) p + 1 ) ;
if ( idxUserVar > = 0 & & m_UserVarNames . get_reference ( idxUserVar ) > = 0 )
2003-06-09 18:59:14 +00:00
{
2003-09-04 18:25:57 +00:00
m_UserVarNames . inc_reference ( idxUserVar ) ;
return idxUserVar ;
2003-06-09 18:59:14 +00:00
}
2003-12-22 00:28:30 +00:00
else
{
2004-03-12 20:43:54 +00:00
int idxConst = m_ShellConstants . get ( ( char * ) p + 1 ) ;
if ( idxConst > = 0 )
{
ERROR_MSG ( " Error: cannot change constants : %s \n " , p ) ;
}
2003-12-22 00:28:30 +00:00
}
2003-09-04 18:25:57 +00:00
}
return - 1 ;
2003-06-09 18:59:14 +00:00
}
2003-06-23 22:40:11 +00:00
void CEXEBuild : : VerifyDeclaredUserVarRefs ( UserVarsStringList * pVarsStringList )
{
2004-01-04 17:05:03 +00:00
for ( int i = m_iBaseVarsNum ; i < pVarsStringList - > getnum ( ) ; i + + )
2003-06-23 22:40:11 +00:00
{
2004-01-04 17:05:03 +00:00
if ( ! pVarsStringList - > get_reference ( i ) )
2005-10-16 05:37:13 +00:00
{
2003-06-23 22:40:11 +00:00
warning ( " Variable \" %s \" not referenced, wasting memory! " , pVarsStringList - > idx2name ( i ) ) ;
2005-10-16 05:37:13 +00:00
}
2003-06-23 22:40:11 +00:00
}
}
2004-10-02 18:04:41 +00:00
2005-04-02 12:04:07 +00:00
int CEXEBuild : : set_compressor ( const string & compressor , const bool solid ) {
string stub = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + compressor ;
if ( solid )
stub + = " _solid " ;
return update_exehead ( stub , & m_exehead_original_size ) ;
}
int CEXEBuild : : update_exehead ( const string & file , size_t * size /*=NULL*/ ) {
FILE * tmpfile = fopen ( file . c_str ( ) , " rb " ) ;
if ( ! tmpfile )
{
ERROR_MSG ( " Error: opening stub \" %s \" \n " , file . c_str ( ) ) ;
return PS_ERROR ;
}
fseek ( tmpfile , 0 , SEEK_END ) ;
size_t exehead_size = ftell ( tmpfile ) ;
unsigned char * exehead = new unsigned char [ exehead_size ] ;
fseek ( tmpfile , 0 , SEEK_SET ) ;
if ( fread ( exehead , 1 , exehead_size , tmpfile ) ! = exehead_size )
{
ERROR_MSG ( " Error: reading stub \" %s \" \n " , file . c_str ( ) ) ;
fclose ( tmpfile ) ;
delete [ ] exehead ;
return PS_ERROR ;
}
fclose ( tmpfile ) ;
update_exehead ( exehead , exehead_size ) ;
if ( size )
* size = exehead_size ;
delete [ ] exehead ;
return PS_OK ;
}
2004-10-02 18:04:41 +00:00
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 ) ;
}
2005-04-02 12:04:07 +00:00