authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-12 23:03:09+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-07-22 08:51:22+02:00
logcc83d92b0b12f5b3fa6462ed878cd7bec7412940
treea8fa37b91ae55fb9b0ba3ca6a268079b9c5372ab
parent9225763f8bd3ab7062a55e6f9200657205c20e3b

Start drafting out os.readlink on Windows


2 files changed, 57 insertions(+), 2 deletions(-)

lib/std/os.zig+30-2
......@@ -2355,6 +2355,8 @@ pub const ReadLinkError = error{
23552355 FileNotFound,
23562356 SystemResources,
23572357 NotDir,
2358 /// Windows-only.
2359 UnsupportedSymlinkType,
23582360} || UnexpectedError;
23592361
23602362/// Read value of a symbolic link.
......@@ -2373,9 +2375,35 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
23732375
23742376pub const readlinkC = @compileError("deprecated: renamed to readlinkZ");
23752377
2376/// Windows-only. Same as `readlink` expecte `file_path` is null-terminated, WTF16 encoded.
2377/// Seel also `readlinkZ`.
2378/// Windows-only. Same as `readlink` except `file_path` is null-terminated, WTF16 encoded.
2379/// See also `readlinkZ`.
23782380pub fn readlinkW(file_path: [*:0]const u16, out_buffer: []u8) ReadLinkError![]u8 {
2381 const handle = windows.OpenFile(file_path, .{
2382 .access_mask = 0,
2383 .creation = c.FILE_OPEN_REPARSE_POINT | c.FILE_LIST_DIRECTORY,
2384 .io_mode = 0,
2385 }) catch |err| {
2386 switch (err) {
2387 error.IsDir => unreachable,
2388 error.NoDevice => return error.FileNotFound,
2389 error.SharingViolation => return error.AccessDenied,
2390 error.PipeBusy => unreachable,
2391 error.PathAlreadyExists => unreachable,
2392 error.WouldBlock => unreachable,
2393 else => return err,
2394 }
2395 };
2396 var reparse_buf: [windows.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;
2397 _ = try windows.DeviceIoControl(handle, windows.FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);
2398 const reparse_struct = @bitCast(windows._REPARSE_DATA_BUFFER, reparse_buf[0..@sizeOf(windows._REPARSE_DATA_BUFFER)]);
2399 switch (reparse_struct.ReparseTag) {
2400 windows.IO_REPARSE_TAG_SYMLINK => {},
2401 windows.IO_REPARSE_TAG_MOUNT_POINT => {},
2402 else => |value| {
2403 std.debug.print("unsupported symlink type: {}", value);
2404 return error.UnsupportedSymlinkType;
2405 },
2406 }
23792407 @compileError("TODO implement readlink for Windows");
23802408}
23812409
lib/std/os/windows/bits.zig+27
......@@ -1542,3 +1542,30 @@ pub const POSVERSIONINFOW = *OSVERSIONINFOW;
15421542pub const LPOSVERSIONINFOW = *OSVERSIONINFOW;
15431543pub const RTL_OSVERSIONINFOW = OSVERSIONINFOW;
15441544pub const PRTL_OSVERSIONINFOW = *RTL_OSVERSIONINFOW;
1545
1546pub const _REPARSE_DATA_BUFFER = extern struct {
1547 ReparseTag: ULONG, ReparseDataLength: USHORT, Reserved: USHORT, u: extern union {
1548 SymbolicLinkReparseBuffer: extern struct {
1549 SubstituteNameOffset: USHORT,
1550 SubstituteNameLength: USHORT,
1551 PrintNameOffset: USHORT,
1552 PrintNameLength: USHORT,
1553 Flags: ULONG,
1554 PathBuffer: [1]WCHAR,
1555 },
1556 MountPointReparseBuffer: extern struct {
1557 SubstituteNameOffset: USHORT,
1558 SubstituteNameLength: USHORT,
1559 PrintNameOffset: USHORT,
1560 PrintNameLength: USHORT,
1561 PathBuffer: [1]WCHAR,
1562 },
1563 GenericReparseBuffer: extern struct {
1564 DataBuffer: [1]UCHAR,
1565 },
1566 }
1567};
1568pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
1569pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
1570pub const IO_REPARSE_TAG_SYMLINK: ULONG = 0xa000000c;
1571pub const IO_REPARSE_TAG_MOUNT_POINT: ULONG = 0xa0000003;