Get process main thread from PsSetCreateThreadNotifyRoutineEx

Does anyone know if it is possible to get the Main Thread ID from inside the PsSetCreateProcessNotifyRoutineEx callback? I need to understand if the thread I am seeing is the main process thread for monitoring reasons.

Thanks in advance for any help.

It used to be that the first thread created was “the main thread”, but bottom line in Windows I can create a process with main thread A then create thread B, then kill thread A, and the process is still running.

Thanks Don. Good to know. It always seems like if I cannot find the answer, it’s because I am asking the wrong questions.

Does anyone know if it is possible to get the Main Thread ID from inside the PsSetCreateProcessNotifyRoutineEx callback?

Please note that the concept of “main thread” is a 100% Win32 (i.e userland) one. The Windows kernel in itself does not make a distinction between “main”/parent threads and the “subsidiary”/child ones. As long as there is at least one thread of a process that happens to be in any state other than a terminated one, the process is considered alive and kicking by the kernel.

To put it simply, all threads of any process are equal from the kernel perspective, but from Win32 subsystem one, the “main” thread of a process is more equal than all others.

In practical terms, the scenario that Don has described cannot occur with a “conventional” Win32 process, but the decision to terminate all threads of a process after its “main” thread has been terminated gets made by the Win32 subsystem, rather than by the kernel itself.
Furthermore, if the process in question happens to be a “not-so-conventional” one, things are not necessarily going to work this way.

For example, consider what happens if a certain driver that is tightly coupled to the target app creates a thread in the target process by calling PsCreateSystemThread(). You cannot terminate a thread until it makes a return to the userland. Once a thread created by PsCreateSystemThread() does not have a userland representation, it is simply impossible to terminate such a thread by any external means, so that Win32 subsystem is totally out of luck here…

Anton Bassov

further, even un UM, there is absolutly nothing to prevent a process from spawning multiple threads that start message loops, own top level windows and all equally could be called main. real world processes actually do this including some that i have written. The AttachThreadInput function (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-attachthreadinput) even allows multiple threads to share a message loop - ususally reserved for very special purpose situations as it can be quite dangerious. All the thread safety implied by a single thread per message pump no longer applies, so use at your peril; but it does exist.

presumably you have a real problem that you are trying to solve via this method. if you can tell us more about it, we might be able to help you to find a method that can solve it even though the problem as stated is unworkable