Skip to content

Transparently add the \\?\ prefix to Win32 calls for extended length path handling #1257

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

Merged
merged 1 commit into from
Apr 23, 2025

Conversation

jakepetroules
Copy link
Contributor

On Windows, there is a built-in maximum path limitation of 260 characters under most conditions. This can be extended to 32767 characters under either of the following two conditions:

  • Adding the longPathAware attribute to the executable's manifest AND enabling the LongPathsEnabled system-wide registry key or group policy.
  • Ensuring fully qualified paths passed to Win32 APIs are prefixed with ?\

Unfortunately, the former is not realistic for the Swift ecosystem, since it requires developers to have awareness of this specific Windows limitation, AND set longPathAware in their apps' manifest AND expect end users of those apps to change their system configuration.

Instead, this patch transparently prefixes all eligible paths in calls to Win32 APIs with the ?\ prefix to allow them to work with paths longer than 260 characters without requiring the caller of Foundation to manually prefix the paths.

See https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more info.

@jakepetroules
Copy link
Contributor Author

@swift-ci test

@jakepetroules
Copy link
Contributor Author

@swift-ci test

@jakepetroules
Copy link
Contributor Author

@swift-ci test

@jakepetroules
Copy link
Contributor Author

@swift-ci test

@jakepetroules
Copy link
Contributor Author

@swift-ci test

Copy link
Member

@compnerd compnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than the labelling, LGTM

@jmschonfeld jmschonfeld requested a review from jrflat April 22, 2025 21:00
Copy link
Contributor

@jmschonfeld jmschonfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor comments on the unit test, but overall this looks good - thanks for putting this together! Added @jrflat as a reviewer as well just for another perspective from the URL side of things in case there's any considerations/impact there.

…path handling

On Windows, there is a built-in maximum path limitation of 260 characters under most conditions. This can be extended to 32767 characters under either of the following two conditions:

- Adding the longPathAware attribute to the executable's manifest AND enabling the LongPathsEnabled system-wide registry key or group policy.
- Ensuring fully qualified paths passed to Win32 APIs are prefixed with \?\

Unfortunately, the former is not realistic for the Swift ecosystem, since it requires developers to have awareness of this specific Windows limitation, AND set longPathAware in their apps' manifest AND expect end users of those apps to change their system configuration.

Instead, this patch transparently prefixes all eligible paths in calls to Win32 APIs with the \?\ prefix to allow them to work with paths longer than 260 characters without requiring the caller of Foundation to manually prefix the paths.

See https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation for more info.
@jakepetroules
Copy link
Contributor Author

@swift-ci test

@jakepetroules
Copy link
Contributor Author

Thanks @jmschonfeld and @compnerd; I've addressed all your feedback so far.

@compnerd
Copy link
Member

@jakepetroules any chance that we might be able to pull this into 6.2 as well? 😄

Copy link
Contributor

@jrflat jrflat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks all good for URL's use-case, thanks!

@jakepetroules
Copy link
Contributor Author

@jakepetroules any chance that we might be able to pull this into 6.2 as well? 😄

Happy to -- @jmschonfeld / @parkera, is your team doing regular merges from main to 6.2 or should I manually bring it over?

// 1. Normalize the path first.
// Contrary to the documentation, this works on long paths independently
// of the registry or process setting to enable long paths (but it will also
Copy link
Contributor Author

@jakepetroules jakepetroules Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it states the truth on this page instead of the docs for GetFullPathName itself:

You can pass paths of more than MAX_PATH characters to GetFullPathName without \\?\. It supports arbitrary length paths up to the maximum string size that Windows can handle.

Copy link
Contributor

@jmschonfeld jmschonfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks!

@jmschonfeld
Copy link
Contributor

@jakepetroules any chance that we might be able to pull this into 6.2 as well? 😄

Happy to -- @jmschonfeld / @parkera, is your team doing regular merges from main to 6.2 or should I manually bring it over?

@parkera / @itingliu can confirm but I believe our plan is to have periodic merges from main into release/6.2 for now until later in the release cycle

jakepetroules added a commit to jakepetroules/swift-subprocess that referenced this pull request Apr 23, 2025
…path handling

This simply updates the implementation of withNTPathRepresentation with what's about to be merged into Foundation via swiftlang/swift-foundation#1257
@jakepetroules jakepetroules merged commit 90953df into swiftlang:main Apr 23, 2025
3 checks passed
@jakepetroules jakepetroules deleted the windows-long-paths branch April 23, 2025 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
windows Issue regarding compiling/running on Windows
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants