6.2.5 Allocating IRPs for Lower-Level Drivers
An NT intermediate-level driver cannot allocate IRPs for lower-level drivers by calling IoMakeAssociatedIrp. Only highest-level NT drivers can call IoMakeAssociatedIrp to allocate IRPs and set them up for a chain of lower drivers. The I/O Manager automatically completes the original IRP when all its associated IRPs have been completed, as long as the driver does not call IoSetCompletionRoutine with the original IRP or with any of the associated IRPs it allocates.
If an intermediate driver creates IRPs for lower drivers, it should call IoAllocateIrp, IoBuildDeviceIoControlRequest, IoBuildSynchronousFsdRequest, or IoBuildAsynchronousFsdRequest. However, IoBuildSynchronousFsdRequest can be called only in the following circumstances:
·By a driver-created thread to build IRPs for read or write requests, because such a thread can wait in a nonarbitrary thread context (its own) on a dispatcher object, such as a driver-initialized Event passed to IoBuildSynchronousFsdRequest
·In the system thread context during initialization or while unloading
·To build IRPs for inherently synchronous operations, such as create, flush, shutdown, close, and device control requests
However, a driver is more likely to call IoBuildDeviceIoControlRequest to allocate device control IRPs than IoBuildSynchronousFsdRequest.