Skip to content

Commit 4c05073

Browse files
committed
std: win: Don't use GetFileInformationByHandle on UWP
1 parent a24be59 commit 4c05073

File tree

2 files changed

+76
-19
lines changed

2 files changed

+76
-19
lines changed

src/libstd/sys/windows/c.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ pub type ULONG = c_ulong;
3434

3535
pub type LPBOOL = *mut BOOL;
3636
pub type LPBYTE = *mut BYTE;
37-
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
3837
pub type LPCSTR = *const CHAR;
3938
pub type LPCVOID = *const c_void;
4039
pub type LPCWSTR = *const WCHAR;
@@ -341,20 +340,6 @@ pub struct WIN32_FILE_ATTRIBUTE_DATA {
341340
pub nFileSizeLow: DWORD,
342341
}
343342

344-
#[repr(C)]
345-
pub struct BY_HANDLE_FILE_INFORMATION {
346-
pub dwFileAttributes: DWORD,
347-
pub ftCreationTime: FILETIME,
348-
pub ftLastAccessTime: FILETIME,
349-
pub ftLastWriteTime: FILETIME,
350-
pub dwVolumeSerialNumber: DWORD,
351-
pub nFileSizeHigh: DWORD,
352-
pub nFileSizeLow: DWORD,
353-
pub nNumberOfLinks: DWORD,
354-
pub nFileIndexHigh: DWORD,
355-
pub nFileIndexLow: DWORD,
356-
}
357-
358343
#[repr(C)]
359344
#[allow(dead_code)] // we only use some variants
360345
pub enum FILE_INFO_BY_HANDLE_CLASS {
@@ -657,6 +642,22 @@ pub struct timeval {
657642
// Functions forbidden when targeting UWP
658643
cfg_if::cfg_if! {
659644
if #[cfg(not(target_vendor = "uwp"))] {
645+
#[repr(C)]
646+
pub struct BY_HANDLE_FILE_INFORMATION {
647+
pub dwFileAttributes: DWORD,
648+
pub ftCreationTime: FILETIME,
649+
pub ftLastAccessTime: FILETIME,
650+
pub ftLastWriteTime: FILETIME,
651+
pub dwVolumeSerialNumber: DWORD,
652+
pub nFileSizeHigh: DWORD,
653+
pub nFileSizeLow: DWORD,
654+
pub nNumberOfLinks: DWORD,
655+
pub nFileIndexHigh: DWORD,
656+
pub nFileIndexLow: DWORD,
657+
}
658+
659+
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
660+
660661
pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
661662

662663
pub const TOKEN_READ: DWORD = 0x20008;
@@ -672,6 +673,9 @@ if #[cfg(not(target_vendor = "uwp"))] {
672673
pub fn GetUserProfileDirectoryW(hToken: HANDLE,
673674
lpProfileDir: LPWSTR,
674675
lpcchSize: *mut DWORD) -> BOOL;
676+
pub fn GetFileInformationByHandle(hFile: HANDLE,
677+
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
678+
-> BOOL;
675679
pub fn SetHandleInformation(hObject: HANDLE,
676680
dwMask: DWORD,
677681
dwFlags: DWORD) -> BOOL;
@@ -688,7 +692,20 @@ cfg_if::cfg_if! {
688692
if #[cfg(target_vendor = "uwp")] {
689693
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
690694

695+
#[repr(C)]
696+
pub struct FILE_STANDARD_INFO {
697+
pub AllocationSize: LARGE_INTEGER,
698+
pub EndOfFile: LARGE_INTEGER,
699+
pub NumberOfLink: DWORD,
700+
pub DeletePending: BOOLEAN,
701+
pub Directory: BOOLEAN,
702+
}
703+
691704
extern "system" {
705+
pub fn GetFileInformationByHandleEx(hFile: HANDLE,
706+
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
707+
lpFileInformation: LPVOID,
708+
dwBufferSize: DWORD) -> BOOL;
692709
pub fn BCryptGenRandom(hAlgorithm: LPVOID, pBuffer: *mut u8,
693710
cbBuffer: ULONG, dwFlags: ULONG) -> LONG;
694711
}
@@ -752,10 +769,6 @@ extern "system" {
752769
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
753770
pub fn SetFileAttributesW(lpFileName: LPCWSTR,
754771
dwFileAttributes: DWORD) -> BOOL;
755-
pub fn GetFileInformationByHandle(hFile: HANDLE,
756-
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
757-
-> BOOL;
758-
759772
pub fn SetLastError(dwErrCode: DWORD);
760773
pub fn GetCommandLineW() -> *mut LPCWSTR;
761774
pub fn GetTempPathW(nBufferLength: DWORD,

src/libstd/sys/windows/fs.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ impl File {
287287
Ok(())
288288
}
289289

290+
#[cfg(not(target_vendor = "uwp"))]
290291
pub fn file_attr(&self) -> io::Result<FileAttr> {
291292
unsafe {
292293
let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
@@ -310,6 +311,49 @@ impl File {
310311
}
311312
}
312313

314+
#[cfg(target_vendor = "uwp")]
315+
pub fn file_attr(&self) -> io::Result<FileAttr> {
316+
unsafe {
317+
let mut info: c::FILE_BASIC_INFO = mem::zeroed();
318+
let size = mem::size_of_val(&info);
319+
cvt(c::GetFileInformationByHandleEx(self.handle.raw(),
320+
c::FileBasicInfo,
321+
&mut info as *mut _ as *mut libc::c_void,
322+
size as c::DWORD))?;
323+
let mut attr = FileAttr {
324+
attributes: info.FileAttributes,
325+
creation_time: c::FILETIME {
326+
dwLowDateTime: info.CreationTime as c::DWORD,
327+
dwHighDateTime: (info.CreationTime >> 32) as c::DWORD,
328+
},
329+
last_access_time: c::FILETIME {
330+
dwLowDateTime: info.LastAccessTime as c::DWORD,
331+
dwHighDateTime: (info.LastAccessTime >> 32) as c::DWORD,
332+
},
333+
last_write_time: c::FILETIME {
334+
dwLowDateTime: info.LastWriteTime as c::DWORD,
335+
dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD,
336+
},
337+
file_size: 0,
338+
reparse_tag: 0,
339+
};
340+
let mut info: c::FILE_STANDARD_INFO = mem::zeroed();
341+
let size = mem::size_of_val(&info);
342+
cvt(c::GetFileInformationByHandleEx(self.handle.raw(),
343+
c::FileStandardInfo,
344+
&mut info as *mut _ as *mut libc::c_void,
345+
size as c::DWORD))?;
346+
attr.file_size = info.AllocationSize as u64;
347+
if attr.is_reparse_point() {
348+
let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
349+
if let Ok((_, buf)) = self.reparse_point(&mut b) {
350+
attr.reparse_tag = buf.ReparseTag;
351+
}
352+
}
353+
Ok(attr)
354+
}
355+
}
356+
313357
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
314358
self.handle.read(buf)
315359
}

0 commit comments

Comments
 (0)