DRIVER_EXTENSION

The DRIVER_EXTENSION structure is an adjunct to the well-known (though partially opaque) DRIVER_OBJECT. It was added when introduction of the PnP Manager for Windows NT 4.0 needed that drivers implement another calling point through which to learn of device addition. The address to call might be set into the DRIVER_OBJECT except for compatibility constraints. Pre-existing drivers depended on at least some members, which therefore could not shift. Members could not be appended without risking a future problem for the MajorFunction array were new types of I/O request ever to be defined. The solution was to replace the Count member, which no drivers should have been accessing, by a pointer to an extension. Thereafter, the Count and anything new that is ever wanted for the DRIVER_OBJECT go to the extension.

Documentation Status

Because writers of device drivers that actually do drive a physical device, here meaning one that’s known to the PnP Manager, need to know of the DRIVER_EXTENSION so that they can set the AddDevice member, the DRIVER_EXTENSION has long been documented—but only indirectly and only to the bare minimum for this one need. Since the structure itself is not even mentioned in the documentation, saying it’s documented indirectly is generous. It is, however, literal: what programmers are told is that they set their AddDevice routine not directly in their driver object but indirectly through its DriverExtension member. It wasn’t until the DDK for Windows XP that they were told in the documentatin that the DriverExtension is a PDRIVER_EXTENSION and that AddDevice is “the only accessible member of the driver extension”.

A C-language definition is in the NTDDK.H from the Device Driver Kit (DDK) for Windows NT 4.0. It moved to WDM.H in the DDK for Windows 2000. No definition in the NTDDK.H or WDM.H from any DDK or in the WDM.H or NTOSP.H from any Windows Driver Kit (WDK) has yet extended beyond the ServiceKeyName member. Type information in public symbol files, however, has always told of more.

Layout

The DRIVER_EXTENSION has varied from version to version only by appending new members. The following table summarises the growing size:

Version Size (x86) Size (x64)
4.0 0x14  
5.0 0x18  
5.1 to 6.1 0x1C 0x38
6.2 0x24 0x48
6.3 to 2004 0x28 0x50

These sizes, and the offsets, types and names in the tables that follow, are from Microsoft’s symbol files for the kernel starting with Windows 2000 SP3 (except as noted after the table). Before then, offsets and names are in tables in the KDEX2X86 debugger extension to support its !strct command.

Offset (x86) Offset (x64) Definition Versions
0x00 0x00
DRIVER_OBJECT *DriverObject;
4.0 and higher
0x04 0x08
PDRIVER_ADD_DEVICE AddDevice;
4.0 and higher
0x08 0x10
ULONG Count;
4.0 and higher
0x0C 0x18
UNICODE_STRING ServiceKeyName;
4.0 and higher
0x14 0x28
IO_CLIENT_EXTENSION *ClientDriverExtension;
5.0 and higher
0x18 0x30
FS_FILTER_CALLBACKS *FsFilterCallbacks;
5.1 and higher
0x1C 0x38
PVOID KseCallbacks;
6.2 and higher
0x20 0x40
PVOID DvCallbacks;
6.2 and higher
0x24 0x48
PVOID VerifierContext;
6.3 and higher

For no reason that is yet understood, the public symbol file for the 64-bit kernel in the 2004 edition of Windows 10 would have it that the structure extends no further than ServiceKeyName. That this is deliberate, to make the type information consistent with the definition in WDM.H, seems unlikely. The type information in just this one PDB is here taken as aberrant. The corresponding symbol file for the 32-bit kernel is not affected, nor is the code in the 64-bit kernel, which continues to allow 0x50 bytes for the extension.