__int64 NSISCALL SetSelfFilePointer(__int64 lDistanceToMove) { __int64 ret; if (!m_file_mapping.LoadFinished) { SetFilePointerEx(g_db_hFile,*(LARGE_INTEGER*)&lDistanceToMove,(LARGE_INTEGER*)&ret,FILE_BEGIN); return ret; } // need to check the valid range if (lDistanceToMove>=(m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume && lDistanceToMove<(m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume+m_file_mapping.cur->dh.length) { // it's okay, locate in the current file m_file_mapping.cur_offset = lDistanceToMove; lDistanceToMove -= (m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume; // convert to the local offset lDistanceToMove += sizeof(dataheader); SetFilePointerEx(g_db_hFile,*(LARGE_INTEGER*)&lDistanceToMove,(LARGE_INTEGER*)&ret,FILE_BEGIN); return /*m_file_mapping.cur_offset*/0;// the return is ignored } // open the correct file m_file_mapping.cur = m_file_mapping.first; while(m_file_mapping.cur) { if (lDistanceToMove>=(m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume && lDistanceToMove<(m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume+m_file_mapping.cur->dh.length) { // found it LPTSTR psz,psz2; 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"),m_file_mapping.cur->dh.volume_index); g_db_hFile = myOpenFile(m_data_file_path, GENERIC_READ, OPEN_EXISTING); m_file_mapping.cur_offset = lDistanceToMove; lDistanceToMove -= (m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume; // convert to the local offset lDistanceToMove += sizeof(dataheader); SetFilePointerEx(g_db_hFile,*(LARGE_INTEGER*)&lDistanceToMove,(LARGE_INTEGER*)&ret,FILE_BEGIN); return /*m_file_mapping.cur_offset*/0;//the return is ignored } m_file_mapping.cur = m_file_mapping.cur->next; } assert(!"shouldn't happen"); return 0; }
BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) { DWORD rd,i; if (!m_file_mapping.LoadFinished) { return ReadFile(g_db_hFile,lpBuffer,nNumberOfBytesToRead,&rd,NULL) && (rd == nNumberOfBytesToRead); } for (i=0;i<nNumberOfBytesToRead;) { __int64 offset=m_file_mapping.cur_offset-(m_file_mapping.cur->dh.volume_index-1)*m_file_mapping.cur->dh.length_per_volume; if (offset < m_file_mapping.cur->dh.length) { // there is still some data,read them first DWORD l= min(m_file_mapping.cur->dh.length-offset,(__int64)nNumberOfBytesToRead-i); if (!ReadFile(g_db_hFile,lpBuffer,l,&rd,NULL) || (rd != l)) return FALSE; i += l; m_file_mapping.cur_offset += l; lpBuffer = (char*)lpBuffer + l; } else { LPTSTR psz,psz2; assert(m_file_mapping.cur->next); m_file_mapping.cur = m_file_mapping.cur->next; 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"),m_file_mapping.cur->dh.volume_index); g_db_hFile = myOpenFile(m_data_file_path, GENERIC_READ, OPEN_EXISTING); SetFilePointer(g_db_hFile,sizeof(dataheader),NULL,FILE_BEGIN); } } return TRUE; }
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; }
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 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow) { static int ret; static const char *m_Err; #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT static HWND hwnd; #endif static int crc; static char no_crc; static char do_crc; #endif//NSIS_CONFIG_CRC_SUPPORT #if defined(NSIS_CONFIG_SILENT_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT) static char silent; #endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT int left; #ifdef NSIS_CONFIG_VISIBLE_SUPPORT unsigned int verify_time=GetTickCount()+1000; #endif char *cmdline=state_command_line; char *realcmds; char seekchar=' '; InitCommonControls(); lstrcpyn(state_command_line,GetCommandLine(),NSIS_MAX_STRLEN); if (*cmdline == '\"') seekchar = *cmdline++; while (*cmdline && *cmdline != seekchar) if (*cmdline) cmdline++; if (*cmdline) cmdline++; realcmds=cmdline; do { #ifdef NSIS_CONFIG_CRC_SUPPORT #endif//NSIS_CONFIG_CRC_SUPPORT while (*cmdline == ' ') if (*cmdline) cmdline++; if (cmdline[0] != '/') break; cmdline++; #if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT) if (cmdline[0] == 'S' && (cmdline[1] == ' ' || !cmdline[1])) { silent++; cmdline+=2; } else #endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_CRC_SUPPORT if (cmdline[0] == 'N' && cmdline[1] == 'C' && cmdline[2] == 'R' && cmdline[3] == 'C' && (cmdline[4] == ' ' || !cmdline[4])) { no_crc++; cmdline+=4; } else #endif//NSIS_CONFIG_CRC_SUPPORT if (cmdline[0] == 'D' && cmdline[1] == '=') { cmdline[-2]=0; // keep this from being passed to uninstaller if necessary lstrcpy(state_install_directory,cmdline+2); cmdline+=lstrlen(cmdline); } else while (*cmdline && *cmdline != ' ') if (*cmdline) cmdline++; } while (*cmdline); lstrcpy(g_caption,_LANG_GENERIC_ERROR); g_hInstance=GetModuleHandle(NULL); GetModuleFileName(g_hInstance,state_exe_directory,NSIS_MAX_STRLEN); g_db_hFile=myOpenFile(state_exe_directory,GENERIC_READ,OPEN_EXISTING); if (g_db_hFile==INVALID_HANDLE_VALUE) { m_Err = _LANG_CANTOPENSELF; goto end; } // make state_exe_directory point to dir, not full exe. trimslashtoend(state_exe_directory); left = m_length = GetFileSize(g_db_hFile,NULL); while (left > 0) { static char temp[512]; DWORD l=left; if (l > 512) l=512; if (!ReadFile(g_db_hFile,temp,l,&l,NULL)) { m_Err=g_crcinvalid; #if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT) if (hwnd) DestroyWindow(hwnd); #endif//NSIS_CONFIG_CRC_SUPPORT goto end; } if (!g_filehdrsize) { int dbl; dbl=isheader((firstheader*)temp); if (dbl) { int a=*(int*)temp; g_filehdrsize=m_pos; if (dbl > left) { m_Err=g_crcinvalid; goto end; } #if defined(NSIS_CONFIG_SILENT_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT) if (a&FH_FLAGS_SILENT) silent++; #endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_CRC_SUPPORT // Changed by Amir Szekely 23rd July 2002 (CRCCheck force) if ((no_crc && !(a&FH_FLAGS_FORCE_CRC)) || !(a&FH_FLAGS_CRC)) break; // if first bit is not set, then no crc checking. do_crc++; #ifndef NSIS_CONFIG_CRC_ANAL left=dbl-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 break; #endif//!NSIS_CONFIG_CRC_SUPPORT } } #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT else if (!silent) #endif//NSIS_CONFIG_SILENT_SUPPORT { if (hwnd) { static MSG msg; while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) DispatchMessage(&msg); } else if (GetTickCount() > verify_time) hwnd=CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_VERIFY),GetDesktopWindow(),verProc); } #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) m_Err=g_crcinvalid; else { #ifdef NSIS_CONFIG_CRC_SUPPORT if (do_crc) { DWORD l; int fcrc; SetFilePointer(g_db_hFile,m_pos,NULL,FILE_BEGIN); if (!ReadFile(g_db_hFile,&fcrc,4,&l,NULL) || crc != fcrc) { m_Err=g_crcinvalid; goto end; } } #endif//NSIS_CONFIG_CRC_SUPPORT SetFilePointer(g_db_hFile,g_filehdrsize,NULL,FILE_BEGIN); if (loadHeaders()) m_Err=g_crcinvalid; } if (m_Err) goto end; #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (g_is_uninstaller) { if (cmdline[0] == '_' && cmdline[1] == '=' && cmdline[2]) { cmdline[-1]=0; cmdline+=2; if (is_valid_instpath(cmdline)) { lstrcpy(state_install_directory,cmdline); lstrcpy(state_output_directory,cmdline); } else { m_Err = g_errorcopyinginstall; goto end; } } else { int x,done=0; for (x = 0; x < 26; x ++) { static char s[]="A~NSISu_.exe"; static char buf2[NSIS_MAX_STRLEN*2]; static char ibuf[NSIS_MAX_STRLEN]; buf2[0]='\"'; GetTempPath(sizeof(buf2)-1,buf2+1); lstrcat(buf2,s); DeleteFile(buf2+1); // clean up after all the other ones if they are there if (!done) { // get current name int l=GetModuleFileName(g_hInstance,ibuf,sizeof(ibuf)); // check if it is ?~NSISu_.exe - if so, f**k it if (!lstrcmpi(ibuf+l-(sizeof(s)-2),s+1)) break; // copy file if (CopyFile(ibuf,buf2+1,FALSE)) { HANDLE hProc; #ifdef NSIS_SUPPORT_MOVEONREBOOT MoveFileOnReboot(buf2+1,NULL); #endif if (state_install_directory[0]) lstrcpy(ibuf,state_install_directory); else trimslashtoend(ibuf); if (!is_valid_instpath(ibuf)) break; done++; lstrcat(buf2,"\" "); lstrcat(buf2,realcmds); lstrcat(buf2," _="); lstrcat(buf2,ibuf); GetTempPath(sizeof(ibuf),ibuf); hProc=myCreateProcess(buf2,ibuf); if (hProc) CloseHandle(hProc); else m_Err = g_errorcopyinginstall; } } s[0]++; } if (!done) m_Err=g_errorcopyinginstall; goto end; } } #endif//NSIS_CONFIG_UNINSTALL_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT if (!g_inst_cmnheader->silent_install) g_inst_cmnheader->silent_install=silent; #endif//NSIS_CONFIG_SILENT_SUPPORT #endif//NSIS_CONFIG_VISIBLE_SUPPORT ret=ui_doinstall(); #ifdef NSIS_CONFIG_LOG log_write(1); #endif//NSIS_CONFIG_LOG end: if (g_db_hFile!=INVALID_HANDLE_VALUE) CloseHandle(g_db_hFile); #ifdef NSIS_COMPRESS_WHOLE if (dbd_hFile!=INVALID_HANDLE_VALUE) CloseHandle(dbd_hFile); #endif if (m_Err) MessageBox(NULL,m_Err,g_caption,MB_OK|MB_ICONSTOP); ExitProcess(ret); }
/** Modifies the wininit.ini file to rename / delete a file. * * @param prevName The previous / current name of the file. * @param newName The new name to move the file to. If NULL, the current file * will be deleted. */ void RenameViaWininit(const TCHAR* prevName, const TCHAR* newName) { static char szRenameLine[1024]; static TCHAR wininit[1024]; static TCHAR tmpbuf[1024]; int cchRenameLine; LPCSTR szRenameSec = "[Rename]\r\n"; // rename section marker HANDLE hfile; DWORD dwFileSize; SIZE_T dwBytes; DWORD dwRenameLinePos; char *pszWinInit; // Contains the file contents of wininit.ini int spn; // length of the short path name in TCHARs. lstrcpy(tmpbuf, _T("NUL")); if (newName) { // create the file if it's not already there to prevent GetShortPathName from failing CloseHandle(myOpenFile(newName,0,CREATE_NEW)); spn = GetShortPathName(newName,tmpbuf,1024); if (!spn || spn > 1024) return; } // wininit is used as a temporary here spn = GetShortPathName(prevName,wininit,1024); if (!spn || spn > 1024) return; #ifdef _UNICODE cchRenameLine = wsprintfA(szRenameLine, "%ls=l%s\r\n", tmpbuf, wininit); #else cchRenameLine = wsprintfA(szRenameLine, "%s=%s\r\n", tmpbuf, wininit); #endif // Get the path to the wininit.ini file. GetWindowsDirectory(wininit, 1024-16); lstrcat(wininit, _T("\\wininit.ini")); hfile = myOpenFile(wininit, GENERIC_READ | GENERIC_WRITE, OPEN_ALWAYS); if (hfile != INVALID_HANDLE_VALUE) { // We are now working on the Windows wininit file dwFileSize = GetFileSize(hfile, NULL); pszWinInit = (char*) GlobalAlloc(GPTR, dwFileSize + cchRenameLine + 10); if (pszWinInit != NULL) { if (ReadFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL) && dwFileSize == dwBytes) { // Look for the rename section in the current file. LPSTR pszRenameSecInFile = mystrstriA(pszWinInit, szRenameSec); if (pszRenameSecInFile == NULL) { // No rename section. So we add it to the end of file. lstrcpyA(pszWinInit+dwFileSize, szRenameSec); dwFileSize += 10; dwRenameLinePos = dwFileSize; } else { // There is a rename section, but is there another section after it? char *pszFirstRenameLine = pszRenameSecInFile+10; char *pszNextSec = mystrstriA(pszFirstRenameLine,"\n["); if (pszNextSec) { char *p = pszWinInit + dwFileSize; char *pEnd = pszWinInit + dwFileSize + cchRenameLine; while (p > pszNextSec) { *pEnd-- = *p--; } dwRenameLinePos = pszNextSec - pszWinInit + 1; // +1 for the \n } // rename section is last, stick item at end of file else dwRenameLinePos = dwFileSize; } mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine); dwFileSize += cchRenameLine; SetFilePointer(hfile, 0, NULL, FILE_BEGIN); WriteFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL); GlobalFree(pszWinInit); } } CloseHandle(hfile); } }
/** Modifies the wininit.ini file to rename / delete a file. * * @param prevName The previous / current name of the file. * @param newName The new name to move the file to. If NULL, the current file * will be deleted. */ void RenameViaWininit(TCHAR* prevName, TCHAR* newName) { static char szRenameLine[1024]; static TCHAR wininit[1024]; static TCHAR tmpbuf[1024]; #ifdef _UNICODE static char shortExisting[1024]; static char shortNew[1024]; #endif int cchRenameLine; static const char szRenameSec[] = "[Rename]\r\n"; // rename section marker HANDLE hfile; DWORD dwFileSize; DWORD dwBytes; DWORD dwRenameLinePos; char *pszWinInit; // Contains the file contents of wininit.ini int spn; // length of the short path name in TCHARs. lstrcpy(tmpbuf, _T("NUL")); if (newName) { // create the file if it's not already there to prevent GetShortPathName from failing CloseHandle(myOpenFile(newName,0,CREATE_NEW)); spn = GetShortPathName(newName,tmpbuf,1024); if (!spn || spn > 1024) return; } // wininit is used as a temporary here spn = GetShortPathName(prevName,wininit,1024); if (!spn || spn > 1024) return; // Because wininit.ini is an ASCII text file, we need to be careful what we // convert here to TCHARs. #ifdef _UNICODE // The short name produced by GetShortPathName is always in the ASCII range // of characters. // Convert short name of new name to ANSI if (WideCharToMultiByte(CP_ACP, 0, tmpbuf, -1, shortNew, sizeof(shortNew), NULL, NULL) == 0) { // We have a failure in conversion to ANSI return; } // Convert short name of old name to ANSI if (WideCharToMultiByte(CP_ACP, 0, wininit, -1, shortExisting, sizeof(shortExisting), NULL, NULL) == 0) { // We have a failure in conversion to ANSI return; } cchRenameLine = wsprintfA(szRenameLine, "%s=%s\r\n", shortNew, shortExisting); #else cchRenameLine = wsprintfA(szRenameLine, "%s=%s\r\n", tmpbuf, wininit); #endif // Get the path to the wininit.ini file. GetWindowsDirectory(wininit, 1024-16); lstrcat(wininit, _T("\\wininit.ini")); hfile = myOpenFile(wininit, GENERIC_READ | GENERIC_WRITE, OPEN_ALWAYS); if (hfile != INVALID_HANDLE_VALUE) { // We are now working on the Windows wininit file dwFileSize = GetFileSize(hfile, NULL); pszWinInit = (char*) GlobalAlloc(GPTR, dwFileSize + cchRenameLine + 10); if (pszWinInit != NULL) { if (ReadFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL) && dwFileSize == dwBytes) { // Look for the rename section in the current file. LPSTR pszRenameSecInFile = mystrstriA(pszWinInit, szRenameSec); if (pszRenameSecInFile == NULL) { // No rename section. So we add it to the end of file. lstrcpyA(pszWinInit+dwFileSize, szRenameSec); dwFileSize += 10; dwRenameLinePos = dwFileSize; } else { // There is a rename section, but is there another section after it? char *pszFirstRenameLine = pszRenameSecInFile+10; char *pszNextSec = mystrstriA(pszFirstRenameLine,"\n["); if (pszNextSec) { char *p = pszWinInit + dwFileSize; char *pEnd = pszWinInit + dwFileSize + cchRenameLine; while (p > pszNextSec) { *pEnd-- = *p--; } dwRenameLinePos = pszNextSec - pszWinInit + 1; // +1 for the \n } // rename section is last, stick item at end of file else dwRenameLinePos = dwFileSize; } mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine); dwFileSize += cchRenameLine; SetFilePointer(hfile, 0, NULL, FILE_BEGIN); WriteFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL); GlobalFree(pszWinInit); } } CloseHandle(hfile); } }