发送到设备驱动程序的大多数请求都打包在 I/O 请求数据包 (IRP) 中。 每个设备都由设备节点表示,每个设备节点都有一个设备堆栈。 有关详细信息,请参阅设备节点和设备堆栈。 若要向设备发送读取、写入或控制请求,I/O 管理器将找到设备的设备节点,然后将 IRP 发送到该节点的设备堆栈。 有时,处理 I/O 请求涉及多个设备堆栈。 无论涉及多少个设备堆栈,参与 I/O 请求的驱动程序的整体序列都称为请求的 驱动程序堆栈 。 我们还使用术语 驱动程序堆栈 来引用特定技术的分层驱动程序集。
由多个设备堆栈处理的 I/O 请求
在某些情况下,处理 IRP 涉及多个设备堆栈。 下图演示了处理单个 IRP 时涉及四个设备堆栈的情况。
在图表中,每个编号阶段如何处理 IRP:
IRP 由 Disk.sys创建,它是“我的 USB 存储设备”节点的设备堆栈中的函数驱动程序。 Disk.sys 将 IRP 向下设备堆栈传递到 Usbstor.sys。
请注意,Usbstor.sys 是“我的 USB 存储设备”节点的 PDO 驱动程序和 USB 大容量存储设备节点的 FDO 驱动程序。 此时,确定 IRP 是由(PDO、Usbstor.sys)对还是(FDO、Usbstor.sys)对拥有并不重要。 IRP 归驱动程序所有,Usbstor.sys,驱动程序有权访问 PDO 和 FDO。
Usbstor.sys 处理完 IRP 后,它将 IRP 传递给 Usbhub.sys。 Usbhub.sys 是 USB 大容量存储设备节点的 PDO 驱动程序,也是 USB 根中心节点的 FDO 驱动程序。 判断 IRP 的归属,是否属于(PDO, Usbhub.sys)对或(FDO, Usbhub.sys)对,并不重要。 IRP 归驱动程序所有,Usbhub.sys,驱动程序有权访问 PDO 和 FDO。
当 Usbhub.sys 完成 IRP 处理后,它将 IRP 传递给 (Usbuhci.sys, Usbport.sys) 对。
Usbuhci.sys 是微型端口驱动程序,Usbport.sys 是端口驱动程序。 (微型端口,端口)对扮演单个驱动程序的角色。 在这种情况下,微型端口驱动程序和端口驱动程序都由Microsoft编写。 (Usbuhci.sys,Usbport.sys)对是 USB 根集线器节点的 PDO 驱动程序,(Usbuhci.sys,Usbport.sys)对则是 USB 主机控制器节点的 FDO 驱动程序。 (Usbuhci.sys, Usbport.sys)对与主机控制器硬件进行直接通信,而后者又进一步与物理 USB 存储设备进行通信。
I/O 请求的驱动程序堆栈
请考虑参与上图中所示的 I/O 请求的四个驱动程序序列。 我们可以通过专注于驱动程序而不是设备节点及其单个设备堆栈来获取序列的另一个视图。 下图显示了从上到下的顺序排列的驱动程序。 请注意,Disk.sys 与一个设备对象相关联,但另外三个驱动程序中的每一个都与两个设备对象相关联。
参与 I/O 请求的驱动程序序列称为 I/O 请求的驱动程序堆栈。 为了说明 I/O 请求的驱动程序堆栈,我们按照驱动程序参与请求的顺序从上到下绘制驱动程序堆栈。
请注意,I/O 请求的驱动程序堆栈与设备节点的设备堆栈大相径庭。 另请注意,I/O 请求的驱动程序堆栈不一定保留在设备树的一个分支中。
技术驱动程序堆栈
请考虑上图中显示的 I/O 请求的驱动程序堆栈。 如果为每个驱动程序提供一个友好名称,并且对关系图进行了一些细微的更改,则我们有一个块关系图,类似于 Windows 驱动程序工具包(WDK)文档中出现的许多驱动程序。
在关系图中,驱动程序堆栈分为三个部分。 我们可以将每个部分视为属于特定技术或作系统的特定组件或部分。 例如,我们可能说驱动程序堆栈顶部的第一部分属于卷管理器,第二部分属于作系统的存储组件,第三部分属于作系统的核心 USB 部分。
考虑第三部分中的驱动程序。 这些驱动程序是 Microsoft 提供的,用于处理各种 USB 请求和 USB 硬件的核心 USB 驱动程序的一部分。 下图显示了整个 USB 核心块图的外观。
显示特定技术或作系统的特定组件或部分的所有驱动程序的块图称为 技术驱动程序堆栈。 通常,技术驱动程序堆栈的名称包括 USB 核心驱动程序堆栈、存储堆栈、1394 驱动程序堆栈和音频驱动程序堆栈。
注意:本文中的 USB 核心块图演示了用于说明 USB 1.0 和 2.0 的技术驱动程序堆栈的几种可能方法之一。 有关 USB 1.0、2.0 和 3.0 驱动程序堆栈的官方图表,请参阅 USB 驱动程序堆栈体系结构。