PENABLECALLBACK callback function (evntprov.h)
ETW event providers optionally define an EnableCallback function to receive configuration change notifications. The PENABLECALLBACK type defines a pointer to this callback function. EnableCallback is a placeholder for the application-defined function name.
Syntax
PENABLECALLBACK Penablecallback;
void Penablecallback(
[in] LPCGUID SourceId,
[in] ULONG IsEnabled,
[in] UCHAR Level,
[in] ULONGLONG MatchAnyKeyword,
ULONGLONG MatchAllKeyword,
[in, optional] PEVENT_FILTER_DESCRIPTOR FilterData,
[in, optional] PVOID CallbackContext
)
{...}
Parameters
[in] SourceId
GUID specified by the caller that is enabling or disabling the provider.
The value comes from the SourceId parameter of EnableTraceEx or the SourceId field of the ENABLE_TRACE_PARAMETERS that is passed to EnableTraceEx2.
Note
The SourceId is the value the session specified in the call to the EnableTraceEx or EnableTraceEx2 API. It may or may not be the same as the session's GUID.
SourceId will be set to GUID_NULL in several scenarios where the notification does not have a source identifier. For example, this can occur when a trace session enabled the provider before the provider started, when the provider is stopping, or when a trace controller calls an EnableTrace API without specifying a SourceId.
[in] IsEnabled
Indicates the ControlCode corresponding to this notification. This can be one of the following values:
Value | Meaning |
---|---|
EVENT_CONTROL_CODE_DISABLE_PROVIDER (0) | No sessions have enabled the provider. |
EVENT_CONTROL_CODE_ENABLE_PROVIDER (1) | One or more sessions have enabled the provider. |
EVENT_CONTROL_CODE_CAPTURE_STATE (2) | A session is requesting that the provider log its state information. The provider will typically respond by writing events containing provider state. |
Note
The value of IsEnabled may not be the same as the ControlCode passed to
the EnableTrace API that triggered this event. For example, if two
sessions have enabled this provider and one session disables this provider by
calling EnableTraceEx2(..., EVENT_CONTROL_CODE_DISABLE_PROVIDER, ...)
, the
provider would receive a notification with IsEnabled set to
EVENT_CONTROL_CODE_ENABLE_PROVIDER
because the provider is still enabled by
the other session.
After receiving a DISABLE_PROVIDER notification, a provider may optimize its performance by disabling all events. After receiving an ENABLE_PROVIDER notification, a provider should enable writing events. It may also optimize its performance by recording the values of the Level, MatchAnyKeyword, and MatchAllKeyword filters, and then only writing the events that pass the filters (as described in remarks). After receiving a CAPTURE_STATE notification, a provider may take whatever action seems appropriate, typically writing events that describe the component's configuration or state.
A provider should ignore notifications with IsEnabled values that it does not recognize or support.
[in] Level
A value that specifies the verbosity of the events that the provider should write. When invoked with the control code EVENT_CONTROL_CODE_ENABLE_PROVIDER, the provider should record the Level value and should subsequently skip events where the event's verbosity level is greater than the recorded Level, i.e. an event should only be written if
eventDescriptor.Level <= recorded.Level
The Level in the notification is the maximum of the levels specified by trace controllers in calls to EnableTrace, EnableTraceEx, or EnableTraceEx2 using this event provider's GUID. In other words, if multiple sessions are recording events from this event provider at different verbosity levels, the Level parameter for the EnableCallback notification will be set to the highest (most verbose) of the levels.
[in] MatchAnyKeyword
A bitmask value that specifies categories of events that the provider should write. When invoked with the control code EVENT_CONTROL_CODE_ENABLE_PROVIDER, the provider should record the MatchAnyKeyword value and should subsequently skip events where the event's keyword is nonzero and does not have any of the bits from the recorded MatchAnyKeyword, i.e. an event should only be written if
eventDescriptor.Keyword == 0 || (eventDescriptor.Keyword & recorded.MatchAnyKeyword) != 0
The MatchAnyKeyword in the notification is the union (OR) of the
match-any-keywords (enable flags) specified by trace controllers in calls to
EnableTrace, EnableTraceEx, and EnableTraceEx2 for this event
provider's GUID. In other words, if multiple sessions are recording events from
this event provider with different match-any-keyword filters, the
MatchAnyKeyword parameter for the EnableCallback notification will be set
to the bitwise-OR
of the match-any-keyword filters of the sessions.
MatchAllKeyword
A bitmask value that specifies categories of events that the provider should write. When notified with the control code EVENT_CONTROL_CODE_ENABLE_PROVIDER, the provider should record the MatchAllKeyword value and should subsequently skip events where the event's keyword is nonzero and does not have all of the bits from the recorded MatchAllKeyword, i.e. an event should only be written if
eventDescriptor.Keyword == 0 || (eventDescriptor.Keyword & recorded.MatchAllKeyword) == recorded.MatchAllKeyword
The MatchAllKeyword in the notification is the disjunction (AND) of the
match-all-keywords specified by trace controllers in calls to EnableTraceEx
and EnableTraceEx2 for this event provider's GUID. In other words, if
multiple sessions are recording events from this event provider with different
match-all-keyword filters, the MatchAllKeyword parameter for the
EnableCallback notification will be set to the bitwise-AND
of the
match-all-keyword filters of the sessions.
[in, optional] FilterData
A pointer to an EVENT_FILTER_DESCRIPTOR with filter data for the event provider.
Each session can specify only one filter. The filter descriptor in the callback notification will contain one filter from each session that specified filter data when enabling the provider.
The filter data is valid only within the callback. Providers should make a local copy of the data if the data will be needed after the callback returns.
[in, optional] CallbackContext
Context for the callback. This is the value of the CallbackContext parameter that was used when the event provider called EventRegister.
Return value
None
Remarks
ETW event providers that need configuration change notifications should provide a pointer to their EnableCallback implementation when they register via EventRegister. ETW will invoke the provider's EnableCallback function when a change is made to the configuration of a trace session that involves the provider. For example, when a trace session controller configures a trace via EnableTraceEx2 or stops a trace via ControlTrace, ETW will call the provider's EnableCallback function with the resulting updated configuration.
Note
Most event providers will not implement EnableCallback directly. Instead,
most event providers are implemented using an ETW framework that provides its
own EnableCallback implementation and wraps the calls to
EventRegister, EventWrite, and EventUnregister. For example, you
might
write an event manifest
and then use the
Message Compiler to generate
C/C++ code for the events, or you might use
TraceLogging to avoid the
need for a manifest. The ETW framework typically implements an
EnableCallback function that records the notification's Level
,
MatchAnyKeyword
, and MatchAllKeyword
values, and the framework
automatically uses the recorded values to filter events. The ETW framework
usually supports invoking a user-provided callback if the user requires custom
notification handling. For example,
TraceLoggingProvider.h allows a
notification callback to be specified via
TraceLoggingRegisterEx.
Important
The provider's EnableCallback function should be as simple as possible. It should record the required information and return quickly. A long-running callback function can cause delays in ETW session control APIs such as EnableTraceEx2 or ControlTrace. The callback function must not do anything that requires the process's loader lock, i.e. it must not directly or indirectly call LoadLibrary or FreeLibrary. The callback function must not block on locks. The callback function may cause a deadlock if it blocks on locks or if it invokes any ETW session control APIs such as StartTrace, ControlTrace, or EnableTrace.
The notification callback allows the event provider to run more efficiently because the provider can perform its own tracking of the level, keywords, and other filters. By tracking the filters, the provider can efficiently skip events that are not enabled (i.e. the provider does not need to prepare the event data or call EventWrite for events that are not needed by any trace sessions).
Note that filter tracking is not required for correct operation of a provider: ETW provides EventEnabled and EventProviderEnabled functions that a provider can use, and the ETW EventWrite APIs will silently ignore any disabled events. However, provider-implemented filter tracking can be more efficient than calls to EventEnabled or EventProviderEnabled.
The notification callback also allows the provider to handle "capture-state" requests from trace sessions. Capture-state requests are typically sent by a trace session when it begins recording events from a provider. If capture-state is supported by a provider, it might respond to the capture-state request by logging state information, e.g. configuration information or summary statistics regarding the component's operation prior to the request.
The Level value that ETW passes to the callback is the highest (most verbose) level value specified for this event provider by any running trace session. For example, if session A has enabled this provider for warning (level 3) events and then session B enables the provider for critical (level 1) events, the Level value for the callback will be 3, not 1.
Similarly, the MatchAnyKeyword and MatchAllKeyword values are composite values computed from the configuration of all sessions that have enabled the event provider. MatchAnyKeyword is the OR of the EnableFlags/MatchAnyKeyword settings of the sessions. MatchAllKeyword is the AND of the MatchAllKeyword settings of the sessions.
If the provider's EnableCallback function has captured the provider's Enabled, Level, MatchAnyKeyword, and MatchAllKeyword state, the provider can determine whether an event should be written using a function like the following:
BOOL MyProviderEventEnabled(
_In_ const MY_PROVIDER_STATE* pProvider,
_In_ const EVENT_DESCRIPTOR* pEvent)
{
return
pProvider->Enabled &&
pEvent->Level <= pProvider->Level &&
(pEvent->Keyword == 0 || (
(pEvent->Keyword & pProvider->MatchAnyKeyword) != 0 &&
(pEvent->Keyword & pProvider->MatchAllKeyword) == pProvider->MatchAllKeyword
));
}
Requirements
Requirement | Value |
---|---|
Minimum supported client | Windows Vista [desktop apps only] |
Minimum supported server | Windows Server 2008 [desktop apps only] |
Target Platform | Windows |
Header | evntprov.h |