snakebite2008
驱动牛犊
驱动牛犊
  • 注册日期2005-08-07
  • 最后登录2009-09-11
  • 粉丝1
  • 关注1
  • 积分2分
  • 威望12点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:5066回复:10

请教 tooflat-sfilter 修改为简单文件过滤功能(有调试代码)

楼主#
更多 发布于:2008-08-10 17:24
开发环境: 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 简单修改, 使之可以统一识别大小写字母

完.
附件名称/大小 下载次数 最后更新
sfilter.rar (31KB)  195 2008-08-10 17:24
snakebite2008
驱动牛犊
驱动牛犊
  • 注册日期2005-08-07
  • 最后登录2009-09-11
  • 粉丝1
  • 关注1
  • 积分2分
  • 威望12点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-08-10 17:33
附一张调试截图. 就是如图所示的情况.
fhqpdcn
驱动牛犊
驱动牛犊
  • 注册日期2007-06-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分14分
  • 威望86点
  • 贡献值1点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-08-20 21:28
顶!!!

最近也在做文件系统过虑。。。
我是菜鸟
BuShiXiaoHaiZi
驱动牛犊
驱动牛犊
  • 注册日期2008-12-20
  • 最后登录2012-04-22
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望531点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-03-22 19:48
我怎么装载不了 ?楼主能说一下装载方法吗 ?
谢谢
qin.susu
驱动牛犊
驱动牛犊
  • 注册日期2007-04-19
  • 最后登录2009-07-07
  • 粉丝0
  • 关注0
  • 积分196分
  • 威望477点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2009-04-01 21:02
期待解决方案!
ieieww
驱动牛犊
驱动牛犊
  • 注册日期2006-04-13
  • 最后登录2010-09-17
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望81点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2010-06-10 14:43
学习了
dlutfrank
驱动牛犊
驱动牛犊
  • 注册日期2010-09-26
  • 最后登录2011-04-11
  • 粉丝0
  • 关注0
  • 积分34分
  • 威望311点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2010-10-19 19:51
学习学习
jyu_730
驱动牛犊
驱动牛犊
  • 注册日期2011-09-03
  • 最后登录2011-10-23
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2011-09-06 17:31
学习学习
wudifccc4
驱动牛犊
驱动牛犊
  • 注册日期2012-06-24
  • 最后登录2012-06-27
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2012-06-26 17:56
下载不了附件
jason.l
驱动牛犊
驱动牛犊
  • 注册日期2012-07-02
  • 最后登录2013-05-07
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望111点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2012-07-02 17:42
STUDYING
Kingyanrao
驱动牛犊
驱动牛犊
  • 注册日期2015-04-08
  • 最后登录2015-08-02
  • 粉丝0
  • 关注0
  • 积分16分
  • 威望161点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2015-04-08 20:25
游客

返回顶部