Get Normalized name when FltGetFileNameInformation fails

@Dejan_Maksimovic said:
You must not synchronize READ/WRITE requests.

Can’t I synchronize just once request? The name will get cached and I won’t need to synchronize next time. And I’m not going to synchronize paging IO.

Try a test version which DbgPrints exact locations, cases and error
codes returned when FGFNI fails.

That’s a good idea and I will try it, but it’s not that easy because the errors occur on numerous client’s machines that I don’t always have access to.

I doubt FltDoCompletionProcessingWhenSafe would not post to a queue
where FGFNI call is safe in cases where the call itself fails.

Why would it fail if it’s safe?

That’s a good idea and I will try it, but it’s not that easy because the errors occur on numerous client’s machines that I don’t always have access to.
WPP might help you there.

First let me address a point of confusion. When I said **It is a bad idea to check if the file is interesting by querying and parsing the file name every single time ** what i meant was that if you have the kind of driver that does something path based (say, tracks the number of times files that are in the subdirectory of …/blah/… are accessed) then instead of calling FGFNI every time and then running a regular expression that checks that the path matches ./blah/. one should do this ONCE and then remember whether the file was IN or OUT (and update when the path can change). Read that paragraph again, you’ll see that it discusses using a StreamContext to see if should track the file or not (and not even anything IN the StreamContext, just the mere presence of the StreamContext).

As to whether you should cache the name yourself or just call FGFNI, I’ve already stated my preference to just calling FGFNI and using its built in cache. The cache is already designed to only be invalidated when necessary and it is, in my view, difficult to do better.

Finally, synchronizing the kinds of operations where FGFNI will fail because it’s not safe to query the name is probably a bad idea.

I think it’s helpful to think about FGFNI as something that’s trying to help you make the right decisions and not something that randomly fails. So instead of trying to “just get the name on every single operation” realize that it’s not always possible to do so in a safe way and design your driver to handle that case. For example, in such cases, do something else like take a reference on the FileObject and query the name asynchronously later or something. It’s hard to come up with a generic approach because it depends on the type of product the driver is for.

I’d like to use an analogy to explain the point here: If when driving you need to pass but you’re in a NO PASSING zone, you can still pass, but it’s not safe to do so and if you ALWAYS do it, sooner or later you’ll be in trouble. You can certainly complain that you don’t think it should be a NO PASSING zone and that the people that designed the road system were not helpful but the reality is that if you chose to do it, you’ll run into something sooner or later. And in the world on filesystems, you’re designing an algorithm that does the driving and customer machines have different sets of drivers of different versions and so if it works on your test track it doesn’t mean it will work safely on every single road out there.

My advice here is to simply try to find a safe work-around for when FGFNI fails.

Best,
Alex

Alex, thank you for the detailed response and clarification.

I realized I can still call FltGetFileNameInformation every time, but in addition to that, also call it in post-create to ensure the name is cached from start, so that the filter manager doesn’t have to query filesystem when it’s not safe.

And those rare cases when I don’t see Create, can be handled asynchronously as you suggest.

Few days ago while testing my driver I saw FGFNI (normalized + always allow cache) returned STATUS_ACCESS_DENIED in pre-Set FileBasicInformation (called by the System process to many dlls). I didn’t call FGFNI in postCreate at that time. The error was consistent, occurred regulary many times but it has disappeared after reboot (because of windows update maybe?), and I can’t reproduce it anymore. It was Windows 10.

It seemed like the file wasn’t opened with enough rights to query name, I’m not 100% sure though. I’ve tried to test such case manually without success.

Now I’m wondering if FGFNI can fail for reasons besides TopLevelIrp or IRQL, and if it can, can it also fail in postCreate (assuming the create has succeeded)? Or maybe it’s not supposed to and it was just a bug?

As a rule, FGFNI can only fail in post create if the caller does not
have Traverse rights. But I think that does not happen on W8/W10, as
the FltMgr can query the FS for a file name then.
If the create was not successful though, it can fail due to traverse rights.

You will often see FGFNI fail in SetFileInfo for a lot of files, due
to either top level IRP being nonNULL or it being a paging I/O call
(which should set the TLI field).

You CANNOT post a query for the latter case.

On 3/19/19, bkmz wrote:
> OSR https://community.osr.com/
> bkmz commented on Get Normalized name when FltGetFileNameInformation fails
>
> Few days ago while testing my driver I saw FGFNI (normalized + always allow
> cache) returned STATUS_ACCESS_DENIED in Set FileBasicinformation (called by
> the System process to many dlls). I didn’t call FGFNI in postCreate at that
> time. The error was consistent, occurred regulary many times but it has
> disappeared after reboot (because of windows update maybe?), and I can’t
> reproduce it anymore. It was Windows 10.
>
> It seemed like the file wasn’t opened with enough rights to query name, I’m
> not 100% sure though. I tried to test such case manually without success.
>
> Now I’m wondering if FGFNI can fail for reasons besides TopLevelIrp or
> IRQL, and if it can, can it also fail in postCreate?

Remember to that FltGetFile… can require a transit through every lower filter (on the stack not via a callback). This is via the Name provider API.

Each of NameProvider is at liberty to fail the request in any way it feels is suitable.

Coop is a beast in its own right. You will need lorazepams when you
first start testing with antivirus filters :slight_smile:
But other name providers are fairly rare. Antiviruses are present everywhere :frowning:

Remember to that FltGetFile… can require a transit through every lower
filter (on the stack not via a callback). This is via the Name provider
API.

Each of NameProvider is at liberty to fail the request in any way it feels
is suitable.

I’ve seen FGFNI for normalized names fail on system files (e.g. $Extend\Bloop\Blortz) because the file system won’t let FltMgr open some part of the path. Our fallback is usually to query for the opened name.

That’s usually in the paging read/write path though and not in the SetBasicInformation path, I’d be interested to see the flags and top level IRP values when you get this error.