Exemple #1
0
HWND CDefTermHk::AllocHiddenConsole(bool bTempForVS)
{
	// функция AttachConsole есть только в WinXP и выше
	AttachConsole_t _AttachConsole = GetAttachConsoleProc();
	if (!_AttachConsole)
		return NULL;

	DefTermMsg(L"AllocHiddenConsole");

	ReloadSettings();
	_ASSERTEX(isDefaultTerminalEnabled() && (gbIsNetVsHost || bTempForVS));

	if (!isDefaultTerminalEnabled())
	{
		// Disabled in settings or registry
		return NULL;
	}

	HANDLE hSrvProcess = NULL;
	DWORD nAttachPID = bTempForVS ? 0 : gnSelfPID;
	DWORD nSrvPID = StartConsoleServer(nAttachPID, true, &hSrvProcess);
	if (!nSrvPID)
	{
		// Failed to start process?
		return NULL;
	}
	_ASSERTEX(hSrvProcess!=NULL);

	HWND hCreatedCon = NULL;

	// Do while server process is alive
	DWORD nStart = GetTickCount(), nMaxDelta = 30000, nDelta = 0;
	DWORD nWait = WaitForSingleObject(hSrvProcess, 0);
	while (nWait != WAIT_OBJECT_0)
	{
		if (_AttachConsole(nSrvPID))
		{
			hCreatedCon = GetRealConsoleWindow();
			if (hCreatedCon)
				break;
		}

		nWait = WaitForSingleObject(hSrvProcess, 150);

		nDelta = (GetTickCount() - nStart);
		if (nDelta > nMaxDelta)
			break;
	}

	return hCreatedCon;
}
Exemple #2
0
void CDefTermHk::OnAllocConsoleFinished()
{
	if (!gbPrepareDefaultTerminal || !this)
	{
		_ASSERTEX((gbPrepareDefaultTerminal && gpDefTerm) && "Must be called in DefTerm mode only");
		return;
	}

	if (!ghConWnd || !IsWindow(ghConWnd))
	{
		_ASSERTEX(FALSE && "ghConWnd must be initialized already!");
		return;
	}

	ReloadSettings();
	_ASSERTEX(isDefaultTerminalEnabled() && gbIsNetVsHost);

	if (!isDefaultTerminalEnabled())
	{
		// Disabled in settings or registry
		return;
	}

	// По идее, после AllocConsole окно RealConsole всегда видимо
	BOOL bConWasVisible = IsWindowVisible(ghConWnd);
	_ASSERTEX(bConWasVisible);
	// Чтобы минимизировать "мелькания" - сразу спрячем его
	ShowWindow(ghConWnd, SW_HIDE);
	DefTermMsg(L"Console window hided");

	if (!StartConsoleServer(gnSelfPID, false, NULL))
	{
		if (bConWasVisible)
			ShowWindow(ghConWnd, SW_SHOW);
		DefTermMsg(L"Starting attach server failed?");
	}
}
Exemple #3
0
BOOL WINAPI OnAllocConsole(void)
{
	//typedef BOOL (WINAPI* OnAllocConsole_t)(void);
	ORIGINALFAST(AllocConsole);
	BOOL lbRc = FALSE, lbAllocated = FALSE;
	COORD crLocked;
	HMODULE hKernel = NULL;
	DWORD nErrCode = 0;
	BOOL lbAttachRc = FALSE;
	HWND hOldConWnd = GetRealConsoleWindow();

	if (ph && ph->PreCallBack)
	{
		SETARGS(&lbRc);

		if (!ph->PreCallBack(&args))
			return lbRc;
	}

	if (gbPrepareDefaultTerminal && gbIsNetVsHost)
	{
		if (!ghConWnd)
			gnVsHostStartConsole = 2;
		else
			gnVsHostStartConsole = 0;
	}

	// Попытаться создать консольное окно "по тихому"
	if (gpDefTerm && !hOldConWnd && !gnServerPID)
	{
		HWND hCreatedCon = gpDefTerm->AllocHiddenConsole(false);
		if (hCreatedCon)
		{
			hOldConWnd = hCreatedCon;
			lbAllocated = TRUE;
		}
	}

	// GUI приложение во вкладке. Если окна консоли еще нет - попробовать прицепиться
	// к родительской консоли (консоли серверного процесса)
	if ((gbAttachGuiClient || ghAttachGuiClient) && !gbPrepareDefaultTerminal)
	{
		if (AttachServerConsole())
		{
			hOldConWnd = GetRealConsoleWindow();
			lbAllocated = TRUE; // Консоль уже есть, ничего не надо
		}
	}

	DefTermMsg(L"AllocConsole calling");

	if (!lbAllocated && F(AllocConsole))
	{
		lbRc = F(AllocConsole)();

		if (lbRc && !gbPrepareDefaultTerminal && IsVisibleRectLocked(crLocked))
		{
			// Размер _видимой_ области. Консольным приложениям запрещено менять его "изнутри".
			// Размер может менять только пользователь ресайзом окна ConEmu
			HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
			CONSOLE_SCREEN_BUFFER_INFO csbi = {};
			if (GetConsoleScreenBufferInfo(hStdOut, &csbi))
			{
				//specified width and height cannot be less than the width and height of the console screen buffer's window
				SMALL_RECT rNewRect = {0, 0, crLocked.X-1, crLocked.Y-1};
				OnSetConsoleWindowInfo(hStdOut, TRUE, &rNewRect);
				#ifdef _DEBUG
				COORD crNewSize = {crLocked.X, max(crLocked.Y, csbi.dwSize.Y)};
				#endif
				hkFunc.setConsoleScreenBufferSize(hStdOut, crLocked);
			}
		}
	}

	//InitializeConsoleInputSemaphore();

	if (ph && ph->PostCallBack)
	{
		SETARGS(&lbRc);
		ph->PostCallBack(&args);
	}

	HWND hNewConWnd = GetRealConsoleWindow();

	// Обновить ghConWnd и мэппинг
	OnConWndChanged(hNewConWnd);

	#ifdef _DEBUG
	//_ASSERTEX(lbRc && ghConWnd);
	wchar_t szAlloc[500], szFile[MAX_PATH];
	GetModuleFileName(NULL, szFile, countof(szFile));
	msprintf(szAlloc, countof(szAlloc), L"OnAllocConsole\nOld=x%08X, New=x%08X, ghConWnd=x%08X\ngbPrepareDefaultTerminal=%i, gbIsNetVsHost=%i\n%s",
		LODWORD(hOldConWnd), LODWORD(hNewConWnd), LODWORD(ghConWnd), gbPrepareDefaultTerminal, gbIsNetVsHost, szFile);
	// VisualStudio host file calls AllocConsole TWICE(!)
	// Second call is totally spare (console already created)
	//MessageBox(NULL, szAlloc, L"OnAllocConsole called", MB_SYSTEMMODAL);
	#endif

	if (hNewConWnd && (hNewConWnd != hOldConWnd) && gpDefTerm && gbIsNetVsHost)
	{
		DefTermMsg(L"Calling gpDefTerm->OnAllocConsoleFinished");
		gpDefTerm->OnAllocConsoleFinished();
		SetLastError(0);
	}
	else if (hNewConWnd)
	{
		DefTermMsg(L"Console was already allocated");
	}
	else
	{
		DefTermMsg(L"Something was wrong");
	}

	TODO("Можно бы по настройке установить параметры. Кодовую страницу, например");

	return lbRc;
}
Exemple #4
0
void CDefTermHk::ShowTrayIconError(LPCWSTR asErrText)
{
	LogHookingStatus(asErrText);
	DefTermMsg(asErrText);
}
Exemple #5
0
BOOL WINAPI OnShowWindow(HWND hWnd, int nCmdShow)
{
	//typedef BOOL (WINAPI* OnShowWindow_t)(HWND hWnd, int nCmdShow);
	ORIGINAL_EX(ShowWindow);
	BOOL lbRc = FALSE, lbGuiAttach = FALSE, lbInactiveTab = FALSE;
	static bool bShowWndCalled = false;

	if (gbPrepareDefaultTerminal && ghConWnd && (hWnd == ghConWnd) && nCmdShow && (gnVsHostStartConsole > 0))
	{
		DefTermMsg(L"ShowWindow(hConWnd) calling");
		nCmdShow = SW_HIDE;
		gnVsHostStartConsole--;
	}

	if (ghConEmuWndDC && (hWnd == ghConEmuWndDC || hWnd == ghConWnd))
	{
		#ifdef _DEBUG
		if (hWnd == ghConEmuWndDC)
		{
			static bool bShowWarned = false;
			if (!bShowWarned) { bShowWarned = true; _ASSERTE(hWnd != ghConEmuWndDC && L"OnShowWindow(ghConEmuWndDC)"); }
		}
		else
		{
			static bool bShowWarned = false;
			if (!bShowWarned) { bShowWarned = true; _ASSERTE(hWnd != ghConEmuWndDC && L"OnShowWindow(ghConWnd)"); }
		}
		#endif
		return TRUE; // обманем
	}

	if ((ghAttachGuiClient == hWnd) || (!ghAttachGuiClient && gbAttachGuiClient))
		OnShowGuiClientWindow(hWnd, nCmdShow, lbGuiAttach, lbInactiveTab);

	if (F(ShowWindow))
	{
		lbRc = F(ShowWindow)(hWnd, nCmdShow);
		// Первый вызов может быть обломным, из-за того, что корневой процесс
		// запускается с wShowCmd=SW_HIDE (чтобы не мелькал)
		if (!bShowWndCalled)
		{
			bShowWndCalled = true;
			if (!lbRc && nCmdShow && !IsWindowVisible(hWnd))
			{
				F(ShowWindow)(hWnd, nCmdShow);
			}
		}

		// Если вкладка НЕ активная - то вернуть фокус в ConEmu
		if (lbGuiAttach && lbInactiveTab && nCmdShow && ghConEmuWnd)
		{
			SetForegroundWindow(ghConEmuWnd);
		}
	}
	DWORD dwErr = GetLastError();

	if (lbGuiAttach)
		OnPostShowGuiClientWindow(hWnd, nCmdShow);

	SetLastError(dwErr);
	return lbRc;
}
Exemple #6
0
void CDefTermHk::ShowTrayIconError(LPCWSTR asErrText)
{
	DefTermMsg(asErrText);
}
Exemple #7
0
int CDefTermHk::DisplayLastError(LPCWSTR asLabel, DWORD dwError/*=0*/, DWORD dwMsgFlags/*=0*/, LPCWSTR asTitle/*=NULL*/, HWND hParent/*=NULL*/)
{
	DefTermMsg(asLabel);
	return 0;
}