IRP_MN_QUERY_ALL_DATA

支持 WMI 的所有驱动程序都必须处理此 IRP。 驱动程序可以通过调用 WmiSystemControl 或处理 IRP 本身来处理 WMI IRP,如处理 WMI 请求中所述

如果驱动程序调用 WmiSystemControl 来处理IRP_MN_QUERY_ALL_DATA请求,WMI 又调用该驱动程序的 DpWmiQueryDataBlock 例程。

主要代码

IRP_MJ_SYSTEM_CONTROL

发送时间

WMI 发送此 IRP 来查询给定数据块的所有实例。

WMI 在 IRQL 处发送此 IRP = 在任意线程上下文中PASSIVE_LEVEL。

输入参数

IRP 中驱动程序 I/O 堆栈位置中的 Parameters.WMI.ProviderId 指向应响应请求的驱动程序的设备对象。

Parameters.WMI.DataPath 指向标识数据块的 GUID。

Parameters.WMI.BufferSize 指示 Parameters.WMI.Buffer 中非分页缓冲区的最大大小,该缓冲区从请求接收输出数据。 缓冲区大小必须大于或等于 sizeofWNODE_ALL_DATA),以及要返回的所有实例的实例名称和数据的大小。

输出参数

如果驱动程序通过调用 WmiSystemControl 处理 WMI IRP,则 WMI 通过针对驱动程序注册的每个块调用驱动程序的 DpWmiQueryDataBlock 例程一次填充WNODE_ALL_DATA

否则,驱动程序会在 Parameters.WMI.Buffer 中填充WNODE_ALL_DATA结构,如下所示:

  • WnodeHeader.BufferSize 设置为要返回的整个WNODE_ALL_DATA的字节数,将 WnodeHeader.Timestamp 设置为 KeQuerySystemTime 返回的值,并根据需要设置要返回的数据的 WnodeHeader.Flags

  • 将 InstanceCount 设置为要返回的实例数。

  • 如果块使用动态实例名称,将 OffsetInstanceNameOffsets 设置为从WNODE_ALL_DATA开头到 ULONG 偏移数组开始位置的偏移量(以字节为单位)。 此数组中的每个元素都是从 存储每个动态实例名称的WNODE_ALL_DATA 偏移量。 每个动态实例名称都存储为计数的 Unicode 字符串,其中计数是 USHORT,后跟 Unicode 字符串。 计数不包括可能属于 Unicode 字符串的任何终止 null 字符。 如果 Unicode 字符串包含终止 null 字符,则此 null 字符仍必须符合 WNodeHeader.BufferSize建立的大小。

  • 如果所有实例的大小都相同:

    • 在 WnodeHeader.Flags设置WNODE_FLAG_FIXED_INSTANCE_SIZE,并将 FixedInstanceSize 设置为该大小(以字节为单位)。
    • 写入从 DataBlockOffset 开始的实例数据,并填充,以便每个实例都与 8 字节边界对齐。 例如,如果 FixedInstanceSize 为 6,驱动程序会在实例之间添加 2 个字节的填充。
  • 如果实例的大小不同:

    • 清除 WnodeHeader.Flags 中的WNODE_FLAG_FIXED_INSTANCE_SIZE,并从 OffsetInstanceDataAndLength 开始写入 InstanceCount OFFSETINSTANCEDATAANDLENGTH 结构的数组 每个 OFFSETINSTANCEDATAANDLENGTH 结构指定从WNODE_ALL_DATA结构的开头到每个实例的数据开头的偏移量(以字节为单位)以及数据的长度。 未使用 DataBlockOffset

    • 在 OffsetInstanceDataAndLength 数组的最后一个元素之后写入实例数据,以及填充,以便每个实例都与 8 字节边界对齐。

如果 Parameters.WMI.Buffer 上的缓冲区太小,无法接收所有数据,驱动程序会在 Parameters.WMI.Buffer 的WNODE_TOO_SMALL结构填充所需的大小。 如果缓冲区小于 sizeofWNODE_TOO_SMALL),驱动程序将失败 IRP 并返回STATUS_BUFFER_TOO_SMALL。

I/O 状态块

如果驱动程序通过调用 WmiSystemControl 处理 IRP,WMI 在 I/O 状态块中设置 Irp-IoStatus.Status>Irp-IoStatus.Information>

否则,驱动程序会将 Irp-IoStatus.Status> 设置为STATUS_SUCCESS或相应的错误状态,例如:

STATUS_BUFFER_TOO_SMALL

STATUS_WMI_GUID_NOT_FOUND

成功后,驱动程序会将 Irp-IoStatus.Information> 设置为在 Parameters.WMI.Buffer写入缓冲区的字节数。

操作

驱动程序可以通过调用 WmiSystemControl 或处理 IRP 本身来处理 WMI IRP,如处理 WMI 请求中所述

如果驱动程序通过调用 WmiSystemControl 处理 WMI IRP,该例程将调用驱动程序的 DpWmiQueryDataBlock 例程。

如果驱动程序处理IRP_MN_QUERY_ALL_DATA请求,则仅当 Parameters.WMI.ProviderId 指向传递给 IoWMIRegistrationControl 的同一设备对象时,它才应执行此操作。 否则,驱动程序必须将请求转发到下一个较低的驱动程序。

在处理请求之前,驱动程序必须确定 Parameters.WMI.DataPath 是否指向驱动程序支持的 GUID。 否则,驱动程序必须失败 IRP 并返回STATUS_WMI_GUID_NOT_FOUND。

如果驱动程序支持数据块,则必须执行以下操作:

  • 验证 Parameters.WMI.BufferSize 是否指定一个足够大的缓冲区,以接收驱动程序将返回的所有数据。

  • 在 Parameters.WMI.Buffer 中填写一个WNODE_ALL_DATA结构,其中包含该数据块的所有实例的数据。

要求

头文件

Wdm.h(包括 Wdm.h、Ntddk.h 或 Ntifs.h)

另请参阅

DpWmiQueryDataBlock

IoWMIRegistrationControl

KeQuerySystemTime

WMILIB_CONTEXT

WmiSystemControl

WNODE_ALL_DATA