Windows卷挂载流程
学习Windows文件系统过滤的前置知识。
两种卷设备
1. 存储卷设备(Storage Volume Device)
- 创建者:由存储驱动栈(如
Disk.sys、FtDisk.sys等)创建,代表一个逻辑存储单元(分区)。 - 设备名示例:
\Device\HarddiskVolume1。 - 作用:这是物理磁盘分区在系统内核中的直接表示,负责处理底层的块读写请求。
2. 文件系统卷设备(File System Volume Device Object, VDO)
- 创建者:文件系统驱动。
- 设备名:通常没有名字(匿名设备对象)。
- 作用:这是文件系统驱动为管理特定卷上的文件、目录等逻辑结构而创建的实例对象。它构成了文件系统设备栈的底部,所有发往该卷的文件I/O请求最终都会到达这里。
完整的卷挂载流程
- 存储卷就绪:存储驱动识别到一个新分区(如插入U盘),并为其创建存储卷设备(
\Device\HarddiskVolumeX)。 - 挂载请求:I/O管理器或挂载管理器(Mount Manager)发现该卷需要被访问,并向已注册的文件系统驱动发出卷挂载请求。
- 创建VDO:文件系统驱动(例如NTFS)收到请求后,为该卷创建一个文件系统卷设备对象(VDO)。
- 建立关联:文件系统驱动通过一个称为卷参数块(VPB)的数据结构,将新创建的VDO与底层的存储卷设备对象关联起来,并设置
VPB_MOUNTED标志,完成挂载。 - 过滤驱动附加:挂载完成后,文件系统过滤驱动(无论是传统的还是Minifilter)便可以将其过滤设备对象附加到这个新创建的文件系统VDO之上,从而拦截发往该卷的所有文件I/O操作。
对文件过滤驱动的意义
这正是为什么在文件过滤驱动中,需要监听卷挂载通知并为其创建过滤设备。附加的目标正是文件系统驱动为每个卷创建的VDO,而不是存储驱动创建的\Device\HarddiskVolumeX。理解这两层设备的区别,是掌握Windows存储栈和文件过滤机制的关键。
IO请求如何从文件系统卷设备到存储卷设备
文件系统卷设备(VDO)接收到的文件I/O请求,最终是通过I/O请求包(IRP)在设备栈中层层向下传递,到达存储卷设备的。具体过程如下:
关键桥梁:卷参数块(VPB)
文件系统驱动在挂载卷时,会创建一个卷参数块(Volume Parameter Block, VPB)。这个数据结构将文件系统卷设备对象(VDO)与底层的存储卷设备对象(如\Device\HarddiskVolume1)关联起来。VPB是两者连接的纽带。
请求传递流程
- 接收请求:当一个文件I/O请求(如读文件)到达文件系统VDO时,它已被解析为针对特定卷上特定文件的操作。
- 文件系统处理:文件系统驱动(如NTFS)根据请求类型,执行其核心逻辑:路径解析、权限检查、文件记录查找、将文件偏移转换为磁盘上的簇号等。
- 转换为磁盘操作:文件系统驱动将文件的“读/写N个字节”的请求,根据簇映射关系,转换为一个或多个针对磁盘逻辑块地址(LBA)的“读/写N个扇区”的请求。
- 向下传递:文件系统驱动通过VDO的VPB,找到关联的存储卷设备对象。然后,它通常会:
- 创建新的IRP:构建一个全新的IRP(
IRP_MJ_READ或IRP_MJ_WRITE),其参数包含计算出的起始LBA和扇区数量。 - 或重用/转发IRP:在某些情况下,也可能修改原始IRP的参数后转发。
- 调用
IoCallDriver函数,将这个新的(或修改后的)IRP发送给存储卷设备对象。
- 创建新的IRP:构建一个全新的IRP(
- 存储栈处理:存储卷设备对象属于存储驱动栈(可能包含卷管理器、磁盘驱动等)。它接收IRP后,进一步处理,最终将请求发送给磁盘端口驱动和磁盘硬件,完成物理读写。
设备栈的完整视图
从高层到低层,一个文件读请求的典型路径是:
用户态API→I/O管理器→文件系统过滤驱动栈→文件系统驱动(VDO)→存储卷过滤驱动栈→存储卷设备→磁盘驱动→硬件