_testFileExistsByName - test if path exists
(path: &std::path::Path, follow_links: bool)
| 670 | |
| 671 | /// _testFileExistsByName - test if path exists |
| 672 | fn _test_file_exists_by_name(path: &std::path::Path, follow_links: bool) -> bool { |
| 673 | use crate::common::fileutils::windows::{ |
| 674 | FILE_INFO_BY_NAME_CLASS, get_file_information_by_name, |
| 675 | }; |
| 676 | use crate::common::windows::ToWideString; |
| 677 | use windows_sys::Win32::Foundation::{CloseHandle, INVALID_HANDLE_VALUE}; |
| 678 | use windows_sys::Win32::Storage::FileSystem::{ |
| 679 | CreateFileW, FILE_ATTRIBUTE_REPARSE_POINT, FILE_FLAG_BACKUP_SEMANTICS, |
| 680 | FILE_FLAG_OPEN_REPARSE_POINT, FILE_READ_ATTRIBUTES, OPEN_EXISTING, |
| 681 | }; |
| 682 | |
| 683 | match get_file_information_by_name( |
| 684 | path.as_os_str(), |
| 685 | FILE_INFO_BY_NAME_CLASS::FileStatBasicByNameInfo, |
| 686 | ) { |
| 687 | Ok(info) => { |
| 688 | if (info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0 |
| 689 | || (!follow_links && is_reparse_tag_name_surrogate(info.ReparseTag)) |
| 690 | { |
| 691 | return true; |
| 692 | } |
| 693 | } |
| 694 | Err(err) => { |
| 695 | if let Some(code) = err.raw_os_error() |
| 696 | && file_info_error_is_trustworthy(code as u32) |
| 697 | { |
| 698 | return false; |
| 699 | } |
| 700 | } |
| 701 | } |
| 702 | |
| 703 | let wide_path = path.to_wide_with_nul(); |
| 704 | let mut flags = FILE_FLAG_BACKUP_SEMANTICS; |
| 705 | if !follow_links { |
| 706 | flags |= FILE_FLAG_OPEN_REPARSE_POINT; |
| 707 | } |
| 708 | let handle = unsafe { |
| 709 | CreateFileW( |
| 710 | wide_path.as_ptr(), |
| 711 | FILE_READ_ATTRIBUTES, |
| 712 | 0, |
| 713 | core::ptr::null(), |
| 714 | OPEN_EXISTING, |
| 715 | flags, |
| 716 | core::ptr::null_mut(), |
| 717 | ) |
| 718 | }; |
| 719 | if handle != INVALID_HANDLE_VALUE { |
| 720 | if follow_links { |
| 721 | unsafe { CloseHandle(handle) }; |
| 722 | return true; |
| 723 | } |
| 724 | let is_regular_reparse_point = _test_file_type_by_handle(handle, PY_IFRRP, false); |
| 725 | unsafe { CloseHandle(handle) }; |
| 726 | if !is_regular_reparse_point { |
| 727 | return true; |
| 728 | } |
| 729 | let handle = unsafe { |
no test coverage detected