FastIo

由于你的驱动将要绑定到文件系统驱动的上边,文件系统除了处理正常的IRP 之外,还要处理所谓的FastIo.FastIoCache Manager 调用所引发的一种没有irp 的请求。换句话说,除了正常的Dispatch Functions 之外,你还得为DriverObject 撰写另一组Fast Io Functions.这组函数的指针在driver->FastIoDispatch.

首先需要了解的是:FastIo 是独立于普通的处理IRP 的分发函数之外的另一组接口。但是他们的作用是一样的,就是由驱动处理外部给予的请求。而且所处理的请求也基本相同。其次,文件系统的普通分发例程和fastio 例程都随时有可能被调用。做好的过滤驱动显然应该同时过滤这两套接口。然而,一般都只介绍IRP 过滤的方法。Fastio 接口非常复杂。但是与IRP 过滤是基本一一对应的。只要了解了前者,后者很容易学会。

在开发的初期学习阶段,你可以简单的设置所有的fastio 例程返回FALSE 并不做任何事。这样这些请求都会通过IRP重新发送被你的普通分发函数捕获。有一定的效率损失,但是并不是很大。

NT FASTIO 是一套IO MANAGER DEVICE DRIVER 沟通的另外一套API. 在进行基于IRP 为基础的接口调用前, IO MANAGER 会尝试使用FAST IO 接口来加速各种IO 操作. FASTIO 本身的文档并不多见本篇就是要介绍一下FASTIO 接口.

FastIoCheckIfPossible, 此调用并不是IO MANAGER 直接调用而是被FsRtlXXX 系列函数调用用于确认读写操作是否可以用FASTIO 接口进行.

FastIoRead/FastIoWrite, 很明显是读写处理的调用.

FastIoQueryBasicInfo/FastIoQueryStandardInfo, 用于获取各种文件信息例如创建,修改日期等.

FastIoLock/FastIoUnlockSingle/FastIoUnlockAll/FastIoUnlockAllByKey,用于对文件的锁定操作.

NT 中有种锁定需要存在。1.排他性锁. 2.共享锁排他性锁在写操作前获取,不准其他进程获得写操作权限而共享锁则代表需要读文件某区间禁止有写动作出现在同一地址上如果有多个共享锁请求那是被允许的.

FastIoDeviceControl 用于提供NtDeviceIoControlFile 的支持.

AcquireFileForNtCreateSection/ReleaseFileForNtCreateSection NTFS 在映射文件内容到内存页面前进行的操作.

FastIoDetachDevice, REMOVABLE 介质被拿走后, FILE SYSTEM DEVICE 对象会在任意的时刻被销毁.只有正确处理这个调用才能把上层DEVICE 和将要销毁的DEVICE 脱钩如果不解决这个函数系统会当.

FastIoQueryNetworkOpenInfo, CIFS 也就是网上邻居,更准确的说是网络重定向驱动尝试获取文件信息,会使用这个调用该调用是因为各种历史原因而产生当时设计CIFS 时为避免多次在网上传输文件信息请求NT4 时传输协议增加了一个FileNetworkOpenInformation 的网络文件请求FSD 则增加了这个接口用于在一次操作中获得所有的文件信息客户段发送FileNetworkOpenInformation, 服务器端的FSD 用本接口完成信息填写.

FastIoAcquireForModWrite, Modified Page Writer 会调用这个接口来获取文件锁如果实现这个接口则能使得文件锁定范围减小到调用指定的范围不实现此接口整个文件被锁.

FastIoPrepareMdlWrite, FSD 提供MDL. 以后向此MDL 写入数据就代表向文件写入数据调用参数中有FILE_BOJECT 描述要写的目标文件.

FastIoMdlWriteComplete, 写操作完成. FSD 回收MDL.

FastIoReadCompressed, 当此调用被调用时读到的数据是压缩后的.应该兼容于标准的NT 提供的压缩库因为调用者负责解压缩.

FastIoWriteCompressed,当此调用被调用时可以将数据是压缩后存储.

FastIoMdlReadCompressed/FastIoMdlReadCompleteCompressed, MDL 版本的压缩读当后一个接口被调用时,MDL 必须被释放.

FastIoMdlWriteCompressed/FastIoMdlWriteCompleteCompressed, MDL 版本的压缩写.当后一个接口被调用时,MDL 必须被释放.

FastIoQueryOpen, 这不是打开文件的操作但是却提供了一个IRP_MJ_CREATE IRP. 我在以前版本的

SECUSTAR 的软件中错误地实现了功能这个操作是打开文件/获取文件基本信息/关闭文件的一个操作.

FastIoReleaseForModWrite,释放FastIoAcquireForModWrite 调用所占有的LOCK.

FastIoAcquireForCcFlush/FastIoReleaseForCcFlush FsRtl 会调用此接口,LAZY WRITE 线程将要把修改后的文件数据写入前调用.获取文件锁.


在应用层读写文件等操作将通过 INT 2E切换到内核层。这个不用说大家都很熟悉流程。那么到了内核层又是如何处理的?

 

就先拿 ZwReadFile,ZwWriteFile 说事。首先将文件句柄转换成FILE_OBJECT 指针。这时 I/OMGR 收到一个 FILE I/O 请求,它将首先选择用 FASTIO 接口来进行缓冲操作(注意:FASTIO 对于FSD 来说不是必须的。且 FASTIO 并不真正读写内容)。如果有 FASTIO 例程则调用FastIoRead,FastIoWrite。在它们的函数处理例程中返回 TRUE 那么则表示操作完成,继续调用 CC MGR。如果返回 FALSE 那么I/O MGR 则创建 IRP 。系统判断 FILE_OBJECT 结构中的PrivateCacheMap 项如果不为 NULL,表示已被 CC MGR映射过了,调用CcCopyRead,CcCopyWrite。如果为 NULL 那么 CC MGR 会调用 CcInitializeCacheMap 来初始化,把相应的 FILE_OBJECT 映射进来。

 

在经过 I/O MGR 处理后无论是 IRP 还是 FASTIO,怎么分支都会走到CC MGR。那么在CC MGR 中又会碰到几个状况。如 CC MGR 的 LAZY WRITETHREAD 会定期调用 MM MGR 的 MmFlushSection 将 CC MGR 中已被修改的PAGE 发送到 FSD 写盘。而 MM MGR 又有几种状况,先拿写来说。MM MGR 存在 DIRTY WRITE, 那么在这种情况下MM MGR 则调用 IoAsynchronousPageWrite向 FSD 发送 NOCACHE IRP 即 IRP HEADER 的 FLAGS 为IRP_NOCACHE 来写盘(也就是说 CC MGR 调用 MM MGR 的 MmFlushSection 而 MM MGR则调用IoAsynchronousPageWrite 发送 NOCACHE IRP 到 FSD,那么 FSD 则直接发送到 STORAGE DRIVER进行写盘操作。这是写盘操作过程)。

 

在走到 CC MGR 后读盘又分几种状况。在调用 CcCopyRead 时如果数据不在 CC MGR 中,则产生缺页中断(这其实也是预先读机制)。产生缺页中断后会走到MM MGR 。此时 MM MGR 调用 IoPageRead 来发送一个 PAGING I/O 的 IRP(即 IRP HEADER 中的 FLAGS为IRP_PAGING_IO 或 IRP_SYNCHRONOUS_PAGING_IO )到 FSD。

还有就是用户层调用 CreateFileMapping其实是调用 NtCreateSection 一样产生缺页中断然后到MM MGR 调用MmCreateSection。其余就跟我上面提到的流程一样了。待一些读/写 IRP 发送到 FSD 时。 FSD 再调用 IoCallDriver继续传递下去。如果你对NT DRIVER 分层机制了解的话。可能就会理解为什么要有这一步。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值