本部分介绍 WDM 的 WMI 扩展(由 Windows 2000 及更高版本支持),内核模式驱动程序(作为信息提供程序)可用于向信息使用者提供信息。 驱动程序通常提供使用者用来确定驱动程序的配置和资源使用情况的信息。 除了 WDM 的 WMI 扩展之外,用户模式 API 还支持 WMI 事件信息的提供程序或使用者,有关详细信息,请参阅 Windows SDK。
事件跟踪记录器最多支持 32 个实例。 其中一个实例保留用于跟踪内核。 记录器支持跟踪高事件率。
跟踪事件的定义方式与其他 WMI 事件相同。 MOF 文件中描述了 WMI 事件。 有关 WMI 事件说明的详细信息,请参阅 WMI 数据和事件块的 MOF 语法。
内核模式驱动程序日志信息集成到现有 WMI 基础结构的过程。 若要记录跟踪事件,驱动程序执行以下作:
要注册为 WMI 提供程序,请调用 IoWMIRegistrationControl。
通过在驱动程序向 WMI 注册事件时传递的 WMIREGGUID 结构的 Flags 成员中设置WMIREG_FLAG_TRACED_GUID,将事件标记为可跟踪。
通过在驱动程序使用 WMIREGGUID 结构向 WMI 注册事件时传递的 Flags 成员中设置 WMIREG_FLAG_TRACE_CONTROL_GUID,将某个事件指定为用于整体启用/禁用一组跟踪事件的控制事件。
从收到 WMI 的请求以启用 GUID 与跟踪控制 GUID 匹配的事件后,驱动程序应将句柄存储到日志记录器。 编写事件时需要该值。 有关如何使用此句柄的信息,请参阅步骤 6。 记录器句柄值包含在启用事件请求的参数中WMI缓冲区的WNODE_HEADER部分内HistoricalContext成员中。
决定是否将跟踪事件发送到 WMI 事件使用者,还是仅针对 WMI 事件日志器。 这将确定 EVENT_TRACE_HEADER 结构的内存应来自何处。 此内存最终将传递到 IoWMIWriteEvent。
如果事件只是日志事件,则 WMI 不会删除内存。 在这种情况下,驱动程序应传入堆栈上的缓冲区,或者应为此重用分配的缓冲区。 出于性能原因,驱动程序应尽量减少任何不必要的调用来分配或释放内存。 不符合此建议将损害日志文件中包含的计时信息的完整性。
如果要将事件同时发送到记录器和 WMI 事件使用者,则必须从非分页池分配内存。 在这种情况下,事件将发送到记录器,然后转发到 WMI,以发送到请求事件通知的 WMI 事件使用者。 然后,根据 IoWMIWriteEvent 的行为,WMI 释放事件的内存。
在 EVENT_TRACE_HEADER 的内存和任何驱动程序事件数据(如果有)已得到保护之后,应设置以下信息:
将Size成员设置为 sizeof(EVENT_TRACE_HEADER)加上将追加到EVENT_TRACE_HEADER末尾的任何其他驱动程序事件数据的大小。
将 Flags 成员设置为 WNODE_FLAG_TRACED_GUID,以便将事件发送到记录器。 如果要将事件发送到 WMI 事件使用者,请设置WNODE_FLAG_LOG_WNODE。 请注意,如果设置WNODE_FLAG_LOG_WNODE,则无需设置WNODE_FLAG_TRACED_GUID。 如果两者都已设置,WNODE_FLAG_TRACED_GUID将优先,并且不会将事件发送到 WMI 事件使用者。
设置 Guid 或 GuidPtr 成员。 如果使用 GuidPtr,请设置 Flags 成员中的WNODE_FLAG_USE_GUID_PTR。
(可选)指定 TimeStamp 的值。 如果驱动程序未指定 TimeStamp 值,记录器将填写此值。 如果驱动程序不希望记录器设置时间戳,则应在 Flags 成员中设置WNODE_FLAG_USE_TIMESTAMP。
设置以下任何 EVENT_TRACE_HEADER 对驱动程序有意义的成员: Class.Type、 Class.Level 和 Class.Version。
最后,将EVENT_TRACE_HEADER转换为WNODE_HEADER,并将Wnode的HistoricalContext值设置为在上述步骤 4 中保存的记录器句柄。
使用指向EVENT_TRACE_HEADER结构的指针调用 IoWMIWriteEvent。
驱动程序应继续记录与控制 GUID 关联的跟踪事件,直到驱动程序收到通知以通过 IRP_MN_DISABLE_EVENTS 请求禁用事件日志记录。