Beispiel #1
0
bool IsExecutable(LPCWSTR aszFilePathName, wchar_t** rsExpandedVars /*= NULL*/)
{
#ifndef __GNUC__
#pragma warning( push )
#pragma warning(disable : 6400)
#endif

	wchar_t* pszExpand = NULL;

	for (int i = 0; i <= 1; i++)
	{
		LPCWSTR pwszDot = PointToExt(aszFilePathName);

		if (pwszDot)  // Если указан .exe или .com файл
		{
			if (lstrcmpiW(pwszDot, L".exe")==0 || lstrcmpiW(pwszDot, L".com")==0)
			{
				if (FileExists(aszFilePathName))
					return true;
			}
		}

		if (!i && wcschr(aszFilePathName, L'%'))
		{
			pszExpand = ExpandEnvStr(aszFilePathName);
			if (!pszExpand)
				break;
			aszFilePathName = pszExpand;
		}
	}

	if (rsExpandedVars)
	{
		*rsExpandedVars = pszExpand; pszExpand = NULL;
	}
	else
	{
		SafeFree(pszExpand);
	}

	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;
	}
// Returns ">0" - when changes was made
//  0 - no changes
// -1 - error
// bForceCurConsole==true, если разбор параметров идет 
//   при запуске Tasks из GUI
int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/)
{
	NewConsole = crb_Undefined;

	if (!pszSpecialCmd || !*pszSpecialCmd)
	{
		_ASSERTE(pszSpecialCmd && *pszSpecialCmd);
		return -1;
	}

	int nChanges = 0;

	// 140219 - Остановить обработку, если встретим любой из: ConEmu[.exe], ConEmu64[.exe], ConEmuC[.exe], ConEmuC64[.exe]
	LPCWSTR pszStopAt = NULL;
	{
		LPCWSTR pszTemp = pszSpecialCmd;
		LPCWSTR pszSave = pszSpecialCmd;
		LPCWSTR pszName;
		CmdArg szExe;
		LPCWSTR pszWords[] = {L"ConEmu", L"ConEmu.exe", L"ConEmu64", L"ConEmu64.exe", L"ConEmuC", L"ConEmuC.exe", L"ConEmuC64", L"ConEmuC64.exe", L"ConEmuPortable.exe", L"ConEmuPortable", NULL};
		while (!pszStopAt && (0 == NextArg(&pszTemp, szExe)))
		{
			pszName = PointToName(szExe);
			for (size_t i = 0; pszWords[i]; i++)
			{
				if (lstrcmpi(pszName, pszWords[i]) == 0)
				{
					pszStopAt = pszSave;
					break;
				}
			}
			pszSave = pszTemp;
		}
	}

	#if 0
	// 140219 - Остановить обработку, если встретим любой из: ConEmu[.exe], ConEmu64[.exe], ConEmuC[.exe], ConEmuC64[.exe]
	if (!hShlwapi)
	{
		hShlwapi = LoadLibrary(L"Shlwapi.dll");
		WcsStrI = hShlwapi ? (StrStrI_t)GetProcAddress(hShlwapi, "StrStrIW") : NULL;
	}
	#endif


	// 111211 - здесь может быть передан "-new_console:..."
	LPCWSTR pszNewCon = L"-new_console";
	// 120108 - или "-cur_console:..." для уточнения параметров запуска команд (из фара например)
	LPCWSTR pszCurCon = L"-cur_console";
	int nNewConLen = lstrlen(pszNewCon);
	_ASSERTE(lstrlen(pszCurCon)==nNewConLen);

	wchar_t* pszFrom = pszSpecialCmd;

	bool bStop = false;
	while (!bStop)
	{
		wchar_t* pszSwitch = wcschr(pszFrom, L'-');
		if (!pszSwitch)
			break;
		// Pre-validation
		if (((pszSwitch[1] != L'n') && (pszSwitch[1] != L'c')) // -new_... or -cur_...
			|| (((pszSwitch != /* > */ pszFrom) // If it is started from pszFrom - no need to check previous symbols
				&& (*(pszSwitch-1) != L'"') || (((pszSwitch-2) >= pszFrom) && (*(pszSwitch-2) == L'\\'))) // Found: \"-new...
				&& (*(pszSwitch-1) != L' '))) // Prev symbol was space
		{
			// НЕ наш аргумент
			pszSwitch = wcschr(pszSwitch+1, L' ');
			if (!pszSwitch)
				break;
			pszFrom = pszSwitch;
			continue;
		}

		wchar_t* pszFindNew = NULL;
		wchar_t* pszFind = NULL;
		wchar_t szTest[12]; lstrcpyn(szTest, pszSwitch+1, countof(szTest));

		if (lstrcmp(szTest, L"new_console") == 0)
			pszFindNew = pszFind = pszSwitch;
		else if (lstrcmp(szTest, L"cur_console") == 0)
			pszFind = pszSwitch;
		else
		{
			// НЕ наш аргумент
			pszSwitch = wcschr(pszSwitch+1, L' ');
			if (!pszSwitch)
				break;
			pszFrom = pszSwitch;
			continue;
		}

		if (!pszFind)
			break;
		if (pszStopAt && (pszFind >= pszStopAt))
			break;

		// Проверка валидности
		_ASSERTE(pszFind >= pszSpecialCmd);
		if ((pszFind[nNewConLen] != L' ') && (pszFind[nNewConLen] != L':')
			&& (pszFind[nNewConLen] != L'"') && (pszFind[nNewConLen] != 0))
		{
			// НЕ наш аргумент
			pszFrom = pszFind+nNewConLen;
		}
		else
		{
			if (pszFindNew)
				NewConsole = crb_On;

			// -- не будем пока, мешает. например, при запуске задач
			//// По умолчанию, принудительно включить "Press Enter or Esc to close console"
			//if (!bForceCurConsole)
			//	eConfirmation = eConfAlways;

			bool lbQuot = (*(pszFind-1) == L'"');
			bool lbWasQuot = lbQuot;
			const wchar_t* pszEnd = pszFind+nNewConLen;
			//wchar_t szNewConArg[MAX_PATH+1];
			if (lbQuot)
				pszFind--;

			if (*pszEnd == L'"')
			{
				pszEnd++;
			}
			else if (*pszEnd != L':')
			{
				// Конец
				_ASSERTE(*pszEnd == L' ' || *pszEnd == 0);
			}
			else
			{
				if (*pszEnd == L':')
				{
					pszEnd++;
				}
				else
				{
					_ASSERTE(*pszEnd == L':');
				}

				// Найти конец аргумента
				const wchar_t* pszArgEnd = pszEnd;
				bool lbLocalQuot = false;
				while (*pszArgEnd)
				{
					switch (*pszArgEnd)
					{
					case L'^':
						pszArgEnd++; // Skip control char, goto escaped char
						break;
					case L'"':
						if (*(pszArgEnd+1) == L'"')
						{
							pszArgEnd += 2; // Skip qoubled qouble quote
							continue;
						}
						if (!lbQuot)
						{
							if (!lbLocalQuot && (*(pszArgEnd-1) == L':'))
							{
								lbLocalQuot = true;
								pszArgEnd++;
								continue;
							}
							if (lbLocalQuot)
							{
								if (*(pszArgEnd+1) != L':')
									goto EndFound;
								lbLocalQuot = false;
								pszArgEnd += 2;
								continue;
							}
						}
						goto EndFound;
					case L' ':
						if (!lbQuot && !lbLocalQuot)
							goto EndFound;
						break;
					case 0:
						goto EndFound;
					}

					pszArgEnd++;
				}
				EndFound:

				// Обработка доп.параметров -new_console:xxx
				bool lbReady = false;
				while (!lbReady && *pszEnd)
				{
					_ASSERTE(pszEnd <= pszArgEnd);
					wchar_t cOpt = *(pszEnd++);

					switch (cOpt)
					{
					//case L'-':
					//	bStop = true; // следующие "-new_console" - не трогать!
					//	break;
					case L'"':
						_ASSERTE(pszEnd > pszArgEnd);
						lbReady = true;
						break;
					case L' ':
					case 0:
						lbReady = true;
						break;

					case L':':
						// Just skip ':'. Delimiter between switches: -new_console:c:b:a
						// Revert stored value to lbQuot. We need to "cut" last double quote in the first two cases
						// cmd -cur_console:d:"C:\users":t:"My title" "-cur_console:C:C:\cmd.ico" -cur_console:P:"<PowerShell>":a /k ver
						lbWasQuot = lbQuot;
						break;

					case L'b':
						// b - background, не активировать таб
						BackgroundTab = crb_On; ForegroungTab = crb_Off;
						break;
					case L'f':
						// f - foreground, активировать таб (аналог ">" в Tasks)
						ForegroungTab = crb_On; BackgroundTab = crb_Off;
						break;

					case L'z':
						// z - don't use "Default terminal" feature
						NoDefaultTerm = crb_On;
						break;

					case L'a':
						// a - RunAs shell verb (as admin on Vista+, login/password in WinXP-)
						RunAsAdministrator = crb_On;
						break;

					case L'r':
						// r - run as restricted user
						RunAsRestricted = crb_On;
						break;

					case L'o':
						// o - disable "Long output" for next command (Far Manager)
						LongOutputDisable = crb_On;
						break;

					case L'w':
						// e - enable "Overwrite" mode in console prompt
						OverwriteMode = crb_On;
						break;

					case L'p':
						if (isDigit(*pszEnd))
						{
							switch (*(pszEnd++))
							{
								case L'0':
									nPTY = 0; // don't change
									break;
								case L'1':
									nPTY = 1; // enable PTY mode
									break;
								case L'2':
									nPTY = 2; // disable PTY mode (switch to plain $CONIN, $CONOUT, $CONERR)
									break;
								default:
									nPTY = 1;
							}
						}
						else
						{
							nPTY = 1; // enable PTY mode
						}
						break;

					case L'i':
						// i - don't inject ConEmuHk into the starting application
						InjectsDisable = crb_On;
						break;

					case L'N':
						// N - Force new ConEmu window with Default terminal
						ForceNewWindow = crb_On;
						break;

					case L'h':
						// "h0" - отключить буфер, "h9999" - включить буфер в 9999 строк
						{
							BufHeight = crb_On;
							if (isDigit(*pszEnd))
							{
								wchar_t* pszDigits = NULL;
								nBufHeight = wcstoul(pszEnd, &pszDigits, 10);
								if (pszDigits)
									pszEnd = pszDigits;
							}
							else
							{
								nBufHeight = 0;
							}
						} // L'h':
						break;

					case L'n':
						// n - отключить "Press Enter or Esc to close console"
						eConfirmation = eConfNever;
						break;

					case L'c':
						// c - принудительно включить "Press Enter or Esc to close console"
						eConfirmation = eConfAlways;
						break;

					case L'x':
						// x - Force using dosbox for .bat files
						ForceDosBox = crb_On;
						break;

					case L'I':
						// I - tell GuiMacro to execute new command inheriting active process state. This is only usage ATM.
						ForceInherit = crb_On;
						break;

					// "Long" code blocks below: 'd', 'u', 's' and so on (in future)

					case L's':
						// s[<SplitTab>T][<Percents>](H|V)
						// Пример: "s3T30H" - разбить 3-ий таб. будет создан новый Pane справа, шириной 30% от 3-го таба.
						{
							UINT nTab = 0 /*active*/, nValue = /*пополам*/DefaultSplitValue/10;
							bool bDisableSplit = false;
							while (*pszEnd)
							{
								if (isDigit(*pszEnd))
								{
									wchar_t* pszDigits = NULL;
									UINT n = wcstoul(pszEnd, &pszDigits, 10);
									if (!pszDigits)
										break;
									pszEnd = pszDigits;
									if (*pszDigits == L'T')
									{
                                    	nTab = n;
                                	}
                                    else if ((*pszDigits == L'H') || (*pszDigits == L'V'))
                                    {
                                    	nValue = n;
                                    	eSplit = (*pszDigits == L'H') ? eSplitHorz : eSplitVert;
                                    }
                                    else
                                    {
                                    	break;
                                    }
                                    pszEnd++;
								}
								else if (*pszEnd == L'T')
								{
									nTab = 0;
									pszEnd++;
								}
								else if ((*pszEnd == L'H') || (*pszEnd == L'V'))
								{
	                            	nValue = DefaultSplitValue/10;
	                            	eSplit = (*pszEnd == L'H') ? eSplitHorz : eSplitVert;
	                            	pszEnd++;
								}
								else if (*pszEnd == L'N')
								{
									bDisableSplit = true;
									pszEnd++;
									break;
								}
								else
								{
									break;
								}
							}

							if (bDisableSplit)
							{
								eSplit = eSplitNone; nSplitValue = DefaultSplitValue; nSplitPane = 0;
							}
							else
							{
								if (!eSplit)
									eSplit = eSplitHorz;
								// Для удобства, пользователь задает размер НОВОЙ части
								nSplitValue = 1000-max(1,min(nValue*10,999)); // проценты
								_ASSERTE(nSplitValue>=1 && nSplitValue<1000);
								nSplitPane = nTab;
							}
						} // L's'
						break;



					// Following options (except of single 'u') must be placed on the end of "-new_console:..."
					// If one needs more that one option - use several "-new_console:..." switches

					case L'd':
						// d:<StartupDir>. MUST be last option
					case L't':
						// t:<TabName>. MUST be last option
					case L'u':
						// u - ConEmu choose user dialog (may be specified in the middle, if it is without ':' - user or pwd)
						// u:<user> - ConEmu choose user dialog with prefilled user field. MUST be last option
						// u:<user>:<pwd> - specify user/pwd in args. MUST be last option
					case L'C':
						// C:<IconFile>. MUST be last option
					case L'P':
						// P:<Palette>. MUST be last option
					case L'W':
						// W:<Wallpaper>. MUST be last option
						{
							if (cOpt == L'u')
							{
								// Show choose user dialog (may be specified in the middle, if it is without ':' - user or pwd)
								SafeFree(pszUserName);
								SafeFree(pszDomain);
								if (szUserPassword[0]) SecureZeroMemory(szUserPassword, sizeof(szUserPassword));
							}


							if (*pszEnd == L':')
							{
								pszEnd++;
							}
							else
							{
								if (cOpt == L'u')
								{
									ForceUserDialog = crb_On;
									break;
								}
							}

							const wchar_t* pszTab = pszEnd;
							// we need to find end of argument
							pszEnd = pszArgEnd;
							// temp buffer
							wchar_t* lpszTemp = NULL;

							wchar_t** pptr = NULL;
							switch (cOpt)
							{
							case L'd': pptr = &pszStartupDir; break;
							case L't': pptr = &pszRenameTab; break;
							case L'u': pptr = &lpszTemp; break;
							case L'C': pptr = &pszIconFile; break;
							case L'P': pptr = &pszPalette; break;
							case L'W': pptr = &pszWallpaper; break;
							}

							if (pszEnd > pszTab)
							{
								size_t cchLen = pszEnd - pszTab;
								SafeFree(*pptr);
								*pptr = (wchar_t*)malloc((cchLen+1)*sizeof(**pptr));
								if (*pptr)
								{
									// We need to process escape sequences ("^>" -> ">", "^&" -> "&", etc.)
									//wmemmove(*pptr, pszTab, cchLen);
									wchar_t* pD = *pptr;
									const wchar_t* pS = pszTab;

									if (lbQuot)
									{
										lbLocalQuot = false;
									}
									else if (*pS == L'"' && *(pS+1) != L'"')
									{
										// Remember, that last processed switch was local-quoted
										lbWasQuot = true;
										// This item is local quoted. Example: -new_console:t:"My title"
										lbLocalQuot = true;
										pS++;
									}

									// There is enough room allocated
									while (pS < pszEnd)
									{
										if ((*pS == L'^') && ((pS + 1) < pszEnd))
										{
											pS++; // Skip control char, goto escaped char
										}
										else if (*pS == L'"')
										{
											if (((pS + 1) < pszEnd) && (*(pS+1) == L'"'))
											{
												pS++; // Skip qoubled qouble quote
											}
											else if (lbLocalQuot)
											{
												pszEnd = (pS+1);
												_ASSERTE(*pszEnd==L':' || *pszEnd==L' ' || *pszEnd==0);
												break; // End of local quoted argument: -new_console:d:"C:\User\super user":t:"My title"
											}
										}

										*(pD++) = *(pS++);
									}
									// Terminate with '\0'
									_ASSERTE(pD <= ((*pptr)+cchLen));
									*pD = 0;
								}
								// Additional processing
								switch (cOpt)
								{
								case L'd':
									// Например, "%USERPROFILE%"
									// TODO("А надо ли разворачивать их тут? Наверное при запуске под другим юзером некорректно? Хотя... все равно до переменных не доберемся");
									if (wcschr(pszStartupDir, L'%'))
									{
										wchar_t* pszExpand = NULL;
										if (((pszExpand = ExpandEnvStr(pszStartupDir)) != NULL))
										{
											SafeFree(pszStartupDir);
											pszStartupDir = pszExpand;
										}
									}
									break;
								case L'u':
									if (lpszTemp)
									{
										// Split in form:
										// [Domain\]UserName[:Password]
										wchar_t* pszPwd = wcschr(lpszTemp, L':');
										if (pszPwd)
										{
											// Password was specified, dialog prompt is not required
											ForceUserDialog = crb_Off;
											*pszPwd = 0;
											int nPwdLen = lstrlen(pszPwd+1);
											lstrcpyn(szUserPassword, pszPwd+1, countof(szUserPassword));
											if (nPwdLen > 0)
												SecureZeroMemory(pszPwd+1, nPwdLen);
											UseEmptyPassword = (nPwdLen == 0) ? crb_On : crb_Off;
										}
										else
										{
											// Password was NOT specified, dialog prompt IS required
											ForceUserDialog = crb_On;
											UseEmptyPassword = crb_Off;
										}
										wchar_t* pszSlash = wcschr(lpszTemp, L'\\');
										if (pszSlash)
										{
											*pszSlash = 0;
											pszDomain = lstrdup(lpszTemp);
											pszUserName = lstrdup(pszSlash+1);
										}
										else
										{
											pszUserName = lstrdup(lpszTemp);
										}
									}
									break;
								}
							}
							SafeFree(lpszTemp);
						} // L't':
						break;

					}
				}
			}

			if (pszEnd > pszFind)
			{
				// pszEnd должен указывать на конец -new_console[:...] / -cur_console[:...]
				// и включать обрамляющую кавычку, если он окавычен
				if (lbWasQuot)
				{
					if (*pszEnd == L'"' && *(pszEnd-1) != L'"')
						pszEnd++;
				}
				else
				{
					while (*(pszEnd-1) == L'"')
						pszEnd--;
				}

				// Откусить лишние пробелы, которые стоят ПЕРЕД -new_console[:...] / -cur_console[:...]
				while (((pszFind - 1) >= pszSpecialCmd)
					&& (*(pszFind-1) == L' ')
					&& (((pszFind - 1) == pszSpecialCmd) || (*(pszFind-2) == L' ') || (/**pszEnd == L'"' ||*/ *pszEnd == 0 || *pszEnd == L' ')))
				{
					pszFind--;
				}
				// Откусить лишние пробелы ПОСЛЕ -new_console[:...] / -cur_console[:...] если он стоит в НАЧАЛЕ строки!
				if (pszFind == pszSpecialCmd)
				{
					while (*pszEnd == L' ')
						pszEnd++;
				}

				// Здесь нужно подвинуть pszStopAt
				if (pszStopAt)
					pszStopAt -= (pszEnd - pszFind);

				// Удалить из строки запуска обработанный ключ
				wmemmove(pszFind, pszEnd, (lstrlen(pszEnd)+1));
				nChanges++;
			}
			else
			{
				_ASSERTE(pszEnd > pszFind);
				*pszFind = 0;
				nChanges++;
			}
		} // if ((((pszFind == pszFrom) ...
	} // while (!bStop)

	return nChanges;
} // int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/)
Beispiel #4
0
int CIconList::CreateTabIcon(LPCWSTR asIconDescr, bool bAdmin)
{
	if (!asIconDescr || !*asIconDescr)
		return GetTabIcon(bAdmin);

	for (INT_PTR i = 0; i < m_Icons.size(); i++)
	{
		const TabIconCache& icn = m_Icons[i];
		if ((icn.bAdmin!=FALSE) != bAdmin)
			continue;
		if (lstrcmpi(icn.pszIconDescr, asIconDescr) != 0)
			continue;
		// Already was created!
		return icn.nIconIdx;
	}

	wchar_t* pszExpanded = ExpandEnvStr(asIconDescr);

	// Need to be created!
	int iIconIdx = -1;
	HICON hFileIcon = NULL;
	wchar_t szTemp[MAX_PATH];
	LPCWSTR pszLoadFile = pszExpanded ? pszExpanded : asIconDescr;
	LPCWSTR lpszExt = (wchar_t*)PointToExt(pszLoadFile);

	if (!lpszExt)
	{
		LPWSTR pszFile = NULL;
		if (SearchPath(NULL, pszLoadFile, L".exe", countof(szTemp), szTemp, &pszFile))
		{
			pszLoadFile = szTemp;
			lpszExt = (wchar_t*)PointToExt(pszLoadFile);
		}

		if (!lpszExt)
			goto wrap;
	}

	if (lstrcmpi(lpszExt, L".ico") == 0)
	{
		hFileIcon = (HICON)LoadImage(0, pszLoadFile, IMAGE_ICON,
			                            GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_LOADFROMFILE);
    }
    else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0))
    {
		//TODO: May be specified index of an icon in the file
		HICON hIconLarge = NULL;
        ExtractIconEx(pszLoadFile, 0, &hIconLarge, &hFileIcon, 1);
		if (hIconLarge) DestroyIcon(hIconLarge);
    }
	else
	{
		//TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...)
	}

	if (hFileIcon)
	{
		int iIconIdxAdm = -1;
		iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon);

		TabIconCache NewIcon = {lstrdup(asIconDescr), false, iIconIdx};
		m_Icons.push_back(NewIcon);

		HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0);
		if (hAdmList)
		{
			HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT);
			if (hNewIcon)
			{
				iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon);
				DestroyIcon(hNewIcon);

				TabIconCache AdmIcon = {lstrdup(asIconDescr), true, iIconIdxAdm};
				m_Icons.push_back(AdmIcon);

				if (bAdmin && (iIconIdxAdm > 0))
				{
					iIconIdx = iIconIdxAdm;
				}
			}
		}

		//TODO: bAdmin!!!

		DestroyIcon(hFileIcon);
	}

wrap:
	SafeFree(pszExpanded);
	return iIconIdx;
}
Beispiel #5
0
bool GetImageSubsystem(const wchar_t *FileName,DWORD& ImageSubsystem,DWORD& ImageBits/*16/32/64*/,DWORD& FileAttrs)
{
	bool Result = false;
	ImageSubsystem = IMAGE_SUBSYSTEM_UNKNOWN;
	ImageBits = 0;
	FileAttrs = (DWORD)-1;
	wchar_t* pszExpand = NULL;
	// Пытаться в UNC? Хотя сам CreateProcess UNC не поддерживает, так что смысла пока нет
	HANDLE hModuleFile = CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);

	// Переменные окружения
	if ((hModuleFile == INVALID_HANDLE_VALUE) && FileName && wcschr(FileName, L'%'))
	{
		pszExpand = ExpandEnvStr(FileName);
		if (pszExpand)
		{
			hModuleFile = CreateFile(pszExpand,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
			if (hModuleFile != INVALID_HANDLE_VALUE)
			{
				FileName = pszExpand;
			}
		}
	}

#if 0
	// Если не указан путь к файлу - попробовать найти его в %PATH%
	if (hModuleFile != INVALID_HANDLE_VALUE && FileName && wcschr(FileName, L'\\') == NULL && wcschr(FileName, L'.') != NULL)
	{
		DWORD nErrCode = GetLastError();
		if (nErrCode)
		{
			wchar_t szFind[MAX_PATH], *psz;
			DWORD nLen = SearchPath(NULL, FileName, NULL, countof(szFind), szFind, &psz);
			if (nLen && nLen < countof(szFind))
				hModuleFile = CreateFile(szFind,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
		}
	}
#endif

	if (hModuleFile != INVALID_HANDLE_VALUE)
	{
		BY_HANDLE_FILE_INFORMATION bfi = {0};
		IMAGE_DOS_HEADER DOSHeader;
		DWORD ReadSize;

		if (GetFileInformationByHandle(hModuleFile, &bfi))
			FileAttrs = bfi.dwFileAttributes;

		// Это это батник - сразу вернуть IMAGE_SUBSYSTEM_BATCH_FILE
		LPCWSTR pszExt = PointToExt(FileName);
		if (pszExt 
			&& (!lstrcmpi(pszExt, L".cmd")
				|| !lstrcmpiW(pszExt, L".bat")
				|| !lstrcmpiW(pszExt, L".btm") // take command
			))
		{
			CloseHandle(hModuleFile);
			ImageSubsystem = IMAGE_SUBSYSTEM_BATCH_FILE;
			ImageBits = IsWindows64() ? 64 : 32; //-V112
			Result = true;
			goto wrap;
		}

		if (ReadFile(hModuleFile,&DOSHeader,sizeof(DOSHeader),&ReadSize,NULL))
		{
			_ASSERTE(IMAGE_DOS_SIGNATURE==0x5A4D);
			if (DOSHeader.e_magic != IMAGE_DOS_SIGNATURE)
			{
				//const wchar_t *pszExt = wcsrchr(FileName, L'.');

				if (pszExt && lstrcmpiW(pszExt, L".com") == 0)
				{
					ImageSubsystem = IMAGE_SUBSYSTEM_DOS_EXECUTABLE;
					ImageBits = 16;
					Result = true;
				}
			}
			else
			{
				ImageSubsystem = IMAGE_SUBSYSTEM_DOS_EXECUTABLE;
				ImageBits = 16;
				Result = true;

				if (SetFilePointer(hModuleFile,DOSHeader.e_lfanew,NULL,FILE_BEGIN))
				{
					IMAGE_HEADERS PEHeader;

					if (ReadFile(hModuleFile,&PEHeader,sizeof(PEHeader),&ReadSize,NULL))
					{
						_ASSERTE(IMAGE_NT_SIGNATURE==0x00004550);
						if (PEHeader.Signature == IMAGE_NT_SIGNATURE)
						{
							switch(PEHeader.OptionalHeader32.Magic)
							{
								case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
								{
									ImageSubsystem = PEHeader.OptionalHeader32.Subsystem;
									_ASSERTE((ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) || (ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI));
									ImageBits = 32; //-V112
								}
								break;
								case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
								{
									ImageSubsystem = PEHeader.OptionalHeader64.Subsystem;
									_ASSERTE((ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) || (ImageSubsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI));
									ImageBits = 64;
								}
								break;
								/*default:
									{
										// unknown magic
									}*/
							}
						}
						else if ((WORD)PEHeader.Signature == IMAGE_OS2_SIGNATURE)
						{
							ImageBits = 32; //-V112
							/*
							NE,  хмм...  а как определить что оно ГУЕВОЕ?

							Andrzej Novosiolov <*****@*****.**>
							AN> ориентироваться по флагу "Target operating system" NE-заголовка
							AN> (1 байт по смещению 0x36). Если там Windows (значения 2, 4) - подразумеваем
							AN> GUI, если OS/2 и прочая экзотика (остальные значения) - подразумеваем консоль.
							*/
							BYTE ne_exetyp = reinterpret_cast<PIMAGE_OS2_HEADER>(&PEHeader)->ne_exetyp;

							if (ne_exetyp==2||ne_exetyp==4) //-V112
							{
								ImageSubsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
							}
							else
							{
								ImageSubsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
							}
						}

						/*else
						{
							// unknown signature
						}*/
					}

					/*else
					{
						// обломс вышел с чтением следующего заголовка ;-(
					}*/
				}

				/*else
				{
					// видимо улетели куда нить в трубу, т.к. dos_head.e_lfanew указал
					// слишком в неправдоподное место (например это чистой воды DOS-файл)
				}*/
			}

			/*else
			{
				// это не исполняемый файл - у него нету заголовка MZ, например, NLM-модуль
				// TODO: здесь можно разбирать POSIX нотацию, например "/usr/bin/sh"
			}*/
		}

		/*else
		{
			// ошибка чтения
		}*/
		CloseHandle(hModuleFile);
	}

	/*else
	{
		// ошибка открытия
	}*/
wrap:
	SafeFree(pszExpand);
	return Result;
}
Beispiel #6
0
int CIconList::CreateTabIconInt(LPCWSTR asIconDescr, bool bAdmin, LPCWSTR asWorkDir)
{
	wchar_t* pszExpanded = ExpandEnvStr(asIconDescr);

	// Need to be created!
	int iIconIdx = -1;
	HICON hFileIcon = NULL;
	wchar_t szTemp[MAX_PATH];
	LPCWSTR pszLoadFile = pszExpanded ? pszExpanded : asIconDescr;
	LPCWSTR lpszExt = (wchar_t*)PointToExt(pszLoadFile);

	bool bDirChanged = false;
	if (asWorkDir && *asWorkDir)
	{
		// Executable (or icon) file may be not availbale by %PATH%, let "cd" to it...
		bDirChanged = gpConEmu->ChangeWorkDir(asWorkDir);
	}

	if (!lpszExt)
	{
		LPWSTR pszFile = NULL;
		if (SearchPath(NULL, pszLoadFile, L".exe", countof(szTemp), szTemp, &pszFile))
		{
			pszLoadFile = szTemp;
			lpszExt = (wchar_t*)PointToExt(pszLoadFile);
		}

		if (!lpszExt)
			goto wrap;
	}

	if (lstrcmpi(lpszExt, L".ico") == 0)
	{
		hFileIcon = (HICON)LoadImage(0, pszLoadFile, IMAGE_ICON, mn_CxIcon, mn_CyIcon, LR_DEFAULTCOLOR|LR_LOADFROMFILE);
	}
	else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0))
	{
		//TODO: May be specified index of an icon in the file
		HICON hIconLarge = NULL, hIconSmall = NULL;
		ExtractIconEx(pszLoadFile, 0, &hIconLarge, &hIconSmall, 1);
		bool bUseLargeIcon = ((mn_CxIcon > 16) && (hIconLarge != NULL)) || (hIconSmall == NULL);
		HICON hDestroyIcon = bUseLargeIcon ? hIconSmall : hIconLarge;
		if (hDestroyIcon) DestroyIcon(hDestroyIcon);
		hFileIcon = bUseLargeIcon ? hIconLarge : hIconSmall;
	}
	else
	{
		//TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...)
	}

	if (hFileIcon)
	{
		wchar_t szIconInfo[80] = L"", szMergedInfo[80] = L"";
		GetIconInfoStr(hFileIcon, szIconInfo);

		if (gpSetCls->isAdvLogging)
		{
			CEStr lsLog(lstrmerge(L"Icon `", asIconDescr, L"` was loaded: ", szIconInfo));
			gpConEmu->LogString(lsLog);
		}

		int iIconIdxAdm = -1;
		iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon);

		TabIconCache NewIcon = {lstrdup(asIconDescr), iIconIdx, false};
		m_Icons.push_back(NewIcon);

		if (mn_AdminIcon >= 0)
		{
			HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0);
			if (hAdmList)
			{
				HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT);
				if (hNewIcon)
				{
					CEStr lsLog(lstrmerge(L"Admin icon `", asIconDescr, L"` was created: ", GetIconInfoStr(hNewIcon, szMergedInfo)));
					gpConEmu->LogString(lsLog);

					iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon);
					DestroyIcon(hNewIcon);

					TabIconCache AdmIcon = {lstrdup(asIconDescr), iIconIdxAdm, true};
					m_Icons.push_back(AdmIcon);

					if (bAdmin && (iIconIdxAdm > 0))
					{
						iIconIdx = iIconIdxAdm;
					}
				}
				else
				{
					gpConEmu->LogString(L"GetIcon for admin icon was failed");
				}
				ImageList_Destroy(hAdmList);
			}
			else
			{
				gpConEmu->LogString(L"Admin icon merging was failed");
			}
		}

		DestroyIcon(hFileIcon);
	}

wrap:
	if (bDirChanged)
	{
		gpConEmu->ChangeWorkDir(NULL);
	}
	SafeFree(pszExpanded);
	if (gpSetCls->isAdvLogging && (iIconIdx < 0))
	{
		CEStr lsLog(lstrmerge(L"Icon `", asIconDescr, L"` loading was failed"));
		gpConEmu->LogString(lsLog);
	}
	return iIconIdx;
}
Beispiel #7
0
bool FileExistsSearch(LPCWSTR asFilePath, CEStr& rsFound, bool abSetPath/*= true*/, bool abRegSearch /*= true*/)
{
	if (!asFilePath || !*asFilePath)
	{
		_ASSERTEX(asFilePath && *asFilePath);
		return false;
	}

	if (FileExists(asFilePath))
	{
		return true;
	}

	// Развернуть переменные окружения
	if (wcschr(asFilePath, L'%'))
	{
		bool bFound = false;
		wchar_t* pszExpand = ExpandEnvStr(asFilePath);
		if (pszExpand && FileExists(pszExpand))
		{
			// asFilePath will be invalid after .Set
			rsFound.Set(pszExpand);
			bFound = true;
		}
		SafeFree(pszExpand);

		if (bFound)
		{
			return true;
		}
	}

	// Search "Path"
	if (FileSearchInDir(asFilePath, rsFound))
	{
		return true;
	}

	// Только если приложение не нашли "по путям" - пытаемся определить его расположение через [App Paths]
	// В противном случае, в частности, может быть запущен "far" не из папки с ConEmu, а зарегистрированный
	// в реестре, если на машине их несколько установлено.

	#if !defined(CONEMU_MINIMAL)
	_ASSERTE(gfnSearchAppPaths!=NULL);
	#endif

	// В ConEmuHk этот блок не активен, потому что может быть "только" перехват CreateProcess,
	// а о его параметрах должно заботиться вызывающее (текущее) приложение
	if (abRegSearch && gfnSearchAppPaths && !wcschr(asFilePath, L'\\'))
	{
		// Если в asFilePath НЕ указан путь - искать приложение в реестре,
		// и там могут быть указаны доп. параметры (пока только добавка в %PATH%)
		if (gfnSearchAppPaths(asFilePath, rsFound, abSetPath, NULL))
		{
			// Нашли по реестру, возможно обновили %PATH%
			return true;
		}
	}

	return false;
}
Beispiel #8
0
static INT_PTR Fast_OnInitDialog(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
	SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon);
	SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm);

	if (gp_DpiAware)
	{
		gp_DpiAware->Attach(hDlg, NULL, CDynDialog::GetDlgClass(hDlg));
	}

	RECT rect = {};
	if (GetWindowRect(hDlg, &rect))
	{
		CDpiAware::GetCenteredRect(NULL, rect);
		MoveWindowRect(hDlg, rect);
	}

	if (lParam)
	{
		SetWindowText(hDlg, (LPCWSTR)lParam);
	}
	else
	{
		wchar_t szTitle[512];
		wcscpy_c(szTitle, gpConEmu->GetDefaultTitle());
		wcscat_c(szTitle, L" fast configuration");
		SetWindowText(hDlg, szTitle);
	}


	// lbStorageLocation
	SettingsStorage Storage = {}; bool ReadOnly = false;
	gpSet->GetSettingsType(Storage, ReadOnly);

	// Same priority as in CConEmuMain::ConEmuXml (reverse order)
	wchar_t* pszSettingsPlaces[] = {
		lstrdup(L"HKEY_CURRENT_USER\\Software\\ConEmu"),
		ExpandEnvStr(L"%APPDATA%\\ConEmu.xml"),
		ExpandEnvStr(L"%ConEmuBaseDir%\\ConEmu.xml"),
		ExpandEnvStr(L"%ConEmuDir%\\ConEmu.xml"),
		NULL
	};
	// Lets find first allowed item
	int iAllowed = 0;
	if (lstrcmp(Storage.szType, CONEMU_CONFIGTYPE_XML) == 0)
	{
		iAllowed = 1; // XML is used, registry is not allowed
		if (Storage.pszFile)
		{
			if (lstrcmpi(Storage.pszFile, pszSettingsPlaces[1]) == 0) // %APPDATA%
				iAllowed = 1; // Any other xml has greater priority
			else if (lstrcmpi(Storage.pszFile, pszSettingsPlaces[2]) == 0) // %ConEmuBaseDir%
				iAllowed = 2; // Only %ConEmuDir% has greater priority
			else if (lstrcmpi(Storage.pszFile, pszSettingsPlaces[3]) == 0) // %ConEmuDir%
				iAllowed = 3; // Most prioritized
			else
			{
				// Directly specified with "/LoadCfgFile ..."
				SafeFree(pszSettingsPlaces[3]);
				pszSettingsPlaces[3] = lstrdup(Storage.pszFile);
				iAllowed = 3; // Most prioritized
			}
		}
	}
	// Index of the default location (relative to listbox, but not a pszSettingsPlaces)
	// By default - suggest %APPDATA% or, if possible, %ConEmuDir%
	// Win2k does not have 'msxml3.dll'/'msxml3r.dll' libraries
	int iDefault = ((iAllowed == 0) && !IsWin2kEql()) ? (CConEmuUpdate::NeedRunElevation() ? 1 : 3) : 0;

	// Populate lbStorageLocation
	while (pszSettingsPlaces[iAllowed])
	{
		SendDlgItemMessage(hDlg, lbStorageLocation, CB_ADDSTRING, 0, (LPARAM)pszSettingsPlaces[iAllowed]);
		iAllowed++;
	}
	SendDlgItemMessage(hDlg, lbStorageLocation, CB_SETCURSEL, iDefault, 0);

	// Release memory
	for (int i = 0; pszSettingsPlaces[i]; i++)
	{
		SafeFree(pszSettingsPlaces[i]);
	}


	// Tasks
	const CommandTasks* pGrp = NULL;
	for (int nGroup = 0; (pGrp = gpSet->CmdTaskGet(nGroup)) != NULL; nGroup++)
	{
		SendDlgItemMessage(hDlg, lbStartupShellFast, CB_ADDSTRING, 0, (LPARAM)pGrp->pszName);
	}
	// Show startup task or shell command line
	LPCWSTR pszStartup = (gpSet->nStartType == 2) ? gpSet->psStartTasksName : (gpSet->nStartType == 0) ? gpSet->psStartSingleApp : NULL;
	if (pszStartup && *pszStartup)
		CSetDlgLists::SelectStringExact(hDlg, lbStartupShellFast, pszStartup);


	// Palettes (console color sets)
	const ColorPalette* pPal = NULL;
	for (int nPal = 0; (pPal = gpSet->PaletteGet(nPal)) != NULL; nPal++)
	{
		SendDlgItemMessage(hDlg, lbColorSchemeFast, CB_ADDSTRING, 0, (LPARAM)pPal->pszName);
	}
	// Show active (default) palette
	gp_DefaultPalette = gpSet->PaletteFindCurrent(true);
	if (gp_DefaultPalette)
	{
		CSetDlgLists::SelectStringExact(hDlg, lbColorSchemeFast, gp_DefaultPalette->pszName);
	}
	else
	{
		_ASSERTE(FALSE && "Current paletted was not defined?");
	}
	// Show its colors in box
	HWND hChild = GetDlgItem(hDlg, stPalettePreviewFast);
	if (hChild)
		gpfn_DefaultColorBoxProc = (WNDPROC)SetWindowLongPtr(hChild, GWLP_WNDPROC, (LONG_PTR)Fast_ColorBoxProc);


	// Single instance
	CheckDlgButton(hDlg, cbSingleInstance, gpSetCls->IsSingleInstanceArg());


	// Quake style and show/hide key
	CheckDlgButton(hDlg, cbQuakeFast, gpSet->isQuakeStyle ? BST_CHECKED : BST_UNCHECKED);
	const ConEmuHotKey* pHK = NULL;
	if (gpSet->GetHotkeyById(vkMinimizeRestore, &pHK) && pHK)
	{
		wchar_t szKey[128] = L"";
		SetDlgItemText(hDlg, tQuakeKeyFast, pHK->GetHotkeyName(szKey));
		ghk_MinMaxKey.SetVkMod(pHK->GetVkMod());
	}


	// Keyhooks required for Win+Number, Win+Arrows, etc.
	CheckDlgButton(hDlg, cbUseKeyboardHooksFast, gpSet->isKeyboardHooks(true));



	// Debug purposes only. ConEmu.exe switch "/nokeyhooks"
	#ifdef _DEBUG
	EnableWindow(GetDlgItem(hDlg, cbUseKeyboardHooksFast), !gpConEmu->DisableKeybHooks);
	#endif

	// Injects
	CheckDlgButton(hDlg, cbInjectConEmuHkFast, gpSet->isUseInjects);

	// Autoupdates
	if (!gpConEmu->isUpdateAllowed())
	{
		EnableWindow(GetDlgItem(hDlg, cbEnableAutoUpdateFast), FALSE);
		EnableWindow(GetDlgItem(hDlg, rbAutoUpdateStableFast), FALSE);
		EnableWindow(GetDlgItem(hDlg, rbAutoUpdatePreviewFast), FALSE);
		EnableWindow(GetDlgItem(hDlg, rbAutoUpdateDeveloperFast), FALSE);
		EnableWindow(GetDlgItem(hDlg, stEnableAutoUpdateFast), FALSE);
	}
	else
	{
		if (gpSet->UpdSet.isUpdateUseBuilds != 0)
			CheckDlgButton(hDlg, cbEnableAutoUpdateFast, gpSet->UpdSet.isUpdateCheckOnStartup|gpSet->UpdSet.isUpdateCheckHourly);
		CheckRadioButton(hDlg, rbAutoUpdateStableFast, rbAutoUpdateDeveloperFast,
			(gpSet->UpdSet.isUpdateUseBuilds == 1) ? rbAutoUpdateStableFast :
			(gpSet->UpdSet.isUpdateUseBuilds == 3) ? rbAutoUpdatePreviewFast : rbAutoUpdateDeveloperFast);
	}

	// Vista - ConIme bugs
	if (!bCheckIme)
	{
		ShowWindow(GetDlgItem(hDlg, gbDisableConImeFast), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, cbDisableConImeFast), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, stDisableConImeFast1), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, stDisableConImeFast2), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, stDisableConImeFast3), SW_HIDE);
		RECT rcGroup, rcBtn, rcWnd;
		if (GetWindowRect(GetDlgItem(hDlg, gbDisableConImeFast), &rcGroup))
		{
			int nShift = (rcGroup.bottom-rcGroup.top);

			HWND h = GetDlgItem(hDlg, IDOK);
			GetWindowRect(h, &rcBtn); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtn, 2);
			SetWindowPos(h, NULL, rcBtn.left, rcBtn.top - nShift, 0,0, SWP_NOSIZE|SWP_NOZORDER);

			h = GetDlgItem(hDlg, IDCANCEL);
			GetWindowRect(h, &rcBtn); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtn, 2);
			SetWindowPos(h, NULL, rcBtn.left, rcBtn.top - nShift, 0,0, SWP_NOSIZE|SWP_NOZORDER);

			h = GetDlgItem(hDlg, stHomePage);
			GetWindowRect(h, &rcBtn); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtn, 2);
			SetWindowPos(h, NULL, rcBtn.left, rcBtn.top - nShift, 0,0, SWP_NOSIZE|SWP_NOZORDER);
			SetWindowText(h, gsHomePage);

			GetWindowRect(hDlg, &rcWnd);
			MoveWindow(hDlg, rcWnd.left, rcWnd.top+(nShift>>1), rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top-nShift, FALSE);
		}
void CommandTasks::ParseGuiArgs(RConStartArgs* pArgs) const
{
	if (!pArgs)
	{
		_ASSERTE(pArgs!=NULL);
		return;
	}

	LPCWSTR pszArgs = pszGuiArgs, pszOk = pszGuiArgs;
	CmdArg szArg;
	while (0 == NextArg(&pszArgs, szArg))
	{
		if (szArg.ms_Arg[0] == L'-')
			szArg.ms_Arg[0] = L'/';

		if (lstrcmpi(szArg, L"/dir") == 0)
		{
			if (0 != NextArg(&pszArgs, szArg))
				break;
			if (*szArg)
			{
				wchar_t* pszExpand = NULL;

				// Например, "%USERPROFILE%"
				if (wcschr(szArg, L'%'))
				{
					pszExpand = ExpandEnvStr(szArg);
				}

				SafeFree(pArgs->pszStartupDir);
				pArgs->pszStartupDir = pszExpand ? pszExpand : lstrdup(szArg);
			}
		}
		else if (lstrcmpi(szArg, L"/icon") == 0)
		{
			if (0 != NextArg(&pszArgs, szArg))
				break;
			if (*szArg)
			{
				wchar_t* pszExpand = NULL;

				// Например, "%USERPROFILE%"
				if (wcschr(szArg, L'%'))
				{
					pszExpand = ExpandEnvStr(szArg);
				}

				SafeFree(pArgs->pszIconFile);
				pArgs->pszIconFile = pszExpand ? pszExpand : lstrdup(szArg);
			}
		}
		else if (lstrcmpi(szArg, L"/single") == 0)
		{
			// Used in the other parts of code
		}
		else if (lstrcmpi(szArg, L"/nosingle") == 0)
		{
			// Force to run in new ConEmu window
			pArgs->aRecreate = cra_CreateWindow;
		}
		else if (lstrcmpi(szArg, L"/quake") == 0)
		{
			// Turn on quake mode in starting console?
			// Disallowed if current window is already in Quake mode.
			if (!gpSet->isQuakeStyle)
				lstrmerge(&pArgs->pszAddGuiArg, L"/quake ");
		}
		else if (lstrcmpi(szArg, L"/noquake") == 0)
		{
			// Disable quake in starting console
			lstrmerge(&pArgs->pszAddGuiArg, L"/noquake ");
		}
		else
		{
			break;
		}

		pszOk = pszArgs;
	}
	// Errors notification
	if (pszOk && *pszOk)
	{
		wchar_t* pszErr = lstrmerge(L"Unsupported task parameters\r\nTask name: ", pszName, L"\r\nParameters: ", pszOk);
		MsgBox(pszErr, MB_ICONSTOP);
		SafeFree(pszErr);
	}
}
Beispiel #10
0
// Returns true, if application was found in registry:
// [HKCU|HKLM]\Software\Microsoft\Windows\CurrentVersion\App Paths
// Also, function may change local process %PATH% variable
bool SearchAppPaths(LPCWSTR asFilePath, CmdArg& rsFound, bool abSetPath, CmdArg* rpsPathRestore /*= NULL*/)
{
	if (rpsPathRestore)
		rpsPathRestore->Empty();

	if (!asFilePath || !*asFilePath)
		return false;

	LPCWSTR pszSearchFile = PointToName(asFilePath);
	LPCWSTR pszExt = PointToExt(pszSearchFile);

	// Lets try find it in "App Paths"
	// "HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\"
	// "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\"
	LPCWSTR pszRoot = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
	HKEY hk; LONG lRc;
	CmdArg lsName; lsName.Attach(lstrmerge(pszRoot, pszSearchFile, pszExt ? NULL : L".exe"));
	// Seems like 32-bit and 64-bit registry branches are the same now, but just in case - will check both
	DWORD nWOW[2] = {WIN3264TEST(KEY_WOW64_32KEY,KEY_WOW64_64KEY), WIN3264TEST(KEY_WOW64_64KEY,KEY_WOW64_32KEY)};
	for (int i = 0; i < 3; i++)
	{
		bool bFound = false;
		DWORD nFlags = ((i && IsWindows64()) ? nWOW[i-1] : 0);
		if ((i == 2) && !nFlags)
			break; // This is 32-bit OS
		lRc = RegOpenKeyEx(i ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, lsName, 0, KEY_READ|nFlags, &hk);
		if (lRc != 0) continue;
		wchar_t szVal[MAX_PATH+1] = L"";
		DWORD nType, nSize = sizeof(szVal)-sizeof(szVal[0]);
		lRc = RegQueryValueEx(hk, NULL, NULL, &nType, (LPBYTE)szVal, &nSize);
		if (lRc == 0)
		{
			wchar_t *pszCheck = NULL;
			if (nType == REG_SZ)
			{
				pszCheck = szVal;
			}
			else if (nType == REG_EXPAND_SZ)
			{
				pszCheck = ExpandEnvStr(szVal);
			}
			// May be quoted
			if (pszCheck)
			{
				LPCWSTR pszPath = Unquote(pszCheck, true);
				if (FileExists(pszPath))
				{
					// asFilePath will be invalid after .Set
					rsFound.Set(pszPath);
					bFound = true;

					if (pszCheck != szVal)
						free(pszCheck);

					// The program may require additional "%PATH%". So, if allowed...
					if (abSetPath)
					{
						nSize = 0;
						lRc = RegQueryValueEx(hk, L"PATH", NULL, &nType, NULL, &nSize);
						if (lRc == 0 && nSize)
						{
							wchar_t* pszCurPath = GetEnvVar(L"PATH");
							wchar_t* pszAddPath = (wchar_t*)calloc(nSize+4,1);
							wchar_t* pszNewPath = NULL;
							if (pszAddPath)
							{
								lRc = RegQueryValueEx(hk, L"PATH", NULL, &nType, (LPBYTE)pszAddPath, &nSize);
								if (lRc == 0 && *pszAddPath)
								{
									// Если в "%PATH%" этого нет (в начале) - принудительно добавить
									int iCurLen = pszCurPath ? lstrlen(pszCurPath) : 0;
									int iAddLen = lstrlen(pszAddPath);
									bool bNeedAdd = true;
									if ((iCurLen >= iAddLen) && (pszCurPath[iAddLen] == L';' || pszCurPath[iAddLen] == 0))
									{
										wchar_t ch = pszCurPath[iAddLen]; pszCurPath[iAddLen] = 0;
										if (lstrcmpi(pszCurPath, pszAddPath) == 0)
											bNeedAdd = false;
										pszCurPath[iAddLen] = ch;
									}
									// Если пути еще нет
									if (bNeedAdd)
									{
										if (rpsPathRestore)
										{
											rpsPathRestore->SavePathVar(pszCurPath);
										}
										pszNewPath = lstrmerge(pszAddPath, L";", pszCurPath);
										if (pszNewPath)
										{
											SetEnvironmentVariable(L"PATH", pszNewPath);
										}
										else
										{
											_ASSERTE(pszNewPath!=NULL && "Allocation failed?");
										}
									}
								}
							}
							SafeFree(pszAddPath);
							SafeFree(pszCurPath);
							SafeFree(pszNewPath);
						}
					}
				}
			}
		}
		RegCloseKey(hk);

		if (bFound)
			return true;
	}

	return false;
}
Beispiel #11
0
static INT_PTR CALLBACK CheckOptionsFastProc(HWND hDlg, UINT messg, WPARAM wParam, LPARAM lParam)
{
	switch (messg)
	{
	case WM_SETHOTKEY:
		gnWndSetHotkey = wParam;
		break;

	case WM_INITDIALOG:
		{
			SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hClassIcon);
			SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hClassIconSm);

			if (gp_DpiAware)
			{
				gp_DpiAware->Attach(hDlg, NULL);
			}

			RECT rect = {};
			if (GetWindowRect(hDlg, &rect))
			{
				CDpiAware::GetCenteredRect(NULL, rect);
				MoveWindowRect(hDlg, rect);
			}

			LRESULT lbRc = FALSE;
			if (lParam)
			{
				SetWindowText(hDlg, (LPCWSTR)lParam);
			}
			else
			{
				wchar_t szTitle[512];
				wcscpy_c(szTitle, gpConEmu->GetDefaultTitle());
				wcscat_c(szTitle, L" fast configuration");
				SetWindowText(hDlg, szTitle);
			}


			// lbStorageLocation
			SettingsStorage Storage = {}; bool ReadOnly = false;
			gpSet->GetSettingsType(Storage, ReadOnly);
			wchar_t* pszSettingsPlaces[] = {
				lstrdup(L"HKEY_CURRENT_USER\\Software\\ConEmu"),
				ExpandEnvStr(L"%APPDATA%\\ConEmu.xml"),
				ExpandEnvStr(L"%ConEmuBaseDir%\\ConEmu.xml"),
				ExpandEnvStr(L"%ConEmuDir%\\ConEmu.xml"),
				NULL
			};
			int iAllowed = 0;
			if (lstrcmp(Storage.szType, CONEMU_CONFIGTYPE_XML) == 0)
			{
				iAllowed = 1; // Реестр уже низя
				if (Storage.pszFile)
				{
					if (lstrcmpi(Storage.pszFile, pszSettingsPlaces[1]) == 0)
						iAllowed = 1; // OK, перебить может любой другой xml
					else if (lstrcmpi(Storage.pszFile, pszSettingsPlaces[2]) == 0)
						iAllowed = 2; // "Перебить" может только %APPDATA%
					else if (lstrcmpi(Storage.pszFile, pszSettingsPlaces[3]) == 0)
						iAllowed = 3; // Приоритетнее настроек нет
					else
					{
						// Этот xml мог быть указан в "/LoadCfgFile ..."
						SafeFree(pszSettingsPlaces[3]);
						pszSettingsPlaces[3] = lstrdup(Storage.pszFile);
						iAllowed = 3; // Приоритетнее настроек нет
					}
				}
			}
			while (pszSettingsPlaces[iAllowed])
			{
				SendDlgItemMessage(hDlg, lbStorageLocation, CB_ADDSTRING, 0, (LPARAM)pszSettingsPlaces[iAllowed]);
				iAllowed++;
			}
			SendDlgItemMessage(hDlg, lbStorageLocation, CB_SETCURSEL, 0, 0);
			for (int i = 0; pszSettingsPlaces[i]; i++)
			{
				SafeFree(pszSettingsPlaces[i]);
			}


			// continue
			CheckDlgButton(hDlg, cbSingleInstance, gpSetCls->IsSingleInstanceArg());

			CheckDlgButton(hDlg, cbUseKeyboardHooksFast, gpSet->isKeyboardHooks(true));



			// Debug purposes only. ConEmu.exe switch "/nokeyhooks"
			#ifdef _DEBUG
			EnableWindow(GetDlgItem(hDlg, cbUseKeyboardHooksFast), !gpConEmu->DisableKeybHooks);
			#endif

			CheckDlgButton(hDlg, cbInjectConEmuHkFast, gpSet->isUseInjects);

			if (!gpConEmu->isUpdateAllowed())
			{
				EnableWindow(GetDlgItem(hDlg, cbEnableAutoUpdateFast), FALSE);
				EnableWindow(GetDlgItem(hDlg, rbAutoUpdateStableFast), FALSE);
				EnableWindow(GetDlgItem(hDlg, rbAutoUpdatePreviewFast), FALSE);
				EnableWindow(GetDlgItem(hDlg, rbAutoUpdateDeveloperFast), FALSE);
				EnableWindow(GetDlgItem(hDlg, stEnableAutoUpdateFast), FALSE);
			}
			else
			{
				if (gpSet->UpdSet.isUpdateUseBuilds != 0)
					CheckDlgButton(hDlg, cbEnableAutoUpdateFast, gpSet->UpdSet.isUpdateCheckOnStartup|gpSet->UpdSet.isUpdateCheckHourly);
				CheckRadioButton(hDlg, rbAutoUpdateStableFast, rbAutoUpdateDeveloperFast,
					(gpSet->UpdSet.isUpdateUseBuilds == 1) ? rbAutoUpdateStableFast :
					(gpSet->UpdSet.isUpdateUseBuilds == 3) ? rbAutoUpdatePreviewFast : rbAutoUpdateDeveloperFast);
			}

			if (!bCheckIme)
			{
				ShowWindow(GetDlgItem(hDlg, gbDisableConImeFast), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, cbDisableConImeFast), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, stDisableConImeFast1), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, stDisableConImeFast2), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, stDisableConImeFast3), SW_HIDE);
				RECT rcGroup, rcBtn, rcWnd;
				if (GetWindowRect(GetDlgItem(hDlg, gbDisableConImeFast), &rcGroup))
				{
					int nShift = (rcGroup.bottom-rcGroup.top);

					HWND h = GetDlgItem(hDlg, IDOK);
					GetWindowRect(h, &rcBtn); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtn, 2);
					SetWindowPos(h, NULL, rcBtn.left, rcBtn.top - nShift, 0,0, SWP_NOSIZE|SWP_NOZORDER);

					h = GetDlgItem(hDlg, IDCANCEL);
					GetWindowRect(h, &rcBtn); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtn, 2);
					SetWindowPos(h, NULL, rcBtn.left, rcBtn.top - nShift, 0,0, SWP_NOSIZE|SWP_NOZORDER);

					h = GetDlgItem(hDlg, stHomePage);
					GetWindowRect(h, &rcBtn); MapWindowPoints(NULL, hDlg, (LPPOINT)&rcBtn, 2);
					SetWindowPos(h, NULL, rcBtn.left, rcBtn.top - nShift, 0,0, SWP_NOSIZE|SWP_NOZORDER);

					GetWindowRect(hDlg, &rcWnd);
					MoveWindow(hDlg, rcWnd.left, rcWnd.top+(nShift>>1), rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top-nShift, FALSE);
				}
			}

			return lbRc;
		}
Beispiel #12
0
// Returns ">0" - when changes was made
//  0 - no changes
// -1 - error
// bForceCurConsole==true, если разбор параметров идет 
//   при запуске Tasks из GUI
int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/)
{
	bNewConsole = FALSE;

	if (!pszSpecialCmd || !*pszSpecialCmd)
	{
		_ASSERTE(pszSpecialCmd && *pszSpecialCmd);
		return -1;
	}

	int nChanges = 0;
	
	// 120115 - Если первый аргумент - "ConEmu.exe" или "ConEmu64.exe" - не обрабатывать "-cur_console" и "-new_console"
	{
		LPCWSTR pszTemp = pszSpecialCmd;
		CmdArg szExe;
		if (0 == NextArg(&pszTemp, szExe))
		{
			pszTemp = PointToName(szExe);
			if (lstrcmpi(pszTemp, L"ConEmu.exe") == 0
				|| lstrcmpi(pszTemp, L"ConEmu") == 0
				|| lstrcmpi(pszTemp, L"ConEmu64.exe") == 0
				|| lstrcmpi(pszTemp, L"ConEmu64") == 0)
			{
				return 0;
			}
		}
	}
	

	// 111211 - здесь может быть передан "-new_console:..."
	LPCWSTR pszNewCon = L"-new_console";
	// 120108 - или "-cur_console:..." для уточнения параметров запуска команд (из фара например)
	LPCWSTR pszCurCon = L"-cur_console";
	int nNewConLen = lstrlen(pszNewCon);
	_ASSERTE(lstrlen(pszCurCon)==nNewConLen);
	bool bStop = false;

	wchar_t* pszFrom = pszSpecialCmd;

	while (!bStop)
	{
		wchar_t* pszFindNew = wcsstr(pszFrom, pszNewCon);
		wchar_t* pszFind = pszFindNew ? pszFindNew : wcsstr(pszFrom, pszCurCon);
		if (pszFindNew)
			bNewConsole = TRUE;
		else if (!pszFind)
			break;

		// Проверка валидности
		_ASSERTE(pszFind >= pszSpecialCmd);
		if (!(((pszFind == pszFrom) || (*(pszFind-1) == L'"') || (*(pszFind-1) == L' ')) // начало аргумента
			&& (pszFind[nNewConLen] == L' ' || pszFind[nNewConLen] == L':' 
				|| pszFind[nNewConLen] == L'"' || pszFind[nNewConLen] == 0)))
		{
			// НЕ наш аргумент
			pszFrom = pszFind+nNewConLen;
		}
		else
		{
			// -- не будем пока, мешает. например, при запуске задач
			//// По умолчанию, принудительно включить "Press Enter or Esc to close console"
			//if (!bForceCurConsole)
			//	eConfirmation = eConfAlways;
		
			bool lbQuot = (*(pszFind-1) == L'"');
			const wchar_t* pszEnd = pszFind+nNewConLen;
			//wchar_t szNewConArg[MAX_PATH+1];
			if (lbQuot)
				pszFind--;

			if (*pszEnd == L'"')
			{
				pszEnd++;
			}
			else if (*pszEnd != L':')
			{
				// Конец
				_ASSERTE(*pszEnd == L' ' || *pszEnd == 0);
			}
			else
			{
				if (*pszEnd == L':')
				{
					pszEnd++;
				}
				else
				{
					_ASSERTE(*pszEnd == L':');
				}

				// Найти конец аргумента
				const wchar_t* pszArgEnd = pszEnd;
				while (*pszArgEnd)
				{
					switch (*pszArgEnd)
					{
					case L'^':
						pszArgEnd++; // Skip control char, goto escaped char
						break;
					case L'"':
						if (*(pszArgEnd+1) == L'"')
							pszArgEnd++; // Skip qoubled qouble quote
						else
							goto EndFound;
						break;
					case L' ':
						if (!lbQuot)
							goto EndFound;
						break;
					case 0:
						goto EndFound;
					}

					pszArgEnd++;
				}
				EndFound:

				// Обработка доп.параметров -new_console:xxx
				bool lbReady = false;
				while (!lbReady && *pszEnd)
				{
					wchar_t cOpt = *(pszEnd++);
					switch (cOpt)
					{
					//case L'-':
					//	bStop = true; // следующие "-new_console" - не трогать!
					//	break;
					case L'"':
					case L' ':
					case 0:
						lbReady = true;
						break;
						
					case L'b':
						// b - background, не активировать таб
						bBackgroundTab = TRUE; bForegroungTab = FALSE;
						break;
					case L'f':
						// f - foreground, активировать таб (аналог ">" в Tasks)
						bForegroungTab = TRUE; bBackgroundTab = FALSE;
						break;

					case L'z':
						// z - don't use "Default terminal" feature
						bNoDefaultTerm = TRUE;
						break;
						
					case L'a':
						// a - RunAs shell verb (as admin on Vista+, login/password in WinXP-)
						bRunAsAdministrator = TRUE;
						break;
						
					case L'r':
						// r - run as restricted user
						bRunAsRestricted = TRUE;
						break;
						
					case L'o':
						// o - disable "Long output" for next command (Far Manager)
						bLongOutputDisable = TRUE;
						break;

					case L'w':
						// e - enable "Overwrite" mode in console prompt
						bOverwriteMode = TRUE;
						break;

					case L'p':
						if (isDigit(*pszEnd))
						{
							switch (*(pszEnd++))
							{
								case L'0':
									nPTY = 0; // don't change
									break;
								case L'1':
									nPTY = 1; // enable PTY mode
									break;
								case L'2':
									nPTY = 2; // disable PTY mode (switch to plain $CONIN, $CONOUT, $CONERR)
									break;
								default:
									nPTY = 1;
							}
						}
						else
						{
							nPTY = 1; // enable PTY mode
						}
						break;

					case L'i':
						// i - don't inject ConEmuHk into the starting application
						bInjectsDisable = TRUE;
						break;

					case L'h':
						// "h0" - отключить буфер, "h9999" - включить буфер в 9999 строк
						{
							bBufHeight = TRUE;
							if (isDigit(*pszEnd))
							{
								wchar_t* pszDigits = NULL;
								nBufHeight = wcstoul(pszEnd, &pszDigits, 10);
								if (pszDigits)
									pszEnd = pszDigits;
							}
							else
							{
								nBufHeight = 0;
							}
						} // L'h':
						break;
						
					case L'n':
						// n - отключить "Press Enter or Esc to close console"
						eConfirmation = eConfNever;
						break;
						
					case L'c':
						// c - принудительно включить "Press Enter or Esc to close console"
						eConfirmation = eConfAlways;
						break;
						
					case L'x':
						// x - Force using dosbox for .bat files
						bForceDosBox = TRUE;
						break;

					case L'I':
						// I - tell GuiMacro to execute new command inheriting active process state. This is only usage ATM.
						bForceInherit = TRUE;
						break;
						
					// "Long" code blocks below: 'd', 'u', 's' and so on (in future)

					case L's':
						// s[<SplitTab>T][<Percents>](H|V)
						// Пример: "s3T30H" - разбить 3-ий таб. будет создан новый Pane справа, шириной 30% от 3-го таба.
						{
							UINT nTab = 0 /*active*/, nValue = /*пополам*/DefaultSplitValue/10;
							bool bDisableSplit = false;
							while (*pszEnd)
							{
								if (isDigit(*pszEnd))
								{
									wchar_t* pszDigits = NULL;
									UINT n = wcstoul(pszEnd, &pszDigits, 10);
									if (!pszDigits)
										break;
									pszEnd = pszDigits;
									if (*pszDigits == L'T')
									{
                                    	nTab = n;
                                	}
                                    else if ((*pszDigits == L'H') || (*pszDigits == L'V'))
                                    {
                                    	nValue = n;
                                    	eSplit = (*pszDigits == L'H') ? eSplitHorz : eSplitVert;
                                    }
                                    else
                                    {
                                    	break;
                                    }
                                    pszEnd++;
								}
								else if (*pszEnd == L'T')
								{
									nTab = 0;
									pszEnd++;
								}
								else if ((*pszEnd == L'H') || (*pszEnd == L'V'))
								{
	                            	nValue = DefaultSplitValue/10;
	                            	eSplit = (*pszEnd == L'H') ? eSplitHorz : eSplitVert;
	                            	pszEnd++;
								}
								else if (*pszEnd == L'N')
								{
									bDisableSplit = true;
									pszEnd++;
									break;
								}
								else
								{
									break;
								}
							}

							if (bDisableSplit)
							{
								eSplit = eSplitNone; nSplitValue = DefaultSplitValue; nSplitPane = 0;
							}
							else
							{
								if (!eSplit)
									eSplit = eSplitHorz;
								// Для удобства, пользователь задает размер НОВОЙ части
								nSplitValue = 1000-max(1,min(nValue*10,999)); // проценты
								_ASSERTE(nSplitValue>=1 && nSplitValue<1000);
								nSplitPane = nTab;
							}
						} // L's'
						break;



					// Following options (except of single 'u') must be placed on the end of "-new_console:..."
					// If one needs more that one option - use several "-new_console:..." switches

					case L'd':
						// d:<StartupDir>. MUST be last option
					case L't':
						// t:<TabName>. MUST be last option
					case L'u':
						// u - ConEmu choose user dialog (may be specified in the middle, if it is without ':' - user or pwd)
						// u:<user> - ConEmu choose user dialog with prefilled user field. MUST be last option
						// u:<user>:<pwd> - specify user/pwd in args. MUST be last option
					case L'C':
						// C:<IconFile>. MUST be last option
					case L'P':
						// P:<Palette>. MUST be last option
					case L'W':
						// W:<Wallpaper>. MUST be last option
						{
							if (cOpt == L'u')
							{
								// Show choose user dialog (may be specified in the middle, if it is without ':' - user or pwd)
								SafeFree(pszUserName);
								SafeFree(pszDomain);
								if (szUserPassword[0]) SecureZeroMemory(szUserPassword, sizeof(szUserPassword));
							}


							if (*pszEnd == L':')
							{
								pszEnd++;
							}
							else
							{
								if (cOpt == L'u')
								{
									bForceUserDialog = TRUE;
									break;
								}
							}

							const wchar_t* pszTab = pszEnd;
							// we need to find end of argument
							pszEnd = pszArgEnd;
							// temp buffer
							wchar_t* lpszTemp = NULL;

							if (pszEnd > pszTab)
							{
								wchar_t** pptr = NULL;
								switch (cOpt)
								{
								case L'd': pptr = &pszStartupDir; break;
								case L't': pptr = &pszRenameTab; break;
								case L'u': pptr = &lpszTemp; break;
								case L'C': pptr = &pszIconFile; break;
								case L'P': pptr = &pszPalette; break;
								case L'W': pptr = &pszWallpaper; break;
								}
								size_t cchLen = pszEnd - pszTab;
								SafeFree(*pptr);
								*pptr = (wchar_t*)malloc((cchLen+1)*sizeof(**pptr));
								if (*pptr)
								{
									// We need to process escape sequences ("^>" -> ">", "^&" -> "&", etc.)
									//wmemmove(*pptr, pszTab, cchLen);
									wchar_t* pD = *pptr;
									const wchar_t* pS = pszTab;
									// There is enough room allocated
									while (pS < pszEnd)
									{
										if ((*pS == L'^') && ((pS + 1) < pszEnd))
											pS++; // Skip control char, goto escaped char
										else if ((*pS == L'"') && ((pS + 1) < pszEnd) && (*(pS+1) == L'"'))
											pS++; // Skip qoubled qouble quote

										*(pD++) = *(pS++);
									}
									// Terminate with '\0'
									_ASSERTE(pD <= ((*pptr)+cchLen));
									*pD = 0;
								}
								// Additional processing
								switch (cOpt)
								{
								case L'd':
									// Например, "%USERPROFILE%"
									// TODO("А надо ли разворачивать их тут? Наверное при запуске под другим юзером некорректно? Хотя... все равно до переменных не доберемся");
									if (wcschr(pszStartupDir, L'%'))
									{
										wchar_t* pszExpand = NULL;
										if (((pszExpand = ExpandEnvStr(pszStartupDir)) != NULL))
										{
											SafeFree(pszStartupDir);
											pszStartupDir = pszExpand;
										}
									}
									break;
								case L'u':
									if (lpszTemp)
									{
										// Split in form:
										// [Domain\]UserName[:Password]
										wchar_t* pszPwd = wcschr(lpszTemp, L':');
										if (pszPwd)
										{
											// Password was specified, dialog prompt is not required
											bForceUserDialog = FALSE;
											*pszPwd = 0;
											int nPwdLen = lstrlen(pszPwd+1);
											lstrcpyn(szUserPassword, pszPwd+1, countof(szUserPassword));
											if (nPwdLen > 0)
												SecureZeroMemory(pszPwd+1, nPwdLen);
											bUseEmptyPassword = (nPwdLen == 0);
										}
										else
										{
											// Password was NOT specified, dialog prompt IS required
											bForceUserDialog = TRUE;
											bUseEmptyPassword = FALSE;
										}
										wchar_t* pszSlash = wcschr(lpszTemp, L'\\');
										if (pszSlash)
										{
											*pszSlash = 0;
											pszDomain = lstrdup(lpszTemp);
											pszUserName = lstrdup(pszSlash+1);
										}
										else
										{
											pszUserName = lstrdup(lpszTemp);
										}
									}
									break;
								}
							}
							SafeFree(lpszTemp);
						} // L't':
						break;
						
					}
				}
			}

			if (pszEnd > pszFind)
			{
				// pszEnd должен указывать на конец -new_console[:...] / -cur_console[:...]
				// и включать обрамляющую кавычку, если он окавычен
				if (lbQuot)
				{
					if (*pszEnd == L'"' && *(pszEnd-1) != L'"')
						pszEnd++;
				}
				else
				{
					while (*(pszEnd-1) == L'"')
						pszEnd--;
				}

				// Откусить лишние пробелы, которые стоят ПЕРЕД -new_console[:...] / -cur_console[:...]
				while (((pszFind - 1) > pszSpecialCmd)
					&& (*(pszFind-1) == L' ')
					&& ((*(pszFind-2) == L' ') || (/**pszEnd == L'"' ||*/ *pszEnd == 0 || *pszEnd == L' ')))
				{
					pszFind--;
				}

				wmemmove(pszFind, pszEnd, (lstrlen(pszEnd)+1));
				nChanges++;
			}
			else
			{
				_ASSERTE(pszEnd > pszFind);
				*pszFind = 0;
				nChanges++;
			}
		} // if ((((pszFind == pszFrom) ...
	} // while (!bStop)

	return nChanges;
} // int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/)
Beispiel #13
0
//------------------------------------------------------------------------
///| Parsing the command line |///////////////////////////////////////////
//------------------------------------------------------------------------
// Returns:
//   true  - continue normal startup
//   false - exit process with iResult code
bool CConEmuStart::ParseCommandLine(LPCWSTR pszCmdLine, int& iResult)
{
	bool bRc = false;
	iResult = 100;

	_ASSERTE(pszCmdLine!=NULL);
	opt.cmdLine.Set(pszCmdLine ? pszCmdLine : L"");

	// pszCmdLine *may* or *may not* start with our executable or full path to our executable
	LPCWSTR pszTemp = opt.cmdLine;
	LPCWSTR cmdLineRest = SkipNonPrintable(opt.cmdLine);
	LPCWSTR pszName, pszArgStart;
	LPCWSTR psUnknown = NULL;
	CEStr   szArg, szNext;
	CEStr   szExeName, szExeNameOnly;

	// Set %ConEmuArgs% env var
	// It may be usefull if we need to restart ConEmu
	// from batch/script with the same arguments (selfupdate etc.)
	LPCWSTR pszCopyToEnvStart = NULL;

	// Have to get our exectuable name and name without extension
	szExeName.Set(PointToName(gpConEmu->ms_ConEmuExe));
	szExeNameOnly.Set(szExeName);
	wchar_t* pszDot = (wchar_t*)PointToExt(szExeNameOnly.ms_Val);
	_ASSERTE(pszDot);
	if (pszDot) *pszDot = 0;


	// Check the first argument in the command line (most probably it will be our executable path/name)
	if (NextArg(&pszTemp, szArg) != 0)
	{
		_ASSERTE(FALSE && "GetCommandLine() is empty");
		// Treat as empty command line, allow to start
		bRc = true; iResult = 0;
		goto wrap;
	}
	pszName = PointToName(szArg);
	if ((lstrcmpi(pszName, szExeName) == 0)
		|| (lstrcmpi(pszName, szExeNameOnly) == 0))
	{
		// OK, our executable was specified properly in the command line
		_ASSERTE(*pszTemp != L' ');
		cmdLineRest = SkipNonPrintable(pszTemp);
	}


	// Must be empty at the moment
	_ASSERTE(opt.runCommand.IsEmpty());

	// Does the command line contain our switches?
	// Or we need to append all switches to starting shell?
	if (cmdLineRest && *cmdLineRest)
	{
		pszTemp = cmdLineRest;
		if (NextArg(&pszTemp, szArg) == 0)
		{
			if ((*szArg.ms_Val != L'/')
				&& (*szArg.ms_Val != L'-')
				/*&& !wcschr(szArg.ms_Val, L'/')*/
				)
			{
				// Save it for further use
				opt.runCommand.Set(cmdLineRest);
				// And do not process it (no switches at all)
				cmdLineRest = NULL;
				opt.params = -1;
			}
		}
	}


	// Let parse the reset
	szArg.Empty();
	szNext.Empty();

	// Processing loop begin
	if (cmdLineRest && *cmdLineRest)
	{
		pszCopyToEnvStart = cmdLineRest;
		opt.cfgSwitches.Set(pszCopyToEnvStart);

		while (NextArg(&cmdLineRest, szArg, &pszArgStart) == 0)
		{
			bool lbNotFound = false;

			// ':' removed from checks because otherwise it will not warn
			// on invalid usage of "-new_console:a" for example
			if (szArg.ms_Val[0] == L'-' && szArg.ms_Val[1] && !wcspbrk(szArg.ms_Val+1, L"\\//|.&<>^"))
			{
				// Seems this is to be the "switch" too
				// Use both notations ('-' and '/')
				*szArg.ms_Val = L'/';
			}

			LPCWSTR curCommand = szArg.ms_Val;

			#define NeedNextArg() \
				if (NextArg(&cmdLineRest, szNext) != 0) { iResult = 101; goto wrap; } \
				curCommand = szNext.ms_Val;


			if (*curCommand != L'/')
			{
				continue; // Try next switch?
			}
			else
			{
				opt.params++;

				if (!klstricmp(curCommand, _T("/autosetup")))
				{
					BOOL lbTurnOn = TRUE;

					NeedNextArg();

					if (*curCommand == _T('0'))
					{
						lbTurnOn = FALSE;
					}
					else
					{
						NeedNextArg();

						DWORD dwAttr = GetFileAttributes(curCommand);

						if (dwAttr == (DWORD)-1 || (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
						{
							iResult = 102;
							goto wrap;
						}
					}

					HKEY hk = NULL; DWORD dw;
					int nSetupRc = 100;

					if (0 != RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Command Processor"),
										   0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, &dw))
					{
						iResult = 103;
						goto wrap;
					}

					if (lbTurnOn)
					{
						size_t cchMax = _tcslen(curCommand);
						LPCWSTR pszArg1 = NULL;
						if (*cmdLineRest)
						{
							// May be ‘/GHWND=NEW’ or smth else
							pszArg1 = cmdLineRest;
							cchMax += _tcslen(pszArg1);
						}
						cchMax += 16; // + quotations, spaces and so on

						wchar_t* pszCmd = (wchar_t*)calloc(cchMax, sizeof(*pszCmd));
						_wsprintf(pszCmd, SKIPLEN(cchMax) L"\"%s\"%s%s%s", curCommand,
							pszArg1 ? L" \"" : L"", pszArg1 ? pszArg1 : L"", pszArg1 ? L"\"" : L"");


						if (0 == RegSetValueEx(hk, _T("AutoRun"), 0, REG_SZ, (LPBYTE)pszCmd,
											(DWORD)sizeof(*pszCmd)*(_tcslen(pszCmd)+1)))
							nSetupRc = 1;

						free(pszCmd);
					}
					else
					{
						if (0==RegDeleteValue(hk, _T("AutoRun")))
							nSetupRc = 1;
					}

					RegCloseKey(hk);
					// сбросить CreateInNewEnvironment для ConMan
					ResetConman();
					iResult = nSetupRc;
					goto wrap;
				}
				else if (!klstricmp(curCommand, _T("/bypass"))
					|| !klstricmp(curCommand, _T("/apparent"))
					|| !klstricmp(curCommand, _T("/system"))
					|| !klstricmp(curCommand, _T("/interactive"))
					|| !klstricmp(curCommand, _T("/demote")))
				{
					// -bypass
					// Этот ключик был придуман для прозрачного запуска консоли
					// в режиме администратора
					// (т.е. чтобы окно UAC нормально всплывало, но не мелькало консольное окно)
					// Но не получилось, пока требуются хэндлы процесса, а их не получается
					// передать в НЕ приподнятый процесс (исходный ConEmu GUI).

					// -apparent
					// Same as -bypass, but run the process as SW_SHOWNORMAL

					// -demote
					// Запуск процесса (ком.строка после "/demote") в режиме простого юзера,
					// когда текущий процесс уже запущен "под админом". "Понизить" текущие
					// привилегии просто так нельзя, поэтому запуск идет через TaskSheduler.

					// -system
					// Non-interactive process, started as System account
					// It's used when starting consoles, our server works fine as non-interactive

					// -interactive
					// Used when ConEmu.exe is started under System account,
					// but we need to give starting process interactive capabilities.

					_ASSERTE(opt.runCommand.IsEmpty());
					pszTemp = cmdLineRest;
					if ((NextArg(&pszTemp, szNext) == 0)
						&& (szNext.ms_Val[0] == L'-' || szNext.ms_Val[0] == L'/')
						&& (lstrcmpi(szNext.ms_Val+1, L"cmd") == 0))
					{
						opt.runCommand.Set(pszTemp);
					}
					else
					{
						opt.runCommand.Set(cmdLineRest);
					}

					if (opt.runCommand.IsEmpty())
					{
						CEStr lsMsg(L"Invalid cmd line. '", curCommand, L"' exists, command line is empty");
						DisplayLastError(lsMsg, -1);
						goto wrap;
					}

					// Information
					#ifdef _DEBUG
					STARTUPINFO siOur = {sizeof(siOur)};
					GetStartupInfo(&siOur);
					#endif

					STARTUPINFO si = {sizeof(si)};
					PROCESS_INFORMATION pi = {};
					si.dwFlags = STARTF_USESHOWWINDOW;
					// Only `-demote` and `-apparent` switches were implemented to start application visible
					// All others are intended to run our server process, without blinking of course
					if ((0 == klstricmp(curCommand, _T("/demote")))
						|| (0 == klstricmp(curCommand, _T("/apparent"))))
						si.wShowWindow = SW_SHOWNORMAL;
					else
						si.wShowWindow = SW_HIDE;

					wchar_t szCurDir[MAX_PATH+1] = L"";
					GetCurrentDirectory(countof(szCurDir), szCurDir);

					BOOL b;
					DWORD nErr = 0;

					// if we were started from TaskScheduler, it would be nice to wait a little
					// to let parent (creator of the scheduler task) know we were started successfully
					bool bFromScheduler = false;

					// Log the command to be started
					{
						CEStr lsLog(
							L"Starting process",
							L": ", curCommand,
							L" `", opt.runCommand.ms_Val, L"`");
						LogString(lsLog);
					}

					if (!klstricmp(curCommand, _T("/demote")))
					{
						b = CreateProcessDemoted(opt.runCommand.ms_Val, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,
							szCurDir, &si, &pi, &nErr);
					}
					else if (!klstricmp(curCommand, _T("/system")))
					{
						b = CreateProcessSystem(opt.runCommand.ms_Val, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,
							szCurDir, &si, &pi);
					}
					else if (!klstricmp(curCommand, _T("/interactive")))
					{
						b = CreateProcessInteractive((DWORD)-1, NULL, opt.runCommand.ms_Val, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL,
							szCurDir, &si, &pi, &nErr);
						bFromScheduler = true;
					}
					else // -bypass, -apparent
					{
						b = CreateProcess(NULL, opt.runCommand.ms_Val, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL,
							NULL, &si, &pi);
						nErr = b ? 0 : GetLastError();
						bFromScheduler = true;
					}

					// Log the result
					{
						CEStr lsLog; wchar_t szExtra[32] = L"";
						if (b)
						{
							if (pi.dwProcessId)
								_wsprintf(szExtra, SKIPCOUNT(szExtra) L", PID=%u", pi.dwProcessId);
							lsLog = lstrmerge(
								L"Process was created successfully",
								szExtra);
						}
						else
						{
							_wsprintf(szExtra, SKIPCOUNT(szExtra) L", ErrorCode=%u", nErr);
							lsLog = lstrmerge(
								L"Failed to start process",
								szExtra);
						}
						LogString(lsLog);
					}

					// If the error was not shown yet
					if (nErr) DisplayLastError(opt.runCommand, nErr);

					// if we were started from TaskScheduler, it would be nice to wait a little
					// to let parent (creator of the scheduler task) know we were started successfully
					if (bFromScheduler)
					{
						LogString(L"Sleeping for 5 seconds");
						Sleep(5*1000);
					}

					// Success?
					if (b)
					{
						iResult = 0;
					}

					// Done, close handles, if they were opened
					SafeCloseHandle(pi.hProcess);
					SafeCloseHandle(pi.hThread);

					goto wrap;
				}
				else if (!klstricmp(curCommand, _T("/multi")))
				{
					gpConEmu->AppendExtraArgs(curCommand);
					gpConEmu->opt.MultiConValue = true;
				}
				else if (!klstricmp(curCommand, _T("/nomulti")))
				{
					gpConEmu->AppendExtraArgs(curCommand);
					gpConEmu->opt.MultiConValue = false;
				}
				else if (!klstricmp(curCommand, _T("/visible")))
				{
					gpConEmu->opt.VisValue = true;
				}
				else if (!klstricmp(curCommand, _T("/ct")) || !klstricmp(curCommand, _T("/cleartype"))
					|| !klstricmp(curCommand, _T("/ct0")) || !klstricmp(curCommand, _T("/ct1")) || !klstricmp(curCommand, _T("/ct2")))
				{
					switch (curCommand[3])
					{
					case L'0':
						gpConEmu->opt.ClearTypeVal = NONANTIALIASED_QUALITY; break;
					case L'1':
						gpConEmu->opt.ClearTypeVal = ANTIALIASED_QUALITY; break;
					default:
						gpConEmu->opt.ClearTypeVal = CLEARTYPE_NATURAL_QUALITY;
					}
				}
				// Interface language
				else if (!klstricmp(curCommand, _T("/lng")))
				{
					NeedNextArg();

					if (!gpConEmu->opt.Language.Exists)
					{
						gpConEmu->opt.Language = curCommand;
						gpConEmu->AppendExtraArgs(L"/lng", curCommand);
					}
				}
				// Optional specific "ConEmu.l10n"
				else if (!klstricmp(curCommand, _T("/lngfile")))
				{
					NeedNextArg();

					if (!gpConEmu->opt.LanguageFile.Exists)
					{
						gpConEmu->opt.LanguageFile = curCommand;
						gpConEmu->AppendExtraArgs(L"/lngfile", curCommand);
					}
				}
				// имя шрифта
				else if (!klstricmp(curCommand, _T("/font")))
				{
					NeedNextArg();

					if (!gpConEmu->opt.FontVal.Exists)
					{
						gpConEmu->opt.FontVal = curCommand;
						gpConEmu->AppendExtraArgs(L"/font", curCommand);
					}
				}
				// Высота шрифта
				else if (!klstricmp(curCommand, _T("/size")))
				{
					NeedNextArg();

					if (!gpConEmu->opt.SizeVal.Exists)
					{
						gpConEmu->opt.SizeVal.SetInt(curCommand);
					}
				}
				// ADD fontname; by Mors
				else if (!klstricmp(curCommand, _T("/fontfile")))
				{
					CESwitch szFile(sw_Str);
					if (!GetCfgParm(cmdLineRest, szFile, MAX_PATH))
					{
						goto wrap;
					}
					gpConEmu->AppendExtraArgs(L"/fontfile", szFile.GetStr());
					gpFontMgr->RegisterFont(szFile.GetStr(), TRUE);
				}
				// Register all fonts from specified directory
				else if (!klstricmp(curCommand, _T("/fontdir")))
				{
					CESwitch szDir(sw_Str);
					if (!GetCfgParm(cmdLineRest, szDir, MAX_PATH))
					{
						goto wrap;
					}
					gpConEmu->AppendExtraArgs(L"/fontdir", szDir.GetStr());
					gpFontMgr->RegisterFontsDir(szDir.GetStr());
				}
				else if (!klstricmp(curCommand, _T("/fs")))
				{
					gpConEmu->opt.WindowModeVal = wmFullScreen;
				}
				else if (!klstricmp(curCommand, _T("/max")))
				{
					gpConEmu->opt.WindowModeVal = wmMaximized;
				}
				else if (!klstricmp(curCommand, _T("/min"))
					|| !klstricmp(curCommand, _T("/mintsa"))
					|| !klstricmp(curCommand, _T("/starttsa")))
				{
					gpConEmu->WindowStartMinimized = true;
					if (klstricmp(curCommand, _T("/min")) != 0)
					{
						gpConEmu->WindowStartTsa = true;
						gpConEmu->WindowStartNoClose = (klstricmp(curCommand, _T("/mintsa")) == 0);
					}
				}
				else if (!klstricmp(curCommand, _T("/tsa")) || !klstricmp(curCommand, _T("/tray")))
				{
					gpConEmu->ForceMinimizeToTray = true;
				}
				else if (!klstricmp(curCommand, _T("/detached")))
				{
					gpConEmu->m_StartDetached = crb_On;
				}
				else if (!klstricmp(curCommand, _T("/here")))
				{
					gpConEmu->mb_ConEmuHere = true;
					gpConEmu->StoreWorkDir();
				}
				else if (!klstricmp(curCommand, _T("/update")))
				{
					gpConEmu->opt.AutoUpdateOnStart = true;
				}
				else if (!klstricmp(curCommand, _T("/noupdate")))
				{
					// This one has more weight than AutoUpdateOnStart
					gpConEmu->opt.DisableAutoUpdate = true;
				}
				else if (!klstricmp(curCommand, _T("/nokeyhook"))
					|| !klstricmp(curCommand, _T("/nokeyhooks"))
					|| !klstricmp(curCommand, _T("/nokeybhook"))
					|| !klstricmp(curCommand, _T("/nokeybhooks")))
				{
					gpConEmu->DisableKeybHooks = true;
				}
				else if (!klstricmp(curCommand, _T("/nocloseconfirm")))
				{
					gpConEmu->DisableCloseConfirm = true;
				}
				else if (!klstricmp(curCommand, _T("/nomacro")))
				{
					gpConEmu->DisableAllMacro = true;
				}
				else if (!klstricmp(curCommand, _T("/nohotkey"))
					|| !klstricmp(curCommand, _T("/nohotkeys")))
				{
					gpConEmu->DisableAllHotkeys = true;
				}
				else if (!klstricmp(curCommand, _T("/nodeftrm"))
					|| !klstricmp(curCommand, _T("/nodefterm")))
				{
					gpConEmu->DisableSetDefTerm = true;
				}
				else if (!klstricmp(curCommand, _T("/noregfont"))
					|| !klstricmp(curCommand, _T("/noregfonts")))
				{
					gpConEmu->DisableRegisterFonts = true;
				}
				else if (!klstricmp(curCommand, _T("/inside"))
					|| !lstrcmpni(curCommand, _T("/inside="), 8))
				{
					bool bRunAsAdmin = isPressed(VK_SHIFT);
					bool bSyncDir = false;
					LPCWSTR pszSyncFmt = NULL;

					gpConEmu->mb_ConEmuHere = true;
					gpConEmu->StoreWorkDir();

					if (curCommand[7] == _T('='))
					{
						bSyncDir = true;
						pszSyncFmt = curCommand+8; // \eCD /d %1 - \e - ESC, \b - BS, \n - ENTER, %1 - "dir", %2 - "bash dir"
					}

					CConEmuInside::InitInside(bRunAsAdmin, bSyncDir, pszSyncFmt, 0, NULL);
				}
				else if (!klstricmp(curCommand, _T("/insidepid")))
				{
					NeedNextArg();

					bool bRunAsAdmin = isPressed(VK_SHIFT);

					wchar_t* pszEnd;
					// Здесь указывается PID, в который нужно внедриться.
					DWORD nInsideParentPID = wcstol(curCommand, &pszEnd, 10);
					if (nInsideParentPID)
					{
						CConEmuInside::InitInside(bRunAsAdmin, false, NULL, nInsideParentPID, NULL);
					}
				}
				else if (!klstricmp(curCommand, _T("/insidewnd")))
				{
					NeedNextArg();

					if (curCommand[0] == L'0' && (curCommand[1] == L'x' || curCommand[1] == L'X'))
						curCommand += 2;
					else if (curCommand[0] == L'x' || curCommand[0] == L'X')
						curCommand ++;

					bool bRunAsAdmin = isPressed(VK_SHIFT);

					wchar_t* pszEnd;
					// Здесь указывается HWND, в котором нужно создаваться.
					HWND hParent = (HWND)(DWORD_PTR)wcstoul(curCommand, &pszEnd, 16);
					if (hParent && IsWindow(hParent))
					{
						CConEmuInside::InitInside(bRunAsAdmin, false, NULL, 0, hParent);
					}
				}
				else if (!klstricmp(curCommand, _T("/icon")))
				{
					NeedNextArg();

					if (!gpConEmu->opt.IconPrm.Exists && *curCommand)
					{
						gpConEmu->opt.IconPrm = true;
						gpConEmu->mps_IconPath = ExpandEnvStr(curCommand);
					}
				}
				else if (!klstricmp(curCommand, _T("/dir")))
				{
					NeedNextArg();

					if (*curCommand)
					{
						// Например, "%USERPROFILE%"
						wchar_t* pszExpand = NULL;
						if (wcschr(curCommand, L'%') && ((pszExpand = ExpandEnvStr(curCommand)) != NULL))
						{
							gpConEmu->StoreWorkDir(pszExpand);
							SafeFree(pszExpand);
						}
						else
						{
							gpConEmu->StoreWorkDir(curCommand);
						}
					}
				}
				else if (!klstricmp(curCommand, _T("/updatejumplist")))
				{
					// Copy current Task list to Win7 Jump list (Taskbar icon)
					gpConEmu->mb_UpdateJumpListOnStartup = true;
				}
				else if (!klstricmp(curCommand, L"/log") || !klstricmp(curCommand, L"/log0")
					|| !klstricmp(curCommand, L"/log1") || !klstricmp(curCommand, L"/log2")
					|| !klstricmp(curCommand, L"/log3") || !klstricmp(curCommand, L"/log4"))
				{
					if (!klstricmp(curCommand, L"/log") || !klstricmp(curCommand, L"/log0"))
						gpConEmu->opt.AdvLogging.SetInt(1);
					else
						gpConEmu->opt.AdvLogging.SetInt((BYTE)(curCommand[4] - L'0')); // 1..4
					// Do create logging service
					DEBUGSTRSTARTUP(L"Creating log file");
					gpConEmu->CreateLog();
				}
				else if (!klstricmp(curCommand, _T("/single")) || !klstricmp(curCommand, _T("/reuse")))
				{
					// "/reuse" switch to be remastered
					gpConEmu->AppendExtraArgs(curCommand);
					gpSetCls->SingleInstanceArg = sgl_Enabled;
				}
				else if (!klstricmp(curCommand, _T("/nosingle")))
				{
					gpConEmu->AppendExtraArgs(curCommand);
					gpSetCls->SingleInstanceArg = sgl_Disabled;
				}
				else if (!klstricmp(curCommand, _T("/DesktopMode")))
				{
					gpConEmu->opt.DesktopMode = true;
				}
				else if (!klstricmp(curCommand, _T("/quake"))
					|| !klstricmp(curCommand, _T("/quakeauto"))
					|| !klstricmp(curCommand, _T("/noquake")))
				{
					if (!klstricmp(curCommand, _T("/quake")))
						gpConEmu->opt.QuakeMode = 1;
					else if (!klstricmp(curCommand, _T("/quakeauto")))
						gpConEmu->opt.QuakeMode = 2;
					else
					{
						gpConEmu->opt.QuakeMode = 0;
						if (gpSetCls->SingleInstanceArg == sgl_Default)
							gpSetCls->SingleInstanceArg = sgl_Disabled;
					}
				}
				else if (!klstricmp(curCommand, _T("/showhide")) || !klstricmp(curCommand, _T("/showhideTSA")))
				{
					gpSetCls->SingleInstanceArg = sgl_Enabled;
					gpSetCls->SingleInstanceShowHide = !klstricmp(curCommand, _T("/showhide"))
						? sih_ShowMinimize : sih_ShowHideTSA;
				}
				else if (!klstricmp(curCommand, _T("/reset"))
					|| !klstricmp(curCommand, _T("/resetdefault"))
					|| !klstricmp(curCommand, _T("/basic")))
				{
					gpConEmu->opt.ResetSettings = true;
					if (!klstricmp(curCommand, _T("/resetdefault")))
					{
						gpSetCls->isFastSetupDisabled = true;
					}
					else if (!klstricmp(curCommand, _T("/basic")))
					{
						gpSetCls->isFastSetupDisabled = true;
						gpSetCls->isResetBasicSettings = true;
					}
				}
				else if (!klstricmp(curCommand, _T("/nocascade"))
					|| !klstricmp(curCommand, _T("/dontcascade")))
				{
					gpConEmu->AppendExtraArgs(curCommand);
					gpSetCls->isDontCascade = true;
				}
				else if (!klstricmp(curCommand, _T("/WndX")) || !klstricmp(curCommand, _T("/WndY"))
					|| !klstricmp(curCommand, _T("/WndW")) || !klstricmp(curCommand, _T("/WndWidth"))
					|| !klstricmp(curCommand, _T("/WndH")) || !klstricmp(curCommand, _T("/WndHeight")))
				{
					TCHAR ch = curCommand[4];
					CharUpperBuff(&ch, 1);

					CESwitch psz(sw_Str); bool bParm = false;
					if (!GetCfgParm(cmdLineRest, bParm, psz, 32))
					{
						goto wrap;
					}
					gpConEmu->opt.SizePosPrm = true;

					// Direct X/Y implies /nocascade
					if (ch == _T('X') || ch == _T('Y'))
					{
						// TODO: isDontCascade must be in our opt struct !!!
						gpSetCls->isDontCascade = true;
					}

					switch (ch)
					{
					case _T('X'): gpConEmu->opt.sWndX.SetStr(psz.Str, sw_Str); break;
					case _T('Y'): gpConEmu->opt.sWndY.SetStr(psz.Str, sw_Str); break;
					case _T('W'): gpConEmu->opt.sWndW.SetStr(psz.Str, sw_Str); break;
					case _T('H'): gpConEmu->opt.sWndH.SetStr(psz.Str, sw_Str); break;
					}
				}
				else if (!klstricmp(curCommand, _T("/Monitor")))
				{
					CESwitch psz(sw_Str); bool bParm = false;
					if (!GetCfgParm(cmdLineRest, bParm, psz, 64))
					{
						goto wrap;
					}

					if ((gpConEmu->opt.Monitor.Mon = MonitorFromParam(psz.Str)) != NULL)
					{
						gpConEmu->opt.Monitor.Exists = true;
						gpConEmu->opt.Monitor.Type = sw_Int;
						gpStartEnv->hStartMon = gpConEmu->opt.Monitor.Mon;
					}
				}
				else if (!klstricmp(curCommand, _T("/Buffer")) || !klstricmp(curCommand, _T("/BufferHeight")))
				{
					NeedNextArg();

					if (!gpConEmu->opt.BufferHeightVal.Exists)
					{
						gpConEmu->opt.BufferHeightVal.SetInt(curCommand);

						if (gpConEmu->opt.BufferHeightVal.GetInt() < 0)
						{
							//setParent = true; -- Maximus5 - нефиг, все ручками
							gpConEmu->opt.BufferHeightVal = -gpConEmu->opt.BufferHeightVal.GetInt();
						}

						if (gpConEmu->opt.BufferHeightVal.GetInt() < LONGOUTPUTHEIGHT_MIN)
							gpConEmu->opt.BufferHeightVal = LONGOUTPUTHEIGHT_MIN;
						else if (gpConEmu->opt.BufferHeightVal.GetInt() > LONGOUTPUTHEIGHT_MAX)
							gpConEmu->opt.BufferHeightVal = LONGOUTPUTHEIGHT_MAX;
					}
				}
				else if (!klstricmp(curCommand, _T("/Config")))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.ConfigVal, 127))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/Palette")))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.PaletteVal, MAX_PATH))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/LoadRegistry")))
				{
					gpConEmu->AppendExtraArgs(curCommand);
					gpConEmu->opt.ForceUseRegistryPrm = true;
				}
				else if (!klstricmp(curCommand, _T("/LoadCfgFile")) || !klstricmp(curCommand, _T("/LoadXmlFile")))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.LoadCfgFile, MAX_PATH, true))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/SaveCfgFile")) || !klstricmp(curCommand, _T("/SaveXmlFile")))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.SaveCfgFile, MAX_PATH, true))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/GuiMacro")))
				{
					// -- выполняется только последний
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.ExecGuiMacro, 0x8000, false))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/UpdateSrcSet")))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.UpdateSrcSet, MAX_PATH*4, false))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/AnsiLog")))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.AnsiLogPath, MAX_PATH-40, true))
					{
						goto wrap;
					}
				}
				else if (!klstricmp(curCommand, _T("/SetDefTerm")))
				{
					gpConEmu->opt.SetUpDefaultTerminal = true;
				}
				else if (!klstricmp(curCommand, _T("/ZoneId")))
				{
					gpConEmu->opt.FixZoneId = true;
				}
				else if (!klstricmp(curCommand, _T("/Exit")))
				{
					gpConEmu->opt.ExitAfterActionPrm = true;
				}
				else if (!klstricmp(curCommand, _T("/QuitOnClose")))
				{
					gpConEmu->mb_ForceQuitOnClose = true;
				}
				else if (!klstricmp(curCommand, _T("/Title")))
				{
					bool bOk = false;
					CESwitch pszTitle(sw_Str);
					if (!GetCfgParm(cmdLineRest, bOk, pszTitle, 127))
					{
						goto wrap;
					}
					gpConEmu->SetTitleTemplate(pszTitle.GetStr());
				}
				else if (!klstricmp(curCommand, _T("/FindBugMode")))
				{
					gpConEmu->mb_FindBugMode = true;
				}
				else if (!klstricmp(curCommand, _T("/debug"))
					|| !klstricmp(curCommand, _T("/debugw"))
					|| !klstricmp(curCommand, _T("/debugi")))
				{
					// These switches were already processed
				}
				else if (!klstricmp(curCommand, _T("/?")) || !klstricmp(curCommand, _T("/h")) || !klstricmp(curCommand, _T("/help")))
				{
					if (gpLng) gpLng->Reload();
					ConEmuAbout::OnInfo_About();
					iResult = -1;
					goto wrap;
				}
				// Final `-cmd ...` or `-cmdlist ...`
				else if (
					!klstricmp(curCommand, _T("/cmd"))
					|| !klstricmp(curCommand, _T("/cmdlist"))
					)
				{
					if (opt.cfgSwitches.ms_Val)
					{
						_ASSERTE(pszArgStart>pszCopyToEnvStart);
						_ASSERTE((INT_PTR)(pszArgStart - pszCopyToEnvStart) <= opt.cfgSwitches.GetLen());
						opt.cfgSwitches.ms_Val[pszArgStart - pszCopyToEnvStart] = 0;
					}

					opt.runCommand.Set(SkipNonPrintable(cmdLineRest));
					opt.isScript = (klstricmp(curCommand, L"/cmdlist") == 0);
					break;
				}
				else
				{
					// Show error on unknown switch
					psUnknown = pszArgStart;
					break;
				}
			} // (*curCommand == L'/')

			// Avoid assertions in NextArg
			szArg.Empty(); szNext.Empty();
		} // while (NextArg(&cmdLineRest, szArg, &pszArgStart) == 0)
	}
	// Processing loop end

	if (psUnknown)
	{
		DEBUGSTRSTARTUP(L"Unknown switch, exiting!");
		if (gpSet->isLogging())
		{
			// For direct logging we do not use lng resources
			CEStr lsLog(L"\r\n", L"Unknown switch specified: ", psUnknown, L"\r\n\r\n");
			gpConEmu->LogString(lsLog, false, false);
		}

		CEStr szNewConWarn;
		LPCWSTR pszTestSwitch =
			(psUnknown[0] == L'-' || psUnknown[0] == L'/')
				? ((psUnknown[1] == L'-' || psUnknown[1] == L'/')
					? (psUnknown+2) : (psUnknown+1))
				: psUnknown;
		if ((lstrcmpni(pszTestSwitch, L"new_console", 11) == 0)
			|| (lstrcmpni(pszTestSwitch, L"cur_console", 11) == 0))
		{
			szNewConWarn = lstrmerge(L"\r\n\r\n",
				CLngRc::getRsrc(lng_UnknownSwitch4/*"Switch -new_console must be specified *after* /cmd or /cmdlist"*/)
				);
		}

		CEStr lsMsg(
			CLngRc::getRsrc(lng_UnknownSwitch1/*"Unknown switch specified:"*/),
			L"\r\n\r\n",
			psUnknown,
			szNewConWarn,
			L"\r\n\r\n",
			CLngRc::getRsrc(lng_UnknownSwitch2/*"Visit website to get thorough switches description:"*/),
			L"\r\n"
			CEGUIARGSPAGE
			L"\r\n\r\n",
			CLngRc::getRsrc(lng_UnknownSwitch3/*"Or run ‘ConEmu.exe -?’ to get the brief."*/)
			);

		MBoxA(lsMsg);
		goto wrap;
	}

	// Set "ConEmuArgs" and "ConEmuArgs2"
	ProcessConEmuArgsVar();

	// Continue normal startup
	bRc = true;
wrap:
	return bRc;
}
Beispiel #14
0
// Returns ">0" - when changes was made
//  0 - no changes
// -1 - error
// bForceCurConsole==true, если разбор параметров идет 
//   при запуске Tasks из GUI
int RConStartArgs::ProcessNewConArg(bool bForceCurConsole /*= false*/)
{
	bNewConsole = FALSE;

	if (!pszSpecialCmd || !*pszSpecialCmd)
	{
		_ASSERTE(pszSpecialCmd && *pszSpecialCmd);
		return -1;
	}

	int nChanges = 0;
	
	// 120115 - Если первый аргумент - "ConEmu.exe" или "ConEmu64.exe" - не обрабатывать "-cur_console" и "-new_console"
	{
		LPCWSTR pszTemp = pszSpecialCmd;
		wchar_t szExe[MAX_PATH+1];
		if (0 == NextArg(&pszTemp, szExe))
		{
			pszTemp = PointToName(szExe);
			if (lstrcmpi(pszTemp, L"ConEmu.exe") == 0
				|| lstrcmpi(pszTemp, L"ConEmu") == 0
				|| lstrcmpi(pszTemp, L"ConEmu64.exe") == 0
				|| lstrcmpi(pszTemp, L"ConEmu64") == 0)
			{
				return 0;
			}
		}
	}
	

	// 111211 - здесь может быть передан "-new_console:..."
	LPCWSTR pszNewCon = L"-new_console";
	// 120108 - или "-cur_console:..." для уточнения параметров запуска команд (из фара например)
	LPCWSTR pszCurCon = L"-cur_console";
	int nNewConLen = lstrlen(pszNewCon);
	_ASSERTE(lstrlen(pszCurCon)==nNewConLen);
	bool bStop = false;

	while (!bStop)
	{
		wchar_t* pszFindNew = wcsstr(pszSpecialCmd, pszNewCon);
		wchar_t* pszFind = pszFindNew ? pszFindNew : wcsstr(pszSpecialCmd, pszCurCon);
		if (pszFindNew)
			bNewConsole = TRUE;
		else if (!pszFind)
			break;

		// Проверка валидности
		_ASSERTE(pszFind >= pszSpecialCmd);
		if (((pszFind == pszSpecialCmd) || (*(pszFind-1) == L'"') || (*(pszFind-1) == L' ')) // начало аргумента
			&& (pszFind[nNewConLen] == L' ' || pszFind[nNewConLen] == L':' 
				|| pszFind[nNewConLen] == L'"' || pszFind[nNewConLen] == 0))
		{
			// -- не будем пока, мешает. например, при запуске задач
			//// По умолчанию, принудительно включить "Press Enter or Esc to close console"
			//if (!bForceCurConsole)
			//	eConfirmation = eConfAlways;
		
			bool lbQuot = (*(pszFind-1) == L'"');
			const wchar_t* pszEnd = pszFind+nNewConLen;
			//wchar_t szNewConArg[MAX_PATH+1];
			if (lbQuot)
				pszFind--;

			if (*pszEnd == L'"')
			{
				pszEnd++;
			}
			else if (*pszEnd != L':')
			{
				// Конец
				_ASSERTE(*pszEnd == L' ' || *pszEnd == 0);
			}
			else
			{
				if (*pszEnd == L':')
				{
					pszEnd++;
				}
				else
				{
					_ASSERTE(*pszEnd == L':');
				}

				// Обработка доп.параметров -new_console:xxx
				bool lbReady = false;
				while (!lbReady && *pszEnd)
				{
					switch (*(pszEnd++))
					{
					//case L'-':
					//	bStop = true; // следующие "-new_console" - не трогать!
					//	break;
					case L'"':
					case L' ':
					case 0:
						lbReady = true;
						break;
						
					case L'b':
						// b - background, не активировать таб
						bBackgroundTab = TRUE;
						break;

					case L'z':
						// z - don't use "Default terminal" feature
						bNoDefaultTerm = TRUE;
						break;
						
					case L'a':
						// a - RunAs shell verb (as admin on Vista+, login/password in WinXP-)
						bRunAsAdministrator = TRUE;
						break;
						
					case L'r':
						// r - run as restricted user
						bRunAsRestricted = TRUE;
						break;
						
					case L'o':
						// o - disable "Long output" for next command (Far Manager)
						bLongOutputDisable = TRUE;
						break;

					case L'w':
						// e - enable "Overwrite" mode in console prompt
						bOverwriteMode = TRUE;
						break;

					case L'p':
						if (isDigit(*pszEnd))
						{
							switch (*(pszEnd++))
							{
								case L'0':
									nPTY = 0; // don't change
									break;
								case L'1':
									nPTY = 1; // enable PTY mode
									break;
								case L'2':
									nPTY = 2; // disable PTY mode (switch to plain $CONIN, $CONOUT, $CONERR)
									break;
								default:
									nPTY = 1;
							}
						}
						else
						{
							nPTY = 1; // enable PTY mode
						}
						break;

					case L'i':
						// i - don't inject ConEmuHk into the starting application
						bInjectsDisable = TRUE;
						break;

					case L'h':
						// "h0" - отключить буфер, "h9999" - включить буфер в 9999 строк
						{
							bBufHeight = TRUE;
							if (isDigit(*pszEnd))
							{
								wchar_t* pszDigits = NULL;
								nBufHeight = wcstoul(pszEnd, &pszDigits, 10);
								if (pszDigits)
									pszEnd = pszDigits;
							}
							else
							{
								nBufHeight = 0;
							}
						} // L'h':
						break;
						
					case L'n':
						// n - отключить "Press Enter or Esc to close console"
						eConfirmation = eConfNever;
						break;
						
					case L'c':
						// c - принудительно включить "Press Enter or Esc to close console"
						eConfirmation = eConfAlways;
						break;
						
					case L'x':
						// x - Force using dosbox for .bat files
						bForceDosBox = TRUE;
						break;
						
					// "Long" code blocks below: 'd', 'u', 's' and so on (in future)
					case L'd':
						// d:<StartupDir>. MUST be last options
						{
							if (*pszEnd == L':')
								pszEnd++;
							const wchar_t* pszDir = pszEnd;
							while ((*pszEnd) && (lbQuot || *pszEnd != L' ') && (*pszEnd != L'"'))
								pszEnd++;
							if (pszEnd > pszDir)
							{
								size_t cchLen = pszEnd - pszDir;
								SafeFree(pszStartupDir);
								pszStartupDir = (wchar_t*)malloc((cchLen+1)*sizeof(*pszStartupDir));
								if (pszStartupDir)
								{
									wmemmove(pszStartupDir, pszDir, cchLen);
									pszStartupDir[cchLen] = 0;
									// Например, "%USERPROFILE%"
									if (wcschr(pszStartupDir, L'%'))
									{
										wchar_t* pszExpand = NULL;
										if (((pszExpand = ExpandEnvStr(pszStartupDir)) != NULL))
										{
											SafeFree(pszStartupDir);
											pszStartupDir = pszExpand;
										}
									}
								}
							}
						} // L'd':
						break;

					case L't':
						// t:<TabName>. MUST be last options
						{
							if (*pszEnd == L':')
								pszEnd++;
							const wchar_t* pszTab = pszEnd;
							while ((*pszEnd) && (lbQuot || *pszEnd != L' ') && (*pszEnd != L'"'))
								pszEnd++;
							if (pszEnd > pszTab)
							{
								size_t cchLen = pszEnd - pszTab;
								SafeFree(pszRenameTab);
								pszRenameTab = (wchar_t*)malloc((cchLen+1)*sizeof(*pszRenameTab));
								if (pszRenameTab)
								{
									wmemmove(pszRenameTab, pszTab, cchLen);
									pszRenameTab[cchLen] = 0;
								}
							}
						} // L't':
						break;

					case L's':
						// s[<SplitTab>T][<Percents>](H|V)
						// Пример: "s3T30H" - разбить 3-ий таб. будет создан новый Pane справа, шириной 30% от 3-го таба.
						{
							UINT nTab = 0 /*active*/, nValue = /*пополам*/DefaultSplitValue/10;
							bool bDisableSplit = false;
							while (*pszEnd)
							{
								if (isDigit(*pszEnd))
								{
									wchar_t* pszDigits = NULL;
									UINT n = wcstoul(pszEnd, &pszDigits, 10);
									if (!pszDigits)
										break;
									pszEnd = pszDigits;
									if (*pszDigits == L'T')
									{
                                    	nTab = n;
                                	}
                                    else if ((*pszDigits == L'H') || (*pszDigits == L'V'))
                                    {
                                    	nValue = n;
                                    	eSplit = (*pszDigits == L'H') ? eSplitHorz : eSplitVert;
                                    }
                                    else
                                    {
                                    	break;
                                    }
                                    pszEnd++;
								}
								else if (*pszEnd == L'T')
								{
									nTab = 0;
									pszEnd++;
								}
								else if ((*pszEnd == L'H') || (*pszEnd == L'V'))
								{
	                            	nValue = DefaultSplitValue/10;
	                            	eSplit = (*pszEnd == L'H') ? eSplitHorz : eSplitVert;
	                            	pszEnd++;
								}
								else if (*pszEnd == L'N')
								{
									bDisableSplit = true;
									pszEnd++;
									break;
								}
								else
								{
									break;
								}
							}

							if (bDisableSplit)
							{
								eSplit = eSplitNone; nSplitValue = DefaultSplitValue; nSplitPane = 0;
							}
							else
							{
								if (!eSplit)
									eSplit = eSplitHorz;
								// Для удобства, пользователь задает размер НОВОЙ части
								nSplitValue = 1000-max(1,min(nValue*10,999)); // проценты
								_ASSERTE(nSplitValue>=1 && nSplitValue<1000);
								nSplitPane = nTab;
							}
						} // L's'
						break;
						
					case L'u':
						{
							// u - ConEmu choose user dialog
							// u:<user>:<pwd> - specify user/pwd in args. MUST be last option
							
							lbReady = true; // последняя опция

							SafeFree(pszUserName);
							SafeFree(pszDomain);
							if (szUserPassword[0]) SecureZeroMemory(szUserPassword, sizeof(szUserPassword));
							
							if (*pszEnd == L':')
							{
								pszEnd++;
								
								wchar_t szUser[MAX_PATH], *p = szUser, *p2 = szUser+countof(szUser)-1;
								while (*pszEnd && (p < p2))
								{
									if ((*pszEnd == 0) || (*pszEnd == L':') || (*pszEnd == L'"'))
									{
										break;
									}
									//else if (*pszEnd == L'"' && *(pszEnd+1) == L'"')
									//{
									//	*(p++) = L'"'; pszEnd += 2;
									//}
									else if (*pszEnd == L'^')
									{
										pszEnd++;
										*(p++) = *(pszEnd++);
									}
									else
									{
										*(p++) = *(pszEnd++);
									}
								}
								*p = 0;

								wchar_t* pszSlash = wcschr(szUser, L'\\');
								if (pszSlash)
								{
									*pszSlash = 0;
									pszDomain = lstrdup(szUser);
									pszUserName = lstrdup(pszSlash+1);
								}
								else
								{
									pszUserName = lstrdup(szUser);
								}
								
								if (*pszEnd == L':')
								{
									pszEnd++;
									//lstrcpyn(szUserPassword, pszPwd, countof(szUserPassword));

									p = szUserPassword; p2 = szUserPassword+countof(szUserPassword)-1;
									while (*pszEnd && (p < p2))
									{
										if ((*pszEnd == 0) || (*pszEnd == L':') || (*pszEnd == L'"'))
										{
											break;
										}
										else if (*pszEnd == L'^')
										{
											pszEnd++;
											*(p++) = *(pszEnd++);
										}
										else
										{
											*(p++) = *(pszEnd++);
										}
									}
									*p = 0;

								}
							}
							else
							{
								bForceUserDialog = TRUE;
							}
						} // L'u'
						break;
					}
				}
			}

			if (pszEnd > pszFind)
			{
				// pszEnd должен указывать на конец -new_console[:...] / -cur_console[:...]
				// и включать обрамляющую кавычку, если он окавычен
				if (lbQuot)
				{
					if (*pszEnd == L'"' && *(pszEnd-1) != L'"')
						pszEnd++;
				}
				else
				{
					while (*(pszEnd-1) == L'"')
						pszEnd--;
				}

				// Откусить лишние пробелы, которые стоят ПЕРЕД -new_console[:...] / -cur_console[:...]
				while (((pszFind - 1) > pszSpecialCmd)
					&& (*(pszFind-1) == L' ')
					&& ((*(pszFind-2) == L' ') || (/**pszEnd == L'"' ||*/ *pszEnd == 0 || *pszEnd == L' ')))
				{
					pszFind--;
				}

				wmemmove(pszFind, pszEnd, (lstrlen(pszEnd)+1));
				nChanges++;
			}
			else
			{
				_ASSERTE(pszEnd > pszFind);
				*pszFind = 0;
				nChanges++;
			}
		}
	}

	return nChanges;
}
Beispiel #15
0
bool CBackgroundInfo::LoadBackgroundFile(bool abShowErrors)
{
	// Пустой путь - значит БЕЗ обоев
	if (!*ms_BgImage)
	{
		return true;
	}

	//_ASSERTE(isMainThread());

	_ASSERTE(isMainThread());
	bool lRes = false;
	BY_HANDLE_FILE_INFORMATION inf = {0};
	BITMAPFILEHEADER* pBkImgData = NULL;

	if (wcspbrk(ms_BgImage, L"%\\.") == NULL)
	{
		// May be "Solid color"
		COLORREF clr = (COLORREF)-1;
		if (GetColorRef(ms_BgImage, &clr))
		{
			pBkImgData = CreateSolidImage(clr, 128, 128);
		}
	}

	if (!pBkImgData)
	{
		wchar_t* exPath = ExpandEnvStr(ms_BgImage);

		if (!exPath || !*exPath)
		{
			if (abShowErrors)
			{
				wchar_t szError[MAX_PATH*2];
				DWORD dwErr = GetLastError();
				_wsprintf(szError, SKIPLEN(countof(szError)) L"Can't expand environment strings:\r\n%s\r\nError code=0x%08X\r\nImage loading failed",
				          ms_BgImage, dwErr);
				MBoxA(szError);
			}

			SafeFree(exPath);
			return false;
		}

		pBkImgData = LoadImageEx(exPath, inf);
		SafeFree(exPath);
	}

	if (pBkImgData)
	{
		ftBgModified = inf.ftLastWriteTime;
		nBgModifiedTick = GetTickCount();
		//NeedBackgroundUpdate();
		//MSectionLock SBG; SBG.Lock(&mcs_BgImgData);
		SafeFree(mp_BgImgData);
		mb_IsBackgroundImageValid = true;
		mp_BgImgData = pBkImgData;
		lRes = true;
	}

	return lRes;
}
// Return true if "SetEnvironmentVariable" was processed
// if (bDoSet==false) - just skip all "set" commands
// Supported commands:
//  set abc=val
//  "set PATH=C:\Program Files;%PATH%"
//  chcp [utf8|ansi|oem|<cp_no>]
//  title "Console init title"
bool ProcessSetEnvCmd(LPCWSTR& asCmdLine, bool bDoSet, CmdArg* rpsTitle /*= NULL*/)
{
	LPCWSTR lsCmdLine = asCmdLine;
	bool bEnvChanged = false;
	CmdArg lsSet, lsAmp;

	// Example: "set PATH=C:\Program Files;%PATH%" & set abc=def & cmd
	while (NextArg(&lsCmdLine, lsSet) == 0)
	{
		bool bTokenOk = false;
		wchar_t* lsNameVal = NULL;

		// It may contains only "set" if was not quoted
		if (lstrcmpi(lsSet, L"set") == 0)
		{
			// Now we shell get in lsSet "abc=def" token
			if ((NextArg(&lsCmdLine, lsSet) == 0) && (wcschr(lsSet, L'=') > lsSet.ms_Arg))
			{
				lsNameVal = lsSet.ms_Arg;
			}
		}
		// Or full "set PATH=C:\Program Files;%PATH%" command (without quotes ATM)
		else if (lstrcmpni(lsSet, L"set ", 4) == 0)
		{
			LPCWSTR psz = SkipNonPrintable(lsSet.ms_Arg+4);
			if (wcschr(psz, L'=') > psz)
			{
				lsNameVal = (wchar_t*)psz;
			}
		}
		// Process "chcp <cp>" too
		else if (lstrcmpi(lsSet, L"chcp") == 0)
		{
			if (NextArg(&lsCmdLine, lsSet) == 0)
			{
				UINT nCP = GetCpFromString(lsSet);

				if (nCP > 0 && nCP <= 0xFFFF)
				{
					bTokenOk = true;
					_ASSERTE(lsNameVal == NULL);
					// Ask to be changed?
					if (bDoSet)
					{
						//Issue 60: BUGBUG: На некоторых системых (Win2k3, WinXP) SetConsoleCP (и иже с ними) просто зависают
						DWORD nTID;
						HANDLE hThread = CreateThread(NULL, 0, OurSetConsoleCPThread, (LPVOID)nCP, 0, &nTID);
						if (hThread)
						{
							DWORD nWait = WaitForSingleObject(hThread, 1000);
							if (nWait == WAIT_TIMEOUT)
							{
								TerminateThread(hThread,100);
							}
							CloseHandle(hThread);
						}
					}
				}
			}
		}
		// Change title without need of cmd.exe
		else if (lstrcmpi(lsSet, L"title") == 0)
		{
			if (NextArg(&lsCmdLine, lsSet) == 0)
			{
				bTokenOk = true;
				_ASSERTE(lsNameVal == NULL);
				// Ask to be changed?
				if (rpsTitle)
					rpsTitle->Set(lsSet);
			}
		}

		// Well, known command was detected. What is next?
		if (lsNameVal || bTokenOk)
		{
			lsAmp.GetPosFrom(lsSet);
			if (NextArg(&lsCmdLine, lsAmp) != 0)
			{
				// End of command? Use may call only "set" without following app? Run simple "cmd" in that case
				_ASSERTE(lsCmdLine!=NULL && *lsCmdLine==0);
				bTokenOk = true; // And process SetEnvironmentVariable
			}
			else
			{
				if (lstrcmp(lsAmp, L"&") == 0)
				{
					// Only simple conveyer is supported!
					bTokenOk = true; // And process SetEnvironmentVariable
				}
				// Update last pointer (debug and asserts purposes)
				lsSet.GetPosFrom(lsAmp);
			}
		}

		if (!bTokenOk)
		{
			break; // Stop processing command line
		}
		else if (lsNameVal)
		{
			// And split name/value
			_ASSERTE(lsNameVal!=NULL);

			wchar_t* pszEq = wcschr(lsNameVal, L'=');
			if (!pszEq)
			{
				_ASSERTE(pszEq!=NULL);
				break;
			}

			if (bDoSet)
			{
				*(pszEq++) = 0;
				// Expand value
				wchar_t* pszExpanded = ExpandEnvStr(pszEq);
				LPCWSTR pszSet = pszExpanded ? pszExpanded : pszEq;
				SetEnvironmentVariable(lsNameVal, (pszSet && *pszSet) ? pszSet : NULL);
				SafeFree(pszExpanded);
			}

			bEnvChanged = true;
		}

		// Remember processed position
		asCmdLine = lsCmdLine;

	} // end of "while (NextArg(&lsCmdLine, lsSet) == 0)"

	// Fin
	if (!asCmdLine || !*asCmdLine)
	{
		static wchar_t szSimple[] = L"cmd";
		asCmdLine = szSimple;
	}

	return bEnvChanged;
}
Beispiel #17
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;
}
Beispiel #18
0
	wchar_t* CreateCommand(LPCWSTR asSource, LPCWSTR asTarget, UINT& iRc)
	{
		wchar_t* pszCommand = NULL;

		if (!szCmdStringFormat || !*szCmdStringFormat)
		{
			wchar_t szConEmuC[MAX_PATH] = L"", *psz;
			wchar_t szOTimeout[20] = L"", szTimeout[20] = L"";

			if (mb_OTimeout)
				_wsprintf(szOTimeout, SKIPCOUNT(szOTimeout) L"%u", mn_OTimeout);
			if (mb_Timeout)
				_wsprintf(szTimeout, SKIPCOUNT(szTimeout) L"%u", mn_Timeout);

			struct _Switches {
				LPCWSTR pszName, pszValue;
			} Switches[] = {
				{L"-login", m_Server.szUser},
				{L"-password", m_Server.szPassword},
				{L"-proxy", m_Proxy.szProxy},
				{L"-proxylogin", m_Proxy.szProxyUser},
				{L"-proxypassword", m_Proxy.szProxyPassword},
				{L"-async", mb_AsyncMode ? L"Y" : L"N"},
				{L"-otimeout", szOTimeout},
				{L"-timeout", szTimeout},
			};

			if (!asSource || !*asSource || !asTarget || !*asTarget)
			{
				iRc = E_INVALIDARG;
				goto wrap;
			}

			if (!GetModuleFileName(ghOurModule, szConEmuC, countof(szConEmuC)) || !(psz = wcsrchr(szConEmuC, L'\\')))
			{
				//ReportMessage(dc_LogCallback, L"GetModuleFileName(ghOurModule) failed, code=%u", at_Uint, GetLastError(), at_None);
				iRc = E_HANDLE;
				goto wrap;
			}
			psz[1] = 0;
			wcscat_c(szConEmuC, WIN3264TEST(L"ConEmuC.exe",L"ConEmuC64.exe"));

			/*
			ConEmuC /download [-login <name> -password <pwd>]
			        [-proxy <address:port> [-proxylogin <name> -proxypassword <pwd>]]
			        [-async Y|N] [-otimeout <ms>] [-timeout <ms>]
			        "full_url_to_file" "local_path_name"
			*/

			if (!(pszCommand = lstrmerge(L"\"", szConEmuC, L"\" -download ")))
			{
				iRc = E_OUTOFMEMORY;
				goto wrap;
			}

			for (INT_PTR i = 0; i < countof(Switches); i++)
			{
				LPCWSTR pszValue = Switches[i].pszValue;
				if (pszValue && *pszValue && !lstrmerge(&pszCommand, Switches[i].pszName, L" \"", pszValue, L"\" "))
				{
					iRc = E_OUTOFMEMORY;
					goto wrap;
				}
			}

			if (!lstrmerge(&pszCommand, asSource, L" \"", asTarget, L"\""))
			{
				iRc = E_OUTOFMEMORY;
				goto wrap;
			}
		}
		else
		{
			// Environment string? Expand it
			wchar_t* pszExp = ExpandEnvStr(szCmdStringFormat);

			// "curl -L %1 -o %2"
			// "wget %1 -O %2"
			LPCWSTR Values[] = {asSource, asTarget};
			pszCommand = ExpandMacroValues((pszExp && *pszExp) ? pszExp : szCmdStringFormat, Values, countof(Values));
			SafeFree(pszExp);

			if (!pszCommand)
			{
				iRc = E_OUTOFMEMORY;
				goto wrap;
			}
		}

	wrap:
		return pszCommand;
	}
Beispiel #19
0
//------------------------------------------------------------------------
///| Parsing the command line |///////////////////////////////////////////
//------------------------------------------------------------------------
// Returns:
//   true  - continue normal startup
//   false - exit process with iResult code
bool CConEmuStart::ParseCommandLine(LPCWSTR pszCmdLine, int& iResult)
{
	bool bRc = false;
	iResult = 100;

	_ASSERTE(pszCmdLine!=NULL);
	opt.cmdLine.Set(pszCmdLine ? pszCmdLine : L"");

	// pszCmdLine *may* or *may not* start with our executable or full path to our executable
	LPCWSTR pszTemp = opt.cmdLine;
	LPCWSTR cmdLineRest = SkipNonPrintable(opt.cmdLine);
	LPCWSTR pszName, pszArgStart;
	LPCWSTR psUnknown = NULL;
	CmdArg  szArg, szNext;
	CEStr   szExeName, szExeNameOnly;

	// Set %ConEmuArgs% env var
	// It may be useful if we need to restart ConEmu
	// from batch/script with the same arguments (selfupdate etc.)
	LPCWSTR pszCopyToEnvStart = NULL;

	// Have to get our exectuable name and name without extension
	szExeName.Set(PointToName(gpConEmu->ms_ConEmuExe));
	szExeNameOnly.Set(szExeName);
	wchar_t* pszDot = (wchar_t*)PointToExt(szExeNameOnly.ms_Val);
	_ASSERTE(pszDot);
	if (pszDot) *pszDot = 0;


	// Check the first argument in the command line (most probably it will be our executable path/name)
	if (!(pszTemp = NextArg(pszTemp, szArg)))
	{
		_ASSERTE(FALSE && "GetCommandLine() is empty");
		// Treat as empty command line, allow to start
		bRc = true; iResult = 0;
		goto wrap;
	}
	pszName = PointToName(szArg);
	if ((lstrcmpi(pszName, szExeName) == 0)
		|| (lstrcmpi(pszName, szExeNameOnly) == 0))
	{
		// OK, our executable was specified properly in the command line
		_ASSERTE(*pszTemp != L' ');
		cmdLineRest = SkipNonPrintable(pszTemp);
	}


	// Must be empty at the moment
	_ASSERTE(opt.runCommand.IsEmpty());

	// Does the command line contain our switches?
	// Or we need to append all switches to starting shell?
	if (cmdLineRest && *cmdLineRest)
	{
		pszTemp = cmdLineRest;
		if ((pszTemp = NextArg(pszTemp, szArg)))
		{
			if ((*szArg.ms_Val != L'/')
				&& (*szArg.ms_Val != L'-')
				/*&& !wcschr(szArg.ms_Val, L'/')*/
				)
			{
				// Save it for further use
				opt.runCommand.Set(cmdLineRest);
				// And do not process it (no switches at all)
				cmdLineRest = NULL;
				opt.params = -1;
			}
		}
	}

	struct RunAsAdmin
	{
		static bool Check(LPCWSTR asSwitch)
		{
			bool bRunAsAdmin = false; // isPressed(VK_SHIFT);
			return bRunAsAdmin;
		};
	};


	// Let parse the reset
	szArg.Empty();
	szNext.Empty();

	// Processing loop begin
	if (cmdLineRest && *cmdLineRest)
	{
		pszCopyToEnvStart = cmdLineRest;
		opt.cfgSwitches.Set(pszCopyToEnvStart);

		while ((cmdLineRest = NextArg(cmdLineRest, szArg, &pszArgStart)))
		{
			bool lbNotFound = false;

			TODO("Replace NeedNextArg with GetCfgParm?")
			#define NeedNextArg() \
				if (!(cmdLineRest = NextArg(cmdLineRest, szNext))) { iResult = CERR_CARGUMENT; goto wrap; }


			if (!szArg.IsPossibleSwitch())
			{
				// -- // continue; // Try next switch?

				// Show error on unknown switch
				psUnknown = pszArgStart;
				break;
			}

			// Main processing cycle
			{
				opt.params++;

				if (szArg.IsSwitch(L"-autosetup"))
				{
					BOOL lbTurnOn = TRUE;

					NeedNextArg();

					if (szNext.Compare(L"0") == 0)
					{
						lbTurnOn = FALSE;
					}
					else if (szNext.Compare(L"1") == 0)
					{
						NeedNextArg();

						DWORD dwAttr = GetFileAttributes(szNext);

						if (dwAttr == (DWORD)-1 || (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
						{
							iResult = 102;
							goto wrap;
						}
					}
					else
					{
						iResult = CERR_CARGUMENT;
						goto wrap;
					}

					HKEY hk = NULL; DWORD dw;
					int nSetupRc = 100;

					if (0 != RegCreateKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Command Processor"),
										   0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, &dw))
					{
						iResult = 103;
						goto wrap;
					}

					if (lbTurnOn)
					{
						size_t cchMax = szNext.GetLen();
						LPCWSTR pszArg1 = NULL;
						if (*cmdLineRest)
						{
							// May be ‘/GHWND=NEW’ or smth else
							pszArg1 = cmdLineRest;
							cchMax += _tcslen(pszArg1);
						}
						cchMax += 16; // + quotations, spaces and so on

						wchar_t* pszCmd = (wchar_t*)calloc(cchMax, sizeof(*pszCmd));
						swprintf_c(pszCmd, cchMax/*#SECURELEN*/, L"\"%s\"%s%s%s", szNext.ms_Val,
							pszArg1 ? L" \"" : L"", pszArg1 ? pszArg1 : L"", pszArg1 ? L"\"" : L"");


						if (0 == RegSetValueEx(hk, _T("AutoRun"), 0, REG_SZ, (LPBYTE)pszCmd,
											(DWORD)sizeof(*pszCmd)*(_tcslen(pszCmd)+1)))
							nSetupRc = 1;

						free(pszCmd);
					}
					else
					{
						if (0==RegDeleteValue(hk, _T("AutoRun")))
							nSetupRc = 1;
					}

					RegCloseKey(hk);
					// сбросить CreateInNewEnvironment для ConMan
					ResetConman();
					iResult = nSetupRc;
					goto wrap;
				}
				else if (szArg.OneOfSwitches(L"-bypass", L"-apparent", L"-system:", L"-interactive:", L"-demote"))
				{
					// -bypass
					// Этот ключик был придуман для прозрачного запуска консоли
					// в режиме администратора
					// (т.е. чтобы окно UAC нормально всплывало, но не мелькало консольное окно)
					// Но не получилось, пока требуются хэндлы процесса, а их не получается
					// передать в НЕ приподнятый процесс (исходный ConEmu GUI).

					// -apparent
					// Same as -bypass, but run the process as SW_SHOWNORMAL

					// -demote
					// Запуск процесса (ком.строка после "/demote") в режиме простого юзера,
					// когда текущий процесс уже запущен "под админом". "Понизить" текущие
					// привилегии просто так нельзя, поэтому запуск идет через TaskSheduler.

					// -system
					// Non-interactive process, started as System account
					// It's used when starting consoles, our server works fine as non-interactive

					// -interactive
					// Used when ConEmu.exe is started under System account,
					// but we need to give starting process interactive capabilities.

					_ASSERTE(opt.runCommand.IsEmpty());
					pszTemp = cmdLineRest;
					if ((pszTemp = NextArg(pszTemp, szNext))
						&& szNext.OneOfSwitches(L"-run",L"-cmd"))
					{
						opt.runCommand.Set(pszTemp);
					}
					else
					{
						opt.runCommand.Set(cmdLineRest);
					}

					if (opt.runCommand.IsEmpty())
					{
						CEStr lsMsg(L"Invalid command line. '", szArg, L"' exists, command line is empty");
						DisplayLastError(lsMsg, -1);
						goto wrap;
					}

					// Information
					#ifdef _DEBUG
					STARTUPINFO siOur = {sizeof(siOur)};
					GetStartupInfo(&siOur);
					#endif

					STARTUPINFO si = {sizeof(si)};
					PROCESS_INFORMATION pi = {};
					si.dwFlags = STARTF_USESHOWWINDOW;
					// Only `-demote` and `-apparent` switches were implemented to start application visible
					// All others are intended to run our server process, without blinking of course
					if (szArg.OneOfSwitches(L"-demote", L"-apparent"))
						si.wShowWindow = SW_SHOWNORMAL;
					else
						si.wShowWindow = SW_HIDE;

					wchar_t szCurDir[MAX_PATH+1] = L"";
					GetCurrentDirectory(countof(szCurDir), szCurDir);

					BOOL b;
					DWORD nErr = 0;

					// if we were started from TaskScheduler, it would be nice to wait a little
					// to let parent (creator of the scheduler task) know we were started successfully
					bool bFromScheduler = false;

					// Log the command to be started
					{
						CEStr lsLog(
							L"Starting process",
							L": ", szArg,
							L" `", opt.runCommand.ms_Val, L"`");
						LogString(lsLog);
					}

					if (szArg.IsSwitch(L"-demote"))
					{
						b = CreateProcessDemoted(opt.runCommand.ms_Val, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,
							szCurDir, &si, &pi, &nErr);
					}
					else if (szArg.IsSwitch(L"-system:"))
					{
						DWORD nSessionID = wcstoul(szArg.ms_Val+wcslen(L"-system:"), NULL, 10);
						b = CreateProcessSystem(nSessionID, opt.runCommand.ms_Val, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL,
							szCurDir, &si, &pi);
					}
					else if (szArg.IsSwitch(L"-interactive:"))
					{
						DWORD nSessionID = wcstoul(szArg.ms_Val+wcslen(L"-interactive:"), NULL, 10);
						b = CreateProcessInteractive(nSessionID, NULL, opt.runCommand.ms_Val, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL,
							szCurDir, &si, &pi, &nErr);
						bFromScheduler = true;
					}
					else // -bypass, -apparent
					{
						b = CreateProcess(NULL, opt.runCommand.ms_Val, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL,
							NULL, &si, &pi);
						nErr = b ? 0 : GetLastError();
						bFromScheduler = true;
					}

					// Log the result
					{
						CEStr lsLog; wchar_t szExtra[32] = L"";
						if (b)
						{
							if (pi.dwProcessId)
								swprintf_c(szExtra, L", PID=%u", pi.dwProcessId);
							lsLog = lstrmerge(
								L"Process was created successfully",
								szExtra);
						}
						else
						{
							swprintf_c(szExtra, L", ErrorCode=%u", nErr);
							lsLog = lstrmerge(
								L"Failed to start process",
								szExtra);
						}
						LogString(lsLog);
					}

					// If the error was not shown yet
					if (nErr) DisplayLastError(opt.runCommand, nErr);

					// if we were started from TaskScheduler, it would be nice to wait a little
					// to let parent (creator of the scheduler task) know we were started successfully
					if (bFromScheduler)
					{
						LogString(L"Sleeping for 5 seconds");
						Sleep(5*1000);
					}

					// Success?
					if (b)
					{
						iResult = 0;
					}

					// Done, close handles, if they were opened
					SafeCloseHandle(pi.hProcess);
					SafeCloseHandle(pi.hThread);

					goto wrap;
				}
				else if (szArg.IsSwitch(L"-multi"))
				{
					gpConEmu->AppendExtraArgs(szArg);
					gpConEmu->opt.MultiConValue = true;
				}
				else if (szArg.IsSwitch(L"-NoMulti"))
				{
					gpConEmu->AppendExtraArgs(szArg);
					gpConEmu->opt.MultiConValue = false;
				}
				else if (szArg.IsSwitch(L"-visible"))
				{
					gpConEmu->opt.VisValue = true;
				}
				else if (szArg.OneOfSwitches(L"-ct", L"-cleartype", L"-ct0", L"-ct1", L"-ct2"))
				{
					switch (szArg[3])
					{
					case L'0':
						gpConEmu->opt.ClearTypeVal = NONANTIALIASED_QUALITY; break;
					case L'1':
						gpConEmu->opt.ClearTypeVal = ANTIALIASED_QUALITY; break;
					default:
						gpConEmu->opt.ClearTypeVal = CLEARTYPE_NATURAL_QUALITY;
					}
				}
				// Interface language
				else if (szArg.IsSwitch(L"-lng"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.Language.Exists)
					{
						gpConEmu->opt.Language = (LPCWSTR)szNext;
						gpConEmu->AppendExtraArgs(L"-lng", szNext);
					}
				}
				// Optional specific "ConEmu.l10n"
				else if (szArg.IsSwitch(L"-lngfile"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.LanguageFile.Exists)
					{
						gpConEmu->opt.LanguageFile = (LPCWSTR)szNext;
						gpConEmu->AppendExtraArgs(L"-lngfile", szNext);
					}
				}
				// Change font name
				else if (szArg.IsSwitch(L"-Font"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.FontVal.Exists)
					{
						gpConEmu->opt.FontVal = (LPCWSTR)szNext;
						gpConEmu->AppendExtraArgs(L"-font", szNext);
					}
				}
				// Change font height
				else if (szArg.IsSwitch(L"-FontSize") || szArg.IsSwitch(L"-Size"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.SizeVal.Exists)
					{
						gpConEmu->opt.SizeVal.SetInt(szNext);
					}
				}
				// ADD fontname; by Mors
				else if (szArg.IsSwitch(L"-FontFile"))
				{
					CESwitch szFile(sw_Str);
					if (!GetCfgParm(cmdLineRest, szFile, MAX_PATH))
					{
						goto wrap;
					}
					gpConEmu->AppendExtraArgs(L"-FontFile", szFile.GetStr());
					gpFontMgr->RegisterFont(szFile.GetStr(), TRUE);
				}
				// Register all fonts from specified directory
				else if (szArg.IsSwitch(L"-FontDir"))
				{
					CESwitch szDir(sw_Str);
					if (!GetCfgParm(cmdLineRest, szDir, MAX_PATH))
					{
						goto wrap;
					}
					gpConEmu->AppendExtraArgs(L"-FontDir", szDir.GetStr());
					gpFontMgr->RegisterFontsDir(szDir.GetStr());
				}
				else if (szArg.IsSwitch(L"-fs"))
				{
					gpConEmu->opt.WindowModeVal = wmFullScreen;
				}
				else if (szArg.IsSwitch(L"-max"))
				{
					gpConEmu->opt.WindowModeVal = wmMaximized;
				}
				else if (szArg.OneOfSwitches(L"-min", L"-MinTSA", L"-StartTSA"))
				{
					gpConEmu->WindowStartMinimized = true;
					if (!szArg.IsSwitch(L"-min"))
					{
						gpConEmu->WindowStartTsa = true;
						gpConEmu->WindowStartNoClose = szArg.IsSwitch(L"-MinTSA");
					}
				}
				else if (szArg.OneOfSwitches(L"-tsa", L"-tray"))
				{
					gpConEmu->ForceMinimizeToTray = true;
				}
				else if (szArg.IsSwitch(L"-detached"))
				{
					gpConEmu->m_StartDetached = crb_On;
					opt.Detached = true;
				}
				else if (szArg.IsSwitch(L"-NoAutoClose"))
				{
					opt.NoAutoClose = true;
				}
				else if (szArg.IsSwitch(L"-here"))
				{
					gpConEmu->mb_ConEmuHere = true;
					gpConEmu->StoreWorkDir();
				}
				else if (szArg.IsSwitch(L"-update"))
				{
					gpConEmu->opt.AutoUpdateOnStart = true;
				}
				else if (szArg.IsSwitch(L"-NoUpdate"))
				{
					// This one has more weight than AutoUpdateOnStart
					gpConEmu->opt.DisableAutoUpdate = true;
				}
				else if (szArg.IsSwitch(L"-NoHooksWarn"))
				{
					// Don't try to warn users about known problems with third-party detours
					gpConEmu->opt.NoHooksWarn = true;
				}
				else if (szArg.OneOfSwitches(L"-NoKeyHook", L"-NoKeyHooks", L"-NoKeybHook", L"-NoKeybHooks"))
				{
					gpConEmu->DisableKeybHooks = true;
				}
				else if (szArg.IsSwitch(L"-NoCloseConfirm"))
				{
					gpConEmu->DisableCloseConfirm = true;
				}
				else if (szArg.IsSwitch(L"-NoMacro"))
				{
					gpConEmu->DisableAllMacro = true;
				}
				else if (szArg.OneOfSwitches(L"-NoHotkey", L"-NoHotkeys"))
				{
					gpConEmu->DisableAllHotkeys = true;
				}
				else if (szArg.OneOfSwitches(L"-NoDefTrm", L"-NoDefTerm"))
				{
					gpConEmu->DisableSetDefTerm = true;
				}
				else if (szArg.OneOfSwitches(L"-NoRegFont", L"-NoRegFonts"))
				{
					gpConEmu->DisableRegisterFonts = true;
				}
				else if (szArg.OneOfSwitches(L"-inside", L"-inside="))
				{
					bool bRunAsAdmin = RunAsAdmin::Check(szArg.ms_Val);
					bool bSyncDir = false;
					LPCWSTR pszSyncFmt = NULL;

					gpConEmu->mb_ConEmuHere = true;
					gpConEmu->StoreWorkDir();

					// Both `-inside:...` and `-inside=...` are supported
					if (szArg.IsSwitch(L"-inside="))
					{
						bSyncDir = true;
						pszSyncFmt = szArg.ms_Val+8; // \eCD /d %1 - \e - ESC, \b - BS, \n - ENTER, %1 - "dir", %2 - "bash dir"
					}

					CConEmuInside::InitInside(bRunAsAdmin, bSyncDir, pszSyncFmt, 0, NULL);
				}
				else if (szArg.IsSwitch(L"-InsidePID"))
				{
					NeedNextArg();

					bool bRunAsAdmin = RunAsAdmin::Check(szArg.ms_Val);

					wchar_t* pszEnd;
					// Здесь указывается PID, в который нужно внедриться.
					DWORD nInsideParentPID = wcstol(szNext, &pszEnd, 10);
					if (nInsideParentPID)
					{
						CConEmuInside::InitInside(bRunAsAdmin, false, NULL, nInsideParentPID, NULL);
					}
				}
				else if (szArg.IsSwitch(L"-InsideWnd"))
				{
					NeedNextArg();

					LPCWSTR pszHWnd = szNext.ms_Val;

					if (pszHWnd[0] == L'0' && (pszHWnd[1] == L'x' || pszHWnd[1] == L'X'))
						pszHWnd += 2;
					else if (pszHWnd[0] == L'x' || pszHWnd[0] == L'X')
						pszHWnd ++;

					bool bRunAsAdmin = RunAsAdmin::Check(szArg.ms_Val);

					wchar_t* pszEnd;
					// Здесь указывается HWND, в котором нужно создаваться.
					HWND hParent = (HWND)(DWORD_PTR)wcstoul(pszHWnd, &pszEnd, 16);
					if (hParent && IsWindow(hParent))
					{
						CConEmuInside::InitInside(bRunAsAdmin, false, NULL, 0, hParent);
					}
				}
				else if (szArg.IsSwitch(L"-icon"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.IconPrm.Exists && !szNext.IsEmpty())
					{
						gpConEmu->opt.IconPrm = true;
						gpConEmu->mps_IconPath = ExpandEnvStr(szNext);
					}
				}
				else if (szArg.IsSwitch(L"-dir"))
				{
					NeedNextArg();

					if (!szNext.IsEmpty())
					{
						// Например, "%USERPROFILE%"
						CEStr szExpand;
						if (wcschr(szNext, L'%') && ((szExpand = ExpandEnvStr(szNext)) != NULL))
						{
							gpConEmu->StoreWorkDir(szExpand);
						}
						else
						{
							gpConEmu->StoreWorkDir(szNext);
						}
					}
				}
				else if (szArg.IsSwitch(L"-UpdateJumpList"))
				{
					// Copy current Task list to Win7 Jump list (Taskbar icon)
					gpConEmu->mb_UpdateJumpListOnStartup = true;
				}
				else if (szArg.OneOfSwitches(L"-log", L"-log0", L"-log1", L"-log2", L"-log3", L"-log4"))
				{
					if (szArg.OneOfSwitches(L"-log", L"-log0"))
						gpConEmu->opt.AdvLogging.SetInt(1);
					else
						gpConEmu->opt.AdvLogging.SetInt((BYTE)(szArg[4] - L'0')); // 1..4
					// Do create logging service
					DEBUGSTRSTARTUP(L"Creating log file");
					gpConEmu->CreateLog();
				}
				else if (szArg.OneOfSwitches(L"-Single", L"-Reuse"))
				{
					// "/reuse" switch to be remastered
					gpConEmu->AppendExtraArgs(szArg);
					gpSetCls->SingleInstanceArg = sgl_Enabled;
				}
				else if (szArg.IsSwitch(L"-NoSingle"))
				{
					gpConEmu->AppendExtraArgs(szArg);
					gpSetCls->SingleInstanceArg = sgl_Disabled;
				}
				else if (szArg.IsSwitch(L"-DesktopMode"))
				{
					gpConEmu->opt.DesktopMode = true;
				}
				else if (szArg.OneOfSwitches(L"-Quake", L"-QuakeAuto", L"-NoQuake"))
				{
					if (szArg.IsSwitch(L"-Quake"))
						gpConEmu->opt.QuakeMode = 1;
					else if (szArg.IsSwitch(L"-QuakeAuto"))
						gpConEmu->opt.QuakeMode = 2;
					else
					{
						gpConEmu->opt.QuakeMode = 0;
						if (gpSetCls->SingleInstanceArg == sgl_Default)
							gpSetCls->SingleInstanceArg = sgl_Disabled;
					}
				}
				else if (szArg.OneOfSwitches(L"-FrameWidth", L"-Frame"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.FrameWidth.Exists)
						gpConEmu->opt.FrameWidth.SetInt(szNext);
				}
				else if (szArg.OneOfSwitches(L"-ShowHide", L"-ShowHideTSA"))
				{
					gpSetCls->SingleInstanceArg = sgl_Enabled;
					gpSetCls->SingleInstanceShowHide = szArg.IsSwitch(L"-ShowHide")
						? sih_ShowMinimize : sih_ShowHideTSA;
				}
				else if (szArg.OneOfSwitches(L"-Reset", L"-ResetDefault", L"-Basic"))
				{
					gpConEmu->opt.ResetSettings = true;
					if (szArg.IsSwitch(L"-ResetDefault"))
					{
						gpSetCls->isFastSetupDisabled = true;
					}
					else if (szArg.IsSwitch(L"-Basic"))
					{
						gpSetCls->isFastSetupDisabled = true;
						gpSetCls->isResetBasicSettings = true;
					}
				}
				else if (szArg.OneOfSwitches(L"-NoCascade", L"-DontCascade"))
				{
					gpConEmu->AppendExtraArgs(szArg);
					gpSetCls->isDontCascade = true;
				}
				else if (szArg.OneOfSwitches(L"-WndX", L"-WndY", L"-WndW", L"-WndWidth", L"-WndH", L"-WndHeight"))
				{
					wchar_t ch = szArg[4];
					CharUpperBuff(&ch, 1);

					CESwitch psz(sw_Str); bool bParm = false;
					if (!GetCfgParm(cmdLineRest, bParm, psz, 32))
					{
						goto wrap;
					}
					gpConEmu->opt.SizePosPrm = true;

					// Direct X/Y implies /nocascade
					if (ch == _T('X') || ch == _T('Y'))
					{
						// TODO: isDontCascade must be in our opt struct !!!
						gpSetCls->isDontCascade = true;
					}

					switch (ch)
					{
					case _T('X'): gpConEmu->opt.sWndX.SetStr(psz.Str, sw_Str); break;
					case _T('Y'): gpConEmu->opt.sWndY.SetStr(psz.Str, sw_Str); break;
					case _T('W'): gpConEmu->opt.sWndW.SetStr(psz.Str, sw_Str); break;
					case _T('H'): gpConEmu->opt.sWndH.SetStr(psz.Str, sw_Str); break;
					}
				}
				else if (szArg.IsSwitch(L"-Monitor"))
				{
					CESwitch psz(sw_Str); bool bParm = false;
					if (!GetCfgParm(cmdLineRest, bParm, psz, 64))
					{
						goto wrap;
					}

					if ((gpConEmu->opt.Monitor.Mon = MonitorFromParam(psz.Str)) != NULL)
					{
						gpConEmu->opt.Monitor.Exists = true;
						gpConEmu->opt.Monitor.Type = sw_Int;
						gpStartEnv->hStartMon = gpConEmu->opt.Monitor.Mon;
					}
				}
				else if (szArg.IsSwitch(L"-Theme"))
				{
					const wchar_t* kDefaultTheme = L"DarkMode_Explorer";
					bool bParm = false;
					if (!cmdLineRest || (*cmdLineRest == L'-' || *cmdLineRest == L'/')
						|| !GetCfgParm(cmdLineRest, bParm, gpConEmu->opt.WindowTheme, 128))
					{
						gpConEmu->opt.WindowTheme.SetStr(kDefaultTheme);
					}
				}
				else if (szArg.OneOfSwitches(L"-Buffer", L"-BufferHeight"))
				{
					NeedNextArg();

					if (!gpConEmu->opt.BufferHeightVal.Exists)
					{
						gpConEmu->opt.BufferHeightVal.SetInt(szNext);

						if (gpConEmu->opt.BufferHeightVal.GetInt() < 0)
						{
							//setParent = true; -- Maximus5 - нефиг, все ручками
							gpConEmu->opt.BufferHeightVal = -gpConEmu->opt.BufferHeightVal.GetInt();
						}

						if (gpConEmu->opt.BufferHeightVal.GetInt() < LONGOUTPUTHEIGHT_MIN)
							gpConEmu->opt.BufferHeightVal = LONGOUTPUTHEIGHT_MIN;
						else if (gpConEmu->opt.BufferHeightVal.GetInt() > LONGOUTPUTHEIGHT_MAX)
							gpConEmu->opt.BufferHeightVal = LONGOUTPUTHEIGHT_MAX;
					}
				}
				else if (szArg.IsSwitch(L"-Config"))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.ConfigVal, 127))
					{
						goto wrap;
					}
				}
				else if (szArg.IsSwitch(L"-Palette"))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.PaletteVal, MAX_PATH))
					{
						goto wrap;
					}
				}
				else if (szArg.IsSwitch(L"-LoadRegistry"))
				{
					gpConEmu->AppendExtraArgs(szArg);
					gpConEmu->opt.ForceUseRegistryPrm = true;
				}
				else if (szArg.OneOfSwitches(L"-LoadCfgFile", L"-LoadXmlFile"))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.LoadCfgFile, MAX_PATH, true))
					{
						goto wrap;
					}
				}
				else if (szArg.OneOfSwitches(L"-SaveCfgFile", L"-SaveXmlFile"))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.SaveCfgFile, MAX_PATH, true))
					{
						goto wrap;
					}
				}
				else if (szArg.IsSwitch(L"-GuiMacro"))
				{
					// -- выполняется только последний
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.ExecGuiMacro, 0x8000, false))
					{
						goto wrap;
					}
				}
				else if (szArg.IsSwitch(L"-UpdateSrcSet"))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.UpdateSrcSet, MAX_PATH*4, false))
					{
						goto wrap;
					}
				}
				else if (szArg.IsSwitch(L"-AnsiLog"))
				{
					// -- используем последний из параметров, если их несколько
					if (!GetCfgParm(cmdLineRest, gpConEmu->opt.AnsiLogPath, MAX_PATH-40, true))
					{
						goto wrap;
					}
				}
				else if (szArg.IsSwitch(L"-SetDefTerm"))
				{
					gpConEmu->opt.SetUpDefaultTerminal = true;
				}
				else if (szArg.IsSwitch(L"-ZoneId"))
				{
					gpConEmu->opt.FixZoneId = true;
				}
				else if (szArg.IsSwitch(L"-Exit"))
				{
					gpConEmu->opt.ExitAfterActionPrm = true;
				}
				else if (szArg.IsSwitch(L"-QuitOnClose"))
				{
					gpConEmu->mb_ForceQuitOnClose = true;
				}
				else if (szArg.IsSwitch(L"-Title"))
				{
					bool bOk = false;
					CESwitch pszTitle(sw_Str);
					if (!GetCfgParm(cmdLineRest, bOk, pszTitle, 127))
					{
						goto wrap;
					}
					gpConEmu->SetTitleTemplate(pszTitle.GetStr());
				}
				else if (szArg.IsSwitch(L"-Settings"))
				{
					gpConEmu->mb_SettingsRequested = true;
				}
				else if (szArg.IsSwitch(L"-FindBugMode"))
				{
					gpConEmu->mb_FindBugMode = true;
				}
				else if (szArg.OneOfSwitches(L"-debug", L"-debugw", L"-debugi"))
				{
					// These switches were already processed
				}
				else if (szArg.OneOfSwitches(L"-?", L"-h", L"-help"))
				{
					if (gpLng) gpLng->Reload();
					ConEmuAbout::OnInfo_About();
					iResult = -1;
					goto wrap;
				}
				// Final `-run ...` or `-runlist ...` (old names `-cmd ...` or `-cmdlist ...`)
				else if (
					szArg.OneOfSwitches(L"-run", L"-runlist", L"-cmd", L"-cmdlist")
					)
				{
					if (opt.cfgSwitches.ms_Val)
					{
						_ASSERTE(pszArgStart>=pszCopyToEnvStart); // If there is only "-run cmd" in arguments
						_ASSERTE((INT_PTR)(pszArgStart - pszCopyToEnvStart) <= opt.cfgSwitches.GetLen());
						opt.cfgSwitches.ms_Val[pszArgStart - pszCopyToEnvStart] = 0;
					}

					opt.runCommand.Set(SkipNonPrintable(cmdLineRest));
					opt.isScript = szArg.OneOfSwitches(L"-runlist", L"-cmdlist");
					break;
				}
				else
				{
					// Show error on unknown switch
					psUnknown = pszArgStart;
					break;
				}
			}
			// Main processing cycle end

			// Avoid assertions in NextArg
			szArg.Empty(); szNext.Empty();
		} // while (NextArg(&cmdLineRest, szArg, &pszArgStart) == 0)
	}
Beispiel #20
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;
}
Beispiel #21
0
void CLngRc::Reload(bool bForce /*= false*/)
{
	bool bChanged = bForce;
	bool bExists = false;
	CEStr lsNewLng, lsNewFile;

	// TODO: There would be gpSet member in future
	lsNewLng.Set(gpConEmu->opt.Language.GetStr());

	// Language was requested?
	if (!lsNewLng.IsEmpty())
	{
		if (ms_Lng.IsEmpty() || (0 != wcscmp(lsNewLng, ms_Lng)))
		{
			bChanged = true;
		}

		// We need a file
		if (gpConEmu->opt.LanguageFile.Exists)
		{
			// It may contain environment variables
			lsNewFile = ExpandEnvStr(gpConEmu->opt.LanguageFile.GetStr());
			if (lsNewFile.IsEmpty())
				lsNewFile.Set(gpConEmu->opt.LanguageFile.GetStr());
			// Check if the file exists
			bExists = FileExists(lsNewFile);
		}
		else
		{
			lsNewFile = JoinPath(gpConEmu->ms_ConEmuExeDir, gsResourceFileName);
			if (!(bExists = FileExists(lsNewFile)))
			{
				lsNewFile = JoinPath(gpConEmu->ms_ConEmuBaseDir, gsResourceFileName);
				bExists = FileExists(lsNewFile);
			}
		}

		// File name was changed?
		if ((bExists == ms_l10n.IsEmpty())
			|| (bExists
				&& (ms_l10n.IsEmpty()
					|| (0 != wcscmp(lsNewFile, ms_l10n)))
				)
			)
		{
			bChanged = true;
		}
	}
	else if (!ms_Lng.IsEmpty())
	{
		bChanged = true;
	}

	// Check if we have to reload data
	if (bChanged)
	{
		if (!bExists
			|| !LoadResouces(lsNewLng, lsNewFile))
		{
			ms_Lng.Empty();
			ms_l10n.Empty();

			Clean(m_CmnHints);
			Clean(m_MnuHints);
			Clean(m_Controls);
		}
	}
}
Beispiel #22
0
int CIconList::CreateTabIconInt(LPCWSTR asIconDescr, bool bAdmin, LPCWSTR asWorkDir)
{
	wchar_t* pszExpanded = ExpandEnvStr(asIconDescr);

	// Need to be created!
	int iIconIdx = -1;
	HICON hFileIcon = NULL;
	wchar_t szTemp[MAX_PATH];
	LPCWSTR pszLoadFile = pszExpanded ? pszExpanded : asIconDescr;
	LPCWSTR lpszExt = (wchar_t*)PointToExt(pszLoadFile);

	bool bDirChanged = false;
	if (asWorkDir && *asWorkDir)
	{
		// Executable (or icon) file may be not availbale by %PATH%, let "cd" to it...
		bDirChanged = gpConEmu->ChangeWorkDir(asWorkDir);
	}

	if (!lpszExt)
	{
		LPWSTR pszFile = NULL;
		if (SearchPath(NULL, pszLoadFile, L".exe", countof(szTemp), szTemp, &pszFile))
		{
			pszLoadFile = szTemp;
			lpszExt = (wchar_t*)PointToExt(pszLoadFile);
		}

		if (!lpszExt)
			goto wrap;
	}

	if (lstrcmpi(lpszExt, L".ico") == 0)
	{
		hFileIcon = (HICON)LoadImage(0, pszLoadFile, IMAGE_ICON,
		                             GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR|LR_LOADFROMFILE);
	}
	else if ((lstrcmpi(lpszExt, L".exe") == 0) || (lstrcmpi(lpszExt, L".dll") == 0))
	{
		//TODO: May be specified index of an icon in the file
		HICON hIconLarge = NULL;
		ExtractIconEx(pszLoadFile, 0, &hIconLarge, &hFileIcon, 1);
		if (hIconLarge) DestroyIcon(hIconLarge);
	}
	else
	{
		//TODO: Shell icons for registered files (cmd, bat, sh, pl, py, ...)
	}

	if (hFileIcon)
	{
		int iIconIdxAdm = -1;
		iIconIdx = ImageList_ReplaceIcon(mh_TabIcons, -1, hFileIcon);

		TabIconCache NewIcon = {lstrdup(asIconDescr), false, iIconIdx};
		m_Icons.push_back(NewIcon);

		HIMAGELIST hAdmList = ImageList_Merge(mh_TabIcons, iIconIdx, mh_TabIcons, mn_AdminIcon+2, 0,0);
		if (hAdmList)
		{
			HICON hNewIcon = ImageList_GetIcon(hAdmList, 0, ILD_TRANSPARENT);
			if (hNewIcon)
			{
				iIconIdxAdm = ImageList_ReplaceIcon(mh_TabIcons, -1, hNewIcon);
				DestroyIcon(hNewIcon);

				TabIconCache AdmIcon = {lstrdup(asIconDescr), true, iIconIdxAdm};
				m_Icons.push_back(AdmIcon);

				if (bAdmin && (iIconIdxAdm > 0))
				{
					iIconIdx = iIconIdxAdm;
				}
			}
		}

		//TODO: bAdmin!!!

		DestroyIcon(hFileIcon);
	}

wrap:
	if (bDirChanged)
	{
		gpConEmu->ChangeWorkDir(NULL);
	}
	SafeFree(pszExpanded);
	return iIconIdx;
}