Skip to content

Commit 2ededc6

Browse files
committed
libstd: win: Don't use GetFileInformationByHandle on UWP
This function isn't supported on UWP. Use a combination of GetFileInformationByHandleEx & GetFileSizeEx instead.
1 parent 00ee174 commit 2ededc6

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

src/libstd/sys/windows/c.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub type DWORDLONG = ULONGLONG;
4040

4141
pub type LPBOOL = *mut BOOL;
4242
pub type LPBYTE = *mut BYTE;
43+
#[cfg(not(target_os = "uwp"))]
4344
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
4445
pub type LPCSTR = *const CHAR;
4546
#[cfg(not(target_os = "uwp"))]
@@ -381,6 +382,7 @@ pub struct WIN32_FILE_ATTRIBUTE_DATA {
381382
pub nFileSizeLow: DWORD,
382383
}
383384

385+
#[cfg(not(target_os = "uwp"))]
384386
#[repr(C)]
385387
pub struct BY_HANDLE_FILE_INFORMATION {
386388
pub dwFileAttributes: DWORD,
@@ -1062,10 +1064,17 @@ extern "system" {
10621064
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
10631065
pub fn SetFileAttributesW(lpFileName: LPCWSTR,
10641066
dwFileAttributes: DWORD) -> BOOL;
1067+
#[cfg(not(target_os = "uwp"))]
10651068
pub fn GetFileInformationByHandle(hFile: HANDLE,
1066-
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
1067-
-> BOOL;
1068-
1069+
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
1070+
-> BOOL;
1071+
#[cfg(target_os = "uwp")]
1072+
pub fn GetFileInformationByHandleEx(hFile: HANDLE,
1073+
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
1074+
lpFileInformation: LPVOID,
1075+
dwBufferSize: DWORD) -> BOOL;
1076+
#[cfg(target_os = "uwp")]
1077+
pub fn GetFileSizeEx(hFile: HANDLE, lpFileSize: PLARGE_INTEGER) -> BOOL;
10691078
pub fn SetLastError(dwErrCode: DWORD);
10701079
pub fn GetCommandLineW() -> *mut LPCWSTR;
10711080
pub fn GetTempPathW(nBufferLength: DWORD,

src/libstd/sys/windows/fs.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use crate::sys::handle::Handle;
1212
use crate::sys::time::SystemTime;
1313
use crate::sys::{c, cvt};
1414
use crate::sys_common::FromInner;
15+
#[cfg(target_os = "uwp")]
16+
use libc::c_void;
1517

1618
use super::to_u16s;
1719

@@ -287,6 +289,7 @@ impl File {
287289
Ok(())
288290
}
289291

292+
#[cfg(not(target_os = "uwp"))]
290293
pub fn file_attr(&self) -> io::Result<FileAttr> {
291294
unsafe {
292295
let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
@@ -310,6 +313,43 @@ impl File {
310313
}
311314
}
312315

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

0 commit comments

Comments
 (0)