Skip to content

Commit 1f2e37c

Browse files
committed
Added a workaround for GetFileInformationByHandleEx error in dir iterator.
Reproduce the workaround for GetFileInformationByHandleEx returning ERROR_INVALID_PARAMETER when querying FILE_ATTRIBUTE_TAG_INFO on FAT/exFAT filesystems in directory iterator construction. Fixes boostorg#237.
1 parent 15249ba commit 1f2e37c

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

doc/release_history.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<h2>1.80.0</h2>
4343
<ul>
4444
<li>On Windows, added a fallback implementation for querying file attributes in case if the file cannot be opened with <code>ERROR_ACCESS_DENIED</code> error. This may allow <code>status</code> and <code>symlink_status</code> to succeed for system files and directories that are not reparse points or symlinks. (<a href="https://github.com/boostorg/filesystem/issues/234">#234</a>)</li>
45-
<li>On Windows, added a workaround for <code>status</code> and <code>symlink_status</code> reporting that files do not exist on FAT/exFAT filesystems. (<a href="https://github.com/boostorg/filesystem/issues/236">#236</a>)</li>
45+
<li>On Windows, added a workaround for FAT/exFAT filesystems that produce <code>ERROR_INVALID_PARAMETER</code> when querying file attributes. This affected <code>status</code> and <code>symlink_status</code>, which reported that files do not exist, and directory iterators, which failed to construct, as well as other dependent operations. (<a href="https://github.com/boostorg/filesystem/issues/236">#236</a>, <a href="https://github.com/boostorg/filesystem/issues/237">#237</a>)</li>
4646
</ul>
4747

4848
<h2>1.79.0</h2>

src/directory.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,14 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
774774
file_attribute_tag_info info;
775775
BOOL res = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info));
776776
if (BOOST_UNLIKELY(!res))
777-
goto return_last_error;
777+
{
778+
// On FAT/exFAT filesystems requesting FILE_ATTRIBUTE_TAG_INFO returns ERROR_INVALID_PARAMETER. See the comment in symlink_status.
779+
DWORD error = ::GetLastError();
780+
if (error == ERROR_INVALID_PARAMETER || error == ERROR_NOT_SUPPORTED)
781+
goto use_get_file_information_by_handle;
782+
783+
return error_code(error, system_category());
784+
}
778785

779786
if (BOOST_UNLIKELY((info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0u))
780787
return make_error_code(system::errc::not_a_directory);
@@ -787,6 +794,7 @@ error_code dir_itr_create(boost::intrusive_ptr< detail::dir_itr_imp >& imp, fs::
787794
}
788795
else
789796
{
797+
use_get_file_information_by_handle:
790798
BY_HANDLE_FILE_INFORMATION info;
791799
BOOL res = ::GetFileInformationByHandle(h.handle, &info);
792800
if (BOOST_UNLIKELY(!res))

src/operations.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3770,12 +3770,20 @@ file_status status(path const& p, error_code* ec)
37703770
file_attribute_tag_info info;
37713771
BOOL res = get_file_information_by_handle_ex(h.handle, file_attribute_tag_info_class, &info, sizeof(info));
37723772
if (BOOST_UNLIKELY(!res))
3773-
goto return_status_failure;
3773+
{
3774+
// See the comment in symlink_status
3775+
DWORD err = ::GetLastError();
3776+
if (err == ERROR_INVALID_PARAMETER || err == ERROR_NOT_SUPPORTED)
3777+
goto use_get_file_information_by_handle;
3778+
3779+
return process_status_failure(err, p, ec);
3780+
}
37743781

37753782
attrs = info.FileAttributes;
37763783
}
37773784
else
37783785
{
3786+
use_get_file_information_by_handle:
37793787
BY_HANDLE_FILE_INFORMATION info;
37803788
BOOL res = ::GetFileInformationByHandle(h.handle, &info);
37813789
if (BOOST_UNLIKELY(!res))

0 commit comments

Comments
 (0)