static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int dontsetdefstyle; page *thispage = g_this_page; TCHAR *dir = g_usrvars[thispage->parms[4]]; int browse_text = thispage->parms[3]; if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { GetUIText(IDC_DIR,dir); validate_filename(dir); #ifdef NSIS_CONFIG_LOG #if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT) build_g_logfile(); #endif if (GetUIItem(IDC_CHECK1) != NULL) log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1); #endif } if (uMsg == WM_INITDIALOG) { HWND hDir = GetUIItem(IDC_DIR); #ifdef NSIS_CONFIG_LOG if (GetAsyncKeyState(VK_SHIFT)&0x8000) { HWND h=GetUIItem(IDC_CHECK1); SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS); ShowWindow(h,SW_SHOWNA); } #endif if (validpathspec(dir) && !skip_root(dir)) addtrailingslash(dir); // workaround for bug #1209843 // // m_curwnd is only updated once WM_INITDIALOG returns. // my_SetWindowText triggers an EN_CHANGE message that // triggers a WM_IN_UPDATEMSG message that uses m_curwnd // to get the selected directory (GetUIText). // because m_curwnd is still outdated, dir varialble is // filled with an empty string. by default, dir points // to $INSTDIR. // // to solve this, m_curwnd is manually set to the correct // window handle. m_curwnd=hwndDlg; my_SetWindowText(hDir,dir); SetUITextFromLang(IDC_BROWSE,this_page->parms[2]); SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]); SetActiveCtl(hDir); { typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD); SHAutoCompletePtr fSHAutoComplete; fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress(MGA_SHAutoComplete); if (fSHAutoComplete) { fSHAutoComplete(hDir, SHACF_FILESYSTEM); } } } if (uMsg == WM_COMMAND) { int id=LOWORD(wParam); if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE) { uMsg = WM_IN_UPDATEMSG; } if (id == IDC_BROWSE) { static TCHAR bt[NSIS_MAX_STRLEN]; BROWSEINFO bi = {0,}; ITEMIDLIST *idlist; bi.hwndOwner = hwndDlg; bi.pszDisplayName = g_tmp; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)dir; bi.lpszTitle = GetNSISString(bt, browse_text); bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; idlist = SHBrowseForFolder(&bi); if (idlist) { // free idlist CoTaskMemFree(idlist); addtrailingslash(dir); if (g_header->install_directory_auto_append && dir == state_install_directory) // only append to $INSTDIR (bug #1174184) { const TCHAR *post_str = ps_tmpbuf; GetNSISStringTT(g_header->install_directory_auto_append); // display name gives just the folder name if (lstrcmpi(post_str, g_tmp)) { mystrcat(dir, post_str); } } dontsetdefstyle++; SetUITextNT(IDC_DIR,dir); } else { uMsg = WM_IN_UPDATEMSG; } } } if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START) { static TCHAR s[NSIS_MAX_STRLEN]; int error = 0; int available_set = 0; unsigned total, available; GetUIText(IDC_DIR,dir); if (!is_valid_instpath(dir)) error = NSIS_INSTDIR_INVALID; /** * This part is tricky. We need to make sure a few things: * * 1. GetDiskFreeSpaceEx is always called at least once for large HD. * Even if skip_root() returned NULL (e.g. "C:"). * Note that trimslashtoend() will nullify "C:". * 2. GetDiskFreeSpaceEx is called with the deepest valid directory. * e.g. C:\drive when the user types C:\drive\folder1\folder2. * This makes sure NTFS mount points are treated properly (#1946112). * 3. `s' stays valid after the loop for GetDiskFreeSpace. * This means there is no cutting beyond what skip_root() returns. * Or `s' could be recreated when GetDiskFreeSpace is called. * 4. If GetDiskFreeSpaceEx doesn't exist, GetDiskFreeSpace is used. * 5. Both functions require a trailing backslash * 6. `dir' is never modified. * */ mystrcpy(s,dir); // Test for and use the GetDiskFreeSpaceEx API { BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) = myGetProcAddress(MGA_GetDiskFreeSpaceEx); if (GDFSE) { ULARGE_INTEGER available64; ULARGE_INTEGER a, b; TCHAR *p; TCHAR *pw = NULL; while (pw != s) // trimslashtoend() cut the entire string { if (GDFSE(s, &available64, &a, &b)) { #ifndef _NSIS_NO_INT64_SHR available = (int)(available64.QuadPart >> 10); #else available = (int)(Int64ShrlMod32(available64.QuadPart, 10)); #endif available_set++; break; } if (pw) // if pw was set, remove the backslash so trimslashtoend() will cut a new one *pw = 0; p = trimslashtoend(s); // trim last backslash // bring it back, but make the next char null pw = p; *pw = 0; --pw; *pw = _T('\\'); } } } if (!available_set) { DWORD spc, bps, fc, tc; TCHAR *root; // GetDiskFreeSpaceEx accepts any path, but GetDiskFreeSpace accepts only the root mystrcpy(s,dir); root=skip_root(s); if (root) *root=0; // GetDiskFreeSpaceEx is not available if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc)) { available = (int)MulDiv(bps * spc, fc, 1 << 10); available_set++; } } total = (unsigned) sumsecsfield(size_kb); #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // available_set is checked first so available is initialized #endif if (available_set && available < total) error = NSIS_INSTDIR_NOT_ENOUGH_SPACE; #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #pragma GCC diagnostic pop #endif if (LANG_STR_TAB(LANG_SPACE_REQ)) { SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total); if (available_set) SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available); else SetUITextNT(IDC_SPACEAVAILABLE,_T("")); } g_exec_flags.instdir_error = error; #ifdef NSIS_SUPPORT_CODECALLBACKS if (!error) error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR); #endif if (thispage->flags & PF_DIR_NO_BTN_DISABLE) error = 0; EnableNext(!error); if (!error && !dontsetdefstyle) SetNextDef(); dontsetdefstyle = 0; }
FORCE_INLINE int NSISCALL ui_doinstall(void) { header *header = g_header; static WNDCLASS wc; // richedit subclassing and bgbg creation // detect default language // more information at: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp LANGID (WINAPI *GUDUIL)(); static const char guduil[] = "GetUserDefaultUILanguage"; GUDUIL = myGetProcAddress(TEXT("KERNEL32.dll"), (char *) guduil); if (GUDUIL) { // Windows ME/2000+ myitoa(state_language, GUDUIL()); } else { *(DWORD*)state_language = CHAR4_TO_DWORD('0', 'x', 0, 0); { // Windows 9x static const TCHAR reg_9x_locale[] = TEXT("Control Panel\\Desktop\\ResourceLocale"); myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, g_tmp); } if (!g_tmp[0]) { // Windows NT // This key exists on 9x as well, so it's only read if ResourceLocale wasn't found static const TCHAR reg_nt_locale_key[] = TEXT(".DEFAULT\\Control Panel\\International"); static const TCHAR reg_nt_locale_val[] = TEXT("Locale"); myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, g_tmp); } mystrcat(state_language, g_tmp); } // set default language set_language(); // initialize auto close flag g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE; // read install directory from registry if (!is_valid_instpath(state_install_directory)) { if (header->install_reg_key_ptr) { myRegGetStr( (HKEY)header->install_reg_rootkey, GetNSISStringNP(header->install_reg_key_ptr), GetNSISStringNP(header->install_reg_value_ptr), ps_tmpbuf ); if (ps_tmpbuf[0]) { TCHAR *p=ps_tmpbuf; TCHAR *e; if (p[0]==TEXT('\"')) { TCHAR *p2; p++; p2 = findchar(p, TEXT('"')); *p2 = 0; } // p is the path now, check for .exe extension e=p+mystrlen(p)-4; if (e > p) { // if filename ends in .exe, and is not a directory, remove the filename if (!lstrcmpi(e, TEXT(".exe"))) // check extension { DWORD d; d=GetFileAttributes(p); if (d == INVALID_FILE_ATTRIBUTES || !(d&FILE_ATTRIBUTE_DIRECTORY)) { // if there is no back-slash, the string will become empty, but that's ok because // it would make an invalid instdir anyway trimslashtoend(p); } } } mystrcpy(state_install_directory,addtrailingslash(p)); } } } if (!is_valid_instpath(state_install_directory)) { GetNSISString(state_install_directory,header->install_directory_ptr); } #ifdef NSIS_CONFIG_LOG if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller) { #if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT) build_g_logfile(); #endif log_dolog=1; } #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED); #ifdef NSIS_SUPPORT_BGBG if (header->bg_color1 != -1) { QTCHAR cn = CHAR4_TO_DWORD(TEXT('_'), TEXT('N'), TEXT('b'), 0); RECT vp; extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM); wc.lpfnWndProc = BG_WndProc; wc.hInstance = g_hInstance; wc.hIcon = g_hIcon; //wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.lpszClassName = (LPCTSTR)&cn; if (!RegisterClass(&wc)) return 0; SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0); m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,(LPCTSTR)&cn,0,WS_POPUP, vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL); } #endif//NSIS_SUPPORT_BGBG #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_SUPPORT_CODECALLBACKS // Select language if (ExecuteCallbackFunction(CB_ONINIT)) return 2; set_language(); #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT if (!g_exec_flags.silent) #endif//NSIS_CONFIG_SILENT_SUPPORT { #ifdef NSIS_SUPPORT_BGBG ShowWindow(m_bgwnd, SW_SHOW); #endif//NSIS_SUPPORT_BGBG #ifdef NSIS_CONFIG_LICENSEPAGE { // load richedit DLL static TCHAR str1[]=TEXT("RichEd20.dll"); #ifdef UNICODE static wchar_t str2[]=L"RichEdit20W"; #else static char str2[]="RichEdit20A"; #endif if (!LoadLibrary(str1)) { *(DTCHAR*)(str1+6) = CHAR2_TO_WORD(TEXT('3'),TEXT('2')); LoadLibrary(str1); } // make richedit20a point to RICHEDIT if (!GetClassInfo(NULL,str2,&wc)) { str2[8]=0; GetClassInfo(NULL,str2,&wc); wc.lpszClassName = str2; str2[8]=TEXT('2'); RegisterClass(&wc); } } #endif { int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) ExecuteCallbackFunction(CB_ONGUIEND); #endif return ret; } } #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT else #endif//NSIS_CONFIG_VISIBLE_SUPPORT { if (install_thread(NULL)) { #ifdef NSIS_SUPPORT_CODECALLBACKS if (!g_quit_flag) ExecuteCallbackFunction(CB_ONINSTFAILED); #endif//NSIS_SUPPORT_CODECALLBACKS return 2; } #ifdef NSIS_SUPPORT_CODECALLBACKS ExecuteCallbackFunction(CB_ONINSTSUCCESS); #endif//NSIS_SUPPORT_CODECALLBACKS return 0; } #endif//NSIS_CONFIG_SILENT_SUPPORT }
FORCE_INLINE int NSISCALL ui_doinstall(void) { header *header = g_header; static WNDCLASS wc; // richedit subclassing and bgbg creation // detect default language // more information at: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp LANGID (WINAPI *GUDUIL)(); GUDUIL = myGetProcAddress(MGA_GetUserDefaultUILanguage); if (GUDUIL) { // Windows ME/2000+ myitoa(state_language, GUDUIL()); } else { static const TCHAR reg_9x_locale[] = _T("Control Panel\\Desktop\\ResourceLocale"); static const TCHAR reg_nt_locale_key[] = _T(".DEFAULT\\Control Panel\\International"); const TCHAR *reg_nt_locale_val = ®_9x_locale[30]; // = _T("Locale") with opt state_language[0] = _T('0'); state_language[1] = _T('x'); state_language[2] = 0; { // Windows 9x myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, g_tmp, 0); } if (!g_tmp[0]) { // Windows NT // This key exists on 9x as well, so it's only read if ResourceLocale wasn't found myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, g_tmp, 0); } mystrcat(state_language, g_tmp); } // set default language set_language(); // initialize auto close flag g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE; #ifdef NSIS_CONFIG_PLUGIN_SUPPORT // initialize plugin api g_exec_flags.plugin_api_version=NSISPIAPIVER_CURR; #endif // read install directory from registry if (!is_valid_instpath(state_install_directory)) { if (header->install_reg_key_ptr) { myRegGetStr( (HKEY)header->install_reg_rootkey, GetNSISStringNP(header->install_reg_key_ptr), GetNSISStringNP(header->install_reg_value_ptr), ps_tmpbuf, 0 ); if (ps_tmpbuf[0]) { TCHAR *p=ps_tmpbuf; TCHAR *e; if (p[0]==_T('\"')) { TCHAR *p2; p++; p2 = findchar(p, _T('"')); *p2 = 0; } // p is the path now, check for .exe extension e=p+mystrlen(p)-4; if (e > p) { // if filename ends in .exe, and is not a directory, remove the filename if (!lstrcmpi(e, _T(".exe"))) // check extension { DWORD d; d=GetFileAttributes(p); if (d == INVALID_FILE_ATTRIBUTES || !(d&FILE_ATTRIBUTE_DIRECTORY)) { // if there is no back-slash, the string will become empty, but that's ok because // it would make an invalid instdir anyway trimslashtoend(p); } } } mystrcpy(state_install_directory,addtrailingslash(p)); } } } if (!is_valid_instpath(state_install_directory)) { GetNSISString(state_install_directory,header->install_directory_ptr); } #ifdef NSIS_CONFIG_LOG if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller) { #if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT) build_g_logfile(); #endif log_dolog=1; } #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED); #ifdef NSIS_SUPPORT_BGBG if (header->bg_color1 != -1) { LPCTSTR cn = _T("_Nb"); RECT vp; extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM); wc.lpfnWndProc = BG_WndProc; wc.hInstance = g_hInstance; wc.hIcon = g_hIcon; //wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.lpszClassName = cn; if (!RegisterClass(&wc)) return 0; SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0); m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,cn,0,WS_POPUP, vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL); } #endif//NSIS_SUPPORT_BGBG #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_SUPPORT_CODECALLBACKS // Select language if (ExecuteCallbackFunction(CB_ONINIT)) return 2; set_language(); #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT if (!g_exec_flags.silent) #endif//NSIS_CONFIG_SILENT_SUPPORT { #ifdef NSIS_SUPPORT_BGBG ShowWindow(m_bgwnd, SW_SHOW); #endif//NSIS_SUPPORT_BGBG #ifdef NSIS_CONFIG_LICENSEPAGE { // load richedit DLL static const TCHAR riched20[]=_T("RichEd20"); static const TCHAR riched32[]=_T("RichEd32"); #ifdef UNICODE static const TCHAR richedit20t[]=_T("RichEdit20W"); #else static const TCHAR richedit20t[]=_T("RichEdit20A"); #endif static const TCHAR richedit[]=_T("RichEdit"); if (!LoadLibrary(riched20)) { LoadLibrary(riched32); // Win95 only ships with v1.0, NT4 has v2.0: web.archive.org/web/20030607222419/http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp } // make richedit20a/w point to RICHEDIT if (!GetClassInfo(NULL,richedit20t,&wc)) { GetClassInfo(NULL,richedit,&wc); wc.lpszClassName = richedit20t; RegisterClass(&wc); } } #endif { int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) ExecuteCallbackFunction(CB_ONGUIEND); #endif #ifdef NSIS_CONFIG_PLUGIN_SUPPORT Plugins_SendMsgToAllPlugins(NSPIM_GUIUNLOAD); #endif return ret; } } #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT else #endif//NSIS_CONFIG_VISIBLE_SUPPORT { if (install_thread(NULL)) { #ifdef NSIS_SUPPORT_CODECALLBACKS if (!g_quit_flag) ExecuteCallbackFunction(CB_ONINSTFAILED); #endif//NSIS_SUPPORT_CODECALLBACKS return 2; } #ifdef NSIS_SUPPORT_CODECALLBACKS ExecuteCallbackFunction(CB_ONINSTSUCCESS); #endif//NSIS_SUPPORT_CODECALLBACKS return 0; } #endif//NSIS_CONFIG_SILENT_SUPPORT }
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; }
int NSISCALL ui_doinstall(void) { header *header = g_header; static WNDCLASS wc; // richedit subclassing and bgbg creation g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE; set_language(); if (!is_valid_instpath(state_install_directory)) { if (header->install_reg_key_ptr) { myRegGetStr( (HKEY)header->install_reg_rootkey, GetNSISStringNP(header->install_reg_key_ptr), GetNSISStringNP(header->install_reg_value_ptr), ps_tmpbuf ); if (ps_tmpbuf[0]) { char *p=ps_tmpbuf; char *e; if (p[0]=='\"') { char *p2=CharNext(p); p=p2; while (*p2 && *p2 != '\"') p2=CharNext(p2); *p2=0; } // p is the path now, check for .exe extension e=p+mystrlen(p)-4; if (e > p) { // if filename ends in .exe, and is not a directory, remove the filename if (!lstrcmpi(e, ".exe")) // check extension { DWORD d; d=GetFileAttributes(p); if (d == (DWORD)-1 || !(d&FILE_ATTRIBUTE_DIRECTORY)) { // if there is no back-slash, the string will become empty, but that's ok because // it would make an invalid instdir anyway trimslashtoend(p); } } } mystrcpy(state_install_directory,p); } } } if (!is_valid_instpath(state_install_directory)) { GetNSISString(state_install_directory,header->install_directory_ptr); } #ifdef NSIS_CONFIG_LOG if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller) { #ifndef NSIS_CONFIG_LOG_ODS build_g_logfile(); #endif log_dolog=1; } #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED); #ifdef NSIS_SUPPORT_BGBG if (header->bg_color1 != -1) { RECT vp; extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM); wc.lpfnWndProc = BG_WndProc; wc.hInstance = g_hInstance; wc.hIcon = g_hIcon; //wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.lpszClassName = "_Nb"; if (!RegisterClass(&wc)) return 0; SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0); m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,"_Nb",0,WS_POPUP, vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL); } #ifdef NSIS_SUPPORT_CODECALLBACKS g_hwnd=m_bgwnd; #endif//NSIS_SUPPORT_CODECALLBACKS #endif//NSIS_SUPPORT_BGBG #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_SUPPORT_CODECALLBACKS // Select language if (ExecuteCodeSegment(header->code_onInit,NULL)) return 1; set_language(); #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_SUPPORT_CODECALLBACKS #ifdef NSIS_SUPPORT_BGBG g_hwnd=NULL; #endif//NSIS_SUPPORT_BGBG #endif//NSIS_SUPPORT_CODECALLBACKS #ifdef NSIS_CONFIG_SILENT_SUPPORT if (!g_exec_flags.silent) #endif//NSIS_CONFIG_SILENT_SUPPORT { #ifdef NSIS_SUPPORT_BGBG ShowWindow(m_bgwnd, SW_SHOW); #endif//NSIS_SUPPORT_BGBG #ifdef NSIS_CONFIG_LICENSEPAGE { // load richedit DLL static char str1[]="RichEd20.dll"; static char str2[]="RichEdit20A"; if (!LoadLibrary(str1)) { *(WORD*)(str1+6) = CHAR2_TO_WORD('3','2'); LoadLibrary(str1); } // make richedit20a point to RICHEDIT if (!GetClassInfo(NULL,str2,&wc)) { str2[8]=0; GetClassInfo(NULL,str2,&wc); wc.lpszClassName = str2; str2[8]='2'; RegisterClass(&wc); } } #endif { int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) ExecuteCodeSegment(header->code_onGUIEnd,NULL); #endif return ret; } } #endif//NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT else #endif//NSIS_CONFIG_VISIBLE_SUPPORT { if (install_thread(NULL)) { #ifdef NSIS_SUPPORT_CODECALLBACKS if (!g_quit_flag) ExecuteCodeSegment(header->code_onInstFailed,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS return 1; } #ifdef NSIS_SUPPORT_CODECALLBACKS ExecuteCodeSegment(header->code_onInstSuccess,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS return 0; } #endif//NSIS_CONFIG_SILENT_SUPPORT }
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) { int ret = 0; const char *m_Err = _LANG_ERRORWRITINGTEMP; int cl_flags = 0; char *realcmds; char seekchar=' '; char *cmdline; InitCommonControls(); #if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT) { extern HRESULT g_hres; g_hres=OleInitialize(NULL); } #endif mystrcpy(g_caption,_LANG_GENERIC_ERROR); GetTempPath(NSIS_MAX_STRLEN, state_temp_dir); if (!ValidateTempDir()) { GetWindowsDirectory(state_temp_dir, NSIS_MAX_STRLEN - 5); // leave space for \Temp lstrcat(state_temp_dir, "\\Temp"); if (!ValidateTempDir()) { goto end; } } DeleteFile(state_command_line); lstrcpyn(state_command_line, GetCommandLine(), NSIS_MAX_STRLEN); #ifdef NSIS_CONFIG_VISIBLE_SUPPORT g_hInstance = GetModuleHandle(NULL); #endif//NSIS_CONFIG_VISIBLE_SUPPORT cmdline = state_command_line; if (*cmdline == '\"') seekchar = *cmdline++; cmdline=findchar(cmdline, seekchar); cmdline=CharNext(cmdline); realcmds=cmdline; while (*cmdline) { // skip over any spaces while (*cmdline == ' ') cmdline++; // get char we should look for to get the next parm seekchar = ' '; if (cmdline[0] == '\"') { cmdline++; seekchar = '\"'; } // is it a switch? if (cmdline[0] == '/') { cmdline++; // this only works with spaces because they have just one bit on #define END_OF_ARG(c) (((c)|' ')==' ') #if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT) if (cmdline[0] == 'S' && END_OF_ARG(cmdline[1])) cl_flags |= FH_FLAGS_SILENT; #endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_CRC_SUPPORT if (*(LPDWORD)cmdline == CHAR4_TO_DWORD('N','C','R','C') && END_OF_ARG(cmdline[4])) cl_flags |= FH_FLAGS_NO_CRC; #endif//NSIS_CONFIG_CRC_SUPPORT if (*(LPDWORD)(cmdline-2) == CHAR4_TO_DWORD(' ', '/', 'D','=')) { cmdline[-2]=0; // keep this from being passed to uninstaller if necessary mystrcpy(state_install_directory,cmdline+2); break; // /D= must always be last } } // skip over our parm cmdline = findchar(cmdline, seekchar); // skip the quote if (*cmdline == '\"') cmdline++; } m_Err = loadHeaders(cl_flags); if (m_Err) goto end; #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (g_is_uninstaller) { char *p = findchar(realcmds, 0); // state_command_line has state_install_directory right after it in memory, so reading // a bit over state_command_line won't do any harm while (p >= realcmds && *(LPDWORD)p != CHAR4_TO_DWORD(' ', '_', '?', '=')) p--; m_Err = _LANG_UNINSTINITERROR; if (p >= realcmds) { *p=0; // terminate before "_?=" p+=4; // skip over " _?=" if (is_valid_instpath(p)) { mystrcpy(state_install_directory, p); mystrcpy(state_output_directory, p); m_Err = 0; } else { goto end; } } else { int x; 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]='\"'; mystrcpy(buf2+1,state_temp_dir); lstrcat(buf2,s); DeleteFile(buf2+1); // clean up after all the other ones if they are there if (m_Err) // not done yet { // 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]) mystrcpy(ibuf,state_install_directory); else trimslashtoend(ibuf); lstrcat(buf2,"\" "); lstrcat(buf2,realcmds); lstrcat(buf2," _?="); lstrcat(buf2,ibuf); // add a trailing backslash to make sure is_valid_instpath will not fail when it shouldn't addtrailingslash(buf2); hProc=myCreateProcess(buf2,state_temp_dir); if (hProc) { CloseHandle(hProc); // success m_Err = 0; } } } s[0]++; } goto end; } } #endif//NSIS_CONFIG_UNINSTALL_SUPPORT g_exec_flags.errlvl = -1; ret = ui_doinstall(); #ifdef NSIS_CONFIG_LOG #ifndef NSIS_CONFIG_LOG_ODS log_write(1); #endif//!NSIS_CONFIG_LOG_ODS #endif//NSIS_CONFIG_LOG end: CleanUp(); #if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT) OleUninitialize(); #endif if (m_Err) { my_MessageBox(m_Err, MB_OK | MB_ICONSTOP | (IDOK << 20)); ExitProcess(2); return 0; } #ifdef NSIS_SUPPORT_REBOOT if (g_exec_flags.reboot_called) { HANDLE h=GetModuleHandle("ADVAPI32.dll"); if (h) { BOOL (WINAPI *OPT)(HANDLE, DWORD,PHANDLE); BOOL (WINAPI *LPV)(LPCTSTR,LPCTSTR,PLUID); BOOL (WINAPI *ATP)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD); OPT=(void*)GetProcAddress(h,"OpenProcessToken"); LPV=(void*)GetProcAddress(h,"LookupPrivilegeValueA"); ATP=(void*)GetProcAddress(h,"AdjustTokenPrivileges"); if (OPT && LPV && ATP) { HANDLE hToken; TOKEN_PRIVILEGES tkp; if (OPT(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { LPV(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; ATP(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); } } } if (!ExitWindowsEx(EWX_REBOOT,0)) ExecuteCallbackFunction(CB_ONREBOOTFAILED); } #endif//NSIS_SUPPORT_REBOOT if (g_exec_flags.errlvl != -1) ret = g_exec_flags.errlvl; ExitProcess(ret); 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); }