Prev: STATUS_ACCESS_DENIED causes file deletion (minifilter driver)
Next: Get buffer size of ExAllocatePoolWithTag
From: Bill Treloar on 23 Dec 2009 13:22 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?
From: Don Burn on 23 Dec 2009 13:33 Ask this on NTFSD at http://www.osronline.com that is the list for file system questions, the pro's including the Microsoft folks hang out there. -- Don Burn (MVP, Windows DKD) Windows Filesystem and Driver Consulting Website: http://www.windrvr.com Blog: http://msmvps.com/blogs/WinDrvr Remove StopSpam to reply "Bill Treloar" <BillTreloar(a)discussions.microsoft.com> wrote in message news:81A256AD-BA76-4DE5-B4BB-D863FADABFC5(a)microsoft.com... > 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? > > > __________ Information from ESET NOD32 Antivirus, version of virus > signature database 4712 (20091223) __________ > > The message was checked by ESET NOD32 Antivirus. > > http://www.eset.com > > > __________ Information from ESET NOD32 Antivirus, version of virus signature database 4712 (20091223) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com
From: Maxim S. Shatskih on 23 Dec 2009 14:17
> 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. Very bad idea. The app does not assume that WriteFile call can alter the data, neither MM can assume that this MDL can introduce dirty pages. Make a copy of the buffer and zero it, do not alter the original data in the write path. -- Maxim S. Shatskih Windows DDK MVP maxim(a)storagecraft.com http://www.storagecraft.com |