KMDF KMDF operates as an abstraction layer over WDM. Because both the framework and associated drivers run in kernel mode, the infrastructure is much simpler than that of UMDF. Figure 4-3 shows the components that make up the KMDF infrastructure. As an example, the figure shows a simple device stack, consisting of a KMDF function driver, a WDM lower filter driver, and a WDM bus driver.
Figure 4-3: KMDF driver and infrastructure
The KMDF infrastructure is made up of several components: the framework, the KMDF drivers, and other drivers.
KMDF has a single runtime component-the framework-as compared to the multiple runtime components that make up the UMDF infrastructure. One instance of the framework supports all of the KMDF drivers on the system. If the system has multiple major versions of the framework installed, there is one instance of each major version to support the drivers that were compiled for that version.
Each KMDF driver calls the framework to create a framework device object for each device that the driver supports. The framework, in turn, creates a corresponding WDM device object and installs it in the device stack for the device. If the KMDF driver is a function driver, the framework creates an FDO and installs it above any lower filter drivers, and so on. Because the upper and lower edge of a KMDF driver operate as a WDM driver, it is therefore possible for a device stack to include a mixture of KMDF and WDM drivers.
When a device object that belongs to the framework receives an IRP from the I/O manager, the framework interacts with the associated KMDF driver to process the request. If the KMDF driver does not complete the request, the framework passes the IRP back to the I/O manager to pass to the next lower driver in the stack, and so on. In addition to managing IRP flow, the framework also supports the KMDF DDI and object model, which drivers use to interact with the framework, other drivers, and the device. The framework also tracks system and device state and provides default processing for Plug and Play and power management requests.
The KMDF model is somewhat similar to the port-miniport model, with the framework acting as the port driver and the KMDF driver acting as a miniport driver. The framework's device object is installed in the device stack, and the framework handles many of the functions of a driver. However, the framework depends on the associated KMDF driver for device-specific processing. There is one major difference between the port-miniport model and KMDF though; KMDF does not restrict the DDI routines that a driver can call or how the driver operates.
The device stack can be made up of multiple drivers, any or all of which can be KMDF drivers. The example in Figure 4-3 shows a KMDF function driver installed over a WDM lower filter driver. However, it could just as easily be two KMDF drivers or a WDM function driver over a KMDF lower filter driver. The IRPs move through the stack as usual, and the framework creates corresponding framework request objects when the IRPs reach a KMDF-related device object.
When the framework stops a driver because of a fatal error, the system has been irretrievably compromised, so the framework generates a bug check and crashes the system. All framework bug checks use the code WDF_VIOLATION and have four parameters. The first parameter indicates the specific type of error, and the additional parameters provide more information about the error.
Tip See "Interpreting Bug Check Codes" in the WDK for more information about bug checks-online at http://go.microsoft.com/fwlink/?LinkId=82320.
An application opens communication with a KMDF driver by using the device interface to obtain the device's symbolic link name and calling CreateFile to obtain a device handle, just as an application would do for other types of drivers. A typical I/O request takes the following path:
An application calls a Windows function such as ReadFile or WriteFile to send an I/O request to the device.
Windows calls the appropriate kernel-mode I/O routine, which passes the request to the I/O manager.
The I/O manager creates an IRP and sends it to the top of the device stack.
In this example, the FDO associated with the KMDF driver is at the top, so it receives the request.
If the FDO handles this type of IRP, the framework converts the IRP into a framework request object.
The framework passes the request object to the KMDF driver.
The driver processes the request and returns the results to the framework.
If the driver completes or fails the request, the framework completes the IRP and returns the results to the I/O manager. Otherwise, the framework formats the IRP and passes it to the next lower driver for further processing. If the KMDF driver must do any final processing after the request is completed, the driver registers an I/O completion callback with the framework, which in turn sets an I/O completion routine in the IRP.
If the KMDF driver passes the request down the stack for further processing, the framework formats the IRP as required and returns it to the I/O manager.
The I/O manager passes the IRP to the WDM lower filter driver, which processes the request, and so on.
When the request is finally complete, if the KMDF driver registered an I/O completion callback, the I/O manager calls the I/O completion routine that the framework set. The framework in turn calls the driver's I/O completion callback, so that the driver can complete its processing.