IoBuildDeviceIoControlRequest vs Usermode buffer

I’d like to build a secondary thread-associated IRP within my DEVICE_IO_CONTROL dispatch routine (called in the user process thread context), to keep the user buffer locked around. If the process ever dies, the IRP will be cancelled and the buffer will be properly unlocked.

I’d like to be sure that IoBuildDeviceIoControlRequest uses the thread previous mode when calling ProbeAndLockPages for the IOCTL buffer.

So is it kosher to use the function to create a IOCTL IRP with METHOD_*_DIRECT and usermode buffer?

The buffer is probed with an access mode of Kernel. The documentation does
state that the input/output buffers need to be in system memory:

http://msdn.microsoft.com/en-us/library/windows/hardware/ff548318(v=vs.85).aspx

This makes sense, otherwise you wouldn’t be able to call this API with
kernel mode buffers in an arbitrary thread context (requestor mode would
possibly be user and the call would fail).

-scott
OSR

wrote in message news:xxxxx@ntdev…

I’d like to build a secondary thread-associated IRP within my
DEVICE_IO_CONTROL dispatch routine (called in the user process thread
context), to keep the user buffer locked around. If the process ever dies,
the IRP will be cancelled and the buffer will be properly unlocked.

I’d like to be sure that IoBuildDeviceIoControlRequest uses the thread
previous mode when calling ProbeAndLockPages for the IOCTL buffer.

So is it kosher to use the function to create a IOCTL IRP with
METHOD_*_DIRECT and usermode buffer?

How about IoBuildSynchronousFsdRequest?

IoBuildSynchronousFsdRequest also uses Kernel mode. Though note that
IoBuildSynchronousFsdRequest only takes on buffer as input, so it bases
whether or not to build an MDL based on the target device object flags and
the method in a control code.

Any reason to not just build the MDL yourself and put it in the IRP after?

-scott
OSR

wrote in message news:xxxxx@ntdev…

How about IoBuildSynchronousFsdRequest?

>Any reason to not just build the MDL yourself and put it in the IRP after?

I need a legit threaded IRP that would be canceled and user memory unlocked when the user thread dies. I can’t keep a user’s DeviceIoControl pending for that, because of some race conditions. At least, having an user-issued IRP was ackward.

The user’s app allocates a buffer for a shared queue, and issues a METHOD_BUFFERED IOCTL to create a custom queue object in the driver. The input buffer contains the queue buffer and other parameters. The output buffer for the IOCTL will contain the object ID (custom handle) that lets the driver identify the object in the future. I cannot pend the IOCTL because I need to return object ID and creation status. The buffer is necessary up front.

To keep the buffer locked and allow for proper unlock, I was planning to build a pending threaded IRP in the driver.

The documentation for IoBuildDeviceIoControlRequest mentions that the caller can replace its RequestorMode to UserMode afterwards. I’m not sure what other considerations and limitations for this case, though.

> The user’s app allocates a buffer for a shared queue, and issues a METHOD_BUFFERED IOCTL

Can you use inverted calls (with queue in the driver) instead of such a design?


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

If there’s an MDL in Irp->MdlAddress, the I/O Manager unlocks it as part of
stage one I/O completion (i.e. IoCompleteRequest calls MmUnlockPages) and
frees it as part of stage two (i.e. IopCompleteRequest calls IoFreeMdl).
It’s a way to get the I/O manager to free up your MDL for you, the requestor
mode doesn’t come into play at all.

Note that you still have race conditions with this approach, you’ll need to
set a Cancel routine in the IRP and make your driver stop using the buffer
before you complete it.

-scott
OSR

wrote in message news:xxxxx@ntdev…

Any reason to not just build the MDL yourself and put it in the IRP after?

I need a legit threaded IRP that would be canceled and user memory unlocked
when the user thread dies. I can’t keep a user’s DeviceIoControl pending for
that, because of some race conditions. At least, having an user-issued IRP
was ackward.

The user’s app allocates a buffer for a shared queue, and issues a
METHOD_BUFFERED IOCTL to create a custom queue object in the driver. The
input buffer contains the queue buffer and other parameters. The output
buffer for the IOCTL will contain the object ID (custom handle) that lets
the driver identify the object in the future. I cannot pend the IOCTL
because I need to return object ID and creation status. The buffer is
necessary up front.

To keep the buffer locked and allow for proper unlock, I was planning to
build a pending threaded IRP in the driver.

The documentation for IoBuildDeviceIoControlRequest mentions that the caller
can replace its RequestorMode to UserMode afterwards. I’m not sure what
other considerations and limitations for this case, though.

>Can you use inverted calls (with queue in the driver) instead of such a design?

The shared queue is part of so-called kernel bypass interface.