by QmlsbCBUcm » Fri, 25 Dec 2009 03:22:01
We are doing a encryption/decryption using a minifilter filesystem driver.
To accomplish this, we are catching IRP_NOCACHE on the writes and reads and
processing them before they are written to disk. Instead of writing/reading
the original buffer to disk, we write/read our buffers to a different
location and zero the original buffer so that nothing of importance is
written to the original file. This works pretty well in most cases and seems
to handle system-buffered io and memory-mapped io.
However, we seem to have a problem handling fastio. The problem can occur
in a number of ways but it usually occurs most consistently when we copy a
file over the network and place it within the realm of our driver. In
windows explorer, this operation fails with the message "File does not
exist". Watching the debug output in windbg, we see the following io
operations when the file is created:
1) IRP_MJ_SET_INFORMATION for a truncate operation. (we don't actually
handle this operation because not being written to the filesystem)
2) IRP_MJ_WRITE is received with the FLT_IS_FASTIO_OPERATION (so we do not
process it since IRP_NOCACHE is not set) (also this is where we would
normally create our encrypted files and zero the buffer)
3) IRP_MJ_READ is recieved with the IRP_NOCACHE so we attempt to read from
our encrypted files (they don't exist) and a zeroed buffer is passed on.
4) IRP_MJ_CLEANUP is received and the delete flag is set so we cleanup.
Normally, we always get a write with a IRP_NOCACHE before we get a read but
this doesn't happen. In order to fix this we have tried a couple of
different things. First, we tried to return FLT_PREOP_DISALLOW_FASTIO in our
preoperations to force the filesystem to not use fastio writes/reads. This
resulted in no change in behavior.
Then we tried using the CDO example to map fastio functions to return false
when FastIoCheckIfPossible is used. This resulted in no change and in fact
our mapped functions never seemed to be called. I do know that fastio can
operate outside of the this framework, but I am a little mystified by this
partial handling by our driver.
I'm sure I left an important detail or two out of this description, so feel
free to ask away. My questions to you fine people are:
What is going on here that we cannot seem to handle correctly? Is there a
problem you see with how we go about this? Which of the methods for handling
fastio do you recommend for an encryption/decryption driver?