| ... | @@ -897,6 +897,7 @@ pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 { | ... | @@ -897,6 +897,7 @@ pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 { |
| 897 | } | 897 | } |
| 898 | | 898 | |
| 899 | pub const GetFinalPathNameByHandleError = error{ | 899 | pub const GetFinalPathNameByHandleError = error{ |
| | 900 | BadPathName, |
| 900 | FileNotFound, | 901 | FileNotFound, |
| 901 | NameTooLong, | 902 | NameTooLong, |
| 902 | Unexpected, | 903 | Unexpected, |
| ... | @@ -925,11 +926,11 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -925,11 +926,11 @@ pub fn GetFinalPathNameByHandle( |
| 925 | ) GetFinalPathNameByHandleError![]u16 { | 926 | ) GetFinalPathNameByHandleError![]u16 { |
| 926 | // Get normalized path; doesn't include volume name though. | 927 | // Get normalized path; doesn't include volume name though. |
| 927 | var path_buffer: [@sizeOf(FILE_NAME_INFORMATION) + PATH_MAX_WIDE * 2]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined; | 928 | var path_buffer: [@sizeOf(FILE_NAME_INFORMATION) + PATH_MAX_WIDE * 2]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined; |
| 928 | try QueryInformationFile(hFile, FILE_INFORMATION_CLASS.FileNormalizedNameInformation, path_buffer[0..]); | 929 | try QueryInformationFile(hFile, .FileNormalizedNameInformation, path_buffer[0..]); |
| 929 | | 930 | |
| 930 | // Get NT volume name. | 931 | // Get NT volume name. |
| 931 | var volume_buffer: [@sizeOf(FILE_NAME_INFORMATION) + MAX_PATH]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined; // MAX_PATH bytes should be enough since it's Windows-defined name | 932 | var volume_buffer: [@sizeOf(FILE_NAME_INFORMATION) + MAX_PATH]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined; // MAX_PATH bytes should be enough since it's Windows-defined name |
| 932 | try QueryInformationFile(hFile, FILE_INFORMATION_CLASS.FileVolumeNameInformation, volume_buffer[0..]); | 933 | try QueryInformationFile(hFile, .FileVolumeNameInformation, volume_buffer[0..]); |
| 933 | | 934 | |
| 934 | const file_name = @ptrCast(*const FILE_NAME_INFORMATION, &path_buffer[0]); | 935 | const file_name = @ptrCast(*const FILE_NAME_INFORMATION, &path_buffer[0]); |
| 935 | const file_name_u16 = @ptrCast([*]const u16, &file_name.FileName[0])[0 .. file_name.FileNameLength / 2]; | 936 | const file_name_u16 = @ptrCast([*]const u16, &file_name.FileName[0])[0 .. file_name.FileNameLength / 2]; |
| ... | @@ -1010,8 +1011,14 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -1010,8 +1011,14 @@ pub fn GetFinalPathNameByHandle( |
| 1010 | | 1011 | |
| 1011 | std.mem.copy(u16, out_buffer[0..], drive_letter); | 1012 | std.mem.copy(u16, out_buffer[0..], drive_letter); |
| 1012 | std.mem.copy(u16, out_buffer[drive_letter.len..], file_name_u16); | 1013 | std.mem.copy(u16, out_buffer[drive_letter.len..], file_name_u16); |
| | 1014 | const total_len = drive_letter.len + file_name_u16.len; |
| 1013 | | 1015 | |
| 1014 | return out_buffer[0 .. drive_letter.len + file_name_u16.len]; | 1016 | // Validate that DOS does not contain any spurious nul bytes. |
| | 1017 | if (std.mem.indexOfScalar(u16, out_buffer[0..total_len], 0)) |_| { |
| | 1018 | return error.BadPathName; |
| | 1019 | } |
| | 1020 | |
| | 1021 | return out_buffer[0..total_len]; |
| 1015 | } | 1022 | } |
| 1016 | } | 1023 | } |
| 1017 | | 1024 | |
| ... | @@ -1030,9 +1037,7 @@ pub fn QueryInformationFile( | ... | @@ -1030,9 +1037,7 @@ pub fn QueryInformationFile( |
| 1030 | out_buffer: []u8, | 1037 | out_buffer: []u8, |
| 1031 | ) QueryInformationFileError!void { | 1038 | ) QueryInformationFileError!void { |
| 1032 | var io: IO_STATUS_BLOCK = undefined; | 1039 | var io: IO_STATUS_BLOCK = undefined; |
| 1033 | const len_bytes = std.math.cast(u32, out_buffer.len) catch |err| switch (err) { | 1040 | const len_bytes = std.math.cast(u32, out_buffer.len) catch unreachable; |
| 1034 | error.Overflow => std.math.maxInt(u32), // If the provided buffer is larger than what we can handle, set size to max what we can handle | | |
| 1035 | }; | | |
| 1036 | const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class); | 1041 | const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class); |
| 1037 | switch (rc) { | 1042 | switch (rc) { |
| 1038 | .SUCCESS => {}, | 1043 | .SUCCESS => {}, |