IRP_MN_CHANGE_SINGLE_ITEM
所有支持 WMI 的驱动程序都必须处理此 IRP。 驱动程序可以通过调用 WmiSystemControl 或通过处理 IRP 本身来处理 WMI IRP,如 处理 WMI 请求中所述。
如果驱动程序调用 WmiSystemControl 来处理 IRP_MN_CHANGE_SINGLE_ITEM 请求,则 WMI 又调用该驱动程序的 DpWmiSetDataItem 例程。
主代码
发送时
WMI 发送此 IRP 以更改数据块的单个实例中的单个数据项。
WMI 在 IRQL = PASSIVE_LEVEL任意线程上下文中发送此 IRP。
输入参数
Parameters.WMI.ProviderId 指向应响应请求的驱动程序的设备对象。 此指针位于 IRP 中驱动程序的 I/O 堆栈位置。
Parameters.WMI.DataPath 指向标识要设置的数据块的 GUID。
Parameters.WMI.BufferSize 指示 Parameters.WMI.Buffer 中非分页缓冲区的大小。
Parameters.WMI.Buffer 指向 WNODE_SINGLE_ITEM 结构,该结构标识数据块的实例、要设置的项的 ID 以及新的数据值。
输出参数
无。
I/O 状态块
如果驱动程序通过调用 WmiSystemControl 处理 IRP,则 WMI 在 I/O 状态块中设置 Irp-IoStatus.Status> 和 Irp-IoStatus.Information>。
否则,驱动程序会将 Irp-IoStatus.Status> 设置为STATUS_SUCCESS或相应的错误状态,如下所示:
STATUS_WMI_INSTANCE_NOT_FOUND
STATUS_WMI_ITEMID_NOT_FOUND
STATUS_WMI_GUID_NOT_FOUND
STATUS_WMI_READ_ONLY
STATUS_WMI_SET_FAILURE
成功后,驱动程序会将 Irp-IoStatus.Information> 设置为零。
Operation
如果驱动程序通过调用 WmiSystemControl 处理 WMI IRP,则该例程将调用驱动程序的 DpWmiSetDataItem 例程,如果驱动程序未定义例程,则返回STATUS_WMI_READ_ONLY。
如果驱动程序处理 IRP_MN_CHANGE_SINGLE_ITEM 请求本身,则仅当 Parameters.WMI.ProviderId 指向与驱动程序传递给 IoWMIRegistrationControl 的指针相同的设备对象时,它才应执行此操作。 否则,驱动程序必须将请求转发到下一个较低的驱动程序。
除非确信系统提供的用户模式组件需要此功能,否则不要实现 对IRP_MN_CHANGE_SINGLE_ITEM 的支持。
在处理请求之前,驱动程序必须确定 Parameters.WMI.DataPath 是否指向驱动程序支持的 GUID。 否则,驱动程序必须使 IRP 失败并返回STATUS_WMI_GUID_NOT_FOUND。
如果驱动程序支持数据块,则必须检查 Parameters.WMI.Buffer 指向的输入WNODE_SINGLE_ITEM结构作为实例名称,如下所示:
如果在 WnodeHeader.Flags 中设置了WNODE_FLAG_STATIC_INSTANCE_NAMES,则驱动程序使用 InstanceIndex 作为该块的驱动程序静态实例名称列表中的索引。 WMI 在注册块时从驱动程序提供的注册数据中获取索引。
如果在 WnodeHeader.Flags 中清除WNODE_FLAG_STATIC_INSTANCE_NAMES,驱动程序将使用 OffsetInstanceName 上的偏移量在输入 WNODE_SINGLE_ITEM 结构中查找实例名称字符串。 OffsetInstanceName 是从结构开头到实例名称字符串 USHORT 大小的长度(以字节为单位)的偏移量(以字节为单位 (而不是字符) )。 此长度包括 NULL 终止符(如果存在),后跟 Unicode 中的实例名称字符串。
驱动程序负责验证所有输入值。 具体而言,如果驱动程序处理 IRP 请求本身,则必须执行以下操作:
对于静态名称,请验证 WNODE_SINGLE_ITEM 结构的 InstanceIndex 成员是否在数据块驱动程序支持的实例索引范围内。
对于动态名称,请验证实例名称字符串是否标识驱动程序支持的数据块实例。
验证 WNODE_SINGLE_ITEM 结构的 ItemId 成员是否在数据块驱动程序支持的项标识符范围内。
验证 WNODE_SINGLE_ITEM 结构的 DataBlockOffset 和 SizeDataItem 成员是否描述有效大小的数据块,以及缓冲区的内容是否对数据项有效。
验证指定的数据项是否是驱动程序允许调用方发起的修改的数据项。 换句话说,驱动程序不应允许修改你打算为只读的数据项。
不要假设线程上下文是正在启动的用户模式应用程序的上下文,更高级别的驱动程序可能已更改它。
如果驱动程序找不到指定的实例,则必须使 IRP 失败并返回STATUS_WMI_INSTANCE_NOT_FOUND。 对于具有动态实例名称的实例,此状态指示驱动程序不支持该实例。 因此,WMI 可以继续查询其他数据访问接口,如果另一个提供程序找到该实例,但由于其他原因而无法处理请求,则向数据使用者返回相应的错误。
如果驱动程序找到实例并可以处理请求,则会将实例中的数据项设置为 WNODE_SINGLE_ITEM中的值。 如果数据项是只读的,则驱动程序使项保持不变,使 IRP 失败,并返回STATUS_WMI_READ_ONLY。
如果实例有效,但驱动程序无法处理请求,它可以返回任何适当的错误状态。
要求
标头 |
Wdm.h(包括 Wdm.h、Ntddk.h 或 Ntifs.h) |