These days, each new upgrade for Windows brings with it a new Windows Driver Kit. And each new Windows Driver Kit brings with it new functions and features. Note that at the time of this writing (21 May 2018) the latest version of Visual Studio is 15.7.1 — and this is definitely the version you should be using.
You should read what Microsoft has to say regarding what’s new in driver development because that’s always interesting and worth a few minutes of your time. We found interesting the addition of driver and device specific directories (on disk, not in the Registry) for storing state (see IoGetDriverDirectory and IoGetDeviceDirectory). There are some interesting new features around PCIe devices that idle in D3Cold being able to specify that they want/need/use auxiliary power. I admit to not knowing about either of these features before reading the “What’s New” section for the WDK.
There’s also a nice new section on Driver Security Guidance written by star WDK writer Don Marshall, and that the team here at OSR spent some time on.
Another reasonably important thing to note is that, without you having to do anything, drivers are now built with the /Qspectre option. If you’re not up on this, check out the article we wrote on the Spectre and Meldown vulnerabilities back in January.
Any Reason Not To Upgrade?
In general, no… but I suppose it always depends on who you ask. Something to keep in mind is that you can install versions of the WDK “Side by Side” (SxS), so you can always drop back to an older release of the headers
and libraries if you have a problem or you specifically want to restrict your driver to using the older headers.
But remember: The only things that are actually SxS are the headers and libs. When you upgrade to a new version of the WDK and VS, you always get a brand new toolchain. That means a new compiler, a new linker, a new Code Analysis engine, and a new version of Static Driver Verifier. Once you upgrade, you don’t have the option to roll-back, or choose to use an older version of, say, Code Analysis.
That’s why the policy here at OSR is never upgrade your version of the WDK or VS while you’re in the middle of a project. And that’s why, if you’re one of our clients, we ask you to (please) only build your driver project using the version of the WDK and Visual Studio that we used to build your driver (pretty please). Not an older version, and not a newer version.
Code Analysis Fun
This brings me to the topic of our latest adventure in Driver Development Land: Code Analysis (CA) in the latest release of the WDK and Visual Studio.
For years it has the policy here at OSR to build our drivers with “Microsoft All Rules” enabled for our driver projects. And, the code we write should pass these checks “clean”, that is with no warnings or errors. Heck, this is even what we teach people to do in our various driver seminars.
Now, each time I install a new version of the WDK, I know that the CA engine will change. And, therefore, I expect that I’ll need to make a few tweaks before my code will build clean again. Sometimes, if I’m really lucky, CA will reveal a genuine potential bug that I’ll get to fix. So, you know… a couple of new warnings is no big deal. It’s to be expected.
Imagine my shock/surprise/horror when I got the following after upgrade to WDK 1803 and rebuilding a recent project:
Yeah… I got 552 warnings. For a shipping driver! What was up? I can miss an error or two, but there’s no way CA found that many legit errors in my code.
A quick look at the output, and the options available for Code Analysis (in your driver project, open “Properties” and select “Code Analysis”) provided the answer: It seems that Microsoft have added C++ Core Guidelines Rule Sets to Code Analysis. And, because we enable “Microsoft All Rules” these rules were included by CA when building my driver. And because our drivers use C++ “as a better C” we have the privilege of being bombarded with hundreds of not-so-very helpful directives to not do pointer arithmetic or use C-style casts. Or, my favorite, to “always initialize an object” when I declare a local variable that happens to be a pointer to something that’s declared with “typedef struct.” Or a zillion other similar things.
Where Are My Driver Rules?
So, clearly “Microsoft All Rules” isn’t what we want to use anymore. Which CA Rule Set should I now select? I tried “Microsoft Native Recommended Rules” but that doesn’t include the many driver-specific rules that make CA particularly valuable to driver devs. And then I noticed: The “Microsoft Driver xxxx Rules” Rule Sets were missing from the Rule Set selection drop down in VS. Now, you may remember “back in the old days” (waaaay back, last month, before WDK 1803 and VS 15.7.1) there were three driver-specific Rule Sets:
Microsoft Driver Must Fix Rules
Microsoft Driver Recommended Rules
Microsoft Driver Minimum Rules
Each one of these Rule Sets includes the Rule Set below it. So, the Must Fix Rule Set includes both the Recommended and Minimum Rule Sets (and adds a few additional rules as well). Or, so it’s always been. But in the latest version of VS and the WDK, these Rule Sets are missing.
So, how do we fix this? Thanks to some help from our friends on the WDK team, we discovered the work around is simple. In the Rule Set Selection box select <Browse…> as shown below:
Then navigate to the CodeAnalysis subdirectory of your WDK install directory (typically example C:\Program Files (x86)\Windows Kits\10\CodeAnalysis\):
And select the Rule Set that you want to add. Having done that, you can check the boxes for the Rule Sets that you want to make active for your driver project. We suggest “Microsoft Driver Must Fix Rules” and also (at a minimum) “Microsoft Native Recommended Rules” as a place to start.
Save these in a *.RuleSet file that you can check-in with your project.
While note quite as handy as being able to just check the “Microsoft All Rules” checkbox, this method allows you (well, it sort of forces you) to consider exactly which CA rules you want to enable for your project. And, because you’re saving a per-project specific Rule Set, you can use these rules to “fine tune” the checks you want to perform. You might even decide to turn on some of those C++ Core Guidelines checks. Maybe. Someday.