Most drivers create I/O queues in their EvtDriverDeviceAdd callback function. To create an I/O queue for a device, the driver calls the framework queue object's WdfIoQueueCreate method (which creates a framework queue object). The driver supplies a WDF_IO_QUEUE_CONFIG structure to the method. This structure contains configuration information about the queue, such as the queue's dispatching method and pointers to request handlers that the framework calls when requests are available in the queue. The structure also indicates whether the queue will be power-managed and whether the driver supports zero-length buffers for the queue's I/O requests.
If the driver sets the DefaultQueue member of the WDF_IO_QUEUE_CONFIG structure to TRUE, the queue becomes the device's default I/O queue. If your driver creates a default I/O queue, the framework places all of the device's I/O requests in this queue, unless you create additional queues to receive some of the requests. A driver can obtain a handle to a device's default I/O queue by calling the WdfDeviceGetDefaultQueue method.
If you want to use more than one I/O queue for a device, the driver can call WdfIoQueueCreate to create as many queue objects as you need. If a driver creates multiple queues, it can call WdfDeviceConfigureRequestDispatching, which instructs the framework to direct different types of requests to different queues. For example, you can specify that all read requests will be delivered to one queue and all write requests will be delivered to another queue.
If your driver creates a set of I/O queues and calls WdfDeviceConfigureRequestDispatching to direct each type of request that your driver can receive to a specific queue, the driver does not need a default queue.
If a driver does not provide an I/O queue for requests of a particular type, and if your driver is a function driver, the framework completes requests of that type with a completion status value of STATUS_INVALID_DEVICE_REQUEST. If your driver is a filter driver and has called WdfFdoInitSetFilter, the framework automatically forwards these requests to the next-lower driver in the driver stack. Thus, for example, a filter driver that does not process read requests does not have to provide an I/O queue that receives read requests.
For examples of how drivers can use I/O queues, see Example Uses of I/O Queues.