remove_all() by handle implementation for Windows Vista and newer
| 2071 | |
| 2072 | //! remove_all() by handle implementation for Windows Vista and newer |
| 2073 | uintmax_t remove_all_nt6_by_handle(HANDLE h, path const& p, error_code* ec) |
| 2074 | { |
| 2075 | error_code local_ec; |
| 2076 | fs::file_status st(fs::detail::status_by_handle(h, p, &local_ec)); |
| 2077 | if (BOOST_UNLIKELY(st.type() == fs::status_error)) |
| 2078 | { |
| 2079 | if (!ec) |
| 2080 | BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec)); |
| 2081 | |
| 2082 | *ec = local_ec; |
| 2083 | return static_cast< uintmax_t >(-1); |
| 2084 | } |
| 2085 | |
| 2086 | uintmax_t count = 0u; |
| 2087 | if (st.type() == fs::directory_file) |
| 2088 | { |
| 2089 | local_ec.clear(); |
| 2090 | |
| 2091 | fs::directory_iterator itr; |
| 2092 | directory_iterator_params params; |
| 2093 | params.dir_handle = h; |
| 2094 | params.close_handle = false; // the caller will close the handle |
| 2095 | fs::detail::directory_iterator_construct(itr, p, directory_options::_detail_no_follow, ¶ms, &local_ec); |
| 2096 | if (BOOST_UNLIKELY(!!local_ec)) |
| 2097 | { |
| 2098 | if (!ec) |
| 2099 | BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::remove_all", p, local_ec)); |
| 2100 | |
| 2101 | *ec = local_ec; |
| 2102 | return static_cast< uintmax_t >(-1); |
| 2103 | } |
| 2104 | |
| 2105 | NtCreateFile_t* nt_create_file = filesystem::detail::atomic_load_relaxed(nt_create_file_api); |
| 2106 | const fs::directory_iterator end_dit; |
| 2107 | while (itr != end_dit) |
| 2108 | { |
| 2109 | fs::path nested_path(itr->path()); |
| 2110 | unique_handle hh; |
| 2111 | if (BOOST_LIKELY(nt_create_file != nullptr)) |
| 2112 | { |
| 2113 | // Note: WinAPI methods like CreateFileW implicitly request SYNCHRONIZE access but NtCreateFile doesn't. |
| 2114 | // Without SYNCHRONIZE access querying file attributes via GetFileInformationByHandleEx fails with ERROR_ACCESS_DENIED. |
| 2115 | boost::winapi::NTSTATUS_ status = nt_create_file_handle_at |
| 2116 | ( |
| 2117 | hh, |
| 2118 | h, |
| 2119 | path_algorithms::filename_v4(nested_path), |
| 2120 | 0u, // FileAttributes |
| 2121 | FILE_LIST_DIRECTORY | DELETE | FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | SYNCHRONIZE, |
| 2122 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 2123 | FILE_OPEN, |
| 2124 | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT |
| 2125 | ); |
| 2126 | |
| 2127 | if (!NT_SUCCESS(status)) |
| 2128 | { |
| 2129 | if (not_found_ntstatus(status)) |
| 2130 | goto next_entry; |
no test coverage detected