Skip to content

Commit

Permalink
Rollup merge of rust-lang#101260 - ChrisDenton:attribute-tag, r=thomcc
Browse files Browse the repository at this point in the history
Use `FILE_ATTRIBUTE_TAG_INFO` to get reparse tag

I've been looking at this code recently and it just occurred to me we don't actually use the full reparse data at this point, only the tag. [`GetFileInformationByHandleEx`](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getfileinformationbyhandleex) can do exactly that by filling a [`FILE_ATTRIBUTE_TAG_INFO`](https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_attribute_tag_info) struct.

r? `@thomcc` since you've made changes here recently (which is why I have this code on my mind atm)
  • Loading branch information
Dylan-DPC authored Sep 2, 2022
2 parents a246df3 + 630f831 commit 1d4adb1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
6 changes: 6 additions & 0 deletions library/std/src/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,12 @@ pub enum FILE_INFO_BY_HANDLE_CLASS {
MaximumFileInfoByHandlesClass,
}

#[repr(C)]
pub struct FILE_ATTRIBUTE_TAG_INFO {
pub FileAttributes: DWORD,
pub ReparseTag: DWORD,
}

#[repr(C)]
pub struct FILE_DISPOSITION_INFO {
pub DeleteFile: BOOLEAN,
Expand Down
26 changes: 18 additions & 8 deletions library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 1d4adb1

Please sign in to comment.