RTL_PROCESS_LOCK_INFORMATION

The RTL_PROCESS_LOCK_INFORMATION structure is a recurring element in the RTL_PROCESS_LOCKS structure that a successful call to ZwQuerySystemInformation or NtQuerySystemInformation produces at the start of its output buffer when given the information class SystemLocksInformation (0x0C). There is one RTL_PROCESS_LOCK_INFORMATION for each ERESOURCE that is initialised but not yet deleted.

Documentation Status

The RTL_PROCESS_LOCK_INFORMATION structure is not documented.

Microsoft does publish the practical equivalent of a C-language definition as type information in public symbol files, though not for the kernel, where the structure is prepared, nor even for low-level user-mode DLLs that interpret the structure, but for various higher-level user-mode DLLs such as URLMON.DLL and only then starting with version 6.2.

Two earlier disclosures of type information are known, though not in symbol files but in statically linked libraries: GDISRVL.LIB from the Device Driver Kit (DDK) for Windows NT 3.51; and SHELL32.LIB from the DDK for Windows NT 4.0.

Layout

Except in the very earliest versions, the RTL_PROCESS_LOCK_INFORMATION is 0x24 or 0x30 bytes in 32-bit and 64-bit Windows, respectively, in version 3.51 and higher. The original RTL_PROCESS_LOCK_INFORMATION from versions 3.10 and 3.50 is 0x3C bytes.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 (3.10 to 3.50)   unaccounted four bytes 3.10 to 3.50  
0x04 (3.10 to 3.50);
0x00
0x00
PVOID Address;
all  
0x08 (3.10 to 3.50)  
ULONG CreatorBackTraceIndex;
3.10 to 3.50 next as USHORT at 0x06
0x0C (3.10 to 3.50);
0x04
0x08
USHORT Type;
all  
0x06 0x0A
USHORT CreatorBackTraceIndex;
3.51 and higher previously ULONG at 0x08
0x0E (3.10 to 3.50)   unknown word 3.10 to 3.50  
0x10 (3.10 to 3.50)   unknown four dwords 3.10 to 3.50  
0x20 (3.10 to 3.50);
0x08
0x10
PVOID OwningThread;
all  
0x24 (3.10 to 3.50);
0x0C
0x18
LONG LockCount;
all  
0x28 (3.10 to 3.50);
0x10
0x1C
ULONG ContentionCount;
all  
0x2C (3.10 to 3.50)   unaccounted four bytes 3.10 to 3.50  
0x14 0x20
ULONG EntryCount;
3.51 and higher  
0x18 0x24
LONG RecursionCount;
3.51 and higher  
0x34 (3.10 to 3.50);
0x1C
0x28
ULONG NumberOfWaitingShared;
all  
0x38 (3.10 to 3.50);
0x20
0x2C
ULONG NumberOfWaitingExclusive;
all  

The Address is that of an ERESOURCE from the kernel’s list. This is a kernel-mode address, which is why the SystemLocksInformation case of NtQuerySystemInformation is nowadays failed for restricted callers.

The Type is always 1. The CreatorBackTraceIndex is always 0, except that version 3.10 gets it from the same-named member of the ERESOURCE.

The word for which no name is known at offset 0x0E in the original layout is the count of dwords that version 3.10 copies to offset 0x10. The count and dwords come from offsets 0x64 and 0x68 in the original ERESOURCE in version 3.10. There is no copying in version 3.50: the count is set to zero. Even in version 3.10, no way is yet known that the count can be non-zero in the ERESOURCE.

Though the OwningThread is formally a PVOID, it is not the address of anything but is instead the thread ID. That the RTL_PROCESS_LOCK_INFORMATION has only one OwningThread is because this information structure tells only which thread, if any, has exclusive access to the resource—or, more precisely, had it when the kernel collected the information.

The unaccounted member at offset 0x2C in the original layout is presumably one of what the much later symbol files present as EntryCount and RecursionCount. No way is yet known that any of these get set in any version.