diff options
| author | Chris Denton <christophersdenton@gmail.com> | 2022-09-01 04:17:36 +0100 |
|---|---|---|
| committer | Chris Denton <christophersdenton@gmail.com> | 2022-09-01 04:17:36 +0100 |
| commit | 630f831cd06d24732c9a422b8d3d3e2ce9e1a879 (patch) | |
| tree | 89112dc031aad7efb8d8ac04bdadf26cc9b437bb /library/std/src/sys/windows | |
| parent | 3892b7074daeb23ddeaffd3e26b4f7979c6cc5a7 (diff) | |
| download | rust-630f831cd06d24732c9a422b8d3d3e2ce9e1a879.tar.gz rust-630f831cd06d24732c9a422b8d3d3e2ce9e1a879.zip | |
Use `FILE_ATTRIBUTE_TAG_INFO` to get reparse tag
This avoid unnecessarily getting the full reparse data when all we need is the tag.
Diffstat (limited to 'library/std/src/sys/windows')
| -rw-r--r-- | library/std/src/sys/windows/c.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/windows/fs.rs | 26 |
2 files changed, 24 insertions, 8 deletions
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index c99c8efe436..b4db77700aa 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -455,6 +455,12 @@ pub enum FILE_INFO_BY_HANDLE_CLASS { } #[repr(C)] +pub struct FILE_ATTRIBUTE_TAG_INFO { + pub FileAttributes: DWORD, + pub ReparseTag: DWORD, +} + +#[repr(C)] pub struct FILE_DISPOSITION_INFO { pub DeleteFile: BOOLEAN, } diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 98c8834d384..c2ad592dfea 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -326,10 +326,15 @@ impl File { cvt(c::GetFileInformationByHandle(self.handle.as_raw_handle(), &mut info))?; let mut reparse_tag = 0; if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { - let mut b = - Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]); - if let Ok((_, buf)) = self.reparse_point(&mut b) { - reparse_tag = (*buf).ReparseTag; + let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed(); + cvt(c::GetFileInformationByHandleEx( + self.handle.as_raw_handle(), + c::FileAttributeTagInfo, + ptr::addr_of_mut!(attr_tag).cast(), + mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(), + ))?; + if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { + reparse_tag = attr_tag.ReparseTag; } } Ok(FileAttr { @@ -390,10 +395,15 @@ impl File { attr.file_size = info.AllocationSize as u64; attr.number_of_links = Some(info.NumberOfLinks); if attr.file_type().is_reparse_point() { - let mut b = - Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]); - if let Ok((_, buf)) = self.reparse_point(&mut b) { - attr.reparse_tag = (*buf).ReparseTag; + let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed(); + cvt(c::GetFileInformationByHandleEx( + self.handle.as_raw_handle(), + c::FileAttributeTagInfo, + ptr::addr_of_mut!(attr_tag).cast(), + mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(), + ))?; + if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { + reparse_tag = attr_tag.ReparseTag; } } Ok(attr) |
