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 = PASSIVE_LEVEL任意线程上下文中发送此 IRP。

输入参数

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

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

Parameters.WMI.BufferSize 指示 Parameters.WMI.Buffer 的非分页缓冲区的最大大小,该缓冲区从请求接收输出数据。 缓冲区大小必须大于或等于 (WNODE_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 开始的 InstanceCountOFFSETINSTANCEDATAANDLENGTH 结构的数组。 每个 OFFSETINSTANCEDATAANDLENGTH 结构指定从 WNODE_ALL_DATA 结构开头到每个实例的数据开头的偏移量(以字节为单位),以及数据的长度。 不使用 DataBlockOffset

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

如果 Parameters.WMI.Buffer 中的缓冲区太小,无法接收所有数据,驱动程序会在 Parameters.WMI.Buffer的WNODE_TOO_SMALL结构中填充所需的大小。 如果 缓冲区小于 (WNODE_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 缓冲区的缓冲区的字节数。

Operation

驱动程序可以通过调用 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