Maarten Bamelis
Maarten Bamelis

Reputation: 2423

Is it safe/defined to assume the value of a Windows pseudo handle?

I am writing a piece C++ code for Windows that needs to query the timings for the process and each of its individual threads.

To do the necessary system calls, I need the handles for the process and each of its threads. I am using the getCurrentProcess and getCurrentThread functions which both return a pseudo handle. Upon further inspection, I noticed that the pseudo handles for all threads share the same value.

After a brief search on the internet, I found the following article that reports the same values for the process and thread pseudo handles as I got: https://weseetips.wordpress.com/2008/03/26/getcurrentthread-returns-pseudo-handle-not-the-real-handle/

My question: is it safe and/or defined to call getCurrentThread once from one thread and use the returned pseudo handle in all other threads to let them refer to themselves?

Using the current implementation, this works as expected. I am just wondering if this behavior is guaranteed. In other words, will it work on any Windows platform that offers the getCurrentThread function; and would changing the behavior be considered a breaking change?


The documentation for the getCurrentThread function states (emphasis mine):

A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. [...]

Which makes me believe this special pseudo handle is just an alias for "the current thread" and can therefore be shared among all threads to let them refer to themselves. On the other hand, the documentation also says that the return value can be used by the calling thread, hence my confusion!

Upvotes: 2

Views: 1152

Answers (2)

RbMm
RbMm

Reputation: 33754

yes, this is safe - this pseudo handles is well known values and documented in wdm.h (from windows wdk)

#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )  
#define ZwCurrentProcess() NtCurrentProcess()         
#define NtCurrentThread() ( (HANDLE)(LONG_PTR) -2 )   
#define ZwCurrentThread() NtCurrentThread()           
#define NtCurrentSession() ( (HANDLE)(LONG_PTR) -3 )  
#define ZwCurrentSession() NtCurrentSession()         

and can therefore be shared among all threads to let them refer to themselves.

of course no, it can not be "shared among all threads" - only current process/thread can use it for refer to themselves.

when kernel mode api got thread/process handle as input parameter - he need convert handle to object pointer (ETHREAD or EPROCESS). for this first check for this constant values - if yes - used pointer to current thread/process object. otherwise handle is index in process handle table

Upvotes: 3

Sneftel
Sneftel

Reputation: 41503

Yep. From that same page:

The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function.

Upvotes: 2

Related Questions