Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::fs::canonicalize uses GetFinalPathNameByHandleW, which can fail #79449

Closed
Dwedit opened this issue Nov 26, 2020 · 3 comments
Closed

std::fs::canonicalize uses GetFinalPathNameByHandleW, which can fail #79449

Dwedit opened this issue Nov 26, 2020 · 3 comments
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` C-bug Category: This is a bug. O-windows Operating system: Windows T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@Dwedit
Copy link

Dwedit commented Nov 26, 2020

I was just testing out the Win32 function GetFinalPathNameByHandleW, and saw a case where it failed to work.

Steps to reproduce:

  • Install OSFMount (Passmark)
  • Mount a Disk Image (I used a NTFS image file, mounted as drive X)
  • Use CreateFileW on a file on the disk image (my path: "X:/flash Movies/11-29-04-thanksgiving.swf")
  • Call GetFinalPathNameByHandleW on that handle, using FILE_NAME_NORMALIZED

Function returns 0 instead of returning a path name, and GetLastError returns 1 (ERROR_INVALID_FUNCTION).

However, if I call GetFinalPathNameByHandleW using VOLUME_NAME_NT, I get something: "\Device\OSFMDisk0\Flash Movies\11-29-04-thanksgiving.swf", but this path isn't usable with CreateFileW.

There are alternative ways to canonicalize a filename on Win32:
PathCanonicalizeW is the traditional way to do it, works on Windows 2000 and later, but it is limited to 260 character filenames, and is marked as deprecated by Microsoft.
PathCchCanonicalizeEx is the replacement function since Windows 8, and is unavailable in Windows 7 and earlier, but does support very long path names.

@Dwedit Dwedit added the C-bug Category: This is a bug. label Nov 26, 2020
@jonas-schievink jonas-schievink added T-libs Relevant to the library team, which will review and decide on the PR/issue. O-windows Operating system: Windows labels Nov 26, 2020
@Dwedit
Copy link
Author

Dwedit commented Nov 27, 2020

According to http://mail.openjdk.java.net/pipermail/core-libs-dev/2020-July/067594.html,

With ImDisk virtual disks, applications that rely on Windows Volume Mount Manager APIs, like GetFinalPathNameByHandleW, will fail because ImDisk does not interact with Windows Volume Mount Manager at all, it effectively bypasses it. Essentially, GetFinalPathNameByHandle and few other APIs will never work properly with ImDisk virtual drives.

This references another virtual disk tool called ImDisk which creates a Ram disk.

The code at https://docs.microsoft.com/en-us/windows/win32/memory/obtaining-a-file-name-from-a-file-handle shows an example of using QueryDosDevice to convert a drive letter into a device path. The code tries all valid drive letters. It was able to match Drive X: with "\Device\OSFMDisk0", and return a correct file path.

Edit:
Perhaps I should also mention #27706. It is closed, but a related issue.

@ehuss
Copy link
Contributor

ehuss commented Nov 27, 2020

This is a fairly well known problem, #59117 discusses some of the problems along with links to many other issues.

Another option I have considered is using GetFullPathNameW. I haven't tested that in depth to know what issues there would be. I think long-path handling might be tricky. I'm not sure if it would make sense for canonicalize to conditionally return device-style paths with \\?\. I suspect that would lead to more unexpected bugs, since many programs can't handle them properly.

It would be nice if canonicalize was less difficult to use properly.

@Enselic
Copy link
Member

Enselic commented Aug 21, 2023

Triage: This seems a like a duplicate to #48249 in practice, so closing as such.

@Enselic Enselic closed this as not planned Won't fix, can't repro, duplicate, stale Aug 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` C-bug Category: This is a bug. O-windows Operating system: Windows T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants