IRP_MN_EXECUTE_METHOD

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

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

主代码

IRP_MJ_SYSTEM_CONTROL

发送时

WMI 发送此 IRP 以执行与数据块关联的方法。

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

WMI 将在发送 IRP_MN_EXECUTE_METHOD 之前发送 IRP_MN_QUERY_SINGLE_INSTANCE。 如果驱动程序支持 IRP_MN_EXECUTE_METHOD 则它必须为正在执行其方法的相同数据块具有 IRP_MN_QUERY_SINGLE_INSTANCE 处理程序。

输入参数

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

Parameters.WMI.DataPath 指向标识与要执行的方法关联的数据块的 GUID。

Parameters.WMI.BufferSize 指示 Parameters.WMI.Buffer 中非分页缓冲区的大小,该缓冲区必须为 >= sizeof (WNODE_METHOD_ITEM) 加上方法的任何输出数据的大小。

Parameters.WMI.Buffer 指向 WNODE_METHOD_ITEM 结构,其中 MethodID 指示要执行的方法的标识符, DataBlockOffset 指示从结构开头到输入数据的第一个字节(如果有)的偏移量(以字节为单位)。 Parameters.WMI.Buffer->SizeDataBlock 指示输入 WNODE_METHOD_ITEM (包括输入数据)的大小(以字节为单位),如果没有输入,则为零。

输出参数

如果驱动程序通过调用 WmiSystemControl 处理 WMI IRP,则 WMI 使用驱动程序的 DpWmiExecuteMethod 例程返回的数据填充WNODE_METHOD_ITEM

否则,驱动程序将填充 Parameters.WMI.Buffer 指向的WNODE_METHOD_ITEM结构,如下所示:

  • 汇报 WnodeHeader.BufferSize,其中包含输出WNODE_METHOD_ITEM的大小,包括任何输出数据。

  • 使用输出数据的大小汇报 SizeDataBlock;如果没有输出数据,则为零。

  • 检查 Parameters.WMI.Buffersize 以确定缓冲区是否足够大,以接收输出 WNODE_METHOD_ITEM 包括任何输出数据。 如果缓冲区不够大,驱动程序在 Parameters.WMI.Buffer 指向的WNODE_TOO_SMALL结构中填充所需的大小。 如果 缓冲区小于 (WNODE_TOO_SMALL) 的大小,驱动程序将失败 IRP 并返回STATUS_BUFFER_TOO_SMALL。

  • DataBlockOffset 开始,通过输入数据写入输出数据(如果有)。 驱动程序不得更改 DataBlockOffset 的输入值。

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

STATUS_WMI_INSTANCE_NOT_FOUND

STATUS_WMI_ITEMID_NOT_FOUND

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

Operation

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

如果驱动程序通过调用 WmiSystemControl 处理 WMI IRP,则该例程将调用驱动程序的 DpWmiExecuteMethod 例程;如果驱动程序未定义例程,则返回STATUS_INVALID_DEVICE_REQUEST。

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

驱动程序负责验证所有输入值。 具体而言,如果驱动程序处理 IRP 请求本身,则必须执行以下操作:

  • 对于静态名称,请验证 WNODE_METHOD_ITEM 结构的 InstanceIndex 成员是否在数据块驱动程序支持的实例索引范围内。

  • 对于动态名称,请验证实例名称字符串是否标识驱动程序支持的数据块实例。

  • 验证 WNODE_METHOD_ITEM 结构的 MethodId 成员是否在数据块驱动程序支持的方法标识符范围内,以及是否允许调用方执行该方法。

  • 验证 WNODE_METHOD_ITEM 结构的 DataBlockOffsetSizeDataBlock 成员描述的缓冲区是否足够大,足以包含指定方法的参数,以及参数是否对方法有效。

  • 验证 Parameters.WMI.Buffersize 是否指定了一个足够大的缓冲区,以在使用输出数据进行更新后接收 WNODE_METHOD_ITEM 结构。

不要假设线程上下文是发起的用户模式应用程序的上下文 , 更高级别的驱动程序可能已更改它。

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

如果驱动程序支持数据块,它会在 Parameters.WMI.Buffer 处检查输入WNODE_METHOD_ITEM实例名称,如下所示:

  • 如果在 WnodeHeader.Flags 中设置了WNODE_FLAG_STATIC_INSTANCE_NAMES,则驱动程序使用 InstanceIndex 作为该块的驱动程序静态实例名称列表中的索引。 WMI 从驱动程序在注册块时提供的注册数据获取索引。

  • 如果在 WnodeHeader.Flags 中清除WNODE_FLAG_STATIC_INSTANCE_NAMES,驱动程序将使用 OffsetInstanceName 上的偏移量在输入 WNODE_METHOD_ITEM中找到实例名称字符串。 OffsetInstanceName 是结构开头到 USHORT 的偏移量(以字节为单位),它是实例名称字符串的长度(以字节 (而不是字符) ,包括终止 null(如果存在),后跟 Unicode 中的实例名称字符串。

如果驱动程序找不到指定的实例,则必须使 IRP 失败并返回STATUS_WMI_INSTANCE_NOT_FOUND。 对于具有动态实例名称的实例,此状态指示驱动程序不支持该实例。 因此,WMI 可以继续查询其他数据访问接口,如果另一个提供程序找到该实例,但由于其他原因而无法处理请求,则向数据使用者返回相应的错误。

然后,驱动程序检查输入 WNODE_METHOD_ITEM 中的方法 ID,以确定它是否是该数据块的有效方法。 否则,驱动程序将失败 IRP 并返回STATUS_WMI_ITEMID_NOT_FOUND。

如果方法生成输出,驱动程序应先检查 Parameters.WMI.BufferSize 中输出缓冲区的大小,然后再执行任何可能有副作用或不应执行两次的操作。 例如,如果方法返回一组计数器的值,然后重置计数器,则在重置计数器之前,驱动程序应检查缓冲区大小 (,如果缓冲区太小) ,则 IRP 失败。 这可确保 WMI 可以使用较大的缓冲区安全地重新发送请求。

如果实例和方法 ID 有效且缓冲区大小足够,驱动程序将执行 方法。 如果输入WNODE_METHOD_ITEM中的 SizeDataBlock 为非零值,则驱动程序使用从 DataBlockOffset 开始的数据作为 方法的输入。

如果 方法生成输出,驱动程序会将输出数据从 DataBlockOffset 开始写入缓冲区,并将输出WNODE_METHOD_ITEM中的 SizeDataBlock 设置为输出数据的字节数。 如果 方法没有输出数据,驱动程序会将 SizeDataBlock 设置为零。 驱动程序不得更改 DataBlockOffset 的输入值。

如果实例有效,但驱动程序无法处理请求,它可以返回任何适当的错误状态。

要求

标头

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

另请参阅

DpWmiExecuteMethod

IoWMIRegistrationControl

WMILIB_CONTEXT

WmiSystemControl

WNODE_METHOD_ITEM