Click here to Skip to main content
14,453,623 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hello.

Could you help me
to find the main (only) thread ID
of a given by ID process, please ? :)

Task context:
A running process has (at the moment) no windows but a(some) thread(s).

Wanted:
Posting of WM_QUIT at the main thread only.

Not-wanted:
Using of TerminateProcess or posting WM_QUIT at the non-primary threads.

Thank you !
Posted
Updated 4-May-10 0:23am
v2
Rate this:
Please Sign up or sign in to vote.

Solution 1

An at the moment found "solution" :-O :) :

#ifndef MAKEULONGLONG
#define MAKEULONGLONG(ldw, hdw) ((ULONGLONG(hdw) << 32) | ((ldw) & 0xFFFFFFFF))
#endif
  
#ifndef MAXULONGLONG
#define MAXULONGLONG ((ULONGLONG)~((ULONGLONG)0))
#endif
  
bool CloseProcessMainThread(DWORD dwProcID)
{
  DWORD dwMainThreadID = 0;
  ULONGLONG ullMinCreateTime = MAXULONGLONG;
  
  HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  if (hThreadSnap != INVALID_HANDLE_VALUE) {
    THREADENTRY32 th32;
    th32.dwSize = sizeof(THREADENTRY32);
    BOOL bOK = TRUE;
    for (bOK = Thread32First(hThreadSnap, &th32); bOK;
         bOK = Thread32Next(hThreadSnap, &th32)) {
      if (th32.th32OwnerProcessID == dwProcID) {
        HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,
                                    TRUE, th32.th32ThreadID);
        if (hThread) {
          FILETIME afTimes[4] = {0};
          if (GetThreadTimes(hThread,
                             &afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3])) {
            ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime,
                                              afTimes[0].dwHighDateTime);
            if (ullTest && ullTest < ullMinCreateTime) {
              ullMinCreateTime = ullTest;
              dwMainThreadID = th32.th32ThreadID; // let it be main... :)
            }
          }
          CloseHandle(hThread);
        }
      }
    }
#ifndef UNDER_CE
    CloseHandle(hThreadSnap);
#else
    CloseToolhelp32Snapshot(hThreadSnap);
#endif
  }
  
  if (dwMainThreadID) {
    PostThreadMessage(dwMainThreadID, WM_QUIT, 0, 0); // close your eyes...
  }
  
  return (0 != dwMainThreadID);
}
   
Rate this:
Please Sign up or sign in to vote.

Solution 2

So accept the answer (there's a button there for it).
   
Rate this:
Please Sign up or sign in to vote.

Solution 3

Much faster, but only WIN32:

Get the ThreadId with this function:

/* CAUTION: ONLY WIN32
 * get the threadId of the main thread of a target process
 *
 * params:
 *     DWORD pId    processId of the target process
 *
 * return:
 *     Success      threadId
 *     Error        NULL
 */
DWORD GetMainThreadId(DWORD pId)
{
    LPVOID lpThId;

    _asm
    {
        mov eax, fs:[18h]
        add eax, 36
        mov [lpThId], eax
    }

    HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, pId);
    if(hProcess == NULL)
        return NULL;

    DWORD tId;
    if(ReadProcessMemory(hProcess, lpThId, &tId, sizeof(tId), NULL) == FALSE)
    {
        CloseHandle(hProcess);
        return NULL;
    }

    CloseHandle(hProcess);

    return tId;
}



Simple open the thread to get the handle:

/*
 * get a handle to the main thread of a target process
 *
 * params:
 *     DWORD pId                processId of the target process
 *     DWORD dwDesiredAccess    desired access rights to the thread
 *
 * return:
 *     Success      threadHandle with desired access rights
 *     Error        NULL
 */
HANDLE GetThreadHandle(DWORD pId, DWORD dwDesiredAccess)
{
    DWORD tId = GetMainThreadId(pId);
    if(tId == FALSE)
        return NULL;

    return OpenThread(dwDesiredAccess, FALSE, tId);
}
   
Comments
Member 13542004 19-Dec-17 7:53am
   
hi, first of all I like your solution a lot! but I'm still trying to understand some of it. according to this https://en.wikipedia.org/wiki/Win32_Thread_Information_Block FS:[0x24] is the location of the thread id, so why adding 36?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100