Thread ID vs. Thread Handle - windows

What is the difference between a thread ID and a thread handle? Why both are needed? Is there a difference between Windows and Linux?

Linux's pthread library does not, as far as I know, have a concept of a thread handle. pthread_create and other pthreads functions, return a thread ID.
Under Windows, the thread handle is different from the thread ID, in the same way that a file handle is different from a file name.
The thread handle is a token which allows you to do something with the thread (typically wait for it or kill it). Win32 has these tokens for lots of objects, and calls them HANDLE in general.
The token is essentially a pointer at the running (or stopped) thread and has a set of abilities associated with it, for example, you can have a handle which permits you to wait for, but not kill, a thread. In the same way, we can have a file handle which is read-only.
This level of indirection may or may not be useful, but it's the way Win32 does it, and it's broadly consistent with how it handles some other types of objects.

The ID is the unique numeric identifier of the thread running in the system. A thread handle, like any kernel object handle, can be seen as a special type of reference counted pointer to the kernel object.
So in kernel space there is an object of type THREAD with ID = 12345
And because you want to do something with the thread you have a pointer in your address space called a threadID with value 44.
Please note that different handles to the same kernel object have different values (two pointers to one object) and that kernel objects can have handles in more than one process.

Thread IDs are progressive (ie, one after another), which you can traverse.
Thread handles, like most handles in Windows, are actually pointers.
You might, for example, set thread property bits by using the thread handle - but not thread id.

Related

Where is a usermode thread context stored, and is it possible to modify?

i was wondering if anyone knows where the context of a thread running in usermode is stored in kernel ? and if there are any API's for dealing with getting and setting a usermode thread context ? i know that you should not be doing this for any reason, so please do not sidetrack into that. This is solely for the sake of research and will not be used by anything else than local projects of my own.
In usermode we have GetThreadContext and SetThreadContext, but i need to do this from a device driver in the kernel, i wish i had more to write but i can't find any information on this topic at all so i wish someone more educated than me can enlighten me on some of the windows internals at hand here.
Regards Paze.
when thread enter in kernel mode it context stored in it kernel stack, in struct _KTRAP_FRAME - it declared in ntdkk.h. in ntoskrnl.exe (all versions from win2000 up to win10) exist exported api
NTKERNELAPI
NTSTATUS
NTAPI
PsGetContextThread(
__in PETHREAD Thread,
__inout PCONTEXT ThreadContext,
__in KPROCESSOR_MODE Mode
);
you can use it for get thread context (and PsSetContextThread for set thread context).
about how this work - look in wrk - when you try get/set context from another thread special kernel mode APC is inserted to this thread with pointer to internal GETSETCONTEXT structure, after this requestor begin wait on event (OperationComplete) from this structure. when thread (for which we query context) next time begin execute in kernel - APC routine (PspGetSetContextSpecialApc) is executed - it fill context from _KTRAP_FRAME and set event (OperationComplete)

ETHREAD Structure and CreateThread "dwCreationFlags"

I'm working on a function to extract information about a thread and would like to know more specifically when calling the CreateThread function, the created thread insert "dwCreationFlags" parameter somewhere in ETHREAD structure
Since these flags only affect thread creation, there is no need to keep them once the thread exists. So no, they are not kept in the ETHREAD.

Windows: how to spawn threads from (NDIS) kernel driver?

Which function is recommended to spawn a new thread within NDIS5/6 context? Looking for something that is guaranteed to work at IRQL=PASSIVE (e.g. no bsods out of nothing); by a quick examination of ndis.h contents, found nothing.
Also, it is planned to use a newly spawned thread for calling upon NdisFreeMemory* family, will it be causing any problems to free allocated, but unused memory from a different thread?
Threading is outside the scope of NDIS. If you need to start a new thread, use the standard kernel routines (like PsCreateSystemThread). Note that usually timers and work items are sufficicent for most miniport needs. It is unusual for an NDIS miniport to create its own thread, although I suppose there are valid cases where it might be a fair design.
It is ok to allocate memory on one thread and free it on another.

windows-kernel - Can a thread id ever be the same as a process id?

Hi I've looked around for an answer to this question and I am wondering if anyone with experience in windows internals knows if the kernel ever will assign a process id that is the same as a thread id. What I mean is say there is process a.exe that I have started that has a thread with id 123. If another process is started, for example b.exe, will the process id be 123? In other words do process and thread identifiers ever collide? Thanks
EDIT: It appears that process and thread ids come from the same pool called the PspCidTable. A hacker named Polynomial who reviewed the windows nt source says the following:
The kernel needs to be able to generate a sequence of process and
thread IDs that are unique across the whole system. To efficiently and
safely do this, the kernel creates a pool of IDs that can be used for
both processes and threads. This pool is exported in the kernel as a
HANDLE_TABLE object called PspCidTable. During Phase0 startup of the
system, the PspInitPhase0 function is called. This function creates a
HANDLE_TABLE object using ExCreateHandleTable, which automatically
populates the table with 65536 entires. Each entry is a 16-bit
unsigned integer (at least it is on a 32-bit OS) stored inside a list
item object that is part of a doubly linked list. Both process and
thread IDs come from the PspCidTable pool.
Source for above: Stuff you (probably) didn't know about Windows
The PspCidTable still exists in Windows XP and empirical observations in Windows 7 lead me to believe the above is still true.
Thread and process ids come from the same pool in all versions of windows AFAIK but that does not mean that this will be true forever. In practice it should not matter at all since you should only pass things that you know is thread id to OpenThread and vice versa.
Don't assume other things about these ids either (They are not 16 bit, they might seem like they are on NT but it is possible to get ids > 0xffff (On Win9x they are xor'ed with a secret and often use the full 32 bits))
The only weird thing you should keep in the back of your mind is that on 64 bit systems they are 32 bit in user mode and pointer sized in kernel mode (Use HandleToUlong/UlongToHandle)

CreateThread vs fork()

Do we have any sort of relationship between fork() and CreateThread? Is there anything that
CreateThread internally calls fork()?
In NT, the fundamental working unit is called a thread (ie NT schedules threads, not processes.). User threads run in the context of a process. When you call CreateThread, you request the NT kernel to allocate a working unit within the context of your process (you also have fibres that are basically threads you can schedule yourself but that's beyond the topic of your question).
When you call CreateThread you provide the function with an entry point that is going to be run after the function is called. The code must be within the virtual space of the process and the page must have execution rights. Put simply, you give a function pointer. ;)
fork() is an UNIX function that requests the kernel to create copy of the running process. The parent process gets the pid of the child process and the child process gets 0 (this way you know who you are).
If you wish to create a process in Windows, you call the CreateProcess function, but that doesn't behave like fork(). The reason being that most of the time you will create threads, not processes.
As you can see, there is no relation between CreateThread and fork.
fork() only exists on Unix systems and it creates a new process with the same state as the caller. CreateThread() creates a new thread in the same process.
The Windows and Unix process model is fundamentally very different, so there is no way of directly mapping the API from one on top of the other.
fork() clones the current process into two. In the parent process, fork() returns the pid, and in the child it returns 0. This is typically used like this:
int pid;
if (pid = fork()) {
// this code is executed in the parent
} else {
// this code is executed in the child
}
Cygwin is an emulation layer for building and running Unix applications on Windows which emulates the behavior of fork() using CreateProcess().
CreateThread - is for threads, fork - is for creating duplicate process. And there is no native way to have fork functionality for windows (at least through Win32 ).
You might want to know Microsoft provides fork() in high-end versions of Windows with component called Subsystem for UNIX-based Applications (SUA). You can find details in my answer here.
Found this link which i believe could be helpful in clearing few facts regarding forking/threading.
Sharing over here: http://www.geekride.com/index.php/2010/01/fork-forking-vs-threading-thread-linux-kernel/

Resources