std: win: Don't use GetFileInformationByHandle on UWP
This commit is contained in:
parent
a24be59b46
commit
4c05073d1d
2 changed files with 76 additions and 19 deletions
|
@ -34,7 +34,6 @@ pub type ULONG = c_ulong;
|
|||
|
||||
pub type LPBOOL = *mut BOOL;
|
||||
pub type LPBYTE = *mut BYTE;
|
||||
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
|
||||
pub type LPCSTR = *const CHAR;
|
||||
pub type LPCVOID = *const c_void;
|
||||
pub type LPCWSTR = *const WCHAR;
|
||||
|
@ -341,20 +340,6 @@ pub struct WIN32_FILE_ATTRIBUTE_DATA {
|
|||
pub nFileSizeLow: DWORD,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BY_HANDLE_FILE_INFORMATION {
|
||||
pub dwFileAttributes: DWORD,
|
||||
pub ftCreationTime: FILETIME,
|
||||
pub ftLastAccessTime: FILETIME,
|
||||
pub ftLastWriteTime: FILETIME,
|
||||
pub dwVolumeSerialNumber: DWORD,
|
||||
pub nFileSizeHigh: DWORD,
|
||||
pub nFileSizeLow: DWORD,
|
||||
pub nNumberOfLinks: DWORD,
|
||||
pub nFileIndexHigh: DWORD,
|
||||
pub nFileIndexLow: DWORD,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[allow(dead_code)] // we only use some variants
|
||||
pub enum FILE_INFO_BY_HANDLE_CLASS {
|
||||
|
@ -657,6 +642,22 @@ pub struct timeval {
|
|||
// Functions forbidden when targeting UWP
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(target_vendor = "uwp"))] {
|
||||
#[repr(C)]
|
||||
pub struct BY_HANDLE_FILE_INFORMATION {
|
||||
pub dwFileAttributes: DWORD,
|
||||
pub ftCreationTime: FILETIME,
|
||||
pub ftLastAccessTime: FILETIME,
|
||||
pub ftLastWriteTime: FILETIME,
|
||||
pub dwVolumeSerialNumber: DWORD,
|
||||
pub nFileSizeHigh: DWORD,
|
||||
pub nFileSizeLow: DWORD,
|
||||
pub nNumberOfLinks: DWORD,
|
||||
pub nFileIndexHigh: DWORD,
|
||||
pub nFileIndexLow: DWORD,
|
||||
}
|
||||
|
||||
pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
|
||||
|
||||
pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
|
||||
|
||||
pub const TOKEN_READ: DWORD = 0x20008;
|
||||
|
@ -672,6 +673,9 @@ if #[cfg(not(target_vendor = "uwp"))] {
|
|||
pub fn GetUserProfileDirectoryW(hToken: HANDLE,
|
||||
lpProfileDir: LPWSTR,
|
||||
lpcchSize: *mut DWORD) -> BOOL;
|
||||
pub fn GetFileInformationByHandle(hFile: HANDLE,
|
||||
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
|
||||
-> BOOL;
|
||||
pub fn SetHandleInformation(hObject: HANDLE,
|
||||
dwMask: DWORD,
|
||||
dwFlags: DWORD) -> BOOL;
|
||||
|
@ -688,7 +692,20 @@ cfg_if::cfg_if! {
|
|||
if #[cfg(target_vendor = "uwp")] {
|
||||
pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FILE_STANDARD_INFO {
|
||||
pub AllocationSize: LARGE_INTEGER,
|
||||
pub EndOfFile: LARGE_INTEGER,
|
||||
pub NumberOfLink: DWORD,
|
||||
pub DeletePending: BOOLEAN,
|
||||
pub Directory: BOOLEAN,
|
||||
}
|
||||
|
||||
extern "system" {
|
||||
pub fn GetFileInformationByHandleEx(hFile: HANDLE,
|
||||
fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
|
||||
lpFileInformation: LPVOID,
|
||||
dwBufferSize: DWORD) -> BOOL;
|
||||
pub fn BCryptGenRandom(hAlgorithm: LPVOID, pBuffer: *mut u8,
|
||||
cbBuffer: ULONG, dwFlags: ULONG) -> LONG;
|
||||
}
|
||||
|
@ -752,10 +769,6 @@ extern "system" {
|
|||
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
|
||||
pub fn SetFileAttributesW(lpFileName: LPCWSTR,
|
||||
dwFileAttributes: DWORD) -> BOOL;
|
||||
pub fn GetFileInformationByHandle(hFile: HANDLE,
|
||||
lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
|
||||
-> BOOL;
|
||||
|
||||
pub fn SetLastError(dwErrCode: DWORD);
|
||||
pub fn GetCommandLineW() -> *mut LPCWSTR;
|
||||
pub fn GetTempPathW(nBufferLength: DWORD,
|
||||
|
|
|
@ -287,6 +287,7 @@ impl File {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_vendor = "uwp"))]
|
||||
pub fn file_attr(&self) -> io::Result<FileAttr> {
|
||||
unsafe {
|
||||
let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
|
||||
|
@ -310,6 +311,49 @@ impl File {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_vendor = "uwp")]
|
||||
pub fn file_attr(&self) -> io::Result<FileAttr> {
|
||||
unsafe {
|
||||
let mut info: c::FILE_BASIC_INFO = mem::zeroed();
|
||||
let size = mem::size_of_val(&info);
|
||||
cvt(c::GetFileInformationByHandleEx(self.handle.raw(),
|
||||
c::FileBasicInfo,
|
||||
&mut info as *mut _ as *mut libc::c_void,
|
||||
size as c::DWORD))?;
|
||||
let mut attr = FileAttr {
|
||||
attributes: info.FileAttributes,
|
||||
creation_time: c::FILETIME {
|
||||
dwLowDateTime: info.CreationTime as c::DWORD,
|
||||
dwHighDateTime: (info.CreationTime >> 32) as c::DWORD,
|
||||
},
|
||||
last_access_time: c::FILETIME {
|
||||
dwLowDateTime: info.LastAccessTime as c::DWORD,
|
||||
dwHighDateTime: (info.LastAccessTime >> 32) as c::DWORD,
|
||||
},
|
||||
last_write_time: c::FILETIME {
|
||||
dwLowDateTime: info.LastWriteTime as c::DWORD,
|
||||
dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD,
|
||||
},
|
||||
file_size: 0,
|
||||
reparse_tag: 0,
|
||||
};
|
||||
let mut info: c::FILE_STANDARD_INFO = mem::zeroed();
|
||||
let size = mem::size_of_val(&info);
|
||||
cvt(c::GetFileInformationByHandleEx(self.handle.raw(),
|
||||
c::FileStandardInfo,
|
||||
&mut info as *mut _ as *mut libc::c_void,
|
||||
size as c::DWORD))?;
|
||||
attr.file_size = info.AllocationSize as u64;
|
||||
if attr.is_reparse_point() {
|
||||
let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||
if let Ok((_, buf)) = self.reparse_point(&mut b) {
|
||||
attr.reparse_tag = buf.ReparseTag;
|
||||
}
|
||||
}
|
||||
Ok(attr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.handle.read(buf)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue