I was thinking about this approach (get name in Create and save it in the context), and I’m still wondering if it’s the most efficient way. The reason for my doubts is the comments of Alex Carp (ex-Microsofot, the author of http://fsfilters.blogspot.com) that I read before.
Basically, he’s saying that calling FltGetFileNameInformation every time is better because it handles all possible cases of name invalidation and it internally does the same as manually storing the name in stream handle context. So I’m still confused, should I really do it, or it can make things worse?
Besides, I would still have to defer completion of some operations in cases when the name wasn’t obtained yet. Wouldn’t it be the same as delaying completion with FltDoCompletionProcessingWhenSafe and then call FltGetFileNameInformation in the delayed post-op? (in theory, I’d have to do that just once, since the name is cached).
https://community.osr.com/discussion/comment/214149/#Comment_214149
Knowing when the name has become invalid is not that easy. You listed postCreate and postRename but in my oppinion that’s an oversimplication. What about overwriting renames? Hardlink creation ? Overwriting hardlink creation? Directory rename (which invalidates all the names in all the files under that directory) ? What about setting a short name on a file or directory which might invalidate some names (opened names) but not others (normalized names)? FltMgr’s name caching is implemented to take these cases into account, but keeping a reference to a name obtained at some point in the past doesn’t guarantee that the name is still accurate. Basically, calling FltGetFileNameInformation() every time is the right way to do it because if FltMgr has seen a condition that required invalidation of the name then you’ll get a new name. Also, the name is cached so it won’t cost you much more in terms of performance than keeping your own reference.
https://community.osr.com/discussion/comment/163696/#Comment_163696
Also, storing the name of the file in a stream context does not help in this case. It only works if you don’t care if it’s accurate at all or if you only want to reflect the name of the file when it was created. However, if you want to report the name of the file as best you can at the time operations happen then you have the issues you’ve already found and IMO you are better off using filter manager’s APIs all the time, because the name cache in filter manager is nothing but a stream handle context for the name, with a lot of optimizations.
So now we’ve come full circle :). FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP means ALWAYS look in the cache first, and if the name isn’t there then try to get it from the file system, which is exactly what you would end up implementing if you tried to have your own caching scheme.
Curiously, in one of his comments he links to his own blog post, where he says the exact opposite:
http://fsfilters.blogspot.com/2010/02/names-and-file-systems-filters.html
It is a bad idea to check if the file is interesting by querying and parsing the file name every single time the filters needs to know this. A better design is to cache the information about the file somewhere and then update it only when it changes. Since we are talking about name based policy here, the only place where it can change is in the rename path. Stream contexts are particularly suited for this task and what filters normally do is attach a stream context if the file is interesting. Then, when they need to decide whether the file is interesting or not they can simply get the stream context and if one is present then it is interesting.
The stream context is initialized at create time and is potentially changed at rename. Both these operations happen at PASSIVE_LEVEL. Some filters prefer to query the name when the operation they care about happens, but this approach usually generates more problems that it solves.