Path.GetDirectoryName() \\?\ and long directory names?

M

Martin Carpella

Hi!

I know, that Path-names should be shorter than MAX_PATH (250), but the
Win32-SDK allows specifiying longer names using the "\\?\" prefix.

As I have an application that accesses files directly using the volume
name instead of the drive letter
(i.e. "\\?\Volume{...}\subdir\file.ext"), I sometimes get an
PathTooLongException, as the total string exceeds 260 characters (due to
the "\\?\Volume{...}\"-part).

Is there any way, to get Path.GetDirectoryName() to honor the "\\?\"
prefix and therefore skip the check for MAX_PATH?

I find it interesting, that GetDirctoryName() and GetFullPath() are the
only two methods checking for the path length, Path.Combine(),
Path.GetFileName(), etc. all work without any problem with the long strings.

Best regards,
Martin

PS: Unfortunately it is no option to use the aliased path ("C:\...")
instead of the full path, as the Path is handed to the application from
external.
 
W

Willy Denoyette [MVP]

|
| Hi!
|
| I know, that Path-names should be shorter than MAX_PATH (250), but the
| Win32-SDK allows specifiying longer names using the "\\?\" prefix.
|
| As I have an application that accesses files directly using the volume
| name instead of the drive letter
| (i.e. "\\?\Volume{...}\subdir\file.ext"), I sometimes get an
| PathTooLongException, as the total string exceeds 260 characters (due to
| the "\\?\Volume{...}\"-part).
|
| Is there any way, to get Path.GetDirectoryName() to honor the "\\?\"
| prefix and therefore skip the check for MAX_PATH?
|
| I find it interesting, that GetDirctoryName() and GetFullPath() are the
| only two methods checking for the path length, Path.Combine(),
| Path.GetFileName(), etc. all work without any problem with the long
strings.
|
| Best regards,
| Martin
|
| PS: Unfortunately it is no option to use the aliased path ("C:\...")
| instead of the full path, as the Path is handed to the application from
| external.

The framework does not support volume and device names in the path for it's
file IO methods, nor does it support Unicode path's (path > 260 characters),
that means some methods do have to check this constraint, unfortunately some
methods don't care at all about this (Combine) while others don't need to
care (GetFileName).
Anyway, you obtained an handle to a "volume path" by a call to Win32's
CreateFile API (through PInvoke), effectively bypassing the restriction
imposed by the IO namespace classes, that means that you will have to
PInvoke some Win32 API's when you need to deal with issues related to the
imposed restrictions.

Willy.
 
M

Martin Carpella

Willy Denoyette said:
Anyway, you obtained an handle to a "volume path" by a call to Win32's
CreateFile API (through PInvoke), effectively bypassing the restriction
imposed by the IO namespace classes, that means that you will have to
PInvoke some Win32 API's when you need to deal with issues related to the
imposed restrictions.

Thanks for your fast response. I almost expected this (and I have no
problem with it), I just wanted to make sure there is no "managed" way
of handling the situation.

Best regards,
Martin
 
M

Martin Carpella

Willy Denoyette said:
The framework does not support volume and device names in the path for it's
file IO methods, nor does it support Unicode path's (path > 260 characters),
that means some methods do have to check this constraint, unfortunately some
methods don't care at all about this (Combine) while others don't need to
care (GetFileName).

Adding to my previous post, I notice there seems to be a "off-by one"
bug in the .NET framework implementation, as I managed to create a
file with 242 characters in a folder with 18 (total 260) using on-board
means (Explorer -> Create new file -> rename).
Path.GetDirectory() fails on this with the same PathTooLongException
(telling me, that the total filename must be less than 260 and the
pathname shorter than 248).

Best regards,
Martin
 
W

Willy Denoyette [MVP]

|
| > The framework does not support volume and device names in the path for
it's
| > file IO methods, nor does it support Unicode path's (path > 260
characters),
| > that means some methods do have to check this constraint, unfortunately
some
| > methods don't care at all about this (Combine) while others don't need
to
| > care (GetFileName).
|
| Adding to my previous post, I notice there seems to be a "off-by one"
| bug in the .NET framework implementation, as I managed to create a
| file with 242 characters in a folder with 18 (total 260) using on-board
| means (Explorer -> Create new file -> rename).
| Path.GetDirectory() fails on this with the same PathTooLongException
| (telling me, that the total filename must be less than 260 and the
| pathname shorter than 248).
|
| Best regards,
| Martin

MAX_PATH is defined as 260 including a terminating 0 character, note that
the docs says LESS than 260, but the doc's and the exception message are
wrong when they says 260 is the max filename length, a filename cannot be
longer than the path.
The filename is a component of path, and it's length is 256 character
(including a terminating 0).
To resume: the maximum for path and filename are respectively 259 and 255
characters.

Willy.
 
M

Martin Carpella

Willy Denoyette said:
MAX_PATH is defined as 260 including a terminating 0 character, note that
the docs says LESS than 260, but the doc's and the exception message are
wrong when they says 260 is the max filename length, a filename cannot be
longer than the path.
The filename is a component of path, and it's length is 256 character
(including a terminating 0).
To resume: the maximum for path and filename are respectively 259 and 255
characters.

Thanks, I'm aware of the limits, thats why I was so confused when I
encountered the 260-file.

I was absolutely sure I managed to create the file with 260 using only
explorer, but as I wrote a reply emphasizing this, I just tried to
reproduce, just in case... And well, Murphy was right (again). I'm
unable to reproduce a 260 file using Explorer alone ;) So I seam to need
to confess I was wrong and my other file seems to have been created
using Win32-API instead...

Sorry for my mistake.

Best regards,
Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top