views:

299

answers:

3

Apperantly, GetThreadId is a Vista API. How can I get a thread's id on pre vista systems?

A: 

If you can somehow make the thread in question call GetCurrentThreadId and store it somewhere, you could read the result.

bobbymcr
A: 

There are a few options:

Reed Copsey
in the enumeration case, is there a way to determine which of the enumerated threads corresponds to a HANDLE you have?
bdonlan
You pass your current process handle to CreateToolhelp32Snapshot with the TH32CS_SNAPMODULE flag. This will just enumerate threads in your process.
Reed Copsey
But it won't let you tell the difference between threads _within_ your module, will it?
bdonlan
I ran into the same problem. The THREADENTRY32 struct has only the thread id, not the handle. As to MODULEENTRY32, according to MSDN in regard to it's th32ModuleID member: "This member is no longer used, and is always set to one"
sold
Well, you get the thread handle for every thread within your module. You can use this against ones that are known (ie: you've created), since you know their handle (provided you saved them)... But, it does give you the full ThreadID for each thread as part of the THREADENTRY32 struct, which is the direct equivalent of using GetThreadId. See http://msdn.microsoft.com/en-us/library/ms686735%28VS.85%29.aspx
Reed Copsey
Sure, you can get a HANDLE from the enumeration, but how can you compare two thread HANDLEs you got from different sources?
bdonlan
@sold: You can get a DWORD threadID from the enumeration. You can get the thread's HANDLE from the thread ID using OpenThread. Nearly all of the thread functions work with one of these two elements, so between enumerating the threads in your process, and converting to handles as necessary, you can do everything you could do with GetThreadId in Vista.
Reed Copsey
See OpenThread for details on getting a HANDLE back from the THREADENTRY32.th32ThreadId member: http://msdn.microsoft.com/en-us/library/ms684335%28VS.85%29.aspx
Reed Copsey
@Reed, but that doesn't help if you have a HANDLE and want to get the thread ID from it.
bdonlan
@Bdonlan: No, it does. You have to enumerate all of your threads in your process, until you find the matching handle (get the thread's ID, convert to handle), then use it's ID. It's ugly, but it works. Vista just makes it easy.
Reed Copsey
Yes, but _how_ do you match the handle? AFAICS, once you have two thread HANDLEs, you have no idea if they refer to the same thread.
bdonlan
+1  A: 

If the thread in question enters an alertable wait state frequently, you could send it an APC with QueueUserAPC; the APC handler can then call GetCurrentThreadId and communicate the result back to the caller using whatever method you like.

You can also do this with undocumented NT functions. Using NtQueryInformationThread() on the ThreadBasicInformation class will give you the thread ID in the returned structure. An example can be found in the wine source. However, I'm not sure what versions of windows this is available on - keep in mind these undocumented functions can change at any time, so it's best to test them on the older versions of windows you're interested in, and simply use GetThreadId() where it's available.

Note that these undocumented functions can only be accessed by LoadLibrary() and GetProcAddress() on NTDLL; they have no import library. According to MSDN, declarations for the data structures can be found in Winternl.h, but if not, just define them yourselves based on the ntinternals links above.

bdonlan