WOWTHREADINFO

The WOWTHREADINFO (formally tagWOWTHREADINFO) is one of two structures that are the primary modelling of what in many ways appears to be a 16-bit process but is in fact the simulation of one by a single thread. The specific concern of the WOWTHREADINFO is the coordination of the one 16-bit process with the execution of all others.

The only known way that WIN32K creates a WOWTHREADINFO is when an attempt is made to create a process from a 16-bit Windows application. A notification gets to the user-mode WINSRV.DLL in the CSRSS.EXE process and ever since version 4.0 is passed through to WIN32K in kernel mode. There never will be a 16-bit process. There is, however, a true process that will host the 16-bit “task” as one of the host’s threads. There is also what may be intended as a unique identifier for the task. If no WOWTHREADINFO yet exists for the task ID, one gets created. The uncertainty about uniqueness is that it is not an error to repeat a task ID: a WOWTHREADINFO that exists for the same task ID gets reused.

Multiple processes can each host multiple 16-bit tasks. If the idTask is meant to be unique, it is meant to be unique across all hosts. All WOWTHREADINFO structures that WIN32K ever creates go into one list, linked through the pwtiNext member. Indeed, WIN32K does very little for the process-creation notification except to ensure that this list has a WOWTHREADINFO for the supposed new task. A newly created WOWTHREADINFO does not get linked to any other WIN32K structures until the task is initialised. It then gets pointed to from a TDB.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 0x00
WOWTHREADINFO *pwtiNext;
3.51 and higher  
0x04 0x08
ULONG idTask;
3.51 and higher  
0x08 0x10
ULONG_PTR idWaitObject;
3.51 and higher  
0x0C 0x18
ULONG idParentProcess;
3.51 and higher  
0x10 0x20
HANDLE hIdleEvent;
3.51 only previously in TDB
KEVENT *pIdleEvent;
4.0 and higher  
0x14 0x28 unknown BOOL 6.2 and higher  

That pIdleEvent had a different prefix when introduced as a handle in the user-mode WOWTHREADINFO is mere speculation. Though the event has been accessed by a pointer ever since the move to kernel mode, logic developed for version 3.51 is retained such that pIdleEvent can be the address of an event object else NULL as would ordinarily be expected, but can alternatively be INVALID_HANDLE_VALUE.

Microsoft’s name for the addition in version 6.2 may never be known, but bInitialized would fit both the established notation and what seems to be the purpose. The new member looks like it was introduced to deal with problems from reusing a WOWTHREADINFO for a repeated task ID. The boolean is zero in a newly created WOWTHREADINFO. It gets set to 1 when later initialisation of the task retrieves the WOWTHREADINFO for the task ID and links it to a newly created TDB. If the boolean somehow is not still 0, then initialisation fails.