适用于 WDF 驱动程序的 WDM 概念
Windows 驱动程序框架 (WDF) 是围绕 Microsoft Windows 驱动程序模型 (WDM) 接口的包装器。 尽管框架简化了许多 WDM 概念并完全隐藏了其他概念,这样就不必使用它们,但你仍应了解 WDM 驱动程序的一些基本概念。 具体而言,应了解 驱动程序类型、 驱动程序堆栈、 设备堆栈和 I/O 请求数据包。
驱动程序类型
基于 Windows 的驱动程序分为三种类型: 总线驱动程序、 函数驱动程序和 筛选器驱动程序。 总线驱动程序通过检测插入父总线的子设备并报告其特征来支持 I/O 总线。 (此活动称为 总线枚举。) 函数驱动程序控制设备和总线的 I/O 操作。 筛选器驱动程序接收、查看并可能修改在用户应用程序和驱动程序之间或单个驱动程序之间流动的数据。
总线的驱动程序本质上是函数驱动程序,也枚举子级。 驱动程序在枚举总线上的子设备时充当“总线驱动程序”。 否则,同一驱动程序在处理访问总线适配器硬件的 I/O 操作时充当总线的“函数驱动程序”。
User-Mode驱动程序框架 (UMDF) 驱动程序不能是总线驱动程序。
驱动程序堆栈
在 Windows 操作系统中,WDM 驱动程序在称为 驱动程序堆栈的垂直调用序列中分层。 堆栈中最顶层的驱动程序通常在请求通过操作系统的 I/O 管理器后接收来自用户应用程序的 I/O 请求。 较低的驱动程序层通常与计算机硬件通信。
简单的驱动程序堆栈包括堆栈底部的总线驱动程序,该驱动程序处理特定于总线的 I/O 操作并枚举连接到该堆栈的子设备。 通常,一个或多个特定于设备的函数驱动程序位于总线驱动程序之上。 这些函数驱动程序处理连接到总线的设备的 I/O 操作。 筛选器驱动程序可以位于函数驱动程序之上,也可以驻留在总线驱动程序和函数驱动程序之间。 正在运行的系统有多个驱动程序堆栈,这些堆栈支持不同类型的设备。
设备堆栈
每个驱动程序堆栈都支持一个或多个 设备堆栈。 设备堆栈是从 WDM 定义的DEVICE_OBJECT结构创建的一组设备对象。 每个设备堆栈表示一个设备。 每个驱动程序为其每个设备创建一个设备对象,并将每个设备对象附加到设备堆栈。 设备堆栈在设备插入和拔出时以及每次重新启动系统时创建和删除。
当总线驱动程序检测到子设备已插入或拔出时,它会通知即插即用 (PnP) 管理器。 作为响应,PnP 管理器要求总线驱动程序为连接到父设备的每个子设备创建物理设备对象, (PDO) (即总线) 。 PDO 将成为设备堆栈的底部。
接下来,PnP 管理器加载函数和筛选器驱动程序以支持每个设备 ((如果它们尚未加载) ),然后 PnP 管理器调用这些驱动程序,以便每个设备都可以创建设备对象并将其添加到设备堆栈的顶部。 函数驱动程序 (FDO) 创建功能设备对象,筛选器驱动程序 (筛选器DO) 创建筛选器设备对象。
当 I/O 管理器向设备的驱动程序发送 I/O 请求时,它会将请求传递给在设备堆栈中创建最顶层设备对象的驱动程序。 如果该驱动程序要求 I/O 管理器将请求传递给下一个较低级别的驱动程序,则 I/O 管理器使用设备堆栈来确定下一个较低级别的驱动程序。 (下一个较低级别的驱动程序是创建下一个较低版本的设备对象的驱动程序。)
WDF 为每个 WDM 设备对象创建一个框架设备对象。 基于框架的驱动程序访问这些框架设备对象,而不是 WDM 设备对象。
I/O 请求数据包
I/O 管理器通过创建 I/O 请求数据包 (IRP) 将应用程序的 I/O 请求发送到驱动程序。 IRP 可以包含执行 I/O 操作 ((例如读取/写入操作) )的请求,也可以包含执行 I/O 控制 (IOCTL) 操作 ((例如返回状态) )的请求。 此外,PnP 管理器会创建表示驱动程序必须执行的 PnP 和电源管理操作的 IRP,并将这些 IRP 发送到驱动程序。
通常,当用户应用程序请求读取或写入操作时,I/O 管理器会创建读取或写入 IRP。 I/O 管理器将 IRP 传递到驱动程序堆栈顶部的驱动程序,该驱动程序要么为请求提供服务,要么将请求传递给下一个较低的驱动程序。 某些请求将到达堆栈底部,而有些请求则由更高级别的驱动程序完全处理。
每次驱动程序收到 IRP 时,驱动程序也会收到指向表示必须处理操作的设备的设备对象的指针。 因此,驱动程序堆栈中的驱动程序使用设备对象来确定应转到特定请求的插入设备中的哪一个。
WDF 驱动程序通常不直接访问 IRP。 框架将表示读取、写入和设备 I/O 控制操作的 WDM IRP 转换为框架请求对象,Kernel-Mode驱动程序框架 (KMDF) 和 UMDF 驱动程序在 I/O 队列中接收。 框架在内部处理 PnP 和电源管理 IRP,并使用事件回调函数通知 PnP 和电源事件的驱动程序。