阅读:11215回复:26
miniFilter下,文件透明加密文件大小返回的问题
我的透明加密加密标志放在文件头部,长度4K。现在经过测试,记事本和Office系列,AutoCAD都能正常加密解密。就是UltraEdit,写字板,打开文件后,文件内容是解密后的正确数据,但是,在正文后面,会有4K的空白区域,我觉得是这两个应用取到了实际的文件大小。
根据论坛上查找到的资料,我处理了IRP_MJ_QUERY_INFORMATION 的FileAllInformation(StandardInformation.EndOfFile 和AllocationSize ),FileAllocationInformation(AllocationSize ),FileValidDataLengthInformation (ValidDataLength ),FileStandardInformation (EndOfFile 和AllocationSize ),FileNetworkOpenInformation(AllocationSize ,EndOfFile ),IRP_MJ_DIRECTORY_CONTROL(FileBothDirectoryInformation )。跟踪观察,这些返回的数据都是我想要的结果。可为什么UltraEdit和写字板还是能够获取到实际文件的大小,搞不懂,难道他们是通过其他途径得到的文件大小? 下面是我的代码: SharePostQueryInfo: switch (FileInfoClass) { case FileAllInformation: { PFILE_ALL_INFORMATION psFileAllInfo = (PFILE_ALL_INFORMATION)FileInfoBuffer ; // 注意FileAllInformation,即使长度不够, // 依然可以返回前面的字节。 // 需要注意的是返回的字节里是否包含了StandardInformation // 这个可能影响文件的大小的信息。 if (Data->IoStatus.Information >= sizeof(FILE_BASIC_INFORMATION) + sizeof(FILE_STANDARD_INFORMATION)) { psFileAllInfo->StandardInformation.EndOfFile.QuadPart -= FILE_HEAD_LENGTH; psFileAllInfo->StandardInformation.AllocationSize.QuadPart -= FILE_HEAD_LENGTH; if(Data->IoStatus.Information >= sizeof(FILE_BASIC_INFORMATION) + sizeof(FILE_STANDARD_INFORMATION) + sizeof(FILE_INTERNAL_INFORMATION) + sizeof(FILE_EA_INFORMATION) + sizeof(FILE_ACCESS_INFORMATION) + sizeof(FILE_POSITION_INFORMATION)) { if(psFileAllInfo->PositionInformation.CurrentByteOffset.QuadPart >= FILE_HEAD_LENGTH) psFileAllInfo->PositionInformation.CurrentByteOffset.QuadPart -= FILE_HEAD_LENGTH; } } break ; } case FileAllocationInformation: { PFILE_ALLOCATION_INFORMATION psFileAllocInfo = (PFILE_ALLOCATION_INFORMATION)FileInfoBuffer; psFileAllocInfo->AllocationSize.QuadPart -= FILE_HEAD_LENGTH; break ; } case FileValidDataLengthInformation: { PFILE_VALID_DATA_LENGTH_INFORMATION psFileValidLengthInfo = (PFILE_VALID_DATA_LENGTH_INFORMATION)FileInfoBuffer ; psFileValidLengthInfo->ValidDataLength.QuadPart -= FILE_HEAD_LENGTH; break ; } case FileStandardInformation: { PFILE_STANDARD_INFORMATION psFileStandardInfo = (PFILE_STANDARD_INFORMATION)FileInfoBuffer ; psFileStandardInfo->AllocationSize.QuadPart -= FILE_HEAD_LENGTH; psFileStandardInfo->EndOfFile.QuadPart -= FILE_HEAD_LENGTH; break ; } case FileEndOfFileInformation: { PFILE_END_OF_FILE_INFORMATION psFileEndInfo = (PFILE_END_OF_FILE_INFORMATION)FileInfoBuffer ; psFileEndInfo->EndOfFile.QuadPart -= FILE_HEAD_LENGTH; break ; } case FilePositionInformation: { PFILE_POSITION_INFORMATION psFilePosInfo = (PFILE_POSITION_INFORMATION)FileInfoBuffer ; if(psFilePosInfo->CurrentByteOffset.QuadPart >= FILE_HEAD_LENGTH) psFilePosInfo->CurrentByteOffset.QuadPart -= FILE_HEAD_LENGTH; break ; } case FileNetworkOpenInformation: { PFILE_NETWORK_OPEN_INFORMATION psFileNetOpenInfo = (PFILE_NETWORK_OPEN_INFORMATION)FileInfoBuffer ; psFileNetOpenInfo->AllocationSize.QuadPart -= FILE_HEAD_LENGTH; psFileNetOpenInfo->EndOfFile.QuadPart -= FILE_HEAD_LENGTH; break ; } default: ASSERT(FALSE) ; }; SharePostDirCtrl是使用自带的SwapBuffer例子,只是在 RtlCopyMemory( origBuf, p2pCtx->SwappedBuffer, /*Data->IoStatus.Information*/ iopb->Parameters.DirectoryControl.QueryDirectory.Length );之前处理p2pCtx->SwappedBuffer,处理流程如下 switch (FileInfoClass) { case FileBothDirectoryInformation : { PFILE_BOTH_DIR_INFORMATION pbdi = (PFILE_BOTH_DIR_INFORMATION)pBuf; do { if (IsMyFile(pbdi)) { pbdi->AllocationSize.QuadPart -= FILE_HEAD_LENGTH; pbdi->EndOfFile.QuadPart -= FILE_HEAD_LENGTH; } if (!pbdi->NextEntryOffset) break; pbdi = (PFILE_BOTH_DIR_INFORMATION)((CHAR*)pbdi + pbdi->NextEntryOffset); } while (FALSE); break; } case FileDirectoryInformation : { PFILE_DIRECTORY_INFORMATION pfdi = (PFILE_DIRECTORY_INFORMATION)pBuf; do { if (IsMyFile(pfdi)) { pfdi->AllocationSize.QuadPart -= FILE_HEAD_LENGTH; pfdi->EndOfFile.QuadPart -= FILE_HEAD_LENGTH; } if (!pfdi->NextEntryOffset) break; pfdi = (PFILE_DIRECTORY_INFORMATION)((CHAR*)pfdi + pfdi->NextEntryOffset); } while (FALSE); break; } case FileFullDirectoryInformation : { PFILE_FULL_DIR_INFORMATION pffdi = (PFILE_FULL_DIR_INFORMATION)pBuf; do { if (IsMyFile(pffdi)) { pffdi->AllocationSize.QuadPart -= FILE_HEAD_LENGTH; pffdi->EndOfFile.QuadPart -= FILE_HEAD_LENGTH; } if (!pffdi->NextEntryOffset) break; pffdi = (PFILE_BOTH_DIR_INFORMATION)((CHAR*)pffdi + pffdi->NextEntryOffset); } while (FALSE); break; } default : break; } |
|
沙发#
发布于:2010-09-23 20:20
楼主在隐藏长度的时候只处理的你说到的那几个吗?(query(set)information)都一样的吗
我在tooflat的代码中用《寒江独钓》的方法(文件头)处理加密标志,也是处理了你说的那几个请求,可是在新建word时获取长度总不对,需要重新设定 而且对tmp文件处理感觉文件长度也不对,导致word无法编辑 希望楼主能解答一下,谢谢! |
|
板凳#
发布于:2010-09-05 14:39
能否传一个给我,谢谢啦,新手学习下~
306142767@qq.com |
|
地板#
发布于:2010-09-05 13:22
能否传一个给我jjhoncy@yahoo.com.cn
|
|
地下室#
发布于:2010-07-17 20:34
参照这个地址提供的解决方法,治了标,不知道会不会有什么问题。
http://bbs.driverdevelop.com/read.php?tid-111958-keyword-notepad%7Cwordpad.html 读取的前后事件中处理 if (!(Data->Iopb->IrpFlags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))) { 如果是读取前,判断偏移量超过文件除去加密标志后的大小,则直接返回STATUS_END_OF_FILE,并退出,否则留待读取后回调事件处理 在读取后事件中,判断如果返回的Data->IoStatus.Information加上读取偏移量超过了文件除去标志后的大小,则修改Data->IoStatus.Information为文件大小减去便宜量后的大小。 } 这样处理目前来说解决了wordpad的读取问题,但是写还是有问题,写入后文件内有乱码。 可喜的是UltraEdit已经解决,读写都没有问题。 感谢dionysus77兄提供的思路。目前这个方法只能治标,不能治本,请使用的同志小心测试。 |
|
5楼#
发布于:2010-07-15 16:26
写字板是通过映射读取的,写字板是通过IO读取的,如果映射读取都没问题,IO读取应该也不会有问题。大致看了下你的代码, 好像在PostRead/Write FileObject->CurrentOffset没有修改回来,由于你在PreRead/Write中ByteOffset+4K, 如果是同步IO需要修改FileObject->CurrentOffset为正确的值。在文件系统中 FileObject->CurrentOffset = ByteOffset + IoStatus.Information, 需要相应的减去4K。
|
|
6楼#
发布于:2010-07-08 16:59
不是控制的问题,跟文件类型也无关,是跟应用有关。
同一个加密文件,用记事本打开正确,用写字板打开就有多文件头长度的空格,就是这样 |
|
7楼#
发布于:2010-07-05 16:59
文件透明加密/解密与文件无关,如果你一些文件类型能正确加解密,另一些不能,肯定是你的控制有问题.
|
|
8楼#
发布于:2010-06-24 09:23
我测试了ReadFile,里面有个参数是返回读取了多少字节,这个值就是整个文件的大小(前提是传入的读取字节数大于整个文件的长度),但是读取的字节数不是从IOStatus的information来的吗,我的information值是期望的返回值啊,不知道这个值是从哪里来的。要不然这个information还有什么用呢。
微软的函数一塌糊涂。 |
|
9楼#
发布于:2010-05-28 16:32
回 17楼(michaelgz) 的帖子
悲剧,这个问题搞的我快疯掉了。文件系统是使用CcSetFileSize来通知缓存管理器文件大小改变,我可不可以也使用这个来修改缓存管理器内保存的文件大小的值。如果可以,在什么时候修改可以达到这个目的? |
|
10楼#
发布于:2010-05-27 22:42
That thread was talking about a file system. Unfortunately yours is not.
|
|
11楼#
发布于:2010-05-27 13:37
http://www.osronline.com/showthread.cfm?link=178045
在OSRam找到了一个解决问题的帖子,但是不是太懂。希望有人给予指点。 |
|
12楼#
发布于:2010-05-24 18:15
回 12楼(michaelgz) 的帖子
谢谢提醒,现在的问题是只能通过缓存管理器和虚拟内存管理器的修改来解决这个问题? |
|
13楼#
发布于:2010-05-13 11:51
回 11楼(crazy4stef) 的帖子
QQ:94228827没太懂你说的情况,我的代码在上面有个链接里面,按你的说法其他程序或许也有这个问题,但是经过测试,Office2003系列和记事本,AutoCAD都没有问题 |
|
14楼#
发布于:2010-05-13 08:38
啊。。。
那楼上有没有关于a filter with its own FCB的例子或资料? |
|
15楼#
发布于:2010-05-12 23:25
I don't think there's good solution for this problem. I've repeated this many times already that only a real file system or a filter with its own FCB may solve this 文件透明加密 issue.
You may play with pre/post read/write. You may play with FCB. You may say it's working for most softwares including Word or VS. But for the past few years, I've seem so many failed filter drivers in production environment. The basic problem is that Windows FS, CMM and VMM are tightly coupled. Without ownership of file context, file-size-change is in conflict with Windows internal structure and synchronization mechanism especially. Hope someone can prove me wrong. So far, my thoughts got confirmed again and again...... |
|
16楼#
发布于:2010-05-12 18:32
4KB的空白区域应该是写的时候没写那么长,被对其到4kb去了,这里可能是cc把一个内存页面给purge到硬盘上
再调看看,楼主留个联系方式把,以后交流交流 |
|
17楼#
发布于:2010-05-12 17:51
回 8楼(crazy4stef) 的帖子
右键看到的文件大小是通过IRP_MJ_DIRECTORY_CONTROL的FileBothDirectoryInformation来处理的,但是这个时候文件对象无效,如果你要判断是否加密文件,就需要遍历读取所有结果集里面的文件判断是否加密文件,如果是酒需要减去加密标志头长度。shenhui说的我稍后试一下。我的WordPad和UltraEdit还是没解决。不知道是否有人能系统的说一下,加密标志在文件头的时候需要处理哪些文件长度信息才能完全隐藏文件头的大小。 |
|
18楼#
发布于:2010-05-12 17:31
楼主你改出来了吗,我的notepad也不行
|
|
19楼#
发布于:2010-05-11 15:17
好像这样处理右键点属性,还是能看到4kb的文件头
|
|
上一页
下一页