Skip to content

Commit 796f312

Browse files
committed
std.os.windows.GetFinalPathNameByHandle: remove QueryInformationFile code path
1 parent b75c0d4 commit 796f312

File tree

1 file changed

+20
-54
lines changed

1 file changed

+20
-54
lines changed

lib/std/os/windows.zig

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ pub const gdi32 = @import("windows/gdi32.zig");
2828

2929
pub usingnamespace @import("windows/bits.zig");
3030

31-
//version detection
32-
const version = std.zig.system.windows;
33-
const WindowsVersion = version.WindowsVersion;
34-
3531
pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));
3632

3733
pub const OpenError = error{
@@ -1033,65 +1029,35 @@ pub fn GetFinalPathNameByHandle(
10331029
out_buffer: []u16,
10341030
) GetFinalPathNameByHandleError![]u16 {
10351031
var path_buffer: [math.max(@sizeOf(FILE_NAME_INFORMATION), @sizeOf(OBJECT_NAME_INFORMATION)) + PATH_MAX_WIDE * 2]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined;
1036-
var volume_buffer: [@sizeOf(FILE_NAME_INFORMATION) + MAX_PATH]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined; // MAX_PATH bytes should be enough since it's Windows-defined name
1037-
1038-
var file_name_u16: []const u16 = undefined;
1039-
var volume_name_u16: []const u16 = undefined;
1040-
if ((comptime (std.builtin.os.version_range.windows.isAtLeast(WindowsVersion.win10_rs4) != true)) and !version.detectRuntimeVersion().isAtLeast(WindowsVersion.win10_rs4)) {
1041-
const final_path = QueryObjectName(hFile, mem.bytesAsSlice(u16, &path_buffer)) catch |err| return switch (err) {
1042-
// we assume InvalidHandle is close enough to FileNotFound in semantics
1043-
// to not further complicate the error set
1044-
error.InvalidHandle => error.FileNotFound,
1045-
else => |e| e,
1046-
};
1032+
const final_path = QueryObjectName(hFile, mem.bytesAsSlice(u16, &path_buffer)) catch |err| switch (err) {
1033+
// we assume InvalidHandle is close enough to FileNotFound in semantics
1034+
// to not further complicate the error set
1035+
error.InvalidHandle => return error.FileNotFound,
1036+
else => |e| return e,
1037+
};
10471038

1048-
if (fmt.volume_name == .Nt) {
1039+
switch (fmt.volume_name) {
1040+
.Nt => {
1041+
// the returned path is already in .Nt format
10491042
if (out_buffer.len < final_path.len) {
10501043
return error.NameTooLong;
10511044
}
10521045
mem.copy(u16, out_buffer, final_path);
10531046
return out_buffer[0..final_path.len];
1054-
}
1055-
1056-
//otherwise we need to parse the string for volume path for the .Dos logic below to work
1057-
const expected_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\");
1058-
1059-
// TODO find out if a path can start with something besides `\Device\<volume name>`,
1060-
// and if we need to handle it differently
1061-
// (i.e. how to determine the start and end of the volume name in that case)
1062-
if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) return error.Unexpected;
1063-
1064-
const index = mem.indexOfPos(u16, final_path, expected_prefix.len, &[_]u16{'\\'}) orelse unreachable;
1065-
volume_name_u16 = final_path[0..index];
1066-
file_name_u16 = final_path[index..];
1067-
1068-
//fallthrough for fmt.volume_name != .Nt
1069-
} else {
1070-
// Get normalized path; doesn't include volume name though.
1071-
try QueryInformationFile(hFile, .FileNormalizedNameInformation, &path_buffer);
1072-
const file_name = @ptrCast(*const FILE_NAME_INFORMATION, &path_buffer);
1073-
file_name_u16 = @ptrCast([*]const u16, &file_name.FileName)[0..@divExact(file_name.FileNameLength, 2)];
1074-
1075-
// Get NT volume name.
1076-
try QueryInformationFile(hFile, .FileVolumeNameInformation, &volume_buffer);
1077-
const volume_name_info = @ptrCast(*const FILE_NAME_INFORMATION, &volume_buffer);
1078-
volume_name_u16 = @ptrCast([*]const u16, &volume_name_info.FileName)[0..@divExact(volume_name_info.FileNameLength, 2)];
1047+
},
1048+
.Dos => {
1049+
// parse the string to separate volume path from file path
1050+
const expected_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\");
10791051

1080-
if (fmt.volume_name == .Nt) {
1081-
// Nothing to do, we simply copy the bytes to the user-provided buffer.
1082-
if (out_buffer.len < volume_name_u16.len + file_name_u16.len) return error.NameTooLong;
1052+
// TODO find out if a path can start with something besides `\Device\<volume name>`,
1053+
// and if we need to handle it differently
1054+
// (i.e. how to determine the start and end of the volume name in that case)
1055+
if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) return error.Unexpected;
10831056

1084-
mem.copy(u16, out_buffer, volume_name_u16);
1085-
mem.copy(u16, out_buffer[volume_name_u16.len..], file_name_u16);
1057+
const file_path_begin_index = mem.indexOfPos(u16, final_path, expected_prefix.len, &[_]u16{'\\'}) orelse unreachable;
1058+
const volume_name_u16 = final_path[0..file_path_begin_index];
1059+
const file_name_u16 = final_path[file_path_begin_index..];
10861060

1087-
return out_buffer[0 .. volume_name_u16.len + file_name_u16.len];
1088-
}
1089-
//fallthrough for fmt.volume_name != .Nt
1090-
}
1091-
1092-
switch (fmt.volume_name) {
1093-
.Nt => unreachable, //handled above
1094-
.Dos => {
10951061
// Get DOS volume name. DOS volume names are actually symbolic link objects to the
10961062
// actual NT volume. For example:
10971063
// (NT) \Device\HarddiskVolume4 => (DOS) \DosDevices\C: == (DOS) C:

0 commit comments

Comments
 (0)