DRAFT: Take more than your usual care.

WMI_RESOURCE

The WMI_RESOURCE is one of many types of fixed-size header that begin the data for an event as held in the trace buffers or flushed to an Event Trace Log (ETL) file for an NT Kernel Logger session. The specific event whose data is a WMI_RESOURCE is PERFINFO_LOG_TYPE_RESOURCE (0x052B).

Usage

The PERFINFO_LOG_TYPE_RESOURCE event traces numerous possible changes of state in ERESOURCE structures. These are compound synchronisation objects through which threads cooperate over securing exclusive or shared ownership of a corresponding resource.

For any particular NT Kernel Logger session to be sent this event, the group mask PERF_SYNC_OBJECTS (0x20020000) must be enabled.

Documentation Status

The WMI_RESOURCE structure is not documented but a C-language definition is published in the NTWMI.H from the Enterprise edition of the Windows Driver Kit (WDK) for Windows 10 version 1511.

Layout

Data for the PERFINFO_LOG_TYPE_RESOURCE event (as it exists in the trace buffers) comprises:

Trace Header

In the PERFINFO_TRACE_HEADER, the Size is the total in bytes of the trace header and all the event data. The HookId is PERFINFO_LOG_TYPE_RESOURCE, which identifies the event.

The Marker is, at its most basic, 0xC0100002 (32-bit) or 0xC0110002 (64-bit). Additional flags may be set to indicate that extended data items are inserted between the trace header and the event data. Ordinarily, however, the event data follows as the trace header’s Data array.

Event Data

The event data is just the one fixed-size structure. This WMI_RESOURCE is 0x30 bytes in both 32-bit and 64-bit Windows:

Offset (x86) Offset (x64) Definition
0x00 0x00
ULONG64 AcquireTime;
0x08 0x08
ULONG64 HoldTime;
0x10 0x10
ULONG64 WaitTime;
0x18 0x18
ULONG MaxRecursionDepth;
0x1C 0x1C
ULONG ThreadId;
0x20 0x20
PVOID Resource;
0x24 0x28
ULONG Action;
0x28 0x2C
ULONG ContentionDelta;

Known values for the Action look to to be composed from bits:

But this is just speculation. Microsoft’s NTWMI.H defines four values without indicating any finer detail and it may be as well just to enumerate the known possibilities:

Value Name Remarks
0x00010008   initialised
0x00010018   reinitialised
0x00010021   acquired exclusive ownership;
internal only
0x00010022 WMI_RESOURCE_ACTION_COMPLETE_RELEASE_EXCLUSIVE released exclusive ownership
0x00010024   wait to acquire exclusive
0x00010031   reacquired exclusive;
internal only
0x00010032   released exclusive reacquisition;
internal only 
0x00010041   acquired shared ownership;
internal only
0x00010042 WMI_RESOURCE_ACTION_COMPLETE_RELEASE_SHARED released shared ownership
0x00010044   wait to acquire shared
0x00010051   reacquired shared;
internal only
0x00010052   released shared reacquisition;
internal only
0x00010120   owner pointer set by exclusive owner
0x00010140   owner pointer set by shared owner
0x00010224 WMI_RESOURCE_ACTION_WAIT_EXCESSIVE_FOR_EXCLUSIVE wait to acquire exclusive timed out
0x00010244 WMI_RESOURCE_ACTION_WAIT_EXCESSIVE_FOR_SHARED wait to acquire shared timed out

All initialisations and reinitialisations are traced, no matter that Microsoft’s NTWMI.H does not define symbols for the corresponding actions. The AcquireTime, HoldTime and WaitTime are all zero. The MaxRecursionDepth and ContentionDelta are both zero for an initialisation. Otherwise, they seem intended as rough measures of demand for ownership of the resource before its reinitialisation, the MaxRecursionDepth telling how many concurrent owners had been provided for and ContentionDelta how many threads owned the resource at the time of reinitialisation.

No event is traced for a resource’s deletion, i.e., for the opposite of its initialisation.

Perhaps only in the retail builds, no events are traced when acquiring a resource. Tracing every acquisition, let alone reacquisition, of a resource is plausibly not feasible even for a debug build. Still, four Action values are assigned. What is done for them is to track the acquisition, in memory only, to help with describing an eventual release.