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)树形结构示意图 根设备 (Root) PCI总线 (PCI Bus) USB控制器 显卡 (GPU) SATA控制器 USB键盘 USB鼠标 硬盘 (Disk) 分区 (Partition) 每个devnode包含设备状态、资源需求、驱动栈指针、子设备列表等关键信息
Devnode关键属性: 每个设备节点包含设备实例ID、硬件ID、兼容ID、资源需求列表、已分配资源、设备状态、指向功能驱动与总线驱动的指针、子节点列表等。UMDF驱动通过WDFDEVICE句柄间接访问这些信息。

2.3 PnP状态机

PnP管理器使用严格的状态机来管理每个设备节点的生命周期。设备状态转换由PnP管理器发起,驱动通过响应IRP_MJ_PNP来配合状态迁移。

PnP设备状态机转换图 未启动 (Not Started) 已启动 (Started) 停止中 (Stop Pending) 移除中 (Remove Pending) 已删除 (Deleted) 意外移除 (Surprise Removed) IRP_MN_START_DEVICE IRP_MN_QUERY_STOP IRP_MN_QUERY_REMOVE IRP_MN_CANCEL_STOP IRP_MN_REMOVE_DEVICE IRP_MN_REMOVE_DEVICE IRP_MN_CANCEL_REMOVE IRP_MN_SURPRISE_REMOVAL IRP_MN_REMOVE_DEVICE 实线:正常路径 | 虚线:意外路径
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在驱动栈中的传递流程

IRP_MJ_PNP在驱动栈中的传递流程 应用层 / 用户模式 UMDF驱动宿主进程 (WudfHost.exe) UMDF框架 (Wudfx02000.dll) 内核模式驱动栈 (KMDF/传统驱动) 硬件抽象层 (HAL) / 物理设备 IRP_MJ_PNP 框架预处理 转发到内核 硬件操作 UMDF驱动不直接处理IRP,框架代为处理

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),即在不重启系统的情况下重新分配硬件资源。这一过程涉及以下步骤:

  1. 查询阶段: PnP管理器向所有受影响设备发送IRP_MN_QUERY_STOP,询问是否可以停止。
  2. 停止阶段: 所有设备确认可停止后,发送IRP_MN_STOP_DEVICE,驱动释放资源。
  3. 重新分配: PnP管理器重新计算资源分配方案。
  4. 启动阶段: 发送IRP_MN_START_DEVICE,驱动使用新资源重新初始化。
DMA传输的陷阱: 在资源重新平衡期间,如果驱动正在进行DMA传输,必须在OnReleaseHardware中等待所有DMA事务完成或取消。未完成的DMA操作可能导致系统崩溃或数据损坏。后续章节将详细讨论DMA传输的同步策略。

2.6 本章小结

概念 核心要点 对UMDF开发的意义
PnP管理器角色 设备检测、资源分配、状态管理 驱动必须遵循PnP管理器的生命周期管理
设备节点 树形结构,描述设备层次关系 决定设备枚举顺序和资源继承关系
PnP状态机 严格的状态转换规则 驱动回调必须与状态机同步
IRP_MJ_PNP 框架封装为回调接口 实现IPnpCallbackHardware接口即可
资源重新平衡 动态资源调整机制 DMA驱动必须支持暂停/恢复