none
Pending a IRP_MJ_DIRECTORY_CONTROL::IRP_MN_QUERY_DIRECTORY operation RRS feed

  • Question

  • I'm running into an issue I don't understand. I'm trying to pend a IRP_MJ_DIRECTORY_CONTROL(IRP_MN_QUERY_DIRECTORY) operation, but seem to lose the return buffer.  I'm doing the following:

    1. Register for IRP_MJ_DIRECTORY_CONTROL (preop) and I can see in the debugger that it is breaking where expected.  I check the ((PFLT_CALLBACK_DATA)cbData)->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer address and it appears to be good (it contains random bytes but I see memory displayed in the debugger memory window).
    2. I create a struct that contains information including the passed in PFLT_CALLBACK_DATA and PCFLT_RELATED_OBJECTS pointers.  I push this struct into a queue and signal that there is something in my queue.  I return a FLT_PREOP_PENDING from my callback.
    3. A different thread alerted by the signal pops the struct from the queue and spawns a worker (FLTQueueDeferredIoWorkItem) thread to calls my user mode component to get the needed information (directory contents in this case).  A call is made to FltSendMessage and no return is expected.
    4. The user mode component finishes it's work and calls the filters notify function with a buffer containing the directory contents.
    5. The notification function calls a function to format the data based on the InformationClass requested and then attempts to copy it into the return buffer ((PFLT_CALLBACK_DATA)cbData)->Iopb->Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer.  Everything goes fine, until it tries to access the return buffer.  While the address of the buffer is the same as in the initial preop call the memory is not available.  The debugger shows ?? as the address contents and the RtlCopyMemory call fails with a memory fault.  I also noticed that the PCFLT_RELATED_OBJECTS that is pointed to is invalid at this point.

    From this description can someone suggest where my mistake is, or where I might begin to look?  Is it valid to assume that the PFLT_CALLBACK_DATA struct is valid until the operation is 'unpended' (FltCompletePendedOperation is called)?  If not how would I get this information?   What would cause the return buffer to become invalid during a pend?

    Thanks


    Static

    Monday, August 8, 2016 11:20 PM

Answers

  • If QueryDirectory.DirectoryBuffer is a user-space pointer, then it is only valid in a specific process. In general, if you have such a pointer and need to access the buffer in a worker thread, then you can allocate an MDL for the buffer, map it to system address space, and access the buffer via the system address. I'm not sure how to do that in a minifilter but the FltLockUserBuffer function looks promising; its documentation says it supports IRP_MJ_DIRECTORY_CONTROL.

    • Marked as answer by Static Shock Wednesday, August 10, 2016 6:07 PM
    Tuesday, August 9, 2016 2:47 PM
  • You need to call FltLockUserBuffer https://msdn.microsoft.com/en-us/library/windows/hardware/ff543371(v=vs.85).aspx before pending.  This will guarantee the buffer for you data is in memory when you process it.  Nothing else needs to be done, the FltLockUserBuffer call takes care of all the details such as creating the MDL, and upon completion of the request the minifilter framework does the cleanup.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 10, 2016 10:45 AM

All replies

  • If QueryDirectory.DirectoryBuffer is a user-space pointer, then it is only valid in a specific process. In general, if you have such a pointer and need to access the buffer in a worker thread, then you can allocate an MDL for the buffer, map it to system address space, and access the buffer via the system address. I'm not sure how to do that in a minifilter but the FltLockUserBuffer function looks promising; its documentation says it supports IRP_MJ_DIRECTORY_CONTROL.

    • Marked as answer by Static Shock Wednesday, August 10, 2016 6:07 PM
    Tuesday, August 9, 2016 2:47 PM
  • You need to call FltLockUserBuffer https://msdn.microsoft.com/en-us/library/windows/hardware/ff543371(v=vs.85).aspx before pending.  This will guarantee the buffer for you data is in memory when you process it.  Nothing else needs to be done, the FltLockUserBuffer call takes care of all the details such as creating the MDL, and upon completion of the request the minifilter framework does the cleanup.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, August 10, 2016 10:45 AM