我有一个顶级minifilter驱动程序和一个用户模式服务,类似于Scanner MSDN example。
我希望我的用户模式服务在记事本中打开时替换A.txt
文件内容。
因此,在IRP_MJ_CREATE
后操作回调中,我正在向服务发送通知并等待它向文件写入新数据。
但服务无法打开A.txt
,因为它已被记事本锁定。
如何在不使用内核FltWriteFile的情况下允许我的服务编写数据?
这样做的最佳方式是什么?
也许取消文件打开,让服务写入数据并用相同的参数重新打开它而不留下操作后回调?
也许我应该在pre-op中覆盖所需的访问权限
---
任何信息将不胜感激。如果你认为这个问题缺乏细节,请告诉我。
答案 0 :(得分:2)
不要在PostOperation上通知您的服务,而是在PreOperation回调中执行此操作。当您在PostOperation中执行此操作时,将为Notepad.exe打开文件,这就是您的服务中打开失败的原因。
此外,如果您尚未执行此操作,则必须在服务将新数据写入文件时等待PreOperation。
答案 1 :(得分:1)
我真的不同意 Rogan的回答,因为在记事本之前该文件很可能被任何其他进程锁定。 这不是问题,或者至少不是你应该如何看待这个问题。
如果你想让记事本有一个A.txt的某个视图,只需使用记事本的FILE_OBJECT并自己从内核写。只需记住使用 ObReferenceObjectByPointer 并要求 WRITE 访问。由于访问模式将是内核模式,因此您将被允许。
或者,如果您真的希望它由您的服务完成,请从驱动程序中自行打开文件并提供服务句柄。从内核模式打开文件可能会影响共享模式等等,您需要阅读 FltCreateFileEx2 的文档以确保您拥有所有必需的参数。 在刚刚打开的FileObject上使用 ObOpenObjectByPointer 并访问模式UserMode。确保通过 KeStackAttachProcess 将您附加到用户模式的进程地址空间。
PostCreate中的操作顺序:
答案 2 :(得分:0)
// Decclaration
PFLT_CALLBACK_DATA Data //Note: you get this in preOperation as argument so dont need to defined explicitly
PFLT_FILE_NAME_INFORMATION nameInfo=NULL;//must be declared
NTSTATUS status;
if(KeCurrentIrql()==PASSIVE_LEVEL)// file operation should be performed in IRQL PASSIVE_LEVEL
{
status=FltGetFileNameInformation(Data,FLT_FILE_NAME_OPENED |FLT_FILE_NAME_qUERY_ALWAYS_ALLOW_CACHE_LOOKUP,&nameInfo);
if(NT_SUCCESS(status))
{
status = FltParseFileNameInformation(nameInfo);
}
}
//现在您在nameInfo Structure中有文件的信息。
//您可以获取文件信息,就像阅读上述结构的文档一样,可以帮助您更多地了解它们。特别是PFLT_FILE_NAME_INFORMATION。