2002-08-02 10:01:35 +00:00
# include <windows.h>
# include "fileform.h"
# include "util.h"
# include "state.h"
2002-08-21 17:23:46 +00:00
# include "resource.h"
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
# ifdef NSIS_COMPRESS_USE_ZLIB
# include "../zlib/zlib.h"
# endif
# ifdef NSIS_COMPRESS_USE_BZIP2
# include "../bzip2/bzlib.h"
2002-09-30 16:49:21 +00:00
static char bz2_needreinit ;
2002-09-27 03:38:41 +00:00
2002-08-02 10:01:35 +00:00
# define z_stream bz_stream
2002-09-21 07:05:31 +00:00
# define inflateInit(x) { if (BZ2_bzDecompressInit(x)<0) return _LANG_INVALIDCRC; }
2002-08-02 10:01:35 +00:00
# define inflate(x) BZ2_bzDecompress(x)
2002-10-01 01:57:14 +00:00
# define inflateReset(x) { if (bz2_needreinit) { inflateInit(x); } else bz2_needreinit++; }
2002-08-02 10:01:35 +00:00
# define Z_OK BZ_OK
# define Z_STREAM_END BZ_STREAM_END
# endif //NSIS_COMPRESS_USE_BZIP2
# endif
# include "ui.h"
2002-09-20 23:22:11 +00:00
char * g_db_strtab ;
2002-08-02 10:01:35 +00:00
static int g_db_offset ;
HANDLE g_db_hFile ;
2002-09-18 21:21:50 +00:00
# if defined(NSIS_CONFIG_COMPRESSION_SUPPORT) && defined(NSIS_COMPRESS_WHOLE)
2002-08-02 10:01:35 +00:00
HANDLE dbd_hFile = INVALID_HANDLE_VALUE ;
static int dbd_size , dbd_pos , dbd_srcpos , dbd_fulllen ;
# endif //NSIS_COMPRESS_WHOLE
2002-08-19 23:18:19 +00:00
int NSISCALL isheader ( firstheader * h )
2002-08-02 10:01:35 +00:00
{
if ( ( h - > flags & ( ~ FH_FLAGS_MASK ) ) | |
h - > siginfo ! = FH_SIG | |
h - > nsinst [ 2 ] ! = FH_INT3 | |
h - > nsinst [ 1 ] ! = FH_INT2 | |
h - > nsinst [ 0 ] ! = FH_INT1 ) return 0 ;
return h - > length_of_all_following_data ;
}
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
static z_stream g_inflate_stream ;
# endif
2002-09-21 07:05:31 +00:00
const char * NSISCALL loadHeaders ( void )
2002-08-02 10:01:35 +00:00
{
void * data ;
firstheader h ;
2002-09-25 03:34:30 +00:00
if ( ! ReadSelfFile ( ( LPVOID ) & h , sizeof ( h ) ) | | ! isheader ( & h ) ) return _LANG_INVALIDCRC ;
2002-08-02 10:01:35 +00:00
2002-09-07 20:49:18 +00:00
data = ( void * ) my_GlobalAlloc ( h . length_of_header ) ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
inflateInit ( & g_inflate_stream ) ;
# ifdef NSIS_COMPRESS_WHOLE
inflateReset ( & g_inflate_stream ) ;
{
char fn [ MAX_PATH ] , fno [ MAX_PATH ] ;
GetTempPath ( sizeof ( fn ) , fn ) ;
GetTempFileName ( fn , " nsi " , 0 , fno ) ;
dbd_hFile = CreateFile ( fno , GENERIC_WRITE | GENERIC_READ , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE , NULL ) ;
2002-08-19 23:18:19 +00:00
if ( dbd_hFile = = INVALID_HANDLE_VALUE )
2002-08-02 10:01:35 +00:00
{
2002-09-21 07:05:31 +00:00
return _LANG_ERRORWRITINGTEMP ;
2002-08-02 10:01:35 +00:00
}
}
2002-09-24 23:26:55 +00:00
dbd_srcpos = SetSelfFilePointer ( 0 , FILE_CURRENT ) ;
2002-08-02 10:01:35 +00:00
dbd_fulllen = dbd_srcpos - sizeof ( h ) + h . length_of_all_following_data - ( ( h . flags & FH_FLAGS_CRC ) ? 4 : 0 ) ;
2002-09-18 21:21:50 +00:00
# endif
2002-08-02 10:01:35 +00:00
# endif
if ( GetCompressedDataFromDataBlockToMemory ( - 1 , data , h . length_of_header ) ! = h . length_of_header )
{
GlobalFree ( ( HGLOBAL ) data ) ;
2002-09-21 07:05:31 +00:00
return _LANG_INVALIDCRC ;
2002-08-02 10:01:35 +00:00
}
2002-09-18 21:21:50 +00:00
# if !defined(NSIS_COMPRESS_WHOLE) || !defined(NSIS_CONFIG_COMPRESSION_SUPPORT)
2002-09-24 23:26:55 +00:00
g_db_offset = SetSelfFilePointer ( 0 , FILE_CURRENT ) ;
2002-08-02 10:01:35 +00:00
# else
g_db_offset = dbd_pos ;
# endif
g_inst_combinedheader = data ;
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if ( h . flags & FH_FLAGS_UNINSTALL )
{
g_is_uninstaller + + ;
g_inst_entry = ( entry * ) ( ( g_inst_uninstheader ) + 1 ) ;
}
else
# endif
{
g_inst_section = ( section * ) ( g_inst_header + 1 ) ;
g_inst_entry = ( entry * ) ( g_inst_section + g_inst_header - > num_sections ) ;
}
g_db_strtab = ( char * ) ( g_inst_entry + g_inst_cmnheader - > num_entries ) ;
return 0 ;
}
2002-08-19 23:18:19 +00:00
const char * NSISCALL GetStringFromStringTab ( int offs )
2002-08-02 10:01:35 +00:00
{
2002-09-29 20:25:15 +00:00
/*if (offs < 0) {
wsprintf ( ps_tmpbuf , " my first user madasd %d->%d which should be %d \n %d " , offs , cur_user_strings_table [ - ( offs + 1 ) ] , cur_user_strings_table [ 0 ] , LANG_COMP_TEXT ) ;
my_MessageBox ( ps_tmpbuf , MB_OK ) ;
} */
return g_db_strtab + ( offs < 0 ? cur_user_strings_table [ - ( offs + 1 ) ] : offs ) ;
2002-08-02 10:01:35 +00:00
}
# define IBUFSIZE 16384
# define OBUFSIZE 32768
// returns -3 if compression error/eof/etc
2002-09-18 21:21:50 +00:00
# if !defined(NSIS_COMPRESS_WHOLE) || !defined(NSIS_CONFIG_COMPRESSION_SUPPORT)
2002-08-02 10:01:35 +00:00
2002-08-19 23:18:19 +00:00
static int NSISCALL _dodecomp ( int offset , HANDLE hFileOut , char * outbuf , int outbuflen )
2002-08-02 10:01:35 +00:00
{
static char inbuffer [ IBUFSIZE + OBUFSIZE ] ;
char * outbuffer ;
int outbuffer_len = outbuf ? outbuflen : OBUFSIZE ;
int retval = 0 ;
int input_len ;
outbuffer = outbuf ? outbuf : ( inbuffer + IBUFSIZE ) ;
2002-08-19 23:18:19 +00:00
if ( offset > = 0 )
2002-08-02 10:01:35 +00:00
{
/*
2002-09-24 23:26:55 +00:00
int lp = SetSelfFilePointer ( 0 , FILE_CURRENT ) ;
2002-08-02 10:01:35 +00:00
if ( lp > g_db_offset + offset )
{
char buf [ 1023 ] ;
wsprintf ( buf , " going from %d to %d " , lp , g_db_offset + offset ) ;
MessageBox ( NULL , buf , " seeking back " , MB_OK ) ;
}
*/
2002-09-24 23:26:55 +00:00
SetSelfFilePointer ( g_db_offset + offset , FILE_BEGIN ) ;
2002-08-02 10:01:35 +00:00
}
2002-09-25 03:34:30 +00:00
if ( ! ReadSelfFile ( ( LPVOID ) & input_len , sizeof ( int ) ) ) return - 3 ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
2002-09-25 03:34:30 +00:00
if ( input_len & 0x80000000 ) // compressed
2002-08-02 10:01:35 +00:00
{
inflateReset ( & g_inflate_stream ) ;
input_len & = 0x7fffffff ; // take off top bit.
while ( input_len > 0 )
{
2002-09-25 03:34:30 +00:00
int l = min ( input_len , IBUFSIZE ) ;
2002-08-02 10:01:35 +00:00
int err ;
2002-09-25 03:34:30 +00:00
if ( ! ReadSelfFile ( ( LPVOID ) inbuffer , l ) ) return - 3 ;
2002-08-02 10:01:35 +00:00
g_inflate_stream . next_in = inbuffer ;
2002-09-25 03:34:30 +00:00
g_inflate_stream . avail_in = l ;
input_len - = l ;
2002-08-02 10:01:35 +00:00
for ( ; ; )
{
int u ;
g_inflate_stream . next_out = outbuffer ;
g_inflate_stream . avail_out = ( unsigned int ) outbuffer_len ;
err = inflate ( & g_inflate_stream ) ;
if ( err < 0 ) return - 4 ;
u = ( char * ) g_inflate_stream . next_out - outbuffer ;
if ( ! u ) break ;
if ( ! outbuf )
{
2002-09-25 03:34:30 +00:00
DWORD r ;
2002-08-02 10:01:35 +00:00
if ( ! WriteFile ( hFileOut , outbuffer , u , & r , NULL ) | | ( int ) r ! = u ) return - 2 ;
retval + = u ;
}
else
{
retval + = u ;
outbuffer_len - = u ;
outbuffer = g_inflate_stream . next_out ;
if ( outbuffer_len < 1 ) return retval ;
}
if ( err = = Z_STREAM_END ) return retval ;
}
}
}
else
2002-09-25 03:34:30 +00:00
# endif //NSIS_CONFIG_COMPRESSION_SUPPORT
2002-08-02 10:01:35 +00:00
{
if ( ! outbuf )
{
while ( input_len > 0 )
{
2002-09-25 03:34:30 +00:00
DWORD l = min ( input_len , outbuffer_len ) ;
2002-08-02 10:01:35 +00:00
DWORD t ;
2002-09-25 03:34:30 +00:00
if ( ! ReadSelfFile ( ( LPVOID ) inbuffer , l ) ) return - 3 ;
if ( ! WriteFile ( hFileOut , inbuffer , l , & t , NULL ) | | l ! = t ) return - 2 ;
retval + = l ;
input_len - = l ;
2002-08-02 10:01:35 +00:00
}
}
else
{
2002-09-25 03:34:30 +00:00
int l = min ( input_len , outbuflen ) ;
if ( ! ReadSelfFile ( ( LPVOID ) outbuf , l ) ) return - 3 ;
retval = l ;
2002-08-02 10:01:35 +00:00
}
}
return retval ;
}
# else //NSIS_COMPRESS_WHOLE
static char _inbuffer [ IBUFSIZE ] ;
static char _outbuffer [ OBUFSIZE ] ;
2002-08-21 17:23:46 +00:00
extern int m_length ;
extern int m_pos ;
extern BOOL CALLBACK verProc ( HWND , UINT , WPARAM , LPARAM ) ;
2002-09-21 15:17:42 +00:00
extern BOOL CALLBACK DialogProc ( HWND , UINT , WPARAM , LPARAM ) ;
2002-08-19 23:18:19 +00:00
static int NSISCALL __ensuredata ( int amount )
2002-08-02 10:01:35 +00:00
{
2002-08-21 17:23:46 +00:00
HWND hwnd = NULL ;
unsigned int verify_time = GetTickCount ( ) + 500 ;
2002-08-02 10:01:35 +00:00
int needed = amount - ( dbd_size - dbd_pos ) ;
if ( needed > 0 )
{
2002-09-24 23:26:55 +00:00
SetSelfFilePointer ( dbd_srcpos , FILE_BEGIN ) ;
2002-08-02 10:01:35 +00:00
SetFilePointer ( dbd_hFile , dbd_size , NULL , FILE_BEGIN ) ;
2002-08-21 17:23:46 +00:00
m_length = needed ;
m_pos = 0 ;
2002-08-02 10:01:35 +00:00
for ( ; ; )
{
int err ;
2002-09-25 03:34:30 +00:00
int l = min ( IBUFSIZE , dbd_fulllen - dbd_srcpos ) ;
if ( ! ReadSelfFile ( ( LPVOID ) _inbuffer , l ) ) return - 1 ;
dbd_srcpos + = l ;
2002-08-02 10:01:35 +00:00
g_inflate_stream . next_in = _inbuffer ;
2002-09-25 03:34:30 +00:00
g_inflate_stream . avail_in = l ;
2002-08-02 10:01:35 +00:00
do
{
DWORD r , t ;
2002-08-21 17:23:46 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
if ( g_inst_cmnheader )
2002-09-16 12:48:43 +00:00
# ifdef NSIS_CONFIG_SILENT_SUPPORT
if ( ! g_inst_cmnheader - > silent_install )
# endif
{
2002-08-21 17:23:46 +00:00
if ( hwnd ) {
static MSG msg ;
m_pos = m_length - ( amount - ( dbd_size - dbd_pos ) ) ;
while ( PeekMessage ( & msg , NULL , 0 , 0 , PM_REMOVE ) ) DispatchMessage ( & msg ) ;
}
2002-09-21 17:17:14 +00:00
else if ( GetWindowLong ( g_hwnd , DWL_DLGPROC ) ! = ( long ) DialogProc & & GetTickCount ( ) > verify_time )
2002-08-21 17:23:46 +00:00
hwnd = CreateDialogParam (
g_hInstance ,
MAKEINTRESOURCE ( IDD_VERIFY ) ,
GetDesktopWindow ( ) ,
verProc ,
( LPARAM ) _LANG_UNPACKING
) ;
}
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
2002-08-02 10:01:35 +00:00
g_inflate_stream . next_out = _outbuffer ;
g_inflate_stream . avail_out = OBUFSIZE ;
err = inflate ( & g_inflate_stream ) ;
if ( err < 0 )
{
return - 3 ;
}
r = g_inflate_stream . next_out - _outbuffer ;
if ( r )
{
if ( ! WriteFile ( dbd_hFile , _outbuffer , r , & t , NULL ) | | r ! = t )
{
return - 2 ;
}
dbd_size + = r ;
}
2002-09-25 03:34:30 +00:00
else if ( g_inflate_stream . avail_in | | ! l ) return - 3 ;
2002-08-02 10:01:35 +00:00
else break ;
}
while ( g_inflate_stream . avail_in ) ;
if ( amount - ( dbd_size - dbd_pos ) < = 0 ) break ;
}
SetFilePointer ( dbd_hFile , dbd_pos , NULL , FILE_BEGIN ) ;
}
2002-08-21 17:23:46 +00:00
if ( hwnd ) DestroyWindow ( hwnd ) ;
2002-08-02 10:01:35 +00:00
return 0 ;
}
2002-08-19 23:18:19 +00:00
static int NSISCALL _dodecomp ( int offset , HANDLE hFileOut , char * outbuf , int outbuflen )
2002-08-02 10:01:35 +00:00
{
DWORD r ;
int input_len ;
int retval ;
if ( offset > = 0 )
{
dbd_pos = g_db_offset + offset ;
SetFilePointer ( dbd_hFile , dbd_pos , NULL , FILE_BEGIN ) ;
}
retval = __ensuredata ( sizeof ( int ) ) ;
if ( retval < 0 ) return retval ;
if ( ! ReadFile ( dbd_hFile , ( LPVOID ) & input_len , sizeof ( int ) , & r , NULL ) | | r ! = sizeof ( int ) ) return - 3 ;
dbd_pos + = sizeof ( int ) ;
retval = __ensuredata ( input_len ) ;
if ( retval < 0 ) return retval ;
if ( ! outbuf )
{
while ( input_len > 0 )
{
DWORD t ;
2002-09-25 03:44:17 +00:00
DWORD l = min ( input_len , IBUFSIZE ) ;
if ( ! ReadFile ( dbd_hFile , ( LPVOID ) _inbuffer , l , & r , NULL ) | | l ! = r ) return - 3 ;
if ( ! WriteFile ( hFileOut , _inbuffer , r , & t , NULL ) | | t ! = l ) return - 2 ;
2002-08-02 10:01:35 +00:00
retval + = r ;
input_len - = r ;
dbd_pos + = r ;
}
}
else
{
if ( ! ReadFile ( dbd_hFile , ( LPVOID ) outbuf , min ( input_len , outbuflen ) , & r , NULL ) ) return - 3 ;
retval = r ;
dbd_pos + = r ;
}
return retval ;
}
# endif //NSIS_COMPRESS_WHOLE
2002-08-19 23:18:19 +00:00
int NSISCALL GetCompressedDataFromDataBlock ( int offset , HANDLE hFileOut )
2002-08-02 10:01:35 +00:00
{
return _dodecomp ( offset , hFileOut , NULL , 0 ) ;
}
2002-08-19 23:18:19 +00:00
int NSISCALL GetCompressedDataFromDataBlockToMemory ( int offset , char * out , int out_len )
2002-08-02 10:01:35 +00:00
{
return _dodecomp ( offset , NULL , out , out_len ) ;
}
2002-09-24 23:26:55 +00:00
2002-09-25 03:34:30 +00:00
BOOL NSISCALL ReadSelfFile ( LPVOID lpBuffer , DWORD nNumberOfBytesToRead )
2002-09-24 23:26:55 +00:00
{
2002-09-25 03:34:30 +00:00
DWORD rd ;
return ReadFile ( g_db_hFile , lpBuffer , nNumberOfBytesToRead , & rd , NULL ) & & ( rd = = nNumberOfBytesToRead ) ;
2002-09-24 23:26:55 +00:00
}
DWORD NSISCALL SetSelfFilePointer ( LONG lDistanceToMove , DWORD dwMoveMethod )
{
return SetFilePointer ( g_db_hFile , lDistanceToMove , NULL , dwMoveMethod ) ;
}