Skip to content

Commit 07d11ae

Browse files
committed
std: win: Don't use GetFileInformationByHandle on UWP
1 parent b514557 commit 07d11ae

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
@@ -38,7 +38,6 @@ pub type ULONG = c_ulong;
3838

3939
pub type LPBOOL = *mut BOOL;
4040
pub type LPBYTE = *mut BYTE;
41-
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
4241
pub type LPCSTR = *const CHAR;
4342
pub type LPCVOID = *const c_void;
4443
pub type LPCWSTR = *const WCHAR;
@@ -345,20 +344,6 @@ pub struct WIN32_FILE_ATTRIBUTE_DATA {
345344
pub nFileSizeLow: DWORD,
346345
}
347346

348-
#[repr(C)]
349-
pub struct BY_HANDLE_FILE_INFORMATION {
350-
pub dwFileAttributes: DWORD,
351-
pub ftCreationTime: FILETIME,
352-
pub ftLastAccessTime: FILETIME,
353-
pub ftLastWriteTime: FILETIME,
354-
pub dwVolumeSerialNumber: DWORD,
355-
pub nFileSizeHigh: DWORD,
356-
pub nFileSizeLow: DWORD,
357-
pub nNumberOfLinks: DWORD,
358-
pub nFileIndexHigh: DWORD,
359-
pub nFileIndexLow: DWORD,
360-
}
361-
362347
#[repr(C)]
363348
#[allow(dead_code)] // we only use some variants
364349
pub enum FILE_INFO_BY_HANDLE_CLASS {
@@ -661,6 +646,22 @@ pub struct timeval {
661646
// Functions forbidden when targeting UWP
662647
#[cfg(not(target_vendor = "uwp"))]
663648
ifdef! {
649+
#[repr(C)]
650+
pub struct BY_HANDLE_FILE_INFORMATION {
651+
pub dwFileAttributes: DWORD,
652+
pub ftCreationTime: FILETIME,
653+
pub ftLastAccessTime: FILETIME,
654+
pub ftLastWriteTime: FILETIME,
655+
pub dwVolumeSerialNumber: DWORD,
656+
pub nFileSizeHigh: DWORD,
657+
pub nFileSizeLow: DWORD,
658+
pub nNumberOfLinks: DWORD,
659+
pub nFileIndexHigh: DWORD,
660+
pub nFileIndexLow: DWORD,
661+
}
662+
663+
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
664+
664665
pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
665666

666667
pub const TOKEN_READ: DWORD = 0x20008;
@@ -676,6 +677,9 @@ ifdef! {
676677
pub fn GetUserProfileDirectoryW(hToken: HANDLE,
677678
lpProfileDir: LPWSTR,
678679
lpcchSize: *mut DWORD) -> BOOL;
680+
pub fn GetFileInformationByHandle(hFile: HANDLE,
681+
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
682+
-> BOOL;
679683
pub fn SetHandleInformation(hObject: HANDLE,
680684
dwMask: DWORD,
681685
dwFlags: DWORD) -> BOOL;
@@ -691,7 +695,20 @@ ifdef! {
691695
ifdef! {
692696
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
693697

698+
#[repr(C)]
699+
pub struct FILE_STANDARD_INFO {
700+
pub AllocationSize: LARGE_INTEGER,
701+
pub EndOfFile: LARGE_INTEGER,
702+
pub NumberOfLink: DWORD,
703+
pub DeletePending: BOOLEAN,
704+
pub Directory: BOOLEAN,
705+
}
706+
694707
extern "system" {
708+
pub fn GetFileInformationByHandleEx(hFile: HANDLE,
709+
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
710+
lpFileInformation: LPVOID,
711+
dwBufferSize: DWORD) -> BOOL;
695712
pub fn BCryptGenRandom(hAlgorithm: LPVOID, pBuffer: *mut u8,
696713
cbBuffer: ULONG, dwFlags: ULONG) -> LONG;
697714
}
@@ -754,10 +771,6 @@ extern "system" {
754771
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
755772
pub fn SetFileAttributesW(lpFileName: LPCWSTR,
756773
dwFileAttributes: DWORD) -> BOOL;
757-
pub fn GetFileInformationByHandle(hFile: HANDLE,
758-
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
759-
-> BOOL;
760-
761774
pub fn SetLastError(dwErrCode: DWORD);
762775
pub fn GetCommandLineW() -> *mut LPCWSTR;
763776
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)