阅读:2028回复:12
关于Sfilter文件动态加解密的小问题
1、原始的Sfilter(IFS2003)在Windows2000下无经修改,可否绑定在Fat32格式的Volume上?
在我的机器上,只能绑定在Ntfs格式的Volume上。而且,目前我还找不到修改的办法让它绑定在Fat32上。 2、在处理读文件时,SfRead是否也只是处理IRP_NOCACHE|IRP_PAGING_IO|IRP_SYNCHRONOUS_PAGING_IO? 我的程序中判定上面三种条件符合时就设置完成进程,但为什么我所设置的完成进程在读文件时不被调用? 3、PAGED_CODE();宏定义是做什么的?可有可无么? |
|
沙发#
发布于:2005-01-14 02:13
1. 为什么不可以? SFilter并没有局限于某一种文件系统.
2. 把CODE贴出来看, 你可能什么地方处理错了. 3. PAGED_CODE是在DEBUG BUILD的时候帮助你判断是不是在正确的IRQL, 在RELEASE时自然就没有了. NTDDK.H里面有定义. toad |
|
板凳#
发布于:2005-01-14 08:58
1. 为什么不可以? SFilter并没有局限于某一种文件系统. sfilter对文件系统类型没什么要求,NTFS和FAT32都可以的。 |
|
|
地板#
发布于:2005-01-14 17:00
NTSTATUS
SfRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ 这个例程实现了对IRP_MJ_READ的操作。 --*/ { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT FileObject = irpSp->FileObject; ULONG Length = irpSp->Parameters.Read.Length; WCHAR FileNameBuf[512],TargetFileNameBuf[512]; UNICODE_STRING FileName, TargetFileName; PAGED_CODE(); DbgPrint("=tianccp=>In SfRead...... \n"); ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject )); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); // // 对目标文件进行判断,驱动只针对目标文件进行过滤,如果符合要求,进行解密 // RtlInitEmptyUnicodeString(&FileName,FileNameBuf,512); RtlInitEmptyUnicodeString(&TargetFileName,TargetFileNameBuf,512); if(FileObject) { if( FileObject->FileName.Buffer && !(FileObject->Flags & FO_DIRECT_DEVICE_OPEN) ) { RtlCopyUnicodeString(&FileName,&FileObject->FileName); } RtlInitUnicodeString(&TargetFileName, L"\\test\\1.txt"); //如果这条语句放到上面那个if语句里面,则启动时会死机。 } else { //文件对象为空,不符合要求,直接下传 IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject,Irp); } DbgPrint("Read File Name: \"%ws\" \n",(&FileName)->Buffer); //比较文件名 if (!RtlCompareUnicodeString( &FileName, &TargetFileName, TRUE )) { DbgPrint("Bingo!\n"); //实际上,只处理这三种情况 if((Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) || (Irp->Flags & IRP_NOCACHE)) { //设置完成例程 IoCopyCurrentIrpStackLocationToNext( Irp ); DbgPrint("set the completion!\n"); IoSetCompletionRoutine( Irp, SfReadCompletion, 0, TRUE, TRUE, TRUE ); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } } //对于一般不符合要求的,即文件名不匹配的,直接下传 IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject,Irp); } ---------------------------------------- 上面是SfRead函数,对被操作文件进行判断。如果是\\test\\1.txt则进行加密,否则直接传递IRP到下一层。 通过dbgview进行观察,发现每次对\\test\\1.txt文件进行读操作时,都不会执行完成例程。(有几次发现刚开机时第一次读该文件会有完成例程进行调用,以后就没有了。) |
|
地下室#
发布于:2005-01-15 02:29
粗看了一下, 你的程序有以下几个问题:
1. 内核线程的STACK只有12K, 而你的程序一下子就干掉了1K+. 这种情况下, 从POOL分配内存比较好. 2. RtlInitEmptyUnicodeString和RtlInitUnicodeString的用法你该看看DDK, 显然你浪费了TargetFileNameBuf的内存. 3. 通常只有在IRP_MJ_CREATE的时候FileObject->FileName里面才会有有效文件名. 在IRP_MJ_READ的时候你不能根据这个FIELD来取文件名. 4. 当你引用UnicodeString.Buffer之前, 要判断一下UnicodeString.Length的值. 5. UnicodeString.Buffer不是一定NULL-terminated, 大多数时候你需要自己APPEND一个L'\\0'. 6. 最后, 你从FileObject里面构造FileName的方法有问题. 具体参考filemon的代码. toad |
|
5楼#
发布于:2005-01-17 18:41
非常感谢toadwolf的回帖,使我获益匪浅。
现在还有一点,就是代码中设置完成例程的那一段。首先文件名验证已经通过了,可是为什么IRP_PAGING_IO || IRP_SYNCHRONOUS_PAGING_IO || IRP_NOCACHE条件不满足呢?每次读过程都不能满足? 谢谢! |
|
6楼#
发布于:2005-01-18 07:22
你说的那些FLAG在IRP_MJ_CREATE的时候设到FileObject->FsContext中去了, 在IRP_MJ_READ的时候文件系统是从FCB中取值的, 不是Irp->Flags中. 作为过滤驱动, 只有在IRP_MJ_CREATE的时候把这个值记下来.
toad |
|
7楼#
发布于:2005-01-18 17:51
谢谢,有点明白了……
不过,如果需要在Create的时候记录文件名称和有关Flags,那么,怎么让我的SfRead知道呢?用参数传递么?或者我可以设置全局变量?如果系统中同时有别的文件在读,会不会有不同的SfRead出现而产生混乱? ------------------ 不好意思,也许问的问题对于过来人有些白痴 :) ,但我由于做这个东西很仓促,有些文件系统基础问题还没有搞明白,所以只能把我脑子里想的问出来了,见谅! |
|
8楼#
发布于:2005-01-18 20:41
你说的那些FLAG在IRP_MJ_CREATE的时候设到FileObject->FsContext中去了, 在IRP_MJ_READ的时候文件系统是从FCB中取值的, 不是Irp->Flags中. 作为过滤驱动, 只有在IRP_MJ_CREATE的时候把这个值记下来. are you sure ??? 据我所知,不是这样 |
|
9楼#
发布于:2005-01-18 21:25
我现在观察了IRP->Flags的值,发现为0900,也就是说,每次读文件的时候,IRP->Flags是IRP_READ_OPERATION和IRP_DEFER_IO_COMPLETION。所以在我的读函数中无法进入到设置完成例程那一段。
如果去掉Flags判断这个条件,则系统会在访问目标文件的时候蓝屏,原因是PAGE_FAULT_.......(我记不清了) ----------------------- 通过IRP_MJ_READ进入SfRead之后就一定是去硬盘上读数据了么? 我的写函数按照“判定->新开缓冲区->加密->交换缓冲区->下传IRP->在完成例程中恢复原缓冲区”的步骤写的,现在由于读函数的问题,每次读出来的都是明文,重新启动之后,却又变成了密文。 ------------------------- 还有,FastIo的操作怎么没有呢?每次我鼠标单击或者双击打开文件,都会调用SfRead,无一例外。我不太明白。不是说如果文件处于缓存中的话,只用调用FastIo就行了么? |
|
10楼#
发布于:2005-01-19 07:48
我也在做文件加密,但是老是出问题,希望能和大家交流。
|
|
|
11楼#
发布于:2005-01-19 11:35
我也在做类似的工作,希望能和大家多多交流。
|
|
|
12楼#
发布于:2005-03-15 13:29
你判定文件名的方法不对,不能用那个FileObject->FileName,这个是个没有用的数值。你需要发送相关的包,你可以看看filemon 怎么取的文件名称。我测试国没有问题的,
FASTIO在你文件很大时就发生了,很多的。 |
|