mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
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
This commit is contained in:
parent
813e8614bc
commit
06a7597ea8
3 changed files with 23 additions and 52 deletions
|
|
@ -889,61 +889,26 @@ pub const ReadLinkError = error{
|
||||||
AccessDenied,
|
AccessDenied,
|
||||||
Unexpected,
|
Unexpected,
|
||||||
NameTooLong,
|
NameTooLong,
|
||||||
|
BadPathName,
|
||||||
|
AntivirusInterference,
|
||||||
UnsupportedReparsePointType,
|
UnsupportedReparsePointType,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
|
pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
|
||||||
// Here, we use `NtCreateFile` to shave off one syscall if we were to use `OpenFile` wrapper.
|
const result_handle = OpenFile(sub_path_w, .{
|
||||||
// With the latter, we'd need to call `NtCreateFile` twice, once for file symlink, and if that
|
.access_mask = FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||||||
// failed, again for dir symlink. Omitting any mention of file/dir flags makes it possible
|
.dir = dir,
|
||||||
// to open the symlink there and then.
|
.creation = FILE_OPEN,
|
||||||
const path_len_bytes = math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
|
.follow_symlinks = false,
|
||||||
var nt_name = UNICODE_STRING{
|
.filter = .any,
|
||||||
.Length = path_len_bytes,
|
}) catch |err| switch (err) {
|
||||||
.MaximumLength = path_len_bytes,
|
error.IsDir, error.NotDir => return error.Unexpected, // filter = .any
|
||||||
.Buffer = @constCast(sub_path_w.ptr),
|
error.PathAlreadyExists => return error.Unexpected, // FILE_OPEN
|
||||||
|
error.WouldBlock => return error.Unexpected,
|
||||||
|
error.NoDevice => return error.FileNotFound,
|
||||||
|
error.PipeBusy => return error.AccessDenied,
|
||||||
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
var attr = OBJECT_ATTRIBUTES{
|
|
||||||
.Length = @sizeOf(OBJECT_ATTRIBUTES),
|
|
||||||
.RootDirectory = if (std.fs.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir,
|
|
||||||
.Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
|
|
||||||
.ObjectName = &nt_name,
|
|
||||||
.SecurityDescriptor = null,
|
|
||||||
.SecurityQualityOfService = null,
|
|
||||||
};
|
|
||||||
var result_handle: HANDLE = undefined;
|
|
||||||
var io: IO_STATUS_BLOCK = undefined;
|
|
||||||
|
|
||||||
const rc = ntdll.NtCreateFile(
|
|
||||||
&result_handle,
|
|
||||||
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
|
||||||
&attr,
|
|
||||||
&io,
|
|
||||||
null,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
FILE_OPEN,
|
|
||||||
FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT,
|
|
||||||
null,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
switch (rc) {
|
|
||||||
.SUCCESS => {},
|
|
||||||
.OBJECT_NAME_INVALID => unreachable,
|
|
||||||
.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
|
|
||||||
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
|
|
||||||
.NO_MEDIA_IN_DEVICE => return error.FileNotFound,
|
|
||||||
.BAD_NETWORK_PATH => return error.NetworkNotFound, // \\server was not found
|
|
||||||
.BAD_NETWORK_NAME => return error.NetworkNotFound, // \\server was found but \\server\share wasn't
|
|
||||||
.INVALID_PARAMETER => unreachable,
|
|
||||||
.SHARING_VIOLATION => return error.AccessDenied,
|
|
||||||
.ACCESS_DENIED => return error.AccessDenied,
|
|
||||||
.PIPE_BUSY => return error.AccessDenied,
|
|
||||||
.OBJECT_PATH_SYNTAX_BAD => unreachable,
|
|
||||||
.OBJECT_NAME_COLLISION => unreachable,
|
|
||||||
.FILE_IS_A_DIRECTORY => unreachable,
|
|
||||||
else => return unexpectedStatus(rc),
|
|
||||||
}
|
|
||||||
defer CloseHandle(result_handle);
|
defer CloseHandle(result_handle);
|
||||||
|
|
||||||
var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 align(@alignOf(REPARSE_DATA_BUFFER)) = undefined;
|
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
|
||||||
const path_buf = @as([*]const u16, &buf.PathBuffer);
|
const path_buf = @as([*]const u16, &buf.PathBuffer);
|
||||||
return parseReadlinkPath(path_buf[offset..][0..len], false, out_buffer);
|
return parseReadlinkPath(path_buf[offset..][0..len], false, out_buffer);
|
||||||
},
|
},
|
||||||
else => |value| {
|
else => {
|
||||||
std.debug.print("unsupported symlink type: {}", .{value});
|
|
||||||
return error.UnsupportedReparsePointType;
|
return error.UnsupportedReparsePointType;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3001,6 +3001,12 @@ pub const ReadLinkError = error{
|
||||||
UnsupportedReparsePointType,
|
UnsupportedReparsePointType,
|
||||||
/// On Windows, `\\server` or `\\server\share` was not found.
|
/// On Windows, `\\server` or `\\server\share` was not found.
|
||||||
NetworkNotFound,
|
NetworkNotFound,
|
||||||
|
/// On Windows, antivirus software is enabled by default. It can be
|
||||||
|
/// disabled, but Windows Update sometimes ignores the user's preference
|
||||||
|
/// and re-enables it. When enabled, antivirus software on Windows
|
||||||
|
/// intercepts file system operations and makes them significantly slower
|
||||||
|
/// in addition to possibly failing with this error code.
|
||||||
|
AntivirusInterference,
|
||||||
} || UnexpectedError;
|
} || UnexpectedError;
|
||||||
|
|
||||||
/// Read value of a symbolic link.
|
/// Read value of a symbolic link.
|
||||||
|
|
|
||||||
|
|
@ -705,6 +705,7 @@ fn abiAndDynamicLinkerFromFile(
|
||||||
error.BadPathName => unreachable, // Windows only
|
error.BadPathName => unreachable, // Windows only
|
||||||
error.UnsupportedReparsePointType => unreachable, // Windows only
|
error.UnsupportedReparsePointType => unreachable, // Windows only
|
||||||
error.NetworkNotFound => unreachable, // Windows only
|
error.NetworkNotFound => unreachable, // Windows only
|
||||||
|
error.AntivirusInterference => unreachable, // Windows only
|
||||||
|
|
||||||
error.AccessDenied,
|
error.AccessDenied,
|
||||||
error.PermissionDenied,
|
error.PermissionDenied,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue