阅读:5197回复:10
请教 tooflat-sfilter 修改为简单文件过滤功能(有调试代码)
开发环境: Windows XP SP3
DDK: WDK 1.0 调试工具: VMware Server 2.0 rc1 和 Windbg 6.9 x86 虚拟机操作系统: Windows XP SP3 源码在附件中. 症状: 我将 tooflat-sfilter 源码修改成一个只有文件过滤功能的驱动, 过滤配置文件还是 xefs.dat 过滤文件时(例如 C:\TEST.TXT) 是正常的. 但是当过滤的对象是目录时 (例如 C:\ABC) , 有时出现 "另一个程序正在使用此文件,进程无法访问" 弹出框. 使用 sc stop sfilter 停止驱动后, 还是会弹出 "另一个程序正在使用此文件,进程无法访问." 请问各位大侠,是什么原因? 是被占用没释放么? 另请教帮我看看代码是不是有什么逻辑问题? 源码说明: 我修改 tooflat-sfilter 的思路是: 1. DriverEntry 中主要保留SfCreate DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate; DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate; DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SfCleanupClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose; // DriverObject->MajorFunction[IRP_MJ_READ] = SfRead; // DriverObject->MajorFunction[IRP_MJ_WRITE] = SfWrite; // DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = SfDirectoryControl; // DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = SfSetInformation; 2. 修改了 WorkerCtx 结构(即_POST_CREATE_WORKER_CONTEXT结构) , 加入了 IRP 和一个bool (用于标识是否找到规则匹配的文件) typedef struct _POST_CREATE_WORKER_CONTEXT { WORK_QUEUE_ITEM WorkItem; KEVENT Event; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; PFILE_CONTEXT FileContext; BOOLEAN NewElement; IN PIRP Irp; BOOLEAN FoundItem; } POST_CREATE_WORKER_CONTEXT, *PPOST_CREATE_WORKER_CONTEXT; 3. 修改 SfPostCreateWorker 使用SfIsFileNeedEncrypt判断是否匹配规则 VOID SfPostCreateWorker( IN PVOID Context ) { PPOST_CREATE_WORKER_CONTEXT WorkerCtx = Context; PDEVICE_OBJECT DeviceObject = WorkerCtx->DeviceObject; PFILE_OBJECT FileObject = WorkerCtx->FileObject; PFILE_CONTEXT FileCtxPtr = WorkerCtx->FileContext; PIRP MyIrp = WorkerCtx->Irp; //PIO_STACK_LOCATION irpSp; BOOLEAN NewElement = WorkerCtx->NewElement; BOOLEAN IsEncryptFlagExist = FALSE; BOOLEAN IsNeedEncrypt = FALSE; NTSTATUS Status = STATUS_SUCCESS; #if DBG KdPrint(("sfilter!SfPostCreateWorker: FileName = %ws\n", FileCtxPtr->Name)); #endif // // we need handle file synchronously // KeWaitForSingleObject(&FileCtxPtr->Event, Executive, KernelMode, FALSE, NULL); if (NewElement) { /// Status = SfIsEncryptFlagExist(DeviceObject, FileCtxPtr->Name, &IsEncryptFlagExist, FileCtxPtr->EncryptExtData, sizeof(FileCtxPtr->EncryptExtData)); /// if (!NT_SUCCESS(Status)) /// KdPrint(("sfilter!SfCreate: SfIsEncryptFlagExist failed, return %x\n", Status)); Status = SfIsFileNeedEncrypt(DeviceObject, FileCtxPtr->Name, &IsNeedEncrypt); if (!NT_SUCCESS(Status)) KdPrint(("sfilter!SfCreate: SfIsFileNeedEncrypt failed, return %x\n", Status)); FileCtxPtr->EncryptFlagExist = IsEncryptFlagExist; FileCtxPtr->NeedEncrypt = IsNeedEncrypt; } else { IsEncryptFlagExist = FileCtxPtr->EncryptFlagExist; IsNeedEncrypt = FileCtxPtr->NeedEncrypt; // ASSERT(IsEncryptFlagExist == IsNeedEncrypt); } if(IsNeedEncrypt) //if found the item { #if DBG KdPrint(("SFilter!SfPostCreateWorker: === **** Find the Item === \n")); #endif MyIrp->IoStatus.Status = STATUS_ACCESS_DENIED; WorkerCtx->FoundItem = TRUE; } else //if not found the item { WorkerCtx->FoundItem = FALSE; } KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE); } 4. SfCreate 修改 主要是这段修改, 用于判断是否找到, 并根据结果执行不同的irp操作 ..... WorkerCtx.FoundItem = FALSE; ExInitializeWorkItem(&WorkerCtx.WorkItem, SfPostCreateWorker, &WorkerCtx); WorkerCtx.DeviceObject = DeviceObject; WorkerCtx.FileObject = FileObject; WorkerCtx.Irp = Irp; KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE); WorkerCtx.FileContext = FileCtxPtr; WorkerCtx.NewElement = NewElement; if (KeGetCurrentIrql() == PASSIVE_LEVEL) SfPostCreateWorker(&WorkerCtx); else { ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue); KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL); } } } while (FALSE); if (FileName) ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName); FoundItem = WorkerCtx.FoundItem; if (!FoundItem) //if found the item { Irp->IoStatus.Status = Status; } else //if not found the item { Irp->IoStatus.Information = 0; WorkerCtx.FoundItem = FALSE; #if DBG KdPrint(("SFilter!SfCreate: === **YULEI** Find the Item === \n")); #endif } IoCompleteRequest(Irp, IO_NO_INCREMENT); .... 5. SfMatchWithPattern 简单修改, 使之可以统一识别大小写字母 完. |
|
|
沙发#
发布于:2008-08-10 17:33
附一张调试截图. 就是如图所示的情况.
|
|
板凳#
发布于:2008-08-20 21:28
顶!!!
最近也在做文件系统过虑。。。 |
|
|
地板#
发布于:2009-03-22 19:48
我怎么装载不了 ?楼主能说一下装载方法吗 ?
谢谢 |
|
地下室#
发布于:2009-04-01 21:02
期待解决方案!
|
|
5楼#
发布于:2010-06-10 14:43
学习了
|
|
6楼#
发布于:2010-10-19 19:51
学习学习
|
|
7楼#
发布于:2011-09-06 17:31
学习学习
|
|
8楼#
发布于:2012-06-26 17:56
下载不了附件
|
|
9楼#
发布于:2012-07-02 17:42
STUDYING
|
|
10楼#
发布于:2015-04-08 20:25
|
|