I am a newbie in driver developement. I have a basic question.
In writing WDM device drivers, one can call IoBuildDeviceIoControlRequest / IoBuildSynchronousFsdRequest to allocate a synchronous IRP to be passed to another target driver. One of the basic requirement is that we have to allocate an event object before calling these functions. And, we must make sure this event object is still available by the time the target driver completes the IRP.
Can we really allocate that event object from the local scope of the function calling IoBuildDeviceIoControlRequest/ IoBuildSynchronousFsdRequest? i.e. from the kernel stack rather than from the nonpaged pool. Many of the sample codes simply allocate the event object from the local scope and hence kernel stack. But would there actually be a problem if our calling driver is paged out while the target driver is still handling our IRP?
So, if I've got this right, you allocate your event (off the stack), build the IRP, issue it, and then wait on the event, all in the one function?
Whether or not the stack gets paged out depends on the wait-mode argument you pass to KeWaitForSingleObject(). UserMode means you're happy for the stack to be paged. KernelMode means the stack is not allowed to be paged.
I think I recall that IRP completion routines run at DISPATCH_LEVEL, which is why you need to guarantee the event is paged in. Those routines will be setting the event, so you know the IRP has completed, but at DISPATCH_LEVEL, paging-in of paged-out pages can't happen (a consequence of the NT kernel design); you blue screen instead.