test‎ > ‎

Driver Components

  1. Driver and Device stack

    The WDM drivers are layered in a vertical calling sequence that is called a driver stack. Because devices operate at speeds that may not match the operating system, the communication between the operating system and device drivers is primarily done through I/O request packets (IRPs). These packets are similar to network packets or Windows message packets. They are passed from operating system to specific drivers and from one driver to another.The topmost driver in the stack typically receives I/O requests from user applications, after the requests have passed through the operating system's I/O manager. The lower driver layers typically communicate with computer hardware. Frequently several drivers participate in a single I/O request (like reading data from a device). The drivers are layered in a stack, and the conventional way to visualize the stack is with the first driver at the top and the last driver at the bottom. The stack has one function driver and can also have filter drivers. Windows operating system communicates with drivers by sending I/O request packets (IRPs). The Windows I/O system provides a layered driver model called stacks. Typically IRPs go from one driver to another in the same stack to facilitate communication. For example, a joystick driver would need to communicate to a USB hub, which in turn would need to communicate to a USB host controller, which would then need to communicate through a PCI bus to the rest of the computer hardware. The stack consists of joystick driver, USB hub, USB host controller, and the PCI bus. This communication is coordinated by having each driver in the stack send and receive IRPs.

    Each driver stack supports one or more device stacks. Each device stack represents one device. Each driver creates a device object for each of its devices and attaches each device object to a device stack. Device stacks are created and removed as devices are plugged in and unplugged, and each time the system is rebooted.

  2. Services

    A service application conforms to the interface rules of the Service Control Manager (SCM). It can be started automatically at system boot, by a user through the Services control panel applet, or by an application that uses the service functions. Services can execute even when no user is logged on to the system. A driver service conforms to the device driver protocols. It is similar to a service application, but it does not interact with the SCM. This section is required as an expansion of the DDInstall section for most kernel-mode device drivers. This includes any WDM drivers (exceptions are INF files for modems and display monitors). It controls how and when the services of a particular driver are started, its dependencies (if any) on underlying legacy, and so forth. This section also sets up event-logging services by a device driver if it supports event logging. These INF files use the DDInstall.Services section with at least one AddService directive to control how and when the services of a particular driver are loaded, any dependencies on other services or on underlying (legacy) drivers it might have, and so forth. Optionally, they set up event-logging services by the device drivers as well. It specifies characteristics of the services associated with drivers, such as how and when the services are loaded, and any dependencies on other underlying legacy drivers or services. Optionally, this directive also sets up event-logging services for the device. INF files commonly use the ClassInstall32.Services section with at least one AddService directive to control how and when the services of a particular device class are loaded, any dependencies it might have on other services, and so forth.

    DisplayName Specifies a friendly name for the service/driver

    DescriptionThis string gives the user more information about the service

    ServiceType The type-code for a kernel-mode device driver must be set to (SERVICE_KERNEL_DRIVER). The type-code for a Microsoft Win32 service that is installed for a device should be set to (SERVICE_WIN32_OWN_PROCESS) or (SERVICE_WIN32_SHARE_PROCESS). If the Win32 service can interact with the desktop, the type-code value should be combined with (SERVICE_INTERACTIVE_PROCESS). The type-code for a highest level network driver, such as a redirector, or a file system driver, should be set to (SERVICE_FILE_SYSTEM_DRIVER).

    StartType Specifies when to start the driver. SERVICE_BOOT_START Indicates a driver started by the operating system loader. This value must be used for drivers of devices required for loading the operating system. SERVICE_SYSTEM_START Indicates a driver started during operating system initialization. This value should be used by PnP drivers that do device detection during initialization but are not required to load the system. SERVICE_AUTO_START Indicates a driver started by the service control manager during system startup. This value should never be used in the INF files for WDM or PnP device drivers. SERVICE_DEMAND_START Indicates a driver started on demand, either by the PnP manager when the corresponding device is enumerated or possibly by the service control manager in response to an explicit user demand for a non-PnP device. This value should be used in the INF files for all WDM drivers of devices that are not required to load the system and for all PnP device drivers that are neither required to load the system nor engaged in device detection. SERVICE_DISABLED Indicates a driver that cannot be started. This value can be used to temporarily disable the driver services for a device. However, a device/driver cannot be installed if this value is specified in the service-install section of its INF file.

    HKLM\System\CurrentControlSet\Services\ServiceName registry key.

    Dependencies Each depend-on-item-name item in a dependencies list specifies the name of a service or load-order group on which the device/driver depends. If the depend-on-item-name specifies a service, the service that must be running before this driver is started. A depend-on-item-name can specify a load order group on which this device/driver depends. Such a driver is started only if at least one member of the specified group was started.

    Specifying Driver Load Order

    The operating system loads drivers according to the service-install-section StartType value, as follows:

    • During the system boot start phase, the operating system loads all (SERVICE_BOOT_START) drivers.
    • During the system start phase, the operating system first loads all WDM and PnP drivers for which the PnP manager finds device nodes (devnodes) in the registry ..\Enum tree (whether their INF files specify SERVICE_SYSTEM_START or SERVICE_DEMAND_START).Then the operating system loads all remaining SERVICE_SYSTEM_START drivers.
    • During the system auto-start phase, the operating system loads all remaining SERVICE_AUTO_START drivers.

    The HKLM\SYSTEM\CurrentControlSet\Services registry tree stores information about each service on the system. Each driver has a key of the form HKLM\SYSTEM\CurrentControlSet\Services\DriverName. The PnP manager passes this path of a driver in the RegistryPath parameter when it calls the driver's DriverEntry routine. A driver can store global driver-defined data under its key in the Services tree. Information that is stored under this key is available to the driver during its initialization.

    The following keys and value entries are of particular interest:

    ImagePath A value entry that specifies the fully qualified path of the driver's image file. Windows creates this value by using the requiredServiceBinary entry in the driver's INF file. This entry is in the service-install-section referenced by the driver's INF AddService directive. A typical value for this path is %SystemRoot%\system32\Drivers\DriverName.sys, where DriverName is the name of the driver's Serviceskey.
    Parameters A key that is used to store driver-specific data. For some types of drivers, the system expects to find specific value entries. You can add value entries to this subkey using AddReg entries in the driver's INF file. Performance

    A key that specifies information for optional performance monitoring. The values under this key specify the name of the driver's performance DLL and the names of certain exported functions in that DLL. You can add value entries to this subkey using AddReg entries in the driver's INF file.


  3. Device Interface Classes

    Used to group devices together that provide similar capabilities. Any driver of a physical, logical, or virtual device to which user-mode code can direct I/O requests must supply some sort of name for its user-mode clients. Using the name, a user-mode application (or other system component) identifies the device from which it is requesting I/O. A device interface class is a way of exporting device and driver functionality to other system components, including other drivers, as well as user-mode applications. A driver can register a device interface class, then enable an instance of the class for each device object to which user-mode I/O requests might be sent.

    Device interface classes provide a mechanism for grouping devices according to shared characteristics. Instead of tracking the presence in the system of an individual device, drivers and user applications can register to be notified of the arrival or removal of any device that belongs to a particular interface class. Definitions of interface classes are not provided in a single file. A device interface class is always defined in a header file that belongs exclusively to a particular class of devices. For example, Ntddmou.h contains the definition of GUID_CLASS_MOUSE, the GUID representing the mouse interface class; Ntddpar.h defines the interface class GUID for parallel devices; Ntddpcm.h defines the standard interface class GUID for PCMCIA devices;Ntddstor.h defines the interface class GUID for storage devices, and so on. The GUIDs in header files that are specific to the device interface class should be used to register for notification of arrival of an instance of a device interface. If a driver registers for notification using a setup class GUID instead of an interface class GUID, then it will not be notified when an interface arrives.

  4. Each device interface class is associated with a GUID. The system defines GUIDs for common device interface classes in device-specific header files. Vendors can create additional device interface classes.

    For example, three different types of mouse devices could be members of the same device interface class, even if one connects through a USB port, a second through a serial port, and the third through an infrared port. Each driver registers its device as a member of the interface class GUID_DEVINTERFACE_MOUSE.

    Typically, drivers register for only one interface class. However, drivers for devices that have specialized functionality beyond that defined for their standard interface class might also register for an additional class. For example, a driver for a disk that can be mounted should register for both its disk interface class (GUID_DEVINTERFACE_DISK) and the mountable device class (MOUNTDEV_MOUNTED_DEVICE_GUID).

    When a driver registers an instance of a device interface class, the I/O manager associates the device and the device interface class GUID with a symbolic link name. The link name is stored in the registry and persists across system starts. An application that uses the interface can query for instances of the interface and receive a symbolic link name representing a device that supports the interface. The application can then use the symbolic link name as a target for I/O requests.

    If a driver exports the functionality of a device interface class, therefore creating a new instance of the interface class, such as kernel-streaming still-image capture or data decompression, its INF file can have this section.

    Device interfaces are available to both kernel-mode components and user-mode applications.

    Registers device functionality (a device interface) for a device. Retrieves information about an existing device interface and adds it to the specified device information set.

    Device interface classes are the methods available to applications for accessing the capabilities of a device driver. They indicate to whatever receives notifications that a particular interface is present. A device driver can have multiple device interface classes, or it can have no device interface classes.

    HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses Contains information about the device interfaces on the system. There is a subkey for each device interface class and entries under those subkeys for each instance of an interface that is registered for the device interface class.

    Before a kernel-mode component can use a specific device or file object, it must do the following:

    Determine whether the required device interface class is registered and enabled. A driver can register with the PnP manager to be notified when an instance of a device interface is enabled or disabled. This routine stores the address of a driver-supplied callback, which is called whenever an instance of a device interface instance is enabled or disabled, for a specified device class.

    A driver or other kernel-mode component can also call IoGetDeviceInterfaces to get a list of all registered, enabled device interface instances for a specific device interface class. The returned list contains pointers to the Unicode symbolic link strings that identify the device interface instances.

    A symbolic link is a file-system object that points to another file system object.

    Get a pointer to a device or file object that corresponds to an instance of the interface. To access a specific device object, the driver must call IoGetDeviceObjectPointer, passing the Unicode string for the required interface in the ObjectName parameter. To access a file object, the driver must call InitializeObjectAttributes, passing the Unicode string in theObjectName parameter, and then pass the successfully initialized attribute structure in a call to ZwCreateFile.

    IoGetDeviceObjectPointer establishes a "connection" between the caller and the next-lower-level driver. A successful caller can use the returned device object pointer to initialize its own device objects. It can also be used as an argument to IoAttachDeviceToDeviceStack,IoCallDriver, and any routine that creates IRPs for lower drivers. The returned pointer is a required argument to IoCallDriver.

    This routine also returns a pointer to the corresponding file object. When unloading, a driver can dereference the file object as a means of indirectly dereferencing the device object. To do so, the driver calls ObDereferenceObject from its Unload routine, passing the file object pointer returned by IoGetDeviceObjectPointer. Failure to dereference the device object in a driver's Unload routine prevents the next-lower driver from being unloaded. However, drivers that close the file object before the unload process must take out an extra reference on the device object before dereferencing the file object. Otherwise, dereferencing the file object can lead to a premature deletion of the device object.

    To get a pointer to the highest-level driver in the file system driver stack, a driver must ensure that the file system is mounted; if it is not, this routine traverses the storage device stack. To ensure that the file system is mounted on the storage device, the driver must specify an appropriate access mask, such as FILE_READ_DATA or FILE_WRITE_ATTRIBUTES, in the DesiredAccess parameter. Specifying FILE_READ_ATTRIBUTES does not cause the file system to be mounted.

    After any higher-level driver has chained itself over another driver by successfully calling this routine, the higher-level driver must set theStackSize field in its device object to that of the next-lower-level driver's device object plus one.

    Callers of IoGetDeviceObjectPointer must be running at IRQL = PASSIVE_LEVEL.

    IoAttachDeviceToDeviceStack establishes layering between drivers so that the same IRPs are sent to each driver in the chain.

    An intermediate driver can use this routine during initialization to attach its own device object to another driver's device object. Subsequent I/O requests sent to TargetDevice are sent first to the intermediate driver.

    This routine sets the AlignmentRequirement in SourceDevice to the value in the next-lower device object and sets the StackSize to the value in the next-lower-object plus one.

    A driver writer must take care to call this routine before any drivers that must layer on top of their driver. IoAttachDeviceToDeviceStackattaches SourceDevice to the highest device object currently layered in the chain and has no way to determine whether drivers are being layered in the correct order.

    A driver that acquired a pointer to the target device by calling IoGetDeviceObjectPointer should call ObDereferenceObject with the file object pointer that was returned by IoGetDeviceObjectPointer to release its reference to the file object before it detaches its own device object, for example, when such a higher-level driver is unloaded.

    Battery and ACPI devices, Bluetooth devices, Display and Image devices, Interactive Input devices, Modem devices, Network devices, Serial and Parallel Port devices, Storage devices

  5. Device Identification Strings

    Windows uses the following device identification strings to locate the information (INF) file that best matches the device. These strings are reported by a device's enumerator. Windows tries to find a match for one of the hardware IDs or compatible IDs. In addition to using the preceding IDs to identify devices, the PnP manager uses the following IDs to uniquely identify instances of each device that are installed in a computer: Each enumerator customizes its device IDs, hardware IDs, and compatible IDs to uniquely identify the device that it enumerates. In addition, each enumerator has its own policy to identify hardware IDs and compatible IDs. Device Identifier Formats. Most, but not all, identifier strings are bus-specific. The Plug and Play (PnP) manager also supports a set of generic device identifiers for devices that can appear on many different buses.
    Hardware ID A hardware ID is a vendor-defined identification string that Windows uses to match a device to an INF file. In most cases, a device has associated with it a list of hardware IDs.
    Compatible ID A compatible ID is a vendor-defined identification string that Windows uses to match a device to an INF file. A device can have associated with it a list of compatible IDs. The compatible IDs should be listed in order of decreasing suitability. If Windows cannot locate an INF file that matches one of a device's hardware IDs, it uses compatible IDs to locate an INF file.
    Instance ID An instance ID is a device identification string that distinguishes a device from other devices of the same type on a computer. An instance ID contains serial number information, if supported by the underlying bus, or some kind of location information.
    Device instance ID A device instance ID is a system-supplied device identification string that uniquely identifies a device in the system. The Plug and Play (PnP) manager assigns a device instance ID to each device node (devnode) in a system's device tree.
    Container ID A container ID is a system-supplied device identification string that uniquely groups the functional devices associated with a single-function or multifunction device installed in the computer. Starting with Windows 7, the PnP manager uses the Container ID device identification string to group one or more device nodes (devnodes) that were enumerated from each instance of a physical device installed in a computer.