void DebugNeedCmdUnitTests() { BOOL b; struct strTests { LPCWSTR pszCmd; BOOL bNeed; } Tests[] = { {L"\"C:\\windows\\notepad.exe -f \"makefile\" COMMON=\"../../../plugins/common\"\"", FALSE}, {L"\"\"C:\\windows\\notepad.exe -new_console\"\"", FALSE}, {L"\"\"cmd\"\"", FALSE}, {L"cmd /c \"\"C:\\Program Files\\Windows NT\\Accessories\\wordpad.exe\" -?\"", FALSE}, {L"cmd /c \"dir c:\\\"", FALSE}, {L"abc.cmd", TRUE}, // Do not do too many heuristic. If user really needs redirection (for 'root'!) // he must explicitly call "cmd /c ...". With only exception if first exe not found. {L"notepad text & start explorer", FALSE}, }; LPCWSTR psArgs; BOOL bNeedCut, bRootIsCmd, bAlwaysConfirm, bAutoDisable; CmdArg szExe; for (INT_PTR i = 0; i < countof(Tests); i++) { szExe.Empty(); RConStartArgs rcs; rcs.pszSpecialCmd = lstrdup(Tests[i].pszCmd); rcs.ProcessNewConArg(); b = IsNeedCmd(TRUE, rcs.pszSpecialCmd, szExe, &psArgs, &bNeedCut, &bRootIsCmd, &bAlwaysConfirm, &bAutoDisable); _ASSERTE(b == Tests[i].bNeed); } }
void RConStartArgs::RunArgTests() { struct { LPCWSTR pszArg, pszNeed; } cTests[] = { { L"\"c:\\cmd.exe\" \"-new_console\" \"c:\\file.txt\"", L"\"c:\\cmd.exe\" \"c:\\file.txt\"" }, { L"\"c:\\cmd.exe\" -new_console:n \"c:\\file.txt\"", L"\"c:\\cmd.exe\" \"c:\\file.txt\"" }, { L"\"c:\\cmd.exe\" \"-new_console:n\" \"c:\\file.txt\"", L"\"c:\\cmd.exe\" \"c:\\file.txt\"" }, { L"c:\\cmd.exe \"-new_console:n\" \"c:\\file.txt\"", L"c:\\cmd.exe \"c:\\file.txt\"" }, { L"\"c:\\cmd.exe\" \"-new_console:n\" c:\\file.txt", L"\"c:\\cmd.exe\" c:\\file.txt" }, { L"c:\\file.txt -cur_console", L"c:\\file.txt" }, { L"\"c:\\file.txt\" -cur_console", L"\"c:\\file.txt\"" }, { L" -cur_console \"c:\\file.txt\"", L" \"c:\\file.txt\"" }, { L"-cur_console \"c:\\file.txt\"", L"\"c:\\file.txt\"" }, { L"-cur_console c:\\file.txt", L"c:\\file.txt" }, }; for (size_t i = 0; i < countof(cTests); i++) { RConStartArgs arg; arg.pszSpecialCmd = lstrdup(cTests[i].pszArg); arg.ProcessNewConArg(); if (lstrcmp(arg.pszSpecialCmd, cTests[i].pszNeed) != 0) { //_ASSERTE(FALSE && "arg.ProcessNewConArg failed"); OutputDebugString(L"arg.ProcessNewConArg failed\n"); } int nDbg = 0; } }
INT_PTR CRecreateDlg::OnButtonClicked(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { switch (LOWORD(wParam)) { case IDC_CHOOSE: { wchar_t *pszFilePath = SelectFile(L"Choose program to run", NULL, NULL, hDlg, L"Executables (*.exe)\0*.exe\0All files (*.*)\0*.*\0\0", sff_AutoQuote); if (pszFilePath) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszFilePath); SafeFree(pszFilePath); } return TRUE; } // case IDC_CHOOSE: case IDC_CHOOSE_DIR: { wchar_t* pszDefFolder = GetDlgItemTextPtr(hDlg, IDC_STARTUP_DIR); wchar_t* pszFolder = SelectFolder(L"Choose startup directory", pszDefFolder, hDlg, sff_Default); if (pszFolder) { SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszFolder); SafeFree(pszFolder); } SafeFree(pszDefFolder); return TRUE; } // case IDC_CHOOSE_DIR: case cbRunAsAdmin: { // BCM_SETSHIELD = 5644 BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (gOSVer.dwMajorVersion >= 6) { SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs && (mp_Args->aRecreate != cra_EditTab)); } if (bRunAs) { CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser); CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); } return TRUE; } // case cbRunAsAdmin: case rbCurrentUser: case rbAnotherUser: case cbRunAsRestricted: { RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0); return TRUE; } case rbRecreateSplitNone: case rbRecreateSplit2Right: case rbRecreateSplit2Bottom: { RConStartArgs* pArgs = mp_Args; switch (LOWORD(wParam)) { case rbRecreateSplitNone: pArgs->eSplit = RConStartArgs::eSplitNone; break; case rbRecreateSplit2Right: pArgs->eSplit = RConStartArgs::eSplitHorz; break; case rbRecreateSplit2Bottom: pArgs->eSplit = RConStartArgs::eSplitVert; break; } EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); if (pArgs->eSplit != pArgs->eSplitNone) SetFocus(GetDlgItem(hDlg, tRecreateSplit)); return TRUE; } // case rbRecreateSplitXXX case IDC_START: { RConStartArgs* pArgs = mp_Args; _ASSERTE(pArgs); SafeFree(pArgs->pszUserName); SafeFree(pArgs->pszDomain); //SafeFree(pArgs->pszUserPassword); if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0)) { pArgs->RunAsRestricted = crb_Off; pArgs->pszUserName = GetDlgItemTextPtr(hDlg, tRunAsUser); if (pArgs->pszUserName) { //pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword); // Попытаться проверить правильность введенного пароля и возможность запуска bool bCheckPwd = pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword)); DWORD nErr = bCheckPwd ? 0 : GetLastError(); if (!bCheckPwd) { DisplayLastError(L"Invalid user name or password was specified!", nErr, MB_ICONSTOP, NULL, hDlg); return 1; } } } else { pArgs->RunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; } // Vista+ (As Admin...) pArgs->RunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; // StartupDir (may be specified as argument) wchar_t* pszDir = GetDlgItemTextPtr(hDlg, IDC_STARTUP_DIR); wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL; LPCWSTR pszDirResult = pszExpand ? pszExpand : pszDir; // Another user? We may fail with access denied. Check only for "current user" account if (!pArgs->pszUserName && pszDirResult && *pszDirResult && !DirectoryExists(pszDirResult)) { wchar_t* pszErrInfo = lstrmerge(L"Specified directory does not exists!\n", pszDirResult, L"\n" L"Do you want to choose another directory?\n\n"); DWORD nErr = GetLastError(); int iDirBtn = DisplayLastError(pszErrInfo, nErr, MB_ICONEXCLAMATION|MB_YESNO, NULL, hDlg); if (iDirBtn == IDYES) { SafeFree(pszDir); SafeFree(pszExpand); SafeFree(pszErrInfo); return 1; } // User want to run "as is". Most likely it will fail, but who knows... } SafeFree(pArgs->pszStartupDir); pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir; if (pszExpand) { SafeFree(pszDir) } // Command // pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода SafeFree(pArgs->pszSpecialCmd); // GetDlgItemText выделяет память через calloc pArgs->pszSpecialCmd = GetDlgItemTextPtr(hDlg, IDC_RESTART_CMD); if (pArgs->pszSpecialCmd) gpSet->HistoryAdd(pArgs->pszSpecialCmd); if ((pArgs->aRecreate != cra_RecreateTab) && (pArgs->aRecreate != cra_EditTab)) { if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0)) pArgs->aRecreate = cra_CreateWindow; else pArgs->aRecreate = cra_CreateTab; } if (((pArgs->aRecreate == cra_CreateTab) || (pArgs->aRecreate == cra_EditTab)) && (pArgs->eSplit != RConStartArgs::eSplitNone)) { BOOL bOk = FALSE; int nPercent = GetDlgItemInt(hDlg, tRecreateSplit, &bOk, FALSE); if (bOk && (nPercent >= 1) && (nPercent <= 99)) { pArgs->nSplitValue = (100-nPercent) * 10; } //pArgs->nSplitPane = 0; Сбрасывать не будем? } mn_DlgRc = IDC_START; EndDialog(hDlg, IDC_START); return TRUE; } // case IDC_START: case IDC_TERMINATE: mn_DlgRc = IDC_TERMINATE; EndDialog(hDlg, IDC_TERMINATE); return TRUE; case IDCANCEL: mn_DlgRc = IDCANCEL; EndDialog(hDlg, IDCANCEL); return TRUE; } return FALSE; }
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { #define UM_USER_CONTROLS (WM_USER+121) #define UM_FILL_CMDLIST (WM_USER+122) CRecreateDlg* pDlg = NULL; if (messg == WM_INITDIALOG) { pDlg = (CRecreateDlg*)lParam; pDlg->mh_Dlg = hDlg; SetWindowLongPtr(hDlg, DWLP_USER, lParam); } else { pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER); } if (!pDlg) { return FALSE; } PatchMsgBoxIcon(hDlg, messg, wParam, lParam); switch (messg) { case WM_INITDIALOG: { LRESULT lbRc = FALSE; // Visual SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); // Set password style (avoid "bars" on some OS) SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); // Add menu items HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED, ID_RESETCMDHISTORY, L"Clear history..."); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | (gpSet->isSaveCmdHistory ? MF_CHECKED : 0), ID_STORECMDHISTORY, L"Store history"); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); // Fill command and task drop down SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); // Set text in command and folder fields SetDlgItemText(hDlg, IDC_RESTART_CMD, pDlg->mpsz_DefCmd ? pDlg->mpsz_DefCmd : pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : L""); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pDlg->mpsz_DefDir ? pDlg->mpsz_DefDir : pArgs->pszStartupDir ? pArgs->pszStartupDir : gpConEmu->WorkDir()); // Split controls if (pArgs->aRecreate == cra_RecreateTab) { // Hide Split's ShowWindow(GetDlgItem(hDlg, gbRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplitNone), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Right), SW_HIDE); ShowWindow(GetDlgItem(hDlg, rbRecreateSplit2Bottom), SW_HIDE); ShowWindow(GetDlgItem(hDlg, stRecreateSplit), SW_HIDE); ShowWindow(GetDlgItem(hDlg, tRecreateSplit), SW_HIDE); } else { // Fill splits SetDlgItemInt(hDlg, tRecreateSplit, (1000-pArgs->nSplitValue)/10, FALSE); CheckRadioButton(hDlg, rbRecreateSplitNone, rbRecreateSplit2Bottom, rbRecreateSplitNone+pArgs->eSplit); EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); } // Спрятать флажок "New window" bool bRunInNewWindow_Hidden = (pArgs->aRecreate == cra_EditTab || pArgs->aRecreate == cra_RecreateTab); ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), bRunInNewWindow_Hidden ? SW_HIDE : SW_SHOWNORMAL); const wchar_t *pszUser = pArgs->pszUserName; const wchar_t *pszDomain = pArgs->pszDomain; bool bResticted = (pArgs->RunAsRestricted == crb_On); int nChecked = rbCurrentUser; DWORD nUserNameLen = countof(pDlg->ms_CurUser); if (!GetUserName(pDlg->ms_CurUser, &nUserNameLen)) pDlg->ms_CurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szOtherUser, pszUser, MAX_PATH); wcscat_c(szOtherUser, L"@"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szOtherUser, pszDomain, MAX_PATH); wcscat_c(szOtherUser, L"\\"); lstrcpyn(szOtherUser+_tcslen(szOtherUser), pszUser, MAX_PATH); } } else { lstrcpyn(szOtherUser, pszUser, countof(szOtherUser)); } SetDlgItemText(hDlg, tRunAsPassword, pArgs->szUserPassword); } } SetDlgItemText(hDlg, tRunAsUser, (nChecked == rbAnotherUser) ? szOtherUser : L""); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && (pArgs->RunAsAdministrator == crb_On))) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to restart console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); // Если ВЫКЛЮЧЕН "Multi consoles in one window" // - Check & Disable "New window" checkbox CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow || !gpSetCls->IsMulti()) ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hDlg, cbRunInNewWindow), gpSetCls->IsMulti()); // SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, (pArgs->aRecreate == cra_EditTab) ? L"&Save" : L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); } // Correct cbRunInNewWindow position if (!bRunInNewWindow_Hidden) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } // Ensure, it will be "on screen" RECT rect; GetWindowRect(hDlg, &rect); RECT rcCenter = CenterInParent(rect, pDlg->mh_Parent); MoveWindow(hDlg, rcCenter.left, rcCenter.top, rect.right - rect.left, rect.bottom - rect.top, false); // Была отключена обработка CConEmuMain::OnFocus (лишние телодвижения) PostMessage(hDlg, (WM_APP+1), 0,0); // Default focus control if (pArgs->aRecreate == cra_RecreateTab) SetFocus(GetDlgItem(hDlg, IDC_START)); // Win+~ (Recreate tab), Focus on "Restart" button" else if ((pArgs->pszUserName && *pArgs->pszUserName) && !*pArgs->szUserPassword) SetFocus(GetDlgItem(hDlg, tRunAsPassword)); // We need password, all other fields are ready else SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); // Set focus in command-line field return lbRc; } case (WM_APP+1): //TODO: Не совсем корректно, не учитывается предыдущее значение флажка gpConEmu->SetSkipOnFocus(false); return FALSE; case WM_CTLCOLORSTATIC: if (GetDlgItem(hDlg, IDC_WARNING) == (HWND)lParam) { SetTextColor((HDC)wParam, 255); HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE); SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)hBrush; } break; //case WM_GETICON: // if (wParam==ICON_BIG) // { // /*SetWindowLong(hWnd2, DWL_MSGRESULT, (LRESULT)hClassIcon); // return 1;*/ // } // else // { // SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LRESULT)hClassIconSm); // return 1; // } // return 0; case UM_FILL_CMDLIST: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); pDlg->AddCommandList(pArgs->pszSpecialCmd); pDlg->AddCommandList(pDlg->mpsz_SysCmd, pArgs->pszSpecialCmd ? -1 : 0); pDlg->AddCommandList(pDlg->mpsz_CurCmd); pDlg->AddCommandList(pDlg->mpsz_DefCmd); // Может быть позван после очистки истории из меню, тогда нет смысла и дергаться if (wParam) { LPCWSTR pszHistory = gpSet->HistoryGet(); if (pszHistory) { while (*pszHistory) { pDlg->AddCommandList(pszHistory); pszHistory += _tcslen(pszHistory)+1; } } } // Tasks int nGroup = 0; const Settings::CommandTasks* pGrp = NULL; while ((pGrp = gpSet->CmdTaskGet(nGroup++))) { pDlg->AddCommandList(pGrp->pszName); } } return 0; case UM_USER_CONTROLS: { if (SendDlgItemMessage(hDlg, rbCurrentUser, BM_GETCHECK, 0, 0)) { EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), TRUE); //BOOL lbText = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) == 0; EnableWindow(GetDlgItem(hDlg, tRunAsUser), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), FALSE); } else { if (SendDlgItemMessage(hDlg, tRunAsUser, CB_GETCOUNT, 0, 0) == 0) { DWORD dwLevel = 3, dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0; NET_API_STATUS nStatus; USER_INFO_3 *info = NULL; nStatus = ::NetUserEnum(NULL, dwLevel, FILTER_NORMAL_ACCOUNT, (PBYTE*) & info, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nStatus == NERR_Success) { wchar_t *pszAdmin = NULL, *pszLikeAdmin = NULL, *pszOtherUser = NULL; for (DWORD i = 0; i < dwEntriesRead; ++i) { // usri3_logon_server "\\*" wchar_t * if (!(info[i].usri3_flags & UF_ACCOUNTDISABLE) && info[i].usri3_name && *info[i].usri3_name) { SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)info[i].usri3_name); if (info[i].usri3_priv == 2/*USER_PRIV_ADMIN*/) { if (!pszAdmin && (info[i].usri3_user_id == 500)) pszAdmin = lstrdup(info[i].usri3_name); else if (!pszLikeAdmin && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0)) pszLikeAdmin = lstrdup(info[i].usri3_name); } else if (!pszOtherUser && (info[i].usri3_priv == 1/*USER_PRIV_USER*/) && (lstrcmpi(pDlg->ms_CurUser, info[i].usri3_name) != 0)) { pszOtherUser = lstrdup(info[i].usri3_name); } } } if (GetWindowTextLength(GetDlgItem(hDlg, tRunAsUser)) == 0) { // Try to suggest "Administrator" account SetDlgItemText(hDlg, tRunAsUser, pszAdmin ? pszAdmin : pszLikeAdmin ? pszLikeAdmin : pszOtherUser ? pszOtherUser : pDlg->ms_CurUser); } ::NetApiBufferFree(info); SafeFree(pszAdmin); SafeFree(pszLikeAdmin); } else { // Добавить хотя бы текущего SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)pDlg->ms_CurUser); } } EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsUser), TRUE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), TRUE); } if (wParam == rbAnotherUser) SetFocus(GetDlgItem(hDlg, tRunAsUser)); } return 0; case WM_SYSCOMMAND: switch (LOWORD(wParam)) { case ID_RESETCMDHISTORY: // Подтверждение спросит ResetCmdHistory if (gpSetCls->ResetCmdHistory(hDlg)) { wchar_t* pszCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_RESETCONTENT, 0,0); SendMessage(hDlg, UM_FILL_CMDLIST, FALSE, 0); if (pszCmd) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); free(pszCmd); } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; case ID_STORECMDHISTORY: if (MsgBox(gpSet->isSaveCmdHistory ? L"Do you want to disable history?" : L"Do you want to enable history?", MB_YESNO|MB_ICONQUESTION, NULL, hDlg) == IDYES) { gpSetCls->SetSaveCmdHistory(!gpSet->isSaveCmdHistory); HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); CheckMenuItem(hSysMenu, ID_STORECMDHISTORY, MF_BYCOMMAND|(gpSet->isSaveCmdHistory ? MF_CHECKED : 0)); } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_CHOOSE: { wchar_t *pszFilePath = SelectFile(L"Choose program to run", NULL, hDlg, L"Executables (*.exe)\0*.exe\0All files (*.*)\0*.*\0\0", true, false, false); if (pszFilePath) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszFilePath); SafeFree(pszFilePath); } return 1; } case IDC_CHOOSE_DIR: { wchar_t* pszDefFolder = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszFolder = SelectFolder(L"Choose startup directory", pszDefFolder, hDlg, false, false); if (pszFolder) { SetDlgItemText(hDlg, IDC_STARTUP_DIR, pszFolder); SafeFree(pszFolder); } SafeFree(pszDefFolder); return 1; } case cbRunAsAdmin: { // BCM_SETSHIELD = 5644 BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (gOSVer.dwMajorVersion >= 6) { SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs && (pDlg->mp_Args->aRecreate != cra_EditTab)); } if (bRunAs) { CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser); CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); } return 1; } case rbCurrentUser: case rbAnotherUser: case cbRunAsRestricted: { RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0); return 1; } case rbRecreateSplitNone: case rbRecreateSplit2Right: case rbRecreateSplit2Bottom: { RConStartArgs* pArgs = pDlg->mp_Args; switch (LOWORD(wParam)) { case rbRecreateSplitNone: pArgs->eSplit = RConStartArgs::eSplitNone; break; case rbRecreateSplit2Right: pArgs->eSplit = RConStartArgs::eSplitHorz; break; case rbRecreateSplit2Bottom: pArgs->eSplit = RConStartArgs::eSplitVert; break; } EnableWindow(GetDlgItem(hDlg, tRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); EnableWindow(GetDlgItem(hDlg, stRecreateSplit), (pArgs->eSplit != pArgs->eSplitNone)); if (pArgs->eSplit != pArgs->eSplitNone) SetFocus(GetDlgItem(hDlg, tRecreateSplit)); return 1; } case IDC_START: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); SafeFree(pArgs->pszUserName); SafeFree(pArgs->pszDomain); //SafeFree(pArgs->pszUserPassword); if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0)) { pArgs->RunAsRestricted = crb_Off; pArgs->pszUserName = GetDlgItemText(hDlg, tRunAsUser); if (pArgs->pszUserName) { //pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword); // Попытаться проверить правильность введенного пароля и возможность запуска bool bCheckPwd = pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword)); DWORD nErr = bCheckPwd ? 0 : GetLastError(); if (!bCheckPwd) { DisplayLastError(L"Invalid user name or password was specified!", nErr, MB_ICONSTOP, NULL, hDlg); return 1; } } } else { pArgs->RunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; } // Vista+ (As Admin...) pArgs->RunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0) ? crb_On : crb_Off; // StartupDir (may be specified as argument) wchar_t* pszDir = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL; LPCWSTR pszDirResult = pszExpand ? pszExpand : pszDir; // Another user? We may fail with access denied. Check only for "current user" account if (!pArgs->pszUserName && pszDirResult && *pszDirResult && !DirectoryExists(pszDirResult)) { wchar_t* pszErrInfo = lstrmerge(L"Specified directory does not exists!\n", pszDirResult, L"\n" L"Do you want to choose another directory?\n\n"); DWORD nErr = GetLastError(); int iDirBtn = DisplayLastError(pszErrInfo, nErr, MB_ICONEXCLAMATION|MB_YESNO, NULL, hDlg); if (iDirBtn == IDYES) { SafeFree(pszDir); SafeFree(pszExpand); SafeFree(pszErrInfo); return 1; } // User want to run "as is". Most likely it will fail, but who knows... } SafeFree(pArgs->pszStartupDir); pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir; if (pszExpand) { SafeFree(pszDir) } // Command // pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода SafeFree(pArgs->pszSpecialCmd); // GetDlgItemText выделяет память через calloc pArgs->pszSpecialCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); if (pArgs->pszSpecialCmd) gpSet->HistoryAdd(pArgs->pszSpecialCmd); if ((pArgs->aRecreate != cra_RecreateTab) && (pArgs->aRecreate != cra_EditTab)) { if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0)) pArgs->aRecreate = cra_CreateWindow; else pArgs->aRecreate = cra_CreateTab; } if (((pArgs->aRecreate == cra_CreateTab) || (pArgs->aRecreate == cra_EditTab)) && (pArgs->eSplit != RConStartArgs::eSplitNone)) { BOOL bOk = FALSE; int nPercent = GetDlgItemInt(hDlg, tRecreateSplit, &bOk, FALSE); if (bOk && (nPercent >= 1) && (nPercent <= 99)) { pArgs->nSplitValue = (100-nPercent) * 10; } //pArgs->nSplitPane = 0; Сбрасывать не будем? } pDlg->mn_DlgRc = IDC_START; EndDialog(hDlg, IDC_START); return 1; } case IDC_TERMINATE: pDlg->mn_DlgRc = IDC_TERMINATE; EndDialog(hDlg, IDC_TERMINATE); return 1; case IDCANCEL: pDlg->mn_DlgRc = IDCANCEL; EndDialog(hDlg, IDCANCEL); return 1; } } else if ((HIWORD(wParam) == EN_SETFOCUS) && lParam) { switch (LOWORD(wParam)) { case tRecreateSplit: case tRunAsPassword: PostMessage((HWND)lParam, EM_SETSEL, 0, SendMessage((HWND)lParam, WM_GETTEXTLENGTH, 0,0)); break; } } break; default: return 0; }
void RConStartArgs::RunArgTests() { CmdArg s; s.Set(L"Abcdef", 3); int nDbg = lstrcmp(s, L"Abc"); _ASSERTE(nDbg==0); s.Set(L"qwerty"); nDbg = lstrcmp(s, L"qwerty"); _ASSERTE(nDbg==0); s.Empty(); //s.Set(L""); // !! Set("") must trigger ASSERT !! nDbg = s.ms_Arg ? lstrcmp(s, L"") : -2; _ASSERTE(nDbg==0); struct { LPCWSTR pszWhole; LPCWSTR pszCmp[10]; } lsArgTest[] = { {L"\"C:\\ConEmu\\ConEmuC64.exe\" /PARENTFARPID=1 /C \"C:\\GIT\\cmdw\\ad.cmd CE12.sln & ci -m \"Solution debug build properties\"\"", {L"C:\\ConEmu\\ConEmuC64.exe", L"/PARENTFARPID=1", L"/C", L"C:\\GIT\\cmdw\\ad.cmd", L"CE12.sln", L"&", L"ci", L"-m", L"Solution debug build properties"}}, {L"/C \"C:\\ad.cmd file.txt & ci -m \"Commit message\"\"", {L"/C", L"C:\\ad.cmd", L"file.txt", L"&", L"ci", L"-m", L"Commit message"}}, {L"\"This is test\" Next-arg \t\n \"Third Arg +++++++++++++++++++\" ++", {L"This is test", L"Next-arg", L"Third Arg +++++++++++++++++++"}}, {L"\"\"cmd\"\"", {L"cmd"}}, {L"\"\"c:\\Windows\\System32\\cmd.exe\" /?\"", {L"c:\\Windows\\System32\\cmd.exe", L"/?"}}, // Following example is crazy, but quotation issues may happens //{L"First Sec\"\"ond \"Thi\"rd\" \"Fo\"\"rth\"", {L"First", L"Sec\"\"ond", L"Thi\"rd", L"Fo\"\"rth"}}, {L"First \"Fo\"\"rth\"", {L"First", L"Fo\"\"rth"}}, // Multiple commands {L"set ConEmuReportExe=VIM.EXE & SH.EXE", {L"set", L"ConEmuReportExe=VIM.EXE", L"&", L"SH.EXE"}}, // Inside escaped arguments {L"reg.exe add \"HKCU\\MyCo\" /ve /t REG_EXPAND_SZ /d \"\\\"C:\\ConEmu\\ConEmuPortable.exe\\\" /Dir \\\"%V\\\" /cmd \\\"cmd.exe\\\" \\\"-new_console:nC:cmd.exe\\\" \\\"-cur_console:d:%V\\\"\" /f", // Для наглядности: // reg.exe add "HKCU\MyCo" /ve /t REG_EXPAND_SZ // /d "\"C:\ConEmu\ConEmuPortable.exe\" /Dir \"%V\" /cmd \"cmd.exe\" \"-new_console:nC:cmd.exe\" \"-cur_console:d:%V\"" /f {L"reg.exe", L"add", L"HKCU\\MyCo", L"/ve", L"/t", L"REG_EXPAND_SZ", L"/d", L"\\\"C:\\ConEmu\\ConEmuPortable.exe\\\" /Dir \\\"%V\\\" /cmd \\\"cmd.exe\\\" \\\"-new_console:nC:cmd.exe\\\" \\\"-cur_console:d:%V\\\"", L"/f"}}, // After 'Inside escaped arguments' regression bug appears {L"/dir \"C:\\\" /icon \"cmd.exe\" /single", {L"/dir", L"C:\\", L"/icon", L"cmd.exe", L"/single"}}, {L"cmd \"one.exe /dir \\\"C:\\\\\" /log\" \"two.exe /dir \\\"C:\\\" /log\" end", {L"cmd", L"one.exe /dir \\\"C:\\\\\" /log", L"two.exe /dir \\\"C:\\\" /log", L"end"}}, {NULL} }; for (int i = 0; lsArgTest[i].pszWhole; i++) { s.Empty(); LPCWSTR pszTestCmd = lsArgTest[i].pszWhole; int j = -1; while (lsArgTest[i].pszCmp[++j]) { if (NextArg(&pszTestCmd, s) != 0) { _ASSERTE(FALSE && "Fails on token!"); } else { nDbg = lstrcmp(s, lsArgTest[i].pszCmp[j]); _ASSERTE(nDbg==0); } } } bool bTest = true; for (size_t i = 0; bTest; i++) { RConStartArgs arg; int nDbg; LPCWSTR pszCmp; switch (i) { case 21: pszCmp = L"cmd '-new_console' `-new_console` \\\"-new_console\\\""; arg.pszSpecialCmd = lstrdup(pszCmp); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, pszCmp) && arg.NewConsole==crb_Undefined); break; case 20: arg.pszSpecialCmd = lstrdup(L"\"c:\\cmd.exe\" \"-new_console\" \"c:\\file.txt\""); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\cmd.exe\" \"c:\\file.txt\"")); break; case 19: arg.pszSpecialCmd = lstrdup(L"\"c:\\cmd.exe\" -new_console:n \"c:\\file.txt\""); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\cmd.exe\" \"c:\\file.txt\"")); break; case 18: arg.pszSpecialCmd = lstrdup(L"\"c:\\cmd.exe\" \"-new_console:n\" \"c:\\file.txt\""); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\cmd.exe\" \"c:\\file.txt\"")); break; case 17: arg.pszSpecialCmd = lstrdup(L"c:\\cmd.exe \"-new_console:n\" \"c:\\file.txt\""); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"c:\\cmd.exe \"c:\\file.txt\"")); break; case 16: arg.pszSpecialCmd = lstrdup(L"\"c:\\cmd.exe\" \"-new_console:n\" c:\\file.txt"); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\cmd.exe\" c:\\file.txt")); break; case 15: arg.pszSpecialCmd = lstrdup(L"c:\\file.txt -cur_console"); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"c:\\file.txt")); break; case 14: arg.pszSpecialCmd = lstrdup(L"\"c:\\file.txt\" -cur_console"); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\file.txt\"")); break; case 13: arg.pszSpecialCmd = lstrdup(L" -cur_console \"c:\\file.txt\""); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\file.txt\"")); break; case 12: arg.pszSpecialCmd = lstrdup(L"-cur_console \"c:\\file.txt\""); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"\"c:\\file.txt\"")); break; case 11: arg.pszSpecialCmd = lstrdup(L"-cur_console c:\\file.txt"); arg.ProcessNewConArg(); _ASSERTE(0==lstrcmp(arg.pszSpecialCmd, L"c:\\file.txt")); break; case 10: pszCmp = L"reg.exe add \"HKCU\\command\" /ve /t REG_EXPAND_SZ /d \"\\\"C:\\ConEmu\\ConEmuPortable.exe\\\" /Dir \\\"%V\\\" /cmd \\\"cmd.exe\\\" \\\"-new_console:nC:cmd.exe\\\" \\\"-cur_console:d:%V\\\"\" /f"; arg.pszSpecialCmd = lstrdup(pszCmp); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, pszCmp)==0 && arg.NewConsole==crb_Undefined); break; case 9: pszCmp = L"\"C:\\Windows\\system32\\cmd.exe\" /C \"\"C:\\Python27\\python.EXE\"\""; arg.pszSpecialCmd = lstrdup(pszCmp); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, pszCmp)==0); break; case 8: arg.pszSpecialCmd = lstrdup(L"cmd --new_console -cur_console:a"); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd --new_console")==0 && arg.NewConsole==crb_Undefined && arg.RunAsAdministrator==crb_On); break; case 7: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:d:\"C:\\My docs\":t:\"My title\" \"-cur_console:C:C:\\my cmd.ico\" -cur_console:P:\"<PowerShell>\":a /k ver"); arg.ProcessNewConArg(); pszCmp = L"cmd /k ver"; _ASSERTE(lstrcmp(arg.pszSpecialCmd, pszCmp)==0); _ASSERTE(arg.pszRenameTab && arg.pszPalette && arg.pszIconFile && arg.pszStartupDir && arg.NewConsole==crb_Undefined && lstrcmp(arg.pszRenameTab, L"My title")==0 && lstrcmp(arg.pszPalette, L"<PowerShell>")==0 && lstrcmp(arg.pszStartupDir, L"C:\\My docs")==0 && lstrcmp(arg.pszIconFile, L"C:\\my cmd.ico")==0); break; case 6: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:b:P:\"^<Power\"\"Shell^>\":t:\"My title\" /k ConEmuC.exe -Guimacro print(\"-new_console:a\")"); arg.ProcessNewConArg(); pszCmp = L"cmd /k ConEmuC.exe -Guimacro print(\"-new_console:a\")"; _ASSERTE(lstrcmp(arg.pszSpecialCmd, pszCmp)==0); _ASSERTE(arg.pszRenameTab && arg.pszPalette && arg.BackgroundTab==crb_On && arg.NewConsole==crb_Undefined && arg.RunAsAdministrator==crb_Undefined && lstrcmp(arg.pszRenameTab, L"My title")==0 && lstrcmp(arg.pszPalette, L"<Power\"Shell>")==0); break; case 5: arg.pszSpecialCmd = lstrdup(L"cmd \"-cur_console:t:My title\" /k ver"); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd /k ver")==0); _ASSERTE(arg.pszRenameTab && lstrcmp(arg.pszRenameTab, L"My title")==0 && arg.NewConsole==crb_Undefined); break; case 4: arg.pszSpecialCmd = lstrdup(L"cmd \"-new_console:P:^<Power\"\"Shell^>\""); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd")==0); nDbg = lstrcmp(arg.pszPalette, L"<Power\"Shell>"); _ASSERTE(nDbg==0 && arg.NewConsole==crb_On); break; case 3: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:u:Max:"); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd")==0); nDbg = lstrcmp(arg.pszUserName,L"Max"); _ASSERTE(nDbg==0 && arg.pszDomain==NULL && !*arg.szUserPassword && arg.ForceUserDialog==crb_Off && arg.NewConsole!=crb_On); break; case 2: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:u:Max -new_console"); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd")==0); nDbg = lstrcmp(arg.pszUserName,L"Max"); _ASSERTE(nDbg==0 && arg.pszDomain==NULL && !*arg.szUserPassword && arg.ForceUserDialog==crb_On && arg.NewConsole==crb_On); break; case 1: arg.pszSpecialCmd = lstrdup(L"cmd -new_console:u -cur_console:h0"); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd")==0); _ASSERTE(arg.pszUserName==NULL && arg.pszDomain==NULL && arg.ForceUserDialog==crb_On && arg.NewConsole==crb_On && arg.BufHeight==crb_On && arg.nBufHeight==0); break; case 0: arg.pszSpecialCmd = lstrdup(L"cmd \"-new_console:d:C:\\John Doe\\Home\" "); arg.ProcessNewConArg(); _ASSERTE(lstrcmp(arg.pszSpecialCmd, L"cmd ")==0); nDbg = lstrcmp(arg.pszStartupDir, L"C:\\John Doe\\Home"); _ASSERTE(nDbg==0 && arg.NewConsole==crb_On); break; default: bTest = false; // Stop tests } } nDbg = -1; }
INT_PTR CRecreateDlg::RecreateDlgProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam) { #define UM_USER_CONTROLS (WM_USER+121) #define UM_FILL_CMDLIST (WM_USER+122) CRecreateDlg* pDlg = NULL; if (messg == WM_INITDIALOG) { pDlg = (CRecreateDlg*)lParam; pDlg->mh_Dlg = hDlg; SetWindowLongPtr(hDlg, DWLP_USER, lParam); } else { pDlg = (CRecreateDlg*)GetWindowLongPtr(hDlg, DWLP_USER); } if (!pDlg) { return FALSE; } switch (messg) { case WM_INITDIALOG: { LRESULT lbRc = FALSE; SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon); SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm); HMENU hSysMenu = GetSystemMenu(hDlg, FALSE); InsertMenu(hSysMenu, 0, MF_BYPOSITION, MF_SEPARATOR, 0); InsertMenu(hSysMenu, 0, MF_BYPOSITION | MF_STRING | MF_ENABLED | ((GetWindowLong(ghOpWnd,GWL_EXSTYLE)&WS_EX_TOPMOST) ? MF_CHECKED : 0), ID_RESETCMDHISTORY, _T("Reset command history...")); SendDlgItemMessage(hDlg, tRunAsPassword, WM_SETFONT, (LPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT), 0); //#ifdef _DEBUG //SetWindowPos(ghOpWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE); //#endif SendMessage(hDlg, UM_FILL_CMDLIST, TRUE, 0); RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); LPCWSTR pszCmd = pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : gpConEmu->ActiveCon()->RCon()->GetCmd(); //int nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszCmd); //if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, 0, (LPARAM)pszCmd); LPCWSTR pszSystem = gpSet->GetCmd(); //if (pszSystem != pszCmd && (pszSystem && pszCmd && (lstrcmpi(pszSystem, pszCmd) != 0))) //{ // nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszSystem); // if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, pArgs->pszSpecialCmd ? -1 : 0, (LPARAM)pszSystem); //} //LPCWSTR pszHistory = gpSet->HistoryGet(); //if (pszHistory) //{ // while (*pszHistory) // { // nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszHistory); // if (nId < 0) // SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pszHistory); // pszHistory += _tcslen(pszHistory)+1; // } //} ////// Обновить группы команд ////gpSet->LoadCmdTasks(NULL); //int nGroup = 0; //const Settings::CommandTasks* pGrp = NULL; //while ((pGrp = gpSet->CmdTaskGet(nGroup++))) //{ // nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pGrp->pszName); // if (nId < 0) // SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pGrp->pszName); //} if (pArgs->aRecreate == cra_RecreateTab) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); SetDlgItemText(hDlg, IDC_STARTUP_DIR, gpConEmu->ActiveCon()->RCon()->GetDir()); } else { SetDlgItemText(hDlg, IDC_RESTART_CMD, pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : pszSystem); SetDlgItemText(hDlg, IDC_STARTUP_DIR, pArgs->pszStartupDir ? pArgs->pszStartupDir : L""); } //EnableWindow(GetDlgItem(hDlg, IDC_STARTUP_DIR), FALSE); //#ifndef _DEBUG //EnableWindow(GetDlgItem(hDlg, IDC_CHOOSE_DIR), FALSE); //#endif const wchar_t *pszUser, *pszDomain; BOOL bResticted; int nChecked = rbCurrentUser; wchar_t szCurUser[MAX_PATH*2+1]; DWORD nUserNameLen = countof(szCurUser); if (!GetUserName(szCurUser, &nUserNameLen)) szCurUser[0] = 0; wchar_t szRbCaption[MAX_PATH*3]; lstrcpy(szRbCaption, L"Run as current &user: "******"UPN format" остается в pszUser lstrcpyn(szCurUser, pszUser, MAX_PATH); wcscat_c(szCurUser, L"@"); lstrcpyn(szCurUser+_tcslen(szCurUser), pszDomain, MAX_PATH); } else { // "Старая" нотация domain\user lstrcpyn(szCurUser, pszDomain, MAX_PATH); wcscat_c(szCurUser, L"\\"); lstrcpyn(szCurUser+_tcslen(szCurUser), pszUser, MAX_PATH); } } else { lstrcpyn(szCurUser, pszUser, countof(szCurUser)); } SetDlgItemText(hDlg, tRunAsPassword, L""); } } SetDlgItemText(hDlg, tRunAsUser, szCurUser); CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, nChecked); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); if (gOSVer.dwMajorVersion < 6) { // В XP и ниже это просто RunAs - с возможностью ввода имени пользователя и пароля //apiShowWindow(GetDlgItem(hDlg, cbRunAsAdmin), SW_HIDE); SetDlgItemTextA(hDlg, cbRunAsAdmin, "&Run as..."); //GCC hack. иначе не собирается // И уменьшить длину RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, 0, 0, (rcBox.right-rcBox.left)/2, rcBox.bottom-rcBox.top, SWP_NOMOVE|SWP_NOZORDER); } else if (gpConEmu->mb_IsUacAdmin || (pArgs && pArgs->bRunAsAdministrator)) { CheckDlgButton(hDlg, cbRunAsAdmin, BST_CHECKED); if (gpConEmu->mb_IsUacAdmin) // Только в Vista+ если GUI уже запущен под админом { EnableWindow(GetDlgItem(hDlg, cbRunAsAdmin), FALSE); } else if (gOSVer.dwMajorVersion < 6) { RecreateDlgProc(hDlg, WM_COMMAND, cbRunAsAdmin, 0); } } //} SetClassLongPtr(hDlg, GCLP_HICON, (LONG_PTR)hClassIcon); RECT rcBtnBox = {0}; if (pArgs->aRecreate == cra_RecreateTab) { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "About to recreate console"); SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_EXCLAMATION), 0); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); // Спрятать флажок "New window" ShowWindow(GetDlgItem(hDlg, cbRunInNewWindow), SW_HIDE); lbRc = TRUE; } else { //GCC hack. иначе не собирается SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); CheckDlgButton(hDlg, cbRunInNewWindow, (pArgs->aRecreate == cra_CreateWindow) ? BST_CHECKED : BST_UNCHECKED); //if (pArgs->aRecreate == cra_CreateWindow) //{ // SetWindowText(hDlg, L"ConEmu - Create new window"); // //GCC hack. иначе не собирается // SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new window"); //} //else //{ // //GCC hack. иначе не собирается // SetDlgItemTextA(hDlg, IDC_RESTART_MSG, "Create new console"); //} SendDlgItemMessage(hDlg, IDC_RESTART_ICON, STM_SETICON, (WPARAM)LoadIcon(NULL,IDI_QUESTION), 0); POINT pt = {0,0}; MapWindowPoints(GetDlgItem(hDlg, IDC_TERMINATE), hDlg, &pt, 1); DestroyWindow(GetDlgItem(hDlg, IDC_TERMINATE)); SetWindowPos(GetDlgItem(hDlg, IDC_START), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetDlgItemText(hDlg, IDC_START, L"&Start"); DestroyWindow(GetDlgItem(hDlg, IDC_WARNING)); // Выровнять флажок по кнопке GetWindowRect(GetDlgItem(hDlg, IDC_START), &rcBtnBox); SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); } if (rcBtnBox.left) { // Выровнять флажок по кнопке MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtnBox, 2); RECT rcBox; GetWindowRect(GetDlgItem(hDlg, cbRunAsAdmin), &rcBox); POINT pt; pt.x = rcBtnBox.left - (rcBox.right - rcBox.left) - 5; pt.y = rcBtnBox.top + ((rcBtnBox.bottom-rcBtnBox.top) - (rcBox.bottom-rcBox.top))/2; SetWindowPos(GetDlgItem(hDlg, cbRunAsAdmin), NULL, pt.x, pt.y, 0,0, SWP_NOSIZE|SWP_NOZORDER); SetFocus(GetDlgItem(hDlg, IDC_RESTART_CMD)); } if (pArgs->aRecreate != cra_RecreateTab) { POINT pt = {}; MapWindowPoints(GetDlgItem(hDlg, cbRunAsAdmin), hDlg, &pt, 1); RECT rcBox2; GetWindowRect(GetDlgItem(hDlg, cbRunInNewWindow), &rcBox2); SetWindowPos(GetDlgItem(hDlg, cbRunInNewWindow), NULL, pt.x-(rcBox2.right-rcBox2.left), pt.y, 0,0, SWP_NOSIZE); } RECT rect; GetWindowRect(hDlg, &rect); RECT rcParent; GetWindowRect(ghWnd, &rcParent); MoveWindow(hDlg, (rcParent.left+rcParent.right-rect.right+rect.left)/2, (rcParent.top+rcParent.bottom-rect.bottom+rect.top)/2, rect.right - rect.left, rect.bottom - rect.top, false); PostMessage(hDlg, (WM_APP+1), 0,0); return lbRc; } case (WM_APP+1): gpConEmu->SetSkipOnFocus(FALSE); return FALSE; case WM_CTLCOLORSTATIC: if (GetDlgItem(hDlg, IDC_WARNING) == (HWND)lParam) { SetTextColor((HDC)wParam, 255); HBRUSH hBrush = GetSysColorBrush(COLOR_3DFACE); SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)hBrush; } break; //case WM_GETICON: // if (wParam==ICON_BIG) // { // /*SetWindowLong(hWnd2, DWL_MSGRESULT, (LRESULT)hClassIcon); // return 1;*/ // } // else // { // SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LRESULT)hClassIconSm); // return 1; // } // return 0; case UM_FILL_CMDLIST: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); LPCWSTR pszCmd = pArgs->pszSpecialCmd ? pArgs->pszSpecialCmd : gpConEmu->ActiveCon()->RCon()->GetCmd(); int nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszCmd); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, 0, (LPARAM)pszCmd); LPCWSTR pszSystem = gpSet->GetCmd(); if (pszSystem != pszCmd && (pszSystem && pszCmd && (lstrcmpi(pszSystem, pszCmd) != 0))) { nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszSystem); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, pArgs->pszSpecialCmd ? -1 : 0, (LPARAM)pszSystem); } if (wParam) { LPCWSTR pszHistory = gpSet->HistoryGet(); if (pszHistory) { while (*pszHistory) { nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pszHistory); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pszHistory); pszHistory += _tcslen(pszHistory)+1; } } } //// Обновить группы команд //gpSet->LoadCmdTasks(NULL); int nGroup = 0; const Settings::CommandTasks* pGrp = NULL; while ((pGrp = gpSet->CmdTaskGet(nGroup++))) { nId = SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_FINDSTRINGEXACT, -1, (LPARAM)pGrp->pszName); if (nId < 0) SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_INSERTSTRING, -1, (LPARAM)pGrp->pszName); } } return 0; case UM_USER_CONTROLS: { if (SendDlgItemMessage(hDlg, rbCurrentUser, BM_GETCHECK, 0, 0)) { EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), TRUE); //BOOL lbText = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0) == 0; EnableWindow(GetDlgItem(hDlg, tRunAsUser), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), FALSE); } else { if (SendDlgItemMessage(hDlg, tRunAsUser, CB_GETCOUNT, 0, 0) == 0) { DWORD dwLevel = 3, dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0; NET_API_STATUS nStatus; USER_INFO_3 *info = NULL; nStatus = ::NetUserEnum(NULL, dwLevel, FILTER_NORMAL_ACCOUNT, (PBYTE*) & info, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); if (nStatus == NERR_Success) { for(DWORD i = 0; i < dwEntriesRead; ++i) { // usri3_logon_server "\\*" wchar_t * if ((info[i].usri3_flags & UF_ACCOUNTDISABLE) == 0) SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)info[i].usri3_name); } ::NetApiBufferFree(info); } else { // Добавить хотя бы текущего wchar_t szCurUser[MAX_PATH]; if (GetWindowText(GetDlgItem(hDlg, tRunAsUser), szCurUser, countof(szCurUser))) SendDlgItemMessage(hDlg, tRunAsUser, CB_ADDSTRING, 0, (LPARAM)szCurUser); } } EnableWindow(GetDlgItem(hDlg, cbRunAsRestricted), FALSE); EnableWindow(GetDlgItem(hDlg, tRunAsUser), TRUE); EnableWindow(GetDlgItem(hDlg, tRunAsPassword), TRUE); } if (wParam == rbAnotherUser) SetFocus(GetDlgItem(hDlg, tRunAsUser)); } return 0; case WM_SYSCOMMAND: if (LOWORD(wParam) == ID_RESETCMDHISTORY) { if (IDYES == MessageBox(hDlg, L"Clear command history?", gpConEmu->GetDefaultTitle(), MB_ICONEXCLAMATION|MB_YESNO|MB_DEFBUTTON2)) { gpSet->HistoryReset(); wchar_t* pszCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); SendDlgItemMessage(hDlg, IDC_RESTART_CMD, CB_RESETCONTENT, 0,0); SendMessage(hDlg, UM_FILL_CMDLIST, FALSE, 0); if (pszCmd) { SetDlgItemText(hDlg, IDC_RESTART_CMD, pszCmd); free(pszCmd); } } SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0); return 1; } break; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { switch(LOWORD(wParam)) { case IDC_CHOOSE: { wchar_t *pszFilePath = NULL; int nLen = MAX_PATH*2; pszFilePath = (wchar_t*)calloc(nLen+3,2); // +2*'"'+\0 if (!pszFilePath) return 1; OPENFILENAME ofn; memset(&ofn,0,sizeof(ofn)); ofn.lStructSize=sizeof(ofn); ofn.hwndOwner = hDlg; ofn.lpstrFilter = _T("Executables (*.exe)\0*.exe\0\0"); ofn.nFilterIndex = 1; ofn.lpstrFile = pszFilePath+1; ofn.nMaxFile = nLen; ofn.lpstrTitle = _T("Choose program to run"); ofn.Flags = OFN_ENABLESIZING|OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST|OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST; if (GetOpenFileName(&ofn)) { LPCWSTR pszNewText = pszFilePath + 1; if (wcschr(pszFilePath, L' ')) { pszFilePath[0] = L'"'; _wcscat_c(pszFilePath, nLen+3, L"\""); pszNewText = pszFilePath; } SetDlgItemText(hDlg, IDC_RESTART_CMD, pszNewText); } SafeFree(pszFilePath); return 1; } case IDC_CHOOSE_DIR: { BROWSEINFO bi = {ghWnd}; wchar_t szFolder[MAX_PATH+1] = {0}; GetDlgItemText(hDlg, IDC_STARTUP_DIR, szFolder, countof(szFolder)); bi.pszDisplayName = szFolder; wchar_t szTitle[100]; bi.lpszTitle = wcscpy(szTitle, L"Choose startup directory"); bi.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS | BIF_VALIDATE; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)szFolder; LPITEMIDLIST pRc = SHBrowseForFolder(&bi); if (pRc) { if (SHGetPathFromIDList(pRc, szFolder)) { SetDlgItemText(hDlg, IDC_STARTUP_DIR, szFolder); } CoTaskMemFree(pRc); } return 1; } case cbRunAsAdmin: { // BCM_SETSHIELD = 5644 BOOL bRunAs = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (gOSVer.dwMajorVersion >= 6) { SendDlgItemMessage(hDlg, IDC_START, 5644/*BCM_SETSHIELD*/, 0, bRunAs); } if (bRunAs) { CheckRadioButton(hDlg, rbCurrentUser, rbAnotherUser, rbCurrentUser); CheckDlgButton(hDlg, cbRunAsRestricted, BST_UNCHECKED); RecreateDlgProc(hDlg, UM_USER_CONTROLS, 0, 0); } return 1; } case rbCurrentUser: case rbAnotherUser: case cbRunAsRestricted: { RecreateDlgProc(hDlg, UM_USER_CONTROLS, LOWORD(wParam), 0); return 1; } case IDC_START: { RConStartArgs* pArgs = pDlg->mp_Args; _ASSERTE(pArgs); SafeFree(pArgs->pszUserName); SafeFree(pArgs->pszDomain); //SafeFree(pArgs->pszUserPassword); if (SendDlgItemMessage(hDlg, rbAnotherUser, BM_GETCHECK, 0, 0)) { pArgs->bRunAsRestricted = FALSE; pArgs->pszUserName = GetDlgItemText(hDlg, tRunAsUser); if (pArgs->pszUserName) { //pArgs->pszUserPassword = GetDlgItemText(hDlg, tRunAsPassword); // Попытаться проверить правильность введенного пароля и возможность запуска if (!pArgs->CheckUserToken(GetDlgItem(hDlg, tRunAsPassword))) return 1; } } else { pArgs->bRunAsRestricted = SendDlgItemMessage(hDlg, cbRunAsRestricted, BM_GETCHECK, 0, 0); } // Command // pszSpecialCmd мог быть передан аргументом - умолчание для строки ввода SafeFree(pArgs->pszSpecialCmd); // GetDlgItemText выделяет память через calloc pArgs->pszSpecialCmd = GetDlgItemText(hDlg, IDC_RESTART_CMD); if (pArgs->pszSpecialCmd) gpSet->HistoryAdd(pArgs->pszSpecialCmd); // StartupDir (может быть передан аргументом) SafeFree(pArgs->pszStartupDir); wchar_t* pszDir = GetDlgItemText(hDlg, IDC_STARTUP_DIR); wchar_t* pszExpand = (pszDir && wcschr(pszDir, L'%')) ? ExpandEnvStr(pszDir) : NULL; pArgs->pszStartupDir = pszExpand ? pszExpand : pszDir; if (pszExpand) { SafeFree(pszDir) } // Vista+ (As Admin...) pArgs->bRunAsAdministrator = SendDlgItemMessage(hDlg, cbRunAsAdmin, BM_GETCHECK, 0, 0); if (pArgs->aRecreate != cra_RecreateTab) { if (SendDlgItemMessage(hDlg, cbRunInNewWindow, BM_GETCHECK, 0, 0)) pArgs->aRecreate = cra_CreateWindow; else pArgs->aRecreate = cra_CreateTab; } pDlg->mn_DlgRc = IDC_START; EndDialog(hDlg, IDC_START); return 1; } case IDC_TERMINATE: pDlg->mn_DlgRc = IDC_TERMINATE; EndDialog(hDlg, IDC_TERMINATE); return 1; case IDCANCEL: pDlg->mn_DlgRc = IDCANCEL; EndDialog(hDlg, IDCANCEL); return 1; } } break; default: return 0; } return 0; }
void RConStartArgs::RunArgTests() { struct { LPCWSTR pszArg, pszNeed; } cTests[] = { { L"\"c:\\cmd.exe\" \"-new_console\" \"c:\\file.txt\"", L"\"c:\\cmd.exe\" \"c:\\file.txt\"" }, { L"\"c:\\cmd.exe\" -new_console:n \"c:\\file.txt\"", L"\"c:\\cmd.exe\" \"c:\\file.txt\"" }, { L"\"c:\\cmd.exe\" \"-new_console:n\" \"c:\\file.txt\"", L"\"c:\\cmd.exe\" \"c:\\file.txt\"" }, { L"c:\\cmd.exe \"-new_console:n\" \"c:\\file.txt\"", L"c:\\cmd.exe \"c:\\file.txt\"" }, { L"\"c:\\cmd.exe\" \"-new_console:n\" c:\\file.txt", L"\"c:\\cmd.exe\" c:\\file.txt" }, { L"c:\\file.txt -cur_console", L"c:\\file.txt" }, { L"\"c:\\file.txt\" -cur_console", L"\"c:\\file.txt\"" }, { L" -cur_console \"c:\\file.txt\"", L" \"c:\\file.txt\"" }, { L"-cur_console \"c:\\file.txt\"", L"\"c:\\file.txt\"" }, { L"-cur_console c:\\file.txt", L"c:\\file.txt" }, }; for (size_t i = 0; i < countof(cTests); i++) { RConStartArgs arg; arg.pszSpecialCmd = lstrdup(cTests[i].pszArg); arg.ProcessNewConArg(); if (lstrcmp(arg.pszSpecialCmd, cTests[i].pszNeed) != 0) { //_ASSERTE(FALSE && "arg.ProcessNewConArg failed"); OutputDebugString(L"arg.ProcessNewConArg failed\n"); } int nDbg = 0; } for (size_t i = 0; i <= 4; i++) { RConStartArgs arg; switch (i) { case 0: arg.pszSpecialCmd = lstrdup(L"cmd \"-new_console:d:C:\\John Doe\\Home\" "); break; case 1: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:u"); break; case 2: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:u:Max"); break; case 3: arg.pszSpecialCmd = lstrdup(L"cmd -cur_console:u:Max:"); break; case 4: arg.pszSpecialCmd = lstrdup(L"cmd \"-new_console:P:^<Power\"\"Shell^>\""); break; } arg.ProcessNewConArg(); int nDbg = lstrcmp(arg.pszSpecialCmd, i ? L"cmd" : L"cmd "); _ASSERTE(nDbg==0); switch (i) { case 0: nDbg = lstrcmp(arg.pszStartupDir, L"C:\\John Doe\\Home"); _ASSERTE(nDbg==0); break; case 1: _ASSERTE(arg.pszUserName==NULL && arg.pszDomain==NULL && arg.bForceUserDialog); break; case 2: nDbg = lstrcmp(arg.pszUserName,L"Max"); _ASSERTE(nDbg==0 && arg.pszDomain==NULL && !*arg.szUserPassword && arg.bForceUserDialog); break; case 3: nDbg = lstrcmp(arg.pszUserName,L"Max"); _ASSERTE(nDbg==0 && arg.pszDomain==NULL && !*arg.szUserPassword && !arg.bForceUserDialog); break; case 4: nDbg = lstrcmp(arg.pszPalette, L"<Power\"Shell>"); _ASSERTE(nDbg==0); break; } } CmdArg s; s.Set(L"Abcdef", 3); int nDbg = lstrcmp(s, L"Abc"); _ASSERTE(nDbg==0); s.Set(L"qwerty"); nDbg = lstrcmp(s, L"qwerty"); _ASSERTE(nDbg==0); s.Empty(); //s.Set(L""); // !! Set("") must trigger ASSERT !! nDbg = s.ms_Arg ? lstrcmp(s, L"") : -2; _ASSERTE(nDbg==0); struct { LPCWSTR pszWhole; LPCWSTR pszCmp[5]; } lsArgTest[] = { {L"\"This is test\" Next-arg \t\n \"Third Arg +++++++++++++++++++\" ++", {L"This is test", L"Next-arg", L"Third Arg +++++++++++++++++++"}}, {L"\"\"cmd\"\"", {L"cmd"}}, {L"\"\"c:\\Windows\\System32\\cmd.exe\" /?\"", {L"c:\\Windows\\System32\\cmd.exe", L"/?"}}, // Following example is crazy, but quotation issues may happens //{L"First Sec\"\"ond \"Thi\"rd\" \"Fo\"\"rth\"", {L"First", L"Sec\"\"ond", L"Thi\"rd", L"Fo\"\"rth"}}, {L"First \"Fo\"\"rth\"", {L"First", L"Fo\"\"rth"}}, // Multiple commands {L"set ConEmuReportExe=VIM.EXE & SH.EXE", {L"set", L"ConEmuReportExe=VIM.EXE", L"&", L"SH.EXE"}}, {NULL} }; for (int i = 0; lsArgTest[i].pszWhole; i++) { s.Empty(); LPCWSTR pszTestCmd = lsArgTest[i].pszWhole; int j = -1; while (lsArgTest[i].pszCmp[++j]) { if (NextArg(&pszTestCmd, s) != 0) { _ASSERTE(FALSE && "Fails on token!"); } else { nDbg = lstrcmp(s, lsArgTest[i].pszCmp[j]); _ASSERTE(nDbg==0); } } } nDbg = -1; }
//// Эта функция пайп не закрывает! //void CGuiServer::GuiServerThreadCommand(HANDLE hPipe) BOOL CGuiServer::GuiServerCommand(LPVOID pInst, CESERVER_REQ* pIn, CESERVER_REQ* &ppReply, DWORD &pcbReplySize, DWORD &pcbMaxReplySize, LPARAM lParam) { BOOL lbRc = FALSE; CGuiServer* pGSrv = (CGuiServer*)lParam; if (!pGSrv) { _ASSERTE(((CGuiServer*)lParam)!=NULL); pGSrv = &gpConEmu->m_GuiServer; } if (pIn->hdr.bAsync) pGSrv->mp_GuiServer->BreakConnection(pInst); gpSetCls->debugLogCommand(pIn, TRUE, timeGetTime(), 0, pGSrv ? pGSrv->ms_ServerPipe : NULL); #ifdef _DEBUG UINT nDataSize = pIn->hdr.cbSize - sizeof(CESERVER_REQ_HDR); #endif // Все данные из пайпа получены, обрабатываем команду и возвращаем (если нужно) результат #ifdef ALLOW_WINE_MSG if (gbIsWine) { wchar_t szMsg[128]; msprintf(szMsg, countof(szMsg), L"CGuiServer::GuiServerCommand.\nGUI TID=%u\nSrcPID=%u, SrcTID=%u, Cmd=%u", GetCurrentThreadId(), pIn->hdr.nSrcPID, pIn->hdr.nSrcThreadId, pIn->hdr.nCmd); MessageBox(szMsg, MB_ICONINFORMATION); } #endif switch (pIn->hdr.nCmd) { case CECMD_NEWCMD: { // Приходит из другой копии ConEmu.exe, когда она запущена с ключом /single, /showhide, /showhideTSA DEBUGSTRCMD(L"GUI recieved CECMD_NEWCMD\n"); LPCWSTR pszCommand = pIn->NewCmd.GetCommand(); _ASSERTE(pszCommand!=NULL && "Must be at least empty string but NOT NULL"); if (pIn->NewCmd.isAdvLogging && !gpSetCls->isAdvLogging) { gpSetCls->isAdvLogging = pIn->NewCmd.isAdvLogging; gpConEmu->CreateLog(); } if (gpSetCls->isAdvLogging && (pIn->NewCmd.isAdvLogging > gpSetCls->isAdvLogging)) { wchar_t szLogLevel[80]; _wsprintf(szLogLevel, SKIPLEN(countof(szLogLevel)) L"Changing log level! Old=%u, New=%u", (UINT)gpSetCls->isAdvLogging, (UINT)pIn->NewCmd.isAdvLogging); gpConEmu->LogString(szLogLevel); gpSetCls->isAdvLogging = pIn->NewCmd.isAdvLogging; } if (gpSetCls->isAdvLogging) { size_t cchAll = 120 + _tcslen(pIn->NewCmd.szConEmu) + _tcslen(pIn->NewCmd.szCurDir) + _tcslen(pszCommand); wchar_t* pszInfo = (wchar_t*)malloc(cchAll*sizeof(*pszInfo)); if (pszInfo) { _wsprintf(pszInfo, SKIPLEN(cchAll) L"CECMD_NEWCMD: Wnd=x%08X, Act=%u, ConEmu=%s, Dir=%s, Cmd=%s", (DWORD)(DWORD_PTR)pIn->NewCmd.hFromConWnd, pIn->NewCmd.ShowHide, pIn->NewCmd.szConEmu, pIn->NewCmd.szCurDir, pszCommand); gpConEmu->LogString(pszInfo); free(pszInfo); } } BOOL bAccepted = FALSE; if (pIn->NewCmd.szConEmu[0]) { bAccepted = (lstrcmpi(gpConEmu->ms_ConEmuExeDir, pIn->NewCmd.szConEmu) == 0); } else { bAccepted = TRUE; } if (bAccepted) { bool bCreateTab = (pIn->NewCmd.ShowHide == sih_None || pIn->NewCmd.ShowHide == sih_StartDetached) // Issue 1275: When minimized into TSA (on all VCon are closed) we need to restore and run new tab || (pszCommand[0] && !CVConGroup::isVConExists(0)); RConStartArgs rTest; if (pszCommand[0]) { rTest.pszSpecialCmd = lstrdup(pszCommand); rTest.ProcessNewConArg(); } bool bSkipActivation = false; // Может быть пусто if (bCreateTab && pszCommand[0]) { RConStartArgs *pArgs = new RConStartArgs; // New tab must be started with same credentials that calling tab if others was not specified { if (!rTest.HasInheritedArgs()) { CVConGuard VCon; if ((pIn->NewCmd.hFromConWnd || pIn->NewCmd.hFromDcWnd) && CVConGroup::GetVConByHWND(pIn->NewCmd.hFromConWnd, pIn->NewCmd.hFromDcWnd, &VCon)) { const RConStartArgs& r = VCon->RCon()->GetArgs(); if (r.HasInheritedArgs()) { pArgs->AssignInheritedArgs(&r); } } } } pArgs->Detached = (pIn->NewCmd.ShowHide == sih_StartDetached) ? crb_On : crb_Off; pArgs->pszSpecialCmd = lstrdup(pszCommand); if (pIn->NewCmd.szCurDir[0] == 0) { _ASSERTE(pIn->NewCmd.szCurDir[0] != 0); } else { pArgs->pszStartupDir = lstrdup(pIn->NewCmd.szCurDir); } LPCWSTR pszStrings = pIn->NewCmd.GetEnvStrings(); if (pszStrings && pIn->NewCmd.cchEnvStrings) { size_t cbBytes = pIn->NewCmd.cchEnvStrings*sizeof(*pArgs->pszEnvStrings); pArgs->pszEnvStrings = (wchar_t*)malloc(cbBytes); if (pArgs->pszEnvStrings) { memmove(pArgs->pszEnvStrings, pszStrings, cbBytes); pArgs->cchEnvStrings = pIn->NewCmd.cchEnvStrings; } } if (gpSetCls->IsMulti() || CVConGroup::isDetached()) { gpConEmu->PostCreateCon(pArgs); } else { // Если хотят в одном окне - только одну консоль gpConEmu->CreateWnd(pArgs); SafeDelete(pArgs); // New window created? Don't activate this one. bSkipActivation = true; } } else { _ASSERTE(pIn->NewCmd.ShowHide==sih_ShowMinimize || pIn->NewCmd.ShowHide==sih_ShowHideTSA || pIn->NewCmd.ShowHide==sih_Show); } // gh#151: Do animation after starting tab creation if (!bSkipActivation && (rTest.BackgroundTab != crb_On)) { gpConEmu->DoMinimizeRestore(bCreateTab ? sih_SetForeground : pIn->NewCmd.ShowHide); } } pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(BYTE); lbRc = ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize); if (lbRc) { ppReply->Data[0] = bAccepted; } break; } //CECMD_NEWCMD case CECMD_TABSCMD: { // 0: спрятать/показать табы, 1: перейти на следующую, 2: перейти на предыдущую, 3: commit switch DEBUGSTRCMD(L"GUI recieved CECMD_TABSCMD\n"); _ASSERTE(nDataSize>=1); DWORD nTabCmd = pIn->Data[0]; gpConEmu->TabCommand((ConEmuTabCommand)nTabCmd); pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(BYTE); if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { lbRc = TRUE; ppReply->Data[0] = TRUE; } break; } // CECMD_TABSCMD case CECMD_ATTACH2GUI: { // Получен запрос на Attach из сервера MCHKHEAP; CESERVER_REQ_SRVSTARTSTOPRET Ret = {}; lbRc = CVConGroup::AttachRequested(pIn->StartStop.hWnd, &(pIn->StartStop), Ret); pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SRVSTARTSTOPRET)+(Ret.cchEnvCommands*sizeof(wchar_t)); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { SafeFree(Ret.pszCommands); goto wrap; } if (lbRc) { _ASSERTE(sizeof(ppReply->SrvStartStopRet) == sizeof(Ret)); memmove(&ppReply->SrvStartStopRet, &Ret, sizeof(Ret)); // Environment strings (inherited from parent console) if (Ret.cchEnvCommands && Ret.pszCommands) { memmove(ppReply->SrvStartStopRet.szCommands, Ret.pszCommands, Ret.cchEnvCommands*sizeof(wchar_t)); ppReply->SrvStartStopRet.cchEnvCommands = Ret.cchEnvCommands; } else { ppReply->SrvStartStopRet.cchEnvCommands = 0; } SafeFree(Ret.pszCommands); _ASSERTE((ppReply->StartStopRet.nBufferHeight == 0) || ((int)ppReply->StartStopRet.nBufferHeight > (pIn->StartStop.sbi.srWindow.Bottom-pIn->StartStop.sbi.srWindow.Top))); } MCHKHEAP; break; } // CECMD_ATTACH2GUI case CECMD_SRVSTARTSTOP: { MCHKHEAP; // SRVSTART не приходит если запускается cmd под админом или из Win+G bool lbAllocated = false; if (pIn->SrvStartStop.Started == srv_Started) { // Запущен процесс сервера HWND hConWnd = (HWND)pIn->dwData[1]; _ASSERTE(hConWnd && IsWindow(hConWnd)); DWORD nStartTick = timeGetTime(); struct MsgSrvStartedArg { HWND hConWnd; DWORD nSrcPID; DWORD dwKeybLayout; DWORD timeStart; DWORD timeRecv; DWORD timeFin; CESERVER_REQ_SRVSTARTSTOPRET Ret; //111002 - вернуть должен HWND окна отрисовки (дочернее окно ConEmu) static LRESULT OnSrvStarted(LPARAM lParam) { MsgSrvStartedArg *pArg = (MsgSrvStartedArg*)lParam; HWND hWndDC = NULL; DWORD nServerPID = pArg->nSrcPID; HWND hWndCon = pArg->hConWnd; DWORD dwKeybLayout = pArg->dwKeybLayout; pArg->timeRecv = timeGetTime(); DWORD t1, t2; int iFound = -1; hWndDC = CVConGroup::DoSrvCreated(nServerPID, hWndCon, dwKeybLayout, t1, t2, iFound, pArg->Ret); UNREFERENCED_PARAMETER(dwKeybLayout); UNREFERENCED_PARAMETER(hWndCon); pArg->timeFin = timeGetTime(); if (hWndDC == NULL) { _ASSERTE(hWndDC!=NULL); } else { #ifdef _DEBUG DWORD nRecvDur = pArg->timeRecv - pArg->timeStart; DWORD nProcDur = pArg->timeFin - pArg->timeRecv; #define MSGSTARTED_TIMEOUT 10000 if ((nRecvDur > MSGSTARTED_TIMEOUT) || (nProcDur > MSGSTARTED_TIMEOUT)) { _ASSERTE((nRecvDur <= MSGSTARTED_TIMEOUT) && (nProcDur <= MSGSTARTED_TIMEOUT)); } #endif } return (LRESULT)hWndDC; }; } arg = {hConWnd, pIn->hdr.nSrcPID, pIn->SrvStartStop.dwKeybLayout, nStartTick}; gpConEmu->CallMainThread(true, arg.OnSrvStarted, (LPARAM)&arg); HWND hWndDC = arg.Ret.Info.hWndDc; HWND hWndBack = arg.Ret.Info.hWndBack; _ASSERTE(hWndDC!=NULL); #ifdef _DEBUG DWORD dwErr = GetLastError(), nEndTick = timeGetTime(), nDelta = nEndTick - nStartTick; if (hWndDC && nDelta >= EXECUTE_CMD_WARN_TIMEOUT) { if (!IsDebuggerPresent()) { //_ASSERTE(nDelta <= EXECUTE_CMD_WARN_TIMEOUT || (pIn->hdr.nCmd == CECMD_CMDSTARTSTOP && nDelta <= EXECUTE_CMD_WARN_TIMEOUT2)); _ASSERTEX(nDelta <= EXECUTE_CMD_WARN_TIMEOUT); } } #endif pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SRVSTARTSTOPRET)+(arg.Ret.cchEnvCommands*sizeof(wchar_t)); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { SafeFree(arg.Ret.pszCommands); goto wrap; } lbAllocated = true; _ASSERTE(sizeof(ppReply->SrvStartStopRet) == sizeof(arg.Ret)); memmove(&ppReply->SrvStartStopRet, &arg.Ret, sizeof(arg.Ret)); // Environment strings (inherited from parent console) if (arg.Ret.cchEnvCommands && arg.Ret.pszCommands) { memmove(ppReply->SrvStartStopRet.szCommands, arg.Ret.pszCommands, arg.Ret.cchEnvCommands*sizeof(wchar_t)); ppReply->SrvStartStopRet.cchEnvCommands = arg.Ret.cchEnvCommands; } else { ppReply->SrvStartStopRet.cchEnvCommands = 0; } SafeFree(arg.Ret.pszCommands); } else if (pIn->SrvStartStop.Started == srv_Stopped) { // Процесс сервера завершается CRealConsole* pRCon = NULL; CVConGuard VCon; for (size_t i = 0;; i++) { if (!CVConGroup::GetVCon(i, &VCon)) break; pRCon = VCon->RCon(); if (pRCon && (pRCon->GetServerPID(true) == pIn->hdr.nSrcPID || pRCon->GetServerPID(false) == pIn->hdr.nSrcPID)) { break; } pRCon = NULL; } gpConEmu->mn_ShellExitCode = pIn->SrvStartStop.nShellExitCode; if (pRCon) pRCon->OnServerClosing(pIn->hdr.nSrcPID, &pIn->SrvStartStop.nShellExitCode); //pIn->dwData[0] = 1; } else { _ASSERTE((pIn->dwData[0] == 1) || (pIn->dwData[0] == 101)); } MCHKHEAP; if (!lbAllocated) { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_SRVSTARTSTOPRET); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; } lbRc = TRUE; //// Отправляем //fSuccess = WriteFile( // hPipe, // handle to pipe // pOut, // buffer to write from // pOut->hdr.cbSize, // number of bytes to write // &cbWritten, // number of bytes written // NULL); // not overlapped I/O //ExecuteFreeResult(pOut); break; } // CECMD_SRVSTARTSTOP case CECMD_ASSERT: { DWORD nBtn = MessageBox(NULL, pIn->AssertInfo.szDebugInfo, pIn->AssertInfo.szTitle, pIn->AssertInfo.nBtns); pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(DWORD); if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { lbRc = TRUE; ppReply->dwData[0] = nBtn; } //ExecutePrepareCmd(&pIn->hdr, CECMD_ASSERT, sizeof(CESERVER_REQ_HDR) + sizeof(DWORD)); //pIn->dwData[0] = nBtn; //// Отправляем //fSuccess = WriteFile( // hPipe, // handle to pipe // pIn, // buffer to write from // pIn->hdr.cbSize, // number of bytes to write // &cbWritten, // number of bytes written // NULL); // not overlapped I/O break; } // CECMD_ASSERT case CECMD_ATTACHGUIAPP: { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_ATTACHGUIAPP); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; ppReply->AttachGuiApp = pIn->AttachGuiApp; //CESERVER_REQ Out; //ExecutePrepareCmd(&Out.hdr, CECMD_ATTACHGUIAPP, sizeof(CESERVER_REQ_HDR)+sizeof(Out.AttachGuiApp)); //Out.AttachGuiApp = pIn->AttachGuiApp; #ifdef SHOW_GUIATTACH_START if (pIn->AttachGuiApp.hWindow == NULL) { wchar_t szDbg[1024]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"AttachGuiApp requested from:\n%s\nPID=%u", pIn->AttachGuiApp.sAppFilePathName, pIn->AttachGuiApp.nPID); //MBoxA(szDbg); MessageBox(NULL, szDbg, L"ConEmu", MB_SYSTEMMODAL); } #endif // Уведомить ожидающую вкладку CRealConsole* pRCon = CVConGroup::AttachRequestedGui(pIn->AttachGuiApp.nServerPID, pIn->AttachGuiApp.sAppFilePathName, pIn->AttachGuiApp.nPID); if (pRCon) { CVConGuard VCon(pRCon->VCon()); RECT rcPrev = ppReply->AttachGuiApp.rcWindow; HWND hBack = pRCon->VCon()->GetBack(); //// Размер должен быть независим от возможности наличия прокрутки в VCon //GetWindowRect(hBack, &ppReply->AttachGuiApp.rcWindow); //ppReply->AttachGuiApp.rcWindow.right -= ppReply->AttachGuiApp.rcWindow.left; //ppReply->AttachGuiApp.rcWindow.bottom -= ppReply->AttachGuiApp.rcWindow.top; //ppReply->AttachGuiApp.rcWindow.left = ppReply->AttachGuiApp.rcWindow.top = 0; ////MapWindowPoints(NULL, hBack, (LPPOINT)&ppReply->AttachGuiApp.rcWindow, 2); //pRCon->CorrectGuiChildRect(ppReply->AttachGuiApp.nStyle, ppReply->AttachGuiApp.nStyleEx, ppReply->AttachGuiApp.rcWindow); // Уведомить RCon и ConEmuC, что гуй подцепился // Вызывается два раза. Первый (при запуске exe) ahGuiWnd==NULL, второй - после фактического создания окна pRCon->SetGuiMode(pIn->AttachGuiApp.nFlags, pIn->AttachGuiApp.hAppWindow, pIn->AttachGuiApp.Styles.nStyle, pIn->AttachGuiApp.Styles.nStyleEx, pIn->AttachGuiApp.sAppFilePathName, pIn->AttachGuiApp.nPID, pIn->hdr.nBits, rcPrev); ppReply->AttachGuiApp.nFlags = agaf_Success | (pRCon->isActive(false) ? 0 : agaf_Inactive); ppReply->AttachGuiApp.nServerPID = pRCon->GetServerPID(); ppReply->AttachGuiApp.nPID = ppReply->AttachGuiApp.nServerPID; ppReply->AttachGuiApp.hConEmuDc = pRCon->GetView(); ppReply->AttachGuiApp.hConEmuBack = hBack; ppReply->AttachGuiApp.hConEmuWnd = ghWnd; ppReply->AttachGuiApp.hAppWindow = pIn->AttachGuiApp.hAppWindow; ppReply->AttachGuiApp.hSrvConWnd = pRCon->ConWnd(); ppReply->AttachGuiApp.hkl = (DWORD)(LONG)(LONG_PTR)GetKeyboardLayout(gpConEmu->mn_MainThreadId); ZeroStruct(ppReply->AttachGuiApp.Styles.Shifts); CRealConsole::CorrectGuiChildRect(pIn->AttachGuiApp.Styles.nStyle, pIn->AttachGuiApp.Styles.nStyleEx, ppReply->AttachGuiApp.Styles.Shifts, pIn->AttachGuiApp.sAppFilePathName); } else { ppReply->AttachGuiApp.nFlags = agaf_Fail; _ASSERTE(FALSE && "No one tab is waiting for ChildGui process"); } lbRc = TRUE; //// Отправляем //fSuccess = WriteFile( // hPipe, // handle to pipe // &Out, // buffer to write from // Out.hdr.cbSize, // number of bytes to write // &cbWritten, // number of bytes written // NULL); // not overlapped I/O break; } // CECMD_ATTACHGUIAPP case CECMD_GUICLIENTSHIFT: { pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(GuiStylesAndShifts); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) goto wrap; ppReply->GuiAppShifts = pIn->GuiAppShifts; ZeroStruct(ppReply->GuiAppShifts.Shifts); CRealConsole::CorrectGuiChildRect(pIn->GuiAppShifts.nStyle, pIn->GuiAppShifts.nStyleEx, ppReply->GuiAppShifts.Shifts, pIn->GuiAppShifts.szExeName); lbRc = TRUE; break; } // CECMD_GUICLIENTSHIFT case CECMD_GUIMACRO: { // Допустимо, если GuiMacro пытаются выполнить извне CVConGuard VCon; CVConGroup::GetActiveVCon(&VCon); DWORD nFarPluginPID = VCon->RCon()->GetFarPID(true); LPWSTR pszResult = ConEmuMacro::ExecuteMacro(pIn->GuiMacro.sMacro, VCon->RCon(), (nFarPluginPID==pIn->hdr.nSrcPID), &pIn->GuiMacro); int nLen = pszResult ? _tcslen(pszResult) : 0; pcbReplySize = sizeof(CESERVER_REQ_HDR)+sizeof(CESERVER_REQ_GUIMACRO)+nLen*sizeof(wchar_t); if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) { SafeFree(pszResult); goto wrap; } if (pszResult) { lstrcpy(ppReply->GuiMacro.sMacro, pszResult); ppReply->GuiMacro.nSucceeded = 1; free(pszResult); } else { ppReply->GuiMacro.sMacro[0] = 0; ppReply->GuiMacro.nSucceeded = 0; } lbRc = TRUE; break; } // CECMD_GUIMACRO case CECMD_CMDSTARTSTOP: { CRealServer* pRSrv = NULL; CVConGuard VCon; DWORD nSrvPID = pIn->hdr.nSrcPID; DWORD nMonitorTID = (pIn->DataSize() >= sizeof(pIn->StartStop)) ? pIn->StartStop.dwAID : 0; if (CVConGroup::GetVConBySrvPID(nSrvPID, nMonitorTID, &VCon)) pRSrv = &VCon->RCon()->m_RConServer; if (pRSrv) { CESERVER_REQ* pOut = pRSrv->cmdStartStop(pInst, pIn, pIn->DataSize()); if (pOut) { DWORD nDataSize = pOut->DataSize(); pcbReplySize = pOut->hdr.cbSize; if (ExecuteNewCmd(ppReply, pcbMaxReplySize, pOut->hdr.nCmd, pcbReplySize)) { if (nDataSize > 0) { memmove(ppReply->Data, pOut->Data, nDataSize); } lbRc = TRUE; } ExecuteFreeResult(pOut); } } break; } // CECMD_CMDSTARTSTOP //case CECMD_DEFTERMSTARTED: //{ // if (gpConEmu->mp_DefTrm) // gpConEmu->mp_DefTrm->OnDefTermStarted(pIn); // pcbReplySize = sizeof(CESERVER_REQ_HDR); // if (!ExecuteNewCmd(ppReply, pcbMaxReplySize, pIn->hdr.nCmd, pcbReplySize)) // goto wrap; // lbRc = TRUE; // break; //} // CECMD_DEFTERMSTARTED default: _ASSERTE(FALSE && "Command was not handled in CGuiServer::GuiServerCommand"); } //// Освободить память //if (pIn && (LPVOID)pIn != (LPVOID)&in) //{ // free(pIn); pIn = NULL; //} wrap: return lbRc; }
int main(int argc, char** argv) { HeapInitialize(); for (int i=0; i<argc; i++) { if (strcmp(argv[i], "-verbose")==0 || strcmp(argv[i], "--verbose")==0) gbVerifyVerbose = true; } // Tests { Verify_Step("ls1(`Test`)"); CEStr ls1(L"Test"); Verify0((ls1.ms_Val && 0==wcscmp(ls1.ms_Val,L"Test")),"ls1==`Test`"); Verify_Step("ls12 = ls1.Detach()"); /* Store ptr for Verify test result */ LPCWSTR pszPtr = ls1.ms_Val; CEStr ls2 = ls1.Detach(); Verify2((ls2.ms_Val && !ls1.ms_Val && ls2.ms_Val==pszPtr),"ls2.ms_Val{x%p}==pszPtr{x%p}",ls2.ms_Val,pszPtr); } { Verify_Step("ls3 = `Test3`"); CEStr ls3 = L"Test3"; Verify0((ls3.ms_Val && 0==wcscmp(ls3.ms_Val,L"Test3")),"ls3==`Test3`"); Verify_Step("ls4 = (LPCWSTR)ls3.ms_Val"); CEStr ls4 = static_cast<LPCWSTR>(ls3.ms_Val); Verify2((ls4.ms_Val && ls4.ms_Val != ls3.ms_Val),"ls4.ms_Val{x%p}!=ls3.ms_Val{x%p}",ls4.ms_Val,ls3.ms_Val); Verify_Step("ls5 = lstrdup(ls3)"); CEStr ls5 = lstrdup(ls3); Verify0((ls5.ms_Val && 0==wcscmp(ls5.ms_Val,L"Test3")),"ls5==`Test3`"); Verify_Step("ls6(lstrdup(ls3))"); CEStr ls6(lstrdup(ls3)); Verify0((ls6.ms_Val && 0==wcscmp(ls6.ms_Val,L"Test3")),"ls6==`Test3`"); } { Verify_Step("-new_console parser tests"); LPCWSTR pszTest = L"-new_console:a \\\"-new_console:c\\\" `-new_console:d:C:\\` -cur_console:b"; LPCWSTR pszCmp = L"\\\"-new_console:c\\\" `-new_console:d:C:\\`"; RConStartArgs arg; arg.pszSpecialCmd = lstrdup(pszTest); arg.ProcessNewConArg(); int iCmp = lstrcmp(arg.pszSpecialCmd, pszCmp); Verify0((iCmp==0),"arg.pszSpecialCmd==\\\"-new_console:c\\\" `-new_console:d:C:\\`"); Verify_Step("RConStartArgs::RunArgTests()"); RConStartArgs::RunArgTests(); Verify0(!gbVerifyFailed,"RConStartArgs tests passed"); } { Verify_Step("msprintf tests"); wchar_t szBuffer[200]; msprintf(szBuffer, countof(szBuffer), L"%u %03u %03u %i %x %02X %02X %04x %08X", 123, 98, 4567, -234, 0x12AB, 0x0A, 0xABC, 0x01A0, 0x0765ABCD); const wchar_t szStd[] = L"123 098 4567 -234 12ab 0A ABC 01a0 0765ABCD"; int iCmp = lstrcmp(szBuffer, szStd); WVerify2((iCmp==0),L"`%s` (msprintf[W])\n `%s` (standard)", szBuffer, szStd); char szBufA[200]; msprintf(szBufA, countof(szBufA), "%u %i %x %02X %02X %04x %08X", 123, -234, 0x12AB, 0x0A, 0xABC, 0x01A0, 0x0765ABCD); const char szStdA[] = "123 -234 12ab 0A ABC 01a0 0765ABCD"; iCmp = lstrcmpA(szBufA, szStdA); Verify2((iCmp==0),"`%s` (msprintf[A])\n `%s` (standard)", szBufA, szStdA); } if (gbVerifyFailed) Verify_MsgFail("Some tests failed!"); else Verify_MsgOk("All done"); return gbVerifyFailed ? 99 : 0; }
int main(int argc, char** argv) { HeapInitialize(); for (int i=0; i<argc; i++) { if (strcmp(argv[i], "-verbose")==0 || strcmp(argv[i], "--verbose")==0) gbVerifyVerbose = true; } // Tests { Verify_Step("ls1(`Test`)"); CEStr ls1(L"Test"); Verify0((ls1.ms_Val && 0==wcscmp(ls1.ms_Val,L"Test")),"ls1==`Test`"); Verify_Step("ls12 = ls1.Detach()"); /* Store ptr for Verify test result */ LPCWSTR pszPtr = ls1.ms_Val; CEStr ls2 = ls1.Detach(); Verify2((ls2.ms_Val && !ls1.ms_Val && ls2.ms_Val==pszPtr),"ls2.ms_Val{x%p}==pszPtr{x%p}",ls2.ms_Val,pszPtr); } { Verify_Step("ls3 = `Test3`"); CEStr ls3 = L"Test3"; Verify0((ls3.ms_Val && 0==wcscmp(ls3.ms_Val,L"Test3")),"ls3==`Test3`"); Verify_Step("ls4 = (LPCWSTR)ls3.ms_Val"); CEStr ls4 = static_cast<LPCWSTR>(ls3.ms_Val); Verify2((ls4.ms_Val && ls4.ms_Val != ls3.ms_Val),"ls4.ms_Val{x%p}!=ls3.ms_Val{x%p}",ls4.ms_Val,ls3.ms_Val); Verify_Step("ls5 = lstrdup(ls3)"); CEStr ls5 = lstrdup(ls3); Verify0((ls5.ms_Val && 0==wcscmp(ls5.ms_Val,L"Test3")),"ls5==`Test3`"); Verify_Step("ls6(lstrdup(ls3))"); CEStr ls6(lstrdup(ls3)); Verify0((ls6.ms_Val && 0==wcscmp(ls6.ms_Val,L"Test3")),"ls6==`Test3`"); } { Verify_Step("NextArg and Switch comparison"); LPCWSTR pszCmd = L"conemu.exe /c/dir -run -inside=0x800 /cmdlist \"-inside=\\eCD /d %1\" -bad|switch "; CEStr ls; Verify0((0==NextArg(&pszCmd,ls)),"NextArg conemu.exe"); Verify0((!ls.IsPossibleSwitch()),"!IsPossibleSwitch()"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg /c/dir"); Verify0((!ls.IsPossibleSwitch()),"!IsPossibleSwitch()"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg -run"); Verify0((ls.OneOfSwitches(L"/cmd",L"/run")),"OneOfSwitches(/cmd,/run)"); Verify0((!ls.OneOfSwitches(L"/cmd",L"/cmdlist")),"!OneOfSwitches(/cmd,/cmdlist)"); Verify0((ls.IsSwitch(L"-run")),"IsSwitch(-run)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg -inside=0x800"); Verify0((ls.IsSwitch(L"-inside=")),"IsSwitch(-inside=)"); Verify0((ls.OneOfSwitches(L"-inside",L"-inside=")),"OneOfSwitches(-inside,-inside=)"); Verify0((!ls.IsSwitch(L"-inside")),"!IsSwitch(-inside)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg /cmdlist"); Verify0((ls.IsSwitch(L"-cmdlist")),"IsSwitch(-cmdlist)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg \"-inside=\\eCD /d %1\""); Verify0((ls.IsSwitch(L"-inside:")),"IsSwitch(-inside=)"); Verify0((0==NextArg(&pszCmd,ls)),"NextArg -bad|switch"); Verify0((ls.Compare(L"-bad|switch")==0),"Compare(-bad|switch)"); Verify0((!ls.IsPossibleSwitch()),"!IsPossibleSwitch"); } { Verify_Step("-new_console parser tests"); LPCWSTR pszTest = L"-new_console:a \\\"-new_console:c\\\" `-new_console:d:C:\\` -cur_console:b"; LPCWSTR pszCmp = L"\\\"-new_console:c\\\" `-new_console:d:C:\\`"; RConStartArgs arg; arg.pszSpecialCmd = lstrdup(pszTest); arg.ProcessNewConArg(); int iCmp = lstrcmp(arg.pszSpecialCmd, pszCmp); Verify0((iCmp==0),"arg.pszSpecialCmd==\\\"-new_console:c\\\" `-new_console:d:C:\\`"); Verify_Step("RConStartArgs::RunArgTests()"); RConStartArgs::RunArgTests(); Verify0(!gbVerifyFailed,"RConStartArgs tests passed"); } { Verify_Step("msprintf tests"); wchar_t szBuffer[200]; msprintf(szBuffer, countof(szBuffer), L"%u %03u %03u %i %x %02X %02X %04x %08X", 123, 98, 4567, -234, 0x12AB, 0x0A, 0xABC, 0x01A0, 0x0765ABCD); const wchar_t szStd[] = L"123 098 4567 -234 12ab 0A ABC 01a0 0765ABCD"; int iCmp = lstrcmp(szBuffer, szStd); WVerify2((iCmp==0),L"`%s` (msprintf[W])\n `%s` (standard)", szBuffer, szStd); char szBufA[200]; msprintf(szBufA, countof(szBufA), "%u %i %x %02X %02X %04x %08X", 123, -234, 0x12AB, 0x0A, 0xABC, 0x01A0, 0x0765ABCD); const char szStdA[] = "123 -234 12ab 0A ABC 01a0 0765ABCD"; iCmp = lstrcmpA(szBufA, szStdA); Verify2((iCmp==0),"`%s` (msprintf[A])\n `%s` (standard)", szBufA, szStdA); } if (gbVerifyFailed) Verify_MsgFail("Some tests failed!"); else Verify_MsgOk("All done"); return gbVerifyFailed ? 99 : 0; }