METHOD_NEITHER IOCTL and mapping

Hello. Apologies if this is in the archives, but I could not find a
definite answer.

I am writing an upper filter, which will perform operations on
METHOD_NEITHER IOCTLs as they come up the stack. So far, my pass through
filter works OK. But I do have some questions on dealing with
METHOD_NEITHER IOCTLs, in particular buffer locking/mapping. And since I’m
not the function driver, I must deal with these IOCTLs as they are.

I’m reading the paper “User-Mode Interactions: Guidelines for Kernel-Mode
Drivers”, but I still have some questions. I do understand that I must lock
the user buffer pages and map it on the way down, so that I can access it in
my completion routine, which could be arbitrary context and at
DISPATCH_LEVEL. I do create an MDL, call MmProbeAndLockPages, and then
MmGetSystemAddressForMdlSafe. I am using try/except where necessary. I can
access this locked and mapped buffer fine in my completion routine.

It’s cleanup which irks me a bit. Currently, I call MmUnmapLockedPages,
MmUnlockPages, and then IoFreeMdl. This is fine with driver verifier, and
the checked kernel/HAL. But I’m still wondering if this cleanup is OK. And
the previously cited white paper is, I admit, confusing me on a point (under
the section “Validation for Neither I/O Transfers”):

“Map the user-mode buffer into the kernel address space and lock the pages
into memory by calling MmProbeAndLockPages within a structured exception
handler.”
Now, as I understand it, MmProbeAndLockPages just locks down the pages, and
does not do any mapping. What am I missing?

Also:
“Unlock and unmap the buffer by calling MmUnlockPages after all kernel-mode
components have finished using it.”
I also though that MmUnlockPages does not do any unmapping. In fact, the
5112 DDK says that “The MmUnlockPages routine unlocks physical pages
described by a given MDL.”. Nothing about unmapping here. Don’t I need to
call MmUnmapLockedPages first, before calling MmUnlockPages?

RELATED question: how does the IO Manager clean up the MDL for
METHOD_Xxx_DIRECT? Just a call to MmUnlockPages?

Thanks for clearing up any confusion,

Philip Lukidis

Hi,

Now, as I understand it, MmProbeAndLockPages just locks down the pages,
and
does not do any mapping. What am I missing?

Looks to me like the docs are wrong, AFAIK no mapping goes on oin the
MmProbeAndLockPages call.

“Unlock and unmap the buffer by calling MmUnlockPages after all
kernel-mode
components have finished using it.”
I also though that MmUnlockPages does not do any unmapping.

Unassembling the first few lines of MmUnlockPages on my XP system shows that
it does indeed call MmUnmapLockedPages on the MDL if the
MDL_MAPPED_TO_SYSTEM_VA bit is set. So, as an implementation detail, if the
MDL was mapped into the kernel VA then MmUnlockPages will also automagically
do the unmapping for you.

Don’t I need to call MmUnmapLockedPages first, before calling
MmUnlockPages?

In your case you should be safe by just calling MmUnlockPages, though making
the call to MmUnmapLockedPages first shouldn’t hurt (it will clear the
MDL_MAPPED_TO_SYSTEM_VA from the MDL, so it won’t be called again when you
make the MmUnlockPages call).

RELATED question: how does the IO Manager clean up the MDL for
METHOD_Xxx_DIRECT? Just a call to MmUnlockPages?

If there is an MDL in Irp->MdlAddress when the IRP is fully completed, the
I/O manager calls MmUnlockPages and IoFreeMdl.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Philip Lukidis” wrote in message
news:xxxxx@ntdev…
> Hello. Apologies if this is in the archives, but I could not find a
> definite answer.
>
> I am writing an upper filter, which will perform operations on
> METHOD_NEITHER IOCTLs as they come up the stack. So far, my pass through
> filter works OK. But I do have some questions on dealing with
> METHOD_NEITHER IOCTLs, in particular buffer locking/mapping. And since
> I’m
> not the function driver, I must deal with these IOCTLs as they are.
>
> I’m reading the paper “User-Mode Interactions: Guidelines for Kernel-Mode
> Drivers”, but I still have some questions. I do understand that I must
> lock
> the user buffer pages and map it on the way down, so that I can access it
> in
> my completion routine, which could be arbitrary context and at
> DISPATCH_LEVEL. I do create an MDL, call MmProbeAndLockPages, and then
> MmGetSystemAddressForMdlSafe. I am using try/except where necessary. I
> can
> access this locked and mapped buffer fine in my completion routine.
>
> It’s cleanup which irks me a bit. Currently, I call MmUnmapLockedPages,
> MmUnlockPages, and then IoFreeMdl. This is fine with driver verifier, and
> the checked kernel/HAL. But I’m still wondering if this cleanup is OK.
> And
> the previously cited white paper is, I admit, confusing me on a point
> (under
> the section “Validation for Neither I/O Transfers”):
>
> “Map the user-mode buffer into the kernel address space and lock the pages
> into memory by calling MmProbeAndLockPages within a structured exception
> handler.”
> Now, as I understand it, MmProbeAndLockPages just locks down the pages,
> and
> does not do any mapping. What am I missing?
>
> Also:
> “Unlock and unmap the buffer by calling MmUnlockPages after all
> kernel-mode
> components have finished using it.”
> I also though that MmUnlockPages does not do any unmapping. In fact, the
> 5112 DDK says that “The MmUnlockPages routine unlocks physical pages
> described by a given MDL.”. Nothing about unmapping here. Don’t I need
> to
> call MmUnmapLockedPages first, before calling MmUnlockPages?
>
> RELATED question: how does the IO Manager clean up the MDL for
> METHOD_Xxx_DIRECT? Just a call to MmUnlockPages?
>
> Thanks for clearing up any confusion,
>
> Philip Lukidis
>
>

Thanks for your quick answer. I guess I probably could have disassembled
MmUnlockPages myself, but thanks for the help there. It’s pretty clear now,
but the DDK docs and that white paper were misleading.

thanks for your help,

Philip Lukidis

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Scott Noone
Sent: Friday, March 03, 2006 10:23 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] METHOD_NEITHER IOCTL and mapping

Hi,

> Now, as I understand it, MmProbeAndLockPages just locks
down the pages,
> and
> does not do any mapping. What am I missing?

Looks to me like the docs are wrong, AFAIK no mapping goes on oin the
MmProbeAndLockPages call.

>
> “Unlock and unmap the buffer by calling MmUnlockPages after all
> kernel-mode
> components have finished using it.”
> I also though that MmUnlockPages does not do any unmapping.
>

Unassembling the first few lines of MmUnlockPages on my XP
system shows that
it does indeed call MmUnmapLockedPages on the MDL if the
MDL_MAPPED_TO_SYSTEM_VA bit is set. So, as an implementation
detail, if the
MDL was mapped into the kernel VA then MmUnlockPages will
also automagically
do the unmapping for you.

> Don’t I need to call MmUnmapLockedPages first, before calling
> MmUnlockPages?

In your case you should be safe by just calling
MmUnlockPages, though making
the call to MmUnmapLockedPages first shouldn’t hurt (it will
clear the
MDL_MAPPED_TO_SYSTEM_VA from the MDL, so it won’t be called
again when you
make the MmUnlockPages call).

> RELATED question: how does the IO Manager clean up the MDL for
> METHOD_Xxx_DIRECT? Just a call to MmUnlockPages?

If there is an MDL in Irp->MdlAddress when the IRP is fully
completed, the
I/O manager calls MmUnlockPages and IoFreeMdl.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Philip Lukidis” wrote in message
> news:xxxxx@ntdev…
> > Hello. Apologies if this is in the archives, but I could not find a
> > definite answer.
> >
> > I am writing an upper filter, which will perform operations on
> > METHOD_NEITHER IOCTLs as they come up the stack. So far,
> my pass through
> > filter works OK. But I do have some questions on dealing with
> > METHOD_NEITHER IOCTLs, in particular buffer
> locking/mapping. And since
> > I’m
> > not the function driver, I must deal with these IOCTLs as they are.
> >
> > I’m reading the paper “User-Mode Interactions: Guidelines
> for Kernel-Mode
> > Drivers”, but I still have some questions. I do understand
> that I must
> > lock
> > the user buffer pages and map it on the way down, so that I
> can access it
> > in
> > my completion routine, which could be arbitrary context and at
> > DISPATCH_LEVEL. I do create an MDL, call
> MmProbeAndLockPages, and then
> > MmGetSystemAddressForMdlSafe. I am using try/except where
> necessary. I
> > can
> > access this locked and mapped buffer fine in my completion routine.
> >
> > It’s cleanup which irks me a bit. Currently, I call
> MmUnmapLockedPages,
> > MmUnlockPages, and then IoFreeMdl. This is fine with
> driver verifier, and
> > the checked kernel/HAL. But I’m still wondering if this
> cleanup is OK.
> > And
> > the previously cited white paper is, I admit, confusing me
> on a point
> > (under
> > the section “Validation for Neither I/O Transfers”):
> >
> > “Map the user-mode buffer into the kernel address space and
> lock the pages
> > into memory by calling MmProbeAndLockPages within a
> structured exception
> > handler.”
> > Now, as I understand it, MmProbeAndLockPages just locks
> down the pages,
> > and
> > does not do any mapping. What am I missing?
> >
> > Also:
> > “Unlock and unmap the buffer by calling MmUnlockPages after all
> > kernel-mode
> > components have finished using it.”
> > I also though that MmUnlockPages does not do any unmapping.
> In fact, the
> > 5112 DDK says that “The MmUnlockPages routine unlocks physical pages
> > described by a given MDL.”. Nothing about unmapping here.
> Don’t I need
> > to
> > call MmUnmapLockedPages first, before calling MmUnlockPages?
> >
> > RELATED question: how does the IO Manager clean up the MDL for
> > METHOD_Xxx_DIRECT? Just a call to MmUnlockPages?
> >
> > Thanks for clearing up any confusion,
> >
> > Philip Lukidis
> >
> >
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Philip Lukidis wrote:

“Map the user-mode buffer into the kernel address space and lock the pages
into memory by calling MmProbeAndLockPages within a structured exception
handler.”
Now, as I understand it, MmProbeAndLockPages just locks down the pages, and
does not do any mapping. What am I missing?

That whitepaper has some bad wording. They mean map the buffer yourself,
and then lock it with MmProbAndLockPages. You’re right, it doesn’t do
any mapping… the implementation details are as follows:

  1. If the specified memory range is paged to disk,
    MmProbeAndLockPages makes it resident.
  2. The routine then confirms that the pages permit the operation
    specified by the Operation parameter.
  3. If the memory range permits the specified operation, the routine
    locks the pages in memory so that they cannot be paged out. Use
    MmUnlockPages to unlock the pages.

This is from the latest WDK docs.

Also:
“Unlock and unmap the buffer by calling MmUnlockPages after all kernel-mode
components have finished using it.”
I also though that MmUnlockPages does not do any unmapping. In fact, the
5112 DDK says that “The MmUnlockPages routine unlocks physical pages
described by a given MDL.”. Nothing about unmapping here. Don’t I need to
call MmUnmapLockedPages first, before calling MmUnlockPages?

RELATED question: how does the IO Manager clean up the MDL for
METHOD_Xxx_DIRECT? Just a call to MmUnlockPages?

Scott answered this so I won’t repeat the same information…

Thanks for clearing up any confusion,

Philip Lukidis

Best regards,
Alex Ionescu