Use Descriptor Type

When given 0x1F as its FunctionCode argument, the NtTraceControl function in version 10.0 and higher records that the given event provider is sufficiently modern that the Type member in its EVENT_DATA_DESCRIPTOR structures is to be treated as meaningful. This Type member is defined in space that used to be Reserved but which will not certainly have been initialised by all event providers. Its use therefore needs to be explicitly enabled.

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.


Well-behaved user-mode software does not call NtTraceControl. The documented user-mode API for reaching this functionality is EventSetInformation, which is exported by name from ADVAPI32.DLL in version 6.2 and higher, though only ever as a forward to the undocumened NTDLL function EtwEventSetInformation. These higher-level functions vary their behaviour according to an InformationClass argument. The case that specifies whether to use the Type in event data descriptors is EventProviderUseDescriptorType (3). Before version 10.0, this case is not supported.

The corresponding API for kernel-mode software is EtwSetInformation. It is exported by name from the kernel in version 10.0 and higher. Microsoft declares it in WDM.H but does not document it. Kernel-mode access through NtTraceControl is not just unwanted but is even unexpected: the handle that is expected in the input (see below) has its access checked as if for a user-mode caller.


The expected input has at offset 0x00 a HANDLE to the provider and at offset 0x08 a BOOLEAN for whether to use types in descriptors. Though Microsoft surely has a structure for this, its name is not known. No output is expected. The function returns STATUS_INVALID_PARAMETER if either of the following is true:

The given HANDLE is to be an Object Manager handle for an event registration object, i.e., an ETW_REG_ENTRY, that grants TRACELOG_REGISTER_GUIDS access to user-mode callers. Failure to reference an event registration object from the given HANDLE is failure for the function. The whole of the function’s essential work is to set the given BOOLEAN into the UseDescriptorType member of the referenced ETW_REG_ENTRY. If the given BOOLEAN is anything but TRUE or FALSE, the function fails, returning STATUS_INVALID_PARAMETER.