Filter驱动比较特殊,它的生命周期基本是辅助他所以来的设备驱动或者总线驱动,故我们只考虑功能驱动和总线驱动即可。
启动设备
总线驱动程序在其 DispatchPnP 例程中使用以下过程启动子设备 (子 PDO) :
1. 启动设备。具体步骤因设备而异。例如,PCI 总线驱动程序对其映射寄存器进行程序,以便在 PCI 总线上启用请求。 PnP ISA 总线驱动程序启用 PnP ISA 卡以便函数驱动程序可以访问它。
2. 完成 IRP。如果总线驱动程序的启动操作成功,驱动程序会将 Irp->IoStatus.Status 设置为 STATUS_SUCCESS并调用 IoCompleteRequest,以指定IO_NO_INCREMENT的优先级提升。 总线驱动程序从其 DispatchPnP 例程返回STATUS_SUCCESS。
如果总线驱动程序在启动操作期间遇到错误,驱动程序会在 IRP 中设置错误状态,使用 IO_NO_INCREMENT 调用 IoCompleteRequest ,并从其 DispatchPnP 例程返回错误。
如果总线驱动程序需要一些时间来启动设备,它可以将 IRP 标记为挂起并返回STATUS_PENDING。
删除设备
删除子设备 (子 PDO) 时,父总线驱动程序必须撤消为添加和启动设备而执行的任何操作。
总线驱动程序在其 DispatchPnP 例程中使用如下过程删除子设备:
1. 驱动程序以前处理过此 PDO 的IRP_MN_SURPRISE_REMOVAL 请求吗?如果是,请执行任何剩余的清理并跳到步骤 4。驱动程序通常在设备扩展中维护一个标志,指示驱动程序是否已处理设备的 IRP_MN_SURPRISE_REMOVAL 请求;
2. 完成驱动程序中排队的任何请求;
3. 如果总线驱动程序能够这样做,请从设备中删除电源,并通过调用 PoSetPowerState 通知电源管理器。如果可能,总线驱动程序关闭子设备,并通知电源管理器设备的电源状态更改。 总线驱动程序执行此操作以响应 IRP_MN_REMOVE_DEVICE 请求;删除设备时,设备的电源策略所有者不会发送 IRP_MN_SET_POWER 请求;
4. 如果总线驱动程序在最近对 BusRelationsIRP_MN_QUERY_DEVICE_RELATIONS请求的响应中报告了此设备,则设备仍实际存在于计算机上。 在这种情况下,总线驱动程序:
- 保留设备的 PDO,直到设备被物理删除。
- 将 Irp->IoStatus.Status 设置为 STATUS_SUCCESS。
- 使用 IoCompleteRequest 完成 IRP。
- 从 DispatchPnP 例程返回 。
总线驱动程序必须继续在后续枚举中报告此设备, (BusRelations) IRP_MN_QUERY_DEVICE_RELATIONS,直到设备被物理移除。 PnP 管理器跟踪枚举设备是否已添加和启动;
5. 如果总线驱动程序对 BusRelations的IRP_MN_QUERY_DEVICE_RELATIONS请求的最新响应中未包含该设备,则总线驱动程序会将该设备视为从计算机中物理删除。 在这种情况下,总线驱动程序执行以下操作:
- 清理特定于设备的分配、内存、事件等。
- 将 Irp->IoStatus.Status 设置为 STATUS_SUCCESS。
- 使用 IoCompleteRequest 完成 IRP。
- 使用 IoDeleteDevice 释放 PDO。
- 如果驱动程序从最新的 BusRelations 列表中省略了设备,则总线驱动程序必须删除 PDO。 如果用户再次将设备插入计算机,总线驱动程序必须创建新的 PDO 以响应下一个 BusRelations 查询。 如果总线驱动程序对设备的新实例重复使用同一 PDO,则计算机将无法正常运行。
- 从 DispatchPnP 例程返回 。
如果在 PnP 管理器发送 IRP_MN_REMOVE_DEVICE 请求时设备仍然存在,则总线驱动程序会保留 PDO。 如果稍后某个时间将设备从总线上物理移除,则 PnP 管理器会发送另一 个IRP_MN_REMOVE_DEVICE。 收到后续删除 IRP 后,总线驱动程序将删除设备的 PDO。
总线驱动程序必须能够处理已移除且其 PDO 标记为要删除的设备 IRP_MN_REMOVE_DEVICE 。 为了响应此类 IRP,总线驱动程序可以成功执行 IRP 或返回STATUS_NO_SUCH_DEVICE。 尽管总线驱动程序以前调用 了 IoDeleteDevice,但在这种情况下尚未删除设备的 PDO,因为某些组件仍具有对 对象的引用。 因此,总线驱动程序可以在处理第二个删除 IRP 时访问 PDO。 总线驱动程序不得为 PDO 再次调用 IoDeleteDevice ;当 PDO 的引用计数达到零时,I/O 系统将删除 PDO。
在收到对设备的 IRP_MN_REMOVE_DEVICE 请求之前,总线驱动程序不会删除子设备的数据结构。 总线驱动程序可能会检测到设备已被移除并调用 IoInvalidateDeviceRelations,但在 PnP 管理器发送 IRP_MN_REMOVE_DEVICE 请求之前,它不得删除设备的 PDO。