Skip to content

Commit

Permalink
Deal with NT paths in GetFinalPathNameByHandle
Browse files Browse the repository at this point in the history
When calling QueryObjectName, NT namespaced paths can be returned. This
change appropriately strips the prefix to turn it into an absolute path.

(The above behaviour was observed at least in Wine so far)
  • Loading branch information
moosichu committed Oct 15, 2023
1 parent 7abf9b3 commit 21837c9
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion lib/std/os/windows.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,21 @@ pub fn GetFinalPathNameByHandle(
// TODO find out if a path can start with something besides `\Device\<volume name>`,
// and if we need to handle it differently
// (i.e. how to determine the start and end of the volume name in that case)
if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) return error.Unexpected;
if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) {
// Wine seems to return NT namespaced paths from QueryObjectName
// (e.g. `\??\Z:\some\path\to\a\file.txt`), in which case we can just strip the
// prefix to turn it into an absolute path
if (getNamespacePrefix(u16, final_path) == .nt) {
const unprefixed_path = final_path[4..];
// TODO: Handle other possible path types, only drive absolute has been observed so far
if (getUnprefixedPathType(unprefixed_path) != .drive_absolute) {
return error.Unexpected;
}
mem.copyForwards(u16, out_buffer[0..unprefixed_path.len], unprefixed_path);
return out_buffer[0..unprefixed_path.len];
}
return error.Unexpected;
}

const file_path_begin_index = mem.indexOfPos(u16, final_path, expected_prefix.len, &[_]u16{'\\'}) orelse unreachable;
const volume_name_u16 = final_path[0..file_path_begin_index];
Expand Down

0 comments on commit 21837c9

Please sign in to comment.