Thursday, January 16, 2014

Getting Started with Windows File System Filters - What's That INF File For ?

In a nutshell, INF files are files that contain parameters for drivers. There is an MSDN page for INF files in general and then there is a file system filter specific MSDN page. I won't go over the information there, which is very comprehensive, I'd rather focus a bit on how I work with them and what sort of decisions a file system designer might need to make.

In terms of how often does one use the INF files, I use the INF file every time I need to install a new version of my minifilter. My workflow is to rebuild the SYS file and copy it to a location shared with the VM, and then I need the INF to load it. Sometimes I load it by right-clicking the INF file and then clicking on Install:
This is fine when I just want to play with a filter but when actively working on it (when I'm building it 40 times a day) I use a script to load it. It's usually a one-line script but it can grow if I need to initialize other things as well:
rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 128 nullfilter.inf
The magic value "128" is documented on the page for the InstallHinfSection Function. I never need to reboot for development versions of my drivers so 128 works for me. I remove any bits that might require a reboot and if I need to run other services and such I just add more lines to my installation script for that.
Now, for most filters I've ever needed to work on I just take one of the INF files for any of the file system filter samples (nullfilter is the one I use as a template most often, for more advanced usage see simrep and minispy) and I change a couple of things:
  • The driver name. This is pretty much a straight find&replace, but make sure you preserve the case.
  • The LoadOrderGroup. This is the big one. Each file system filter developer needs to pick the right LoadOrderGroup for their filter, depending on what they plan do to. All the various load orders are listed on the MSDN page Load Order Groups for File System Filter Drivers. For an in-depth look at how loading a filter works and how to more closely control the load order see my previous post on Controlling the Load Order of File System Filters. However, at the time of writing the INF all one needs to worry about is the proper LoadOrderGroup.
  • The Class and ClassGuid. This is closely related to the LoadOrderGroup, basically just copy the name and the GUID from the MSDN page File System Filter Driver Classes and Class GUIDs.
  • The altitude. You need to get this from Microsoft, they allocate unique ones for each filter. If you follow the steps on the page Minifilter Altitude Request you should receive your altitude in an email. This might take a couple of weeks or more (AFAIK it's a manual process and each request is reviewed to make sure that the LoadOrderGroup for the filter type makes sense (based on the brief description in the submission form; thus it helps to explain what the filter does fairly clearly, to expedite the process)). But again, I don't think there are any guarantees when it comes to the time, so you want to do this early in the development process and not wait till the last minute. However, when starting development you'll need an altitude to load your filter so what I normally do is just pick an unused one in the right LoadOrderGroup from the page Allocated Altitudes while I wait for my request to be processed. Please keep in mind that this page isn't updated all the often so it's possible that the altitude you picked has already been allocated to someone else. But in general when you get the new altitude it's simply a matter of replacing it in the INF file and you should be good to go. Please make sure to use altitudes that you picked (not allocated by Microsoft) ONLY for development and debugging, you NEVER should to release a filter or share it with customers without a proper altitude from Microsoft.
  • The InstanceFlags. The only documentation I've been able to find for these is in a presentation on Loading and Unloading Minifilters. In short, 1 means 'don't allow automatic attachments' and 2 means 'don't allow manual attachments'. I mostly use 1 during development anyway since I prefer to attach my filter manually to specific drives (generally by adding more lines to the script that loads the driver).
Since I mentioned altitudes here and the fact that you must register your filter with Microsoft and get an altitude from them, there is another process that requires a similar registration with Microsoft. I'm talking about the process of requiring a reparse point. Basically, if you call FSCTL_SET_REPARSE_POINT in your product (assuming you don't set any of the Microsoft reparse points, which are undocumented anyway as far as I know) you need a reparse point tag. There is a page that describes that process, Reparse Point Tag Request and the only other thing you'll need when applying for one of those is a GUID, which you must generate and then use together with the Reparse Point Tag (the one you get back from Microsoft) every time you call FSCTL_SET_REPARSE_POINT. (NOTE: this is only necessary for a very small set of filters and it's not related with the INF file at all, I'm just mentioning it here because it also requires a tag from Microsoft, similar to altitudes, so it's easy to do them both at the same time (if you are one of those filters)).

Anyway, hopefully this page and the links to MSDN documentation will get you going with your INF so that you can finally start working on the actual filter.