2. PnP管理器基础:PnP管理器角色、设备节点(devnode)概念、PnP状态机、IRP_MJ_PNP处理流程
2.1 PnP管理器的核心角色
即插即用(PnP)管理器是Windows操作系统内核中负责硬件资源动态管理的关键组件。在UMDF驱动开发中,理解PnP管理器的角色是掌握设备生命周期管理的前提。
| 角色维度 | 具体职责 | 对UMDF驱动的影响 |
|---|---|---|
| 设备检测 | 检测硬件设备的插入、移除、配置变化 | 触发设备回调(如OnPrepareHardware) |
| 资源分配 | 分配I/O端口、内存范围、中断、DMA通道 | 驱动通过IPnpCallbackHardware接口获取资源 |
| 设备节点管理 | 维护设备节点(devnode)树形结构 | 决定设备枚举顺序与层次关系 |
| 状态机驱动 | 驱动设备状态转换(如启动→停止→移除) | 驱动必须正确响应状态变化IRP |
| IRP分发 | 发送IRP_MJ_PNP请求到驱动栈 | UMDF框架自动处理大部分PnP IRP |
关键认知: PnP管理器是设备与驱动之间的"交通警察"——它决定设备何时启动、何时停止、何时移除,驱动开发者必须遵循PnP管理器的节奏,而不是自行控制硬件状态。
2.2 设备节点(Devnode)概念
设备节点(devnode)是PnP管理器在内存中维护的数据结构,用于描述系统中的每个逻辑设备。所有devnode构成一棵以"根设备"为根的树形结构,称为设备树。
Devnode关键属性: 每个设备节点包含设备实例ID、硬件ID、兼容ID、资源需求列表、已分配资源、设备状态、指向功能驱动与总线驱动的指针、子节点列表等。UMDF驱动通过WDFDEVICE句柄间接访问这些信息。
2.3 PnP状态机
PnP管理器使用严格的状态机来管理每个设备节点的生命周期。设备状态转换由PnP管理器发起,驱动通过响应IRP_MJ_PNP来配合状态迁移。
UMDF驱动注意事项: UMDF驱动不直接处理IRP_MN_QUERY_STOP和IRP_MN_QUERY_REMOVE——框架会代表驱动处理这些查询。但驱动必须实现
IPnpCallbackSelfManagedIo接口来响应暂停/重启回调,否则可能导致系统挂起或设备无法安全移除。
2.4 IRP_MJ_PNP处理流程
IRP_MJ_PNP是PnP管理器与驱动通信的主要机制。每个PnP操作对应一个IRP,IRP中包含一个Minor Function Code(次要功能码)来标识具体操作。
2.4.1 主要PnP次要功能码
| 次要功能码 | 操作描述 | UMDF框架处理方式 |
|---|---|---|
IRP_MN_START_DEVICE |
启动设备,分配资源 | 调用OnPrepareHardware回调 |
IRP_MN_STOP_DEVICE |
停止设备,释放资源 | 调用OnReleaseHardware回调 |
IRP_MN_QUERY_STOP |
查询是否可停止 | 框架自动响应成功 |
IRP_MN_CANCEL_STOP |
取消停止操作 | 框架自动处理 |
IRP_MN_QUERY_REMOVE |
查询是否可移除 | 框架自动响应成功 |
IRP_MN_CANCEL_REMOVE |
取消移除操作 | 框架自动处理 |
IRP_MN_SURPRISE_REMOVAL |
意外移除通知 | 调用OnReleaseHardware回调 |
IRP_MN_REMOVE_DEVICE |
最终移除设备 | 调用OnDestroyDevice回调 |
2.4.2 IRP_MJ_PNP在驱动栈中的传递流程
2.4.3 UMDF框架对IRP_MJ_PNP的封装
UMDF驱动开发者不需要直接处理IRP_MJ_PNP。框架将PnP IRP转换为面向对象的回调接口:
// UMDF驱动实现IPnpCallbackHardware接口来响应PnP事件
class MyDevice : public IPnpCallbackHardware
{
public:
// 对应 IRP_MN_START_DEVICE
HRESULT OnPrepareHardware(_In_ IWDFDevice* pDevice,
_In_ IWDFCmResourceList* pResourcesRaw,
_In_ IWDFCmResourceList* pResourcesTranslated)
{
// 1. 解析翻译后的资源列表(I/O端口、内存、中断、DMA)
// 2. 配置DMA适配器(后续章节详述)
// 3. 初始化硬件寄存器
return S_OK;
}
// 对应 IRP_MN_STOP_DEVICE / IRP_MN_SURPRISE_REMOVAL
HRESULT OnReleaseHardware(_In_ IWDFDevice* pDevice,
_In_ IWDFCmResourceList* pResourcesTranslated)
{
// 1. 停止DMA传输
// 2. 释放硬件资源
// 3. 清理DMA适配器
return S_OK;
}
};
调试要点: 在WinDbg中,可以使用
!devnode命令查看设备节点状态,使用!irp命令查看当前待处理的PnP IRP。当驱动在OnPrepareHardware中返回失败时,PnP管理器会将设备状态回退到"未启动"状态,并可能触发资源重新平衡。
2.5 PnP资源重新平衡
PnP管理器支持资源重新平衡(Resource Rebalance),即在不重启系统的情况下重新分配硬件资源。这一过程涉及以下步骤:
- 查询阶段: PnP管理器向所有受影响设备发送
IRP_MN_QUERY_STOP,询问是否可以停止。 - 停止阶段: 所有设备确认可停止后,发送
IRP_MN_STOP_DEVICE,驱动释放资源。 - 重新分配: PnP管理器重新计算资源分配方案。
- 启动阶段: 发送
IRP_MN_START_DEVICE,驱动使用新资源重新初始化。
DMA传输的陷阱: 在资源重新平衡期间,如果驱动正在进行DMA传输,必须在
OnReleaseHardware中等待所有DMA事务完成或取消。未完成的DMA操作可能导致系统崩溃或数据损坏。后续章节将详细讨论DMA传输的同步策略。
2.6 本章小结
| 概念 | 核心要点 | 对UMDF开发的意义 |
|---|---|---|
| PnP管理器角色 | 设备检测、资源分配、状态管理 | 驱动必须遵循PnP管理器的生命周期管理 |
| 设备节点 | 树形结构,描述设备层次关系 | 决定设备枚举顺序和资源继承关系 |
| PnP状态机 | 严格的状态转换规则 | 驱动回调必须与状态机同步 |
| IRP_MJ_PNP | 框架封装为回调接口 | 实现IPnpCallbackHardware接口即可 |
| 资源重新平衡 | 动态资源调整机制 | DMA驱动必须支持暂停/恢复 |