📄 mainwin.cpp
字号:
{
SHELLEXECUTEINFO sei = {0};
char buf[MAX_PATH];
sprintf(buf, "%s%p,%x", GetLoadStrA(IDS_RUNAS_OPT), hWnd, flg);
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.lpVerb = "runas";
sei.lpFile = cfg.execPath;
sei.lpDirectory = cfg.execDir;
sei.nShow = /*SW_MAXIMIZE*/ SW_NORMAL;
sei.lpParameters = buf;
isRunAsParent = ::ShellExecuteEx(&sei);
return isRunAsParent;
}
BOOL TMainDlg::EnableLogFile(BOOL on)
{
if (on && hErrLogFile == INVALID_HANDLE_VALUE) {
hErrLogMutex = ::CreateMutex(NULL, TRUE, FASTCOPYLOG_MUTEX);
hErrLogFile = ::CreateFileV(logFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0);
}
else if (!on && hErrLogFile != INVALID_HANDLE_VALUE) {
::CloseHandle(hErrLogFile);
hErrLogFile = INVALID_HANDLE_VALUE;
::CloseHandle(hErrLogMutex);
hErrLogMutex = NULL;
}
return TRUE;
}
int GetArgOpt(void *arg, int default_value)
{
if (GetChar(arg, 0) == '=') {
arg = MakeAddr(arg, 1);
}
if (GetChar(arg, 0) == 0) {
return default_value;
}
if (lstrcmpiV(arg, TRUE_V) == 0)
return TRUE;
if (lstrcmpiV(arg, FALSE_V) == 0)
return FALSE;
if (GetChar(arg, 0) >= '0' && GetChar(arg, 0) <= '9' /* || GetChar(arg, 0) == '-' */)
return strtolV(arg, NULL, 0);
return default_value;
}
int CmdNameToComboIndex(void *cmd_name)
{
for (int i=0; COPYINFO_LIST[i].cmdline_name; i++) {
if (lstrcmpiV(cmd_name, COPYINFO_LIST[i].cmdline_name) == 0)
return i;
}
return -1;
}
BOOL TMainDlg::CommandLineExecV(int argc, void **argv)
{
VBuf shellExtBuf;
int len;
int job_idx = -1;
BOOL is_openwin = FALSE;
BOOL is_noexec = FALSE;
BOOL is_delete = FALSE;
BOOL is_estimate = FALSE;
BOOL is_filter = FALSE;
BOOL is_job_filter = FALSE;
DWORD runas_flg = 0;
void *CMD_STR = GetLoadStrV(IDS_CMD_OPT);
void *BUSIZE_STR = GetLoadStrV(IDS_BUFSIZE_OPT);
void *LOG_STR = GetLoadStrV(IDS_LOG_OPT);
void *LOGFILE_STR = GetLoadStrV(IDS_LOGFILE_OPT);
void *UTF8LOG_STR = GetLoadStrV(IDS_UTF8LOG_OPT);
void *REPARSE_STR = GetLoadStrV(IDS_REPARSE_OPT);
void *FORCESTART_STR = GetLoadStrV(IDS_FORCESTART_OPT);
void *SKIPEMPTYDIR_STR = GetLoadStrV(IDS_SKIPEMPTYDIR_OPT);
void *ERRSTOP_STR = GetLoadStrV(IDS_ERRSTOP_OPT);
void *ESTIMATE_STR = GetLoadStrV(IDS_ESTIMATE_OPT);
void *AUTOSLOW_STR = GetLoadStrV(IDS_AUTOSLOW_OPT);
void *SPEED_STR = GetLoadStrV(IDS_SPEED_OPT);
void *SPEED_FULL_STR = GetLoadStrV(IDS_SPEED_FULL);
void *SPEED_AUTOSLOW_STR = GetLoadStrV(IDS_SPEED_AUTOSLOW);
void *SPEED_SUSPEND_STR = GetLoadStrV(IDS_SPEED_SUSPEND);
void *DISKMODE_STR = GetLoadStrV(IDS_DISKMODE_OPT);
void *DISKMODE_SAME_STR = GetLoadStrV(IDS_DISKMODE_SAME);
void *DISKMODE_DIFF_STR = GetLoadStrV(IDS_DISKMODE_DIFF);
void *DISKMODE_AUTO_STR = GetLoadStrV(IDS_DISKMODE_AUTO);
void *OPENWIN_STR = GetLoadStrV(IDS_OPENWIN_OPT);
void *AUTOCLOSE_STR = GetLoadStrV(IDS_AUTOCLOSE_OPT);
void *FORCECLOSE_STR = GetLoadStrV(IDS_FORCECLOSE_OPT);
void *NOEXEC_STR = GetLoadStrV(IDS_NOEXEC_OPT);
void *SHELLEXT1_STR = GetLoadStrV(IDS_SHEXT1_OPT);
void *SHELLEXT2_STR = GetLoadStrV(IDS_SHEXT2_OPT);
void *SHELLEXT4_STR = GetLoadStrV(IDS_SHEXT4_OPT);
void *FCSHEXT1_STR = GetLoadStrV(IDS_FCSHEXT1_OPT);
void *NOCONFIRMDEL_STR = GetLoadStrV(IDS_NOCONFIRMDEL_OPT);
void *INCLUDE_STR = GetLoadStrV(IDS_INCLUDE_OPT);
void *EXCLUDE_STR = GetLoadStrV(IDS_EXCLUDE_OPT);
void *REGEXP_STR = GetLoadStrV(IDS_REGEXP_OPT);
void *JOB_STR = GetLoadStrV(IDS_JOB_OPT);
void *OWDEL_STR = GetLoadStrV(IDS_OWDEL_OPT);
void *ACL_STR = GetLoadStrV(IDS_ACL_OPT);
void *STREAM_STR = GetLoadStrV(IDS_STREAM_OPT);
void *TO_STR = GetLoadStrV(IDS_TO_OPT);
void *RUNAS_STR = GetLoadStrV(IDS_RUNAS_OPT);
void *p;
void *dst_path = NULL;
argc--, argv++; // 幚峴僼傽僀儖柤偼 skip
while (*argv && GetChar(*argv, 0) == '/') {
if (strnicmpV(*argv, CMD_STR, len = strlenV(CMD_STR)) == 0) {
int idx = CmdNameToComboIndex(MakeAddr(*argv, len));
if (idx == -1)
return MessageBox(GetLoadStr(IDS_USAGE), "Illegal Command"), FALSE;
// 僐儅儞僪儌乕僪傪慖戰
SendDlgItemMessage(MODE_COMBO, CB_SETCURSEL, idx, 0);
}
else if (strnicmpV(*argv, JOB_STR, len = strlenV(JOB_STR)) == 0) {
if ((job_idx = cfg.SearchJobV(MakeAddr(*argv, len))) == -1)
return MessageBox(GetLoadStr(IDS_JOBNOTFOUND), "Illegal Command"), FALSE;
SetJob(job_idx);
if (GetChar(cfg.jobArray[job_idx]->includeFilter, 0) || GetChar(cfg.jobArray[job_idx]->excludeFilter, 0))
is_job_filter = TRUE;
}
else if (strnicmpV(*argv, BUSIZE_STR, len = strlenV(BUSIZE_STR)) == 0) {
SetDlgItemTextV(BUFSIZE_EDIT, MakeAddr(*argv, len));
}
else if (strnicmpV(*argv, LOGFILE_STR, len = strlenV(LOGFILE_STR)) == 0 && (p = MakeAddr(*argv, len))) {
strcpyV(logFile, p);
}
else if (strnicmpV(*argv, LOG_STR, len = strlenV(LOG_STR)) == 0) {
isErrLog = GetArgOpt(MakeAddr(*argv, len), TRUE);
}
else if (strnicmpV(*argv, UTF8LOG_STR, len = strlenV(UTF8LOG_STR)) == 0) {
isUtf8Log = GetArgOpt(MakeAddr(*argv, len), TRUE) && IS_WINNT_V;
}
else if (strnicmpV(*argv, REPARSE_STR, len = strlenV(REPARSE_STR)) == 0) {
isReparse = GetArgOpt(MakeAddr(*argv, len), TRUE);
}
else if (strnicmpV(*argv, FORCESTART_STR, len = strlenV(FORCESTART_STR)) == 0) {
forceStart = GetArgOpt(MakeAddr(*argv, len), TRUE);
}
else if (strnicmpV(*argv, SKIPEMPTYDIR_STR, len = strlenV(SKIPEMPTYDIR_STR)) == 0) {
skipEmptyDir = GetArgOpt(MakeAddr(*argv, len), TRUE);
}
else if (strnicmpV(*argv, ERRSTOP_STR, len = strlenV(ERRSTOP_STR)) == 0) {
CheckDlgButton(IGNORE_CHECK, GetArgOpt(MakeAddr(*argv, len), TRUE) ? FALSE : TRUE);
}
else if (strnicmpV(*argv, ESTIMATE_STR, len = strlenV(ESTIMATE_STR)) == 0) {
is_estimate = GetArgOpt(MakeAddr(*argv, len), TRUE);
}
else if (strnicmpV(*argv, AUTOSLOW_STR, len = strlenV(AUTOSLOW_STR)) == 0) {
SetSpeedLevelLabel(this, speedLevel = GetArgOpt(MakeAddr(*argv, len), TRUE) ? SPEED_AUTO : SPEED_FULL);
}
else if (strnicmpV(*argv, SPEED_STR, len = strlenV(SPEED_STR)) == 0) {
p = MakeAddr(*argv, len);
speedLevel = lstrcmpiV(p, SPEED_FULL_STR) == 0 ? SPEED_FULL : lstrcmpiV(p, SPEED_AUTOSLOW_STR) == 0 ? SPEED_AUTO : lstrcmpiV(p, SPEED_SUSPEND_STR) == 0 ? SPEED_SUSPEND : GetArgOpt(p, SPEED_FULL);
SetSpeedLevelLabel(this, speedLevel = min(speedLevel, SPEED_FULL));
}
else if (strnicmpV(*argv, OWDEL_STR, len = strlenV(OWDEL_STR)) == 0) {
CheckDlgButton(OWDEL_CHECK, GetArgOpt(MakeAddr(*argv, len), TRUE));
}
else if (strnicmpV(*argv, ACL_STR, len = strlenV(ACL_STR)) == 0) {
CheckDlgButton(ACL_CHECK, GetArgOpt(MakeAddr(*argv, len), TRUE) && IS_WINNT_V);
}
else if (strnicmpV(*argv, STREAM_STR, len = strlenV(STREAM_STR)) == 0) {
CheckDlgButton(STREAM_CHECK, GetArgOpt(MakeAddr(*argv, len), TRUE) && IS_WINNT_V);
}
else if (strnicmpV(*argv, OPENWIN_STR, len = strlenV(OPENWIN_STR)) == 0) {
is_openwin = GetArgOpt(MakeAddr(*argv, len), TRUE);
}
else if (strnicmpV(*argv, AUTOCLOSE_STR, len = strlenV(AUTOCLOSE_STR)) == 0 && autoCloseLevel != FORCE_CLOSE) {
autoCloseLevel = (AutoCloseLevel)GetArgOpt(MakeAddr(*argv, len), NOERR_CLOSE);
}
else if (strnicmpV(*argv, FORCECLOSE_STR, strlenV(FORCECLOSE_STR)) == 0) {
autoCloseLevel = FORCE_CLOSE;
}
else if (strnicmpV(*argv, NOEXEC_STR, strlenV(NOEXEC_STR)) == 0) {
is_noexec = TRUE;
}
else if (strnicmpV(*argv, DISKMODE_STR, len = strlenV(DISKMODE_STR)) == 0) {
if (lstrcmpiV(MakeAddr(*argv, len), DISKMODE_SAME_STR) == 0)
diskMode = 1;
else if (lstrcmpiV(MakeAddr(*argv, len), DISKMODE_DIFF_STR) == 0)
diskMode = 2;
else
diskMode = 0;
}
else if (strnicmpV(*argv, INCLUDE_STR, len = strlenV(INCLUDE_STR)) == 0) {
is_filter = TRUE;
SetDlgItemTextV(INCLUDE_COMBO, strtok_pathV(MakeAddr(*argv, len), EMPTY_STR_V, &p));
}
else if (strnicmpV(*argv, EXCLUDE_STR, len = strlenV(EXCLUDE_STR)) == 0) {
is_filter = TRUE;
SetDlgItemTextV(EXCLUDE_COMBO, strtok_pathV(MakeAddr(*argv, len), EMPTY_STR_V, &p));
}
else if (strnicmpV(*argv, REGEXP_STR, strlenV(REGEXP_STR)) == 0) {
isRegExp = TRUE;
}
else if (strnicmpV(*argv, SHELLEXT1_STR, strlenV(SHELLEXT1_STR)) == 0
|| strnicmpV(*argv, SHELLEXT2_STR, strlenV(SHELLEXT2_STR)) == 0
|| strnicmpV(*argv, SHELLEXT4_STR, strlenV(SHELLEXT4_STR)) == 0) {
if (TMsgBox(this).Exec(GetLoadStr(IDS_UPDATE), FASTCOPY, MB_OKCANCEL) == IDOK)
UpdateShellExt(&cfg);
return FALSE;
}
else if (strnicmpV(*argv, FCSHEXT1_STR, strlenV(FCSHEXT1_STR)) == 0) {
isShellExt = TRUE;
is_openwin = !cfg.shextTaskTray;
autoCloseLevel = cfg.shextAutoClose ? NOERR_CLOSE : NO_CLOSE;
HANDLE hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
DWORD read_size;
BOOL convertErr = FALSE;
shellExtBuf.AllocBuf(SHELLEXT_MIN_ALLOC, SHELLEXT_MAX_ALLOC);
while (::ReadFile(hStdInput, shellExtBuf.Buf() + shellExtBuf.UsedSize(), shellExtBuf.RemainSize(), &read_size, 0) && read_size > 0) {
if (shellExtBuf.AddUsedSize(read_size) == shellExtBuf.Size())
shellExtBuf.Grow(SHELLEXT_MIN_ALLOC);
}
shellExtBuf.Buf()[shellExtBuf.UsedSize()] = 0;
if (convertErr)
return FALSE;
if ((argv = CommandLineToArgvV(shellExtBuf.Buf(), &argc)) == NULL)
break;
continue; // 嵞 parse
}
else if (strnicmpV(*argv, NOCONFIRMDEL_STR, strlenV(NOCONFIRMDEL_STR)) == 0) {
noConfirmDel = TRUE;
}
else if (strnicmpV(*argv, TO_STR, strlenV(TO_STR)) == 0) {
SetDlgItemTextV(DST_COMBO, dst_path = MakeAddr(*argv, strlenV(TO_STR)));
}
else if (strnicmpV(*argv, RUNAS_STR, strlenV(RUNAS_STR)) == 0 && IS_WINNT_V) {
void *p = MakeAddr(*argv, strlenV(RUNAS_STR));
HWND hRunasParent = (HWND)strtolV(p, 0, 16);
runas_flg = strtolV(MakeAddr(strchrV(p, ','), 1), 0, 16);
if (!TIsUserAnAdmin() || RunasSync(hRunasParent) == FALSE) {
return MessageBox("Not Admin or Failed to read parent window info", FASTCOPY), FALSE;
}
}
else
return MessageBoxV(GetLoadStrV(IDS_USAGE), *argv), FALSE;
argc--, argv++;
}
is_delete = GetCopyMode() == FastCopy::DELETE_MODE;
if (!isRunAsStart) {
if (job_idx == -1) {
SetDlgItemText(SRC_COMBO, "");
if (!dst_path)
SetDlgItemText(DST_COMBO, "");
}
PathArray pathArray;
int path_len = 0;
WCHAR wBuf[MAX_PATH_EX];
while (*argv && GetChar(*argv, 0) != '/') {
void *path = *argv;
if (isShellExt && !is_delete) {
if (NetPlaceConvertV(path, wBuf)) {
path = wBuf;
isNetPlaceSrc = TRUE;
}
}
pathArray.RegisterPath(path);
path_len += strlenV(path) + 3;
argc--, argv++;
}
void *path = new WCHAR [path_len+1];
if (pathArray.GetMultiPath(path, path_len))
SetDlgItemTextV(SRC_COMBO, path);
delete [] path;
if (argc == 1 && strnicmpV(*argv, TO_STR, strlenV(TO_STR)) == 0) {
dst_path = MakeAddr(*argv, strlenV(TO_STR));
if (isShellExt && NetPlaceConvertV(dst_path, wBuf))
dst_path = wBuf;
SetDlgItemTextV(DST_COMBO, dst_path);
}
else if (argc >= 1)
return MessageBox(GetLoadStr(IDS_USAGE), "Too few/many argument"), FALSE;
if ((is_filter || is_job_filter) && (GetCopyMode() == FastCopy::MOVE_MODE))
return MessageBox(GetLoadStr(IDS_NOFILTER_USAGE), FASTCOPY), FALSE;
if (::GetWindowTextLengthV(GetDlgItem(SRC_COMBO)) == 0 || (!is_delete && ::GetWindowTextLengthV(GetDlgItem(DST_COMBO)) == 0)) {
is_noexec = TRUE;
if (isShellExt) // 僐僺乕愭偺柍偄 shell婲摦帪偼丄autoclose 傪柍帇偡傞
autoCloseLevel = NO_CLOSE;
}
if (is_filter && !is_job_filter)
ReflectFilterCheck(TRUE);
SetItemEnable(is_delete);
if (diskMode)
UpdateMenu();
if (!is_delete && (is_estimate || !isShellExt && !is_noexec && cfg.estimateMode && !is_estimate))
CheckDlgButton(ESTIMATE_CHECK, is_estimate);
}
if (is_openwin || is_noexec || isRunAsStart) {
Show();
}
else {
MoveCenter(FALSE);
TaskTray(NIM_ADD, hMainIcon[FCNORMAL_ICON_INDEX], FASTCOPY);
}
return is_noexec || (isRunAsStart && !(runas_flg & RUNAS_IMMEDIATE)) ? TRUE : ExecCopy(CMDLINE_EXEC);
}
BOOL CopyItem(HWND hSrc, HWND hDst)
{
if (!hSrc || !hDst) return FALSE;
DWORD len = ::SendMessageV(hSrc, WM_GETTEXTLENGTH, 0, 0) + 1;
WCHAR *wbuf = new WCHAR [len];
if (!wbuf) return FALSE;
::SendMessageV(hSrc, WM_GETTEXT, len, (LPARAM)wbuf);
::SendMessageV(hDst, WM_SETTEXT, 0, (LPARAM)wbuf);
::EnableWindow(hDst, ::IsWindowEnabled(hSrc));
delete [] wbuf;
return TRUE;
}
BOOL TMainDlg::RunasSync(HWND hOrg)
{
/* GUI忣曬傪僐僺乕 */
CopyItem(::GetDlgItem(hOrg, SRC_COMBO), GetDlgItem(SRC_COMBO));
CopyItem(::GetDlgItem(hOrg, DST_COMBO), GetDlgItem(DST_COMBO));
CopyItem(::GetDlgItem(hOrg, BUFSIZE_EDIT), GetDlgItem(BUFSIZE_EDIT));
CopyItem(::GetDlgItem(hOrg, INCLUDE_COMBO), GetDlgItem(INCLUDE_COMBO));
CopyItem(::GetDlgItem(hOrg, EXCLUDE_COMBO), GetDlgItem(EXCLUDE_COMBO));
CopyItem(::GetDlgItem(hOrg, JOBTITLE_STATIC), GetDlgItem(JOBTITLE_STATIC));
CheckDlgButton(IGNORE_CHECK, ::IsDlgButtonChecked(hOrg, IGNORE_CHECK));
CheckDlgButton(ESTIMATE_CHECK, ::IsDlgButtonChecked(hOrg, ESTIMATE_CHECK));
CheckDlgButton(ACL_CHECK, ::IsDlgButtonChecked(hOrg, ACL_CHECK));
CheckDlgButton(STREAM_CHECK, ::IsDlgButtonChecked(hOrg, STREAM_CHECK));
CheckDlgButton(OWDEL_CHECK, ::IsDlgButtonChecked(hOrg, OWDEL_CHECK));
CheckDlgButton(FILTER_CHECK, ::IsDlgButtonChecked(hOrg, FILTER_CHECK));
SendDlgItemMessage(MODE_COMBO, CB_SETCURSEL, ::SendDlgItemMessage(hOrg, MODE_COMBO, CB_GETCURSEL, 0, 0), 0);
/* Pipe 偱撪晹忣曬傪庴偗搉偟 */
DWORD pid;
::GetWindowThreadProcessId(hOrg, &pid);
HANDLE hProc = ::OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid);
HANDLE hRead, hWrite, hDupWrite;
::CreatePipe(&hRead, &hWrite, NULL, 8192);
::DuplicateHandle(::GetCurrentProcess(), hWrite, hProc, &hDupWrite, 0, FALSE, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);
::PostMessage(hOrg, WM_FASTCOPY_RUNAS, 0, (LPARAM)hDupWrite);
DWORD size = RunasShareSize();
::ReadFile(hRead, RunasShareData(), size, &size, 0);
::CloseHandle(hProc);
::CloseHandle(hRead);
::SendMessage(hOrg, WM_CLOSE, 0, 0);
/* 撪晹忣曬偲GUI傪柍柕弬偵偡傞 */
SetSpeedLevelLabel(this, speedLevel);
UpdateMenu();
SetItemEnable(GetCopyMode() == FastCopy::DELETE_MODE);
isRunAsStart = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -