6.3.3 DispatchRead and/or DispatchWrite Functionality
Every driver of a device from which data can be transferred to the system must have a DispatchRead routine and must set its entry point in the driver object during initialization. Every driver of a device to which data can be transferred from the system must have a DispatchWrite routine and must set its entry point in the driver object during initialization. Any device driver that transfers data in both directions can have a combined DispatchReadWrite routine, as can any higher-level driver layered above it.
Any higher-level driver layered above such a device driver must set its Dispatch entry point(s) in its driver object for IRP_MJ_READ and/or IRP_MJ_WRITE requests that are handled by the underlying device driver.
As already mentioned in Section 6.2.6, lower-level NT drivers handle IRP_MJ_READ and IRP_MJ_WRITE requests asynchonously. Therefore, DispatchRead and/or DispatchWrite routines must pass these requests on for further processing, provided that any such request has valid parameters in that driver's I/O stack location of the IRP.
Whether an NT driver sets up its device objects for buffered or direct I/O affects how it handles transfer requests, as already described in Chapter 3. In particular, a device driver that uses direct I/O to do DMA operations might need to split up large transfer requests into a sequence of smaller transfer operations in order to satisfy an IRP_MJ_READ or IRP_MJ_WRITE request.
The following subsections discuss some of the design and implementation considerations for DispatchReadWrite routines in device drivers that use buffered I/O and direct I/O, as well as in higher-level drivers layered above them. Section 6.3.3.4 summarizes points to consider in implementing a DispatchRead, DispatchWrite, or combined DispatchReadWrite routine.