| ... | ... | @@ -590,6 +590,7 @@ pub const Dir = struct { |
| 590 | 590 | self.end_index = io.Information; |
| 591 | 591 | switch (rc) { |
| 592 | 592 | w.STATUS.SUCCESS => {}, |
| 593 | w.STATUS.ACCESS_DENIED => return error.AccessDenied, |
| 593 | 594 | else => return w.unexpectedStatus(rc), |
| 594 | 595 | } |
| 595 | 596 | } |
| ... | ... | @@ -708,7 +709,7 @@ pub const Dir = struct { |
| 708 | 709 | |
| 709 | 710 | /// Call `close` on the result when done. |
| 710 | 711 | pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir { |
| 711 | | std.debug.warn("openDir {}\n", sub_path); |
| 712 | // std.debug.warn("openDir {}\n", sub_path); |
| 712 | 713 | if (os.windows.is_the_target) { |
| 713 | 714 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 714 | 715 | return self.openDirW(&sub_path_w); |
| ... | ... | @@ -740,9 +741,26 @@ pub const Dir = struct { |
| 740 | 741 | /// This function is Windows-only. |
| 741 | 742 | pub fn openDirW(self: Dir, sub_path_w: [*]const u16) OpenError!Dir { |
| 742 | 743 | const w = os.windows; |
| 744 | |
| 743 | 745 | var result = Dir{ |
| 744 | 746 | .fd = undefined, |
| 745 | 747 | }; |
| 748 | |
| 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 | |
| 746 | 764 | //var mask: ?[*]const u16 = undefined; |
| 747 | 765 | //var nt_name: w.UNICODE_STRING = undefined; |
| 748 | 766 | //if (w.ntdll.RtlDosPathNameToNtPathName_U(sub_path_w, &nt_name, null, null) == 0) { |
| ... | ... | @@ -760,7 +778,7 @@ pub const Dir = struct { |
| 760 | 778 | //} |
| 761 | 779 | |
| 762 | 780 | const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2); |
| 763 | | std.debug.warn("path_len_bytes = {}\n", path_len_bytes); |
| 781 | // std.debug.warn("path_len_bytes = {}\n", path_len_bytes); |
| 764 | 782 | var nt_name = w.UNICODE_STRING{ |
| 765 | 783 | .Length = path_len_bytes, |
| 766 | 784 | .MaximumLength = path_len_bytes, |
| ... | ... | @@ -774,7 +792,11 @@ pub const Dir = struct { |
| 774 | 792 | .SecurityDescriptor = null, |
| 775 | 793 | .SecurityQualityOfService = null, |
| 776 | 794 | }; |
| 777 | | std.debug.warn("RootDirectory = {}\n", attr.RootDirectory); |
| 795 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { |
| 796 | // Windows does not recognize this, but it does work with empty string. |
| 797 | nt_name.Length = 0; |
| 798 | } |
| 799 | // std.debug.warn("RootDirectory = {}\n", attr.RootDirectory); |
| 778 | 800 | var io: w.IO_STATUS_BLOCK = undefined; |
| 779 | 801 | const wide_slice = nt_name.Buffer[0 .. nt_name.Length / 2]; |
| 780 | 802 | //const wide_slice2 = std.mem.toSliceConst(u16, mask.?); |
| ... | ... | @@ -782,11 +804,11 @@ pub const Dir = struct { |
| 782 | 804 | //var buf2: [200]u8 = undefined; |
| 783 | 805 | const len = std.unicode.utf16leToUtf8(&buf, wide_slice) catch unreachable; |
| 784 | 806 | //const len2 = std.unicode.utf16leToUtf8(&buf2, wide_slice2) catch unreachable; |
| 785 | | std.debug.warn("path: {}\n", buf[0..len]); |
| 807 | // std.debug.warn("path: {}\n", buf[0..len]); |
| 786 | 808 | //std.debug.warn("path: {}\nmask: {}\n", buf[0..len], buf2[0..len2]); |
| 787 | 809 | const rc = w.ntdll.NtCreateFile( |
| 788 | 810 | &result.fd, |
| 789 | | w.GENERIC_READ | w.SYNCHRONIZE, |
| 811 | desired_access, |
| 790 | 812 | &attr, |
| 791 | 813 | &io, |
| 792 | 814 | null, |
| ... | ... | @@ -797,11 +819,12 @@ pub const Dir = struct { |
| 797 | 819 | null, |
| 798 | 820 | 0, |
| 799 | 821 | ); |
| 800 | | std.debug.warn("result.fd = {}\n", result.fd); |
| 822 | // std.debug.warn("result.fd = {}\n", result.fd); |
| 801 | 823 | switch (rc) { |
| 802 | 824 | w.STATUS.SUCCESS => return result, |
| 803 | 825 | w.STATUS.OBJECT_NAME_INVALID => @panic("openDirW invalid object name"), |
| 804 | 826 | w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 827 | w.STATUS.OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| 805 | 828 | w.STATUS.INVALID_PARAMETER => { |
| 806 | 829 | @panic("invalid parameter"); |
| 807 | 830 | }, |