Commit 9b00dc941b
Changed files (3)
lib
std
os
windows
lib/std/os/windows/bits.zig
@@ -1543,7 +1543,7 @@ pub const LPOSVERSIONINFOW = *OSVERSIONINFOW;
pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW;
-pub const _REPARSE_DATA_BUFFER = extern struct {
+pub const REPARSE_DATA_BUFFER = extern struct {
ReparseTag: ULONG, ReparseDataLength: USHORT, Reserved: USHORT, u: extern union {
SymbolicLinkReparseBuffer: extern struct {
SubstituteNameOffset: USHORT,
@@ -1572,4 +1572,4 @@ pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;
pub const SYMBOLIC_LINK_FLAG_FILE: DWORD = 0x0;
pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
-pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
\ No newline at end of file
+pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
lib/std/os/windows.zig
@@ -1370,54 +1370,4 @@ pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {
std.debug.dumpCurrentStackTrace(null);
}
return error.Unexpected;
-}
-
-pub fn ReadLink(path_w: []const u16) OpenError!HANDLE {
- var result: HANDLE = undefined;
-
- const path_len_bytes = math.cast(u16, path_w.len * 2) catch |err| switch (err) {
- error.Overflow => return error.NameTooLong,
- };
- var nt_name = UNICODE_STRING{
- .Length = path_len_bytes,
- .MaximumLength = path_len_bytes,
- .Buffer = @intToPtr([*]u16, @ptrToInt(path_w.ptr)),
- };
- var attr = OBJECT_ATTRIBUTES{
- .Length = @sizeOf(OBJECT_ATTRIBUTES),
- .RootDirectory = null,
- .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
- .ObjectName = &nt_name,
- .SecurityDescriptor = null,
- .SecurityQualityOfService = null,
- };
- var io: IO_STATUS_BLOCK = undefined;
- const rc = ntdll.NtCreateFile(
- &result,
- FILE_LIST_DIRECTORY,
- &attr,
- &io,
- null,
- FILE_ATTRIBUTE_NORMAL,
- FILE_SHARE_READ | FILE_SHARE_DELETE,
- FILE_OPEN,
- FILE_OPEN_REPARSE_POINT,
- null,
- 0,
- );
- switch (rc) {
- .SUCCESS => return result,
- .OBJECT_NAME_INVALID => unreachable,
- .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
- .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
- .NO_MEDIA_IN_DEVICE => return error.NoDevice,
- .INVALID_PARAMETER => unreachable,
- .SHARING_VIOLATION => return error.WouldBlock,
- .ACCESS_DENIED => return error.AccessDenied,
- .PIPE_BUSY => return error.PipeBusy,
- .OBJECT_PATH_SYNTAX_BAD => unreachable,
- .OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
- .FILE_IS_A_DIRECTORY => return error.IsDir,
- else => return unexpectedStatus(rc),
- }
}
\ No newline at end of file
lib/std/os.zig
@@ -2381,7 +2381,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
@compileError("readlink is not supported in WASI; use readlinkat instead");
} else if (builtin.os.tag == .windows) {
const file_path_w = try windows.sliceToPrefixedFileW(file_path);
- return readlinkW(file_path_w.span(), out_buffer);
+ return readlinkW(file_path_w.span().ptr, out_buffer);
} else {
const file_path_c = try toPosixPath(file_path);
return readlinkZ(&file_path_c, out_buffer);
@@ -2392,26 +2392,28 @@ pub const readlinkC = @compileError("deprecated: renamed to readlinkZ");
/// Windows-only. Same as `readlink` except `file_path` is null-terminated, WTF16 encoded.
/// See also `readlinkZ`.
-pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
- const handle = windows.ReadLink(file_path) catch |err| {
+pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 {
+ const w = windows;
+ const access_mode: w.DWORD = 0;
+ const sharing = w.FILE_SHARE_DELETE | w.FILE_SHARE_READ | w.FILE_SHARE_WRITE;
+ const disposition = w.OPEN_EXISTING;
+ const flags = w.FILE_FLAG_BACKUP_SEMANTICS | w.FILE_FLAG_OPEN_REPARSE_POINT;
+ const handle = w.CreateFileW(file_path, access_mode, sharing, null, disposition, flags, null) catch |err| {
switch (err) {
- error.IsDir => unreachable,
- error.NoDevice => return error.FileNotFound,
error.SharingViolation => return error.AccessDenied,
- error.PipeBusy => unreachable,
error.PathAlreadyExists => unreachable,
- error.WouldBlock => unreachable,
+ error.PipeBusy => unreachable,
else => |e| return e,
}
};
- var reparse_buf: [windows.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;
- _ = try windows.DeviceIoControl(handle, windows.FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);
- const reparse_struct = mem.bytesAsValue(windows._REPARSE_DATA_BUFFER, reparse_buf[0..@sizeOf(windows._REPARSE_DATA_BUFFER)]);
+ var reparse_buf: [w.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;
+ _ = try w.DeviceIoControl(handle, w.FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);
+ const reparse_struct = mem.bytesAsValue(w.REPARSE_DATA_BUFFER, reparse_buf[0..@sizeOf(w.REPARSE_DATA_BUFFER)]);
switch (reparse_struct.ReparseTag) {
- windows.IO_REPARSE_TAG_SYMLINK => {
+ w.IO_REPARSE_TAG_SYMLINK => {
std.debug.warn("got symlink!", .{});
},
- windows.IO_REPARSE_TAG_MOUNT_POINT => {
+ w.IO_REPARSE_TAG_MOUNT_POINT => {
std.debug.warn("got mount point!", .{});
},
else => |value| {
@@ -2426,7 +2428,7 @@ pub fn readlinkW(file_path: []const u16, out_buffer: []u8) ReadLinkError![]u8 {
pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
if (builtin.os.tag == .windows) {
const file_path_w = try windows.cStrToPrefixedFileW(file_path);
- return readlinkW(file_path_w.span(), out_buffer);
+ return readlinkW(file_path_w.span().ptr, out_buffer);
}
const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);
switch (errno(rc)) {