Geoff Chappell, Software Analyst
When given EtwWdiScenarioCode (0x0D) as its FunctionCode argument, the NtTraceControl function tells the kernel’s Scenario Event Mapper (SEM) to start or end every Windows Diagnostic Infrastructure (WDI) scenario for which the given event from the given event provider is configured as a start or end event. 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 higher-level user-mode API for reaching this functionality is a pair of undocumented functions named EventWriteStartScenario and EventWriteEndScenario. These are exported by name from ADVAPI32.DLL in version 6.0 and higher, though only ever as forwards to the undocumented NTDLL functions EtwEventWriteStartScenario and EtwEventWriteEndScenario. For both of these, the starting or ending of the scenario, independently of writing the start or end event, is done through NtTraceControl.
Kernel-mode code also does not call NtTraceControl to start or end a scenario. The kernel-mode API for this work is a pair of undocumented functions named EtwWriteStartScenario and EtwWriteEndScenario. These are exported by name from the kernel in version 6.0 and higher.
Since EtwWdiScenarioCode is known only as an argument for an undocumented function, it should not surprise that it too is undocumented. Microsoft’s name for it has been published in anything like plain text only in the NTETW.H from the Enterprise WDK for Windows 10 version 1511—specifically this one edition, its publication being very plausibly an oversight. Otherwise it is known from type information in symbol files that Microsoft has published for a few user-mode DLLs in Windows 8 and higher.
If the input buffer does not provide exactly 0x30 bytes as input or if any output buffer is given, the function returns STATUS_INVALID_PARAMETER. Microsoft presumably defines the expected input as a structure but Microsoft’s name for it is not known:
|0x00||a 64-bit allowance for a registration handle to an event provider||6.0 and higher|
|0x08||an EVENT_DESCRIPTOR for the start or end event||6.0 and higher|
|0x18||a GUID as the scenario identifier||6.0 and higher|
|0x28||32-bit control code||6.0 and higher|
The control code is 10 to start the scenario. Anything else ends the scenario (though NTDLL uses 11, which is presumably the intended value).