Exemple #1
0
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);
	}
}
Exemple #2
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;
	}
}
Exemple #3
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;
}
Exemple #6
0
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;
}
Exemple #7
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;
}
Exemple #8
0
//// Эта функция пайп не закрывает!
//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;
}
Exemple #9
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("-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;
}
Exemple #10
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;
}