Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<filesystem>: __std_fs_get_stats should work on FAT32 #2373

Merged
merged 6 commits into from
May 5, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions stl/src/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -888,12 +888,10 @@ struct alignas(long long) _Aligned_file_attrs {
return _Last_error;
}

constexpr auto _Basic_info_data = __std_fs_stats_flags::_Attributes | __std_fs_stats_flags::_Last_write_time;
constexpr auto _Attribute_tag_info_data = __std_fs_stats_flags::_Attributes | __std_fs_stats_flags::_Reparse_tag;
constexpr auto _Standard_info_data = __std_fs_stats_flags::_File_size | __std_fs_stats_flags::_Link_count;
constexpr auto _Basic_info_data = __std_fs_stats_flags::_Attributes | __std_fs_stats_flags::_Last_write_time;
constexpr auto _Standard_info_data = __std_fs_stats_flags::_File_size | __std_fs_stats_flags::_Link_count;

if (_Flags != _Attribute_tag_info_data && _Bitmask_includes(_Flags, _Basic_info_data)) {
// we have data FileBasicInfo can fill in, that FileAttributeTagInfo wouldn't exactly fill in
if (_Bitmask_includes(_Flags, _Basic_info_data | __std_fs_stats_flags::_Reparse_tag)) {
FILE_BASIC_INFO _Info;
if (!GetFileInformationByHandleEx(_Handle._Get(), FileBasicInfo, &_Info, sizeof(_Info))) {
return __std_win_error{GetLastError()};
Expand All @@ -902,17 +900,21 @@ struct alignas(long long) _Aligned_file_attrs {
_Stats->_Attributes = __std_fs_file_attr{_Info.FileAttributes};
_Stats->_Last_write_time = _Info.LastWriteTime.QuadPart;
_Flags &= ~_Basic_info_data;
}
if (_Bitmask_includes(_Flags, __std_fs_stats_flags::_Reparse_tag)) {
// Calling GetFileInformationByHandleEx with FileAttributeTagInfo fails on FAT file system with
// ERROR_INVALID_PARAMETER. We avoid calling this for non-reparse-points.
if (_Info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
FILE_ATTRIBUTE_TAG_INFO _TagInfo;
if (!GetFileInformationByHandleEx(_Handle._Get(), FileAttributeTagInfo, &_TagInfo, sizeof(_TagInfo))) {
return __std_win_error{GetLastError()};
}

if (_Bitmask_includes(_Flags, _Attribute_tag_info_data)) {
FILE_ATTRIBUTE_TAG_INFO _Info;
if (!GetFileInformationByHandleEx(_Handle._Get(), FileAttributeTagInfo, &_Info, sizeof(_Info))) {
return __std_win_error{GetLastError()};
_Stats->_Reparse_point_tag = __std_fs_reparse_tag{_TagInfo.ReparseTag};
} else {
_Stats->_Reparse_point_tag = __std_fs_reparse_tag::_None;
}
_Flags &= ~__std_fs_stats_flags::_Reparse_tag;
}

_Stats->_Attributes = __std_fs_file_attr{_Info.FileAttributes};
_Stats->_Reparse_point_tag = __std_fs_reparse_tag{_Info.ReparseTag};
_Flags &= ~_Attribute_tag_info_data;
}

if (_Bitmask_includes(_Flags, _Standard_info_data)) {
Expand Down