SKETCH OF HOW RESEARCH MIGHT CONTINUE AND RESULTS BE PRESENTED

Real-Time Connect

When given 0x0B as its FunctionCode argument, the NtTraceControl function connects a real-time consumer to a logger. Microsoft’s name for this function code is not known. This note deals only with the function’s behaviour that is specific to this function code. The function’s general behaviour is here taken as assumed knowledge.

A fixed-size context is expected as both input and output. Microsoft’s name for this real-time connection context is not known (though an insufficiently substantial hint is that another structure’s pointer to this structure is named RealtimeConnectContext). It is the same in both 32-bit and 64-bit Windows but has changed between versions, notably to be reworked significantly for Windows 7. The following changes of size are known.

Versions Size
6.0 0x20
6.1 to 6.2 0x50
6.3 and higher 0x60

In version 6.1 and higher, most of the structure provides input for creation of an EtwConsumer object. Internally this is an ETW_REALTIME_CONSUMER structure. Type information for this is available in public symbol files and it seems highly likely that Microsoft uses the same names and types in both structures for members that correspond closely. Where pointers are padded to 64 bits so that the kernel deals with one format for both 32-bit and 64-bit callers, type information that Microsoft has disclosed for other structures that are involved with NtTraceControl, e.g., WMI_LOGGER_INFORMATION, suggests a convention that Microsoft perhaps uses for this structure too.

Offset Definition Versions Remarks
0x00
ULONG LoggerId;
6.0 and higher input
0x04
ULONG ReservedBufferSpaceSize;
6.1 and higher input
0x08
union {
    UCHAR *ReservedBufferSpace;
    ULONG64 ReservedBufferSpace64;
};
6.1 and higher input
0x10 a 64-bit allowance for the address of a buffer to use for the ReservedBufferSpaceBitMap 6.1 and higher input
0x18
union {
    HANDLE DisconnectEvent;
    ULONG64 DisconnectEvent64;
};
6.1 and higher input
0x20
union {
    HANDLE DataAvailableEvent;
    ULONG64 DataAvailableEvent64;
};
6.1 and higher input
0x28
union {
    SINGLE_LIST_ENTRY *UserBufferListHead;
    ULONG64 UserBufferListHead64;
};
6.1 and higher input
0x30
union {
    ULONG *UserBufferCount;
    ULONG64 UserBufferCount64;
};
6.1 and higher input
0x38
union {
    ULONG *EventsLostCount;
    ULONG64 EventsLostCount64;
};
6.3 and higher input
0x40
union {
    ULONG *BuffersLostCount;
    ULONG64 BuffersLostCount;
};
6.3 and higher input
0x04 (6.0) a 32-bit consumer ID 6.0 only output
0x08 (6.0);
0x38 (6.1);
0x48
a 64-bit allowance for a HANDLE to a pipe 6.0 only output
a 64-bit allowance for a HANDLE to the EtwConsumer object 6.1 and higher output
0x10 (6.0);
0x40 (6.1);
0x50
an ETW_REF_CLOCK 6.0 and higher output

Version 6.0 defines no object type for real-time event consumers and therefore has a very different implementation. Each connection of a real-time consumer to a logger is represented not by a handle but by a sequence number. When tracing events, the kernel does not have direct access to the user-mode memory supplied by the consumer but instead writes through a pipe.

If the input and output buffers are not both exactly the expected size, the function returns STATUS_INVALID_PARAMETER.

TO BE DONE?