DispatchPnP 例程

驱动程序的 DispatchPnP 例程通过处理IRP_MJ_PNP I/O 函数代码的 IRP 支持即插即用。 与IRP_MJ_PNP函数代码关联的是几个次要 I/O 函数代码, (查看即插即用次要 IRP) ,其中一些所有驱动程序都必须处理,其中一些可以选择性地处理。 PnP 管理器使用这些次要功能代码来指示驱动程序启动、停止和删除设备,并查询驱动程序有关其设备的信息。

设备的所有驱动程序都必须有机会处理设备的 PnP IRP,但允许函数或筛选器驱动程序使 IRP 失败的少数情况除外。

每个驱动程序的 DispatchPnP 例程必须遵循以下规则:

  • 函数或筛选器驱动程序必须将 PnP IRP 向下传递到设备堆栈中的下一个驱动程序,除非函数或筛选器驱动程序处理 IRP,并且由于资源不足(例如) )而遇到故障 (。

    设备的所有驱动程序都必须有机会处理设备的 PnP IRP,除非其中一个驱动程序遇到错误。 PnP 管理器将 IRP 发送到设备堆栈中的顶级驱动程序。 函数和筛选器驱动程序将 IRP 向下传递到下一个驱动程序,父总线驱动程序完成 IRP。 有关详细信息 ,请参阅在设备堆栈中传递 PnP IRP

    如果驱动程序尝试处理 IRP 并遇到错误 ((例如) 资源不足),则 IRP 可能会使 IRP 失败。 如果驱动程序收到 IRP 且其无法处理的代码,则驱动程序不得使 IRP 失败。 它必须将此类 IRP 向下传递到下一个驱动程序,而无需修改 IRP 的状态。

  • 驱动程序必须处理某些 PnP IRP,并且可以选择性地处理其他 PnP。

    每个 PnP 驱动程序都需要处理某些 IRP(例如 IRP_MN_REMOVE_DEVICE),并且可以选择性地处理其他 IRP。 有关每种驱动程序 (函数驱动程序、筛选器驱动程序和总线驱动程序) 的必需和可选 IRP 的信息,请参阅即插即用次要 IRP。

    驱动程序可能会使所需的 PnP IRP 失败并具有适当的错误状态,但驱动程序不得返回此类 IRP 的STATUS_NOT_SUPPORTED。

  • 如果驱动程序成功处理 PnP IRP,驱动程序会将 IRP 状态设置为成功。 它不依赖于堆栈中的另一个驱动程序来设置状态。

    驱动程序将 Irp-IoStatus.Status> 设置为 STATUS_SUCCESS,以通知 PnP 管理器驱动程序已成功处理 IRP。 对于某些 IRP,非总线驱动程序可能能够依赖其父总线驱动程序将状态设置为成功。 但是,这是一种有风险的做法。 为了保持一致性和稳定性,驱动程序必须将它成功处理的每个 PnP IRP 的 IRP 状态设置为成功。

  • 如果驱动程序未能通过 IRP,驱动程序会以错误状态完成 IRP,并且不会将 IRP 向下传递到下一个驱动程序。

    若要使 IRP(如 IRP_MN_QUERY_STOP_DEVICE)失败,驱动程序会将 Irp-IoStatus.Status> 设置为 STATUS_UNSUCCESSFUL。 其他 IRP 的其他错误状态值包括STATUS_INSUFFICIENT_RESOURCES和STATUS_INVALID_DEVICE_STATE。

    驱动程序不会为其处理的 IRP 设置STATUS_NOT_SUPPORTED。 这是 PnP 管理器设置的初始状态。 如果 IRP 以此状态完成,则意味着堆栈中没有驱动程序处理 IRP;所有驱动程序刚刚将 IRP 传递给下一个驱动程序。

  • 驱动程序必须在 IRP 的调度例程中处理 PnP IRP, (在 IRP 沿着设备堆栈) ,在 IoCompletion 例程 (IRP 上备份设备堆栈) 或两者,如 IRP 参考页中所述。

    某些 PnP IRP(如 IRP_MN_REMOVE_DEVICE)必须先由设备堆栈顶部的驱动程序处理,然后由每个下一个较低的驱动程序进行处理。 其他(如 IRP_MN_START_DEVICE)必须首先由父总线驱动程序处理。 还有一些,例如 IRP_MN_QUERY_CAPABILITIES,可以在设备堆栈下行和备份途中进行处理。 有关适用于每个 PnP IRP 的规则,请参阅即插即用次要 IRP。 有关处理父总线驱动程序必须首先处理的 PnP IRP 的信息,请参阅将 PnP IRP 处理推迟到较低驱动程序完成

  • 驱动程序必须在 IRP 沿着设备堆栈向下向 IRP 添加信息,并修改或删除有关 IRP 备份方式的信息。

    返回信息以响应 PnP 查询 IRP 时,驱动程序必须遵循此约定,以便按分层驱动程序为设备有序传递信息。

  • 除非有明确记录,否则驱动程序不得依赖于以任何特定顺序发送的 PnP IRP。

  • 当驱动程序发送 PnP IRP 时,它必须将 IRP 发送到设备堆栈中的顶部驱动程序。

    大多数 PnP IRP 是由 PnP 管理员发送的,但有些 IRP 可由驱动程序 (发送,例如 ,IRP_MN_QUERY_INTERFACE) 。 驱动程序必须将 PnP IRP 发送到设备堆栈顶部的驱动程序。 调用 IoGetAttachedDeviceReference 以获取指向设备堆栈顶部驱动程序的设备对象的指针。