我可以使用FltQueueDeferredIoWorkItem挂起IRP_MJ_WRITE和IRP_MJ_READ吗?

时间:2017-03-27 03:53:33

标签: windows hang minifilter

我正在编写一个文件系统minifilter驱动程序,它将监视IRP_MJ_CREATE,IRP_MJ_CLOSE,IRP_MJ_READ& IRP_MJ_WRITE操作。我必须以这样的方式实现它:当我调用pre-op回调时,我需要从用户程序获得一个输入,是否允许或阻止我计划的操作(对于所选文件的列表)使用FltQueueDeferredIoWorkItem和FltCompletePendedPreOperation()。

我写了一个示例,其中我的Preop回调函数执行以下操作(作为测试) - 分配工作项目 - 调用FltQueueDeferredIoWorkItem并对其进行排队 - 将CompletionContext设置为NULL - 返回FLT_PREOP_PENDING

我的延迟IO回调例程将创建一个记录(来自非分页池的自定义类型),从PFLT_CALLBACK_DATA复制详细信息并将其传递给Completioncontext参数并返回状态FLT_PREOP_SUCCESS_WITH_CALLBACK。

如果我只监视IRP_MJ_CREATE,这可以正常工作。如果我同时为IRP_MJ_WRITE / READ / CLOSE注册前后操作例程,它只能工作几秒钟,之后我的机器会冻结。

在预创建例程中,我不应该像这样为了IRP_MJ_WRITE / READ / CLOSE而放置IO吗?

1 个答案:

答案 0 :(得分:1)

好的,有两个问题:

  1. 我最初没有检查FltQueueDeferredIoWorkItem的状态,即使排队失败也返回FLT_PREOP_PENDING。

  2. 第二个问题与在调用FltQueueDeferredIoWorkItem之前锁定用户缓冲区有关。看起来使用FltQueueDeferredIoWorkItem进行读/写等的正确方法是在调用FltQueueDeferredIoWorkItem之前使用FltLockUserBuffer锁定用户缓冲区。我在MSDN中找不到这个文档,但发现了其他一些链接。 改变我的Precreate例程如下,现在它可以工作:

  3. ..      WorkItem = FltAllocateDeferredIoWorkItem();

     FltLockUserBuffer(Data);
    
     Status = FltQueueDeferredIoWorkItem(WorkItem, Data, &FileDeferredRoutine,     DelayedWorkQueue, CompletionContext);
    
     if(Status==STATUS_SUCCESS)
    
     return FLT_PREOP_PENDING;
    

    ...