Accessing User Buffers
All parameters specific to a given I/O operation, including buffers and memory descriptor lists (MDLs), are defined in an FLT_PARAMETERS union. This union is contained in an FLT_IO_PARAMETER_BLOCK structure that is accessed through the Iopb member of the FLT_CALLBACK_DATA structure that represents the I/O operation. Both the filter manager and minifilter drivers use FLT_CALLBACK_DATA structures to initiate and process I/O operations.
The FLT_PARAMETERS union also contains any parameter definitions for IRP-based operations that are specific to the buffering method used for that operation (buffered, direct I/O, or neither buffered nor direct I/O). It also contains parameter definitions for non-IRP-based operations (fast I/O and FsFilter callback routines).
A minifilter driver can call FltDecodeParameters to get pointers to the MDL address, buffer pointer, buffer length, and desired access parameters for an I/O operation. This saves minifilter drivers from having a switch statement to find the position of these parameters in helper routines that access these parameters across multiple I/O operations.
When processing an I/O operation that involves user buffers, a minifilter driver should always use an MDL if one is available. If so, the minifilter driver should call MmGetSystemAddressForMdlSafe to get a system address for the MDL and use the system address to access the user buffer.
If only a buffer address is available, the minifilter driver should always enclose any attempts to access the buffer in a try/except block. If the minifilter driver needs to access the buffer in a postoperation callback routine that is not synchronized, or if the I/O operation is posted to a worker thread, the minifilter driver should also lock the user buffer by calling FltLockUserBuffer. This function determines the appropriate access method to apply for the locked buffer based on the type of I/O operation and creates an MDL that points to the locked pages.
The filter manager provides the following support routines for accessing user buffers in preoperation and postoperation callback routines: