INF File Driver Package

I’ve had to hack around with an INF file driver package in the past, either to create them from scratch or to amend them. And because I do it so infrequently I always forget what each section does!

This is a very high-level overview that discusses the structure of an INF file used to install a PDF printer driver. We’ll start with the whole INF file and break it down in to what each section does.

What is an INF File?

An INF file forms part of a driver package. The driver package contains all associated software components (INF file, SYS files, CAT files, DLL files, associated registry etc.) required to support the device on the Windows operating system.

INF File Driver Package Example – PDF Driver

Here is an example of a relatively simple INF file used to install the driver for a PDF printer:

[Version]
Signature="$Windows NT$"
Provider=%OrganizationName%
DriverPackageDisplayName="Black Ice PDF Printer Driver"
ClassGUID={4D36E979-E325-11CE-BFC1-08002BE10318}
Class=Printer
CatalogFile.NTx86  = blackicepdfdesktop32.cat
CatalogFile.NTAMD64 = blackicepdfdesktop64.cat
DriverVer=06/19/2019,15.25.0.0
[Manufacturer]
"Black Ice Software LLC" = BlackIce,NTx86,NTamd64
[BlackIce.NTx86]
"Black Ice PDF Driver" = BIDRIVER_DATA,,Black_Ice_PDF
[BlackIce.NTamd64]
"Black Ice PDF Driver" = BIDRIVER_DATA,,Black_Ice_PDF
[BIDRIVER_DATA]
CopyFiles=BIDRIVER
DependentFiles=BuPResNT.dll
DataFile=BuPIniNT.ini
ConfigFile=BuPUifNT.dll
DriverFile=BuPDrvNT.dll
Comment=Black Ice PDF
[BIDRIVER]
BuPDrvNT.dll
BuPUifNT.dll
BuPResNT.dll
BuPIniNT.ini
[DestinationDirs]
DefaultDestDir=66000
[SourceDisksNames.x86]
34 = %disk1%,,,i386
[SourceDisksNames.amd64]
34 = %disk1%,,,amd64
[SourceDisksFiles]
BuPDrvNT.dll=34
BuPUifNT.dll=34
BuPResNT.dll=34
BuPIniNT.ini=34
[PrinterPackageInstallation.amd64]
PackageAware=TRUE
[PrinterPackageInstallation.x86]
PackageAware=TRUE
[Strings]
OrganizationName="Black Ice Software LLC"
disk1="Black Ice PDF Installation"

Now let’s walk through each section and try to explain what each part does, and how the sections chain together.

INF Version Section

The Version section is mandatory and always appears first in INF files.

Signature – this needs to be either $Windows NT$ or $Chicago$. Both denote that the driver is valid on all Windows operating systems.
Provider – the name of the organisation (usually the software vendor). In this example it has been substituted by a ‘key token’ called ‘OrganizationName’. The value of this can be found in the [Strings] section which we’ll discuss later.
DriverPackageDisplayName – a description for the driver. If installing using DIFx frameworks this will be the name in Add/Remove programs (if that option is chosen).
ClassGUID – a globally unique identifier (GUIDs) that registers the type of device class (for example, a generic Printer device class) in the registry at HKLM\System\CurrentControlSet\Control\Class.
Class – defines the device class. If this is specified, the INF file should also specify a ClassGUID (see above) to speed up installation through optimised searching.
CatalogFile.NTx86 – a CAT file denoting that the driver is digitally signed. The CAT file always exists in the same folder as the INF file. This CAT file is used on x86 platforms.
CatalogFile.NTAMD64 – a CAT file denoting that the driver is digitally signed. The CAT file always exists in the same folder as the INF file. This CAT file is used on x86 platforms.
DriverVer – This is always specified in the format “MM/dd/yyyy,w.x.y.z” and denotes the version of the driver.

INF Manufacturer Section

This section specifies the Manufacturer of the driver, and the models that it supports. It is defined in the format:
[Manufacturer]=[ModelSectionInINF][,TargetOSVersion][,TargetOSVersion] and so on.

ModelSectionInINF defines the name of a model section within the INF file. This is concatenated with the TargetOSVersion sections, which should identify the target platform architecture(s). There are various target architectures we can choose from:

ntamd64, ntia64, ntx86, ntarm, ntarm64, nt

For more information read this.

In our example: BlackIce,NTx86,NTamd64 , we will require two model sections in the INF file called [BlackIce.NTx86] and [BlackIce.NTamd64] .

Model Section(s)

We have two model sections called [BlackIce.NTx86] and [BlackIce.NTamd64] which have been referenced from the [Manufacturer] section. These sections are written in the format:

device-description=install-section-name[,hw-id][,compatible-id...]

In our example: "Black Ice PDF Driver" = BIDRIVER_DATA,,Black_Ice_PDF

“Black Ice PDF Driver” is the description of the device we wish to install.

BIDRIVER_DATA – references an install section within the INF file called [BIDRIVER_DATA] which will be used to install the device driver.

Null parameter – the missing entry between the two commas can be optionally used to specify a hardware ID for the device driver (since this is a PDF printer there is no specific hardware required).

Compatible ID – provided by the vendor. 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.

Install Section

We can see that both Model Sections use the same Install Section – [BIDRIVER_DATA] . This section is also known as a DDInstall section. It could have specified different sections for each architecture, but in this case it didn’t.

This Install section contains instructions for installing driver files and writing any device-specific and/or driver-specific information into the registry.

CopyFiles – This directive can specify one file to be copied from the source media to the destination. If more than one file needs to be copied, it can reference an INF-writer-defined section. In this example, multiple files need to be copied so it references an INF-writer-defined section called [BIDRIVER] (see below).

DependentFiles – BuPResNT.dll is a dependency file for this PDF printer driver.
DataFile – BuPIniNT.ini is the file used to configure the PDF printer settings at installation time.
ConfigFile – BuPUifNT.dll is the printer’s interface DLL. This is called in user-mode and typically provides users with modifiable configuration options that can be changed for each document that is printed (paper size, colour/greyscale etc)
DriverFile – BuPDrvNT.dll is the main driver file for the PDF printer, and configures how documents are rendered in PDF format.
Comment – “Black Ice PDF” is an arbitrary comment for the PDF printer installation.

INF-writer-defined Section

The CopyFiles directive in the Install Section points to an INF-writer-defined section called [BIDRIVER] . This section lists multiple file names which need to be copied. In this example we want to copy the files:

BuPDrvNT.dll
BuPUifNT.dll
BuPResNT.dll
BuPIniNT.ini

But how does the INF file know where to copy these files to? It uses the [DestinationDirs] section.

DestinationDirs Section

A DestinationDirs section specifies the target destination directory (or directories) for all copy, delete, and/or rename operations on files referenced by names elsewhere in the INF file.

In this example, 66000 is a printer directory ID, and resolves to the following path: C:\Windows\System32\DriverStore\FileRepository

But how does the driver installation know how to locate the driver files in relation to the INF file location on disk? It uses the [SourceDisksNames] section.

SourceDisksNames Sections

The SourceDisksNames section identifies where on the disk the source files are located relative to the installation root, and is in the form:

diskid = disk-description[,[tag-or-cab-file][,[unused][,path]]]

and taking our example of:

34 = %disk1%,,,i386

diskid – a non-negative enumeration to identify different locations on disk. It could be 0, but the vendor has specified 34.

disk-description – %disk1% again is a key token which is referenced the [Strings] section, and resolves to a description of “Black Ice PDF Installation”

tag-or-cab-file – optional (null in this case), and used to specify the name of a tag file or cabinet (.cab) file.

unused – no longer supported (null in this case)

path – The path to look for when locating the required files. In this example the location is a folder called ‘i386’ in the same directory as the INF file.

SourceDisksFiles Sections

This section points a file name to a location on disk. The location is a reference to the diskid specified in the [SourceDisksNames] section.

PrinterPackageInstallation Section

This section, combined with PackageAware=TRUE , specifies that files in the driver package are uniquely named and do not occur in any other driver package.

Strings Section

An INF file must have at least one Strings section to define every %strkey% token specified elsewhere in that INF. It is a repository for all of the key tokens used throughout the INF file.

In Conclusion

When an INF file is installed, the resultant output can be found in the registry here:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\[Windows x64 or Windows NT x86]\Drivers\Version-3\[DriverName]

and since the DestinationDir above was set to 66000, the driver files will be copied to the driver store at the following file location: C:\Windows\System32\DriverStore\FileRepository

Finally it’s worth using INFVerif to verify the structure of the INF file. If errors are found whilst verifying your INF structure then your driver will most probably fail during installation.