/* ================ 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 ); } }
void CDefaultTerminal::AutoClearThreads() { if (!isMainThread()) return; // Clear finished threads ClearThreads(false); }
CDefaultTerminal::~CDefaultTerminal() { ClearThreads(true); ClearProcessed(true); DeleteCriticalSection(&mcs); //SafeCloseHandle(mh_SignEvent); }
// Проверка окна переднего плана. Если оно принадлежит к хукаемым процесса - вставить хук. 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; }
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; } }
~JobSheduler_Impl() { ClearThreads(); }
/* ================ rvDebuggerClient::~rvDebuggerClient ================ */ rvDebuggerClient::~rvDebuggerClient ( ) { ClearBreakpoints ( ); ClearCallstack ( ); ClearThreads ( ); }