Hi to all,
I’m trying to create a minifilter to implement a sort of “low level recycle bin” that work also for files deleted through network shares.
I think different approaches and I’d like to have your feedbacks about.
I think to
1 - capture the SET_INFORMATION FileDispositionInformation operations (for a subset of monitored files) and changing the Information into FileRenameInformation and setting the dirty flag… But I don’t know if it is allowed to change this information.
2 - …Cancel the delete changing DeleteFile flag in the pre-op and issuing a Rename in the (synchronized) post-op with fltSetInformation. but I don’t know if I can open the file with write access during a delete…
3 - …Cancel the delete with delete flag in the pre-op and doing the rename in a safe worker thread.
What do you think is the better way?
Thanks,
F.
> 1 - capture the SET_INFORMATION FileDispositionInformation operations (for
a subset of
monitored files) and changing the Information into FileRenameInformation
and setting the dirty
flag… But I don’t know if it is allowed to change this information.
You can certainly change that. I suspect however that you will find that
the restrictions imposed on FileRenameInformation are completely different
from those imposed in FileDispositionInformation, and because you are
running on the network, this matters. Probably more of an issue is that
fact that network file objects cannot be used once they have had a rename
sent to them so any application which does more than that will suddenly stop
working…
2 - …Cancel the delete changing DeleteFile flag in the pre-op and
issuing
a Rename in the (synchronized) post-op with fltSetInformation. but I don’t
know if I can open the file with write access during a delete…
Or this.
3 - …Cancel the delete with delete flag in the pre-op and doing the
rename in a safe worker thread.
Or this.
In general however I think that all of these problems have some significant
issues.
-
Applications tend to issues SetDisposition (Delete=True) and the
SetDisposition (Delete=False). How will you handle that,
-
There are at least 4 other ways of effectively deleting a file
(Destructive disposition, DELETE_ON_CLOSE, destructive rename and
destructice link creation.
-
And transactions make things really interesting (Is a rolled-back create
a delete?)
-
With any of your posposed situations, the attempt to open a “marked for
delete” file is different with your filter (you will cause
STATUS_OBJECT_NAME_NOT_FOUND when the real answer is STATUS_FILE_DELETED
-
Any there may be much more…
What do you think is the better way?
Off the top of my head (so this will be buggy)
Simulate the filesystem more closely.
- keep a “marked for delete flag” in the stream context
- keep a “marked for delete on close” in the steramhandle context
- keep an open count
in MJ_CLEANUP :
- promote the streamhandlecontext to the stream context
- if the count is zero and the delete flag is set do the rename thing. You
may need a fresh handle for that and that means you may need to squirrel
away enough security context in pre-create to make that work. You may find
other horrible gotchas here as well - like not being able to rename
directories which have files below them open - even though you cannot delete
a directory with contents, there is always a chance that caching has done
something dreadful.
In MJ_SET_FILEINFO
- swallow the SetDisposition and just set the flag. There is a case to
actually bounce the SetDisposition down to the FSD below you and the clear
is (so that the correct tests are done, and so that other clients see the
right thing). Then you need to undelete the file in MJ_CLEANUP before you
rename it…
- Worry about destructive rename
- Worry about destructive link creation
In CREATE
- Depending on whether you send the delete down or not you may or may not
have to police creates so that you can return STATUS_FILE_IS_DELETED
- Worry (if relevant) about destructive creates…
Rod, thank you very much for your feedback,
You give me a good summary of “delete” related issues, and a great suggestion.
In reality I’ve already tried both my 2nd and 3rd solution, in details, filtering operations only for some local directory and only for files having particular extensions (.doc, .txt, .xls, …)
What I want to reach is to have a chance to recover a document after an accidental permanent delete. (Whether this is done locally by a SHIFT+CANC or a delete through network share).
I don’t try the first one because I don’t know if it is allowed to change the information parameter of SET_INFORMATION.
Really you think it is allowed? Docs on msdn explain the dirty flag and let us understand that we can change everithing in FLT_CALLBACK_DATA structure…
Trying the second way, I experienced a sharing error when I opened the same file that is being deleted to issue the rename with fltSetInformation. (both in pre-op cllbk and in post-op).
This can be caused by a reentrancy related issue or simply because of sharing requirement of delete operation?
The third way works… leaving open all issues you explain…
> Off the top of my head (so this will be buggy)
Simulate the filesystem more closely.
- keep a “marked for delete flag” in the stream context
And yes, also transactions
I think that the filter must register itself as RM for this.
–
Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com
> Really you think it is allowed?
Yes, really. You can change pretty much everything in there. That’s why
its there…
> I think that the filter must register itself as RM for this.
FltMgr does this for you, but you have to register with Fltmgr of course…