Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / .NET SDK / July 2006

Tip: Looking for answers? Try searching our database.

get canonical filename?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
David Thielen - 15 Jun 2006 17:11 GMT
Hi;

How can I get the canonical version of a filename. For example, if I pass in
c:/windows/fonts I get back C:\\WINDOWS\\Fonts (how it is on my system).

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Peter Ritchie - 15 Jun 2006 22:39 GMT
Path.GetFullPath(text) works for me.

Signature

http://www.peterRitchie.com/

> Hi;
>
> How can I get the canonical version of a filename. For example, if I pass in
> c:/windows/fonts I get back C:\\WINDOWS\\Fonts (how it is on my system).
David Thielen - 15 Jun 2006 22:51 GMT
I tried that and got back fonts instead of Fonts.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

> Path.GetFullPath(text) works for me.
>
> > Hi;
> >
> > How can I get the canonical version of a filename. For example, if I pass in
> > c:/windows/fonts I get back C:\\WINDOWS\\Fonts (how it is on my system).
Peter Ritchie - 16 Jun 2006 02:22 GMT
I wouldn't consider that canonical...  Short of recursively calling Platform
SDK FindFirstFile on each directory part, I don't think a single function or
method exists to get the "actual" file/path matching case.

Signature

http://www.peterRitchie.com/

> I tried that and got back fonts instead of Fonts.
>
[quoted text clipped - 4 lines]
> > > How can I get the canonical version of a filename. For example, if I pass in
> > > c:/windows/fonts I get back C:\\WINDOWS\\Fonts (how it is on my system).
David Thielen - 16 Jun 2006 02:54 GMT
That's what I was afraid of. Java has this but probably because in the unix
world Fonts and fonts are different directories.

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

> I wouldn't consider that canonical...  Short of recursively calling Platform
> SDK FindFirstFile on each directory part, I don't think a single function or
[quoted text clipped - 8 lines]
> > > > How can I get the canonical version of a filename. For example, if I pass in
> > > > c:/windows/fonts I get back C:\\WINDOWS\\Fonts (how it is on my system).
Peter Ritchie - 16 Jun 2006 04:01 GMT
Yep, "Fonts" and "fonts" are the same in Windows...  But, it wouldn't be to
hard to code a method to do this.  Yanking the FindFirstFile prototypes and
structures from some of Stephen Toub's articles [1][2] and throwing together
a loop:
/// <summary>
/// Get the actual path case-correct for <paramref name="path"/>
/// </summary>
/// <author>Peter Ritchie</author>
/// <param name="path"></param>
/// <returns>Actual Path</returns>
/// <exception cref="T:System.Security.SecurityException">The caller does
not have the required permissions. </exception>
/// <exception cref="T:System.ArgumentNullException">path is null.
</exception>
/// <exception cref="T:System.ArgumentException">path is a zero-length
string, contains only white space, or contains one or more invalid characters
as defined by <see cref="F:Path.InvalidPathChars"></see>, or contains a
wildcard character.-or- The system could not retrieve the absolute path.
</exception>
/// <exception cref="T:System.NotSupportedException">path contains a colon
(":"). </exception>
/// <exception cref="T:PathTooLongException">The specified path, file name,
or both exceed the system-defined maximum length. For example, on
Windows-based platforms, paths must be less than 248 characters, and file
names must be less than 260 characters. </exception>
/// <exception cref="T:System.ArgumentException">The path parameter contains
invalid characters, is empty, or contains only white spaces, or contains a
wildcard character. </exception>
/// <using>
///    using System.IO;
///    using Microsoft.Win32.SafeHandles;
///    using System.Security.Permissions;
///    using System.Runtime.ConstrainedExecution;
/// </using>
static String GetPathActual ( String path )
{
    String result = "";
    path = Path.GetFullPath(path);
    Win32Native.WIN32_FIND_DATA findData = new Win32Native.WIN32_FIND_DATA();
    if (File.Exists(path))
    {
        Win32Native.FindFirstFile(path, findData);
        result = findData.fileName;
        path = Path.GetDirectoryName(path);
    }
    DirectoryInfo directoryInfo = new DirectoryInfo(path);
    while(Directory.Exists(path) && directoryInfo.Root.Name != path)
    {
        Win32Native.FindFirstFile(path, findData);
        result = findData.fileName + Path.DirectorySeparatorChar + result;
        System.Diagnostics.Debug.WriteLine(path);
        path = Path.GetDirectoryName(path);
        directoryInfo = new DirectoryInfo(path);
    }
    return path + result;
}

internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
    private SafeFindHandle ( ) : base(true)
    {
    }

    protected override bool ReleaseHandle ( )
    {
        return FindClose(this.handle);
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    private static extern bool FindClose ( IntPtr handle );
}

[System.Security.SuppressUnmanagedCodeSecurity]
internal static class Win32Native
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public class WIN32_FIND_DATA
    {
        public int fileAttributes = 0;
        // creationTime was an embedded FILETIME structure.
        public int creationTime_lowDateTime = 0;
        public int creationTime_highDateTime = 0;
        // lastAccessTime was an embedded FILETIME structure.
        public int lastAccessTime_lowDateTime = 0;
        public int lastAccessTime_highDateTime = 0;
        // lastWriteTime was an embedded FILETIME structure.
        public int lastWriteTime_lowDateTime = 0;
        public int lastWriteTime_highDateTime = 0;
        public int nFileSizeHigh = 0;
        public int nFileSizeLow = 0;
        public int dwReserved0 = 0;
        public int dwReserved1 = 0;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public String fileName = null;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public String alternateFileName = null;
    }
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern SafeFindHandle FindFirstFile ( string lpFileName,
        [In, Out, MarshalAs(UnmanagedType.LPStruct)]
       WIN32_FIND_DATA lpFindFileData );
}

[1] http://msdn.microsoft.com/msdnmag/issues/05/12/NETMatters
[2] http://msdn.microsoft.com/msdnmag/issues/05/10/Reliability 

Signature

http://www.peterRitchie.com/

> That's what I was afraid of. Java has this but probably because in the unix
> world Fonts and fonts are different directories.
[quoted text clipped - 15 lines]
> > > > > david_at_windward_dot_net
> > > > > http://www.windwardreports.com
Peter Ritchie - 16 Jun 2006 04:03 GMT
Sorry, that previous example is missing "SafeFindHandle handle = " before
each call to FindFileFirst.

Signature

http://www.peterRitchie.com/

> Yep, "Fonts" and "fonts" are the same in Windows...  But, it wouldn't be to
> hard to code a method to do this.  Yanking the FindFirstFile prototypes and
[quoted text clipped - 123 lines]
> > > > > > david_at_windward_dot_net
> > > > > > http://www.windwardreports.com
Chris Mullins - 12 Jul 2006 02:00 GMT
[Canonical file name]

>> > Path.GetFullPath(text) works for me.
>> I tried that and got back fonts instead of Fonts.

Generally speaking, canonical names are lower case.

In the work I've done with StringPrep and IDNA "Fonts" would be case folded
down to "fonts". This is what you want in a canonical case on a file system
that doesn't distinguish between case. Otherwise you would have a big mess -
fonts could be:
"FOnts"
"fOnts"
"foNts"
"fonTs"
"fontS"

(and all the other combinations).

The only two cases that makes sense are "FONTS" or "fonts", and forever
whatever reason lower case is used in all the cases I've ever seen.

As a result of this getting back "fonts" and not "Fonts" is a good thing
that makes me believe this is a canonical file name.

Signature

Chris Mullins
Coversant, Inc.

David Thielen - 12 Jul 2006 02:31 GMT
But what if it's a drive that is mapped to a linux share?

Signature

thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

> [Canonical file name]
>
[quoted text clipped - 20 lines]
> As a result of this getting back "fonts" and not "Fonts" is a good thing
> that makes me believe this is a canonical file name.
Chris Mullins - 12 Jul 2006 04:27 GMT
[canonical file names]

After looking this up on Google, there is a difference between a canonical
path and a real path. Things like file system compares cannot be done using
canonical paths, for this reason.

In general, I would punt on it and say it's the responsability of the driver
(Samba in the case of a Linux share) to take care of mapping a canonical
Win32 path to a valid Linux Filesystem path.

--
Chris Mullins

> But what if it's a drive that is mapped to a linux share?
>
[quoted text clipped - 25 lines]
>> As a result of this getting back "fonts" and not "Fonts" is a good thing
>> that makes me believe this is a canonical file name.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.