文件过滤的一点总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
文件系统驱动
文件系统驱动主要生成两类设备:文件系统控制设备,文件系统的卷设备
文件系统控制设备:主要任务是修改整个驱动的内部配置
文件系统的卷设备:一个卷对应一个逻辑盘
发送给控制设备的请求(IRP),一般是文件系统控制IRP(主功能号为IRP_MJ_FILE_SYSTEM_CONTROL);发送给卷设备的IRP一般则是文件操作IRP。过滤的目标最终是为了得到文件操作的IRP,但是控制设备的IRP,一般用来捕获卷设备的生成信息,所以我们要先绑定文件系统的控制设备,达到绑定文件系统的卷设备的目的~~
(1)生成自己的一个控制设备,当然必须给控制设备指定名称
(2)设置普通分发函数
(3)设置快速IO分发函数
(4)编写一个文件系统变动回调函数,在其中绑定刚激活的文件系统控制设备(动态绑定)
(5)使用IoRegisterFsRegistrationChange调用注册这个回调函数
文件系统控制设备的绑定
过滤设备扩展
typedef struct _SFILTER_DEVICE_EXTENSION {
ULONG TypeFlag;
//
// 绑定的文件系统设备(真实设备)
//
PDEVICE_OBJECT AttachedToDeviceObject;
//
// 与文件系统设备相关的真实设备(磁盘),这个在绑定时使用
//
//
PDEVICE_OBJECT StorageStackDeviceObject;
//
//
// 如果绑定了一个卷,那么这是物理磁盘卷名;否则这是绑定的控制设备名
//
//
UNICODE_STRING DeviceName;
//
// 用来保存名字字符串的缓冲区
//
WCHAR DeviceNameBuffer[MAX_DEVNAME_LENGTH];
//
// The extension used by other user.
//
UCHAR UserExtension[1];
} SFILTER_DEVICE_EXTENSION, *PSFILTER_DEVICE_EXTENSION;
绑定文件系统控制设备
SfAttachToFileSystemDevice
文件系统控制设备已经被绑定,绑定的目的是为了获得发送给文件系统控制设备的文件系统控制请求。这些IRP的主功能号是IRP_MJ_FILE_SYSTEM_CONTROL,每个主功能号下一般都有次功能号
从这些控制IRP中能得到足够的信息,确定一个卷被挂载,这样才有可能去绑定文件系统的卷设备
当有卷被挂载或解挂载时,SfFsControl()就会被系统回调。现在的任务是在这个函数中获得卷设备的相关信息并对它实行绑定,才能捕获各种针对文件的IRP,从而获得临控各种文件操作的能力
主功能号为IRP_MJ_FILE_SYSTEM_CONTROL时,有以下几个不同次功能号的IRP要处理(1)次功能号为IRP_MN_MOUNT_VOLUME,说明一个卷被挂载,应该调用SfFsControlMountVolume来绑定一个卷
(2)次功能号为IRP_MN_LOAD_FILE_SYSTEM,这个请求比较特殊,它一般出现在文件系统识别器要求加载真正的文件系统时,此时说明前面绑定了一个文件系统识别器,现在应该在这里开始绑定真正的文件系统控制设备了
(3)次功能号为IRP_MN_USER_FS_REQUEST,此时可以从irpSp->Parameters.FileSystemControl.FsControlCode得到一个控制码。当控制码为FSCTL_DISMOUNT_VOLUME时,说明是一个磁盘在解挂载
(1)生成一个控制设备。当然此前必须给控制设备指定名称
(2)设置分发函数和快速IO分发函数
(3)编写一个文件系统变动回调函数,在其中绑定刚激活的文件系统的控制设备,并注册这
个回调函数
(4)编写默认的分发函数
(5)处理文件系统控制请求(IRP主功能号为IRP_MJ_FILE_SYSTEM_CONTROL),在其中监控卷设备的Mount和Dismount
文件系统卷设备的绑定
从IRP中获得VPB指针:指针irpSp->Parameters.MountVolume.Vpb是一个VPB,VPB是卷参数(Volume Parameter Block),一个重要的数据结构,它在这里的主要作用是把实际存储媒介设备对象和文件系统上的卷设备对象联系起来
下面的代码用VPB来做一下倒手工作,首先,从irpSp中获得文件系统卷设备的VPB,然后从VPB中获得一个存储设备对象
storageStackDeviceObject = irpSp->Parameters.MountVolume.Vpb->RealDevice
以后可以从这个存储设备对象再得到原来的VPB。这里记下存储设备,实际上是为了从存储设备对象找回VPB,再找回文件系统卷设备。
为什么要进行上面的倒手工作?
这里的IRP是一个Mount请求,而文件系统卷设备对象实际上是这个请求完成之后才可用。因此,在这个请求还没完成之前irpSp->Parameter.MountVolume.Vpb->DeviceObject是没有意义的,必须等这个IRP完成后irpSp->Parameter.MountVolume.Vpb->DeviceObject才是需要绑定的设备对象
但是这个IRP传递过程中,irpSp->Parameter.MountVolume.Vpb可能被修改。换句话说,有可能IRP完成之后,这个指针就已经不是原来那个了,对这种情况的处理,WDK文档有如下说明:
IrpSp->Parameter.MountVolume.Vpb指向一个被挂载的卷参数块(VPB)的指针。支持可移动介质的文件系统,可能替换掉预先传入的这个参数。在这样的文件系统上,在卷被挂载之后,这个指针可能不再有效。过滤这种文件系统的过滤驱动必须按下面的方法使用这个参数:在把IRP发送到下层驱动之前,保存IrpSp->Parameter.MountVolume.Vpb->RealDevice的值。这个卷被成功挂载之后,过滤驱动可以用这个存储设备的指针重新获得正确的VPB指针。
为此,必须先获得IrpSp->Parameter.MountVolume.Vpb->RealDevice的值保存起来,等待IRP完成之后,再从RealDevice中去获得那个VPB
设置完成函数并等待IRP完成SfFsControlMountVolume
完成函数相应实现SfFsControlCompletion
绑定卷的实现:在SfFsControlMountVolume,调用ExInitializeWorkItem实现SfFsControlMountVolumeCompleteWorker