The need for the Driver Module Framework has become apparent through the evolution of the Surface brand. Microsoft develops drivers and firmware for products such as the Studio, Book, Laptop, and of course the Surface Pro. What’s interesting about these products is Microsoft approached each individually. This means separate teams worked in product-specific drivers despite the similarities between the hardware. In a blog today, Microsoft says this presented problems in terms of duplicate code and maintenance time. Developers were forced to create their own solutions to solve the issues, which left to unstructured and confusing code. Microsoft started developing a way to make reused code more efficient. The company says it sought to improve serviceability, scalability, and efficiency. This led to the creation of Driver Module Framework.
Benefits
Internally, Microsoft has been using DMF on all Windows Driver Framework drivers: “Modules are well tested and can be reused or extended later to meet new requirements. Besides having the benefit of well-architected drivers, bug fixes are now efficient. A bug fix in a Module is automatically applied to all the drivers that were built using the Module.” In its announcement, Microsoft explains some core difference between WDF’s using DMF compared to normal WDF drivers:
WDF communicates with DMF, while DMF communicates with the driver. The device context (shown in green) exists independently in each Module and in the client driver-specific code. Each smaller device context holds only the elements that are needed for that Module. No Module can access another Module’s device context. The WDF callbacks (shown in red) now exist independently in each Module and in the client-specific code. WDF calls into the client driver. DMF intercepts that call and dispatches it to each Module in the tree of instantiated Modules. Each Module handles each callback as it sees fit. Finally, DMF dispatches the callbacks to the client driver’s callbacks. Finally, note the arrows. The arrows specifically show the flow among Modules and the client-specific code. In this example, client-specific code can only communicate with three Modules: ACPI, Button, and Stream. It cannot communicate with GPIO, FIFO, List, or Thread. ACPI cannot communicate with FIFO, etc. Even without looking at source code, we have a good idea of how data flows in this driver.