200 likes | 926 Views
Accessing User Buffers. Buffer Handling in the IO Manager. DeviceObjects have 3 different buffering methods DO_BUFFERED_IO IoMgr allocates nonPaged pool and copies data to/from users buffer to system buffer Occurs in context of initiating thread DO_DIRECT_IO
E N D
Accessing User Buffers © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling in theIO Manager • DeviceObjects have 3 different buffering methods • DO_BUFFERED_IO • IoMgr allocates nonPaged pool and copies data to/from users buffer to system buffer • Occurs in context of initiating thread • DO_DIRECT_IO • IoMgr probes and locks the users buffer • An MDL is always created • Occurs in context of initiating thread • NEITHER (meaning neither of the above flags are set) • System does nothing to the buffers • All standard Microsoft file systems use NEITHER buffering © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling is Operation Specific • These operations buffer according to the state of the DeviceObject buffering flags: • IRP_MJ_READ • IRP_MJ_WRITE • IRP_MJ_QUERY_EA • IRP_MJ_SET_EA • IRP_MJ_DIRECTORY_CONTROL • IRP_MJ_QUERY_QUOTA • IRP_MJ_SET_QUOTA © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling is Operation Specific (cont’d) • These operations are always buffered regardless of the state of the DeviceObject buffering flags: • IRP_MJ_CREATE (EA buffer) • IRP_MJ_QUERY_INFORMATION • IRP_MJ_SET_INFORMATION • IRP_MJ_QUERY_VOLUME_INFORMATION • IRP_MJ_SET_VOLUME_INFORMATION • IRP_MJ_SYSTEM_CONTROL © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling is Operation Specific (cont’d) • These operations never look at the state of the DeviceObject buffering flags. Their buffers should be treated as if NEITHER buffering was selected: • IRP_MJ_QUERY_SECURITY • IRP_MJ_SET_SECURITY • IRP_MJ_PNP © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling is Operation Specific (cont’d) • These operations have no buffer • IRP_MJ_CREATE_NAMED_PIPE • IRP_MJ_CREATE_MAILSLOT • IRP_MJ_LOCK_CONTROL © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling is Operation Specific (cont’d) • These operations define their buffering method inside the IoControlCode parameter: • IRP_MJ_FILE_SYSTEM_CONTROL • IRP_MJ_DEVICE_CONTROL • IRP_MJ_INTERNAL_DEVICE_CONTROL © 2004 Microsoft Corporation. All rights reserved.
Buffer Handling is Operation Specific (cont’d) • FastIO operations • Never look at the state of the buffering flags in the DeviceObject • Should always be treated as NEITHER buffering • FsFilter callbacks • Don’t have user buffers © 2004 Microsoft Corporation. All rights reserved.
FLT_PARAMETERS Structure • Union which defines all parameters for each operation • Includes Buffer and MDL parameters • Buffer and MDL parameters are stacked © 2004 Microsoft Corporation. All rights reserved.
FLT_PARAMETERS Structure (cont) • Buffering method specific parameter definitions for • IRP_MJ_FILE_SYSTEM_CONTROL • IRP_MJ_DEVICE_CONTROL • Parameter definitions for non-IRP operations • FastIO only operations • FsFilter callbacks • New Operations • IRP_MJ_VOLUME_MOUNT • IRP_MJ_VOLUME_DISMOUNT (not currently implemented) © 2004 Microsoft Corporation. All rights reserved.
Buffer Address vs. MDL • You can have the following combinations of the two: • MDL only (typically on paging IO) • Buffer Address only • Buffer Address and MDL • Always check for a MDL first • If it has one, get a system address for it and use that © 2004 Microsoft Corporation. All rights reserved.
Accessing User Buffer in the PreOperation Callback • IRP operation • Has MDL • Always use system address by calling MmGetSystemAddressForMdlSafe() • Does not have MDL • Use Try/Except around access • FastIO operation • Never has a MDL • Use Try/Except around access © 2004 Microsoft Corporation. All rights reserved.
Accessing User Buffer in the PostOperation Callback • IRP operation • Has MDL • Always use system address by calling MmGetSystemAddressForMdlSafe() • Can do this at DPC level • No MDL • FLTFL_CALLBACK_DATA_SYSTEM_BUFFER flag set • Can directly access the buffer • Can do this at DPC level © 2004 Microsoft Corporation. All rights reserved.
Accessing User Buffer in the PostOperation Callback (cont) • No MDL (cont) • FLTFL_CALLBACK_DATA_SYSTEM_BUFFER flag not set • Move to safe IRQL • see FltDoCompletionProcessingWhenSafe() • Lock the users buffer • seeFltLockUserBuffer() • Get system address by calling MmGetSystemAddressForMdlSafe() • Do this because you don’t know what thread context you are in © 2004 Microsoft Corporation. All rights reserved.
Accessing User Buffer in the PostOperation Callback (cont’d) • FastIO operation • Use Try/Except around access • You are always in the correct thread context • You are never at DPC level © 2004 Microsoft Corporation. All rights reserved.
FltLockUserBuffer() • Restrictions: • Can not be called at DPC level • If no MDL defined • Allocates MDL • Updates MdlAddress parameter in CallbackData • Marks the CallbackData dirty • FLT_SET_CALLBACK_DATA_DIRTY() • Properly handles buffers in system address space © 2004 Microsoft Corporation. All rights reserved.
FltLockUserBuffer() (cont) • If pages are not already locked, probe and lock the pages • Filter must still call MmGetSystemAddressForMdlSafe()to get a system buffer that represents this memory • NOTE: This function is expensive – don’t map buffers unless you absolutely need to © 2004 Microsoft Corporation. All rights reserved.
FLTFL_CALLBACK_DATA_SYSTEM_BUFFER Flag • If set, the buffer parameter is BUFFERED. • Address is in system address space • Flag should never be changed by a filter • When creating a MDL for a buffered parameter, always use MmBuildMdlForNonPagedPool() • FltLockUserBuffer()properly handles buffers with this flag set © 2004 Microsoft Corporation. All rights reserved.
FltDecodeParameters() • Returns pointers into the current IOPB based on the current operation for • MDL address parameter • Buffer address parameter • Length parameter • Returns access you have to the buffer • IoReadAccess • You can look at the buffer, you can’t change it • IoWriteAccess & IoModifyAccess • You can look at and change the buffer © 2004 Microsoft Corporation. All rights reserved.
FltDecodeParameters() (cont) • The returned MDL and length pointers may be NULL for some operations • Returns an error for operations that don’t have a buffer • Recommended you don’t use for IRP_MJ_FILE_SYSTEM_CONTROL and IRP_MJ_DEVICE_CONTROL • Method NEITHER and DIRECT buffering have 2 buffer parameters • Use with caution © 2004 Microsoft Corporation. All rights reserved.