Key Driver Concepts and Tips

If you are new to Windows driver development, start here for pointers to first steps for concepts, tools, and driver models.

Key Driver Concepts Whatever the driver model and device class for your driver, you need a good understanding of Windows system internals such as memory management, I/O flow, and I/O request packets (IRPs).

Driver Design You must design a driver carefully to build in reliability, serviceability, and the feature-based functionality needed to support the driver’s device.

Driver Performance: Best Practices A high-quality driver runs reliably and causes no slowing of the entire system. Creating drivers for Windows that perform well requires effort throughout design and development.

This paper provides information about writing drivers for the Microsoft Windows family of operating systems. It provides guidelines for driver writers to determine when support for IRP cancellation is required and how to implement it properly.

WDK MVP Donald D. Burn shares his experience and insights about tools for creating a device driver for Microsoft Windows, with information about debugging, testing tools, and techniques that can help you find and fix bugs early in development.

Unless an application opens a device for overlapped I/O, the I/O Manager serializes requests so the driver gets only one request at a time. Here's what to do in your application and your driver to support overlapped I/O.

Driver development tip: The size of the kernel-mode stack varies among different hardware platforms, but it is always a scarce resource. Here are some tips for understanding and managing your driver's use of the kernel-mode stack.

Any time an IRP can be queued indefinitely or remain active on a device for a long time, the driver should support IRP cancellation. This allows the driver to remove and quickly complete an outstanding I/O request that a user has cancelled.

This topic provides I/O completion and cancellation guidelines for Windows Vista and Windows Server 2008. It describes how drivers can cause applications to hang and how they can cause application terminations to fail. It then discusses ways that driver developers and equipment and device manufacturers can prevent these failures, as well as support the new application-initiated I/O cancellation feature planned for Windows Vista and Windows Server 2008.

This paper explains how to use synchronization mechanisms to protect shared memory locations in kernel-mode drivers for the Microsoft Windows family of operating systems. By following the guidelines in this paper, driver writers will be able to determine when synchronization is required, what synchronization mechanisms are provided by the operating system, and how each type of synchronization mechanism is used.

As a savvy driver writer, you know that Windows can pre-empt the thread in which your driver is running to run a higher-priority thread at any time. And you know that on a multiprocessor system, including systems with hyper-threaded CPUs, your driver can run concurrently on more than one processor at a time. In either situation, your driver must synchronize access to shared, writable data. But do you know exactly which kernel-mode driver routines can be called concurrently - and therefore exactly which data you need to protect?

A work item is a structure of type IO_WORKITEM that is associated with a worker routine and a context area. A driver adds a work item to the system work queue; a system worker thread later removes the item and runs the associated routine at PASSIVE_LEVEL. However, queuing a work item that is already in the work queue can corrupt the queue and cause hard-to-detect problems in your driver.

When a device driver creates a device object by calling IoCreateDevice, the I/O manager sets DO_DEVICE_INITIALIZING in the Flags field of the DEVICE_OBJECT structure. The purpose of DO_DEVICE_INITIALIZING is to prevent other components from sending I/O to a device before the driver has finished initializing the device object.

Drivers sometimes need to lock pages so they stay in memory during certain operations, such as copying data from a device to the data buffer in a DPC routine or performing DMA to the buffer. The MmProbeAndLockPages routine makes a specified memory range resident (if it isn't already), confirms that the pages permit the specified operation at the specified access mode, and locks the pages in memory so that they cannot be paged out.

A memory descriptor list (MDL) is a system-defined structure that describes a buffer by a set of physical addresses. A driver that performs direct I/O receives a pointer to an MDL from the I/O manager, and reads and writes data through the MDL. Some drivers also use MDLs when they perform direct I/O to satisfy a device I/O control request.

A curious driver writer asks:
"According to the Windows Driver Kit (WDK), the MmAllocateContiguousMemory function allocates memory from the nonpaged pool, which is currently limited to 256 MB on 32-bit systems and 128 GB on 64-bit systems. However, my driver has successfully requested 370 MB on a Windows XP or Windows Server 2003 system. How can this happen?"