Eryk Sun <eryk...@gmail.com> added the comment:

Long-path support in Windows 10 does not extend to the lpCurrentDirectory 
parameter of CreateProcessW. If the path length exceeds the old limit of 
MAX_PATH - 2 characters (not counting the required trailing backslash and 
null), CreateProcessW fails with either ERROR_DIRECTORY (267) or 
ERROR_INVALID_PARAMETER (87).

If we pass lpCurrentDirectory as a long path, it fails with ERROR_DIRECTORY 
(i.e. the directory name is invalid). This is a bit confusing because it maps 
to Python NotADirectoryError, which is the common usage for ERROR_DIRECTORY. 
CreateProcessW, however, uses it in its broadest sense. It also fails with this 
error if lpCurrentDirectory can't be validated as an existing directory via 
GetFileAttributesW.

If we pass lpCurrentDirectory as NULL (i.e. inherit the current directory) and 
our current directory is a long path, CreateProcessW fails with 
ERROR_INVALID_PARAMETER. The source of this error isn't obvious unless we know 
what to look for, since all of the passed parameters are in fact valid. 
However, I'm not sure how to clarify the error without making assumptions. In 
particular, a future release of Windows 10 may remove this limitation, in which 
case we could end up obscuring an unrelated error. 

> the workaround is to use the "\\?\" prefix

Without long-path support, the working directory is always limited to MAX_PATH 
- 2 characters. The \\?\ prefix doesn't help. A few years ago, the 
documentation for SetCurrentDirectory [1] was changed to include an invalid 
claim that we can use the \\?\ prefix. We need to go back to 2016 [2] to get 
the correct documentation. 

Windows doesn't even fully support setting the current directory to a device 
path (i.e. prefixed by \\.\ or \\?\). Operations on rooted paths will fail 
badly because the system computes an invalid working drive in this case. We can 
observe the problem by calling GetFullPathNameW:

    >>> os.chdir(r'\\.\C:\Temp')
    >>> print(os.path._getfullpathname(r'\Temp'))
    \\Temp

The incorrect result might even be a valid path, coincidentally. For example:

    >>> print(os.getcwd())
    \\.\C:\Temp
    >>> os.chdir(r'\localhost\C$')
    >>> print(os.getcwd())
    \\localhost\C$


[1]: 
https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setcurrentdirectory
[2]: 
https://web.archive.org/web/20160428232130/https://msdn.microsoft.com/en-us/library/windows/desktop/aa365530(v=vs.85).aspx

----------
nosy: +eryksun

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue36213>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to