static inline void write_thread_traces(struct exception_handler_data *data) { THREADENTRY32 entry = {0}; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); bool success; if (snapshot == INVALID_HANDLE_VALUE) return; entry.dwSize = sizeof(entry); success = !!Thread32First(snapshot, &entry); while (success) { write_thread_trace(data, &entry, true); success = !!Thread32Next(snapshot, &entry); } success = !!Thread32First(snapshot, &entry); while (success) { write_thread_trace(data, &entry, false); success = !!Thread32Next(snapshot, &entry); } CloseHandle(snapshot); }
/** * Returns a std::vector<DWORD> of all thread IDs for a given process. * * If pid is 0 (the default) your current process ID is used. */ std::vector<unsigned long> get_thread_ids(unsigned long pid = 0) { std::vector<DWORD> threadIds; THREADENTRY32 threadEntry; threadEntry.dwSize = sizeof(THREADENTRY32); // if not specified, default to THIS process if (!pid) pid = GetCurrentProcessId(); // toolhelp: m$ft's most poorly named library? HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if(snapshot == INVALID_HANDLE_VALUE) return threadIds; if(!Thread32First(snapshot, &threadEntry)) { fprintf(stderr, "Thread32First: err code %d", GetLastError()); CloseHandle(snapshot); return threadIds; } // find all threads matching pid do { if (threadEntry.th32OwnerProcessID == pid) threadIds.push_back(threadEntry.th32ThreadID); } while(Thread32Next(snapshot, &threadEntry)); CloseHandle(snapshot); return threadIds; }
void SeeThreadDlg::initThreadList() { //遍历所有的thread; // SetWindowText(m_StrThread); THREADENTRY32 thd32={sizeof(THREADENTRY32)}; HANDLE hThreadsnap; hThreadsnap=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD ,m_currPid); if (hThreadsnap==INVALID_HANDLE_VALUE) { return; } if (!Thread32First(hThreadsnap,&thd32)) { CloseHandle(hThreadsnap); return; } m_VecThdList.clear(); do { _stprintf_s(strThreadId,_T("%d"),thd32.th32ThreadID); m_ThreadList.InsertItem(0,strThreadId); m_VecThdList.push_back(thd32); } while (Thread32Next(hThreadsnap,&thd32)); CloseHandle(hThreadsnap); }
// Obtain the process and thread identifiers of the parent process. BOOL GetParentProcessInfo( LPPROCESS_INFORMATION ppi ) { HANDLE hSnap; PROCESSENTRY32 pe; THREADENTRY32 te; DWORD id = GetCurrentProcessId(); BOOL fOk; hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD, id ); if (hSnap == INVALID_HANDLE_VALUE) return FALSE; find_proc_id( hSnap, id, &pe ); if (!find_proc_id( hSnap, pe.th32ParentProcessID, &pe )) { CloseHandle( hSnap ); return FALSE; } te.dwSize = sizeof(te); for (fOk = Thread32First( hSnap, &te ); fOk; fOk = Thread32Next( hSnap, &te )) if (te.th32OwnerProcessID == pe.th32ProcessID) break; CloseHandle( hSnap ); ppi->dwProcessId = pe.th32ProcessID; ppi->dwThreadId = te.th32ThreadID; return fOk; }
DWORD GetMainThreadId() { DWORD dwCurProcessId = GetCurrentProcessId(); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwCurProcessId); if(hSnapshot == INVALID_HANDLE_VALUE) { return 0; } THREADENTRY32 te; te.dwSize=sizeof(THREADENTRY32); BOOL fOk=Thread32First(hSnapshot,&te); for(;fOk;){ //the second parameter of CreateToolhelp32Snapshot will not work,so I have to enum //all Process if (te.th32OwnerProcessID == dwCurProcessId) { //found process if (te.th32ThreadID!=0) { return te.th32ThreadID; } } fOk=Thread32Next(hSnapshot,&te); } return 0; }
AIDLIB_API std::set<DWORD> GetProcessThreads(const DWORD processId) { TRY_CATCH std::set<DWORD> threads; CScopedTracker<HANDLE> threadSnap; // Retriving threads snapshot threadSnap.reset(CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, processId),CloseHandle); Log.Add(_MESSAGE_,_T("Retriving threads for process(%d), with handle(%d)"), processId, threadSnap.get()); if (INVALID_HANDLE_VALUE == threadSnap) throw MCException_Win("Failed to CreateToolhelp32Snapshot"); // Enumerating threads THREADENTRY32 threadEntry = {0}; threadEntry.dwSize = sizeof(THREADENTRY32); if(Thread32First(threadSnap, &threadEntry)) { do { if (processId == threadEntry.th32OwnerProcessID) threads.insert(threadEntry.th32ThreadID); threadEntry.dwSize = sizeof(THREADENTRY32); threadEntry.th32ThreadID = 0; } while(Thread32Next(threadSnap, &threadEntry)); } else throw MCException_Win("Failed to Thread32First"); return threads; CATCH_THROW() }
vector<THREADENTRY32> CProcessTool::GetProcessThreads(DWORD dwOwnerPID) { HANDLE hThreadSnap = INVALID_HANDLE_VALUE; THREADENTRY32 te32; VCTTHREAD vctThread; memset(&te32,0,sizeof(te32)); hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); if(hThreadSnap == INVALID_HANDLE_VALUE) return vctThread; te32.dwSize = sizeof(THREADENTRY32); if(!Thread32First(hThreadSnap,&te32)) { LOG::printError(TEXT("Thread32First")); CloseHandle(hThreadSnap); return vctThread; } do { if(te32.th32OwnerProcessID == dwOwnerPID) { vctThread.push_back(te32); } } while (Thread32Next(hThreadSnap,&te32)); CloseHandle(hThreadSnap); return vctThread; }
static BOOL resume_process (DWORD dwOwnerPID) { HANDLE hThreadSnap = NULL; BOOL bRet = FALSE; THREADENTRY32 te32 = { 0 }; hThreadSnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0); if (hThreadSnap == INVALID_HANDLE_VALUE) return FALSE; te32.dwSize = sizeof (THREADENTRY32); if (Thread32First (hThreadSnap, &te32)) { do { if (te32.th32OwnerProcessID == dwOwnerPID) { HANDLE hThread = OpenThread (THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID); printf ("Resuming Thread: %u\n",te32.th32ThreadID); ResumeThread (hThread); CloseHandle (hThread); } } while (Thread32Next (hThreadSnap, &te32)); bRet = TRUE; } else bRet = FALSE; CloseHandle (hThreadSnap); return bRet; }
short GetOneThreadID(short nPID) { HANDLE hThreadSnap = NULL; THREADENTRY32 te32 = {0}; hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hThreadSnap == INVALID_HANDLE_VALUE) return 0; memset(&te32, 0, sizeof(THREADENTRY32)); te32.dwSize = sizeof(THREADENTRY32); if( Thread32First( hThreadSnap, &te32 ) ) { do { if (te32.th32ThreadID && te32.th32OwnerProcessID == nPID) { CloseHandle (hThreadSnap); return te32.th32ThreadID; } } while ( Thread32Next( hThreadSnap, &te32 ) ); } CloseHandle (hThreadSnap); return 0; }
PDWORD enumerate_threads() { temp_var = 0; thread_entry = THREADENTRY32(); snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid); if (snapshot != NULL) { thread_entry.dwSize = sizeof(thread_entry); success = Thread32First(snapshot, &thread_entry); while (success) { if (thread_entry.th32OwnerProcessID == pid) { thread_list[temp_var++] = thread_entry.th32ThreadID; } success = Thread32Next(snapshot, &thread_entry); } thread_list[temp_var] = ENT_OF_THREAD_LIST; // end of the thread_list CloseHandle(snapshot); return thread_list; } else { std::cout << "[!] enumerate_threads() error" << std::endl; return false; } }
/* * GetNextThread - * NB - callers must continue to call this function until it returns FALSE */ BOOL GetNextThread( ThreadList *info, ThreadPlace *place, DWORD pid, BOOL first ) { BOOL noerror; noerror = FALSE; if( first ) { place->thrddata = MemAlloc( sizeof( THREADENTRY32 ) ); memset( place->thrddata, 0, sizeof( THREADENTRY32 ) ); place->thrddata->dwSize = sizeof( THREADENTRY32 ); place->hdl = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); noerror = Thread32First( place->hdl, place->thrddata ); if( noerror ) { place->pid = pid; } } else { noerror = Thread32Next( place->hdl, place->thrddata ); } while( noerror ) { if( pid == place->thrddata->th32OwnerProcessID ) break; noerror = Thread32Next( place->hdl, place->thrddata ); } if( noerror ) { info->tid = place->thrddata->th32ThreadID; info->priority = place->thrddata->tpBasePri + place->thrddata->tpDeltaPri; } if( !noerror ) { CloseHandle( place->hdl ); MemFree( place->thrddata ); } return( noerror ); }
//----------------------------------------------------------------------------- // 初始化 bool C_ThreadList::Initialize(IN unsigned long ulProcessID) { m_Thread.clear(); C_WHandle ccSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); // 取得處理程序中執行緒的快照 if(ccSnap == INVALID_HANDLE_VALUE) return C_NOutput::Instance().Error(ERRORNSTD, C_ErrorWin(), __T("CreateToolhelp32Snapshot failed")); THREADENTRY32 sThread; ZeroMemory(&sThread, sizeof(sThread)); sThread.dwSize = sizeof(sThread); // 取得第一個執行緒列表資訊 if(Thread32First(static_cast<HANDLE>(ccSnap), &sThread) == FALSE) return C_NOutput::Instance().Error(ERRORNSTD, C_ErrorWin(), __T("Thread32First failed")); // 依序取得執行緒列表資訊 do { // 檢查此執行緒資訊是否屬於輸入的處理程序 if(sThread.th32OwnerProcessID == ulProcessID) m_Thread.push_back(S_Thread(sThread)); } while(Thread32Next(static_cast<HANDLE>(ccSnap), &sThread) == TRUE); return true; }
/// <summary> /// Gets all process threads /// </summary> /// <param name="dontUpdate">Return already existing thread list</param> /// <returns>Threads collection</returns> std::vector<Thread>& ProcessThreads::getAll( bool dontUpdate /*= false*/ ) { if (dontUpdate) return _threads; HANDLE hThreadSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); _threads.clear(); if (hThreadSnapshot != INVALID_HANDLE_VALUE) { THREADENTRY32 tEntry = { 0 }; tEntry.dwSize = sizeof(THREADENTRY32); // Iterate threads for (BOOL success = Thread32First( hThreadSnapshot, &tEntry ); success == TRUE; success = Thread32Next( hThreadSnapshot, &tEntry )) { if (tEntry.th32OwnerProcessID != _core.pid()) continue; _threads.emplace_back( Thread( tEntry.th32ThreadID, &_core ) ); } CloseHandle( hThreadSnapshot ); } return _threads; }
void runner::enumerate_threads_(std::function<void(handle_t)> on_thread) { if (!is_running()) { return; } HANDLE thread_snapshot_h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (thread_snapshot_h == handle_default_value) { return; } THREADENTRY32 thread_entry; thread_entry.dwSize = sizeof(thread_entry); if (!Thread32First(thread_snapshot_h, &thread_entry)) { return; } do { if (thread_entry.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(thread_entry.th32OwnerProcessID) && thread_entry.th32OwnerProcessID == process_info.dwProcessId) { handle_t handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_entry.th32ThreadID); if (on_thread) { on_thread(handle); } CloseHandle(handle); } thread_entry.dwSize = sizeof(thread_entry); } while (Thread32Next(thread_snapshot_h, &thread_entry)); CloseHandle(thread_snapshot_h); }
// Плагин может быть вызван в первый раз из фоновой нити (диалог поиска при поиске в архивах) // Поэтому простой "gnMainThreadId = GetCurrentThreadId();" не прокатит. Нужно искать первую нить процесса! DWORD GetMainThreadId() { DWORD nThreadID = 0; DWORD nProcID = GetCurrentProcessId(); HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (h != INVALID_HANDLE_VALUE) { THREADENTRY32 ti = {sizeof(THREADENTRY32)}; if (Thread32First(h, &ti)) { do { // Нужно найти ПЕРВУЮ нить процесса if (ti.th32OwnerProcessID == nProcID) { nThreadID = ti.th32ThreadID; break; } } while (Thread32Next(h, &ti)); } CloseHandle(h); } // Нехорошо. Должна быть найдена. Вернем хоть что-то (текущую нить) if (!nThreadID) { _ASSERTE(nThreadID!=0); nThreadID = GetCurrentThreadId(); } return nThreadID; }
BOOL ResumeProcess(LPCTSTR lpszProcName, DWORD dwExceptThdId = -1) { THREADENTRY32 th32; th32.dwSize = sizeof(th32); BOOL bRet = TRUE; DWORD dwPid = ScanProcess(lpszProcName); if (0 == dwPid) return FALSE; HANDLE hThreadSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); if( INVALID_HANDLE_VALUE != hThreadSnap ) { if ( Thread32First(hThreadSnap, &th32) ) { do { if(th32.th32OwnerProcessID == dwPid && th32.th32ThreadID != dwExceptThdId) { DWORD dwCount = 0; HANDLE oth = OpenThread (THREAD_ALL_ACCESS,FALSE,th32.th32ThreadID); while( (dwCount = ::ResumeThread(oth)) > 0); CloseHandle(oth); } }while(::Thread32Next(hThreadSnap,&th32)); } else bRet = FALSE; } else bRet = FALSE; ::CloseHandle(hThreadSnap); return bRet; }
void SetThreadsState(bool Resume) { HANDLE h, hThread; DWORD CurrTh, CurrPr; THREADENTRY32 Thread; CurrTh = GetCurrentThreadId(); CurrPr = GetCurrentProcessId(); h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (h != INVALID_HANDLE_VALUE) { Thread.dwSize = sizeof(THREADENTRY32); Thread32First(h, &Thread); do { if (Thread.th32ThreadID != CurrTh && Thread.th32OwnerProcessID == CurrPr) { hThread = OpenThread(THREAD_SUSPEND_RESUME, false, Thread.th32ThreadID); if (hThread != INVALID_HANDLE_VALUE) { if (Resume) ResumeThread(hThread); else SuspendThread(hThread); CloseHandle(hThread); } } } while (Thread32Next(h, &Thread)); CloseHandle(h); } }
void PauseResumeThreadList( bool bResumeThread ) { if (hProcess == NULL) return; DWORD dwOwnerPID = GetProcessId(hProcess); HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hThreadSnap == INVALID_HANDLE_VALUE) return; THREADENTRY32 te32; ZeroMemory(&te32,sizeof(te32)); te32.dwSize = sizeof(THREADENTRY32); BOOL MoreThreads = Thread32First(hThreadSnap, &te32); while (MoreThreads) { if (te32.th32OwnerProcessID == dwOwnerPID) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID); if (bResumeThread) ResumeThread(hThread); else SuspendThread(hThread); CloseHandle(hThread); } MoreThreads = Thread32Next(hThreadSnap, &te32); } CloseHandle (hThreadSnap); }
void SimpleCounterWorker::updateThreadList() { // now enum all threads for this processId if (loopCounter) { HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid); // FIXME [avlechen] Strategy for exeptions is not defined if (hSnap == INVALID_HANDLE_VALUE) { DWORD exitCode = 0; if (GetExitCodeProcess(hProcess, &exitCode)) { if (exitCode != STILL_ACTIVE) { // FIXME [avlechen] Target program exited with code 0x%08x, exitCode; } } else { // FIXME [avlechen] CreateToolhelp32Snapshot failed with error code 0x%08x, GetLastError() } } threads.clear(); THREADENTRY32 te; memset(&te, 0, sizeof(te)); te.dwSize = sizeof(te); while (Thread32First(hSnap, &te) == FALSE) { if (te.th32OwnerProcessID == pid) { threads.push_back(te); } } // TODO [avlechen]: Possibly, we should store hSnap during sampling CloseHandle(hSnap); } loopCounter++; }
HRESULT fSuspendThreadsInProcessById(DWORD dwProcessId) { HANDLE hThreadSnapshot; HRESULT hResult = fGetSnapshot(TH32CS_SNAPTHREAD, 0, hThreadSnapshot); if (SUCCEEDED(hResult)) { THREADENTRY32 oThreadEntry32; oThreadEntry32.dwSize = sizeof(oThreadEntry32); if (!Thread32First(hThreadSnapshot, &oThreadEntry32)) { _tprintf(_T("Cannot get first thread from snapshot\r\n")); hResult = HRESULT_FROM_WIN32(GetLastError()); } else do { if (oThreadEntry32.th32OwnerProcessID == dwProcessId) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, oThreadEntry32.th32ThreadID); if (!hThread) { _tprintf(_T("Cannot open thread %d of process %d"), oThreadEntry32.th32ThreadID, oThreadEntry32.th32OwnerProcessID); hResult = HRESULT_FROM_WIN32(GetLastError()); } else { if (SuspendThread(hThread) == -1) { _tprintf(_T("Cannot suspend thread %d of process %d"), oThreadEntry32.th32ThreadID, oThreadEntry32.th32OwnerProcessID); hResult = HRESULT_FROM_WIN32(GetLastError()); } if (!fCloseHandleAndUpdateResult(hThread, hResult)) { _tprintf(_T("Cannot close thread %d of process %d\r\n"), oThreadEntry32.th32ThreadID, oThreadEntry32.th32OwnerProcessID); } } } } while (SUCCEEDED(hResult) && Thread32Next(hThreadSnapshot, &oThreadEntry32)); if (!fCloseHandleAndUpdateResult(hThreadSnapshot, hResult)) { _tprintf(_T("Cannot close snapshot\r\n")); } } return hResult; }
void SuspendTask(const DWORD Pid)//挂起一个进程中的所有线程 { THREADENTRY32 th32; th32.dwSize=sizeof(th32);//指定结构的长度,以字节为单位。在调用Thread32First时,设置这个成员为SIZEOF(THREADENTRY32)。如果你不初始化的dwSize,Thread32First将调用失败。 HANDLE hThreadSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); //CreateToolhelp32Snapshot可以通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。 if(hThreadSnap==INVALID_HANDLE_VALUE) { //AfxMessageBox(_T("CreateToolhelp32Snapshot调用失败!")); return; } bool more=Thread32First(hThreadSnap,&th32); while(more) { if(th32.th32OwnerProcessID==Pid) { HANDLE oth=OpenThread(THREAD_ALL_ACCESS,FALSE,th32.th32ThreadID); if(!(::SuspendThread(oth))<=0) { //MessageBox(0,_T("冻结失败"),0,0); } else { //MessageBox(0,_T("已冻结!"),0,0); } CloseHandle(oth); } more=Thread32Next(hThreadSnap,&th32);//hTreadSnap快照句柄 } CloseHandle(hThreadSnap); }
void ResumeTask(DWORD Pid)//恢复一个进程中的所有线程 { THREADENTRY32 th32; th32.dwSize=sizeof(th32); HANDLE hThreadSnap=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); if(hThreadSnap==INVALID_HANDLE_VALUE) { //AfxMessageBox(_T("CreateToolhelp32Snapshot调用失败!")); return; } bool more=Thread32First(hThreadSnap,&th32); while(more) { if(th32.th32OwnerProcessID==Pid) { HANDLE oth=OpenThread(THREAD_ALL_ACCESS,FALSE,th32.th32ThreadID); if(!(::ResumeThread(oth))<0) { //MessageBox(0,_T("解冻失败"),0,0); } else { //MessageBox(0,_T("已 解冻!"),0,0); } CloseHandle(oth); } more=Thread32Next(hThreadSnap,&th32);//hTreadSnap快照句柄 } CloseHandle(hThreadSnap); }
vector<Thread> Process::threads(bool inheritHandle, DWORD desiredAccess) const { vector<Thread> threads_; HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, id()); if (h != INVALID_HANDLE_VALUE) { THREADENTRY32 te; te.dwSize = sizeof(te); if (Thread32First(h, &te)) { do { if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) { if (te.th32OwnerProcessID == id()) { try { threads_.push_back(Thread::open(te.th32ThreadID, inheritHandle, desiredAccess)); } catch (...) { // if the process is running, threads may have terminated } } } te.dwSize = sizeof(te); } while (Thread32Next(h, &te)); } CloseHandle(h); } return threads_; }
static BOOL SupendProcess(DWORD dwPid, DWORD dwExceptThdId = -1) { THREADENTRY32 th32; th32.dwSize = sizeof(th32); BOOL bRet = TRUE; if (0 <= dwPid) return FALSE; HANDLE hThreadSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0); if( INVALID_HANDLE_VALUE != hThreadSnap ) { if ( Thread32First(hThreadSnap, &th32) ) { do { if(th32.th32OwnerProcessID == dwPid && th32.th32ThreadID != dwExceptThdId) { HANDLE oth = OpenThread (THREAD_ALL_ACCESS,FALSE,th32.th32ThreadID); if(-1 == (::SuspendThread(oth))) { bRet = FALSE; } CloseHandle(oth); } }while(::Thread32Next(hThreadSnap,&th32)); } else bRet = FALSE; } else bRet = FALSE; ::CloseHandle(hThreadSnap); return bRet; }
int oLaucher::PauseProcess(DWORD pid) { HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, pid); THREADENTRY32 thrdEntry; thrdEntry.dwSize = sizeof(thrdEntry); Thread32First(hSnap, &thrdEntry); do { if(thrdEntry.th32OwnerProcessID==pid) { HANDLE hThrd = OpenThread(THREAD_ALL_ACCESS, FALSE, thrdEntry.th32ThreadID); SuspendThread(hThrd); CloseHandle(hThrd); } } while(Thread32Next(hSnap, &thrdEntry)); CloseHandle(hSnap); return 0; }
/* * GetThreadInfo */ BOOL GetThreadInfo( DWORD pid, DWORD tid, ThreadStats *info ) { BOOL noerror; HANDLE hdl; THREADENTRY32 thrddata; noerror = FALSE; memset( &thrddata, 0, sizeof( THREADENTRY32 ) ); thrddata.dwSize = sizeof( THREADENTRY32 ); hdl = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); noerror = Thread32First( hdl, &thrddata ); while( noerror ) { if( tid == thrddata.th32ThreadID ) { if( pid == thrddata.th32OwnerProcessID ) { break; } } noerror = Thread32Next( hdl, &thrddata ); } if( noerror ) { info->tid = tid; info->pid = pid; info->base_pri = thrddata.tpBasePri; info->cur_pri = thrddata.tpBasePri + thrddata.tpDeltaPri; info->state = -1; info->wait_reason = -1; } CloseHandle( hdl ); return( noerror ); }
/* * Returns a list of thread identifiers that are running in the context of the * supplied process. * * req: TLV_TYPE_PID - The process identifier to operate on */ DWORD request_sys_process_thread_get_threads(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); THREADENTRY32 entry; HANDLE th32 = NULL; DWORD result = ERROR_SUCCESS; DWORD processId; processId = packet_get_tlv_value_uint(packet, TLV_TYPE_PID); do { // Validate the process identifier if (!processId) { result = ERROR_INVALID_PARAMETER; break; } // Get a snapshot of the threads running in the supplied process if (!(th32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, processId))) { result = GetLastError(); break; } entry.dwSize = sizeof(entry); // If the first enumeration fails, see why if (Thread32First(th32, &entry)) { // Keep looping until there are no more threads do { if (entry.th32OwnerProcessID != processId) continue; packet_add_tlv_uint(response, TLV_TYPE_THREAD_ID, entry.th32ThreadID); } while (Thread32Next(th32, &entry)); } // If we did not reach the end of the enumeration cleanly, something // stupid happened if (GetLastError() != ERROR_NO_MORE_FILES) { result = GetLastError(); break; } } while (0); packet_transmit_response(result, remote, response); // Cleanup if (th32) CloseHandle(th32); return ERROR_SUCCESS; }
BOOL WINAPI EnumThread(ThreadVisitor& visitor) { HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL); THREADENTRY32 te = { sizeof(THREADENTRY32), 0 }; if (hSnap == INVALID_HANDLE_VALUE) return FALSE; if (!Thread32First(hSnap, &te)) { CloseHandle(hSnap); return FALSE; } do { try { if (!visitor.visit(te)) break; } catch (...) { CloseHandle(hSnap); return FALSE; } } while (Thread32Next(hSnap, &te)); CloseHandle(hSnap); return TRUE; }
/****************************************************************** * backtrace_all * * Do a backtrace on every running thread in the system (except the debugger) * (preserves current process information) */ static void backtrace_all(void) { struct dbg_process* process = dbg_curr_process; struct dbg_thread* thread = dbg_curr_thread; CONTEXT ctx = dbg_context; DWORD cpid = dbg_curr_pid; THREADENTRY32 entry; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (snapshot == INVALID_HANDLE_VALUE) { dbg_printf("Unable to create toolhelp snapshot\n"); return; } entry.dwSize = sizeof(entry); if (Thread32First(snapshot, &entry)) { do { if (entry.th32OwnerProcessID == GetCurrentProcessId()) continue; if (dbg_curr_process && dbg_curr_pid != entry.th32OwnerProcessID && cpid != dbg_curr_pid) dbg_curr_process->process_io->close_process(dbg_curr_process, FALSE); if (entry.th32OwnerProcessID == cpid) { dbg_curr_process = process; dbg_curr_pid = cpid; } else if (entry.th32OwnerProcessID != dbg_curr_pid) { if (!dbg_attach_debuggee(entry.th32OwnerProcessID, FALSE)) { dbg_printf("\nwarning: could not attach to %04x\n", entry.th32OwnerProcessID); continue; } dbg_curr_pid = dbg_curr_process->pid; dbg_active_wait_for_first_exception(); } dbg_printf("\nBacktracing for thread %04x in process %04lx (%s):\n", entry.th32ThreadID, dbg_curr_pid, dbg_W2A(dbg_curr_process->imageName, -1)); backtrace_tid(dbg_curr_process, entry.th32ThreadID); } while (Thread32Next(snapshot, &entry)); if (dbg_curr_process && cpid != dbg_curr_pid) dbg_curr_process->process_io->close_process(dbg_curr_process, FALSE); } CloseHandle(snapshot); dbg_curr_process = process; dbg_curr_pid = cpid; dbg_curr_thread = thread; dbg_curr_tid = thread ? thread->tid : 0; dbg_context = ctx; }
int CSysinfo::GetTIDs (pid_t pid, ExtArray<DWORD> & tids) { DWORD s = 0; if ( !IsWin2k ) { /*** Window NT 4.0 Specific Code -- this does not work on Win2k! ***/ DWORD *block; Refresh(); block = FindBlock (pid); if (!block) return 0; for (s=0; s < *(block+1); s++) { tids[s] = *(block+43+s*16); // tstatus[s] = *(block+48+s*16) + (*(block+47+s*16)<<8); } return (int)s; } /******** Win2k Specific Code -- use spiffy new Toolhelp32 calls ***/ HANDLE hThreadSnap = NULL; THREADENTRY32 te32 = {0}; // Take a snapshot of all threads currently in the system. hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (hThreadSnap == (HANDLE)-1) { // dprintf(D_DAEMONCORE,"CreateToolhelp32Snapshot failed\n"); return 0; } // Fill in the size of the structure before using it. te32.dwSize = sizeof(THREADENTRY32); // Walk the thread snapshot to find all threads of the process. // If the thread belongs to the process, add its information // to the list. if (Thread32First(hThreadSnap, &te32)) { do { if (te32.th32OwnerProcessID == pid) { tids[s] = te32.th32ThreadID; s++; } } while (Thread32Next(hThreadSnap, &te32)); } // Do not forget to clean up the snapshot object. CloseHandle (hThreadSnap); return (int)s; }