Hi!

Out of the urgent need to access files with a path longer than MAX_PATH on
Windows, I started some research.
At first I thought it might be a good idea to write my own stream wrapper
extension (e.g. file_long://.....) .

Before I started, I tried to find out, why those paths don't work in the
current php code.

According to [1] it is possible to use long_paths, if the path is prefixed
correctly, e.g.

\\?\

for a local file path, and

\\?\UNC\

for a UNC path.


I checked that fopen() and even open() in fact do work in C code with such
long paths when using the prefix.

So I bumped up MAXPATHLEN in php.h and tsrm_config_common.h to 32786 and
recompiled a fresh php 5.3.20.

Suprisingly a php script using a long path (including the prefix) did throw
an error.

Tracing that error leads to

plain_wrapper.c:914 expand_filepath ->expand_filepath_ex ->virtual_file_ex

These are the lines, that produce the error (tsrm_virtual_cwd.c:1255):

#ifdef TSRM_WIN32
    if (memchr(resolved_path, '*', path_length) ||
        memchr(resolved_path, '?', path_length)) {
        return 1;
    }
#endif

Since there's a '?' in the string from the long path prefix the
virtual_file_ex fails at this point.
I did not quite understand the rationale behind this check.
Of course, both checked characters are invalid for a regular file path.
There seem to be some checking in tsrm_realpath_r()
for paths like

\\?\Volume{62d1c3f8-83b9-11de-b108-806e6f6e6963}\foo

If I remove those memchr lines, everything magically works, e.g. fopen(),
file_get_contents(), file_put_contents(), unlink(), rmdir(), mkdir(), etc.

Only thing to do from userspace is to define the path as

$path = "\\\\?\\x:\\long_stuff.......\\.....\\......\file.txt";

There are a few macros that get irritated (e.g. IS_ABSOLUTE_PATH,
IS_UNC_PATH) by the double double backslash in the path...

My questions here:

1. What is the rationale behind the memchr checks for ? and *? Just
filtering invalid paths?
2. Does allowing the "\\?\" prefix to bubble through the stream wrapper
layer (which effectively makes it usable) break anything?
3. If not, is it possible to include this in php 5.3. or php 5.4?

It would be indeed nice if the "\\?\" prefix was not needed in userspace
and php would do the work. But just for now I really would like to see php
support for long paths on windows at all. To my mind the changes needed for
the prefix workaround are function is minimal-invasive. Correct me, if I'm
wrong :)

Any comment is much appreciated, if I can help implementing this "feature",
let me know.

Greetings

Nico

[1]
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx

Reply via email to