In the INF format, each line contains one of following two basic types of entry:
Section An INF contains multiple sections that are indicated by square brackets around the name, such as [Version]. Some standard sections are required for all INFs, and other sections are optional. You can also define custom sections that are specific to a particular INF.
Directive Each section contains one or more key=value pairs called directives, which are used to specify installation-related data.
The example in Listing 20-1 is the [Version] section from the Fx2_Driver sample's INF. It contains six directives.
Listing 20-1: Fx2_Driver sample [Version] section
[Version] Signature="$Windows NT$" Class=Sample ClassGuid={} Provider=%MSFTUMDF% DriverVer=10/13/2006,6.0.5753.0 CatalogFile=wudf.cat
The DriverVer directive specifies the build date as well as the version. This particular example was built on 10/13/06.
Most of the sections and directives for WDF drivers are essentially identical to those that are used for a comparable WDM driver. For example, roughly the first two-thirds of the Osrusbfx 2 INF is nearly identical to the INF for the WDM version of the driver. The main difference is that WDF INFs must include a set of sections devoted to the WDF co-installers.
This section focuses primarily on the WDF-specific parts of an INF.
Tip See "Creating an INF File" in the WDK for details-online at http://go.microsoft.com/fwlink/?LinkId=79356.
The sections and their contents in any particular INF depend on the driver for which the file is created. The following sections are commonly used:
[Version]
In addition to the driver version, this section can include various basic driver information such as the name of the package's catalog file.
[Manufacturer]
This section identifies the manufacturer of the device or devices that can be installed with the INF.
[SourceDisksNames] and [SourceDisksFiles]
These two sections provide the locations of the files that are to be installed.
[DestinationDirs]
This section specifies the destination folders for the installed files.
[ClassInstall32]
This section installs a new device setup class.
[Strings]
This section contains tokens and their corresponding strings. The tokens are used elsewhere in the INF and then replaced with the corresponding string. This section is especially useful if the strings must be localized.
Several sections are devoted to the WDF co-installers. See "INFs for WDF Drivers: The Co-installer Sections" later in this chapter for a discussion of the WDF-specific sections.
The WDK does not provide automated tools for creating INFs-they must be created manually by using a text editor. However, you are usually not required to create the entire INF. Instead, start with the INF from an appropriate sample and modify it to suit your driver.
Tip | ChkINF-a WDK tool-verifies an INF's structure and syntax. You can find this tool at %wdk%\tools\chkinf. Read the ChkINF documentation in the WDK-online at http://go.microsoft.com/fwlink/?LinkId=79776. Note that ChkINF is not currently designed to validate the WDF-specific sections of an INF. |
Drivers must usually be provided for all of the supported CPU architectures. However, each CPU architecture requires a separate build of the driver. The file names produced by the Build utility are usually identical, so the different builds are typically kept in different target folders. Some aspects of driver installation depend on the CPU architecture of the system, so INF files must have the necessary data to support all three architectures.
You can create INFs to support different architectures in two basic ways:
Put all the architecture-dependent data in different sections in a single INF file. This has the advantage of putting all the data in a single file, but the file tends to be relatively long and complex.
Implement a separate INF for each architecture. The individual files are simpler and shorter, but much of the data in them-such as the KMDF version-is not architecture dependent and is identical for all three. This means that, if any of the common data changes, you must update all three files separately.
The most efficient solution-used by the WDF samples-is to combine both approaches by having your project use an INX file. An INX is an architecture-independent version of an INF. Almost all of the contents of an INX are identical to an INF, but the INX has tokens in place of the CPU architecture-dependent values. For UMDF drivers, the INX also uses tokens for the UMDF co-installer version and the UMDF library version.
When you build a project, you instruct the Build utility to run a tool called Stampinf that replaces the tokens with the appropriate architecture-dependent values and puts the resulting INF in the output folder with the driver binaries. If any data changes, you can simply modify the INX and then rebuild the projects to update the INFs.
Chapter 19, "How to Build WDF Drivers," discusses how to set up a project to use an INX file.
For example, the [Manufacturer] section for the Osrusbfx2 sample's INX file is shown in Listing 20-2. For drivers produced by IHVs, "Microsoft" would be replaced by the appropriate company name.
Listing 20-2: [Manufacturer] sections from the Osrusbfx2 sample's INX and INFs
The INX section [Manufacturer] %MfgName%=Microsoft,NT$ARCH$ In the x86 version of the corresponding INF, this section becomes: [Manufacturer] %MfgName%=Microsoft,NTx86 In the x64 version of the INF, the Manufacturer section becomes: [Manufacturer] %MfgName%=Microsoft,NTAMD64
Important | Projects that use INX files must have a Makefile.inc file that instructs Build.exe how to run Stampinf.exe to create the INFs. Chapter 19, "How to Build WDF Drivers," contains details. |
The primary distinction between INFs for earlier driver models and those for WDF drivers is that the WDF INF must contain data and instructions to accomplish the following tasks:
Copying the co-installer to the target computer.
Specifying the co-installer as the co-installer for the device.
The entries in the [Manufacturer] section specify a section name-usually the manufacturer's name-and the CPU architecture. For the Osrusbfx2 example in the previous section, the specified section name is [Microsoft]. The specified section contains a list of hardware IDs, each of which specifies a DDInstall value to be used to install the device that matches the ID. For example, the [Microsoft] section for an x86 build of the Osrusbfx2 driver sample has one hardware ID with a DDInstall value of Osrusbfx2.dev, as shown in Listing 20-3.
Listing 20-3: [Microsoft] section from the Osrusbfx2 sample's INF
[Microsoft.NTx86] %USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, USB\VID_0547&PID_1002 %Switch.DeviceDesc%=Switch.Dev, {}\OsrUsbFxRawPdo
The primary WDF co-installer section is named [DDInstall.Coinstallers] and uses CopyFiles and AddReg directives to install the co-installer and associate it with the device.
Note The parts of the section names in bold are required. Names or portions of names in italics can have any user-defined value.
The coinstaller, in turn, reads the [DDInstall.Wdf] section, which contains installation directives for the co-installer. Typically, several other related sections such as a DestinationDirs section specify where the files are to be copied.
KMDF For KMDF drivers, [DDInstall.Wdf] includes one directive-KmdfService-as in the following example:
KmdfService = DriverService, Wdf-install
KmdfService assigns a name to the driver's kernel-mode service and points to the [Wdf-install] section that contains a KmdfLibraryVersion directive, as in the following example:
KmdfLibraryVersion = WdfLibraryVersion
WdfLibraryVersion is a number, such as 1.5 or 2.0, that specifies the minimum major and minor KMDF library version that the driver requires.
UMDF For UMDF drivers, [DDInstall.Wdf] has at least two directives. Table 20-3 contains some commonly used directives.
Directive | Required | Description |
---|---|---|
UmdfService | Yes | Assigns a name to the driver and points to a [Umdf-install] section. An INF can have multiple UmdfService directives, one for each UMDF service. |
UmdfServiceOrder | Yes | Specifies the order in which the UMDF drivers should be installed in the device stack. This directive is required even if the stack has only one driver. |
UmdfDispatcher | For some types of driver | Specifies where the framework should send I/O requests after the requests leave the device stack. This directive is mandatory for USB drivers and drivers that use file-handle I/O targets. |
UmdfImpersonationLevel | No | Specifies the driver's maximum impersonation level. If the directive is omitted, the impersonation level is set to Identification. |
Chapter 8, "I/O Flow and Dispatching," provides information about impersonation.
Note If you have implemented a hybrid driver, which includes both UMDF and KMDF drivers, any kernel-mode drivers in the stack should be listed by using the standard mechanism for kernel-mode drivers-either as the service or as an upper or lower filter driver.
The [Umdf-install] section typically contains the directives shown in Table 20-4.
Directive | Required | Description |
---|---|---|
UmdfLibraryVersion | Yes | Specifies the UMDF version that the driver requires. UMDF uses three-part version numbers, such as 1.0.0 or 1.5.0. |
ServiceBinary | Yes | Specifies where to place the driver's DLL. UMDF drivers must go in the %windir%\System32\Drivers\UMDF folder. |
DriverCLSID | Yes | Specifies the CLSID of the driver's driver callback object. |
The version of the coinstaller in the driver package must match the version of the framework library in the INF. If Microsoft releases a new minor version of the coinstaller-and thus of the library itself-vendors that use the new coinstaller must revise their INFs to specify the new coinstaller and framework. Alternatively, vendors can continue to use the older minor version of the INF and UMDF framework and let end users get the newer minor framework version when another driver is installed that uses a newer minor version or when Windows Update distributes a new minor version to fix a critical security issue.
Note The coinstallers and the resources that they contain are all signed components. The associated certificates are installed with Windows or distributed with service packs. Driver installation fails if the certificate with which the coinstaller was signed is not available on the target system.