The Big Picture: A Relay Race, Not a Solo Run
Many people imagine one device = one driver. In reality, a single request often passes through several drivers, each doing one small job. Think of a relay race or a factory assembly line. This section explains the building blocks: the models (rules for writing drivers), the objects (records Windows keeps) and the stacks (chains of drivers).
4.1 Windows Driver Model (WDM)
What it is: WDM (Windows Driver Model) is the original set of rules for writing Windows drivers. It was introduced with Windows 98 and Windows 2000. It defines:
- how a driver starts (
DriverEntry, Section 6), - how it receives work (I/O Request Packets, Section 9),
- how it takes part in Plug and Play (Section 7) and power management.
WDM is powerful but hard. A WDM driver author must handle every Plug and Play and power message by hand. There are dozens of tricky situations: the device is removed in the middle of a request, the PC goes to sleep while a request is running, and so on. Getting even one wrong causes rare, nasty crashes.
Even today, everything sits on top of WDM. Newer frameworks still produce WDM-style drivers inside; they just hide the hard parts.
4.2 Windows Driver Frameworks (WDF): KMDF and UMDF
What it is: WDF (Windows Driver Frameworks) is a set of ready-made building blocks that does the hard WDM work for the driver author. The author writes only the device-specific part.
| Framework | Full name | Where the driver runs |
|---|---|---|
| KMDF | Kernel-Mode Driver Framework | Kernel mode (ring 0) |
| UMDF | User-Mode Driver Framework | User mode (ring 3), see Section 3 |
Think of WDM as building a house from raw wood and WDF as building from ready-made wall panels.
What WDF handles for you:
| Chore | Without WDF | With WDF |
|---|---|---|
| Plug and Play and power events | Write many handlers by hand | The framework handles them with safe defaults |
| Request queues | Build your own | Ready-made queues |
| Cancelling requests | Tricky and bug-prone | Built in |
| Locking | Do it yourself | Mostly handled |
Result: fewer bugs, shorter code. Most new Microsoft-recommended drivers use WDF. You will also see plain WDM in older drivers and in a few special cases.
Other models you may meet (brief): miniport models, where a Microsoft "port driver" does the generic work and the maker only writes a small "miniport" for the chip. Examples: storage (storport), network (NDIS), audio and graphics. You do not need these details now; just know that the idea is the same, which is Microsoft supplies the shared part.
4.3 Driver Object
What it is: When Windows loads a driver, it creates a record in kernel memory describing it: the driver object (type name DRIVER_OBJECT). One per driver, no matter how many devices use that driver.
What it holds (simplified):
| Item | Meaning |
|---|---|
| Name and image location | Which .sys file, where it sits in memory |
| Dispatch table | A list of function addresses, one per type of request (Section 9 explains "major function codes") |
| Unload routine | The code to run when the driver is removed |
| AddDevice routine | The code to run when a new device for this driver appears (Section 6) |
| List of its device objects | All the devices this driver controls |
Picture it as the driver's business card plus phone directory: "to ask me to read, call this number; to write, call that number."
DRIVER OBJECT (disk.sys)
┌────────────────────────────────────────────┐
│ Dispatch table: │
│ IRP_MJ_CREATE → address A │
│ IRP_MJ_READ → address B │
│ IRP_MJ_WRITE → address C │
│ IRP_MJ_DEVICE_CONTROL → address D │
│ AddDevice → address E Unload → address F │
│ Devices: [device 1] [device 2] ... │
└────────────────────────────────────────────┘
The object manager keeps driver objects under the name \Driver\ (for example \Driver\disk). You can browse this with the free Sysinternals tool WinObj (Section 12).
4.4 Device Object
What it is: A device object (DEVICE_OBJECT) represents one device (or one layer of handling a device). One driver can create many device objects. For instance, disk.sys makes one device object per physical disk.
| Item | Meaning |
|---|---|
| Which driver owns it | A pointer back to the driver object |
| Device name (optional) | Such as \Device\HarddiskVolume3 (Section 12) |
| Device type and flags | Disk? Keyboard? How are I/O buffers handled? |
| A "device extension" | A private block of memory where the driver keeps its own per-device information |
| Pointer to the next device object | To link up the stack (4.5) |
There are three important kinds of device object in a stack:
| Short name | Full name | Meaning |
|---|---|---|
| PDO | Physical Device Object | Created by the bus driver. It represents the real device as the bus sees it. Always at the bottom |
| FDO | Functional Device Object | Created by the function driver, the main driver that knows what the device actually does |
| Filter DO | Filter Device Object | Created by a filter driver, an extra layer that watches or adjusts requests |
4.5 Device Stacks (Layered Drivers)
What it is: A device stack is a vertical pile of device objects, one from each driver involved with that one device. A request enters at the top and moves downward.
Requests come in here
│
▼
┌──────────────────────────────┐
│ Upper filter device object │ (optional) watches / changes requests
├──────────────────────────────┤
│ FDO (function driver) │ the "main" driver; knows the device's job
├──────────────────────────────┤
│ Lower filter device object │ (optional) sits just above the bus
├──────────────────────────────┤
│ PDO (bus driver) │ talks to the bus the device is plugged into
└──────────────────────────────┘
│
▼
The real hardware (on a bus)
How to read it:
- The bottom is the bus driver (for example the PCIe or USB bus driver). It created the PDO and knows how to physically reach the device.
- The function driver in the middle is the expert on this specific device.
- Filters are optional extras that can be added above or below the function driver.
Where do the layers come from? Different companies supply different layers. For a USB keyboard, the bus driver comes from Microsoft, and the keyboard layers come from Microsoft too. For a fancy gaming keyboard, the maker may add its own filter. Each layer only does its own job and passes the rest down.
Another view: Not only hardware has stacks. A file on disk goes through the file system driver (NTFS), then a volume driver, then a partition driver, and finally the disk driver. Each is one layer of one long request path.
4.6 Filter Drivers (Upper/Lower Filters)
What it is: A filter driver sits in a stack and can look at, change, block or add requests passing through. It is like a security guard at a door, or a spell-checker inserted in a pipeline.
| Type | Position | Typical use |
|---|---|---|
| Upper filter | Above the function driver | Change requests before the main driver sees them (for example, a keyboard macro tool) |
| Lower filter | Between function driver and bus driver | See the device's own traffic (for example, a device tool or encrypted disk layer) |
| File system filter | Above the file system | Antivirus scanners, backup tools, encryption (see fltmc, Section 13) |
Where Windows records which filters belong to a device: the registry values UpperFilters and LowerFilters. They exist either under the device class key (HKLM\SYSTEM\CurrentControlSet\Control\Class\{GUID}; applies to every device of that class) or under the specific device's key.
Why filters are useful: you can add a feature without touching the main driver. Antivirus can scan every file opened. Disk encryption can encrypt every block written. Both do so as filters.
Why filters are risky: each filter adds one more place where a crash can occur, and a bad filter can break an entire class of devices. A classic example: after uninstalling a program, an old UpperFilters entry remains that points to a missing driver. Then the device (a CD drive, for instance) fails with Code 19 or Code 39 in Device Manager. Deleting the stale entry is the fix. (Do this only with a backup, and only if you are sure.)
Summary
| Term | Plain meaning |
|---|---|
| WDM | The original driver rules; powerful but hard |
| WDF (KMDF / UMDF) | Ready-made framework that handles the hard parts; kernel or user mode |
| Driver object | One record per loaded driver: its dispatch table and routines |
| Device object | One record per device or layer: name, owner, per-device memory |
| PDO / FDO / Filter DO | Bus-side / main-driver-side / extra-layer device objects |
| Device stack | A vertical pile of device objects; requests travel down it |
| Upper / lower filter | Extra layer above or below the function driver |