We have a FS legacy filter in which we pend some of the IRPs (read and write) based one some condition. So, obviously we need to lock the buffer before pending it and putting it in a queue for later processing.
Normally, Irp->UserBuffer contains a user mode buffer in which case IoAllocateMdl and MmProbeAndLockPages work fine.
But what if some kernel mode component has built an IRP and sent it such that it has used a Pageable memory in Irp->UserBuffer. This problem is straightforward since we will still be able to lock using the IoAllocateMdl and MmProbeAndLockPages functions. However, what if the driver specifies a NonPagedPool memory in the Irp->UserBuffer? I will end up doing an IoAllocateMdl and then MmProbeAndLockPages and then Boom. Probably the correct way would be to use IoAllocateMdl and then MmBuildMdlForNonPagedPool in this case. Now the question comes:
How do i decide by seeing the IRP which method to use for locking the buffer?
Thank you Maxim.
I am just predicting the “Boom”. So, if it is OK to call MmProbeAndLockPages for NonPaged address, then probably it will be safe to call IoFreeMdl too on the above built Mdl and the code for IoFreeMdl would be having the right check for Nonpaged address so that it does not try to unlock the pages described by the Mdl.
One more thing. Then how do i know if I need to call MmUnlockPages or not for the Mdl? If i understand it correctly, we cannot call MmUnlockPages for MDL that describes nonpagedpool address.
Also, the documentation for MmBuildMdlForNonPagedPool says that “Because the pages described by the MDL are already nonpageable and are already mapped to the system address space, drivers must not try to lock them by using the MmProbeAndLockPages routine, or to create additional system-address-space mappings by using the MmMapLockedPagesSpecifyCache routine.”
So, does this mean that we SHOULD NOT call MmProbeAndLockPages for nonpaged?
Then how do we build the MDL without worrying that the Irp->UserBuffer might have a nonpaged address.
MmBuildMdlForNonPagedPool is just there as an optimization if you know for
100% certain that the buffer came from non-paged pool. Instead of going
through all of the effort to make the pages of the buffer resident and pin
them to ensure that they stay resident, the Mm can short circuit the process
and simply grab the PFNs for the underlying buffer pages (since, by
definition, they’re always resident).
So, does this mean that we SHOULD NOT call MmProbeAndLockPages for
nonpaged?
The docs are actually trying to say that you should not call
MmProbeAndLockPages on an MDL built with MmBuildMdlForNonPagedPool. It’s not
very clear until the last sentence of that paragraph:
“If a driver performs any of these illegal operations on an MDL that is
built by MmBuildMdlForNonPagedPool, the resulting behavior is undefined.”
It is however just dandy to build an MDL describing a non-paged pool buffer
just like you would any other buffer
(IoAllocateMdl/MmProbeAndLockPages/etc). Again, MmBuildMdlForNonPagedPool is
just there as an optimization.
wrote in message news:xxxxx@ntfsd… > One more thing. Then how do i know if I need to call MmUnlockPages or not > for the Mdl? If i understand it correctly, we cannot call MmUnlockPages > for MDL that describes nonpagedpool address. > Also, the documentation for MmBuildMdlForNonPagedPool says that “Because > the pages described by the MDL are already nonpageable and are already > mapped to the system address space, drivers must not try to lock them by > using the MmProbeAndLockPages routine, or to create additional > system-address-space mappings by using the MmMapLockedPagesSpecifyCache > routine.” > So, does this mean that we SHOULD NOT call MmProbeAndLockPages for > nonpaged? > Then how do we build the MDL without worrying that the Irp->UserBuffer > might have a nonpaged address. >