WOWPROCESSINFO

The WOWPROCESSINFO (formally tagWOWPROCESSINFO) is the primary structural modelling of a process’s hosting of 16-bit tasks.

The address of a process’s one WOWPROCESSINFO is held in the pwpi member of the PROCESSINFO. Only one way is known that WIN32K creates a WOWPROCESSINFO for a process. It starts with that same process calling the exported USER32 function UserRegisterWowHandlers. Calling this function gives USER32 a set of routines that it is to call for handling various events, but it also fills a table with the addresses of more routines to call in USER32. One of these is named in symbol files as RegisterUserHungAppHandlers. What it registers is one routine, which is presumably the one “hung app handler”, and an event. Only through this registration does the current process get a WOWPROCESSINFO.

History

The WOWPROCESSINFO is at least as old as version 3.51—I have no version 3.50 of WINSRV.DLL to inspect—but is certainly not in version 3.10, which has 16-bit tasks but does not provide for hosting them in different processes. In structural terms, where later versions have the ptiScheduled and ptdbHead members in the WOWPROCESSINFO for each process that hosts 16-bit tasks, version 3.10 has global variables (which the WINSRV.DBG file for that version names as gpti16Bit and gptdbHead).

Documentation Status

The WOWPROCESSINFO is not documented, nor even declared in any header for kernel-mode programming as published, for instance, in the Windows Driver Kit (WDK). Public disclosure by Microsoft of structural detail is known just the once, as type information in symbol files for WIN32K.SYS in Windows 7.

Layout

For an undocumented structure, the WOWPROCESSINFO has changed strikingly little in its long life. However important support for 16-bit execution must have been in the early days of 32-bit Windows, it is undeniably obscure now and so it would be only natural to expect that the relevant structures and code hardly ever get looked at, let alone revised. What may surprise, though, is that the structure is not just defined for 64-bit Windows but is still supported by code that can create instances of it.

Version Size (x86) Size (x64)
3.51 to 5.1 0x2C  
5.2 to 10.0 0x28 0x48

These sizes, and the offsets, types and names in the tables that follow, are from Microsoft’s symbol files for WIN32K.SYS in Windows 7. Since symbol files for other versions do not contain type information for the WOWPROCESSINFO, what’s known for them is instead inferred from what corresponding use WIN32K—and even earlier, WINSRV—is seen to make of the WOWPROCESSINFO in those versions.

Offset (x86) Offset (x64) Definition Versions
0x00 0x00
WOWPROCESSINFO *pwpiNext;
3.51 and higher
0x04 0x08
THREADINFO *ptiScheduled;
3.51 and higher
0x08 (3.51 to 5.1)  
ULONG nTaskLock;
3.51 to 5.1
0x0C (3.51 to 5.1);
0x08
0x10
TDB *ptdbHead;
3.51 and higher
0x10 (3.51 to 5.1);
0x0C
0x18
PVOID lpfnWowExitTask;
3.51 and higher
0x14 (3.51 to 5.1);
0x10
 
HANDLE hEventWowExecServer;
3.51 only
0x20
KEVENT *pEventWowExec;
4.0 and higher
0x18 (3.51 to 5.1);
0x14
0x28
HANDLE hEventWowExecClient;
3.51 and higher
0x1C (3.51 to 5.1);
0x18
0x30
ULONG nSendLock;
3.51 and higher
0x20 (3.51 to 5.1);
0x1C
0x34
ULONG nRecvLock;
3.51 and higher
0x24 (3.51 to 5.1);
0x20
 
DWORD CSOwningThread;
3.51 only
0x38
THREADINFO *CSOwningThread;
4.0 and higher
0x28 (3.51 to 5.1);
0x24
0x40
LONG CSLockCount;
3.51 and higher

The name nTaskLock is proposed for the dword at offset 0x08 in early versions. It is a guess but not without support: Microsoft’s name for the corresponding global variable in version 3.10 is known to be gnTaskLock.

Though symbol files have lpfnWowExitTask as pointing to void, it does of course point to a function. Specifically, it points to a thread routine. This is the “hung app handler” that is supplied when creating the WOWPROCESSINFO. When the caller is WOW32.DLL, as expected, the registered handler is the exported function W32HungAppNotifyThread.

That pEventWowExec had a different prefix when it was a server-side handle to the event, rather than a kernel-mode pointer, is mere speculation but if we are to guess at its having a different prefix then we may as well suppose it had a suffix too, for balance with the name hEventWowExecClient that is certain from symbol files.