IRP_MN_DEVICE_USAGE_NOTIFICATION

系统组件发送此 IRP,询问设备的驱动程序设备是否可以支持 特殊文件。 特殊文件包括分页文件、转储文件和休眠文件。 如果设备的所有驱动程序都成功执行 IRP,系统会创建特殊文件。 系统还会发送此 IRP,通知驱动程序已从设备中删除了一个特殊文件。

如果函数驱动程序的设备可以包含分页文件、转储文件或休眠文件,则必须处理此 IRP。 如果筛选的函数驱动程序处理 IRP,则筛选器驱动程序必须处理此 IRP。 总线驱动程序必须为其适配器或控制器 (总线 FDO) 处理此 IRP,以及其子设备 (子 PDO) 。

0x16

主代码

IRP_MJ_PNP

发送时

系统在创建或删除分页文件、转储文件或休眠文件时发送此 IRP。 如果设备具有超出传统父子关系的电源管理关系,驱动程序可以发送此 IRP,以将设备使用情况信息传播到另一个设备堆栈。 有关详细信息,请参阅 IRP_MN_QUERY_DEVICE_RELATIONS 中的 PowerRelations 请求的说明。

系统组件和驱动程序在任意线程上下文中的 IRQL PASSIVE_LEVEL发送此 IRP。

输入参数

IO_STACK_LOCATION 结构的 Parameters.UsageNotification.InPath 成员是 BOOLEAN。 如果此参数为 TRUE,则系统正在设备上创建分页、故障转储或休眠文件。 当 InPathFALSE 时,此类文件已从设备中删除。

Parameters.UsageNotification.Type 是一个枚举,指示文件类型。 此参数具有以下值之一: DeviceUsageTypePagingDeviceUsageTypeDumpFileDeviceUsageTypeHibernation

输出参数

I/O 状态块

驱动程序将 Irp-IoStatus.Status> 设置为STATUS_SUCCESS或相应的错误状态。

驱动程序不会修改 Irp-IoStatus.Information> 字段;它保持为零,由发送 IRP 的组件设置。

Operation

驱动程序在 IRP 沿着设备堆栈向下和 IRP 的备份堆栈的方式处理此 IRP。

驱动程序使用如下过程来响应此 IRP:

  • 如果 Parameters.UsageNotification.InPathTRUE,请确定设备是否支持特殊文件。

    驱动程序应测试驱动程序可以支持的特定 Parameters.UsageNotification.Type () 。 将来可能会添加其他通知类型。

    请参阅下面描述支持每种通知类型所需的操作的详细信息。

    如果 Parameters.UsageNotification.InPathTRUE ,并且驱动程序不支持设备上的特殊文件,则驱动程序必须以失败状态完成 IRP。

  • 如果设备支持特殊文件:

    1. 采取适当的操作以反映设备现在包含或不再包含特殊文件。

      驱动程序通常会递增或递减计数器。 例如,如果 Parameters.UsageNotification.TypeDeviceUsageTypePagingParameters.UsageNotification.InPathTRUE,则递增设备上分页文件数的计数。 某些驱动程序调度例程必须检查计数器 () 。

      不应禁用包含特殊文件的设备。 驱动程序可以调用 IoInvalidateDeviceState,请求 PnP 管理器重新查询设备的 PnP 设备状态信息。 为了响应生成的 IRP IRP_MN_QUERY_PNP_DEVICE_STATE ,驱动程序应设置 PNP_DEVICE_NOT_DISABLEABLE 标志。

      如果 InPathFALSE,则驱动程序在其设备对象中为设备设置DO_POWER_PAGABLE位。

    2. 将设备使用情况信息传播到需要该信息的任何相关设备。

      作为处理 IRP_MN_DEVICE_USAGE_NOTIFICATION IRP 的一部分,驱动程序可能需要将信息传递给一个或多个其他设备堆栈。 此类驱动程序) 创建新的 IRP_MN_DEVICE_USAGE_NOTIFICATION IRP (或 IRP,并将其发送到相应的设备堆栈 (或堆栈) 。 驱动程序必须等待其发送的任何设备使用情况通知 IRP () 完成,然后驱动程序才能处理它收到的设备使用情况 IRP。

      如何识别相关设备特定于设备和驱动程序。 通常,驱动程序将 IRP 发送到其他驱动程序,它将向其发送文件的 I/O 请求。 当总线驱动程序处理子设备的此请求时,它必须向设备父级的设备堆栈发送使用通知 IRP。

      例如,当 ftdisk 运行包含五个磁盘的条带集时,它会将分页通知传播到这五个磁盘中的每个磁盘,因为可能需要其中每个设备来处理分页文件操作。

    3. 在函数或筛选器驱动程序中,设置 IoCompletion 例程。

    4. 在函数或筛选器驱动程序中,将 Irp-IoStatus.Status> 设置为 STATUS_SUCCESS,设置下一个堆栈位置,并使用 IoCallDriver 将 IRP 传递到下一个较低的驱动程序。 不要完成 IRP。

      在正在处理子 PDO 的 IRP 的总线驱动程序中,设置 Irp-IoStatus.Status> 并完成 IRP (IoCompleteRequest) 。

    5. 在 IRP 完成处理期间:

      如果 IoCompletion 例程检测到较低驱动程序使 IRP 失败,函数或筛选器驱动程序必须撤消它为响应 IRP 而执行的任何操作并传播错误。 如果函数或筛选器驱动程序将使用情况信息传播到任何其他设备堆栈,则驱动程序必须向这些堆栈发送另一个使用情况 IRP,以通知它们失败。

      如果 status 为 STATUS_SUCCESS 且 InPathTRUE,请清除DO_POWER_PAGABLE位。

有关处理即插即用次要 IRP 的一般规则,请参阅即插即用。

支持设备上的分页、故障转储和休眠文件

当驱动程序的任何特殊文件计数为非零时,驱动程序必须支持其设备上存在特殊文件 () (或后代设备) 。

对于在其设备上创建的 DeviceUsageTypePaging 文件,驱动程序必须执行以下操作:

对于其设备上的 DeviceUsageTypeDumpFile 文件,驱动程序必须执行以下操作:

  • 在其 DispatchReadDispatchWriteDispatchDeviceControlDispatchPower 例程的内存中锁定代码。

  • 请勿将设备从 D0 状态中取出。

    不要将设备注册为空闲检测 (PoRegisterDeviceForIdleDetection) 。 如果设备已注册,请取消注册。 如果驱动程序对设备执行自己的空闲检测,请暂停此类检测。

  • 清除其设备对象中的设备DO_POWER_PAGABLE位,以便设备 (IRP 上设备堆栈) 。

  • 对设备的IRP_MN_QUERY_STOP_DEVICEIRP_MN_QUERY_REMOVE_DEVICE请求失败。

对于其设备上的 DeviceUsageTypeHibernation 文件,驱动程序必须执行以下操作:

  • 在其 DispatchReadDispatchWriteDispatchDeviceControlDispatchPower 例程的内存中锁定代码。

  • 当驱动程序收到指示系统即将休眠的 S4 系统电源 IRP 时,请确保设备处于 D0 状态。

  • 不要关闭设备以响应 S4 休眠操作的 D3 设置电源 IRP。 有关详细信息 ,请参阅系统电源操作

    收到此类 D3 设置电源 IRP 后,执行将设备置于 D3 状态所需的所有任务,但关闭设备电源并通知电源管理器 (PoSetPowerState) 。 设备必须保持电源,直到写入休眠文件。

  • 清除其设备对象中的设备DO_POWER_PAGABLE位,以便设备 (IRP 上设备堆栈) 。

  • 对设备的IRP_MN_QUERY_STOP_DEVICEIRP_MN_QUERY_REMOVE_DEVICE请求失败。

有关设备电源状态、电源 IRP 和支持驱动程序中的电源管理的详细信息,请参阅电源管理。

发送此 IRP

驱动程序可以发送 IRP_MN_DEVICE_USAGE_INFORMATION IRP,但只能将设备使用情况信息传播到另一个设备堆栈。 驱动程序从来不是设备使用情况信息的初始源。

要求

标头

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

另请参阅

DispatchDeviceControl

DispatchPower

DispatchRead

DispatchWrite

IoAdjustPagingPathCount

IoCallDriver

IoCompleteRequest

IO_STACK_LOCATION

IRP_MJ_PNP

IRP_MN_QUERY_DEVICE_RELATIONS

IRP_MN_QUERY_PNP_DEVICE_STATE

IRP_MN_QUERY_REMOVE_DEVICE

IRP_MN_QUERY_STOP_DEVICE

PoRegisterDeviceForIdleDetection

PoSetPowerState