Backporting normalized path routines to support FLT_FILE_NAME_NORMALIZED functionality in the existi

Ok, as you might have seen from my last post, I am having some difficulties with ensuring I have a clean long file name in my filter driver.

In the new Filter Manager you can use FLT_FILE_NAME_NORMALIZED with FltGetFileNameInformation() to get a fully normalized filepath which includes expanding all SFN to LFN and ripping all :$DATA from the stream name. This works great, and its one of the things that compelled me to look at the new filter manager at the last Driver DevCon.

However, I find myself needing to backport some code I have to my existing driver framework, which doesn’t have this luxury. And quite frankly, I am lost in doing so.

I originally thought I could use ZwQueryDirectoryFile. With thanks to Neal Christiansen he reminded me that such an approach would be a bad idea since I would have recursive IO which could be a problem. Especially since I am doing this during entrance to my function handler for IRP_MJ_CREATE. The recommendation was to roll my own query directory IRP and handle it properly.

Does anyone know of any snippets of code in the IFS kit or online that does this? I really want to understand the right way to do this, and do so without significantly impacting the performance of the system. (I am going to have to do this for every filepath that enters my create function) I am guessing I need to roll IRP_MJ_DIRECTORY_CONTROL with IRP_MN_QUERY_DIRECTORY, using FILE_BOTH_DIR_INFORMATION. I would need to break up the path in the irpSp->FileObject->FileName and then loop through, calling against the previously built path. ie:

Assuming I have \Device\HarddiskVolume1\MYDOCU~1\MYREAL~1.txt which should be normalized to \Device\HarddiskVolume1\my documents\myreallylongfile.txt

Iteration1: \Device\HarddiskVolume1\MYDOCU~1
Iternation2: \Device\HarddiskVolume1\my documents\MYREAL~1.txt

etc, etc. Depending on depth of path. Is that correct? How does that handle “.” and “…” within a path? Is there not some way to get this all converted in one pass without having to fire it to usermode and calling GetLongPathName()?

Basically I need a FltGetFileNameInformation() function I can call in the existing IFS kit. How the heck can I do that? I can’t be the only one that has had to deal with normalized LFN.

Pointers to help docs and online resources that cover this would be a great help. As would code snippets to get me on the right track.

Thanks in advance.


Regards,
Dana Epp
[Blog: http://silverstr.ufies.org/blog/]

For each component of the path
{
if (RtlIsNameLegalDOS8Dot3 == TRUE)
{
Open the parent directory
Query for FileBothDirectoryInformation
Close the parent directory
Add the long name to the long path
}
else
{
Add the name to the long path
}
}

Your recursion problems won’t typically be in
ZwQueryDirectoryFile. They will be in ZwCreateFile.
Read the OSR FAQ to see how to handle this.

On NT the same stuff gets opened over and over. So it
seems that even rudimentary caching might help.

If you still think that you need to roll your own
query IRP, let me know and I can send you an example.
It is one of the easy ones to do.

Randy

— Dana Epp wrote:

> Ok, as you might have seen from my last post, I am
> having some difficulties with ensuring I have a
> clean long file name in my filter driver.
>
> In the new Filter Manager you can use
> FLT_FILE_NAME_NORMALIZED with
> FltGetFileNameInformation() to get a fully
> normalized filepath which includes expanding all SFN
> to LFN and ripping all :$DATA from the stream name.
> This works great, and its one of the things that
> compelled me to look at the new filter manager at
> the last Driver DevCon.
>
> However, I find myself needing to backport some code
> I have to my existing driver framework, which
> doesn’t have this luxury. And quite frankly, I am
> lost in doing so.
>
> I originally thought I could use
> ZwQueryDirectoryFile. With thanks to Neal
> Christiansen he reminded me that such an approach
> would be a bad idea since I would have recursive IO
> which could be a problem. Especially since I am
> doing this during entrance to my function handler
> for IRP_MJ_CREATE. The recommendation was to roll my
> own query directory IRP and handle it properly.
>
> Does anyone know of any snippets of code in the IFS
> kit or online that does this? I really want to
> understand the right way to do this, and do so
> without significantly impacting the performance of
> the system. (I am going to have to do this for every
> filepath that enters my create function) I am
> guessing I need to roll IRP_MJ_DIRECTORY_CONTROL
> with IRP_MN_QUERY_DIRECTORY, using
> FILE_BOTH_DIR_INFORMATION. I would need to break up
> the path in the irpSp->FileObject->FileName and then
> loop through, calling against the previously built
> path. ie:
>
> Assuming I have
> \Device\HarddiskVolume1\MYDOCU~1\MYREAL~1.txt which
> should be normalized to \Device\HarddiskVolume1\my
> documents\myreallylongfile.txt
>
> Iteration1: \Device\HarddiskVolume1\MYDOCU~1
> Iternation2: \Device\HarddiskVolume1\my
> documents\MYREAL~1.txt
>
> etc, etc. Depending on depth of path. Is that
> correct? How does that handle “.” and “…” within a
> path? Is there not some way to get this all
> converted in one pass without having to fire it to
> usermode and calling GetLongPathName()?
>
> Basically I need a FltGetFileNameInformation()
> function I can call in the existing IFS kit. How the
> heck can I do that? I can’t be the only one that has
> had to deal with normalized LFN.
>
> Pointers to help docs and online resources that
> cover this would be a great help. As would code
> snippets to get me on the right track.
>
> Thanks in advance.
>
> –
> Regards,
> Dana Epp
> [Blog: http://silverstr.ufies.org/blog/]
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as:
> xxxxx@yahoo.com
> To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Just to properly set expectations, even the correct algorithm for doing
this is slow (and Randy’s algorithm below is correct :slight_smile: ). Opening
files is an expensive operations and there is no way to get around this.

The name generation code in the Filter Manager has these same
performance limitations. We have the opportunity to do more caching
than the normal filter since our name cache is shared by all minifilters
in the system who need names, but at the end of the day, a normalized
name is very expensive to generate.

Your best options for better performance are:

  1. Caching the names (if you need the name in pre-create, caching won’t
    help you because you cannot uniquely identify the file yet). The
    FileSpy sample from the IFS Kit shows you how to do a name cache.

  2. Reduce the number of times you need to query the name. Do any checks
    you can that would help you to determine if the file is interesting to
    you *before* your name generation (e.g., can you ignore new files, can
    you ignore opens of existing files, can you ignore directories, etc.).
    Some of this type of information you may only get if the caller used the
    most explicit CREATE options, but when you’ve got the hints use them.

Regards,
Molly Brown
Microsoft Corporation

This posting is provided “AS IS” with no warranties and confers no
rights.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Randy Cook
Sent: Wednesday, July 28, 2004 1:58 PM
To: Windows File Systems Devs Interest List
Subject: Re: [ntfsd] Backporting normalized path routines to support
FLT_FILE_NAME_NORMALIZED functionality in the existing IFS

For each component of the path
{
if (RtlIsNameLegalDOS8Dot3 == TRUE)
{
Open the parent directory
Query for FileBothDirectoryInformation
Close the parent directory
Add the long name to the long path
}
else
{
Add the name to the long path
}
}

Your recursion problems won’t typically be in
ZwQueryDirectoryFile. They will be in ZwCreateFile.
Read the OSR FAQ to see how to handle this.

On NT the same stuff gets opened over and over. So it
seems that even rudimentary caching might help.

If you still think that you need to roll your own
query IRP, let me know and I can send you an example.
It is one of the easy ones to do.

Randy

— Dana Epp wrote:

> Ok, as you might have seen from my last post, I am
> having some difficulties with ensuring I have a
> clean long file name in my filter driver.
>
> In the new Filter Manager you can use
> FLT_FILE_NAME_NORMALIZED with
> FltGetFileNameInformation() to get a fully
> normalized filepath which includes expanding all SFN
> to LFN and ripping all :$DATA from the stream name.
> This works great, and its one of the things that
> compelled me to look at the new filter manager at
> the last Driver DevCon.
>
> However, I find myself needing to backport some code
> I have to my existing driver framework, which
> doesn’t have this luxury. And quite frankly, I am
> lost in doing so.
>
> I originally thought I could use
> ZwQueryDirectoryFile. With thanks to Neal
> Christiansen he reminded me that such an approach
> would be a bad idea since I would have recursive IO
> which could be a problem. Especially since I am
> doing this during entrance to my function handler
> for IRP_MJ_CREATE. The recommendation was to roll my
> own query directory IRP and handle it properly.
>
> Does anyone know of any snippets of code in the IFS
> kit or online that does this? I really want to
> understand the right way to do this, and do so
> without significantly impacting the performance of
> the system. (I am going to have to do this for every
> filepath that enters my create function) I am
> guessing I need to roll IRP_MJ_DIRECTORY_CONTROL
> with IRP_MN_QUERY_DIRECTORY, using
> FILE_BOTH_DIR_INFORMATION. I would need to break up
> the path in the irpSp->FileObject->FileName and then
> loop through, calling against the previously built
> path. ie:
>
> Assuming I have
> \Device\HarddiskVolume1\MYDOCU~1\MYREAL~1.txt which
> should be normalized to \Device\HarddiskVolume1\my
> documents\myreallylongfile.txt
>
> Iteration1: \Device\HarddiskVolume1\MYDOCU~1
> Iternation2: \Device\HarddiskVolume1\my
> documents\MYREAL~1.txt
>
> etc, etc. Depending on depth of path. Is that
> correct? How does that handle “.” and “…” within a
> path? Is there not some way to get this all
> converted in one pass without having to fire it to
> usermode and calling GetLongPathName()?
>
> Basically I need a FltGetFileNameInformation()
> function I can call in the existing IFS kit. How the
> heck can I do that? I can’t be the only one that has
> had to deal with normalized LFN.
>
> Pointers to help docs and online resources that
> cover this would be a great help. As would code
> snippets to get me on the right track.
>
> Thanks in advance.
>
> –
> Regards,
> Dana Epp
> [Blog: http://silverstr.ufies.org/blog/]
>
> —
> Questions? First check the IFS FAQ at
> https://www.osronline.com/article.cfm?id=17
>
> You are currently subscribed to ntfsd as:
> xxxxx@yahoo.com
> To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


Questions? First check the IFS FAQ at
https://www.osronline.com/article.cfm?id=17

You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com