MmUnmapLockedPages.

Hi,

I need to use MmUnmapLockedPages on memory mapped to user mode in an EvtIoCanceledOnQueue routine. The memory is mapped when I receive an ioctl from an user mode program. My problem is, how do I ensure that this gets called in the same context that it was mapped in?

Thanks,

Kevin.

Strictly speaking, you can’t.

It sounds like you have a design problem, if you ask me. The usual pattern for this sort of thing (if you DO indeed need to map anything at all) is “map in Create, unmap in Cleanup.” Does this pattern not work for you?

There are, of course, “tricks” that you can play to GET something running in the context of the requestor… but they’re all pretty high overhead. How do you ensure you’re in the requesting process context when you get the IOCTL in the first place?

Peter
OSR

Store a pointer to the EPROCESS of the calling process when you map the
pages and attach to that process when before unmapping the process-relative
virtual address. Whether it is permitted to do that in EvtIoCanceledOnQueue
I don’t know. If it is prohibited the rule has nothing to do with the
underlying technology.

When you map the MDL to user space the process should be stored in
MDL->Process. Maybe you can use that to attach.

I looked at MiUnmapLockedPagesInUserSpace and it doesn’t appear to use
MDL->Process even though that might have been the logical thing.

Regards,

Rossetoecioccolato.

wrote in message news:xxxxx@ntdev…
> Hi,
>
> I need to use MmUnmapLockedPages on memory mapped to user mode in an
> EvtIoCanceledOnQueue routine. The memory is mapped when I receive an ioctl
> from an user mode program. My problem is, how do I ensure that this gets
> called in the same context that it was mapped in?
>
> Thanks,
>
> Kevin.
>

Relevant thread from last year:

http://www.osronline.com/showThread.CFM?link=182871

MDL->Process is a private field, please don’t use it for anything. It wouldn’t help here anyway, since it typically describes the process which owns the pages locked using MmProbeAndLockPages, so it will be NULL for MDLs built from nonpaged pool or MmAllocatePagesForMdl etc.

Thanks,
Pavel

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of George M. Garner Jr.
Sent: Wednesday, February 02, 2011 12:20 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] MmUnmapLockedPages.

Store a pointer to the EPROCESS of the calling process when you map the pages and attach to that process when before unmapping the process-relative virtual address. Whether it is permitted to do that in EvtIoCanceledOnQueue I don’t know. If it is prohibited the rule has nothing to do with the underlying technology.

When you map the MDL to user space the process should be stored in
MDL->Process. Maybe you can use that to attach.

I looked at MiUnmapLockedPagesInUserSpace and it doesn’t appear to use
MDL->Process even though that might have been the logical thing.

Regards,

Rossetoecioccolato.

wrote in message news:xxxxx@ntdev…
> Hi,
>
> I need to use MmUnmapLockedPages on memory mapped to user mode in an
> EvtIoCanceledOnQueue routine. The memory is mapped when I receive an
> ioctl from an user mode program. My problem is, how do I ensure that
> this gets called in the same context that it was mapped in?

You’re using wrong approach to kernel-user shared memory.

The best method is to have an IOCTL of METHOD_OUT_DIRECT. The buffer will be locked and mapped to kernel mode space by the IO manager for you. Your driver should pend the IRP and set the cancel routine for it. This buffer will be locked and accessible by both user mode app the the driver. When you want to unmap it, complete the IRP. That’s it.

> I think you can handle these cases by checking PsGetCurrentProcess()

when you receive IRP_MJ_CLEANUP and if it doesn’t match what you
expect, using KeStackAttachProcess to attach to the right process
before unmapping the pages. <

I think that the general concept of keeping an open handle to the driver and
then unmapping the process pages in IRP_MJ_CLEANUP is a good one for the
case where the process returned by PsGetCurrentProcess() and the process
with the mapped pages are the same. You lost me with the part about calling
KeStackAttachProcess() for a foreign process from IRP_MJ_CLEANUP. In my
experience calling KeStackAttachProcess() on a process that is exiting can
hang the calling thread indefinitely. At a minimum the OP would need to
acquire rundown protection on the third party process before calling
KeStackAttachProcess(). A better approach would be for each process to
maintain an open handle to the driver and then manage its own locked pages
in IRP_MJ_CLEANUP.

We still don’t know why the OP needs to map the kernel pages into a user
process. Often there is a better solution without so many problems.

Regards,

Rossetoecioccolato.

IRP_MJ_CLEANUP approach will fail miserably if for some reason the handle gets duplicated to another (child) process. The original process may be terminated, but the FILE_OBJECT will still have a handle. Prepare for a BSOD.

Use a DIRECT IOCTL approach instead.