DRAFT: Take more than your usual care.


This function registers what is nowadays termed a classic event provider.


EtwRegisterTraceGuids (
    WMIDPREQUEST RequestAddress, 
    PVOID RequestContext, 
    LPCGUID ControlGuid, 
    ULONG GuidCount, 
    LPCTSTR MofImagePath, 
    LPCTSTR MofResourceName, 
    TRACEHANDLE *RegistrationHandle);

This function has both ANSI and Unicode forms with A and W suffixes, respectively.


The required RequestAddress argument is the address of a routine at which the provider can be called back for various purposes both during this function and later, until the provider is unregistered. The RequestContext argument is an arbitrary caller-supplied value that will be passed back to the provider as an argument on all calls to the routine.

The required ControlGuid argument is the address of a GUID that uniquely identifies the provider.

The GuidCount argument tells how many TRACE_GUID_REGISTRATION structures are in the array whose address is given as TraceGuidReg. These are optional in the sense that the latter can be NULL if the former is zero. Within each TRACE_GUID_REGISTRATION that is supplied, the Guid supplies input and the RegHandle is filled in by the function as output.

The MofImagePath and MofResourceName arguments are ignored in versions 6.0 and higher. They are anyway optional in earlier versions.

The required RegistrationHandle argument is the address of a variable that is to receive a 64-bit handle to the registered provider.

Return Value

The function returns zero for success, else a Win32 error code (which the function also sets as the thread’s last error).


The EtwRegisterTraceGuidsA and EtwRegisterTraceGuidsW functions are exported by name from NTDLL in version 5.2 and higher. The Unicode form has the native implementation. Both forms have higher-level availability as forwards from the ADVAPI32 exports RegisterTraceGuidsA and RegisterTraceGuidsW functions in its versions 5.2 and higher, and as forwards from KERNELBASE exports with these names in its version 6.2 and higher. Starting with ADVAPI32 version 6.3, the ANSI form is forward first to KERNELBASE and then to NTDLL.

This note is concerned only with the function as implemented in NTDLL version 5.2 and higher. The earlier implementations in ADVAPI32 may be covered some time, separately. Even in NTDLL, the implementation in version 5.2 is very different, notably for predating the NtTraceControl function and instead working through Device I/O Control to the WMI support device, and is presently not covered here.

Documentation Status

The EtwRegisterTraceGuids function is not documented. Well-behaved user-mode software would call the documented RegisterTraceGuids function instead. Note, however, that a strict reading of Microsoft’s documentation prohibits calling the higher-level function, but not the lower-level, from a DllMain routine. For some hint that Microsoft has experience either of or closely related to this point, see the cautionary note about the loader lock in Microsoft’s documentation of the WMIDPREQUEST callback function.


If any of the required pointer arguments, i.e., RequestAddress, ControlGuid and RegistrationHandle, are NULL or if the GuidCount exceeds 64K, the function returns ERROR_INVALID_PARAMETER.

The function saves its inputs into a user-mode context to retain while the provider remains registered. This can fail for insufficient memory.