authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-14 08:45:04+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-22 08:51:22+02:00
logd17c9b3591ba822df3af341a0d4cf5f004413f4a
treeff72017ff283e1b19312f0d223c71fc3b0fb5a31
parent9b00dc941bf641f171443d18466b5fc9cbcc882b

Fix incorrect byte format of REPARSE_DATA_BUFFER struct


2 files changed, 36 insertions(+), 28 deletions(-)

lib/std/os.zig+15-7
...@@ -2394,11 +2394,10 @@ pub const readlinkC = @compileError("deprecated: renamed to readlinkZ");...@@ -2394,11 +2394,10 @@ pub const readlinkC = @compileError("deprecated: renamed to readlinkZ");
2394/// See also `readlinkZ`.2394/// See also `readlinkZ`.
2395pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 {2395pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 {
2396 const w = windows;2396 const w = windows;
2397 const access_mode: w.DWORD = 0;
2398 const sharing = w.FILE_SHARE_DELETE | w.FILE_SHARE_READ | w.FILE_SHARE_WRITE;2397 const sharing = w.FILE_SHARE_DELETE | w.FILE_SHARE_READ | w.FILE_SHARE_WRITE;
2399 const disposition = w.OPEN_EXISTING;2398 const disposition = w.OPEN_EXISTING;
2400 const flags = w.FILE_FLAG_BACKUP_SEMANTICS | w.FILE_FLAG_OPEN_REPARSE_POINT;2399 const flags = w.FILE_FLAG_BACKUP_SEMANTICS | w.FILE_FLAG_OPEN_REPARSE_POINT;
2401 const handle = w.CreateFileW(file_path, access_mode, sharing, null, disposition, flags, null) catch |err| {2400 const handle = w.CreateFileW(file_path, 0, sharing, null, disposition, flags, null) catch |err| {
2402 switch (err) {2401 switch (err) {
2403 error.SharingViolation => return error.AccessDenied,2402 error.SharingViolation => return error.AccessDenied,
2404 error.PathAlreadyExists => unreachable,2403 error.PathAlreadyExists => unreachable,
...@@ -2406,22 +2405,31 @@ pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8...@@ -2406,22 +2405,31 @@ pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8
2406 else => |e| return e,2405 else => |e| return e,
2407 }2406 }
2408 };2407 };
2409 var reparse_buf: [w.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;2408 var reparse_buf align(@alignOf(w.REPARSE_DATA_BUFFER)) = [_]u8{0} ** (w.MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
2410 _ = try w.DeviceIoControl(handle, w.FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);2409 _ = try w.DeviceIoControl(handle, w.FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);
2411 const reparse_struct = mem.bytesAsValue(w.REPARSE_DATA_BUFFER, reparse_buf[0..@sizeOf(w.REPARSE_DATA_BUFFER)]);2410 const reparse_struct = @ptrCast(*const w.REPARSE_DATA_BUFFER, &reparse_buf[0]);
2412 switch (reparse_struct.ReparseTag) {2411 switch (reparse_struct.ReparseTag) {
2413 w.IO_REPARSE_TAG_SYMLINK => {2412 w.IO_REPARSE_TAG_SYMLINK => {
2414 std.debug.warn("got symlink!", .{});2413 const alignment = @alignOf(w.SymbolicLinkReparseBuffer);
2414 const buf = @ptrCast(*const w.SymbolicLinkReparseBuffer, @alignCast(alignment, &reparse_struct.DataBuffer[0]));
2415 const offset = buf.SubstituteNameOffset / 2;
2416 const len = buf.SubstituteNameLength / 2;
2417 const f = buf.Flags;
2418 const path_buf = @as([*]const u16, &buf.PathBuffer);
2419 std.debug.warn("got symlink => offset={}, len={}, flags = {}, {}\n", .{ offset, len, f, w.SYMLINK_FLAG_RELATIVE });
2420 // TODO handle absolute paths and namespace prefix
2421 const out_len = std.unicode.utf16leToUtf8(out_buffer, path_buf[offset .. offset + len]) catch unreachable;
2422 std.debug.warn("got symlink => utf8={}\n", .{out_buffer[0..out_len]});
2423 return out_buffer[0..out_len];
2415 },2424 },
2416 w.IO_REPARSE_TAG_MOUNT_POINT => {2425 w.IO_REPARSE_TAG_MOUNT_POINT => {
2417 std.debug.warn("got mount point!", .{});2426 @panic("TODO parse mount point");
2418 },2427 },
2419 else => |value| {2428 else => |value| {
2420 std.debug.warn("unsupported symlink type: {}", .{value});2429 std.debug.warn("unsupported symlink type: {}", .{value});
2421 return error.UnsupportedSymlinkType;2430 return error.UnsupportedSymlinkType;
2422 },2431 },
2423 }2432 }
2424 @panic("Oh no!");
2425}2433}
24262434
2427/// Same as `readlink` except `file_path` is null-terminated.2435/// Same as `readlink` except `file_path` is null-terminated.
lib/std/os/windows/bits.zig+21-21
...@@ -1544,31 +1544,31 @@ pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;...@@ -1544,31 +1544,31 @@ pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
1544pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW;1544pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW;
15451545
1546pub const REPARSE_DATA_BUFFER = extern struct {1546pub const REPARSE_DATA_BUFFER = extern struct {
1547 ReparseTag: ULONG, ReparseDataLength: USHORT, Reserved: USHORT, u: extern union {1547 ReparseTag: ULONG,
1548 SymbolicLinkReparseBuffer: extern struct {1548 ReparseDataLength: USHORT,
1549 SubstituteNameOffset: USHORT,1549 Reserved: USHORT,
1550 SubstituteNameLength: USHORT,1550 DataBuffer: [1]UCHAR,
1551 PrintNameOffset: USHORT,1551};
1552 PrintNameLength: USHORT,1552pub const SymbolicLinkReparseBuffer = extern struct {
1553 Flags: ULONG,1553 SubstituteNameOffset: USHORT,
1554 PathBuffer: [1]WCHAR,1554 SubstituteNameLength: USHORT,
1555 },1555 PrintNameOffset: USHORT,
1556 MountPointReparseBuffer: extern struct {1556 PrintNameLength: USHORT,
1557 SubstituteNameOffset: USHORT,1557 Flags: ULONG,
1558 SubstituteNameLength: USHORT,1558 PathBuffer: [1]WCHAR,
1559 PrintNameOffset: USHORT,1559};
1560 PrintNameLength: USHORT,1560pub const MountPointReparseBuffer = extern struct {
1561 PathBuffer: [1]WCHAR,1561 SubstituteNameOffset: USHORT,
1562 },1562 SubstituteNameLength: USHORT,
1563 GenericReparseBuffer: extern struct {1563 PrintNameOffset: USHORT,
1564 DataBuffer: [1]UCHAR,1564 PrintNameLength: USHORT,
1565 },1565 PathBuffer: [1]WCHAR,
1566 }
1567};1566};
1568pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;1567pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: ULONG = 16 * 1024;
1569pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;1568pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
1570pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;1569pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;
1571pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;1570pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;
1571pub const SYMLINK_FLAG_RELATIVE: ULONG = 0x1;
15721572
1573pub const SYMBOLIC_LINK_FLAG_FILE: DWORD = 0x0;1573pub const SYMBOLIC_LINK_FLAG_FILE: DWORD = 0x0;
1574pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;1574pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;