Better support for os::windows::fs::MetadataExt on uwp #86075
Better support for os::windows::fs::MetadataExt on uwp #86075CDirkx wants to merge 3 commits intorust-lang:masterfrom
os::windows::fs::MetadataExt on uwp #86075Conversation
…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. Details#![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,
#endifI guess if you want to use |
JohnTitor
left a comment
There was a problem hiding this comment.
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.
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
GetFileInformationByHandleby default on Windows, andGetFileInformationByHandleExon UWP. This PR makes two changes toos::windows::fs::MetadataExt:GetFileInformationByHandlefields, but also the equivalentGetFileInformationByHandleExfields.file_indexmethod (tracking issue: Tracking issue forfs::Metadataextensions on Windows based on handle information #63010) tofile_identifierand change the return type fromOption<u64>toOption<u128>. This allowsfile_identifierandvolume_serial_numberto be implemented on UWP usingFILE_ID_INFO, previously they would always returnNone.