Skip to content

Commit 06a7597

Browse files
committed
windows.ReadLink: Use OpenFile now that .filter = .any exists
The reasoning in the comment deleted by this commit no longer applies, since that same benefit can be obtained by using OpenFile with `.filter = .any`. Also removes a stray debug.print
1 parent 813e861 commit 06a7597

File tree

3 files changed

+23
-52
lines changed

3 files changed

+23
-52
lines changed

lib/std/os/windows.zig

Lines changed: 16 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -889,61 +889,26 @@ pub const ReadLinkError = error{
889889
AccessDenied,
890890
Unexpected,
891891
NameTooLong,
892+
BadPathName,
893+
AntivirusInterference,
892894
UnsupportedReparsePointType,
893895
};
894896

895897
pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
896-
// Here, we use `NtCreateFile` to shave off one syscall if we were to use `OpenFile` wrapper.
897-
// With the latter, we'd need to call `NtCreateFile` twice, once for file symlink, and if that
898-
// failed, again for dir symlink. Omitting any mention of file/dir flags makes it possible
899-
// to open the symlink there and then.
900-
const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
901-
var nt_name = UNICODE_STRING{
902-
.Length = path_len_bytes,
903-
.MaximumLength = path_len_bytes,
904-
.Buffer = @constCast(sub_path_w.ptr),
905-
};
906-
var attr = OBJECT_ATTRIBUTES{
907-
.Length = @sizeOf(OBJECT_ATTRIBUTES),
908-
.RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir,
909-
.Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
910-
.ObjectName = &nt_name,
911-
.SecurityDescriptor = null,
912-
.SecurityQualityOfService = null,
898+
const result_handle = OpenFile(sub_path_w, .{
899+
.access_mask = FILE_READ_ATTRIBUTES | SYNCHRONIZE,
900+
.dir = dir,
901+
.creation = FILE_OPEN,
902+
.follow_symlinks = false,
903+
.filter = .any,
904+
}) catch |err| switch (err) {
905+
error.IsDir, error.NotDir => return error.Unexpected, // filter = .any
906+
error.PathAlreadyExists => return error.Unexpected, // FILE_OPEN
907+
error.WouldBlock => return error.Unexpected,
908+
error.NoDevice => return error.FileNotFound,
909+
error.PipeBusy => return error.AccessDenied,
910+
else => |e| return e,
913911
};
914-
var result_handle: HANDLE = undefined;
915-
var io: IO_STATUS_BLOCK = undefined;
916-
917-
const rc = ntdll.NtCreateFile(
918-
&result_handle,
919-
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
920-
&attr,
921-
&io,
922-
null,
923-
FILE_ATTRIBUTE_NORMAL,
924-
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
925-
FILE_OPEN,
926-
FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT,
927-
null,
928-
0,
929-
);
930-
switch (rc) {
931-
.SUCCESS => {},
932-
.OBJECT_NAME_INVALID => unreachable,
933-
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
934-
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
935-
.NO_MEDIA_IN_DEVICE => return error.FileNotFound,
936-
.BAD_NETWORK_PATH => return error.NetworkNotFound, // \\server was not found
937-
.BAD_NETWORK_NAME => return error.NetworkNotFound, // \\server was found but \\server\share wasn't
938-
.INVALID_PARAMETER => unreachable,
939-
.SHARING_VIOLATION => return error.AccessDenied,
940-
.ACCESS_DENIED => return error.AccessDenied,
941-
.PIPE_BUSY => return error.AccessDenied,
942-
.OBJECT_PATH_SYNTAX_BAD => unreachable,
943-
.OBJECT_NAME_COLLISION => unreachable,
944-
.FILE_IS_A_DIRECTORY => unreachable,
945-
else => return unexpectedStatus(rc),
946-
}
947912
defer CloseHandle(result_handle);
948913

949914
var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(REPARSE_DATA_BUFFER)) = undefined;
@@ -970,8 +935,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin
970935
const path_buf = @as([*]const u16, &buf.PathBuffer);
971936
return parseReadlinkPath(path_buf[offset..][0..len], false, out_buffer);
972937
},
973-
else => |value| {
974-
std.debug.print("unsupported symlink type: {}", .{value});
938+
else => {
975939
return error.UnsupportedReparsePointType;
976940
},
977941
}

lib/std/posix.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3001,6 +3001,12 @@ pub const ReadLinkError = error{
30013001
UnsupportedReparsePointType,
30023002
/// On Windows, `\\server` or `\\server\share` was not found.
30033003
NetworkNotFound,
3004+
/// On Windows, antivirus software is enabled by default. It can be
3005+
/// disabled, but Windows Update sometimes ignores the user's preference
3006+
/// and re-enables it. When enabled, antivirus software on Windows
3007+
/// intercepts file system operations and makes them significantly slower
3008+
/// in addition to possibly failing with this error code.
3009+
AntivirusInterference,
30043010
} || UnexpectedError;
30053011

30063012
/// Read value of a symbolic link.

lib/std/zig/system.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ fn abiAndDynamicLinkerFromFile(
705705
error.BadPathName => unreachable, // Windows only
706706
error.UnsupportedReparsePointType => unreachable, // Windows only
707707
error.NetworkNotFound => unreachable, // Windows only
708+
error.AntivirusInterference => unreachable, // Windows only
708709

709710
error.AccessDenied,
710711
error.PermissionDenied,

0 commit comments

Comments
 (0)