我正在编写一个文件系统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吗?
答案 0 :(得分:1)
好的,有两个问题:
我最初没有检查FltQueueDeferredIoWorkItem的状态,即使排队失败也返回FLT_PREOP_PENDING。
第二个问题与在调用FltQueueDeferredIoWorkItem之前锁定用户缓冲区有关。看起来使用FltQueueDeferredIoWorkItem进行读/写等的正确方法是在调用FltQueueDeferredIoWorkItem之前使用FltLockUserBuffer锁定用户缓冲区。我在MSDN中找不到这个文档,但发现了其他一些链接。 改变我的Precreate例程如下,现在它可以工作:
.. WorkItem = FltAllocateDeferredIoWorkItem();
FltLockUserBuffer(Data);
Status = FltQueueDeferredIoWorkItem(WorkItem, Data, &FileDeferredRoutine, DelayedWorkQueue, CompletionContext);
if(Status==STATUS_SUCCESS)
return FLT_PREOP_PENDING;
...