A Brief History of WdfVerifier
I'll begin my article set about the Windows Driver Foundation Verifier Control Application, which I've always called WdfVerifier, with a short discussion of its genesis, as this may help in understanding what it is, what it can do for you, and why it is the way it is.
Go back to early 2005, when I have just joined the KMDF QA team and have begun writing my first KMDF test drivers. I didn't start small- my first test required three different drivers- a software bus driver and two software function drivers which were spawned by it. Test code that crashes more often than the product it is testing is an annoying thing to have, so I made sure my code was PreFast clean from the start (and continually update it as PreFast and PFD improve and widen the static analysis net). I also wanted to make sure I whacked these drivers hard with Driver Verifier and the KMDF verification functions.
Well, I'm definitely not the best driver developer on the planet (ask anyone in a position to know), but I try not to use that as an excuse for poor work, so DV- no problem.
But the KMDF stuff- setting registry switches under each driver? Trying to remember new switch names? I'm on the high side of 50, and I'm tired of remembering things like that! I'm also one rotten typist. After wasting hours one day only to find I'd typo'd one of the key names (I'd pasted the name from the documentation, and a trailing blank in the key name was the culprit), I decided I'd save Microsoft some of my future salary and write something that would make this easier to do.
The initial WdfVerifier was a dialog with a dropdown list of known KMDF versions (1.0 hadn't shipped, but we were only fixing important bugs in it). It identified the KMDF version of a driver by examining information the coinstaller left in the WDF/Parameters key, and it decided it was a KMDF driver by looking for that key in the driver's service entry. Selecting a version listed the KMDF drivers known to be of that version. Selecting a driver caused the settings for that driver to be shown. It was smart enough to remember settings for a driver if you switched to another driver, and it only committed changes to the registry when you said to.
It had hardcoded lists of valid flag names for each version (one was documented for 1.0, but as it didn't work as it should have, I left it off the list), and dynamically constructed the UI from that list. All of the check boxes for individual settings were 3-state: when grayed, the registry value was deleted, in the other cases, it was set to 0 or 1 if it was a binary switch. Logic was included to take DWORD settings and only let the grayed and checked states exist. For those settings a numeric edit control was also presented
Because the entire sequence was registry driven, and I test on a lot of machines, I also had the capability to process a machine NETBIOS name from the command line and manipulate said machine as long as I was an admin on it. I've done UI programming almost as much as I have drivers, so I stayed pretty close to good handling as far as when changes were committed.
This was good enough for me, and I used it a lot. As far as I know, nobody else did (people were used to batch files, or coding settings in INF files for tests, etc). One early objection was that my method for detecting drivers couldn't find inbox drivers on Vista (I later found that people cheat a bit on using the coinstaller on multi-driver setups, as well).
I then added the ability to provide command line switches to set the flags on a list of drivers. If you set the magic -inbox switch, then I let you set the flags for a driver I didn't know was a KMDF driver. I never used it myself, but it could have been used for automated tests (DTM is a subsetted version of one of our fundamental automation tools- command lines with substituted parameters are a lot easier than GUI apps).
Still, I'm sure I was the only person that used it. I added V 1.5 as Vista neared, but spending cycles adding to a "good enough for me" tool isn't something I'd do.
That problem sounds familiar...
Then people began adopting KMDF in earnest, and as a part of that process, I would occasionally try to steer people on mailing lists through setting up the KMDF verifier. When one of them made exactly the same (since forgotten) error in pasting a switch name from the documentation, I sent an email to the group. For a reasonably accurate paraphrasing- "Devs are wasting time initially trying to set up the verifier- as lame and uninspired as WdfVerifier is, it at least makes that task easier". I was surprised- Eliyas and Doron thought it would be a good idea to whip it into better shape and put it into the WDK!
But my next problem is even more familiar- the deadline for adding such content is fast approaching, so whatever I do to make it a better tool has to be done in a small timeframe.
Groupthink ain't so bad
A few things were just plain obvious:
- those tri-state boxes would confuse anyone at first- they were nice as they let me completely control the state of the registry, but they weren't needed to help someone work on their driver.
- If we wanted to reach new people, using the switch names wasn't terribly friendly.
- The version-based subsetting of the drivers list was wrong (because the settings for the latest KMDF version installed are what matter, and the switch set has so far been very stable).
- When I designed it, all switches were DWORDs, and that was implicit in the internal design- but TrackHandles is REG_MULTI_SZ...
- Some other switches (which existed, but hadn't been documented at the time I wrote it) were only relevant on Win2K.
I began with those issues (I was able to encode the handles in a DWORD because we had fewer than 32 object types- eventually that will break, but it can be fixed in a non-crisis mode or at least as a known issue), and had a demo version- the UI was still dynamic, but we now listed the inbox drivers and there was something a little more explanatory for the individual controls. This went before the dev, test, and PM teams for a review, and I got excellent feedback.
In response to that, I added code to use the service API and identify when a driver was running (because changes to these settings on a running driver mean it must be loaded and unloaded). I made the UI a property sheet with the old KMDF dialog as one page, and added a new page for UMDF- this listed a few documented switches, and showed the PIDs for running host processes (but not for remote machines). I added maxima / minima and logic to enforce them where needed. I added the ability to modify the WDFLDR diagnostics output. I changed some of the interactions so that, for instance, when you change a setting that requires other settings, those settings are also reflected in the UI. I got more ambitious requests, but deferred them for the next product cycle, as I couldn't do them in time without breaking what was at least a working tool that should satisfy an obvious need.
The Hair of the Dog What Bit Ya
This went for round two. The command line was horridly complicated, and nobody liked it. I decided that not even I had used it, so I got rid of it entirely. There was some tweaking of the UI, and since I no longer had a command line (which suppressed the UI), I made it a real Windows app, and added a manifest so it would elevate properly on Windows Vista.
This was the app that appeared in the Server 2008 Beta WDK earlier in 2007. I also wrote the initial draft of the documentation which appeared there.
Round two
There were a bunch of really good ideas that I couldn't get to. I thought they would have to wait for the next version of Windows because the guidelines for adding content to server 2008 I could never meet. But the WDK was now treated as a separate product, and the guidelines there were more conducive to adding features to test tools.
So I was able to add some of the coolest ideas in the (soon to appear) 2008 RC / Vista SP1 WDK version.
- I added code to identify how a KMDF driver was used with respect to known devices. If a driver is a function or filter driver for a device node, I list the associated instance IDs in the UI.
- I added a mechanism that lets you set multiple drivers to the same setting (Specifically you use one as a template and "paste" them to the others).
- I added code to automatically determine which device stacks needed to be disabled and re-enabled when KMDF settings were changed. It will even reboot the machine if that is the only way to make them stick.
- I added the ability to turn on DbgPrint spew when the target machine is running Windows Vista.
- I added tool tips for virtually every single control on every dialog.
- I added a "Preferences" tab so you could control the tool tips, and the response to changes- for example, if you like letting it reboot when it has to, it will- if you want it to ask, it will- if you never want it done, it won't.
- I added much more control to UMDF drivers.
- I integrated debugging support for UMDF drivers- the application can detect the most common configurations of the Debugging tools For Windows and will automatically use those debuggers.
- You can attach to a running UMDF process at the push of a button (slightly dangerous for reasons I'll post at a later date).
- The app will automatically attach a debugger if it sees a new UMDF host process launch, and the UMDF settings say a debugger is expected to be present.
- You can configure debugger command lines, and even specify your own debugger (it has to be able to handle a PID).
- I made most of the changes needed to localize the application if need arises.
This went through a similar review- since I had more time to do a proper job and had already collected a lot of feedback, the reviews left me with few work items.
Soon, though- we'll see. I think it is a more useful tool than what I had originally. But the user community will decide what use it is or not...
On the assumption that it does get used, I'll be posting some more detailed how-to's. I just thought the history might explain some of the quirkier aspects of it- most tools get a more disciplined design phase than this one got- it's a bit seat-of-the pants.