-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better support for os::windows::fs::MetadataExt
on uwp
#86075
Conversation
…andleEx` for `os::windows::fs::MetadataExt`
…ataExt::volume_serial_number` and `file_index`
(rust-highfive has picked a reviewer for you, use r? to override) |
Is there a reason we don't always use |
Is the |
Not exactly sure, Requirements
Which I initially interpreted as not yet being supported anywhere, but in a test I did (see below) it was working fine, at least on Windows 10. #![feature(with_options)]
use std::path::Path;
mod c {
#[repr(C)]
pub enum FILE_INFO_BY_HANDLE_CLASS {
FileBasicInfo = 0,
FileStandardInfo = 1,
FileNameInfo = 2,
FileRenameInfo = 3,
FileDispositionInfo = 4,
FileAllocationInfo = 5,
FileEndOfFileInfo = 6,
FileStreamInfo = 7,
FileCompressionInfo = 8,
FileAttributeTagInfo = 9,
FileIdBothDirectoryInfo = 10, // 0xA
FileIdBothDirectoryRestartInfo = 11, // 0xB
FileIoPriorityHintInfo = 12, // 0xC
FileRemoteProtocolInfo = 13, // 0xD
FileFullDirectoryInfo = 14, // 0xE
FileFullDirectoryRestartInfo = 15, // 0xF
FileStorageInfo = 16, // 0x10
FileAlignmentInfo = 17, // 0x11
FileIdInfo = 18, // 0x12
FileIdExtdDirectoryInfo = 19, // 0x13
FileIdExtdDirectoryRestartInfo = 20, // 0x14
MaximumFileInfoByHandlesClass,
}
#[repr(C)]
#[derive(Debug)]
pub struct FILE_ID_INFO {
pub VolumeSerialNumber: u64,
pub FileId: u128
}
extern "system" {
pub fn GetFileInformationByHandleEx(
hFile: *mut std::ffi::c_void,
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
lpFileInformation: *mut std::ffi::c_void,
dwBufferSize: u32,
) -> i32;
}
}
fn main() {
unsafe {
use std::os::windows::prelude::*;
let handle = std::fs::File::with_options().access_mode(0).open("a/real.file").unwrap().into_raw_handle();
let mut info: c::FILE_ID_INFO = std::mem::zeroed();
let result = c::GetFileInformationByHandleEx(
handle,
c::FILE_INFO_BY_HANDLE_CLASS::FileIdInfo,
&mut info as *mut _ as *mut std::ffi::c_void,
std::mem::size_of_val(&info) as u32
);
if result == 0 {
panic!("{}", std::io::Error::last_os_error())
} else {
// prints "FILE_ID_INFO { VolumeSerialNumber: xxxxxxxxxxxxxxxxx, FileId: xxxxxxxxxxxxxxxxx }" on Windows 10
println!("{:?}", info);
}
}
} |
Based on https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_descriptor it seems that 128 bit file identifiers are not supported before Windows 8, so I think This means always using |
Yeah, that table looks suspiciously like it was auto-generated without the relevant data. Peeking at the Windows header files, it says that it was introduced in Windows 8: #if (NTDDI_VERSION >= NTDDI_WIN8)
FileStorageInfo,
FileAlignmentInfo,
FileIdInfo,
FileIdExtdDirectoryInfo,
FileIdExtdDirectoryRestartInfo,
#endif I guess if you want to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix itself shouldn't have a compatibility issue and looks good to me. On file_index
, renaming and extending the return type to u128
would need a t-libs-api member's review (but it looks reasonable to me).
let mut info: c::FILE_ID_INFO = mem::zeroed(); | ||
let size = mem::size_of_val(&info); | ||
cvt(c::GetFileInformationByHandleEx( | ||
self.handle.raw(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given I/O safety has been merged, as_raw_handle
should be used instead of raw
.
☔ The latest upstream changes (presumably #84096) made this pull request unmergeable. Please resolve the merge conflicts. |
Ping from triage: Please adjust the label with |
Currently to get metadata we use
GetFileInformationByHandle
by default on Windows, andGetFileInformationByHandleEx
on UWP. This PR makes two changes toos::windows::fs::MetadataExt
:GetFileInformationByHandle
fields, but also the equivalentGetFileInformationByHandleEx
fields.file_index
method (tracking issue: Tracking issue forfs::Metadata
extensions on Windows based on handle information #63010) tofile_identifier
and change the return type fromOption<u64>
toOption<u128>
. This allowsfile_identifier
andvolume_serial_number
to be implemented on UWP usingFILE_ID_INFO
, previously they would always returnNone
.