Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

File System Redirector

Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
Hello,

I am trying to do at file system level, what subst.exe does. From user
space point of view, I have 2 drive letters, let's call them C: D:. I
wish that every file access that references D:, to go to another
directory on the C drive, like C:\foo.

D:\ -> C:\foo\
D:\bar -> C:\foo\bar

I wish to log every file I/O to D, and not log file access that is
done through C:\foo. When I mean `not log' I mean that I wish that my
logging filters won't run at all on the real volume, not that there's
some check in the filter that tells it to log only a specific
directory. That is, I wish my filters to reside only on D, and somehow
file I/O to be ultimately redirected to C:\foo.

I create a virtual volume (RamDisk) that gets a new drive letter and I
format it as NTFS. It's not used directly for file system operations,
I just create it so I can have something my filter driver can attach
to. I wish to implement a file system minifilter that does the
operations described above. From my understanding this can be done in
3 ways:

1) Filter IRP_MJ_CREATE, IRP_MJ_READ, IRP_MJ_WRITE and associated
stuff, do the file I/O on the real target myself in the filter, copy
data to necessary buffers and complete the I/O in the filter. This is
very hard to do right, a lot of code to write, security is very
complicated (you can do in your filter anything, while you should do
only what the caller could do). I don't think I'll do this, I post it
here just for reference.

2) Filter only IRP_MJ_CREATE, modify the target paths and return
STATUS_REPARSE. This is easier to do and there is no need to think
about security (it just works right). However, the problem is that
since I return in the filter, and since I don't return the real stuff,
my logging filters attached to the virtual volume will either see
bogus stuff in the completion routine if the redirect filter is below
the logging filter, either nothing if it's above the filter. This is
not good.

3) Filter IRP_MJ_CREATE, IRP_MJ_READ, IRP_MJ_WRITE and associated
stuff, the change FLT_IO_PARAMETER_BLOCK::TargetFileObject and
FLT_IO_PARAMETER_BLOCK::TargetInstance. I don't understand this yet.
It seems like I need another filter (same filter?) on the target
volume, which kind of defies the point of doing this, plus I am not
sure how it will interact with the logging stuff.

What (else) do you recommend?

Thanks,

--
Aram Hăvărneanu

Comments

  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Wed, Aug 25, 2010 at 10:11 AM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > I wish that every file access that references D:, to go to another
    > directory on the C drive, like C:\foo.
    >
    > [...]
    >
    > 3) Filter IRP_MJ_CREATE, IRP_MJ_READ, IRP_MJ_WRITE and associated
    > stuff, the change FLT_IO_PARAMETER_BLOCK::TargetFileObject and
    > FLT_IO_PARAMETER_BLOCK::TargetInstance. I don't understand this yet.
    > It seems like I need another filter (same filter?) on the target
    > volume, which kind of defies the point of doing this, plus I am not
    > sure how it will interact with the logging stuff.

    Actually, from my understanding, if I wish to go this path, I think I
    only need to filter IRP_MJ_CREATE. Is
    FLT_IO_PARAMETER_BLOCK::TargetFileObject relevant in other operations
    except IRP_MJ_CREATE? I can't find anything in the docs, but that was
    my conclusion after reading list archives. Please correct me if I am
    wrong.

    The docs state when I can change TargetInstance. It seems my filter
    needs to reside on the target volume too (obviously I can configure it
    differently for PassThrough operation, so it doesn't do anything but
    serve as a proxy). What I don't understand is who will receive the
    completion notification. If I have the following design (simplified
    for clarity):

    D -> [ logging filter ] -> [ redirect filter D ] -> [ NTFS ] -> [ Bogus Volume ]
    C -> [ redirect filter C ] -> [ NTFS ] -> [ Real Volume ]

    Where [ redirect filter D ] does the I/O redirection to [ redirect filter C ].

    1) Will [ redirect filter D ] receive completion notification or
    (only) [ redirect filter C ]?
    2) Will [ logging filter ] receive completion notifcation (after I/O
    has been redirected)?

    Hope you will clarify my doubts regarding this design. If everything
    works as I understand it now, it should be easy to implement.

    Thanks,

    --
    Aram Hăvărneanu
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    Hmm. No suggestions?

    On Wed, Aug 25, 2010 at 12:33 PM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    > On Wed, Aug 25, 2010 at 10:11 AM, Aram Hăvărneanu <xxxxx@mgk.ro> wrote:
    >> I wish that every file access that references D:, to go to another
    >> directory on the C drive, like C:\foo.
    >>
    >> [...]
    >>
    >> 3) Filter IRP_MJ_CREATE, IRP_MJ_READ, IRP_MJ_WRITE and associated
    >> stuff, the change FLT_IO_PARAMETER_BLOCK::TargetFileObject and
    >> FLT_IO_PARAMETER_BLOCK::TargetInstance. I don't understand this yet.
    >> It seems like I need another filter (same filter?) on the target
    >> volume, which kind of defies the point of doing this, plus I am not
    >> sure how it will interact with the logging stuff.
    >
    > Actually, from my understanding, if I wish to go this path, I think I
    > only need to filter IRP_MJ_CREATE. Is
    > FLT_IO_PARAMETER_BLOCK::TargetFileObject relevant in other operations
    > except IRP_MJ_CREATE? I can't find anything in the docs, but that was
    > my conclusion after reading list archives. Please correct me if I am
    > wrong.
    >
    > The docs state when I can change TargetInstance. It seems my filter
    > needs to reside on the target volume too (obviously I can configure it
    > differently for PassThrough operation, so it doesn't do anything but
    > serve as a proxy). What I don't understand is who will receive the
    > completion notification. If I have the following design (simplified
    > for clarity):
    >
    > D -> [ logging filter ] -> [ redirect filter D ] -> [ NTFS ] -> [ Bogus Volume ]
    > C -> [ redirect filter C ] -> [ NTFS ] -> [ Real Volume ]
    >
    > Where [ redirect filter D ] does the I/O redirection to [ redirect filter C ].
    >
    > 1) Will [ redirect filter D ] receive completion notification or
    > (only) [ redirect filter C ]?
    > 2) Will [ logging filter ] receive completion notifcation (after I/O
    > has been redirected)?
    >
    > Hope you will clarify my doubts regarding this design. If everything
    > works as I understand it now, it should be easy to implement.
    >
    > Thanks,
    >
    > --
    > Aram Hăvărneanu
    >



    --
    Aram Hăvărneanu
  • Alex_CarpAlex_Carp Member Posts: 1,016
    I haven't looked at this in a while, but from what I remember, your filter wouldn't see the request twice. Only the instance on volume D would see it and then the operation would be send to minifilters below the instance you have on volume C. The instance on volume D should receive the completion notification (basically your instance on volume C is used as a reference point on where to insert the IO in the other stack). However, you specifically stated that one of the requirements of your design is to not have a minfilter attached to volume C at all...

    Now, again, my memory is a bit sketchy on the subject so please try and validate this.

    Also, IIRC, if you redirect IRP_MJ_CREATE in this manner then subsequent operations on that FILE_OBJECT will be automatically redirected by the IO manager. This might not be what you want, as it is basically the same as a STATUS_REPARSE.

    Another problem with this approach is that you might run out of IO_STACK_LOCATIONs in the IRP since you would be effectively be taking an IRP from one device stack and sending it to another.

    Looking at your original mail, your goal seems to be "...trying to do at file system level, what subst.exe does. " and you have the additional requirement that "my logging filters won't run at all on the real volume ". I don't have a better solution than to redirect each IO operation (redirecting IRP_MJ_CREATE either with STATUS_REPARSE or with TargetInstance will send subsequent operations directly to the target volume (at least as far as I remember)), which I'm afraid is the more complicated approach that you've already suggested in your original mail.

    Perhaps you could explain what it is you are trying to do at a higher level (i.e. "log access to a file for security purposes" or "keep track of all modifications to files for back-up purposes").

    Thanks,
    Alex.
  • Aram_Havarneanu-2Aram_Havarneanu-2 Member Posts: 161
    On Fri, Aug 27, 2010 at 7:08 PM, Alex Carp <xxxxx@gmail.com> wrote:
    > Looking at your original mail, your goal seems to be "...trying to do at file system level, what subst.exe does. " and you have the additional requirement that "my logging filters won't run at all on the real volume ". I don't have a better solution than to redirect each IO operation (redirecting IRP_MJ_CREATE either with STATUS_REPARSE or with TargetInstance will send subsequent operations directly to the target volume (at least as far as I remember)), which I'm afraid is the more complicated approach that you've already suggested in your original mail.

    What is the minimum set of I/O operations I need to support?

    I obviously need IRP_MJ_CREATE for opening files, IRP_MJ_READ and
    IRP_MJ_WRITE for reading and writing files, and
    IRP_MJ_DIRECTORY_CONTROL for directory listings. Is everything else
    optional?

    Isn't it possible to generate IRPs directly in my driver (as opposed
    to the I/O manager) by creating a new IRP, copying the old IRP
    (obviously changing what's relevant) and then letting it go instead of
    doing file I/O the `classic' way (with FltCreateFile)? I am not sure
    how FastIO will interact with this (maybe I can disable FastIO?).

    --
    Aram Hăvărneanu
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Developing Minifilters 29 July 2019 OSR Seminar Space
Writing WDF Drivers 23 Sept 2019 OSR Seminar Space
Kernel Debugging 21 Oct 2019 OSR Seminar Space
Internals & Software Drivers 18 Nov 2019 Dulles, VA