Shared memory

Hello!

I need to have shared memory with user-mode process (which calls DeviceIoControl()). But I should allocate and fill it in NDIS Filter callbacks, not in DeviceIoControl().
It isn’t known in advance how much memory will be needed. I understand how to use MDLs to allocate memory for user-mode process in DeviceControl(). But if I’m in NDIS Filter callback, I will not have the user-mode context.
How can I allocate shared memory in this case?

Thank you!

I need to have shared memory with user-mode process (which calls DeviceIoControl()). But I should allocate and fill it
in NDIS Filter callbacks, not in DeviceIoControl().

In general, mapping driver - allocated memory in the userland is considered a bad programming practice under Windows NT, for the security reasons. Although you may do this kind of thing under some other OS with support for mmap() just fine, in the Windows NT world it would be better to do it the other way around, and to map a userland-allocated memory buffer to the kernel address space.

But if I’m in NDIS Filter callback, I will not have the user-mode context. How can I allocate shared memory in this case?

However, if you are just desperate to do it anyway, you can split allocating-mapping sequence in 2 parts. In your particular case you can allocate and fill your target buffer in context of of a NDIS callback(i.e. in context of an arbitrary address space), and subsequently map it it to the userland in context of your target address space.

For example, you can allocate your target range in context of a callback, add a pointer to some global queue, and complete an asynchronous IOCTL that your target app had earlier submitted (check the archives for"inverted call" for more info). In response to this , you app will submit another IOCTL to a driver, this time a synchronous one. Once this IOCTL is going to get received by the driver in context of the the target app,
you can build an a MDL for the target range and map it to the target address space by calling MmMapLockedPagesSpecifyCache() in IOCTL handler. Simple, ugh.

Another option is to create a system thread that runs in context of the target app by specifying a valid non-NULL ‘ProcessHandle’ to PsCreateSystemThread(). In such case your callback, instead of completing an asynch request, will simply signal an event that above mentioned system thread is waiting on. Once the above mentioned system thread runs in context of your target address space it can already map the buffer the way I had already explained. In such case it will, apparently, have to notify an app about it anyway, but this is already a different story.

If you are just desperate to map driver-allocated memory to the userland the option A , i.e. the inverted call, seems to be a better one.
However, I would advise you to think one more time about the possibility of changing this requirement …

Anton Bassov