Пример #1
0
bool CompareProcessNames(LPCWSTR pszProcess1, LPCWSTR pszProcess2)
{
	LPCWSTR pszName1 = PointToName(pszProcess1);
	LPCWSTR pszName2 = PointToName(pszProcess2);
	if (!pszName1 || !*pszName1 || !pszName2 || !*pszName2)
		return false;

	LPCWSTR pszExt1 = wcsrchr(pszName1, L'.');
	LPCWSTR pszExt2 = wcsrchr(pszName2, L'.');

	CEStr lsName1, lsName2;
	if (!pszExt1)
	{
		lsName1.Attach(lstrmerge(pszName1, L".exe"));
		pszName1 = lsName1;
		if (!pszName1)
			return false;
	}
	if (!pszExt2)
	{
		lsName2.Attach(lstrmerge(pszName2, L".exe"));
		pszName2 = lsName2;
		if (!pszName2)
			return false;
	}

	int iCmp = lstrcmpi(pszName1, pszName2);
	return (iCmp == 0);
}
Пример #2
0
	// Create the command to show on the Integration settings page
	LPCWSTR CreateCommand(CEStr& rsReady)
	{
		rsReady = L"";

		for (INT_PTR i = 0; i < ourSwitches.size(); i++)
		{
			Switch* ps = ourSwitches[i];
			_ASSERTE(ps && !ps->szSwitch.IsEmpty());
			bool bOpt = !ps->szOpt.IsEmpty();
			bool bQuot = (bOpt && IsQuotationNeeded(ps->szOpt));
			lstrmerge(&rsReady.ms_Val,
				ps->szSwitch,
				bOpt ? L" " : NULL,
				bQuot ? L"\"" : NULL,
				bOpt ? ps->szOpt.c_str() : NULL,
				bQuot ? L"\" " : L" ");
		}

		if (!rsReady.IsEmpty() || bCmdList)
		{
			lstrmerge(&rsReady.ms_Val,
				bCmdList ? L"-runlist " : L"-run ", szCmd);
		}
		else
		{
			rsReady.Set(szCmd);
		}

		return rsReady.c_str(L"");
	};
Пример #3
0
void ConEmuAbout::LogStartEnvInt(LPCWSTR asText, LPARAM lParam, bool bFirst, bool bNewLine)
{
	lstrmerge(&gsSysInfo, asText, bNewLine ? L"\r\n" : NULL);

	if (bFirst && gpConEmu)
	{
		lstrmerge(&gsSysInfo, L"  AppID: ", gpConEmu->ms_AppID, L"\r\n");
	}
}
Пример #4
0
wchar_t* MergeCmdLine(LPCWSTR asExe, LPCWSTR asParams)
{
	bool bNeedQuot = IsQuotationNeeded(asExe);
	if (asParams && !*asParams)
		asParams = NULL;

	wchar_t* pszRet;
	if (bNeedQuot)
		pszRet = lstrmerge(L"\"", asExe, asParams ? L"\" " : L"\"", asParams);
	else
		pszRet = lstrmerge(asExe, asParams ? L" " : NULL, asParams);

	return pszRet;
}
Пример #5
0
void DefTermLogString(LPCWSTR asMessage, LPCWSTR asLabel /*= NULL*/)
{
	if (!asMessage || !*asMessage)
	{
		return;
	}

	// To ensure that we may force debug output for troubleshooting
	// even from non-def-term-ed applications
	if (!gpDefTerm)
	{
		DebugStr(asMessage);
		if (asMessage[lstrlen(asMessage) - 1] != L'\n')
		{
			DebugStr(L"\n");
		}
		return;
	}

	LPCWSTR pszReady = asMessage;
	CEStr lsBuf;
	if (asLabel && !asLabel)
	{
		lsBuf = lstrmerge(asLabel, asMessage);
		if (lsBuf.ms_Arg)
			pszReady = lsBuf.ms_Arg;
	}

	gpDefTerm->LogHookingStatus(pszReady);
}
Пример #6
0
wchar_t* JoinPath(LPCWSTR asPath, LPCWSTR asPart1, LPCWSTR asPart2 /*= NULL*/)
{
	LPCWSTR psz1 = asPath, psz2 = NULL, psz3 = asPart1, psz4 = NULL, psz5 = asPart2;

	// Добавить слеши если их нет на гранях
	// удалить лишние, если они указаны в обеих частях

	if (asPart1)
	{
		bool bDirSlash1  = (psz1 && *psz1) ? (psz1[lstrlen(psz1)-1] == L'\\') : false;
		bool bFileSlash1 = (asPart1[0] == L'\\');

		if (bDirSlash1 && bFileSlash1)
			psz3++;
		else if (!bDirSlash1 && !bFileSlash1 && asPath && *asPath)
			psz2 = L"\\";

		if (asPart2)
		{
			bool bDirSlash2  = (psz3 && *psz3) ? (psz3[lstrlen(psz3)-1] == L'\\') : false;
			bool bFileSlash2 = (asPart2[0] == L'\\');

			if (bDirSlash2 && bFileSlash2)
				psz5++;
			else if (!bDirSlash2 && !bFileSlash2)
				psz4 = L"\\";
		}
	}

	return lstrmerge(psz1, psz2, psz3, psz4, psz5);
}
Пример #7
0
bool MyOpenClipboard(LPCWSTR asAction)
{
	_ASSERTE(gnMyClipboardOpened==0 || gnMyClipboardOpened==1);

	if (gnMyClipboardOpened > 0)
	{
		InterlockedIncrement(&gnMyClipboardOpened);
		return true;
	}

	BOOL lbRc;
	int iMaxTries = 100;

	// Open Windows' clipboard
	while (!(lbRc = OpenClipboard((ghWnd && IsWindow(ghWnd)) ? ghWnd : NULL)) && (iMaxTries-- > 0))
	{
		DWORD dwErr = GetLastError();

		wchar_t szCode[32]; _wsprintf(szCode, SKIPCOUNT(szCode) L", Code=%u", dwErr);
		wchar_t* pszMsg = lstrmerge(L"OpenClipboard failed (", asAction, L")", szCode);
		LogString(pszMsg);
		int iBtn = DisplayLastError(pszMsg, dwErr, MB_RETRYCANCEL|MB_ICONSTOP);
		SafeFree(pszMsg);

		if (iBtn != IDRETRY)
			return false;
	}

	InterlockedIncrement(&gnMyClipboardOpened);
	_ASSERTE(gnMyClipboardOpened==1);

	LogString(L"OpenClipboard succeeded");
	return true;
}
Пример #8
0
void CPushInfo::OnNotificationClick()
{
    if (!mp_Active)
        return;

    bool bOpenUrl = false;

    if (mp_Active->pszFullMessage)
    {
        CEStr lsMsg(lstrmerge(mp_Active->pszFullMessage, L"\r\n\r\n", INFO_MESSAGE_FOOTER));
        int iBtn = MsgBox(lsMsg, MB_ICONINFORMATION|MB_YESNOCANCEL);

        switch (iBtn)
        {
        case IDYES:
            bOpenUrl = true;
            break;
        case IDNO:
            gpSet->SaveStopBuzzingDate();
            break;
        }
    }
    else
    {
        bOpenUrl = true;
    }

    if (bOpenUrl)
    {
        OpenNotificationUrl();
    }
}
Пример #9
0
// Concatenate strings from array and set resource item
bool CLngRc::SetResource(MArray<LngRcItem>& arr, int idx, MJsonValue* pJson)
{
	CEStr lsValue;
	MJsonValue jStr;

	// [ "Decrease window height ", "(check ‘Resize with arrows’)" ]
	size_t iCount = pJson->getLength();

	for (size_t i = 0; i < iCount; i++)
	{
		if (!pJson->getItem(i, jStr) || (jStr.getType() != MJsonValue::json_String))
		{
			_ASSERTE(FALSE && "String format failure");
			return false;
		}
		lstrmerge(&lsValue.ms_Val, jStr.getString());
	}

	if (lsValue.IsEmpty())
	{
		_ASSERTE(FALSE && "Empty resource string (array)");
		return false;
	}

	return SetResource(arr, idx, lsValue.ms_Val, true);
}
Пример #10
0
CEStr::CEStr(const wchar_t* asStr1, const wchar_t* asStr2/*= NULL*/, const wchar_t* asStr3/*= NULL*/, const wchar_t* asStr4/*= NULL*/, const wchar_t* asStr5/*= NULL*/, const wchar_t* asStr6/*= NULL*/, const wchar_t* asStr7/*= NULL*/, const wchar_t* asStr8/*= NULL*/, const wchar_t* asStr9/*= NULL*/)
	: ms_Val(NULL), mn_MaxCount(0)
{
	CESTRLOG1("CEStr::CEStr(const wchar_t* x%p, x%p, x%p, ...)", asStr1, asStr2, asStr3);
	Empty();
	wchar_t* lpszMerged = lstrmerge(asStr1, asStr2, asStr3, asStr4, asStr5, asStr6, asStr7, asStr8, asStr9);
	AttachInt(lpszMerged);
}
Пример #11
0
void ConEmuAbout::OnInfo_OnlineWiki(LPCWSTR asPageName /*= NULL*/)
{
	CEStr szUrl(lstrmerge(CEWIKIBASE, asPageName ? asPageName : L"TableOfContents", L".html"));
	DWORD shellRc = (DWORD)(INT_PTR)ShellExecute(ghWnd, L"open", szUrl, NULL, NULL, SW_SHOWNORMAL);
	if (shellRc <= 32)
	{
		DisplayLastError(L"ShellExecute failed", shellRc);
	}
}
Пример #12
0
bool CPushInfo::ShowNotification()
{
    if (!mp_Active)
        return false;

    if (mp_Active->pszTsaNotify)
    {
        CEStr lsMsg(lstrmerge(mp_Active->pszTsaNotify, TSA_MESSAGE_FOOTER));
        Icon.ShowTrayIcon(lsMsg, tsa_Push_Notify);
    }
    return true;
}
Пример #13
0
bool CheckProcessName(LPCWSTR pszProcessName, LPCWSTR* lsNames)
{
	LPCWSTR pszName1 = PointToName(pszProcessName);
	if (!pszName1 || !*pszName1 || !lsNames)
		return false;

	LPCWSTR pszExt1 = wcsrchr(pszName1, L'.');

	CEStr lsName1;
	if (!pszExt1)
	{
		lsName1.Attach(lstrmerge(pszName1, L".exe"));
		pszName1 = lsName1;
		if (!pszName1)
			return false;
	}

	for (size_t i = 0; lsNames[i]; i++)
	{
		LPCWSTR pszName2 = lsNames[i];

		_ASSERTE(wcsrchr(pszName2, L'.') != NULL);
		#if 0
		CEStr lsName2;
		LPCWSTR pszExt2 = wcsrchr(pszName2, L'.');
		if (!pszExt2)
		{
			lsName2 = lstrmerge(pszName2, L".exe");
			pszName2 = lsName2;
			if (!pszName2)
				return false;
		}
		#endif

		if (lstrcmpi(pszName1, pszName2) == 0)
			return true;
	}

	return false;
}
Пример #14
0
bool lstrmerge(wchar_t** apsStr1, const wchar_t* asStr2, const wchar_t* asStr3 /*= NULL*/, const wchar_t* asStr4 /*= NULL*/)
{
	_ASSERTE(apsStr1!=NULL);

	wchar_t* pszNew = lstrmerge(*apsStr1, asStr2, asStr3, asStr4);
	if (!pszNew)
		return false;

	if (*apsStr1)
		free(*apsStr1);
	*apsStr1 = pszNew;

	return true;
}
Пример #15
0
int CDefTermHk::DisplayLastError(LPCWSTR asLabel, DWORD dwError/*=0*/, DWORD dwMsgFlags/*=0*/, LPCWSTR asTitle/*=NULL*/, HWND hParent/*=NULL*/)
{
	if (dwError)
	{
		wchar_t szInfo[64];
		msprintf(szInfo, countof(szInfo), L", ErrCode=x%X(%i)", dwError, (int)dwError);
		CEStr lsMsg = lstrmerge(asLabel, szInfo);
		LogHookingStatus(lsMsg);
	}
	else
	{
		LogHookingStatus(asLabel);
	}
	return 0;
}
Пример #16
0
void ConEmuAbout::TabSelected(HWND hDlg, int idx)
{
	if (idx < 0 || idx >= countof(Pages))
		return;

	wcscpy_c(sLastOpenTab, Pages[idx].Title);
	LPCWSTR pszNewText = Pages[idx].Text;
	CEStr lsTemp;
	if (gpConEmu->mp_PushInfo && gpConEmu->mp_PushInfo->mp_Active && gpConEmu->mp_PushInfo->mp_Active->pszFullMessage)
	{
		// EDIT control requires \r\n as line endings
		lsTemp = lstrmerge(gpConEmu->mp_PushInfo->mp_Active->pszFullMessage, L"\r\n\r\n\r\n", pszNewText);
		pszNewText = lsTemp.ms_Arg;
	}
	SetDlgItemText(hDlg, tAboutText, pszNewText);
}
Пример #17
0
void ConEmuAbout::OnInfo_About(LPCWSTR asPageName /*= NULL*/)
{
	InitCommCtrls();

	bool bOk = false;

	if (!asPageName && sLastOpenTab[0])
	{
		// Reopen last active tab
		asPageName = sLastOpenTab;
	}

	ReloadSysInfo();

	{
		DontEnable de;
		if (!mp_DpiAware)
			mp_DpiAware = new CDpiForDialog();
		HWND hParent = (ghOpWnd && IsWindowVisible(ghOpWnd)) ? ghOpWnd : ghWnd;
		// Modal dialog (CreateDialog)
		INT_PTR iRc = CDynDialog::ExecuteDialog(IDD_ABOUT, hParent, aboutProc, (LPARAM)asPageName);
		bOk = (iRc != 0 && iRc != -1);

		mh_AboutDlg = NULL;
		if (mp_DpiAware)
			mp_DpiAware->Detach();

		#ifdef _DEBUG
		// Any problems with dialog resource?
		if (!bOk) DisplayLastError(L"DialogBoxParam(IDD_ABOUT) failed");
		#endif
	}

	if (!bOk)
	{
		wchar_t* pszTitle = lstrmerge(gpConEmu->GetDefaultTitle(), L" About");
		DontEnable de;
		MSGBOXPARAMS mb = {sizeof(MSGBOXPARAMS), ghWnd, g_hInstance,
			pAbout,
			pszTitle,
			MB_USERICON, MAKEINTRESOURCE(IMAGE_ICON), 0, NULL, LANG_NEUTRAL
		};
		SafeFree(pszTitle);
		// Use MessageBoxIndirect instead of MessageBox to show our icon instead of std ICONINFORMATION
		MessageBoxIndirect(&mb);
	}
}
Пример #18
0
BOOL WINAPI OnSetConsoleTitleW(LPCWSTR lpConsoleTitle)
{
	//typedef BOOL (WINAPI* OnSetConsoleTitleW_t)(LPCWSTR lpConsoleTitle);
	ORIGINALFASTEX(SetConsoleTitleW,NULL);

	#ifdef DEBUG_CON_TITLE
	if (!gpLastSetConTitle)
		gpLastSetConTitle = new CEStr(lstrdup(lpConsoleTitle));
	else
		gpLastSetConTitle->Set(lpConsoleTitle);
	CEStr lsDbg(lstrmerge(L"SetConsoleTitleW('", lpConsoleTitle, L"')\n"));
	OutputDebugString(lsDbg);
	#endif

	BOOL bRc = FALSE;
	if (F(SetConsoleTitleW))
		bRc = F(SetConsoleTitleW)(lpConsoleTitle);
	return bRc;
}
Пример #19
0
void UnitModuleTest()
{
	wchar_t* pszConEmuCD = lstrmerge(gpConEmu->ms_ConEmuBaseDir, WIN3264TEST(L"\\ConEmuCD.dll",L"\\ConEmuCD64.dll"));
	HMODULE hMod, hGetMod;
	bool bTest;

	_ASSERTE(!IsModuleValid((HMODULE)NULL));
	_ASSERTE(!IsModuleValid((HMODULE)INVALID_HANDLE_VALUE));

	hMod = GetModuleHandle(L"kernel32.dll");
	if (hMod)
	{
		bTest = IsModuleValid(hMod);
		_ASSERTE(bTest);
	}
	else
	{
		_ASSERTE(FALSE && "GetModuleHandle(kernel32) failed");
	}

	hMod = LoadLibrary(pszConEmuCD);
	if (hMod)
	{
		bTest = IsModuleValid(hMod);
		_ASSERTE(bTest);

		FreeLibrary(hMod);
		bTest = IsModuleValid(hMod);
		// Due to unknown reason (KIS?) FreeLibrary was not able to release hMod sometimes
		hGetMod = GetModuleHandle(pszConEmuCD);
		if (!hGetMod)
			bTest = IsModuleValid(hMod);
		_ASSERTE(!bTest || (hGetMod!=NULL));
	}
	else
	{
		_ASSERTE(FALSE && "LoadLibrary(pszConEmuCD) failed");
	}
}
Пример #20
0
// These variables `ConEmuArgs` and `ConEmuArgs2` are required
// to (re)start ConEmu instance from batch with same arguments
// Called from CConEmuStart::ParseCommandLine
void CConEmuStart::ProcessConEmuArgsVar()
{
	// Full command line: config switches AND -cmd/-cmdlist
	_ASSERTE(!opt.cmdLine.IsEmpty());

	// Don't set `NULL`, it would remove var from env block!
	LPCWSTR pszValue;

	pszValue = opt.cfgSwitches.IsEmpty() ? L"" : opt.cfgSwitches.ms_Val;
	SetEnvironmentVariableW(L"ConEmuArgs", pszValue);

	if (opt.runCommand.IsEmpty())
	{
		SetEnvironmentVariableW(L"ConEmuArgs2", L"");
		_ASSERTE(opt.cmdRunCommand.IsEmpty());
	}
	else
	{
		opt.cmdRunCommand.Attach(lstrmerge(opt.isScript ? L"-cmd " : L"-cmdlist ", opt.runCommand));
		_ASSERTE(!opt.cmdRunCommand.IsEmpty());
		SetEnvironmentVariableW(L"ConEmuArgs2", opt.cmdRunCommand);
	}
}
Пример #21
0
int WINAPI OnGetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
{
	//typedef int (WINAPI* OnGetWindowTextW_t)(HWND hWnd, LPWSTR lpString, int nMaxCount);
	ORIGINAL_EX(GetWindowTextW);
	int iRc = 0;

	FixHwnd4ConText(hWnd);

	if (F(GetWindowTextW))
		iRc = F(GetWindowTextW)(hWnd, lpString, nMaxCount);

	#ifdef DEBUG_CON_TITLE
	wchar_t szPrefix[32]; _wsprintf(szPrefix, SKIPCOUNT(szPrefix) L"GetWindowTextW(x%08X)='", (DWORD)(DWORD_PTR)hWnd);
	CEStr lsDbg(lstrmerge(szPrefix, lpString, L"'\n"));
	OutputDebugString(lsDbg);
	if (gFarMode.cbSize && lpString && gpLastSetConTitle && gpLastSetConTitle->ms_Arg)
	{
		int iCmp = lstrcmp(gpLastSetConTitle->ms_Arg, lpString);
		_ASSERTE((iCmp == 0) && "Console window title was changed outside or was not applied yet");
	}
	#endif

	return iRc;
}
Пример #22
0
void ConEmuAbout::OnInfo_About(LPCWSTR asPageName /*= NULL*/)
{
	InitCommCtrls();

	bool bOk = false;

	{
		DontEnable de;
		HWND hParent = (ghOpWnd && IsWindowVisible(ghOpWnd)) ? ghOpWnd : ghWnd;
		// Modal dialog
		INT_PTR iRc = DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_ABOUT), hParent, aboutProc, (LPARAM)asPageName);
		bOk = (iRc != 0 && iRc != -1);

		ZeroStruct(m_Btns);
		mh_AboutDlg = NULL;

		#ifdef _DEBUG
		// Any problems with dialog resource?
		if (!bOk) DisplayLastError(L"DialogBoxParam(IDD_ABOUT) failed");
		#endif
	}

	if (!bOk)
	{
		wchar_t* pszTitle = lstrmerge(gpConEmu->GetDefaultTitle(), L" About");
		DontEnable de;
		MSGBOXPARAMS mb = {sizeof(MSGBOXPARAMS), ghWnd, g_hInstance,
			pAbout,
			pszTitle,
			MB_USERICON, MAKEINTRESOURCE(IMAGE_ICON), 0, NULL, LANG_NEUTRAL
		};
		SafeFree(pszTitle);
		// Use MessageBoxIndirect instead of MessageBox to show our icon instead of std ICONINFORMATION
		MessageBoxIndirect(&mb);
	}
}
Пример #23
0
// Used for URL wrapped on several lines
bool CMatch::GetNextLine(CRConDataGuard& data, int nLine)
{
	// Perhaps not only for "URL"?

	if (!data.isValid())
		return false;

	ConsoleLinePtr line;
	if (!data->GetConsoleLine(nLine, line) || line.nLen <= 0 || !line.pChar)
		return false;

	// ConsoleLinePtr doesn't contain Z-terminated strings, only RAW characters
	CEStr add;
	wchar_t* ptr = add.GetBuffer(line.nLen);
	if (!ptr)
		return false;
	wmemmove(ptr, line.pChar, line.nLen);
	ptr[line.nLen] = 0;
	// Append new data
	if (!lstrmerge(&m_SrcLine.ms_Val, ptr))
		return false;
	mn_SrcLength += line.nLen;
	return true;
}
Пример #24
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;
}
Пример #25
0
bool CLngRc::LoadResouces(LPCWSTR asLanguage, LPCWSTR asFile)
{
	bool  bOk = false;
	CEStr lsJsonData;
	DWORD jsonDataSize = 0, nErrCode = 0;
	MJsonValue* jsonFile = NULL;
	MJsonValue jsonSection;
	DWORD nStartTick = 0, nLoadTick = 0, nFinTick = 0, nDelTick = 0;
	int iRc;
	wchar_t szLog[120];

	struct { LPCWSTR pszSection; MArray<LngRcItem>* arr; int idDiff; }
	sections[] = {
		{ L"cmnhints", &m_CmnHints, 0 },
		{ L"mnuhints", &m_MnuHints, IDM__MIN_MNU_ITEM_ID },
		{ L"controls", &m_Controls, 0 },
		{ L"strings",  &m_Strings, 0 },
	};

	iRc = ReadTextFile(asFile, 1<<24 /*16Mb max*/, lsJsonData.ms_Val, jsonDataSize, nErrCode);
	if (iRc != 0)
	{
		// TODO: Log error
		goto wrap;
	}
	
	nStartTick = GetTickCount();
	jsonFile = new MJsonValue();
	if (!jsonFile->ParseJson(lsJsonData))
	{
		// TODO: Log error
		CEStr lsErrMsg = lstrmerge(
			L"Language resources loading failed!\r\n"
			L"File: ", asFile, L"\r\n"
			L"Error: ", jsonFile->GetParseError());
		gpConEmu->LogString(lsErrMsg.ms_Val);
		DisplayLastError(lsErrMsg.ms_Val, (DWORD)-1, MB_ICONSTOP);
		goto wrap;
	}
	nLoadTick = GetTickCount();

	// Remember language parameters
	ms_Lng.Set(asLanguage);
	ms_l10n.Set(asFile);

	// Allocate intial array size
	m_CmnHints.alloc(4096);
	m_MnuHints.alloc(512);
	m_Controls.alloc(4096);
	m_Strings.alloc(lng_NextId);

	// Process sections
	for (size_t i = 0; i < countof(sections); i++)
	{
		if (jsonFile->getItem(sections[i].pszSection, jsonSection) && (jsonSection.getType() == MJsonValue::json_Object))
			bOk |= LoadSection(&jsonSection, *(sections[i].arr), sections[i].idDiff);
		else
			Clean(*(sections[i].arr));
	}

	nFinTick = GetTickCount();

wrap:
	SafeDelete(jsonFile);
	nDelTick = GetTickCount();
	if (bOk)
	{
		_wsprintf(szLog, SKIPCOUNT(szLog) L"Language resources duration (ms): Parse: %u; Internal: %u; Delete: %u", (nLoadTick - nStartTick), (nFinTick - nLoadTick), (nDelTick - nFinTick));
		gpConEmu->LogString(szLog);
	}
	return bOk;
}
Пример #26
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)
	}
Пример #27
0
// Called from OnShellExecCmdLine
HRESULT OurShellExecCmdLine(HWND hwnd, LPCWSTR pwszCommand, LPCWSTR pwszStartDir, bool bRunAsAdmin, bool bForce)
{
	HRESULT hr = E_UNEXPECTED;
	BOOL bShell = FALSE;

	CEStr lsLog = lstrmerge(L"OnShellExecCmdLine", bRunAsAdmin ? L"(RunAs): " : L": ", pwszCommand);
	DefTermLogString(lsLog);

	// Bad thing, ShellExecuteEx needs File&Parm, but we get both in pwszCommand
	CmdArg szExe;
	LPCWSTR pszFile = pwszCommand;
	LPCWSTR pszParm = pwszCommand;
	if (NextArg(&pszParm, szExe) == 0)
	{
		pszFile = szExe; pszParm = SkipNonPrintable(pszParm);
	}
	else
	{
		// Failed
		pszFile = pwszCommand; pszParm = NULL;
	}

	if (!bForce)
	{
		DWORD nCheckSybsystem1 = 0, nCheckBits1 = 0;
		if (!FindImageSubsystem(pszFile, nCheckSybsystem1, nCheckBits1))
		{
			hr = (HRESULT)-1;
			DefTermLogString(L"OnShellExecCmdLine: FindImageSubsystem failed");
			goto wrap;
		}
		if (nCheckSybsystem1 != IMAGE_SUBSYSTEM_WINDOWS_CUI)
		{
			hr = (HRESULT)-1;
			DefTermLogString(L"OnShellExecCmdLine: !=IMAGE_SUBSYSTEM_WINDOWS_CUI");
			goto wrap;
		}
	}

	// "Run as admin" was requested?
	if (bRunAsAdmin)
	{
		SHELLEXECUTEINFO sei = {sizeof(sei), 0, hwnd, L"runas", pszFile, pszParm, pwszStartDir, SW_SHOWNORMAL};
		bShell = OnShellExecuteExW(&sei);
	}
	else
	{
		wchar_t* pwCommand = lstrdup(pwszCommand);
		DWORD nCreateFlags = CREATE_NEW_CONSOLE|CREATE_UNICODE_ENVIRONMENT|CREATE_DEFAULT_ERROR_MODE;
		STARTUPINFO si = {sizeof(si)};
		PROCESS_INFORMATION pi = {};
		bShell = OnCreateProcessW(NULL, pwCommand, NULL, NULL, FALSE, nCreateFlags, NULL, pwszStartDir, &si, &pi);
		if (bShell)
		{
			CloseHandle(pi.hProcess);
			CloseHandle(pi.hThread);
		}
	}

	hr = bShell ? S_OK : HRESULT_FROM_WIN32(GetLastError());
wrap:
	return hr;
}
Пример #28
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;
	}

	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;
	}
Пример #29
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;
}
Пример #30
0
void UpdateComspec(ConEmuComspec* pOpt, bool DontModifyPath /*= false*/)
{
	if (!pOpt)
	{
		_ASSERTE(pOpt!=NULL);
		return;
	}

	if (pOpt->isUpdateEnv && (pOpt->csType != cst_EnvVar))
	{
		//if (pOpt->csType == cst_AutoTccCmd) -- always, if isUpdateEnv
		{
			LPCWSTR pszNew = NULL;
			switch (pOpt->csBits)
			{
			case csb_SameOS:
				pszNew = IsWindows64() ? pOpt->Comspec64 : pOpt->Comspec32;
				break;
			case csb_SameApp:
				pszNew = WIN3264TEST(pOpt->Comspec32,pOpt->Comspec64);
				break;
			case csb_x32:
				pszNew = pOpt->Comspec32;
				break;
			default:
				_ASSERTE(pOpt->csBits==csb_SameOS || pOpt->csBits==csb_SameApp || pOpt->csBits==csb_x32);
				pszNew = NULL;
			}
			if (pszNew && *pszNew)
			{
				#ifdef SHOW_COMSPEC_CHANGE
				wchar_t szCurrent[MAX_PATH]; GetEnvironmentVariable(L"ComSpec", szCurrent, countof(szCurrent));
				if (lstrcmpi(szCurrent, pszNew))
				{
					wchar_t szMsg[MAX_PATH*4], szProc[MAX_PATH] = {}, szPid[MAX_PATH];
					GetModuleFileName(NULL, szProc, countof(szProc));
					_wsprintf(szPid, SKIPLEN(countof(szPid))
						L"PID=%u, '%s'", GetCurrentProcessId(), PointToName(szProc));
					_wsprintf(szMsg, SKIPLEN(countof(szMsg))
						L"Changing %%ComSpec%% in %s\nCur=%s\nNew=%s",
						szPid , szCurrent, pszNew);
					MessageBox(NULL, szMsg, szPid, MB_SYSTEMMODAL);
				}
				#endif

				_ASSERTE(wcschr(pszNew, L'%')==NULL);
				SetEnvVarExpanded(L"ComSpec", pszNew);
			}
		}
	}

	if (pOpt->AddConEmu2Path && !DontModifyPath)
	{
		if ((pOpt->ConEmuBaseDir[0] == 0) || (pOpt->ConEmuExeDir[0] == 0))
		{
			_ASSERTE(pOpt->ConEmuBaseDir[0] != 0);
			_ASSERTE(pOpt->ConEmuExeDir[0] != 0);
		}
		else
		{
			wchar_t* pszCur = GetEnvVar(L"PATH");

			if (!pszCur)
				pszCur = lstrdup(L"");

			DWORD n = lstrlen(pszCur);
			wchar_t* pszUpr = lstrdup(pszCur);
			wchar_t* pszDirUpr = (wchar_t*)malloc(MAX_PATH*sizeof(*pszCur));

			MCHKHEAP;

			if (!pszUpr || !pszDirUpr)
			{
				_ASSERTE(pszUpr && pszDirUpr);
			}
			else
			{
				bool bChanged = false;
				wchar_t* pszAdd = NULL;

				CharUpperBuff(pszUpr, n);

				for (int i = 0; i <= 1; i++)
				{
					// Put '%ConEmuExeDir' on first place
					switch (i)
					{
					case 1:
						if (!(pOpt->AddConEmu2Path & CEAP_AddConEmuExeDir))
							continue;
						pszAdd = pOpt->ConEmuExeDir;
						break;
					case 0:
						if (!(pOpt->AddConEmu2Path & CEAP_AddConEmuBaseDir))
							continue;
						if (lstrcmp(pOpt->ConEmuExeDir, pOpt->ConEmuBaseDir) == 0)
							continue; // второй раз ту же директорию не добавляем
						pszAdd = pOpt->ConEmuBaseDir;
						break;
					}

					int nDirLen = lstrlen(pszAdd);
					lstrcpyn(pszDirUpr, pszAdd, MAX_PATH);
					CharUpperBuff(pszDirUpr, nDirLen);

					MCHKHEAP;

					// Need to find exact match!
					bool bFound = false;

					LPCWSTR pszFind = wcsstr(pszUpr, pszDirUpr);
					while (pszFind)
					{
						if (pszFind[nDirLen] == L';' || pszFind[nDirLen] == 0)
						{
							// OK, found
							bFound = true;
							break;
						}
						// Next try (may be partial match of subdirs...)
						pszFind = wcsstr(pszFind+nDirLen, pszDirUpr);
					}

					if (!bFound)
					{
						wchar_t* pszNew = lstrmerge(pszAdd, L";", pszCur);
						if (!pszNew)
						{
							_ASSERTE(pszNew && "Failed to reallocate PATH variable");
							break;
						}
						MCHKHEAP;
						SafeFree(pszCur);
						pszCur = pszNew;
						bChanged = true; // Set flag, check next dir
					}
				}

				MCHKHEAP;

				if (bChanged)
				{
					SetEnvironmentVariable(L"PATH", pszCur);
				}
			}

			MCHKHEAP;

			SafeFree(pszUpr);
			SafeFree(pszDirUpr);

			MCHKHEAP;
			SafeFree(pszCur);
		}
	}
}