If your driver has specified either the sequential or the parallel dispatching method for an I/O queue, the framework calls a driver-supplied callback function each time it is ready to deliver one of the queue's requests to the driver.
For each I/O queue, the driver can provide one or more of the following callback functions, which are called request handlers:
The framework calls an I/O queue's EvtIoRead callback function when a read request is available in the queue.
The framework calls an I/O queue's EvtIoWrite callback function when a write request is available in the queue.
The framework calls an I/O queue's EvtIoDeviceControl callback function when a device I/O control request is available in the queue.
The framework calls an I/O queue's EvtIoInternalDeviceControl callback function when an internal device I/O control request is available in the queue.
The framework calls an I/O queue's EvtIoDefault callback function when any request is available, if the driver has not supplied the associated request-type-specific callback function.
The driver registers callback functions when it calls WdfIoQueueCreate to create an I/O queue for a device.
Each of these callback functions receives two input arguments: a handle to the I/O request that the framework is delivering to the driver and a handle to the I/O queue that held the request. A callback function can determine the target device by calling WdfIoQueueGetDevice.
The framework calls your driver's request handlers in an arbitrary thread context. A driver should not wait for an extended period of time while executing in an arbitrary thread context. In some cases, your driver might use kernel dispatcher objects as synchronization mechanisms. For information about when your driver can wait for dispatcher objects, and what to do when it can't, see Introduction to Kernel Dispatcher Objects.