// For example, mintty is terminated ‘abnormally’. It calls TerminateProcess instead of ExitProcess. BOOL WINAPI OnTerminateProcess(HANDLE hProcess, UINT uExitCode) { //typedef BOOL (WINAPI* OnTerminateProcess_t)(HANDLE hProcess, UINT uExitCode); ORIGINAL_KRNL(TerminateProcess); BOOL lbRc; if (hProcess == GetCurrentProcess()) { #ifdef PRINT_ON_EXITPROCESS_CALLS wchar_t szInfo[80]; _wsprintf(szInfo, SKIPCOUNT(szInfo) L"\n\x1B[1;31;40m::TerminateProcess(%u) called\x1B[m\n", uExitCode); WriteProcessed2(szInfo, lstrlen(szInfo), NULL, wps_Error); #endif gnDllState |= ds_OnTerminateProcess; // We don't need to do proper/full deinitialization, // because the process is to be terminated abnormally DoDllStop(false, ds_OnTerminateProcess); lbRc = F(TerminateProcess)(hProcess, uExitCode); } else { lbRc = F(TerminateProcess)(hProcess, uExitCode); } return lbRc; }
// May be called from "C" programs VOID WINAPI OnExitProcess(UINT uExitCode) { //typedef BOOL (WINAPI* OnExitProcess_t)(UINT uExitCode); ORIGINAL_KRNL(ExitProcess); #if 0 if (gbIsLessProcess) { _ASSERTE(FALSE && "Continue to ExitProcess"); } #endif gnDllState |= ds_OnExitProcess; #ifdef PRINT_ON_EXITPROCESS_CALLS wchar_t szInfo[80]; _wsprintf(szInfo, SKIPCOUNT(szInfo) L"\n\x1B[1;31;40m::ExitProcess(%u) called\x1B[m\n", uExitCode); WriteProcessed2(szInfo, lstrlen(szInfo), NULL, wps_Error); #endif // And terminate our threads DoDllStop(false, ds_OnExitProcess); bool bUseForceTerminate; // Issue 1865: Due to possible dead locks in LdrpAcquireLoaderLock() call TerminateProcess bUseForceTerminate = gbHookServerForcedTermination; #ifdef USE_GH_272_WORKAROUND // gh#272: For unknown yet reason existance of nvd3d9wrap.dll (or nvd3d9wrapx.dll on 64-bit) // caused stack overflow with following calls // // nvd3d9wrap!GetNVDisplayW+0x174f // nvd3d9wrap!GetNVDisplayW+0x174f // user32!_UserClientDllInitialize+0x2ca // ntdll!LdrpCallInitRoutine+0x14 // ntdll!LdrShutdownProcess+0x1aa // ntdll!RtlExitUserProcess+0x74 // kernel32!ExitProcessStub+0x12 // CallExit!main+0x47 if (!bUseForceTerminate && GetModuleHandle(WIN3264TEST(L"nvd3d9wrap.dll",L"nvd3d9wrapx.dll"))) { bUseForceTerminate = true; } #endif // USE_GH_272_WORKAROUND #ifdef FORCE_GH_272_WORKAROUND bUseForceTerminate = true; #endif if (bUseForceTerminate) { //CancelSynchronousIo(GetCurrentThread()); // -- VISTA //HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //FlushFileBuffers(hOut); //CloseHandle(hOut); ORIGINAL_KRNL(TerminateProcess); F(TerminateProcess)(GetCurrentProcess(), uExitCode); return; // Assume not to get here } F(ExitProcess)(uExitCode); }
/// Returns ThreadID of main thread /// /// If the process was started by standard ConEmuC/ConEmuHk functions, /// this function is called with (bUseCurrentAsMain==true) from DllMain. /// Otherwise we must enumerate **all** processes in system, there is no /// way to enumerate only current process threads unfortunately. /// Also, enumerating threads may cause noticeable lags, but we can't /// do anything with that... However, this is rare situation, and in most /// cases main thread ID is initialized with (bUseCurrentAsMain==true). DWORD GetMainThreadId(bool bUseCurrentAsMain) { // Найти ID основной нити if (!gnHookMainThreadId) { if (bUseCurrentAsMain) { // Only one thread is expected at the moment gnHookMainThreadId = GetCurrentThreadId(); } else { DWORD dwPID = GetCurrentProcessId(); #ifdef FORCE_GETMAINTHREAD_PRINTF wchar_t szInfo[160], szTail[32]; msprintf(szInfo, countof(szInfo), L"\x1B[1;31;40m" L"*** [PID=%u %s] GetMainThreadId is using CreateToolhelp32Snapshot", dwPID, gsExeName); wcscpy_c(szTail, L"\x1B[1;31;40m" L" ***" L"\x1B[0m" L"\n"); WriteProcessed2(szInfo, wcslen(szInfo), NULL, wps_Error); #endif // Unfortunately, dwPID is ignored in TH32CS_SNAPTHREAD HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwPID); if (snapshot != INVALID_HANDLE_VALUE) { THREADENTRY32 module = {sizeof(THREADENTRY32)}; if (Thread32First(snapshot, &module)) { // Don't stop enumeration on first thread, populate gStartedThreads do { if (module.th32OwnerProcessID == dwPID) { DWORD nTID = module.th32ThreadID; if (!gnHookMainThreadId) gnHookMainThreadId = nTID; if (!gStartedThreads.Get(nTID, NULL)) gStartedThreads.Set(nTID, FALSE); } } while (Thread32Next(snapshot, &module)); } CloseHandle(snapshot); } #ifdef FORCE_GETMAINTHREAD_PRINTF WriteProcessed2(szTail, wcslen(szTail), NULL, wps_Error); #endif } } #ifdef _DEBUG char szInfo[100]; msprintf(szInfo, countof(szInfo), "GetMainThreadId()=%u, TID=%u\n", gnHookMainThreadId, GetCurrentThreadId()); //OutputDebugStringA(szInfo); #endif _ASSERTE(gnHookMainThreadId!=0); return gnHookMainThreadId; }