Question

I have a top-level minifilter driver and a user-mode service, which is similar to the Scanner MSDN example.

I want my user-mode service to replace the A.txt file contents, when it's opened in the Notepad.

So, in the IRP_MJ_CREATE post-operation callback I'm sending notification to the service and waiting for it to write a new data to the file.
But service cannot open the A.txt, because it's already locked by notepad.

How to allow my service to write the data without using the kernel FltWriteFile?
What is the best way of doing this?

Maybe cancel file open, letting service write data and reopen it with the same parameters without leaving the post-operation callback?
Maybe I should overwrite the desired access in the pre-op?

---
Any info will be appreciated. If you think this question lacks of details, please, let me know.

Was it helpful?

Solution

Instead of notifying to your service in on PostOperation, do that in PreOperation callback. By the time you do that in PostOperation file will be already opened for Notepad.exe, which is why open in your service is failing.

Also, if you are not doing already, you would have to wait in PreOperation while your service writes new data to the file.

OTHER TIPS

I don't really agreee with Rogan's answer, as the file could very well be locked by any other process before notepad. That is not the issue here or at least not how you should look at this problem.

If you want to notepad to have a certain view of A.txt, simply use notepad's FILE_OBJECT and do the writing yourself from the kernel. Just remember to use ObReferenceObjectByPointer and ask for the WRITE access. Since access mode will be kernel mode you will be allowed.

Alternatively if you really want it to be done by your service, open the file yourself, from the driver and provide a handle to your service. Opening the file from kernel mode could supress share modes and so on, you will need to read the documentation for FltCreateFileEx2 to make sure you have all the necessary parameters. Use ObOpenObjectByPointer on the FileObject you have just opened and access mode UserMode. Make sure you will be attached to your user-mode's process address space via KeStackAttachProcess.

Order of operations in PostCreate:

  1. FltCreateFileEx2(the_file, ignore_share_access, etcc )
  2. KeStackAttachProcess(your_service_eprocess)
  3. ObOpenObjectByPointer(UserMode=access_mode) -> now your um process has a handle to the file
  4. KeUnstackDetachProcess()
  5. Send the HANDLE pointer to the user-mode process as now it is able to use it.
  6. Wait for the user mode service to write the data and also close the handle Dereference the FileObject obtained as well as close the handle from FltCreateFileEx2.
  7. Let the Create go for Notepad
  8. Profit.

Good luck.

//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);
}
}

//Now you have Inforamtion of files in nameInfo Structure.

//you can get files inforamtion like that read documentions of above used structures will help you more about them. Specially PFLT_FILE_NAME_INFORMATION .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top