Skip to content

Fix paths on Windows #7537

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

Closed
wants to merge 2 commits into from
Closed

Fix paths on Windows #7537

wants to merge 2 commits into from

Conversation

marler8997
Copy link
Contributor

@marler8997 marler8997 commented Dec 24, 2020

fixes: #6044

This PR replaces the custom logic Zig has implemented to convert legacy DOS paths to NT paths with calls into ntdll to do the conversion for us. These should be the same conversion functions that Win32 functions like CreateFile use to convert DOS paths to NT paths.

Now that ntdll is handling this conversion, missing features like support for "." and ".." should be resolved.

Follow Up: look for more NT calls

This PR has only replaced the implementation for the openDir* calls because those functions boil down to NtCreateFile which requires an NT formatted path. We should see if there are any other filesystem functions that end up calling NT-specific functions and fix those as well (if there are any). Look for places where sliceToPrefixedFileW is called and where those paths are passed to NT functions such as NtCreateFile.

Follow Up: consider RtlDosPathNameToRelativeNtPathName_U_WithStatus

Another thing to follow up on is using RtlDosPathNameToRelativeNtPathName_U_WithStatus for relative paths. The current mechanism uses RtlDosPathNameToNtPathName_U_WithStatus for the path and then removes the CWD prefix. I don't know whether one implementation has benefits over the other. There's also diverging implementations to consider, I noticed that Wine and ReactOS seemed to have differences in opinion on these functions, so we may want to keep our usage of them to a minimal subset.

@marler8997 marler8997 changed the title use ntdll to convert NT paths Fix paths on Windows Dec 24, 2020
@marler8997 marler8997 marked this pull request as ready for review December 24, 2020 08:41
@@ -1235,15 +1235,13 @@ pub const Dir = struct {
}
}

/// Same as `openDir` except the path parameter is WTF-16 encoded, NT-prefixed.
/// Same as `openDir` except the path parameter is WTF-16 encoded.
/// This function asserts the target OS is Windows.
pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16, args: OpenDirOptions) OpenError!Dir {
Copy link
Member

Choose a reason for hiding this comment

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

Can we delete this function now? The idea of this function is that it's slightly more efficient if you already have wide strings you want to pass, but if we have to do the conversion anyway, there's no reason for this function to exist.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we delete it, then applications that have a u16 string will now need to do 2 conversions, one to u8 and then the second internal conversion.

Comment on lines +1587 to +1588
const status = ntdll.RtlDosPathNameToNtPathName_U_WithStatus(dos_path, &str, null, null);
if (status != .SUCCESS) return unexpectedStatus(status);
Copy link
Member

Choose a reason for hiding this comment

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

This introduces unnecessary heap allocation, causing OutOfMemory to be added to the OpenError set. We can do better. Check the wine implementation of RtlDosPathNameToNtPathName_U_WithStatus for inspiration. Opening a file should not do heap allocation for the path name.

@marler8997
Copy link
Contributor Author

The idea behind this PR was to remove the Windows logic from Zig's standard library and use the implementation that Windows provides instead for Nt path conversion. However, the interface that Windows provides requires heap allocation. @andrewrk has indicated that in order to avoid this heap allocation, we should duplicate the code inside ntdll in the Zig standard library so we can provide an interface that does not require heap allocation.

With this new direction, I'll have to start over so I'm going to close this PR and create a new one for the new direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

'.' and '..' components in relative paths in std.os.windows.OpenFile
3 participants