| ... | ... | @@ -377,6 +377,8 @@ pub const Dir = struct { |
| 377 | 377 | }; |
| 378 | 378 | }; |
| 379 | 379 | |
| 380 | const IteratorError = error{AccessDenied} || os.UnexpectedError; |
| 381 | |
| 380 | 382 | pub const Iterator = switch (builtin.os) { |
| 381 | 383 | .macosx, .ios, .freebsd, .netbsd => struct { |
| 382 | 384 | dir: Dir, |
| ... | ... | @@ -387,9 +389,11 @@ pub const Dir = struct { |
| 387 | 389 | |
| 388 | 390 | const Self = @This(); |
| 389 | 391 | |
| 392 | pub const Error = IteratorError; |
| 393 | |
| 390 | 394 | /// Memory such as file names referenced in this returned entry becomes invalid |
| 391 | 395 | /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized. |
| 392 | | pub fn next(self: *Self) !?Entry { |
| 396 | pub fn next(self: *Self) Error!?Entry { |
| 393 | 397 | switch (builtin.os) { |
| 394 | 398 | .macosx, .ios => return self.nextDarwin(), |
| 395 | 399 | .freebsd, .netbsd => return self.nextBsd(), |
| ... | ... | @@ -504,9 +508,11 @@ pub const Dir = struct { |
| 504 | 508 | |
| 505 | 509 | const Self = @This(); |
| 506 | 510 | |
| 511 | pub const Error = IteratorError; |
| 512 | |
| 507 | 513 | /// Memory such as file names referenced in this returned entry becomes invalid |
| 508 | 514 | /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized. |
| 509 | | pub fn next(self: *Self) !?Entry { |
| 515 | pub fn next(self: *Self) Error!?Entry { |
| 510 | 516 | start_over: while (true) { |
| 511 | 517 | if (self.index >= self.end_index) { |
| 512 | 518 | const rc = os.linux.getdents64(self.dir.fd, &self.buf, self.buf.len); |
| ... | ... | @@ -560,17 +566,13 @@ pub const Dir = struct { |
| 560 | 566 | |
| 561 | 567 | const Self = @This(); |
| 562 | 568 | |
| 563 | | pub fn next(self: *Self) !?Entry { |
| 569 | pub const Error = IteratorError; |
| 570 | |
| 571 | pub fn next(self: *Self) Error!?Entry { |
| 564 | 572 | start_over: while (true) { |
| 565 | 573 | const w = os.windows; |
| 566 | 574 | if (self.index >= self.end_index) { |
| 567 | 575 | var io: w.IO_STATUS_BLOCK = undefined; |
| 568 | | //var mask_buf = [2]u16{ 'a', 0 }; |
| 569 | | //var mask = w.UNICODE_STRING{ |
| 570 | | // .Length = 2, |
| 571 | | // .MaximumLength = 2, |
| 572 | | // .Buffer = &mask_buf, |
| 573 | | //}; |
| 574 | 576 | const rc = w.ntdll.NtQueryDirectoryFile( |
| 575 | 577 | self.dir.fd, |
| 576 | 578 | null, |
| ... | ... | @@ -709,7 +711,6 @@ pub const Dir = struct { |
| 709 | 711 | |
| 710 | 712 | /// Call `close` on the result when done. |
| 711 | 713 | pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir { |
| 712 | | // std.debug.warn("openDir {}\n", sub_path); |
| 713 | 714 | if (os.windows.is_the_target) { |
| 714 | 715 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 715 | 716 | return self.openDirW(&sub_path_w); |
| ... | ... | @@ -746,39 +747,7 @@ pub const Dir = struct { |
| 746 | 747 | .fd = undefined, |
| 747 | 748 | }; |
| 748 | 749 | |
| 749 | | const desired_access = w.GENERIC_READ | w.SYNCHRONIZE; |
| 750 | | |
| 751 | | // if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { |
| 752 | | // // Windows gives me STATUS_OBJECT_NAME_INVALID with "." as the object name. |
| 753 | | |
| 754 | | // if (w.kernel32.DuplicateHandle(w.self_process_handle, self.fd, w.self_process_handle, &result.fd, desired_access, w.TRUE, 0) == 0) { |
| 755 | | // switch (w.kernel32.GetLastError()) { |
| 756 | | // else => |err| return w.unexpectedError(err), |
| 757 | | // } |
| 758 | | |
| 759 | | // @panic("handle DuplicateHandle error"); |
| 760 | | // } |
| 761 | | // return result; |
| 762 | | // } |
| 763 | | |
| 764 | | //var mask: ?[*]const u16 = undefined; |
| 765 | | //var nt_name: w.UNICODE_STRING = undefined; |
| 766 | | //if (w.ntdll.RtlDosPathNameToNtPathName_U(sub_path_w, &nt_name, null, null) == 0) { |
| 767 | | // return error.FileNotFound; |
| 768 | | //} |
| 769 | | //defer w.ntdll.RtlFreeUnicodeString(&nt_name); |
| 770 | | //if (mask) |m| { |
| 771 | | // if (m[0] == 0) { |
| 772 | | // return error.FileNotFound; |
| 773 | | // } else { |
| 774 | | // nt_name.Length = @intCast(u16, @ptrToInt(mask) - @ptrToInt(nt_name.Buffer)); |
| 775 | | // } |
| 776 | | //} else { |
| 777 | | // return error.FileNotFound; |
| 778 | | //} |
| 779 | | |
| 780 | 750 | const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2); |
| 781 | | // std.debug.warn("path_len_bytes = {}\n", path_len_bytes); |
| 782 | 751 | var nt_name = w.UNICODE_STRING{ |
| 783 | 752 | .Length = path_len_bytes, |
| 784 | 753 | .MaximumLength = path_len_bytes, |
| ... | ... | @@ -796,19 +765,15 @@ pub const Dir = struct { |
| 796 | 765 | // Windows does not recognize this, but it does work with empty string. |
| 797 | 766 | nt_name.Length = 0; |
| 798 | 767 | } |
| 799 | | // std.debug.warn("RootDirectory = {}\n", attr.RootDirectory); |
| 768 | if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) { |
| 769 | // If you're looking to contribute to zig and fix this, see here for an example of how to |
| 770 | // implement this: https://git.midipix.org/ntapi/tree/src/fs/ntapi_tt_open_physical_parent_directory.c |
| 771 | @panic("TODO opening '..' with a relative directory handle is not yet implemented on Windows"); |
| 772 | } |
| 800 | 773 | var io: w.IO_STATUS_BLOCK = undefined; |
| 801 | | const wide_slice = nt_name.Buffer[0 .. nt_name.Length / 2]; |
| 802 | | //const wide_slice2 = std.mem.toSliceConst(u16, mask.?); |
| 803 | | var buf: [200]u8 = undefined; |
| 804 | | //var buf2: [200]u8 = undefined; |
| 805 | | const len = std.unicode.utf16leToUtf8(&buf, wide_slice) catch unreachable; |
| 806 | | //const len2 = std.unicode.utf16leToUtf8(&buf2, wide_slice2) catch unreachable; |
| 807 | | // std.debug.warn("path: {}\n", buf[0..len]); |
| 808 | | //std.debug.warn("path: {}\nmask: {}\n", buf[0..len], buf2[0..len2]); |
| 809 | 774 | const rc = w.ntdll.NtCreateFile( |
| 810 | 775 | &result.fd, |
| 811 | | desired_access, |
| 776 | w.GENERIC_READ | w.SYNCHRONIZE, |
| 812 | 777 | &attr, |
| 813 | 778 | &io, |
| 814 | 779 | null, |
| ... | ... | @@ -819,15 +784,12 @@ pub const Dir = struct { |
| 819 | 784 | null, |
| 820 | 785 | 0, |
| 821 | 786 | ); |
| 822 | | // std.debug.warn("result.fd = {}\n", result.fd); |
| 823 | 787 | switch (rc) { |
| 824 | 788 | w.STATUS.SUCCESS => return result, |
| 825 | | w.STATUS.OBJECT_NAME_INVALID => @panic("openDirW invalid object name"), |
| 789 | w.STATUS.OBJECT_NAME_INVALID => unreachable, |
| 826 | 790 | w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 827 | 791 | w.STATUS.OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| 828 | | w.STATUS.INVALID_PARAMETER => { |
| 829 | | @panic("invalid parameter"); |
| 830 | | }, |
| 792 | w.STATUS.INVALID_PARAMETER => unreachable, |
| 831 | 793 | else => return w.unexpectedStatus(rc), |
| 832 | 794 | } |
| 833 | 795 | } |