diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index adc378e7..296f5bb2 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -751,8 +751,9 @@ static int NSISCALL getreqsize() static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - char *dir = g_usrvars[g_this_page->parms[4]]; - int browse_text = g_this_page->parms[3]; + page *thispage = g_this_page; + char *dir = g_usrvars[thispage->parms[4]]; + int browse_text = thispage->parms[3]; if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { GetUIText(IDC_DIR,dir,NSIS_MAX_STRLEN); @@ -831,12 +832,13 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar { static char s[NSIS_MAX_STRLEN]; char *p; - int is_valid_path; + int error = 0; int total, available=-1; DWORD spc,bps,fc,tc; GetUIText(IDC_DIR,dir,NSIS_MAX_STRLEN); - is_valid_path=is_valid_instpath(dir); + if (!is_valid_instpath(dir)) + error = NSIS_INSTDIR_INVALID; mystrcpy(s,dir); p=skip_root(s); @@ -852,6 +854,9 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar total = getreqsize(); + if ((unsigned int)available < (unsigned int)total) + error = NSIS_INSTDIR_NOT_ENOUGH_SPACE; + if (LANG_STR_TAB(LANG_SPACE_REQ)) { SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,GetNSISString(s,LANG_SPACE_REQ))); if (available != -1) @@ -860,12 +865,17 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar SetUITextNT(IDC_SPACEAVAILABLE,""); } - EnableWindow(m_hwndOK, - is_valid_path && ((unsigned int)available >= (unsigned int)total) + g_exec_flags.instdir_error = error; + #ifdef NSIS_SUPPORT_CODECALLBACKS - && !ExecuteCodeSegment(g_header->code_onVerifyInstDir,NULL) + if (!error) + error = ExecuteCodeSegment(g_header->code_onVerifyInstDir,NULL); #endif - ); + + if (thispage->flags & PF_DIR_NO_BTN_DISABLE) + error = 0; + + EnableWindow(m_hwndOK, !error); } return HandleStaticBkColor(); } diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index c725f430..caee4827 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -122,31 +122,43 @@ static int NSISCALL ExecuteEntry(entry *entry_) char *buf3 = bufs[3]; char *buf4 = bufs[4]; - int parm0 = entry_->offsets[0]; - char *var0 = g_usrvars[parm0]; - int parm1 = entry_->offsets[1]; - char *var1 = g_usrvars[parm1]; - int parm2 = entry_->offsets[2]; - char *var2 = g_usrvars[parm2]; - int parm3 = entry_->offsets[3]; - char *var3 = g_usrvars[parm3]; - int parm4 = entry_->offsets[4]; -//char *var4 = g_usrvars[parm4]; // not used yet - int parm5 = entry_->offsets[5]; -//char *var5 = g_usrvars[parm5]; // not used yet - int which = entry_->which; - - // Saves 8 bytes - // HWND mainHwnd = g_hwnd; - // #define g_hwnd mainHwnd + char *var0; + char *var1; + char *var2; + char *var3; + //char *var4; + //char *var5; #ifdef NSIS_CONFIG_COMPONENTPAGE HWND hwSectionHack = g_SectionHack; #endif + // Saves 8 bytes + HWND mainHwnd = g_hwnd; +#define g_hwnd mainHwnd + int exec_error = 0; - parms = entry_->offsets; + entry lent; + mini_memcpy(&lent, entry_, sizeof(entry)); + +#define which (lent.which) +#define parm0 (lent.offsets[0]) +#define parm1 (lent.offsets[1]) +#define parm2 (lent.offsets[2]) +#define parm3 (lent.offsets[3]) +#define parm4 (lent.offsets[4]) +#define parm5 (lent.offsets[5]) + + var0 = g_usrvars[parm0]; + var1 = g_usrvars[parm1]; + var2 = g_usrvars[parm2]; + var3 = g_usrvars[parm3]; + // not used yet + //var4 = g_usrvars[parm4]; + //var5 = g_usrvars[parm5]; + + parms = lent.offsets; switch (which) { @@ -202,7 +214,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) break; case EW_IFFLAG: { - int f=entry_->offsets[!g_exec_flags.flags[parm2]]; + int f=lent.offsets[!g_exec_flags.flags[parm2]]; g_exec_flags.flags[parm2]&=parm3; return f; } @@ -377,7 +389,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) int cmp=0; if (ffd) { - cmp=CompareFileTime(&ffd->ftLastWriteTime, (FILETIME*)(entry_->offsets + 3)); + cmp=CompareFileTime(&ffd->ftLastWriteTime, (FILETIME*)(lent.offsets + 3)); } overwriteflag=!(cmp & (0x80000000 | (overwriteflag - 3))); } @@ -431,7 +443,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) log_printf3("File: wrote %d to \"%s\"",ret,buf0); if (parm3 != 0xffffffff || parm4 != 0xffffffff) - SetFileTime(hOut,(FILETIME*)(entry_->offsets+3),NULL,(FILETIME*)(entry_->offsets+3)); + SetFileTime(hOut,(FILETIME*)(lent.offsets+3),NULL,(FILETIME*)(lent.offsets+3)); CloseHandle(hOut); diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index d40fcaab..efb36fb9 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -360,6 +360,7 @@ enum #define PF_LICENSE_SELECTED 1 // must be 1 #define PF_NO_NEXT_FOCUS 128 #define PF_PAGE_EX 512 +#define PF_DIR_NO_BTN_DISABLE 1024 typedef struct { @@ -448,6 +449,9 @@ DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove); #endif #endif +#define NSIS_INSTDIR_INVALID 1 +#define NSIS_INSTDIR_NOT_ENOUGH_SPACE 2 + union exec_flags { struct { int autoclose; @@ -462,6 +466,7 @@ union exec_flags { #ifdef NSIS_CONFIG_SILENT_SUPPORT int silent; #endif + int instdir_error; }; int flags[1]; }; diff --git a/Source/script.cpp b/Source/script.cpp index 41320205..6fa6c09a 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -1350,6 +1350,26 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("DirVar: %s\n", line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); + case TOK_DIRVERIFY: + { + if (!cur_page || cur_page_type != PAGE_DIRECTORY) { + ERROR_MSG("Error: can't use DirVerify outside of PageEx directory.\n"); + return PS_ERROR; + } + cur_page->flags &= ~PF_DIR_NO_BTN_DISABLE; + int k = line.gettoken_enum(1,"auto\0leave\0"); + if (k == -1) + PRINTHELP(); + if (k) + cur_page->flags |= PF_DIR_NO_BTN_DISABLE; + SCRIPT_MSG("DirVerify: %s\n", line.gettoken_str(1)); + } + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); + case TOK_GETINSTDIRERROR: + ent.which = EW_GETFLAG; + ent.offsets[0] = GetUserVarIndex(line, 1); + ent.offsets[1] = FLAG_OFFSET(instdir_error); + return add_entry(&ent); #ifdef NSIS_CONFIG_COMPONENTPAGE case TOK_COMPTEXT: { diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 746cea78..6bf731f3 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -49,6 +49,8 @@ static tokenType tokenlist[TOK__LAST] = {TOK_DIRTEXT,"DirText",0,4,"[directory_page_description] [directory_page_subtext] [browse_button_text] [browse_dlg_text]"}, {TOK_DIRSHOW,"DirShow",1,0,"(show|hide)"}, {TOK_DIRVAR,"DirVar",1,0,"$(user_var: dir in/out))"}, +{TOK_DIRVERIFY,"DirVerify",1,0,"auto|leave"}, +{TOK_GETINSTDIRERROR,"GetInstDirError",1,0,"$(user_var: error output)"}, {TOK_ROOTDIRINST,"AllowRootDirInstall",1,0,"(true|false)"}, {TOK_CHECKBITMAP,"CheckBitmap",1,0,"local_bitmap.bmp"}, {TOK_ENABLEWINDOW,"EnableWindow",2,0,"hwnd (1|0)"}, diff --git a/Source/tokens.h b/Source/tokens.h index abc37010..27a6bb67 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -109,8 +109,11 @@ enum TOK_PAGEEX, TOK_PAGEEXEND, TOK_DIRVAR, + TOK_DIRVERIFY, TOK_PAGECALLBACKS, + TOK_GETINSTDIRERROR, + // flag setters TOK_SETDATESAVE, TOK_SETOVERWRITE,