Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know from python if Windows path limit has been removed

Tags:

python

windows

In a python application, that has to be compatible with Python 2 and Python 3, running in Windows, I would like to know if the 260 characters path lenght limit imposed by Windows has been removed in the system.

Latest Windows gives the possibility to disable the path length limit, and even the Python 3.6 Windows installer allows to automatically do this. But it is something that also the user can do at the system level. This feature is only available for NTFS filesystems.

How do I know from my python code if this is enabled, so I can use long paths or provide my own workarounds? It is fine to check it for a given unit, like "C:/" or "D:/". Is it possible to know if long paths are enabled for a given unit?

like image 342
drodri Avatar asked Sep 08 '17 09:09

drodri


1 Answers

Historically paths longer than MAX_PATH (260) have required using the "\\?\" prefix. This limit isn't imposed by file systems such as NTFS. Microsoft's file systems can handle long paths up to about 32,760 characters. The limit is instead imposed by the system runtime library when it normalizes DOS paths (e.g. UNC paths, relative paths, and paths with DOS drive letters and DOS devices such as COM1) as native OBJECT_ATTRIBUTES paths.

In Windows 10, applications have the option to support paths up to the maximum length supported by file systems, without requiring the "\\?\" prefix. Don't expect everything to be smooth sailing, however. For example, as of 10.0.15063, CreateProcess still fails if the working directory exceeds MAX_PATH.

The new behavior is enabled by the IsLongPathAwareProcess flag in the Process Environment Block (PEB). Process initialization code in kernelbase.dll enables this flag if and only if both the "LongPathsEnabled" system policy is configured and the "longPathAware" application-manifest setting is true. For more information, see towards the end of Maximum Path Length Limitation. Note however that it's mistaken (or poorly worded) when it states that one "can also enable" the new behavior via the application manifest. Both settings have to be enabled.

The value of the IsLongPathAwareProcess flag can be queried directly by calling the undocumented runtime library function, RtlAreLongPathsEnabled. For example:

import ctypes
ntdll = ctypes.WinDLL('ntdll')

if hasattr(ntdll, 'RtlAreLongPathsEnabled'):

    ntdll.RtlAreLongPathsEnabled.restype = ctypes.c_ubyte
    ntdll.RtlAreLongPathsEnabled.argtypes = ()

    def are_long_paths_enabled():
        return bool(ntdll.RtlAreLongPathsEnabled())

else:

    def are_long_paths_enabled():
        return False
like image 65
Eryk Sun Avatar answered Oct 13 '22 16:10

Eryk Sun