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 无法记录事件,也可以返回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 函数是用户模式 EventWrite 函数的内核模式等效函数。 为了确保要发布的事件有使用者,可以在调用 EtwWrite 之前调用 EtwEventEnabled 或 EtwProviderEnabled。
必须先向 EtwRegister 注册提供程序,然后才能调用 EtwWrite 函数发布事件。 不应在 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) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | 任何级别 (“查看注释”部分。) |