EtwWrite 函数 (wdm.h)
EtwWrite 函数是用于在内核模式驱动程序代码中发布事件的跟踪函数。
语法
NTSTATUS EtwWrite(
[in] REGHANDLE RegHandle,
[in] PCEVENT_DESCRIPTOR EventDescriptor,
[in, optional] LPCGUID ActivityId,
[in] ULONG UserDataCount,
[in, optional] PEVENT_DATA_DESCRIPTOR UserData
);
参数
[in] RegHandle
指向事件提供程序注册句柄的指针,如果事件提供程序注册成功,则由 EtwRegister 函数返回。
[in] EventDescriptor
指向 EVENT_DESCRIPTOR 结构的指针。
[in, optional] ActivityId
指示与事件关联的活动的标识符。 ActivityID 提供了一种方法来对相关事件进行分组,并在端到端跟踪中使用。
[in] UserDataCount
UserData中的EVENT_DATA_DESCRIPTOR结构数。
[in, optional] UserData
指向EVENT_DATA_DESCRIPTOR结构的数组的指针。
返回值
如果成功发布事件,EtwWrite 返回STATUS_SUCCESS。
如果指向事件提供程序注册句柄的指针无效,EtwWrite 返回STATUS_INVALID_HANDLE。 在 调用 EtwWrite 之前,必须先注册事件提供程序。 如果 EtwWrite 无法记录事件,则 EtwWrite 也可以返回STATUS_INVALID_HANDLE。
如果 UserDataCount 中指定的EVENT_DATA_DESCRIPTOR结构数大于允许的最大结构数(128),EtwWrite 返回STATUS_INVALID_PARAMETER。
如果指定 了 activityID,但内存不足,无法记录与事件关联的数据,EtwWrite 返回STATUS_NO_MEMORY。
如果未为任何会话启用提供程序,EtwWrite 将返回STATUS_SUCCESS,并且不会记录事件。
由于多种原因,事件可能会丢失;例如,如果事件速率过高或事件大小大于缓冲区大小。 在这些情况下,EventsLost 计数器(相应记录器EVENT_TRACE_PROPERTIES结构的成员)使用未记录的事件数进行更新。
言论
EtwWrite 函数是与 user-mode EventWrite 函数等效的内核模式。 若要确保发布事件有使用者,可以在调用 EtwWrite etwWrite 之前调用 EtwEventEnabled 或 EtwProviderEnabled。
在调用 EtwWrite 函数发布事件之前,必须将提供程序注册到 EtwRegister。 不应对 EtwRegister 和 EtwUnregister 函数绑定的代码之外进行跟踪调用。 为了获得最佳性能,可以在 DriverEntry 例程中调用 EtwRegister 函数,并在 DriverUnload 例程中调用 EtwUnregister 函数。
如果在 EtwWrite 函数中使用可选的 UserData 参数来记录其他事件数据,则可以使用 EventDataDescCreate 宏来简化EVENT_DATA_DESCRIPTOR结构的创建。 以下示例使用 EventDataDescCreate 宏使用设备名称及其状态初始化EVENT_DATA_DESCRIPTOR结构。 EventDataDescCreate 宏存储指向数据的指针(即,它不存储数据的副本)。 指针必须保持有效,直到调用 EtwWrite 返回。
可以在任何 IRQL 中调用 EtwWrite。 但是,当 IRQL 大于APC_LEVEL时,传递给 EtwWrite、EtwWriteEx、EtwWriteString、EtwWriteTransfer 函数的任何数据不得分页。 也就是说,在大于 APC_LEVEL 的 IRQL 上运行的任何内核模式例程都无法访问可分页内存。 传递给 EtwWrite、EtwWriteEx、EtwWriteString和 EtwWriteTransfer 函数的数据必须驻留在系统空间内存中,而不考虑 IRQL 是什么。
例
//
// Register the provider with ETW in DriverEntry
// Unregister the provider in DriverUnload
//
// Build the EVENT_DATA_DESCRIPTOR structures using
// the EventDataDescCreate macros
if (RegHandle != (REGHANDLE)NULL) {
//
// Log an Event with : DeviceNameLength
// DeviceName
// Status
//
EventDataDescCreate(&EventDataDescriptor[0],
(PVOID)&DeviceName.Length,
sizeof(USHORT));
EventDataDescCreate(&EventDataDescriptor[1],
(PVOID)DeviceName.Buffer,
DeviceName.Length);
EventDataDescCreate(&EventDataDescriptor[2],
(PVOID)&Status,
sizeof(ULONG));
EtwWrite(RegHandle, // Handle from EtwRegister
&StartEvent, // EventDescriptor
NULL, // Activity ID
3, // Number of data items
EventDataDescriptor); // Array of data descriptors
}
//
要求
要求 | 价值 |
---|---|
目标平台 | 普遍 |
标头 | wdm.h (包括 Wdm.h、Ntddk.h) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | 任何级别 (请参阅“批注”部分)。 |