Layered FSD with Reparse question

I’m in the midst of a large project and determined that I need a shadow FO like system. I’ve written both filters and fsd, just nothing as complex as what is need in this circumstance.

Can some please tell if I am going down the correct path with this logic:

In my filter PostCreate if I see a STATUS_REPARSE (or even a CREATE/SUPERSEDE) I:

  1. Read an id from the reparse header or create and id
  2. Create a “shadow” FO for that on my FSD virtual device
  3. Cancel the original open
  4. Set Iopb->TargetFileObject to the shadow FO
  5. set IoStatus->Status to STATUS_SUCCESS
  6. set IoStatus->Information appropriately
  7. return FLT_POSTOP_FINISHED_PROCESSING

At this point my filter pretty much steps out of the way and the FSD components handle the I/O from then on, with the exception of a few record keeping items collect in a STREAM_CONTEXT on the FO. Other than that are there any obvious objects to this concept that anyone can see?

Each file system instance has an FDO that a filter stack is built on top of. I do not think it is okay for you to replace the file object post-create (or for that matter pre-create) with a file object that represents a file on a different filesystem (different FDO, different filter stack). I think you need to detect the scenario, and then replace the return code with STATUS_REPARSE as well as the path with something like \device\myvirtualfs1\some\path. Then the Io Manager will reissue it to the appropriate filter stack allowing all involved filters to play nice with you. Alternatively, the mini-filter system allows you to replace the TargetInstance with another instance of your filter attached to some other filesystem (your shadow?). It seems like this would ultimately generate the same behavior; the io would need to be reissued by the IoManager/FltMgr to send the Pre-Create with the correct FS stack information to all filters that are supposed to see it. Also, I think in some versions of FltMgr, there is something about this that prevents driver unload (a bug mention i saw in another forum post here).

Could you please explain why you need a shadow file object filter ?

Also, there is no point in changing the TargetFileObject on the way back up (i.e in the PostOP). It has no effect on anything. TargetFileObject is better left alone as a redirection mechanism, it has pretty serious issues.

Perhaps you could explain what you are trying to do ? If you simply wish to open a file on a different volume or a different file on the same volume then TJ’s solution is usually good enough (return STATUS_REPARSE). If you have a different goal in mind, could you please explain what it is ?

Thanks,
Alex.

The purpose of the shadow file is basically so I can managed the cache, etc. For some files, some or all of the data will reside elsewhere and therefor I need to use the layered fsd approach to maintain cache consistency. TJs example is the classic simple case of redirection which I fully understand but does not apply here for certain.

Other items I have to ensure are filesize, etc. It possible that some data written to the file will not end up in stream itself, but elsewhere on the volume, soI need to make all of the other attributes are kosher.

Well, the rules for an SFO filter (at a high level) are:

  1. you need all FOs on the system to be created by IO manager
  2. you must make sure that a FO is NEVER seen below its layer.

The approaches i’ve seen usually achieve this by issuing a FltCreateFile in preCreate and then complete the original create at their level. This ensures that the FO on the original create is not seen below its layer (because the minifilter completes the create) and that the second file object (the SFO) is created by the IO manager. You could do this in a postCreate if you got STATUS_REPARSE back, since the FO isn’t initialized yet. However, once you claim ownership for it (by returning STATUS_SUCCESS on a create) it must never leak below.

The issues with the original approach you’ve outlined are:

  1. if you see STATUS_REPARSE in postCreate, you don’t need to cancel the original open because the file isn’t opened.
  2. setting Iopb->TargetFileObject to the shadow FO achieves nothing. You need to allocate your own FCB-like structure (make sure to use the FSRTL_ADVANCED_FCB_HEADER) and that’s where you keep your context for your FO and remember the FO to SFO mapping. Setting anything in the Iopb in the postOp path is useless because FltMgr design guarantees that filters will see the same parameteres in the postOp that they’ve see in the preOp, so your changes would simply be ignored.
  3. your filter cannot step out of the way since from the FS’s perspecive the original FO is still invalid and any operation on that one will probably bugcheck the machine. You need to catch all those requests and try to satisfy them using the SFO and whatever internal logic you have.

Does this make sense ?

Thanks,
Alex.