Ported from win32_xstat_slow_impl
(path: &OsStr, traverse: bool)
| 271 | |
| 272 | /// Ported from win32_xstat_slow_impl |
| 273 | fn win32_xstat_slow_impl(path: &OsStr, traverse: bool) -> std::io::Result<StatStruct> { |
| 274 | use windows_sys::Win32::{ |
| 275 | Foundation::{ |
| 276 | CloseHandle, ERROR_ACCESS_DENIED, ERROR_CANT_ACCESS_FILE, ERROR_INVALID_FUNCTION, |
| 277 | ERROR_INVALID_PARAMETER, ERROR_NOT_SUPPORTED, ERROR_SHARING_VIOLATION, GENERIC_READ, |
| 278 | INVALID_HANDLE_VALUE, |
| 279 | }, |
| 280 | Storage::FileSystem::{ |
| 281 | BY_HANDLE_FILE_INFORMATION, CreateFileW, FILE_ATTRIBUTE_DIRECTORY, |
| 282 | FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_REPARSE_POINT, FILE_BASIC_INFO, |
| 283 | FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_ID_INFO, |
| 284 | FILE_READ_ATTRIBUTES, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_TYPE_CHAR, |
| 285 | FILE_TYPE_DISK, FILE_TYPE_PIPE, FILE_TYPE_UNKNOWN, FileAttributeTagInfo, FileBasicInfo, |
| 286 | FileIdInfo, GetFileAttributesW, GetFileInformationByHandle, |
| 287 | GetFileInformationByHandleEx, GetFileType, INVALID_FILE_ATTRIBUTES, OPEN_EXISTING, |
| 288 | }, |
| 289 | }; |
| 290 | |
| 291 | let wide: Vec<u16> = path.to_wide_with_nul(); |
| 292 | |
| 293 | let access = FILE_READ_ATTRIBUTES; |
| 294 | let mut flags = FILE_FLAG_BACKUP_SEMANTICS; |
| 295 | if !traverse { |
| 296 | flags |= FILE_FLAG_OPEN_REPARSE_POINT; |
| 297 | } |
| 298 | |
| 299 | let mut h_file = unsafe { |
| 300 | CreateFileW( |
| 301 | wide.as_ptr(), |
| 302 | access, |
| 303 | 0, |
| 304 | core::ptr::null(), |
| 305 | OPEN_EXISTING, |
| 306 | flags, |
| 307 | core::ptr::null_mut(), |
| 308 | ) |
| 309 | }; |
| 310 | |
| 311 | let mut file_info: BY_HANDLE_FILE_INFORMATION = unsafe { core::mem::zeroed() }; |
| 312 | let mut tag_info = FileAttributeTagInfo::default(); |
| 313 | let mut is_unhandled_tag = false; |
| 314 | |
| 315 | if h_file == INVALID_HANDLE_VALUE { |
| 316 | let error = std::io::Error::last_os_error(); |
| 317 | let error_code = error.raw_os_error().unwrap_or(0) as u32; |
| 318 | |
| 319 | match error_code { |
| 320 | ERROR_ACCESS_DENIED | ERROR_SHARING_VIOLATION => { |
| 321 | // Try reading the parent directory using FindFirstFileW |
| 322 | let (info, reparse_tag) = attributes_from_dir(path)?; |
| 323 | file_info = info; |
| 324 | tag_info.reparse_tag = reparse_tag; |
| 325 | |
| 326 | if file_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0 |
| 327 | && (traverse || !is_reparse_tag_name_surrogate(tag_info.reparse_tag)) |
| 328 | { |
| 329 | return Err(error); |
| 330 | } |
no test coverage detected