Example #1
0
	// Parse switches stored in gpConEmu during initialization (AppendExtraArgs)
	// These are, for example, `-lngfile`, `-fontdir`, and so on.
	void ParseStdSwitches()
	{
		_ASSERTE(stdSwitches.empty());

		CEStr szArg, szNext, lsExta;
		LPCWSTR psz, pszExtraArgs;

		pszExtraArgs = gpConEmu->MakeConEmuStartArgs(lsExta);
		psz = pszExtraArgs;
		while (psz && *psz)
		{
			Switch* ps = GetNextPair(psz);
			if (!ps)
			{
				continue;
			}
			if (IsIgnored(ps, GetSkipSwitches()))
			{
				SafeDelete(ps);
				continue;
			}
			stdSwitches.push_back(ps);
		}
	};
Example #2
0
CAttachDlg::AttachMacroRet CAttachDlg::AttachFromMacro(DWORD anPID, bool abAlternative)
{
	MArray<AttachParm> Parms;

	HWND hFind = NULL;
	CProcessData ProcessData;

	while ((hFind = FindWindowEx(NULL, hFind, NULL, NULL)) != NULL)
	{
		if (!IsWindowVisible(hFind))
			continue;

		AttachWndInfo Info = {};
		if (!GetWindowThreadProcessId(hFind, &Info.nPID) || (Info.nPID != anPID))
			continue;

		if (!CanAttachWindow(hFind, 0, &ProcessData, Info))
			continue;

		AttachParm p = {};
		p.hAttachWnd = hFind;
		p.nPID = Info.nPID;
		p.nBits = Info.nImageBits;
		if (lstrcmp(Info.szType, szTypeCon) == 0)
			p.nType = apt_Console;
		else if (lstrcmp(Info.szType, szTypeGui) == 0)
			p.nType = apt_Gui;
		else
			continue;
		p.bAlternativeMode = abAlternative;
		Parms.push_back(p);
	}

	if (Parms.empty())
		return amr_WindowNotFound;
	if (Parms.size() > 1)
		return amr_Ambiguous;

	AttachParm Null = {};
	Parms.push_back(Null);

	// Работу делаем в фоновом потоке, чтобы не блокировать главный
	// (к окну ConEmu должна подцепиться новая вкладка)
	AttachParm* pParm = Parms.detach();
	if (!pParm)
		return amr_Unexpected;

	DWORD nTID = 0;
	HANDLE hThread = apiCreateThread((LPTHREAD_START_ROUTINE)StartAttachThread, pParm, &nTID, "CAttachDlg::StartAttachThread#2");
	if (!hThread)
	{
		//DWORD dwErr = GetLastError();
		//_wsprintf(szItem, SKIPLEN(countof(szItem)) L"ConEmu Attach, PID=%u, TID=%u", GetCurrentProcessId(), GetCurrentThreadId());
		//DisplayLastError(L"Can't start attach thread", dwErr, 0, szItem);
		return amr_Unexpected;
	}
	// We don't need this handle
	CloseHandle(hThread);

	return amr_Success;
}
Example #3
0
bool CAttachDlg::OnStartAttach()
{
	bool lbRc = false;
	// Тут нужно получить инфу из списка и дернуть собственно аттач
	wchar_t szItem[128] = {};
	//DWORD nPID = 0, nBits = WIN3264TEST(32,64);
	//AttachProcessType nType = apt_Unknown;
	wchar_t *psz;
	int iSel, iCur;
	DWORD nTID;
	HANDLE hThread = NULL;
	AttachParm *pParm = NULL;
	MArray<AttachParm> Parms;
	//HWND hAttachWnd = NULL;

	ShowWindow(mh_Dlg, SW_HIDE);

	BOOL bAlternativeMode = (IsDlgButtonChecked(mh_Dlg, IDC_ATTACH_ALT) != 0);

	iSel = ListView_GetNextItem(mh_List, -1, LVNI_SELECTED);
	while (iSel >= 0)
	{
		iCur = iSel;
		iSel = ListView_GetNextItem(mh_List, iCur, LVNI_SELECTED);

		AttachParm L = {NULL, 0, WIN3264TEST(32,64), apt_Unknown, bAlternativeMode};

		ListView_GetItemText(mh_List, iCur, alc_PID, szItem, countof(szItem)-1);
		L.nPID = wcstoul(szItem, &psz, 10);
		if (L.nPID)
		{
			psz = wcschr(szItem, L'[');
			if (!psz)
			{
				_ASSERTE(FALSE && "Process bitness was not detected?");
			}
			else
			{
				L.nBits = wcstoul(psz+1, &psz, 10);
			}
		}
		ListView_GetItemText(mh_List, iCur, alc_Type, szItem, countof(szItem));
		if (lstrcmp(szItem, szTypeCon) == 0)
			L.nType = apt_Console;
		else if (lstrcmp(szItem, szTypeGui) == 0)
			L.nType = apt_Gui;

		ListView_GetItemText(mh_List, iCur, alc_HWND, szItem, countof(szItem));
		L.hAttachWnd = (szItem[0]==L'0' && szItem[1]==L'x') ? (HWND)(DWORD_PTR)wcstoul(szItem+2, &psz, 16) : NULL;

		if (!L.nPID || !L.nBits || !L.nType || !L.hAttachWnd)
		{
			MBoxAssert(L.nPID && L.nBits && L.nType && L.hAttachWnd);
			goto wrap;
		}

		Parms.push_back(L);
	}

	if (Parms.empty())
	{
		goto wrap;
	}
	else
	{
		AttachParm N = {NULL};
		Parms.push_back(N);
	}

	//// Чтобы клик от мышки в консоль не провалился
	//WARNING("Клик от мышки в консоль проваливается");
	//gpConEmu->mouse.nSkipEvents[0] = WM_LBUTTONUP;
	//gpConEmu->mouse.nSkipEvents[1] = 0;
	//gpConEmu->mouse.nReplaceDblClk = 0;

	// Все, диалог закрываем, чтобы не мешался
	Close();

	// Работу делаем в фоновом потоке, чтобы не блокировать главный
	// (к окну ConEmu должна подцепиться новая вкладка)
	pParm = Parms.detach();
	if (!pParm)
	{
		_wsprintf(szItem, SKIPLEN(countof(szItem)) L"ConEmu Attach, PID=%u, TID=%u", GetCurrentProcessId(), GetCurrentThreadId());
		DisplayLastError(L"Parms.detach() failed", -1, 0, szItem);
		goto wrap;
	}
	else
	{
		hThread = apiCreateThread((LPTHREAD_START_ROUTINE)StartAttachThread, pParm, &nTID, "CAttachDlg::StartAttachThread#1");
		if (!hThread)
		{
			DWORD dwErr = GetLastError();
			_wsprintf(szItem, SKIPLEN(countof(szItem)) L"ConEmu Attach, PID=%u, TID=%u", GetCurrentProcessId(), GetCurrentThreadId());
			DisplayLastError(L"Can't start attach thread", dwErr, 0, szItem);
		}
		else
			lbRc = true;
	}
wrap:
	// We don't need this handle
	if (hThread)
		CloseHandle(hThread);

	return lbRc;
}
Example #4
0
// Supports MultiLine and SingleLine strings
// If there were no key_value or key_value_type is unexpected, DOESN'T touch *value
bool SettingsXML::Load(const wchar_t *regName, wchar_t **value) noexcept
{
	bool lbRc = false;
	SettingsXML::node *pChild = NULL;
	SettingsXML::node *pNode = NULL;
	const char *sType;
	size_t cchMax = 0;
	CEStrA data;
	LPCSTR pszData = nullptr;

	try
	{
		if (mp_Key)
			pChild = FindItem(mp_Key, L"value", regName, false);

		if (!pChild)
			return false;

		sType = GetAttr(pChild, "type");

		if (0 == _strcmpi(sType, "multi"))
		{
			//<value name="CmdLineHistory" type="multi">
			//	<line data="C:\Far\Far.exe"/>
			//	<line data="cmd"/>
			//</value>
			struct line_info { const char* str; size_t cchSize; };
			MArray<line_info> lines;

			for (pNode = pChild->first_node("line"); pNode; pNode = pNode->next_sibling("line"))
			{
				const char* lstr = GetAttr(pNode, "data");
				if (!lstr || !*lstr)
					lstr = " "; // Because of ASCIIZZ we must be sure there were no zero-length string
				size_t cchSize = strlen(lstr) + 1;
				cchMax += cchSize;
				lines.push_back({lstr, cchSize});
			}

			if (!lines.empty())
			{
				// ASCIIZ,ASCIIZ,...,ASCIIZ buffer
				if (char* buffer = data.getbuffer(cchMax))
				{
					for (INT_PTR i = 0; i < lines.size(); ++i)
					{
						const auto& line = lines[i];
						strcpy_s(buffer, line.cchSize, line.str);
						buffer += line.cchSize;
					}
					_ASSERTE(cchMax>=1 && data.ms_Val[cchMax-1]==0);
					pszData = data.c_str();
				}
			}
		}
		else if (0 == _strcmpi(sType, "string"))
		{
			pszData = GetAttr(pChild, "data");
			cchMax = pszData ? (strlen(pszData) + 1) : 0; // ASCIIZ
		}
		else
		{
			// We don't care about other data types, only strings here
		}

		// Data exist?
		if (pszData)
		{
			int cvt_size = MultiByteToWideChar(CP_UTF8, 0, pszData, cchMax, nullptr, 0);
			if (cvt_size > 0)
			{
				// Allocate data for ASCIIZZ (additional zero at the end)
				if ((*value = (wchar_t*)realloc(*value, (cvt_size + 1) * sizeof(**value))))
				{
					int cvt = MultiByteToWideChar(CP_UTF8, 0, pszData, cchMax, *value, cvt_size+1);
					_ASSERTE(cvt == cvt_size);
					if (cvt > 0)
					{
						_ASSERTE((*value)[cvt-1] == 0);
						(*value)[cvt] = 0; // ASCIIZZ
						lbRc = true;
					}
				}
			}
		}
	}
	catch (rapidxml::parse_error&)
	{
		// #XML Log error
		lbRc = false;
	}
	return lbRc;
}