I’m developing an encryption filter based on minifilter.
As I have learned, the most popular way is to create a shadow FileObject and use the second FCB to finish encryption work. But when I try to do the work in this way, I found there are some problems if done with Double FCB:
If I just create a shadow FileObject for the same file, what if the share access was not allowed?
If I create a new tmp file(finally the tmp file will be renamed to the origin one) and create a FileObject for it as the shadow FileObject, how can I handle the condition that program just change piece of data?(e.g. add content to the end of file)
I’m not sure what “double FCB” here means. The way this is done with an isolation filter (using shadow file objects) is that the first file object (passed into the filter) has its own control structures (so the FCB/SCB is defined by the filter, and the SOP may be different if the application view differs from the underlying physical file view).
You are responsible for dealing with sharing issues. The cleanest way is to simply use the same sharing when you pass the IRP_MJ_CREATE down (with your shadow file object) and let the file system sort it out. But you aren’t opening the file twice - just once, using the shadow file object.
That’s why you need a separate SOP. So that the view for the application is different than the view for the physical file. When you see the paging I/O operation for the application file object, you adjust it as necessary to retrieve the correct data from the file system (using the shadow file object). That may involve adjusting offsets, decrypting or encrypting data, changing file attributes, etc.
Hey Tony, thanks for your response.
But I still do not understand what do you mean by opening the file only once. The way I create the shadow file object is using FltCreateFile in the post routine of IRP_MJ_CREATE, so plus the origin file object, isn’t it opening file twice?
No, you use IoCreateStreamFileObjectEx to create the shadow file object. Then you switch the original file object with the shadow file object and permit the create to proceed to the FSD. There is only a single create operation - you’re substituting the orginal file object with your shadow file object.
Another way is to just do everything in pre-create (roll your own FO back
to the caller, create the SFO using FltCreateFile and set the contexts) and
return COMPLETE so the original request doesn’t go to the FSD. Tony, I’d
be interested to hear the drawbacks to this approach vice your method of
IoCreateStreamFileObjectEx.
On Thu, Sep 11, 2014 at 1:04 AM, Tony Mason wrote:
> >
> > No, you use IoCreateStreamFileObjectEx to create the shadow file object. > Then you switch the original file object with the shadow file object and > permit the create to proceed to the FSD. There is only a single create > operation - you’re substituting the orginal file object with your shadow > file object. > > Tony > OSR > > > — > NTFSD is sponsored by OSR > > OSR is hiring!! Info at http://www.osr.com/careers > > For our schedule of debugging and file system seminars visit: > http://www.osr.com/seminars > > To unsubscribe, visit the List Server section of OSR Online at > http://www.osronline.com/page.cfm?name=ListServer >
I suppose that I’m just used to the stream file object trick, though there is at least one advantage using FltCreateFileEx2: you don’t have to worry about that annoying file object extension area being created properly - this is where important things like the “ignore share access check” bit is set.
I had to go look and see what we’re currently using in our Isolation framework: indeed, it’s FltCreateFileEx2. We’re not using IoCreateStreamFileObject* at this point (though we have in the past).
In either case, only one create gets sent down to the underlying FSD. Thus, there’s no sharing issue (at least not between the original create and the mini-filter’s second create).
Of course, the developer still has to deal with destructive creates potentially. In addition you have to re-translate"stuff" in the CBD structure into the correct flags for the new call to FltCreateFile*: case sensitivity (that goes back into the object attributes), share access ignore mode (which you ask the I/O Manager to extract from the file object extension for you via IoIsFileObjectIgnoringSharing - on the original file object), etc. So FltCreateFile* isn’t that easy either.
So I need to create a SFO in the pre-create and save it in the context of the origin FO, and later when I catch the IRP whose TargetFileObject is origin FO I can switch it with the SFO which has been stored in the context of the origin FO?
But if the origin FO was not created, how can I use StreamHandleContext for it?
> So I need to create a SFO in the pre-create and save it in the context of > the origin FO, and later when I catch the IRP whose TargetFileObject is > origin FO I can switch it with the SFO which has been stored in the context > of the origin FO? > But if the origin FO was not created, how can I use StreamHandleContext > for it? > > — > NTFSD is sponsored by OSR > > OSR is hiring!! Info at http://www.osr.com/careers > > For our schedule of debugging and file system seminars visit: > http://www.osr.com/seminars > > To unsubscribe, visit the List Server section of OSR Online at > http://www.osronline.com/page.cfm?name=ListServer >
At that point *you* own that file object. So you don’t need a stream handle context: you own the FsContext/FsContext2 pointers.
FsContext: set it up to use the FSRTL_ADVANCED_FCB_HEADER inside your own data structure. That’s the equivalent of a Stream Context. In fact, when you initialize your FCB/SCB properly, you’ll let filters above you attach stream context (and stream handle context) to the file object - and when you tear it down, you’ll (indirectly) tell them their context is going away.
FsContext2: set it up to point to whatever you want. This is the FSD equivalent of a stream handle context.