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

Support long path names on all Windows versions #2188

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions text/0000-long-paths-windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
- Feature Name: long_windows_paths
- Start Date: 2017-10-24
- RFC PR:
- Rust Issue:

# Summary
[summary]: #summary

Rust programs currently cannot access files on Windows 8 and below with paths longer than `MAX_PATH`. This is a bug and should be fixed.

# Motivation
[motivation]: #motivation

Windows 8 and below make it difficult but not impossible for a program to access a file with a name longer than `MAX_PATH`. The kernel APIs have no problem with such paths at all, but the user-mode APIs do. They require that the path be prefixed with `\\?\`, which disables all normalization.

Fortunately, there is a solution that gets back normalization: if (and only if) the file name *does not* begin with `\??\` or `\\?\`, one can pass it to the Windows API function `GetFullPathNameW`, which supports long paths just fine and can easily be called from Rust. The resulting path can safely have `\\?\` prepended and then be passed to the underlying Windows API calls.  `GetFullPathNameW`’s documentation claims that it does not support long paths, but it in fact does.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

This should require at most a brief mention in the Rust book. All that is needed is a note that while many programs do not support long paths on Windows 8 and below (or Windows 10 without proper manifest/registry settings), Rust’s standard library has no such problems, and will work on any path that the underlying NT API supports.

# Reference-level explanation
[reference-level-explanation]: #reference-level-explanation

Whenever Rust sends a path to an underlying NT API, it should use first check if the path length is less than 260 characters **or** begins with either `\\?\` or `\??\`, then pass it to the underlying Windows API function directly. Otherwise, pass it to `GetFullPathNameW`. If it fails, return; if not, pass the result to the underlying Windows API call.

# Drawbacks
[drawbacks]: #drawbacks

This adds a small amount of complexity to the standard library. This complexity should be more than compensated by the ability to handle long paths generated by e.g. NPM.

# Rationale and alternatives
[alternatives]: #alternatives

The alternatives are:

- Do nothing. This is bad, because tools like NPM already support and generate long paths.
- Try to implement `GetFullPathNameW` in pure Rust. This is not easy, and does not guarantee compatibility with the Windows implementation.
- Use `GetFullPathNameW` to allow for long paths on Windows. This is the approach chosen here.

# Unresolved questions
[unresolved]: #unresolved-questions

None. This is a bug fix, pure and simple.