Dear members of the ntfsd mailing list,
I am using a Kernel Mode minifilter driver in one of the most unlikely scenarios -
providing global photorealistic terrain to Microsoft’s Flight Simulator X. It’s a
noncommerical project, a hobby so to say. The project works fine on Windows XP
so far and is well received by testers. I am not an experienced kernel mode driver
programmer yet - this is my first endeavour in this direction.
Let me quickly explain how the driver works before I describe my problem that I see
on Windows Vista.
I use a driver to modify the content of BMP (bitmap) files on disk as they are read by
an application (fsx.exe). If the BMPs don’t exist yet or the level of detail is below the
requirement, I pass the filename on to a userspace application which downloads and
the files from the Internet . The filter driver then makes the BMP files appear at any
required detail level (resolution, and thus file size) depending on distance to the aircraft:
My project is based on the “scanner” minifilter sample by Microsoft. The following
essential operations (among others) are performed by the driver for BMP files that
meet certain filename requirements. All other I/O is handled transparently.
* In IRP_MJ_NETWORK_QUERY_OPEN (Preop) I provide a modified file size for the file on
disk. Turns out the flight sim uses this information to determine whether a file exists
or not. I provide the intended file size here as well.
* In IRP_MJ_QUERY_INFORMATION (Preop) I intercept queries for FileStandardInformation and
return the intended file size for the BMP file.
* In IRP_MJ_READ (Preop), I satisfy read calls to the file contents with bitmap header
and data in the intended resolution.
Note that the file size of the BMP and contents as provided by the filter driver may
differ from the file size and content on disk! That seems to be one cause of my problem.
The content as seen by the application is *volatile* after going through the filter driver,
however the Cache Manager in the Windows Kernel assumes it can cache both the file size
and the file contents. If the aplication explicitly requested non-cached I/O, this
would not be a problem. But the application (Flight Simulator) uses CreateFile() with
standard parameters, and that triggers the Cache Manager.
Nevertheless the filter has worked fine on Windows XP so far, users are happy.
However on Windows Vista I am seeing some problems. That is some reads seem to
bypass the Minifilter driver and are serviced directly by the Cache Manager. Bad thing.
The contents of the BMP files need to keep changing to increase level of detail as
aircraft nears a given terrain tile. However when CacheManager satisfies the reads,
the content is static. It works most of the time, but some terrain tiles are getting
corrupted or remain blurred (low detail).
At first I suspected the SuperFetch feature of Vista to be responsible. But that appears
not to be the problem. A “net stop superfetch” command did not help out. In particular
I would like to know why Vista shows so different behavior to Windows XP although both
systems have the Cache Manager.
Before you point out the obvious, that is “Get Mark Russinovich’s Book Windows Internals
and learn the delicacies of Paged I/O, Memory mapping and the Cache Manager”, I would
like to hear an opinion whether my approach is totally insane and not workable, or whether
a slight modification could make the thing work on Vista. (By the way, I have just
ordered the above book for further studies.)
Can a minifilter driver tell the upper layers to not cache the returned data - or does
only the filesystem have this power? The intended effect is similar to an application
using CreateFile() with FILE_FLAG_NO_BUFFERING at the application level.
I cannot really change the application’s behaviour unless I hooked into the running
process and changed the respective CreateFile() calls to use nonbuffered I/O exclusively.
If I can’t solve the problem at the driver level, this is going to be my last resort -
kind of hacky though.
Christian