阅读:3908回复:24
Lazy write导致的内容丢失问题
各位,我现在在做一个加解密的minifilter驱动,现在遇到一个问题:
我的加密头在文件首部。我在Write、read中,都会跳过这个首部(512B),通常情况下,这种情况都OK。但是发现当system进行延缓写的时候,会出现最后一部分WriteBuffer中的内容丢失,具体如下: 一个Write请求,Offset是0,WriteLength是8KB, 经过我的minifilter时,我修改offset为512,这样就跳过了我的加密头。然后发现写后返回的结果是只写了7.5KB,最后512字节没写进去,这导致文件中的512字节为随机脏数据,破坏了我的文档。 其中FileSize,AllocationSize都是足够大的,出现这个现象的原因不是因为空间不足而被截断。 我想请教各位朋友,这是因为什么,如何解决。 先多谢各位 :) |
|
最新喜欢:snox |
沙发#
发布于:2008-05-20 12:22
我也遇到这个问题,就是FileSize不够大的问题,因为SetInformation的IRP出现在磁盘写之后,而paging_io的写不能自动更新EoF。所以写入时,文件大小是不够的。自己设置一下长度再写入就好了。
|
|
板凳#
发布于: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 是足够大的 |
|
地板#
发布于:2008-05-21 19:47
引用第2楼boxcounter于2008-05-20 13:47发表的 : 对不起,我没看懂,postwrite里面怎么得到的FileSize? |
|
地下室#
发布于:2008-05-22 09:27
引用第3楼dionysus77于2008-05-21 19:47发表的 : 通过FCB来获取的 :) |
|
5楼#
发布于:2008-05-22 10:34
ValidDataLength比BytesWritten大1024字节。且小于写入长度,这里是不是有问题?
|
|
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这么长的数据。 |
|
7楼#
发布于:2008-05-23 12:14
ValidDataLength(11677)<Length: (12288).
|
|
8楼#
发布于:2008-05-24 11:00
这个确实是个问题,帮忙顶下,
期望大牛们给个回应 |
|
|
9楼#
发布于:2008-05-24 11:02
引用第1楼dionysus77于2008-05-20 12:22发表的 : 通过我的观察 SetInformation的IRP是在磁盘写之前出现的。。。。 所以 应该先在 SetInformation 中修改大小 但是 如果简单的修改大小 还是会有问题 |
|
|
10楼#
发布于:2008-05-24 11:34
加密头在文件首部时,考虑了映射文件吗?
应用层用CreateFileMapping、MapViewOfFile 内核层用NtCreateSection、NtMapViewOfSection 这些都要处理的 |
|
11楼#
发布于:2008-05-24 14:54
引用第10楼fly1101于2008-05-24 11:34发表的 : 不是很明白你说的意思, 可以在说详细点吗? 谢谢! |
|
|
12楼#
发布于:2008-05-25 14:38
引用第9楼goodone于2008-05-24 11:02发表的 : 磁盘写出现之前的Set标志是A00,标志0x42的Set在磁盘写之后 |
|
13楼#
发布于:2008-05-26 08:17
为什么会有两次的 set了?写之前有,写完以后还有?
还有就是写磁盘的话 flag应是0x43吧 |
|
|
14楼#
发布于:2008-05-26 12:41
引用第13楼goodone于2008-05-26 08:17发表的 : 一次是应用程序发的,一次是系统发的,具体我也在研究。 磁盘写是0x43,但Set的是0x42,具体flag定义参考微软文档,我也忘啦 |
|
15楼#
发布于:2008-05-27 18:41
我已经解决了,原因是因为CCmgr不知道我的加密头的存在,导致刷脏页的时候出现这个问题。多谢各位 :)
|
|
16楼#
发布于:2008-05-27 19:25
引用第15楼boxcounter于2008-05-27 18:41发表的 : 怎么解决的?这个问题是出现在NTFS上,还是FAT32上也会有? |
|
17楼#
发布于:2008-05-28 11:51
让CCmgr感知到加密头的存在就OK了,当然我调整了整个框架实现这么个功能。
我是在NTFS上做的测试。 |
|
18楼#
发布于:2008-05-28 12:39
引用第17楼boxcounter于2008-05-28 11:51发表的 : 如何让CCmgr感知到文件头呢? 对缓冲读写也偏移文件头长度吗? |
|
19楼#
发布于:2008-06-02 18:38
让CCmgr感知到文件头?如果让它感知到了,那它不会往下刷脏数据吗?
不会损毁我们自己的加在头部的加密标志吗? |
|
|
上一页
下一页