Windows System Software -- Consulting, Training, Development -- Engineering Excellence, Every Time.

OSR Learning Library

You have come to the right place to learn about Windows driver development (WDF, KMDF, UMDF), file systems, file system minifilters, or Windows kernel debugging and crash analysis.

Start Here: How Do I Write a Windows Driver (or Minifilter)?

Are you new to the world of Windows driver development? Looking for a tutorial on Windows driver development that’ll help you get started? We wrote this article just for you: Getting Started Writing Windows Drivers

Learning Library, Organized by Topic

Below, we’ve organized the current topics in our Learning Library by subject area. Click the tab of the subject that you’re interested in exploring further. And enjoy!

Windows Driver Foundation (WDF) including both KMDF and UMDF

  • Receiving and Sorting I/O Requests in Your Driver Using WDF Queues
    How to use receive and sort Requests that are sent to your driver, using WDFQUEUEs.
  • Limiting the Number of Simultaneous Requests from Parallel Dispatched Queues
    Using Sequential Dispatching, you can get one Request delivered to your driver at a time. With parallel Dispatching, you get an unlimited number of Requests delivered to your driver at once by default. This article describes how to set a maximum number of simultaneously active parallel Requests.
  • Sending Requests to Other Devices/Drivers is Easy… If You Follow These Simple Rules
    If your WDF driver needs to send a Request to another device/driver for processing, you’ll call WdfRequestSend to send the Request to a WDFIOTARGET. Like most things in WDF, these features aren’t hard to use, but they can be surprisingly easy to unintentionally use incorrectly… leading to rare or difficult to diagnose errors. This article gives you easy guidance so you can’t go wrong.
  • Understanding Sync Scope in WDF Drivers
    All Windows drivers need to be “thread safe.” This can lead to complexity, potentially dealing with different types of locks (Mutex? Spin lock?) and multiple different locking levels. The WDF designers recognized this and created what they hoped would be a simplifying concept called Sync Scope. This article provides a detailed dive into Sync Scope, discussing both how to use it and when it might not be the best solution for your needs.
  • Surprising Side-Effects of Sync Scope and Using Timers and/or Work Items
    If you use a Sync Scope other than “none” in your driver, beware of the unintended consequences this can have on timers and/or work items that you may also be using.
  • Making User Access to Your Driver Easy… and SAFE
    There are two potential ways users can access the device(s) your driver makes available: Using a Device Interface GUID, or using a device name. Each way has advantages and disadvantages. And naming your device can introduce surprising security challenges. It’s definitely not as simple as just calling WdfDeviceIniteAssignSddlString. This is the definitive article on how to make your Device Objects accessible and properly protected. We got some big surprises when writing it. We’re willing to be almost every Windows driver dev will get similar surprises reading it.
  • FileObject Callbacks Demystified
    When a user calls CreateFile targeting one of your devices, what callback is invoked in your WDF driver? Do you need to handle this callback? Similarly, what callback is invoked with a user calls CloseHandle and do you need to implement this callback? This article answers these questions.
  • What Happens When an App Exits With I/O In Progress? Handling Cleanup, Close and Cancel in your WDF Driver
    Cleanup, Close, and Cancel operations in Windows drivers are very commonly misunderstood. Not handling them properly can lead to crashes or the classic “application hangs on exit” problem that new Windows driver devs so often see. This article teaches you the difference between these three operations, and when you need to handle each. It also provides guidance for best practices regarding handling these functions in your WDF driver.
  • I²C and SPI Devices on Windows: Intro to SPB Devices and Drivers
    The I2C and SPI buses provide simple, inexpensive, ways to connect devices to a system. Despite their having been around for many years, support for these buses has only been added to Windows in recent years. This article gives you a quick introduction to writing WDF drivers for devices that are connected via I2C and SPI.
  • How a Driver Tells an Application That “Something” Happened
    How can my driver inform an application that “something has happened” that the application might be interested in? How can my driver make a “callback” to user-mode? There’s a standard model for doing this in the world of Windows drivers, and it’s called “the inverted call model.” This article explains that model, and even points off to some sample code we put on GitHub that can get you started.
  • The WDFSTRING Object
    Did you know that there’s a WDFSTRING object? There is! And sometimes it’s even useful.
  • Be Careful When Calling WdfIoQueuePurgeSynchronously
    A brief reminder that you can’t call WdfIoQueuePurgeSynchronously from an EvtIoXxx Event Processing Callback. And that means, any Queue’s EvtIo Event Processing Callback.
  • Are All Three Variants of WdfRequestSend Useful?
    WdfRequestSend seems so easy. And there seem to be three equally useful ways to use it: synchrnous, asynchronous with a callback, and send-and-forget. But are these three variants really equally useful?
  • Understanding WDFMEMORY Objects
    Is it a buffer? An object? A Memory Descriptor? We describe the differences between these features in WDF.
  • Driver to Driver Communication in WDF Made Easy: Using Bus Interfaces
    What’s the best way for two drivers to “interact”, aside from having one send a Request to the other? How can DriverA call a function in DriverB? There are many ways to do this. But one of the easiest ways to do this in WDF is to use a Bus Interface. This article gives you the details.
  • Understanding EvtIoStop, Bugcheck 9F and Related SDV Errors
    Does your WDF driver get a 0x9F bugcheck? I bet you’re not handling EvtIoStop. This article explains why you probably need to implement this callback.
  • Creating Custom WDF Objects
    Did you ever find yourself wishing that you could extend the WDF Framework? Add your own, custom, type of WDF Object for a specific purpose? Well, you can. This article tells you how.
  • The Three Most Common Errors in Shipping WDF Drivers
    One of the things we do a lot here at OSR is review code written by other driver devs. When reviewing WDF drivers, we most often see three errors that are easily avoidable if the dev who wrote the code was aware of the issue. And the biggest problem with these errors is that you can test your driver, and it seem like it works properly. But, in fact, your driver is broken. Don’t make these mistakes.
  • Five Basic Hints for Successful WDF Testing and Debugging
    You write code. Sometimes it doesn’t work the first time. We often see folks struggle with the process of debugging more than they do even with the initial design and coding of their driver. Here, we give you five basic tips to ensure your debugging activities get started on the right track.

Articles About File System and File System Filter/Minifilter Development

  • Understanding Minifilters: Why and How File System Filter Drivers Evolved
    You want to write a file system Minifilter, and what you’ve read about Windows Filter Manager makes it sound easy! Well, it can be easy. But it can also be surprisingly challenging. To understand how to write that Minifilter, you really need to understand a bit about how Filter Manager came into being, and how to avoid what we call The Minifilter Cliff. This article gives you the background you need.
  • Scanning File Content During Create: FsRtlCreateSectionForDataScan (And Flt Variant) Explained
    Many Minifilters, such as antivirus filters, need to examine the contents of a file before allowing access to that file. There’s an FsRtl function that was created specifically for this purpose, and even a Filter Manager variant. In this article, we describe that API, how to use it, and a few caveats specific to the Flt version.
  • Windows 10 Changes File Systems and File System Filters
    Windows 10 continue to evolve and change. In this article, we review a big chunk of file system changes that were first introduced in Windows version 1607, including the new FILE_INFORMATION_CLASS FileDispositionInformationEx, and changes to IRP_MJ_FLUSH_BUFFERS behavior.
  • Making Sense of User-Mode Paths: Drive Letters and Volume GUIDs
  • The problems of properly identifying drives in your Minifilter.
  • An Introduction to Standard and Isolation Minifilters
    Writing file system filters can be challenging. But when your Minifilter seeks to separate one or more “views” of a file’s data from the actual underlying data in the file (such as through translation or encryption), things can quickly get tricky. In this article, we describe the key differences between Standard Minifilters and Isolation Minifitlers.
  • Logical and Physical File Sizes in Windows
    File size is a simple concept: It’s the number of bytes that are stored in a file, right? But… did you know that files on disk in Windows have three different sizes? Yup. They have an Allocation Size, and End Of File size, and a Valid Data Length size. This article introduces you to the key distinctions among these three sizes.
  • More on Maintaining Valid Data Length
    Veteran Microsoft file system and file system filter expert Malcom Smith provides the definitive, and detailed, description of Valid Data Length that you’ll only find here.

Articles About Windows Kernel-Mode Debugging and Crash Analysis

  • Updating Drivers with KDFiles
    As you go through the process of developing and debugging your driver, how do get the updated driver image from your host machine onto your target machine? One of the easiest ways with with “.kdfiles” — And if you’re an experienced Windows dev who’s tried this and failed to get it to work, we bet you haven’t tried the “-m” option. Read all about it in this article.
  • The New Kernel Pool Allocator: What Changed? How Well Does It Work?
    Windows 10 version 1809 (build 17763), otherwise known as RS5, introduced a new pool allocator in the kernel. It’s the same Low Fragmentation Heap allocator that’s been used in user-mode for a long time. Is it as robust as the old allocator, in terms of finding pool problems? Let’s see!
  • Experimenting with Live Kernel Reports
    Did you know there’s a DbgkWerCaptureLiveKernelDump API, that generates a “live kernel report” dump on command, while the system keeps running? Well, we tried to use it. Here’s what we found it.
  • Analyst’s Perspective: My Driver Passes Driver Verifier! (Or Does It…)
    You have to test your driver with Windows Driver Verifier. But testing your driver correctly with Verifier might require more than just enabling Verifier for your .sys image.
  • Fix Your Symbols! How to Set The WinDbg Symbol Search Path
    Getting your symbols, all your symbols, properly setup in WinDbg can stump new Windows driver devs. In this article (with optional video) OSR’s Scott Noone shows you step-by-step how to properly set the WinDbg symbol search path.
  • Fix Your (Offline) Symbols
    You know that setting the symbol search path in WinDbg is critical to successful driver debugging. But, how do you get the symbols for the OS, the various wrappers and frameworks, and other system images loaded when you don’t have access to the Internet? Here’s how.
  • Debugging Drivers on Virtual Machines via the Network using KDNET
    Your working on a filter driver, and your using a virtual machine as your target macine for your testing. Great! You’re connecting the debugger to that VM over a virtual serial port. Yuck! Slow and annoying. You can use network debugging and things will be much faster.
  • 10 WinDbg Commands You Might Not Know (But Should)
    Most of us know just enough about how to use WinDbg to “get by.” But debugging and crash analysis is a lot faster, and easier, when you have a a good understanding of the tools available to you. In this article, we review ten of the most important WinDbg commands (other than “!analyze -v”, “bp”, and “ed”) for you to know.
    What’s all that mumble in the description of this bugcheck code? Particularly, what does the output from !analyze -v mean when it says this “must be protected by a probe”?
  • Analyzing User Mode State from a Kernel Connection
    You’ve got WinDbg setup for debugging a driver. But you need to know what’s going on in a particular user process. Can you do it? Sure! This article walks you through the steps.
  • Finding the Computer Name in a Crash Dump in Windows 10
    You’re debugging a crash. You want to know the name of the system on which the crash occurred. There are many internet articles on how to do this, but few of those work on systems from Win7 through Win10. In this brief article, we show a method that works everywhere.
  • Tracking an NTSTATUS to its Source
    You’re getting a particular error return value. How do you find out what’s failing? This article shows you one technique for tracking down the location from which that error code originates.
  • Turning DbgPrint into WPP Trace Statements
    Both DbgPrint and WPP Tracing have their place. At OSR, we tend to use DbgPrint during development, and WPP Tracing for released drivers. But, suppose you’re using DbgPrint, but want to quickly convert to using WPP Tracing… perhaps temporarily to isolate a problem. You need a quick and dirty solution. This article describes one such solution.
  • NatVis Support in WinDbg
    Writing your own NatVis extension to display structured data in WinDbg. It’s XML… and it’s easy!
  • SAL Annotations — It’s Worth The Bother
    SAL annotations aren’t pretty. But they can save you tons of time, by helping you avoid coding mistakes. In this rightly famous blog post, OSR’s Scott Noone provides some useful examples while he makes the case for using SAL in driver code.
  • Turning a Breakpoint into a “Busypoint”
    When you’re debugging a live system, sometimes you just want a code path to not go any further after it reaches a certain point. But you don’t want to stop the process from running. What to do? Use a “busypoint”! We explain in this article.
  • Hunting for Strings in WinDbg
    Did you know that you can get WinDbg to show you all the ASCII or UNICODE strings in a given memory range? You can. Here’s how.

Articles on General Topics of Interest to Windows Driver Developers

  • Getting Started with Windows Drivers
    You’re pretty sure you need to develop a driver for Windows. But you’ve never done it before, and you don’t know how to begin. This article will tell you all you need to know to get started.
  • Best Practices for Windows Driver Developers
    The definitive list of best practices for coding, building, and testing drivers on Windows.
  • Why Don’t I See My DbgPrint Output?
    You’ve got the debugger set up. You’re calling the DbgPrint function in your driver code. But you don’t see any output! What’s up? You haven’t enabled DbgPrint output. It’s “off” by default. We’ll show you how to enable it in this article.
  • Develop and Test Complex Driver Code in User Mode
    There’s no denying it’s “harder” to debug things in kernel-mode than in user-mode. So, when you have a set of complex algorithms to implement, why not code and test them in user-mode first, and then move them to kernel-mode. This article describes the process.
  • What Do We Mean by “Arbitrary Process/Thread Context”?
  • Devs who are new to Windows driver often hear the term “arbitrary process/thread context” used. But they’re also often confused because nobody takes the time to define this simple, yet critical, concept. OSR’s Peter Viscarola provides the definition in this article with optional video.
  • A Catalog of Windows Kernel-Mode Synchronization Methods
    Spin Lock? In Stack Queued Spin Lock? ERESOURCE? Push Lock? There sure are a lot of synchronization methods available to driver writers in Windows. How do you choose the right one? This article gives you some definitive answers.
  • Introducing Reader/Writer Spin Locks
    Most Windows driver devs are aware of standard Spin Locks. And they’re probably also aware of In Stack Queued Spin Locks. But not as many realize that there is another class of Spin Lock that can be acquired either shared or exclusive. We describe that type of Spin Lock in this article.
  • The Wonderful World of Software Drivers
    You want to collect some information from kernel-mode. You need to write a “software-only driver.” In this article, we describe the different types of software drivers and when you might choose to implement each.
  • The Scoop on Universal Drivers
    As Microsoft changes Windows to run on multiple different platforms and in multiple configurations, it has defined a subset of kernel-mode functions that are guaranteed to be present on any Windows system. This is the subset for use by Universal Drivers. But there’s more to the concept of Universal Drivers than just defining a functional subset. This article gives you the details.
  • Happiness is Xperf
    ISR to DPC latency? The time between two events in your driver? Xpref is a tool that allows you to harvest a wealth of information about the performance of your system and of your driver. Yes, it’s complex. But it’s also worthy of your effort to learn it. In this article, we point you on the right path.
  • Understanding Critical Regions
    Why do you have to call KeEnterCriticalRegion before acquiring an ERESOURCE? Heck, what ARE Critical Regions anyhow? We explain in this article.