boxcounter
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
阅读:3623回复:24

Lazy write导致的内容丢失问题

楼主#
更多 发布于:2008-05-20 11:28
各位,我现在在做一个加解密的minifilter驱动,现在遇到一个问题:
我的加密头在文件首部。我在Write、read中,都会跳过这个首部(512B),通常情况下,这种情况都OK。但是发现当system进行延缓写的时候,会出现最后一部分WriteBuffer中的内容丢失,具体如下:

一个Write请求,Offset是0,WriteLength是8KB,
经过我的minifilter时,我修改offset为512,这样就跳过了我的加密头。然后发现写后返回的结果是只写了7.5KB,最后512字节没写进去,这导致文件中的512字节为随机脏数据,破坏了我的文档。
其中FileSize,AllocationSize都是足够大的,出现这个现象的原因不是因为空间不足而被截断。

我想请教各位朋友,这是因为什么,如何解决。
先多谢各位 :)

最新喜欢:

snoxsnox
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-05-20 12:22
我也遇到这个问题,就是FileSize不够大的问题,因为SetInformation的IRP出现在磁盘写之后,而paging_io的写不能自动更新EoF。所以写入时,文件大小是不够的。自己设置一下长度再写入就好了。
boxcounter
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-05-20 13:47
dionysus77兄:
我的日志如下,这段日志是我采用1KB的加密头的结果:


[TFGF] PreCallback(IRP_MJ_WRITE): IrpFlags: 0x00000043, Offset(0), Length: (12288).
[TFGF] PostCallback(IRP_MJ_WRITE): AllocationSize(16384), FileSize(12701), ValidDataLength(11677).
[TFGF] PostCallback(IRP_MJ_WRITE): BytesWritten(10653), *Status(00000000).

日志上看  FileSize 是足够大的
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-05-21 19:47
引用第2楼boxcounter于2008-05-20 13:47发表的  :
dionysus77兄:
我的日志如下,这段日志是我采用1KB的加密头的结果:


[TFGF] PreCallback(IRP_MJ_WRITE): IrpFlags: 0x00000043, Offset(0), Length: (12288).
.......

对不起,我没看懂,postwrite里面怎么得到的FileSize?
boxcounter
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-05-22 09:27
引用第3楼dionysus77于2008-05-21 19:47发表的  :

对不起,我没看懂,postwrite里面怎么得到的FileSize?


通过FCB来获取的 :)
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-05-22 10:34
ValidDataLength比BytesWritten大1024字节。且小于写入长度,这里是不是有问题?
boxcounter
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-05-23 09:36
回dionysus77兄:
可能是我的日志没说太清楚,我解释一下 :)

[TFGF] PreCallback(IRP_MJ_WRITE): IrpFlags: 0x00000043, Offset(0), Length: (12288).
[TFGF] PostCallback(IRP_MJ_WRITE): AllocationSize(16384), FileSize(12701), ValidDataLength(11677).
[TFGF] PostCallback(IRP_MJ_WRITE): BytesWritten(10653), *Status(00000000).

这里是Paging IO,所以待写长度是页的整数倍大小(实际待写长度可能是没有这么多的),ValidDataLength就是实际上需要写的,但是实际上只写了10653, 比ValidDataLength还少1KB,而从FileSize上来看,文件的确有足够的空间可以写入ValidDataLength这么长的数据。
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2008-05-23 12:14
ValidDataLength(11677)<Length: (12288).
goodone
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2014-04-30
  • 粉丝3
  • 关注0
  • 积分372分
  • 威望174点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2008-05-24 11:00
这个确实是个问题,帮忙顶下,

期望大牛们给个回应
栀子花驿站 www.zhizihua.com
goodone
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2014-04-30
  • 粉丝3
  • 关注0
  • 积分372分
  • 威望174点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2008-05-24 11:02
引用第1楼dionysus77于2008-05-20 12:22发表的  :
我也遇到这个问题,就是FileSize不够大的问题,因为SetInformation的IRP出现在磁盘写之后,而paging_io的写不能自动更新EoF。所以写入时,文件大小是不够的。自己设置一下长度再写入就好了。



通过我的观察 SetInformation的IRP是在磁盘写之前出现的。。。。
所以 应该先在 SetInformation 中修改大小
但是 如果简单的修改大小 还是会有问题
栀子花驿站 www.zhizihua.com
fly1101
驱动牛犊
驱动牛犊
  • 注册日期2007-10-22
  • 最后登录2012-04-19
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望93点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2008-05-24 11:34
加密头在文件首部时,考虑了映射文件吗?
应用层用CreateFileMapping、MapViewOfFile
内核层用NtCreateSection、NtMapViewOfSection

这些都要处理的
goodone
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2014-04-30
  • 粉丝3
  • 关注0
  • 积分372分
  • 威望174点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2008-05-24 14:54
引用第10楼fly1101于2008-05-24 11:34发表的  :
加密头在文件首部时,考虑了映射文件吗?
应用层用CreateFileMapping、MapViewOfFile
内核层用NtCreateSection、NtMapViewOfSection

这些都要处理的


不是很明白你说的意思,
可以在说详细点吗?
谢谢!
栀子花驿站 www.zhizihua.com
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2008-05-25 14:38
引用第9楼goodone于2008-05-24 11:02发表的  :



通过我的观察 SetInformation的IRP是在磁盘写之前出现的。。。。
所以 应该先在 SetInformation 中修改大小
.......


磁盘写出现之前的Set标志是A00,标志0x42的Set在磁盘写之后
goodone
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2014-04-30
  • 粉丝3
  • 关注0
  • 积分372分
  • 威望174点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2008-05-26 08:17
为什么会有两次的 set了?写之前有,写完以后还有?

还有就是写磁盘的话 flag应是0x43吧
栀子花驿站 www.zhizihua.com
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2008-05-26 12:41
引用第13楼goodone于2008-05-26 08:17发表的  :
为什么会有两次的 set了?写之前有,写完以后还有?

还有就是写磁盘的话 flag应是0x43吧


一次是应用程序发的,一次是系统发的,具体我也在研究。
磁盘写是0x43,但Set的是0x42,具体flag定义参考微软文档,我也忘啦
boxcounter
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2008-05-27 18:41
我已经解决了,原因是因为CCmgr不知道我的加密头的存在,导致刷脏页的时候出现这个问题。多谢各位 :)
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2008-05-27 19:25
引用第15楼boxcounter于2008-05-27 18:41发表的  :
我已经解决了,原因是因为CCmgr不知道我的加密头的存在,导致刷脏页的时候出现这个问题。多谢各位 :)

怎么解决的?这个问题是出现在NTFS上,还是FAT32上也会有?
boxcounter
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望20点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2008-05-28 11:51
让CCmgr感知到加密头的存在就OK了,当然我调整了整个框架实现这么个功能。
我是在NTFS上做的测试。
dionysus77
驱动小牛
驱动小牛
  • 注册日期2006-11-15
  • 最后登录2011-12-18
  • 粉丝0
  • 关注0
  • 积分27分
  • 威望392点
  • 贡献值0点
  • 好评度177点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2008-05-28 12:39
引用第17楼boxcounter于2008-05-28 11:51发表的  :
让CCmgr感知到加密头的存在就OK了,当然我调整了整个框架实现这么个功能。
我是在NTFS上做的测试。


如何让CCmgr感知到文件头呢?
对缓冲读写也偏移文件头长度吗?
goodone
驱动牛犊
驱动牛犊
  • 注册日期2007-01-30
  • 最后登录2014-04-30
  • 粉丝3
  • 关注0
  • 积分372分
  • 威望174点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2008-06-02 18:38
让CCmgr感知到文件头?如果让它感知到了,那它不会往下刷脏数据吗?
不会损毁我们自己的加在头部的加密标志吗?
栀子花驿站 www.zhizihua.com
上一页
游客

返回顶部