Thread overview
[Issue 8967] New: dirEntries throws when encountering a "long path" on windows
Nov 06, 2012
Regan Heath
Nov 06, 2012
Regan Heath
Dec 22, 2012
Vladimir Panteleev
November 06, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8967

           Summary: dirEntries throws when encountering a "long path" on
                    windows
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: regan@netmail.co.nz


--- Comment #0 from Regan Heath <regan@netmail.co.nz> 2012-11-06 09:56:10 PST ---
Exception thrown:

Bypasses std.file.FileException@std\file.d(2434)
=== Bypassed ===
std.file.FileException@std\file.d(2434):
E:\basic\2012-10-16_0\abcdefghi1abcdefghi2abcdefghi3abcdefghi4abcdefghi5abcdefghi6abcdefghi7abcdefghi8abcdefghi9abcdefg
hi0\abcdefghi1abcdefghi2abcdefghi3abcdefghi4abcdefghi5abcdefghi6abcdefghi7abcdefghi8abcdefghi9abcdefghi0\abcdefghi1abcdefghi2abcdefghi3abcdefghi4abcdefghi5abcde
fghi6abcdefghi7abcdefghi8abcdefghi9abcdefghi0: The system cannot find the path
specified.

The solution is simple/trivial.  FindFirstFileW will handle "long paths" in the following format:

  \\?\<path>

where <path> may be C:\folder\... or \\host\share\...

So, the simplest fix is to alter DirIteratorImpl.stepIn, line:
  string search_pattern = buildPath(directory, "*.*");
to read:
  string search_pattern = r"\\?\" ~ buildPath(directory, "*.*");

(I have tried/tested this fix and it works for me)

Alternately (better) have buildPath (on windows) detect paths longer than 256
characters and automatically pre-pend \\?\ itself.

This should work ok as long as W functions are used, but will cause issues when some A functions, and other windows functions are used as long paths are not supported throughout.

But, in those cases a too long short path would error - just in a different way.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 06, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8967


Regan Heath <regan@netmail.co.nz> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         OS/Version|All                         |Windows


--- Comment #1 from Regan Heath <regan@netmail.co.nz> 2012-11-06 10:01:39 PST ---
I should add, the call to direntries used SpanMode.depth, and was passed a short path which contained the long path shown in the exception.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 22, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8967


Vladimir Panteleev <thecybershadow@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |thecybershadow@gmail.com


--- Comment #2 from Vladimir Panteleev <thecybershadow@gmail.com> 2012-12-21 21:24:30 PST ---
I'm not sure whether the standard library should be adding the \\?\ prefix internally. If we are to change dirEntries, then we should also change all I/O routines that deal with paths. And even then, the resulting paths may not be usable by other components (used directly in the user's program), such as OS or C functions, and external programs.

To work around this problem, the user could also use a function such as the one here [1], and pass path strings through it at the point where they enter the program's I/O logic layer.

  [1]: https://github.com/CyberShadow/RABCDAsm/blob/master/common.d#L25

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------