WDM Driver Design Author: Tang Lin Published: 2001/03/14
Thesis:
Now Windows98 and Windows 2000 have become the mainstream of the mainstream operating system, the VXD technology used to implement the driver will slowly exit the historical stage with the Win95 fade out, and the device driver in Windows98 and Windows 2000 will be based on the Windows driver model. (WDM) to design. WDM simplifies the development of drivers by providing a flexible way, reducing and reducing the number and complexity of the drivers that must be developed based on new hardware support.
text:
WDM driver design one. WDM Introduction Microsoft continues to introduce new operating systems, now Windows98 and Windows 2000 have become mainstream, and VXD technology used to implement drivers will slowly exit historical stations with Win95 fade, in Windows 98 and Windows2000 device drivers. The WINDOWS driver model (WDM) will be designed. WDM simplifies the development of drivers by providing a flexible way, reducing and reducing the number and complexity of the drivers that must be developed based on new hardware support. Two aspects of the Windows Driver Model, in addition to the core model description of the standard structure of the device driver, WDM also implements a modular, hierarchical bus driver and class driver for common types of devices. The bus driver implements supports the General Serial Bus (USB), IEEE1394 (FireWire) protocol. The class driver is to provide conditions for the implementation of the standard Windows feature. WDM supports the number and complexity of the device driver required for Windows 95 and Windows NT on the standard interface. On the Windows platform, WDM will become the mainstream driver mode of the 21st Century. WDM supports new hardware standards such as USB, IEEE 1394, ACPI. And in the past two platforms, two truncated drivers need to be written, and now you can write a WDM driver. The WDM driver is also hierarchical, that is, drivers on different layers have different priorities, and VXD under Windows 9X does not have this structure. WDM also introduces a functional device object FDO (Functional Device Object) to describe hardware, a PDO corresponding to a real hardware. One hardware allows only one PDO, but can have multiple FDOs, which are not hardware in the driver, but the corresponding PDO and FDO. In terms of user state and kernel communication, the system is packaged for each user request to form an IRP structure, transmit it to the driver, and distinguishes it to which the device is sent. In addition, the WDM does not recognize the driver name, but is identified by a 128-bit global unique identifier GUID to achieve the identification of the driver. We use the above figure to illustrate the layering and calls of the device driver. Write WDM and other mode drivers are basically the same, the main difference in the code is how to create the device. In the WDM driver, Plug and Play (PNP) manager informs to when a device is added to the system, or delete the device from the system. PNP Manager uses the installed INF file to find the correct driver of the new device; and other mode drivers must discover its own devices, install it with a dedicated installer. In addition, there are many differences in detail, and other mode driver parameters are generally provided by the registry, call the function of the read registry in the DriveREntry, and then call CreateDevice according to the registry, but WDM is generally not the case, this is due to Windows 2000 Support PNP, PNP Manager calls the AddDevice entry point creation device when loading. A virtual appliance that is typically created in DriveREntry is a virtual device that is uncommon with the device or object for managing communication with Win32. If you don't want to do something special for the device, or the device is not complicated, addDevice can simply return NT_SUCCESS without calling CreateDevice. In addition, the entire equipment drive tree has changed, thereby causing a large change in the installer. The WDM itself has increased to the root position of the PNP manager. The PNP Manager is responsible for the loading of all bus drivers.
The bus driver is responsible for traversing all the devices located on the bus and creates a corresponding device object for each device. When the PNP manager discovers a device object, you find the Driver corresponding to the object. And call the DRIVER's Add Device routine. If DRIVER is not in memory, then load it first, then call the Add Device routine. Of course, the bus itself does not issue any signal to tell the PNP manager's own existence, so the bus driver is set when the NT is installed. ISA equipment is not specified, because KMD needs to check the existence and state of hardware, so it is the only reason for the existence of old-fashioned KMD. This is also one of the reasons for Microsoft's trust in the new specification to cancel the ISA bus. WDM supports PNP protocols and PM protocols, and implements only routines that need to be added to PNP and PM events in the Major Function. A complete driver To complete the following: initialization; create and delete devices; process the request for the application layer program to open and close the handle; process the input / output request of the application layer program; serialization to the device; access hardware; Call other drivers; cancel I / O requests; timeout I / O requests; process the addition and delete events of hot swap devices; power management and WMI. two. Development Equipment Driver 2.1 Design Tools DDK Installation WDM Device Driver We need Microsoft Driver Development Kit DDK. Although Microsoft claims that the WDM driver is binary compatible between Windows98 and 2000, only the corresponding DDK is installed in different systems. (1). Install this section of Windows 98 DDK describes how to install Windows 98 DDK. We agree that% 98DDK% is the root directory of the Windows 98 DDK;% mstools% is the root directory of the Microsoft SDK platform;% vcppdev% is the root directory of the installed VC development environment. Software platforms using DDK are usually Windows 98 operating systems and VC 4.2 or version 5.0, and if you want to compile video capture examples, you need VC 5.0. You must install the VC compilation / development environment before installing Windows 98 DDK, otherwise, Windows 98 DDK's setENV.BAT file will not establish the correct compilation environment. Reading DDK documents requires IE 4.01 or later, if it is from a disc or a test disc driver, the optical drive is required, 16MB memory is indispensable, and the full installation requires 82MB hard disk space (minimum installation requires a 32MB hard disk space). All driver examples of Windows 98 DDK do not need to be constructed under a platform installed with SDK. However, if you start developing your own driver, you may need to do not but in the SDK platform in Windows 98 DDK, so you can consider two methods: copy the desired header file or SDK platform file to% 98DDK In the appropriate INCLUDE directory of% and% vcppdev; you can also install the SDK platform directly, edit the setEnv.bat file in% 98ddk% / bin, and run the setENv.bat file installed in% mstools%. Install the DDK with the SETUP program, steps for: (1) Run the setup.exe file in Windows 98 DDK, follow the dialog box to install Windows 98 DDK to% 98DDK%. (2) Install VC 5.0 to% vcppdev%. (3) Modify config.sys increasing environment variable space.
In the config.sys file, finally join the line: shell = c: / windows/command.com / P / E: 4096 Before installing Windows 98 DDK, you must install the VC compiler / development environment first, otherwise Win Dows 98 DDK The setenv.bat batch file will not establish the correct environment. The following describes how to establish a WINDOWS 98 driver constructor and a method of constructing a driver using constructor and tools. 1. Use setEnv.bat to install the driver constructor's directory in the "Development Kits / Windows 98 DDK" in the Release. This directory includes free construction of environmental items and inspecting construction environments. Restart the operating system each time, before constructing the driver, click the appropriate item in these program folders. These items modulate the STENV.BAT batch file in% 98DDK% / bin to create the correct environment variable driver constructor. 2. Manually run Stenv.bat Under the MS-DOS prompt, or in "Start / Run": setENV% 98DDK% [free | checked], for example, at C: / 98DDK / BIN> prompt, Type Stenv C: / 98DDK Free, where the first parameter specifies the folder installed by DDK, pay attention to the default installation is / 98DDK; optionally the second parameter description of the target constructor, the default type is free. 3. Constructing the WDM driver Use a series of rules to specify how the driver is created, the constructor can be used to construct a WDM driver on the Windows 98 and the Windows NT platform. After the Windows 98 DDK is installed, the WDM driver constructs the work example and components of the tree to be available on the hard disk. The driver constructs the root directory in% 98DDK% / SRC. View the contents of the Makefile.def file in% 98ddk% / inc, and the contents of various DIRS files and source files that run through the driver, which can be used as a work instance. 4. Construct the driver Create a subdirectory in the current directory driver construction tree, then run the constructor. In the current directory of the construction tree, the constructor can automatically create the source code for the driver. The constructor is running in the root of the Windows 98 DDK example driver structure tree (% 98DDK% / src). For example, if you are interested in an example driver that is constructed as a sound device class, you can set the current directory to% 98ddk% / src / audio, then run the constructor. 5. Check the configuration of the Windows 98 DDK's installation is used in the form of build -cz; thus making the construction utility to perform the scan of related files, perform full creation, and generate an error record. Check the installation method to: Run the complete set of the example driver source code for the installation of the build -cz and the configuration installation at the /
In general, successfully compiling a basic device driver requires four files, the first is the driver, the C language source file (such as isousb.c, pay attention to all the examples below); The second is the RC file (such as isousb.rc); the third is a Sources file; the fourth file is the Makefile file. Sources files and make files are similar to specify files that need to be compiled and the library that needs to be connected. These three auxiliary documents are simple. There are three such files in each routine of DDK Samples, and they can understand their structure and significance. 1. In the following Examples isousb analysis program, for example, set isousb.rc code: #include
# Makefile ################################################################################################################################################################################################################################################################################################## #################### # # CopyRight (c) Microsoft Corporation 1995 # All Rights Reserved. # Makefile for WDM Device Driver Kit # ######################################################################################################################################################################################################################################################################################################## ################# # # do not edit this file !!! Edit ./sources. If you want to add a new source # file to this component. This file merely indirects to the real make file # that is shared by all the driver components of the Windows NT DDK #! INCLUDE $ (NTMAKEENV) /makefile.def # end of makefile for all drivers, makefile They are all the same, Microsoft also warned not to edit this file, if needed, edit the Sources file to achieve the same effect. For device drivers, the C compiler used is basically selected by VC . 2. Basic steps in compilation (1) First enter the Check or Free Compilation Environment, initialize the DDK compilation environment. (2) Run the vcvars32.bat under the bin directory in the VC installation directory, initialize the VC compilation environment. (3) Run Build.exe for compilation. (two). WINDOWS2000 DDK installation Since we have introduced the installation of Windows98 DDK in detail, we mainly introduce the Windows2000 DDK installation and Windows98 DDK. Both are different from the requirements of the system, Windows2000 DDK requires Windows2000 or Windows98 operating system, VC 5.0 or 6.0 professional or enterprise version, at least 64MB memory, recommended 128MB or more memory, fully installed 200MB, and if you are in Windows2000 If you install, you must log in as an administrator. 2.2 Device Driver Design I / O Request Pack (IRP) is the center of the driver operation, IRP is a kernel object, which is a predefined data structure with a set of I / O manager cases that operate. Process. I / O Manager receives an I / O request assignment and initializes an IRP. An IRP has a fixed header and variable purpose IRP unit block, each I / O request, has a primary function code (IRP_MJ_XXX) and may have a secondary function code (IRP_MN_XXX). Design a device driver to support the same IRP_MJ_XXX and IOCTL request code as drivers for other same types of devices. If an intermediate layer driver is designed, you should first confirm that the device managed by the lower driver, because a high-level driver must have a low-level driver most IRP_MJ_XXX routine entry. When the high-level driver is connected to the I / O request, set the stack unit of the next low-level driver in the IRP in determining the current stack unit parameters, and then call the IocallDriver to pass the request to the lower driver. .
Once the driver should process which IRP_MJ_XXX should be processed, you can start determining how many DISPATCH routines should have on the driver. Of course, it is also possible to consider combining the routines for some IRP_MJ_XXX to process as the same routine. A driver must create a Device object for the physical and logic devices that can be managed for each of the targets that may be I / O requests. Some low-level drivers may also create some unseasive number of Device objects. For example, a hard drive must create a Device object for each physical hard disk while also creating a Device object for each logical partition on each physical disk. A high-level driver must create a Device object for a virtual device it represent, such a higher-level driver to connect their Device objects to the Device object of this driver. In addition, a high-level driver typically creates a series of virtual or logical Device objects for Device objects created by its low-level driver. Although the driver can be designed in phases, a driver in the development phase does not have to create all the Device objects that it will handle, but determine all Device objects that are ultimately created from the beginning. Help any synchronization problem to be solved by the designer. In addition, it is determined that the DEVICE object to be created also helps to define the contents and data structures of Device Extension of the Device object. The development of the driver is a process from rough to fine. DDK's SRC / directory has a huge template code, almost all types of device drivers, high-level drivers, and filter drivers. Before starting to develop the driver, you can look for whether there is a similar type of routine that is to be developed below this model library. The following writers will further introduce the basic steps of the development driver: l. Writing the driver framework (1) First write a DriveRETRY routine and call IOCREATEDEVICE in this routine to create a Device object. A series of callback routines must be set in this routine to process IRPs. (2) Write a basic framework for processing the routines requested by the IRP_MJ_CREATE. If the driver creates more than one DEVICE object, you must write a routine for IRP_MJ_CLOSE requests. (3) Compile the connection driver. 2. Test drivers (1) First install the driver in the system. (2) Establish a symbolic link between the logical device name and the target Device object name, which already knows that the Device object name is invisible to Win32 user mode. If you cannot access it directly through the API, Win32 API can only access symbols Link name. You can establish a symbolic link between the two names by modifying the registry. Running regedt32.exe Create a symbolic link under / hkey_local_machine / system / currentControlSet / Control / Session Manager / DOS Devices, create this symbolic link, you can also call the function IOCREATESYMBOLICLINK in the driver, use the parameters to pass the appropriate symbolic link name and kernel device name. (3) Complete all the above settings and check the error, we must restart the Windows system. (4) Write a simple test program to call the CREATEFILE function in the Win32 API and open this device with a symbolic link name. If it is successful, a simplest driver is successfully written. Support for more device I / O requests, such as drivers may need to respond to IRP_MJ_READ requests (available after completion of the ReadFile function). If the driver needs to be able to uninstall, IRP_MJ_CLOSE must be responded.
Write the processing routine for the IRP_MJ_XXX you need, and initialize these routine portals in DriveREntry. A low-level driver requires a StartIO, ISR, and DPCFORSR routines that may also need a SYNCHCRITSECTION routine. If the device uses DMA, you may need an AdapterControl routine. For high-level drivers, one or more IOCOMPLETION routines may require one or more IOCOMPLETITION routines, at least check the I / O status block and then call IOCOMPLETEREQUEST. If necessary, make some modifications to the Device Extension data structure and content. One must be clear, that is, the code run level, i.e. IRQL, the most common level is Passive_LEVEL, APC_LEVEL, DISPATCH_LEVEL, and DIRQL. When viewing the function described in DDK Help, pay attention to the run-up level of the function, such as some functions can only be run under passive_level, and some functions can run at the DISPATCH_LEVEL below, the higher the level, the code The more strict requirements, such as when DISPATCH_LEVEL, you cannot use paging memory. Usually, you should run as much as possible to run under the low run level such as Passive_LEVEL, which runs over a long period of time will result in system efficiency, affect the real-time performance of system response. But sometimes you can't control the level of running, for example using IocallDriver when calling the low-level DRIVER, the low-level Driver response will execute the Completion routine, the level of the routine is determined by the low-level DRIVER. So when writing the Completion routine, try to be able to run this function at the Dispatch_level level. According to the above development step, we can design a new WDM device driver. 2.3 Installation of the device driver (1). WDM driver installation driver installed according to the instruction of the INF file, copy the executable to the correct location, and create a variety of registry keys. Some drivers need to occupy some hardware resources, mainly I / O addresses and interrupt numbers, and PNP manager will be assigned. The INF file after use is copied to the Windows INF subdirectory. The INF file contains all information required to install a WDM device driver, including files to be copied, and the registry item to be created. The INF file is a text file, which consists of a section. Each section starts with a name of the brackets, and each line is a simple item, or set a value. Below we will briefly introduce the INF file in an example in DDK.
BULKUSB.INF [Version] Signature = "$ CHICAGO $" Class = USB provider =% MSFT% LayoutFile = layout.inf [SourceDisksNames] 1 = "DDK BULKUSB Sample", "", 1 [SourceDisksFiles] bulkusb.sys = 1 [ Manufacturer]% MfgName% = Microsoft [Microsoft]% USB / VID_045E & PID_930A.DeviceDesc% = BULKUSB.Dev, USB / VID_045E & PID_930A [PreCopySection] HKR ,, NoSetupUI ,, 1 [DestinationDirs] BULKUSB.Files.Ext = 10, System32 / Drivers BULKUSB .Files.inf = 10, inf [bulkusb.dev] CopyFiles = Bulkusb.files.ext, burkusb.files.inf addreg = bulkusb.addreg [bulkusb.dev.nt] CopyFiles = Bulkusb.files.ext, burkusb.files. Inf AddReg = BULKUSB.AddReg [BULKUSB.Dev.NT.Services] addservice = BULKUSB, 0x00000002, BULKUSB.AddService [BULKUSB.AddService] DisplayName =% BULKUSB.SvcDesc% ServiceType = 1; SERVICE_KERNEL_DRIVER StartType = 2; SERVICE_AUTO_START ErrorControl = 1; Service_error_normal servicebinary =% 10% / system32 / drivers / bulkusb.sys loadordergroup = base [bulkusb.addreg] HKR, DEVLOADER, * NTKERN HKR, NTMPDRIVER ,, BULKUSB.sys HKLM, "System / Currentcontrolset / Services / BulkUsb / Parameters", "MaximumTransferSize", 0x10001,4096 HKLM, "System / Currentcontrolset / Services / BulkUsb / Parameters", "DebugLevel", 0x10001,2 [BULKUSB. Files.ext] Bulkusb.sys [bulkusb.files.inf] bulkusb.inf; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -------------------------------; [Strings] msft = "microsoft" mfgname = "intel" USB / VID_045E & PID_930A.Devicedesc = "Bulkusb.sys intel 82930 USB Bulk Io Test Board" Bulkusb.svcdesc = "Bulkusb.sys i82930 bulk Io test driver" We introduced common section:
[Version] Signature items $ Windows NT $, $ Windows 95 $ or $ Chicago $; Class item is a class name (USB) or a new class name specified by the user; Provider item is INF file Created; [SourceDiskSNames] Specifies its description and possible packaging files and directories for each distribution floppy disk or CD-ROM; [SourceDisksFiles] Specifies the file name, the source disk ID, and the optional subdirectory and file size, if all The files can be empty in the root directory; [Manufacturer] specifies the manufacturer name; [DestinationDirs] Copy the default file replication and specified file copy specified directory; [bulkusb.dev] Specify the list of the file to copy the file (Bulkusb.Files The name of .ext, burkusb.files.inf; specify the name of the addReg section; [Bulkusb.addService] Specifies the details of the driver service; [bulkusb.addreg] Add a new key value in the registry [Strings] Specifies some strings; (b). NT driver installation 1. Add key value for the registry to construct the driver list by scanning the registry when booting. This list includes both start-up drivers, including drivers that require manual startup. This list is actually all the devices listed in the device applet in the control panel. All device drivers should have corresponding key values on the hkey_local_machine / system / currentcontrol-set / service / currents / under / currentControl-set / Services / SESTEM / CURRENTCAL_MACHINE / SESTEM / CURRENTCAL_MACHINE / SERVICES. The name here should be consistent with your driver name. Below, the following key value is generally: Type value is 1 represents the kernel mode driver; 2 represents the file system driver. ERRORCONTROL value is 0 indicates logging errors and ignores; the value indicates logging error and display a dialog; value 2 indicates logging error, and reboots with the last correct configuration; value 3 indicates logging errors, if already Use the correct configuration to return to fail. In any device driver, the top three parameters in the above table are required. 2. Controlling the order of the driver Sometimes the order in which the plurality of drivers are controlled is necessary. Sometimes some of the program in a driver must start under other programs. 3. The START value of the driver's START value above the registry's START value control driver starts at the system. Currently, Start can be taken to the lower value, in addition to this value to apply to new requirements: (L) 0x0 (service_boot_start): This value specifies that this driver should be loaded by the operating system load program. The general driver does not adopt this value because the system is almost not started at this time, and most of the system is not available. (2) 0x1 (Service_System_Start): This value indicates that the driver is started when the operating system is loaded but initializes itself. (3) 0x2 (Service_AUTO_START): This value indicates that the service control manager is loaded after the entire system is started and run. (4) 0x3 (service_demand_start): This value indicates that the driver must be started manually. You can start with the device applet of the control panel or use Win32 API programming. (5) 0x4 (service_disabled): Indicates that the driver is disabled.