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"
|
|
|
|
static int bz2_needreinit;
|
|
|
|
#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)
|
|
|
|
#define inflateReset(x) { if (bz2_needreinit) { BZ2_bzDecompressEnd(x); inflateInit(x); } bz2_needreinit=1; }
|
|
|
|
#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
|
|
|
{
|
|
|
|
DWORD r;
|
|
|
|
void *data;
|
|
|
|
firstheader h;
|
|
|
|
|
2002-09-24 23:26:55 +00:00
|
|
|
if (!ReadSelfFile((LPVOID)&h,sizeof(h),&r) || r != 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
|
|
|
{
|
|
|
|
if (offs < 0) return "";
|
|
|
|
return g_db_strtab+offs;
|
|
|
|
}
|
|
|
|
|
|
|
|
#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;
|
|
|
|
DWORD r;
|
|
|
|
|
|
|
|
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-24 23:26:55 +00:00
|
|
|
if (!ReadSelfFile((LPVOID)&input_len,sizeof(int),&r)) return -3;
|
2002-08-02 10:01:35 +00:00
|
|
|
|
|
|
|
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
|
|
|
else if (input_len & 0x80000000) // compressed
|
|
|
|
{
|
|
|
|
inflateReset(&g_inflate_stream);
|
|
|
|
input_len &= 0x7fffffff; // take off top bit.
|
|
|
|
|
|
|
|
while (input_len > 0)
|
|
|
|
{
|
|
|
|
DWORD r;
|
|
|
|
int err;
|
|
|
|
|
2002-09-24 23:26:55 +00:00
|
|
|
if (!ReadSelfFile((LPVOID)inbuffer,min(input_len,IBUFSIZE),&r)) return -3;
|
2002-08-02 10:01:35 +00:00
|
|
|
|
|
|
|
g_inflate_stream.next_in = inbuffer;
|
|
|
|
g_inflate_stream.avail_in = r;
|
|
|
|
input_len-=r;
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!outbuf)
|
|
|
|
{
|
|
|
|
while (input_len > 0)
|
|
|
|
{
|
|
|
|
DWORD t;
|
2002-09-24 23:26:55 +00:00
|
|
|
if (!ReadSelfFile((LPVOID)inbuffer,min(input_len,outbuffer_len),&r)) return -3;
|
2002-08-02 10:01:35 +00:00
|
|
|
if (!WriteFile(hFileOut,inbuffer,r,&t,NULL) || r!=t) return -2;
|
|
|
|
retval+=r;
|
|
|
|
input_len-=r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-09-24 23:26:55 +00:00
|
|
|
if (!ReadSelfFile((LPVOID)outbuf,min(input_len,outbuflen),&r)) return -3;
|
2002-08-02 10:01:35 +00:00
|
|
|
retval=r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
DWORD or;
|
2002-09-24 23:26:55 +00:00
|
|
|
if (!ReadSelfFile((LPVOID)_inbuffer,min(IBUFSIZE,dbd_fulllen-dbd_srcpos),&or)) return -1;
|
2002-08-02 10:01:35 +00:00
|
|
|
dbd_srcpos+=or;
|
|
|
|
g_inflate_stream.next_in=_inbuffer;
|
|
|
|
g_inflate_stream.avail_in=or;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
else if (g_inflate_stream.avail_in || !or) return -3;
|
|
|
|
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;
|
|
|
|
if (!ReadFile(dbd_hFile,(LPVOID)_inbuffer,min(input_len,IBUFSIZE),&r,NULL)) return -3;
|
|
|
|
if (!WriteFile(hFileOut,_inbuffer,r,&t,NULL) || r!=t) return -2;
|
|
|
|
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
|
|
|
|
|
|
|
BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead)
|
|
|
|
{
|
|
|
|
return ReadFile(g_db_hFile,lpBuffer,nNumberOfBytesToRead,lpNumberOfBytesRead,NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod)
|
|
|
|
{
|
|
|
|
return SetFilePointer(g_db_hFile,lDistanceToMove,NULL,dwMoveMethod);
|
|
|
|
}
|