static int NSISCALL __ensuredata(int amount) { int needed=amount-(dbd_size-dbd_pos); #ifdef NSIS_CONFIG_VISIBLE_SUPPORT verify_time=GetTickCount()+500; #endif if (needed>0) { SetSelfFilePointer(dbd_srcpos); SetFilePointerEx(dbd_hFile,(LARGE_INTEGER*)&dbd_size,NULL,FILE_BEGIN); m_length=needed; m_pos=0; for (;;) { int err; int l=min(IBUFSIZE,dbd_fulllen-dbd_srcpos); if (!ReadSelfFile((LPVOID)_inbuffer,l)) return -1; dbd_srcpos+=l; g_inflate_stream.next_in=_inbuffer; g_inflate_stream.avail_in=l; do { DWORD r,t; #ifdef NSIS_CONFIG_VISIBLE_SUPPORT if (g_header) #ifdef NSIS_CONFIG_SILENT_SUPPORT if (!g_exec_flags.silent) #endif { m_pos=m_length-(amount-(dbd_size-dbd_pos)); handle_ver_dlg(FALSE); } #endif//NSIS_CONFIG_VISIBLE_SUPPORT g_inflate_stream.next_out=_outbuffer; g_inflate_stream.avail_out=OBUFSIZE; err=inflate(&g_inflate_stream); if (err<0) { return -3; } r=(DWORD)g_inflate_stream.next_out-(DWORD)_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 || !l) return -3; else break; } while (g_inflate_stream.avail_in); if (amount-(dbd_size-dbd_pos) <= 0) break; } SetFilePointerEx(dbd_hFile,(LARGE_INTEGER*)&dbd_pos,NULL,FILE_BEGIN); } #ifdef NSIS_CONFIG_VISIBLE_SUPPORT handle_ver_dlg(TRUE); #endif//NSIS_CONFIG_VISIBLE_SUPPORT return 0; }
// Decompress data. __int64 NSISCALL _dodecomp(__int64 offset, HANDLE hFileOut, unsigned char *outbuf, int outbuflen) { static char inbuffer[IBUFSIZE+OBUFSIZE]; char *outbuffer; __int64 outbuffer_len=outbuf?outbuflen:OBUFSIZE; __int64 retval=0; __int64 input_len; outbuffer = outbuf?(char*)outbuf:(inbuffer+IBUFSIZE); if (offset>=0) { SetSelfFilePointer(g_blocks[NB_DATA].offset+offset); } if (!ReadSelfFile((LPVOID)&input_len,sizeof(__int64))) return -3; #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT if (input_len & COMPRESSED_FLAG_MARK /* 0x80000000*/) // compressed , modified by yew { TCHAR progress[64]; __int64 input_len_total; DWORD ltc = GetTickCount(), tc; inflateReset(&g_inflate_stream); input_len_total = input_len &= /*0x7fffffff*/~COMPRESSED_FLAG_MARK; // take off top bit. while (input_len > 0) { __int64 l=min(input_len,(__int64)IBUFSIZE); int err; if (!ReadSelfFile((LPVOID)inbuffer,l)) return -3; g_inflate_stream.next_in = inbuffer; g_inflate_stream.avail_in = l; input_len-=l; 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; tc = GetTickCount(); if (g_exec_flags.status_update & 1 && (tc - ltc > 200 || !input_len)) { wsprintf(progress, _T("... %d%%"), (input_len_total - input_len) * 100/input_len_total); update_status_text(0, progress); ltc = tc; } // if there's no output, more input is needed if (!u) break; if (!outbuf) { DWORD r; 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 (err==Z_STREAM_END) return retval; } } } else #endif//NSIS_CONFIG_COMPRESSION_SUPPORT { if (!outbuf) { while (input_len > 0) { DWORD l=min(input_len,outbuffer_len); DWORD t; if (!ReadSelfFile((LPVOID)inbuffer,l)) return -3; if (!WriteFile(hFileOut,inbuffer,l,&t,NULL) || l!=t) return -2; retval+=l; input_len-=l; } } else { int l=min(input_len,outbuflen); if (!ReadSelfFile((LPVOID)outbuf,l)) return -3; retval=l; } } return retval; }
const TCHAR * NSISCALL loadHeaders(int cl_flags) { __int64 left; #ifdef NSIS_CONFIG_CRC_SUPPORT crc32_t crc = 0; int do_crc = 0; #endif//NSIS_CONFIG_CRC_SUPPORT void *data; firstheader h; header *header; dataheader dh; HANDLE db_hFile; #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT verify_time = GetTickCount() + 1000; #endif #endif//NSIS_CONFIG_CRC_SUPPORT GetModuleFileName(NULL, state_exe_path, NSIS_MAX_STRLEN); g_db_hFile = db_hFile = myOpenFile(state_exe_path, GENERIC_READ, OPEN_EXISTING); if (db_hFile == INVALID_HANDLE_VALUE) { return _LANG_CANTOPENSELF; } mystrcpy(state_exe_directory, state_exe_path); mystrcpy(state_exe_file, trimslashtoend(state_exe_directory)); GetFileSizeEx(db_hFile, (LARGE_INTEGER*)&m_length); left = m_length; while (left > 0) { static char temp[32768*32]; // modified by yew: for fast crc DWORD l = min(left, (g_filehdrsize ? sizeof(temp) : 512)); if (!ReadSelfFile(temp, l)) { #if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT) handle_ver_dlg(TRUE); #endif//NSIS_CONFIG_CRC_SUPPORT return _LANG_INVALIDCRC; } if (!g_filehdrsize) { mini_memcpy(&h, temp, sizeof(firstheader)); if ( (h.flags & (~FH_FLAGS_MASK)) == 0 && h.siginfo == FH_SIG && h.nsinst[2] == FH_INT3 && h.nsinst[1] == FH_INT2 && h.nsinst[0] == FH_INT1 ) { g_filehdrsize = m_pos; #if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_CONFIG_SILENT_SUPPORT) cl_flags |= h.flags; #endif #ifdef NSIS_CONFIG_SILENT_SUPPORT g_exec_flags.silent |= cl_flags & FH_FLAGS_SILENT; #endif if (h.length_of_all_following_data > left) return _LANG_INVALIDCRC; #ifdef NSIS_CONFIG_CRC_SUPPORT if ((cl_flags & FH_FLAGS_FORCE_CRC) == 0) { if (cl_flags & FH_FLAGS_NO_CRC) break; } do_crc++; #ifndef NSIS_CONFIG_CRC_ANAL left = h.length_of_all_following_data - 4; // end crc checking at crc :) this means you can tack stuff on the end and it'll still work. #else //!NSIS_CONFIG_CRC_ANAL left -= 4; #endif//NSIS_CONFIG_CRC_ANAL // this is in case the end part is < 512 bytes. if (l > left) l=left; #else//!NSIS_CONFIG_CRC_SUPPORT // no crc support, no need to keep on reading break; #endif//!NSIS_CONFIG_CRC_SUPPORT } } #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT else if ((cl_flags & FH_FLAGS_SILENT) == 0) #endif//NSIS_CONFIG_SILENT_SUPPORT { handle_ver_dlg(FALSE); } #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifndef NSIS_CONFIG_CRC_ANAL if (left < m_length) #endif//NSIS_CONFIG_CRC_ANAL crc = CRC32(crc, (unsigned char*)temp, l); #endif//NSIS_CONFIG_CRC_SUPPORT m_pos += l; left -= l; } #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_CRC_SUPPORT handle_ver_dlg(TRUE); #endif//NSIS_CONFIG_CRC_SUPPORT #endif//NSIS_CONFIG_VISIBLE_SUPPORT if (!g_filehdrsize) return _LANG_INVALIDCRC; #ifdef NSIS_CONFIG_CRC_SUPPORT if (do_crc) { crc32_t fcrc; SetSelfFilePointer(m_pos); if (!ReadSelfFile(&fcrc, sizeof(crc32_t)) || crc != fcrc) return _LANG_INVALIDCRC; } #endif//NSIS_CONFIG_CRC_SUPPORT data = (void *)GlobalAlloc(GPTR,h.length_of_header); #ifdef NSIS_COMPRESS_WHOLE inflateReset(&g_inflate_stream); { TCHAR fno[MAX_PATH]; my_GetTempFileName(fno, state_temp_dir); dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL); if (dbd_hFile == INVALID_HANDLE_VALUE) return _LANG_ERRORWRITINGTEMP; } dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader)); #ifdef NSIS_CONFIG_CRC_SUPPORT dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((h.flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(crc32_t)); #else dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data; #endif//NSIS_CONFIG_CRC_SUPPORT #else SetSelfFilePointer(g_filehdrsize + sizeof(firstheader)); #endif//NSIS_COMPRESS_WHOLE if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header) { return _LANG_INVALIDCRC; } header = g_header = data; g_flags = header->flags; #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (h.flags & FH_FLAGS_UNINSTALL) g_is_uninstaller++; #endif // set offsets to real memory offsets rather than installer's header offset left = BLOCKS_NUM; while (left--) header->blocks[left].offset += (int)data; m_file_mapping.first = NULL; m_file_mapping.cur = NULL; m_file_mapping.LoadFinished = FALSE; #ifdef NSIS_COMPRESS_WHOLE header->blocks[NB_DATA].offset = dbd_pos; #else if (h.flags & FH_FLAGS_DATA_FILE) { LPTSTR psz,psz2; int cur_index= 1; __int64 length; while(1) { CloseHandle(g_db_hFile); mystrcpy(m_data_file_path, state_exe_directory); mystrcat(m_data_file_path, _T("\\setup-.bin")); psz =_tcsrchr(m_data_file_path,'\\'); if (psz==NULL) psz=m_data_file_path; while (psz2=_tcschr(psz+1,'.')) { psz = psz2; } wsprintf(psz,_T("%u.bin"),cur_index); g_db_hFile = db_hFile = myOpenFile(m_data_file_path, GENERIC_READ, OPEN_EXISTING); if (db_hFile == INVALID_HANDLE_VALUE) { return _LANG_CANTOPENSELF; } if (!ReadSelfFile(&dh, sizeof(dh))) {// read out the data file header return _LANG_INVALIDCRC; } if (cur_index==1) { m_length = dh.total_length; } if (!GetFileSizeEx(db_hFile,(LARGE_INTEGER*)&length) || length!=dh.length+sizeof(dataheader) || dh.volume_index!=cur_index) {// check the whole file length return _LANG_INVALIDCRC; } if (m_file_mapping.first==NULL) {// it's the first time to meet a data file m_file_mapping.cur = GlobalAlloc(GPTR,sizeof(struct FileMapping)); m_file_mapping.first = m_file_mapping.cur; } else {// push the new data file to the end, and replace the current one m_file_mapping.cur->next = GlobalAlloc(GPTR,sizeof(struct FileMapping)); m_file_mapping.cur = m_file_mapping.cur->next; } mini_memcpy(&m_file_mapping.cur->dh,&dh,sizeof(dh)); m_file_mapping.cur->next = NULL; #ifdef NSIS_CONFIG_CRC_SUPPORT if (do_crc) { __int64 cur_length= 0; crc = 0; while (cur_length<dh.length) { static char temp[32768*32]; // modified by yew: for fast crc DWORD l = min(dh.length-cur_length, sizeof(temp)); if (!ReadSelfFile(temp, l)) { #if defined(NSIS_CONFIG_VISIBLE_SUPPORT) handle_ver_dlg(TRUE); #endif return _LANG_INVALIDCRC; } #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT if ((cl_flags & FH_FLAGS_SILENT) == 0) #endif//NSIS_CONFIG_SILENT_SUPPORT { handle_ver_dlg(FALSE); } #endif//NSIS_CONFIG_VISIBLE_SUPPORT crc = CRC32(crc, (unsigned char*)temp, l); m_pos += l; cur_length += l; } if (dh.crc != crc) return _LANG_INVALIDCRC; } #endif//NSIS_CONFIG_CRC_SUPPORT if (cur_index<dh.total_volume) cur_index++;// need to check next file else break; } #ifdef NSIS_CONFIG_CRC_SUPPORT if (do_crc) { #ifdef NSIS_CONFIG_VISIBLE_SUPPORT handle_ver_dlg(TRUE); #endif//NSIS_CONFIG_VISIBLE_SUPPORT } #endif//NSIS_CONFIG_CRC_SUPPORT // re-open the first file if (cur_index!=1) { CloseHandle(g_db_hFile); mystrcpy(m_data_file_path, state_exe_directory); mystrcat(m_data_file_path, _T("\\setup-.bin")); psz =_tcsrchr(m_data_file_path,'\\'); if (psz==NULL) psz=m_data_file_path; while (psz2=_tcschr(psz+1,'.')) { psz = psz2; } wsprintf(psz,_T("%u.bin"),1); g_db_hFile = db_hFile = myOpenFile(m_data_file_path, GENERIC_READ, OPEN_EXISTING); } m_file_mapping.cur = m_file_mapping.first;// reset the current mapping to the first one m_file_mapping.LoadFinished = TRUE;// if there is no data file, keep it to be FALSE always header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_BEGIN); m_file_mapping.cur_offset = 0; } header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT); #endif mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks)); return 0; }
static int NSISCALL __ensuredata(int amount) { #ifdef NSIS_CONFIG_VISIBLE_SUPPORT HWND hwnd=NULL; unsigned int verify_time=GetTickCount()+500; #endif int needed=amount-(dbd_size-dbd_pos); if (needed>0) { SetSelfFilePointer(dbd_srcpos); SetFilePointer(dbd_hFile,dbd_size,NULL,FILE_BEGIN); m_length=needed; m_pos=0; for (;;) { int err; int l=min(IBUFSIZE,dbd_fulllen-dbd_srcpos); if (!ReadSelfFile((LPVOID)_inbuffer,l)) return -1; dbd_srcpos+=l; g_inflate_stream.next_in=_inbuffer; g_inflate_stream.avail_in=l; do { DWORD r,t; #ifdef NSIS_CONFIG_VISIBLE_SUPPORT if (g_header) #ifdef NSIS_CONFIG_SILENT_SUPPORT if (!g_exec_flags.silent) #endif { if (hwnd) { m_pos=m_length-(amount-(dbd_size-dbd_pos)); MessageLoop(0); } else if (GetTickCount() > verify_time) { hwnd = CreateDialogParam( g_hInstance, MAKEINTRESOURCE(IDD_VERIFY), 0, verProc, g_hwnd ? 0 : (LPARAM)_LANG_UNPACKING ); } } #endif//NSIS_CONFIG_VISIBLE_SUPPORT g_inflate_stream.next_out=_outbuffer; g_inflate_stream.avail_out=OBUFSIZE; err=inflate(&g_inflate_stream); if (err<0) { return -3; } r=(DWORD)g_inflate_stream.next_out-(DWORD)_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 || !l) 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); } #ifdef NSIS_CONFIG_VISIBLE_SUPPORT if (hwnd) { m_pos=m_length; SendMessage(hwnd,WM_TIMER,0,0); DestroyWindow(hwnd); } #endif//NSIS_CONFIG_VISIBLE_SUPPORT return 0; }
const char * NSISCALL loadHeaders(int cl_flags) { #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT HWND hwnd = 0; unsigned int verify_time = GetTickCount() + 1000; #endif crc32_t crc = 0; int do_crc = 0; #endif//NSIS_CONFIG_CRC_SUPPORT int left; void *data; firstheader h; header *header; HANDLE db_hFile; GetModuleFileName(NULL, state_exe_path, NSIS_MAX_STRLEN); g_db_hFile = db_hFile = myOpenFile(state_exe_path, GENERIC_READ, OPEN_EXISTING); if (db_hFile == INVALID_HANDLE_VALUE) { return _LANG_CANTOPENSELF; } mystrcpy(state_exe_directory, state_exe_path); mystrcpy(state_exe_file, trimslashtoend(state_exe_directory)); left = m_length = GetFileSize(db_hFile,NULL); while (left > 0) { static char temp[32768]; DWORD l = min(left, (g_filehdrsize ? 32768 : 512)); if (!ReadSelfFile(temp, l)) { #if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT) if (hwnd) DestroyWindow(hwnd); #endif//NSIS_CONFIG_CRC_SUPPORT return _LANG_INVALIDCRC; } if (!g_filehdrsize) { mini_memcpy(&h, temp, sizeof(firstheader)); if ( (h.flags & (~FH_FLAGS_MASK)) == 0 && h.siginfo == FH_SIG && h.nsinst[2] == FH_INT3 && h.nsinst[1] == FH_INT2 && h.nsinst[0] == FH_INT1 ) { g_filehdrsize = m_pos; #if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_CONFIG_SILENT_SUPPORT) cl_flags |= h.flags; #endif #ifdef NSIS_CONFIG_SILENT_SUPPORT g_exec_flags.silent |= cl_flags & FH_FLAGS_SILENT; #endif if (h.length_of_all_following_data > left) return _LANG_INVALIDCRC; #ifdef NSIS_CONFIG_CRC_SUPPORT if ((cl_flags & FH_FLAGS_FORCE_CRC) == 0) { if (cl_flags & FH_FLAGS_NO_CRC) break; } do_crc++; #ifndef NSIS_CONFIG_CRC_ANAL left = h.length_of_all_following_data - 4; // end crc checking at crc :) this means you can tack shit on the end and it'll still work. #else //!NSIS_CONFIG_CRC_ANAL left -= 4; #endif//NSIS_CONFIG_CRC_ANAL // this is in case the end part is < 512 bytes. if (l > (DWORD)left) l=(DWORD)left; #else//!NSIS_CONFIG_CRC_SUPPORT // no crc support, no need to keep on reading break; #endif//!NSIS_CONFIG_CRC_SUPPORT } } #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT else if ((cl_flags & FH_FLAGS_SILENT) == 0) #endif//NSIS_CONFIG_SILENT_SUPPORT { if (hwnd) { MessageLoop(0); } else if (GetTickCount() > verify_time) hwnd = CreateDialogParam( g_hInstance, MAKEINTRESOURCE(IDD_VERIFY), 0, verProc, (LPARAM)_LANG_VERIFYINGINST ); } #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifndef NSIS_CONFIG_CRC_ANAL if (left < m_length) #endif//NSIS_CONFIG_CRC_ANAL crc = CRC32(crc, temp, l); #endif//NSIS_CONFIG_CRC_SUPPORT m_pos += l; left -= l; } #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_CRC_SUPPORT if (hwnd) { DestroyWindow(hwnd); } #endif//NSIS_CONFIG_CRC_SUPPORT #endif//NSIS_CONFIG_VISIBLE_SUPPORT if (!g_filehdrsize) return _LANG_INVALIDCRC; #ifdef NSIS_CONFIG_CRC_SUPPORT if (do_crc) { crc32_t fcrc; SetSelfFilePointer(m_pos); if (!ReadSelfFile(&fcrc, sizeof(crc32_t)) || crc != fcrc) return _LANG_INVALIDCRC; } #endif//NSIS_CONFIG_CRC_SUPPORT data = (void *)GlobalAlloc(GPTR,h.length_of_header); #ifdef NSIS_COMPRESS_WHOLE inflateReset(&g_inflate_stream); { char fno[MAX_PATH]; my_GetTempFileName(fno, state_temp_dir); dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL); if (dbd_hFile == INVALID_HANDLE_VALUE) return _LANG_ERRORWRITINGTEMP; } dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader)); #ifdef NSIS_CONFIG_CRC_SUPPORT dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((h.flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(crc32_t)); #else dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data; #endif//NSIS_CONFIG_CRC_SUPPORT #else SetSelfFilePointer(g_filehdrsize + sizeof(firstheader)); #endif//NSIS_COMPRESS_WHOLE if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header) { return _LANG_INVALIDCRC; } header = g_header = data; g_flags = header->flags; #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (h.flags & FH_FLAGS_UNINSTALL) g_is_uninstaller++; #endif // set offsets to real memory offsets rather than installer's header offset left = BLOCKS_NUM; while (left--) header->blocks[left].offset += (int)data; #ifdef NSIS_COMPRESS_WHOLE header->blocks[NB_DATA].offset = dbd_pos; #else header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT); #endif mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks)); return 0; }
int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen) { static char inbuffer[IBUFSIZE+OBUFSIZE]; char *outbuffer; int outbuffer_len=outbuf?outbuflen:OBUFSIZE; int retval=0; int input_len; outbuffer = outbuf?outbuf:(inbuffer+IBUFSIZE); if (offset>=0) { SetSelfFilePointer(g_blocks[NB_DATA].offset+offset); } if (!ReadSelfFile((LPVOID)&input_len,sizeof(int))) return -3; #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT if (input_len & 0x80000000) // compressed { char progress[64]; int input_len_total; DWORD ltc = GetTickCount(), tc; inflateReset(&g_inflate_stream); input_len_total = input_len &= 0x7fffffff; // take off top bit. while (input_len > 0) { int l=min(input_len,IBUFSIZE); int err; if (!ReadSelfFile((LPVOID)inbuffer,l)) return -3; g_inflate_stream.next_in = inbuffer; g_inflate_stream.avail_in = l; input_len-=l; 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; tc = GetTickCount(); if (ui_st_updateflag & 1 && (tc - ltc > 200 || !input_len)) { wsprintf(progress, "... %d%%", MulDiv(input_len_total - input_len, 100, input_len_total)); update_status_text(0, progress); ltc = tc; } // if there's no output, more input is needed if (!u) break; if (!outbuf) { DWORD r; 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 #endif//NSIS_CONFIG_COMPRESSION_SUPPORT { if (!outbuf) { while (input_len > 0) { DWORD l=min(input_len,outbuffer_len); DWORD t; if (!ReadSelfFile((LPVOID)inbuffer,l)) return -3; if (!WriteFile(hFileOut,inbuffer,l,&t,NULL) || l!=t) return -2; retval+=l; input_len-=l; } } else { int l=min(input_len,outbuflen); if (!ReadSelfFile((LPVOID)outbuf,l)) return -3; retval=l; } } return retval; }