[issue12777] Inconsistent use of VOLUME_NAME_* with GetFinalPathNameByHandle

Eryk Sun report at bugs.python.org
Mon Mar 15 13:39:20 EDT 2021


Eryk Sun <eryksun at gmail.com> added the comment:

bpo-33016 fixed the problem with the inconsistent dwFlags argument passed to GetFinalPathNameByHandleW().

We do need the ability to get the NT name in order to implement samefile() and sameopenfile() reliably in all cases -- i.e. when the volume serial number and/or file ID are 0 because the filesystem doesn't support them. A new issue needs to be opened to extend nt._getfinalpathname() to support passing either a file descriptor or a name and to add a parameter for the flags that defaults to 0.

> VOLUME_NAME_NT was more general purpose

The most broadly supported flags value is `VOLUME_NAME_NT | FILE_NAME_OPENED` -- e.g. "\Device\HarddiskVolume2\Windows\Temp\FILENA~1.TXT". 

For general use, the preferred form is `VOLUME_NAME_DOS | FILE_NAME_NORMALIZED` (dwFlags=0), which is the canonical DOS path with long component names -- e.g. "\\?\C:\Windows\Temp\filename_long.txt". This requires a volume device that supports the mountpoint manager; a registered or auto-assigned DOS drive-letter name; and a filesystem that supports normalizing names in the opened path.

GetFinalPathNameByHandleW() has special handling for the Multiple UNC Provider (MUP) device at the root of UNC paths (i.e. \\server\share -> \\?\UNC\server\share -> \Device\Mup\server\share). For the DOS 'volume' name, it returns the "\\?\UNC" form.

Caveats

Substitute drives and mapped drives are never present in the final DOS path. They resolve to a filesystem directory, not to a volume device, and they're usually defined locally in a logon session. Such drives are not final, globally accessible paths.

A file/directory in a filesystem is required, such as a filesystem mounted on a volume device, the named-pipe filesystem implemented on \Device\NamedPipe, or the mailslot filesystem implemented on \Device\Mailslot. Non-filesystem devices are not supported, such as \\?\CON (i.e. \Device\ConDrv\Console) and \\?\NUL (i.e. \Device\Null).

> That's slightly off-topic, but is it enough to strip the leading
> '\\?\' (and replace 'UNC' with '\')

The \\?\ path prefix, which signifies an extended path (i.e. a verbatim local-device path), should not be removed without testing that it results in an equivalent, accessible path. An extended path may be required in order to access DOS paths that are longer than MAX_PATH. Also, the last path component of the final path may be a reserved DOS device name, or end with trailing dots and/or spaces, which is inaccessible without using an extended path.

----------
nosy: +eryksun
resolution:  -> out of date
stage:  -> resolved
status: open -> closed
superseder:  -> nt._getfinalpathname may use uninitialized memory

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue12777>
_______________________________________


More information about the Python-bugs-list mailing list