调用 WmiSystemControl 以处理 WMI IRP
WMI 库例程简化了 WMI 请求的处理,因为驱动程序调用 WmiSystemControl,而不是处理每个此类请求。 在 WmiSystemControl 调用中,驱动程序将包含入口点 的初始化WMILIB_CONTEXT 结构传递到驱动程序的 WMI 库回调例程 (DpWmiXxx 例程) 以及有关驱动程序的数据块和事件块的信息。
由于 WMI 库不提供传递动态实例名称或静态实例名称列表的机制,因此驱动程序可以使用 WMI 库来处理仅涉及基于 PDO 或单个基名称字符串的静态实例名称的数据块的请求。 有关静态和动态实例名称的详细信息,请参阅 定义 WMI 实例名称。 不会阻止驱动程序使用 WMI 库处理此类块的请求,并在其 DispatchSystemControl 例程中处理其他块的请求。 有关详细信息,请参阅 在 DispatchSystemControl 例程中处理 WMI IRP。
若要通过调用 WmiSystemControl 处理 WMI IRP,驱动程序必须实现某些必需的 DpWmiXxx 回调例程,并且可能实现其他可选的 DpWmiXxx 回调例程:
DpWmiQueryReginfo - (必需) 提供有关驱动程序注册的数据和事件块的信息。 WMI 调用驱动程序的 DpWmiQueryReginfo 例程来处理 IRP_MN_REGINFO 或 IRP_MN_REGINFO_EX 请求。 有关详细信息,请参阅 使用 WMI 库注册块。
DpWmiQueryDataBlock — (必需) 返回数据块的单个实例或所有实例。 WMI 调用驱动程序的 DpWmiQueryDataBlock 例程来处理 IRP_MN_QUERY_SINGLE_INSTANCE 或 IRP_MN_QUERY_ALL_DATA 请求。
DpWmiSetDataBlock - (可选) 更改数据块的单个实例中的所有数据项。 WMI 调用驱动程序的 DpWmiSetDataBlock 例程来处理 IRP_MN_CHANGE_SINGLE_INSTANCE 请求。
DpWmiSetDataItem - (可选) 更改数据块实例中的单个数据项。 WMI 调用驱动程序的 DpWmiSetDataItem 例程来处理 IRP_MN_CHANGE_SINGLE_ITEM 请求。
DpWmiFunctionControl - (可选) 为注册为收集成本高昂的块启用和禁用事件通知和数据收集。 WMI 调用驱动程序的 DpWmiFunctionControl 例程来处理 IRP_MN_ENABLE_COLLECTION、 IRP_MN_DISABLE_COLLECTION、 IRP_MN_ENABLE_EVENTS或 IRP_MN_DISABLE_EVENTS 请求。
DpWmiExecuteMethod - (Optional) 执行与数据块关联的方法。 WMI 调用驱动程序的 DpWmiExecuteMethod 例程来处理 IRP_MN_EXECUTE_METHOD 请求。
驱动程序的 DpWmiXxx 例程可以具有驱动程序编写器选择的任何名称。
在调用 WmiSystemControl 之前,驱动程序必须使用其 DpWmiXxx 例程的入口点以及有关其数据块和事件块的信息初始化WMILIB_CONTEXT结构。
当驱动程序收到 WMI 请求时:
驱动程序使用指向其初始化WMILIB_CONTEXT结构的指针、指向其设备对象的指针和指向 IRP 的指针调用 WmiSystemControl。
WMI 验证 IRP 参数并调用处理请求的驱动程序的 DpWmiXxx 例程。 如果驱动程序在其 WMILIB_CONTEXT 中没有为可选 DpWmiXxx 例程设置入口点,则 WMI 使用默认值和状态完成 IRP。
在其 DpWmiXxx 例程中,驱动程序处理请求并将任何输出写入调用方提供的缓冲区。 例如,驱动程序的 DpWmiQueryDataBlock 例程会将所请求的实例 (指定块的) 写入缓冲区。
在所有 DpWmiXxx 例程( DpWmiQueryReginfo 除外)中,驱动程序调用 WmiCompleteRequest 来完成请求,或返回STATUS_PENDING以推迟完成,就像对于任何 IRP 一样。
WMI 执行任何必要的后处理,将任何输出打包在适当的 WNODE_XXX 结构中,并将输出和状态传递给数据使用者。