This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients Geoff.Alexander, eryksun, paul.moore, steve.dower, tim.golden, vstinner, zach.ware
Date 2019-03-07.03:45:46
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1551930346.92.0.238758103429.issue36213@roundup.psfhosted.org>
In-reply-to
Content
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
History
Date User Action Args
2019-03-07 03:45:46eryksunsetrecipients: + eryksun, paul.moore, vstinner, tim.golden, zach.ware, steve.dower, Geoff.Alexander
2019-03-07 03:45:46eryksunsetmessageid: <1551930346.92.0.238758103429.issue36213@roundup.psfhosted.org>
2019-03-07 03:45:46eryksunlinkissue36213 messages
2019-03-07 03:45:46eryksuncreate