hcl456
驱动牛犊
驱动牛犊
  • 注册日期2007-11-05
  • 最后登录2010-03-24
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望93点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:6600回复:4

在pre-read 中使用 FltReadFile

楼主#
更多 发布于:2009-04-21 00:50
大家好

最近在开发Minifilter文件加密驱动
因为 streamcontext 只能使用在 NTFS及FAT文件系统上
所以想要改用增加文件头的方式来做为加密档案的标识
可是在我想要读出之前写入的标识时
不管使用 FltReadFile 或者是 ZwReadFile总是没办法成功得到数据
请大家帮忙看看我的代码

在 pre-read callback 中如果直接呼叫 FltReadFile
(此时 Data->RequestorMode == 0)

    offset.QuadPart = (LONGLONG)0;
    status = FltReadFile( FltObjects->Instance,
                          FltObjects->FileObject,
                          &offset,
                          1024,
                          tempbuf,
                          FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET|FLTFL_IO_OPERATION_NON_CACHED,
                          NULL,
                          NULL,
                          NULL
                          );
                          
就会发生 C0000128 STATUS_FILE_CLOSED 的错误

于是我试着自己开启这个档案 于是将上面的代码改成这样

            UNICODE_STRING filename;
            PUCHAR tempbuf=NULL;
            HANDLE f_handle=INVALID_HANDLE_VALUE;
            OBJECT_ATTRIBUTES object_attribs;
            IO_STATUS_BLOCK io_status;
            LARGE_INTEGER offset;

            // filename 是类似这样的文字 "\??\F:\Somedir\somefile.txt"

            InitializeObjectAttributes(&object_attribs,
                                       &filename,
                                       OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
                                       NULL,
                                       NULL
                                       );

            status = FltCreateFile( FltObjects->Filter,
                                    FltObjects->Instance,
                                    &f_handle,
                                    GENERIC_READ|GENERIC_WRITE,
                                    &object_attribs,
                                    &io_status,
                                    NULL,
                                    FILE_ATTRIBUTE_NORMAL,
                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                                    FILE_OPEN,
                                    FILE_NON_DIRECTORY_FILE,
                                    NULL,
                                    0,
                                    IO_IGNORE_SHARE_ACCESS_CHECK
                                    );
                                        
            tempbuf = (PUCHAR) ExAllocatePoolWithTag(NonPagedPool,
                                                     1024,
                                                     BUFFER_SWAP_TAG
                                                     );

            if (tempbuf==NULL) {
                LOG_PRINT( LOGFL_ERRORS,
                           (__FUNCTION__" ExAllocatePoolWithTag return NULL\n"));

                leave;
            }

            offset.QuadPart = (LONGLONG) 0;

            status = ZwReadFile(f_handle,
                                NULL,
                                NULL,
                                NULL,
                                &io_status,
                                tempbuf,
                                1024,
                                &offset,
                                NULL
                                );      
                                
结果 即便FltCreateFile是成功的 但是ZwReadFile却回传错误 C000000D STATUS_INVALID_PARAMETER
后来我到OSR去看文章 看到有人在讨论类似的问题
http://www.osronline.com/showThread.cfm?link=154376
据他们的说法 加上 FILE_SYNCHRONOUS_IO_ALERT 参数就可以
我就把代码再改了一下 加上这些参数

            UNICODE_STRING filename;
            PUCHAR tempbuf=NULL;
            HANDLE f_handle=INVALID_HANDLE_VALUE;
            OBJECT_ATTRIBUTES object_attribs;
            IO_STATUS_BLOCK io_status;
            LARGE_INTEGER offset;

            InitializeObjectAttributes(&object_attribs,
                                       &filename,
                                       OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
                                       NULL,
                                       NULL
                                       );

            status = FltCreateFile( FltObjects->Filter,
                                    FltObjects->Instance,
                                    &f_handle,
                                    GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
                                    &object_attribs,
                                    &io_status,
                                    NULL,
                                    FILE_ATTRIBUTE_NORMAL,
                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                                    FILE_OPEN,
                                    FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_ALERT,
                                    NULL,
                                    0,
                                    IO_IGNORE_SHARE_ACCESS_CHECK
                                    );
                                        
            tempbuf = (PUCHAR) ExAllocatePoolWithTag(NonPagedPool,
                                                     1024,
                                                     BUFFER_SWAP_TAG
                                                     );

            if (tempbuf==NULL) {
                LOG_PRINT( LOGFL_ERRORS,
                           (__FUNCTION__" ExAllocatePoolWithTag return NULL\n"));

                leave;
            }

            offset.QuadPart = (LONGLONG) 0;

            status = ZwReadFile(f_handle,
                                NULL,
                                NULL,
                                NULL,
                                &io_status,
                                tempbuf,
                                1024,
                                &offset,
                                NULL
                                );          
                                
结果好像更糟 ZwReadFile 回传 C00002E8 STATUS_MULTIPLE_FAULT_VIOLATION
就不知道问题出在哪里了

试了好久都没结果 拜托各位帮忙看看啊

谢谢大家
zzbwang
驱动牛犊
驱动牛犊
  • 注册日期2009-03-18
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分62分
  • 威望611点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分1分
沙发#
发布于:2009-04-21 13:22
你的问题还没有描述清楚,你要读的这个文件是在PreRead中的目标文件吗?还是preRead要读A,你想先去读B?如果要读的是目标文件,那就不需要再打开。

既然是在minifilter中,我觉得应该尽量用FltReadFile之类的函数,而不是ZwReadFile类。

文件的打开与读写选项参数不要随便加,你要先理解这些选项的意义,比如FLTFL_IO_OPERATION_NON_CACHED这个选项会导致FSD要求你读写的Offset和Length都跟磁盘扇区大小对齐。

文件读写的时候要注意你使用的文件句柄是以什么方式打开的,不同的文件操作方式对文件读写有不同要求。
hcl456
驱动牛犊
驱动牛犊
  • 注册日期2007-11-05
  • 最后登录2010-03-24
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望93点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-04-23 22:33
我要读取的就是当前的目标文件 ( FltObjects->FileObject )

想到要再去开启它是因为FltReadFile 回传了 发生 C0000128 STATUS_FILE_CLOSED 的错误
pk8995
驱动牛犊
驱动牛犊
  • 注册日期2006-11-12
  • 最后登录2010-04-29
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望78点
  • 贡献值0点
  • 好评度14点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-07-21 15:47
返回C0000128是因为Read发生在Cleanup之后了
可能是Paging IO的Read,此类情况还可能发生在SetInfo、FlushBuffer之类的请求中……
shenhui
驱动小牛
驱动小牛
  • 注册日期2006-05-11
  • 最后登录2023-02-10
  • 粉丝14
  • 关注11
  • 积分142分
  • 威望1314点
  • 贡献值1点
  • 好评度146点
  • 原创分0分
  • 专家分1分
  • 社区居民
地下室#
发布于:2009-07-28 17:51
直接向文件系统DO发IRP来进行写操作
作一名真实,诚实,优秀的科技工作者!
游客

返回顶部