Example #1
0
/*
================
rvDebuggerClient::HandleInspectThreads

Handle the message DBMSG_INSPECTTHREADS being sent from the server.  This message
is handled by adding the list of threads to a list for later lookup.
================
*/
void rvDebuggerClient::HandleInspectThreads ( msg_t* msg )
{
	int	count;

	ClearThreads ( );

	// Loop over the number of threads in the message	
	for ( count = (short)MSG_ReadShort ( msg ) ; count > 0; count -- )
	{
		rvDebuggerThread* entry = new rvDebuggerThread;
	
		char temp[1024];

		// Thread name
		MSG_ReadString ( msg, temp, 1024 );
		entry->mName = temp;

		// Thread ID
		entry->mID = MSG_ReadLong ( msg );

		// Thread state
		entry->mCurrent = MSG_ReadBits ( msg, 1 ) ? true : false;
		entry->mDoneProcessing = MSG_ReadBits ( msg, 1 ) ? true : false;
		entry->mWaiting = MSG_ReadBits ( msg, 1 ) ? true : false;
		entry->mDying = MSG_ReadBits ( msg, 1 ) ? true : false;

		// Add thread to list
		mThreads.Append ( entry );
	}
}
Example #2
0
void CDefaultTerminal::AutoClearThreads()
{
	if (!isMainThread())
		return;

	// Clear finished threads
	ClearThreads(false);
}
Example #3
0
CDefaultTerminal::~CDefaultTerminal()
{
	ClearThreads(true);

	ClearProcessed(true);

	DeleteCriticalSection(&mcs);

	//SafeCloseHandle(mh_SignEvent);
}
Example #4
0
// Проверка окна переднего плана. Если оно принадлежит к хукаемым процесса - вставить хук.
bool CDefaultTerminal::CheckForeground(HWND hFore, DWORD nForePID, bool bRunInThread /*= true*/)
{
	if (!isDefaultTerminalAllowed())
		return false;

	bool lbRc = false;
	bool lbLocked = false;
	bool lbConHostLocked;
	DWORD nResult = 0;
	wchar_t szClass[MAX_PATH]; szClass[0] = 0;
	PROCESSENTRY32 prc;
	bool bMonitored = false;
	const wchar_t* pszMonitored = NULL;
	HANDLE hProcess = NULL;
	//int nBits = 0;
	//wchar_t szCmdLine[MAX_PATH*3];
	//wchar_t szName[64];
	//PROCESS_INFORMATION pi = {};
	//STARTUPINFO si = {sizeof(si)};
	//BOOL bStarted = FALSE;
	DWORD nErrCode = 0;
	int iHookerRc = -1;

	// Если главное окно еще не создано
	if (!mb_ReadyToHook)
	{
		// Сразу выходим
		goto wrap;
	}

	//_ASSERTE(gpConEmu->isMainThread());
	if (!hFore || !nForePID)
	{
		_ASSERTE(hFore && nForePID);
		goto wrap;
	}

	if (hFore == mh_LastWnd || hFore == mh_LastIgnoredWnd)
	{
		// Это окно уже проверялось
		lbRc = (hFore == mh_LastWnd);
		goto wrap;
	}

	if (bRunInThread && (hFore == mh_LastCall))
	{
		// Просто выйти. Это проверка на частые фоновые вызовы.
		goto wrap;
	}
	mh_LastCall = hFore;

	if (bRunInThread)
	{
		if (gpConEmu->isMainThread())
		{
			// Clear finished threads
			ClearThreads(false);
		}

		HANDLE hPostThread = NULL; DWORD nThreadId = 0;
		ThreadArg* pArg = (ThreadArg*)malloc(sizeof(ThreadArg));
		if (!pArg)
		{
			_ASSERTE(pArg);
			goto wrap;
		}
		pArg->pTerm = this;
		pArg->hFore = hFore;
		pArg->nForePID = nForePID;

		hPostThread = CreateThread(NULL, 0, PostCheckThread, pArg, 0, &nThreadId);
		_ASSERTE(hPostThread!=NULL);
		if (hPostThread)
		{
			m_Threads.push_back(hPostThread);
		}

		lbRc = (hPostThread != NULL); // вернуть OK?
		goto wrap;
	}

	EnterCriticalSection(&mcs);
	lbLocked = true;

	// Clear dead processes and windows
	ClearProcessed(false);

	// Check window class
	if (GetClassName(hFore, szClass, countof(szClass)))
	{
		if ((lstrcmp(szClass, VirtualConsoleClass) == 0)
			//|| (lstrcmp(szClass, L"#32770") == 0) // Ignore dialogs // -- Process dialogs too (Application may be dialog-based)
			|| isConsoleClass(szClass))
		{
			mh_LastIgnoredWnd = hFore;
			goto wrap;
		}
	}

	// Go and check
	if (!GetProcessInfo(nForePID, &prc))
	{
		mh_LastIgnoredWnd = hFore;
		goto wrap;
	}

	CharLowerBuff(prc.szExeFile, lstrlen(prc.szExeFile));

	if (lstrcmp(prc.szExeFile, L"csrss.exe") == 0)
	{
		// This is "System" process and may not be hooked
		mh_LastIgnoredWnd = hFore;
		goto wrap;
	}

	// Is it in monitored applications?
	pszMonitored = gpSet->GetDefaultTerminalAppsMSZ();
	if (pszMonitored)
	{
		// All strings are lower case
		const wchar_t* psz = pszMonitored;
		while (*psz)
		{
			if (_tcscmp(psz, prc.szExeFile) == 0)
			{
				bMonitored = true;
				break;
			}
			psz += _tcslen(psz)+1;
		}
	}

	// And how it is?
	if (!bMonitored)
	{
		mh_LastIgnoredWnd = hFore;
		goto wrap;
	}

	// Need to process
	for (INT_PTR i = m_Processed.size(); i--;)
	{
		if (m_Processed[i].nPID == nForePID)
		{
			bMonitored = false;
			break; // already hooked
		}
	}

	// May be hooked already?
	if (!bMonitored)
	{
		mh_LastWnd = hFore;
		lbRc = true;
		goto wrap;
	}

	_ASSERTE(isDefaultTerminalAllowed());

	TODO("Show status in status line?");

	lbConHostLocked = gpConEmu->LockConhostStart();
	iHookerRc = StartDefTermHooker(nForePID, hProcess, nResult, gpConEmu->ms_ConEmuBaseDir, nErrCode);
	if (lbConHostLocked) gpConEmu->UnlockConhostStart();
	if (iHookerRc != 0)
	{
		mh_LastIgnoredWnd = hFore;
		if (iHookerRc == -3)
			DisplayLastError(L"Failed to start hooking application!\nDefault terminal feature will not be available!", nErrCode);
		goto wrap;
	}

	//hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|SYNCHRONIZE, FALSE, nForePID);
	//if (!hProcess)
	//{
	//	// Failed to hook
	//	mh_LastIgnoredWnd = hFore;
	//	goto wrap;
	//}

	//// Need to be hooked
	//nBits = GetProcessBits(nForePID, hProcess);
	//switch (nBits)
	//{
	//case 32:
	//	_wsprintf(szCmdLine, SKIPLEN(countof(szCmdLine)) L"\"%s\\%s\" /DEFTRM=%u",
	//		gpConEmu->ms_ConEmuBaseDir, L"ConEmuC.exe", nForePID);
	//	break;
	//case 64:
	//	_wsprintf(szCmdLine, SKIPLEN(countof(szCmdLine)) L"\"%s\\%s\" /DEFTRM=%u",
	//		gpConEmu->ms_ConEmuBaseDir, L"ConEmuC64.exe", nForePID);
	//	break;
	//}
	//if (!*szCmdLine)
	//{
	//	// Unsupported bitness?
	//	CloseHandle(hProcess);
	//	mh_LastIgnoredWnd = hFore;
	//	goto wrap;
	//}

	//// Prepare event
	//_wsprintf(szName, SKIPLEN(countof(szName)) CEDEFAULTTERMHOOK, nForePID);
	//SafeCloseHandle(mh_SignEvent);
	//mh_SignEvent = CreateEvent(LocalSecurity(), FALSE, FALSE, szName);
	//if (mh_SignEvent) SetEvent(mh_SignEvent); // May be excess, but if event already exists...

	//// Run hooker
	//si.dwFlags = STARTF_USESHOWWINDOW;
	//bStarted = CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	//if (!bStarted)
	//{
	//	DisplayLastError(L"Failed to start hooking application!\nDefault terminal feature will not be available!");
	//	CloseHandle(hProcess);
	//	mh_LastIgnoredWnd = hFore;
	//	goto wrap;
	//}
	//CloseHandle(pi.hThread);
	//// Waiting for result
	//WaitForSingleObject(pi.hProcess, INFINITE);
	//GetExitCodeProcess(pi.hProcess, &nResult);
	//CloseHandle(pi.hProcess);

	// And what?
	if ((nResult == (UINT)CERR_HOOKS_WAS_SET) || (nResult == (UINT)CERR_HOOKS_WAS_ALREADY_SET))
	{
		mh_LastWnd = hFore;
		ProcessInfo inf = {};
		inf.hProcess = hProcess;
		hProcess = NULL; // его закрывать НЕ нужно, сохранен в массиве
		inf.nPID = nForePID;
		//inf.bHooksSucceeded = (nResult == (UINT)CERR_HOOKS_WAS_ALREADY_SET);
		inf.nHookTick = GetTickCount();
		m_Processed.push_back(inf);
		lbRc = true;
		goto wrap;
	}
	// Failed, remember this
	CloseHandle(hProcess);
	mh_LastIgnoredWnd = hFore;
	_ASSERTE(lbRc == false);
wrap:
	if (lbLocked)
	{
		LeaveCriticalSection(&mcs);
	}
	return lbRc;
}
Example #5
0
void CDefaultTerminal::PostCreated(bool bWaitForReady /*= false*/, bool bShowErrors /*= false*/)
{
	if (!ghWnd)
	{
		// Main ConEmu window must be created
		// It is required for initialization of ConEmuHk.dll
		// wich will be injected into hooked processes
		_ASSERTE(ghWnd!=NULL);
		return;
	}

	mb_Initialized = true;

	if (!isDefaultTerminalAllowed())
	{
		_ASSERTE(bWaitForReady == false);
		if (bShowErrors && gpConEmu->DisableSetDefTerm)
		{
			DisplayLastError(L"Default terminal feature was blocked\n"
				L"with '/NoDefTerm' ConEmu command line argument!", -1);
		}
		return;
	}

	if (mb_PostCreatedThread)
	{
		if (!bShowErrors)
			return;
		ClearThreads(false);
		if (m_Threads.size() > 0)
		{
			Icon.ShowTrayIcon(L"Previous Default Terminal setup cycle was not finished yet", tsa_Default_Term);
			return;
		}
	}

	CheckRegisterOsStartup();

	mb_ReadyToHook = TRUE;

	// Этот процесс занимает некоторое время, чтобы не блокировать основной поток - запускаем фоновый
	mb_PostCreatedThread = true;
	DWORD  nWait = WAIT_FAILED;
	HANDLE hPostThread = CreateThread(NULL, 0, PostCreatedThread, this, 0, &mn_PostThreadId);
	
	if (hPostThread)
	{
		if (bWaitForReady)
		{
			// Wait for 30 seconds
			DWORD nStart = GetTickCount();
			SetCursor(LoadCursor(NULL, IDC_WAIT));
			nWait = WaitForSingleObject(hPostThread, 30000);
			SetCursor(LoadCursor(NULL, IDC_ARROW));
			DWORD nDuration = GetTickCount() - nStart;
			if (nWait == WAIT_OBJECT_0)
			{
				CloseHandle(hPostThread);
				return;
			}
			else
			{
				//_ASSERTE(nWait == WAIT_OBJECT_0);
				DisplayLastError(L"PostCreatedThread was not finished in 30 seconds");
				UNREFERENCED_PARAMETER(nDuration);
			}
		}

		m_Threads.push_back(hPostThread);
	}
	else
	{
		if (bShowErrors)
		{
			DisplayLastError(L"Failed to start PostCreatedThread");
		}
		_ASSERTE(hPostThread!=NULL);
		mb_PostCreatedThread = false;
	}
}
Example #6
0
	~JobSheduler_Impl()
	{
		ClearThreads();
	}
Example #7
0
/*
================
rvDebuggerClient::~rvDebuggerClient
================
*/
rvDebuggerClient::~rvDebuggerClient ( )
{
	ClearBreakpoints ( );	
	ClearCallstack ( );
	ClearThreads ( );
}