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 之前调用 EtwEventEnabledEtwProviderEnabled

在调用 EtwWrite 函数发布事件之前,必须将提供程序注册到 EtwRegister。 不应对 EtwRegisterEtwUnregister 函数绑定的代码之外进行跟踪调用。 为了获得最佳性能,可以在 DriverEntry 例程中调用 EtwRegister 函数,并在 DriverUnload 例程中调用 EtwUnregister 函数。

如果在 EtwWrite 函数中使用可选的 UserData 参数来记录其他事件数据,则可以使用 EventDataDescCreate 宏来简化EVENT_DATA_DESCRIPTOR结构的创建。 以下示例使用 EventDataDescCreate 宏使用设备名称及其状态初始化EVENT_DATA_DESCRIPTOR结构。 EventDataDescCreate 宏存储指向数据的指针(即,它不存储数据的副本)。 指针必须保持有效,直到调用 EtwWrite 返回。

可以在任何 IRQL 中调用 EtwWrite。 但是,当 IRQL 大于APC_LEVEL时,传递给 EtwWriteEtwWriteExEtwWriteStringEtwWriteTransfer 函数的任何数据不得分页。 也就是说,在大于 APC_LEVEL 的 IRQL 上运行的任何内核模式例程都无法访问可分页内存。 传递给 EtwWriteEtwWriteExEtwWriteStringEtwWriteTransfer 函数的数据必须驻留在系统空间内存中,而不考虑 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 任何级别 (请参阅“批注”部分)。

另请参阅

EtwEventEnabled

EtwProviderEnabled

EtwRegister

EtwUnregister

EtwWriteEx

EtwWriteString

EtwWriteTransfer

EventDataDescCreate