使用 IoWMIWriteEvent 发送事件
驱动程序可以调用 IoWMIWriteEvent 来发送任何事件。 事件可以包含单个项、单个实例或数据块的所有实例,并且可以使用动态实例名称。
与通过查询或更改请求传递 的WNODE_XXX 结构不同,这些结构由 WMI 分配和部分初始化,驱动程序必须分配并初始化包含事件的 WNODE_XXX 结构的所有成员。
只有在 WMI 发送 了启用事件的IRP_MN_ENABLE_EVENTS 请求后,驱动程序才必须发送事件。 然后,当事件发生的触发条件时,驱动程序会:
从非分页池分配缓冲区,以包含事件所需的 WNODE_XXX 结构,包括变量数据的空间(如果有)。
根据事件,驱动程序可能会为事件分配 WNODE_SINGLE_ITEM、 WNODE_SINGLE_INSTANCE或 WNODE_ALL_DATA 。 WNODE_XXX 加上变量数据的大小不得超过注册表定义的 1K 限制。
初始化 WNODE_XXX 结构的所有成员,包括 WnodeHeader.Flags:
驱动程序设置 WNODE_FLAG_EVENT_ITEM 标志以指示结构是事件。
驱动程序设置以下标志之一来指示 WNODE_XXX 结构的类型:
WNODE_FLAG_ALL_DATA
WNODE_FLAG_SINGLE_INSTANCE
WNODE_FLAG_SINGLE_ITEM
驱动程序设置或清除以下标志,以指示块是使用静态实例名称还是动态实例名称:
WNODE_FLAG_STATIC_INSTANCE_NAMES
WNODE_FLAG_PDO_INSTANCE_NAMES
驱动程序可能会根据事件设置其他标志。
将指向 WNODE_XXX 的指针强制转换为PWNODE_EVENT_ITEM。
使用 指针调用 IoWMIWriteEvent 。
如果 IoWMIWriteEvent 成功完成,WMI 会释放事件驱动程序分配的内存。
IoWMIWriteEvent 返回后,驱动程序将继续监视事件的触发条件,并在每次触发条件发生时发送事件,直到 WMI 发送IRP_MN_DISABLE_EVENTS请求来禁用该事件。
如果事件的大小超过注册表定义的最大值 1K (不建议) 驱动程序应使用初始化WNODE_EVENT_REFERENCE调用 IoWmiWriteEvent ,该初始化 WNODE_EVENT_REFERENCE 指定事件的 GUID、大小以及静态实例名称的实例索引 (,) 或动态实例名称的名称 () 。 WMI 将使用 WNODE_EVENT_REFERENCE 中的信息来查询事件。
驱动程序可以通过调用 WMI 库例程 WmiFireEvent 发送不使用动态实例名称且包含单个实例的事件。 驱动程序不需要为 WmiFireEvent 调用分配和初始化 WNODE_XXX 结构。 WMI 将驱动程序的事件数据打包在 WNODE_SINGLE_INSTANCE 中,并将其传递给数据使用者。 有关使用 WmiFireEvent 发送事件的详细信息,请参阅 使用 WmiFireEvent 发送事件。