Mapping IRP_MJ_WRITE associated MDL to user space?

Hi

I’m trying to do what the title describes. Have tried everything (including using the info here http://www.osronline.com/article.cfm?id=423) but only get crashes when trying to access the buffer from the user mode app I’m communicating to. I’m currently copying the buffer to a previously allocated (and mapped to user space) address, which works ok, but I’d like to map the MDL associated with the IRP (Irp->MdlAddress) to user space to skip copying the data. Can anyone help?

Wow, something weird in the rendering of that page. Can someone at OSR wave
the magicke wand? (I checked IE/Chrome/Opera/Firefox/Safari so I don’t
*think* its browser specific)

Not real input apart from that and that article is real hard to read, I am
assuming you mean this paragraph:

Alternatively, a particularly interesting way to use
MmMapLockedPagesSpecifyCache is to map
the buffer specified by an MDL into the context of a user process. Note
that because the MDL
describes a set of fixed physical pages, the MDL can be referred to in any
process context. To
map the data buffer described by the MDL into the user virtual address
space of the current
process, call MmMapLockedPagesSpecifyCache and specify UserMode as the
AccessMode parameter.

I’ve never done this, but the things I’d check are

  1. Is the address really in user mode?
  2. Are you sure you are in the correct process
  3. what does the protection on the PTEs for the VM look like?

/R

I’ve used that technique successfully in the past, so it sounds like there’s something specific about your implementation of it. Without more information it is difficult to say what you’re doing wrong.

(the referenced page looks fine in my browser Rod…)

Tony
OSR

Works for me as well. Although the fonts get hosed about half-way through… and then get fixed somehow.

Peter
OSR

That page looks ok on my browser (Chrome), though towards the end some fonts are enlarged.

About my question… Coming to think about it I’m not doing the mapping from the right context, that must be the issue. Another OSR article (http://www.osronline.com/article.cfm?article=39) says:

“Of course, this method does have the disadvantage that the call to MmMapLockedPagesSpecifyCache must be done in the context of the process into which you want the pages to be mapped.”

The IRP_MJ_WRITEs I’m interested in are paging I/O, so in the dispatch routine I’ll not be in the context of my user mode app. Is there any way around this?

You can use the KeStackAttachProcess () API noting the caveats and
cautions listed in the documentation for it.

Pete

On 10/4/2014 9:25 AM, xxxxx@gmail.com wrote:

That page looks ok on my browser (Chrome), though towards the end some fonts are enlarged.

About my question… Coming to think about it I’m not doing the mapping from the right context, that must be the issue. Another OSR article (http://www.osronline.com/article.cfm?article=39) says:

“Of course, this method does have the disadvantage that the call to MmMapLockedPagesSpecifyCache must be done in the context of the process into which you want the pages to be mapped.”

The IRP_MJ_WRITEs I’m interested in are paging I/O, so in the dispatch routine I’ll not be in the context of my user mode app. Is there any way around this?


NTFSD is sponsored by OSR

OSR is hiring!! Info at http://www.osr.com/careers

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

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


Kernel Drivers
Windows File System and Device Driver Consulting
www.KernelDrivers.com
866.263.9295

They are probably in the system process context, so when you map the buffer, you are mapping it into the user portion of the system process context. Thus, when your application tries to access it (in its own process context) it isn’t in the address space - essentially, this call is adding entries into a process context specific table (the virtual to physical page mapping table).

As Pete notes, you can use KeStackAttachProcess. Another approach is to insert it into a queue so when you have a thread in that process context it can do the mapping - this avoids the overhead of a forced context switch, which is an expensive operation. But that very much depends upon the way in which you’ve built your driver.

For example, suppose the service calls down to your driver. You don’t have anything for it to do, so you make it wait on an event. When you get that paging write operation you can take the operation and place it in a queue that you’ve created within your driver - call IoMarkIrpPending, stick it on the queue, set that event the service thread is waiting for and then retun STATUS_PENDING from the dispatch call.

If you look, both IRPs and filter manager callback data structures have fields that make it straight-forward to do this. Filter manager also has additional primitives to handle queuing logistics - though I tend to avoid using FM queues because they leverage off the standard system queues, which run at elevated priority and are used by the underlying file systems, which can create complex interdependencies that lead to deadlock.

From the IRP:

//
// List entry - used to queue the packet to completion queue, among
// others.
//

LIST_ENTRY ListEntry;

And from the CBD:

union {
struct {

//
// Queue links if the FltMgr queue is used to
// pend the callback
//

LIST_ENTRY QueueLinks;

//
// Additional context
//

PVOID QueueContext[2];
};

//
// The following are available to filters to use
// in whatever manner desired if not using the filter manager
// queues.
// NOTE: These fields are only valid while the filter is
// processing this operation which is inside the operation
// callback or while the operation is pended.
//

PVOID FilterContext[4];
};

Tony
OSR

I think I understand… but as long as I’m mainly concerned with ressources utilization (not copying the data buffer if it’s accessible from user mode), KeStackAttachProcess may not be the best idea.

Pending the IRPs seems to be the way to go but in the end I’m wondering if there’s much benefit gained for the added complexity.

>allocated (and mapped to user space) address, which works ok, but I’d like to map the MDL

associated with the IRP (Irp->MdlAddress) to user space to skip copying the data.

Given the fact FltMgr has very great communication ports, I do not think memory remapping is a good idea.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com