Linux Device Driver Report I/O Request Flow in WDF Kernel-Mode Drivers
Dec 19, 2015
Outline
• Flow of an I/O Request Throught the System– Application I/O Requests– I/O Request Path from Application to Driver– KMDF Driver Processing of I/O Requests
• Flow of an I/O Request Within a KMDF Driver– Framework Receives a Request and Inserts It on a
WDFQUEUE– Framework Invokes the Driver’s I/O Event Proces
sing Callback– Driver’s I/O Event Processing Callback Executes
Application I/O Requests
• Application I/O Requests 的種類– Create Requests
• CreateFile– Close Requests
• Close– Read and Write Requests
• ReadFile WriteFile– Device Control Requests
• DeviceControl
Application I/O Requests
• 同步、非同步– Synchronous– Control 會等到 request 完成後,才會回到
application 。– Asynchronous– Control 會立刻回到 application 。– Application 必須自己檢查 Request 是否完
成。
I/O Request Path from Application to Driver
USBHUB
System Service Dispatcher
I/O Manager
Kernel Mode
User Mode
1
Applicationstatus = ReadFile(handle,...)
USBPORT
PCI
UsbDev.sys(KMDF driver)
KMDF Library(Wdfdynam.sys)
3
5 4
2
1
6
I/O Request Path
I/O Request Path from Application to Driver
• 1.When an application issues an I/O request, Windows issues a system service call to the system service dispatcher.
• 2.The system service dispatcher calls the corresponding I/O processing function of the Windows I/O Manager.
• 3.The I/O Manager builds an I/O request packet (IRP) that describes the I/O request issued by the application and sends it to the framework (the KMDF library, Wdfdynam.sys). The framework sorts incoming requests by major function code and, in the case of a read, write, or device control request, sends it to the framework's I/O package for processing.
• The I/O package validates the request parameters and processes the request according to its type and the driver's configuration of its WDFQUEUE(s).
• 4.If the KMDF driver is a filter driver and has configured its WDFQUEUE(s) to forward requests of this type to the next-lower driver on the underlying driver stack, the framework forwards the request to the next-lower driver. Otherwise, it forwards the request to the KMDF driver.
• 5.If the KMDF driver receives the request, it processes the request and, if necessary, forwards it to the next-lower driver on the underlying stack.
• 6.That driver processes the request and, in turn, forwards the request to the next-lower driver and so on down the driver stack, as needed to satisfy the request.
I/O Request Path from Application to Driver
• I/O Request Path from Application to the Framework
• Windows Issues a System Service Call for an Application I/O Request
• The System Service Dispatcher Calls the I/O Manager
• The I/O Manager Builds an IRP and Sends It to the Framework– Validating request parameters – Building the IRP – Sending the IRP to the framework.
I/O Request Path from Application to Driver
• I/O Request Path from Framework to Driver
Driver Callbacks
IRP_MJ_PNPIRP_MJ_POWER
IRP_MJ_SYSTEM_CONTROL (KMDF only)
I/O Requests(IRP_MJ_READIRP_MJ_WRITEIRP_MJ_DEVICE_CONTROL)
IRP_MJ_Xxx
Driver Callbacks
Driver Callbacks
Dispatcher
I/O Package
Plug and Play/Power
Package
WMI Package
I/O Target
Non-power-managed I/O
Queues
...
Power-managed I/O Queues
KMDF Driver Processing of I/O Requests
• Processing a Request Internally• Processing a Request by Sending It
to Another Driver• Requests Marked Pending During
Processing
KMDF Driver Processing of I/O Requests
• I/O Completion Path from Driver to Application.
USBHUB
System Service Dispatcher
I/O Manager
Kernel Mode
User Mode
Applicationstatus = ReadFile(handle,...)
USBPORT
PCI
UsbDev.sys(KMDF driver)
KMDF Library(Wdfdynam.sys)
3
5 4
2
1
6
E
D
C
B
A
I/O Completion Path
I/O Request Path
I/O statusCompletion informationBuffered data
KMDF Driver Processing of I/O Requests
• Driver Completion of a Request– I/O status. – Completion information. – Requested data.
• I/O Completion Path from Framework to I/O Manager
• I/O Manager Completion of a Request – Stage 1: Completion Processing in Arbitrary C
ontext – Stage 2: Completion Processing in the Requ
estor’s Context
Framework Receives a Request and Inserts It on a WDFQUEUE
• WDFQUEUE Insertion Logic– If the device has previously been defined as a
filter device object (by calling WdfFdoInitSetFilter)
– The framework determines the correct WDFQUEUE into which to place the arriving WDFREQUEST
– The framework then checks the dispatch type for the chosen WDFQUEUE
• Driver Queue Implementation
Framework Receives a Request and Inserts It on a WDFQUEUE
• Consider the following queue structure provided by the WDFDIO driver:
• WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioCallbacks,
• WdfIoQueueDispatchSequential);• ioCallbacks.EvtIoDeviceControl = DioEvtDeviceControl;• status = WdfIoQueueCreate(device,• &ioCallbacks,• WDF_NO_OBJECT_ATTRIBUTES,• NULL); // optional pointer for queue handle
Framework Invokes the Driver's I/O Event Processing Callback
• Dispatch Type of the Queue• Dispatch Types
– WdfIoQueueDispatchParallel – WdfIoQueueDispatchSequential – WdfIoQueueDispatchSequential
• Impact of Dispatch Type on Driver Design
• Synchronization Scope for WDFDEVICEs and WDFQUEUEs
• Specifying Synchronization Scope
Framework Invokes the Driver's I/O Event Processing Callback
• How Synchronization Scope Works • Queue State• Is the Callback Called?
Driver's I/O Event Processing Callback Executes
• Validating the Arriving Request • Processing the Arriving Request• Satisfying the Request within the I/
O Event Processing Callback• Initiating a Request on the Device• Sending a Request to Another Driv
er for Processing
Driver's I/O Completion Routine Executes
• I/O Completion Routine Example– VOID– EvtRequestReadCompletionRoutine(– IN WDFREQUEST Request,– IN WDFIOTARGET Target,– PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,– IN WDFCONTEXT Context– )– { – NTSTATUS status;– size_t bytesRead = 0;– PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;– UNREFERENCED_PARAMETER(Target);– UNREFERENCED_PARAMETER(Context);– status = CompletionParams->IoStatus.Status;– – usbCompletionParams = – CompletionParams->Parameters.Usb.Completion;– – bytesRead = usbCompletionParams->Parameters.PipeRead.Length;– – WdfRequestCompleteWithInformation(Request, status, bytesRead);– return;– }