From fdd1aad3b5dd44e28ea9a5192f7e9d00507c84da Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Sat, 4 Dec 2021 03:19:01 +0700 Subject: [PATCH 1/4] refresh should work on FAT32 --- stl/src/filesystem.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/stl/src/filesystem.cpp b/stl/src/filesystem.cpp index 97a404bde0..1e8ac5748d 100644 --- a/stl/src/filesystem.cpp +++ b/stl/src/filesystem.cpp @@ -907,7 +907,14 @@ struct alignas(long long) _Aligned_file_attrs { 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()}; + const DWORD _Error = GetLastError(); + if (_Error == ERROR_INVALID_PARAMETER) { + // Calling GetFileInformationByHandleEx with FileAttributeTagInfo fails on FAT file system with + // ERROR_INVALID_PARAMETER. Clear _Info.ReparseTag to indicate no symlinks are possible. + _Info.ReparseTag = 0; + } else { + return __std_win_error{_Error}; + } } _Stats->_Attributes = __std_fs_file_attr{_Info.FileAttributes}; From 43dd7d8033b03770b3ac5bb02f4d9fa9864dcbe9 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Sat, 4 Dec 2021 12:00:22 +0700 Subject: [PATCH 2/4] GetFileInformationByHandleEx doesn't fill FileAttributes when fails --- stl/src/filesystem.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/stl/src/filesystem.cpp b/stl/src/filesystem.cpp index 1e8ac5748d..52aae35da2 100644 --- a/stl/src/filesystem.cpp +++ b/stl/src/filesystem.cpp @@ -888,11 +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)) { + if (_Bitmask_includes(_Flags, _Basic_info_data | __std_fs_stats_flags::_Reparse_tag)) { // we have data FileBasicInfo can fill in, that FileAttributeTagInfo wouldn't exactly fill in FILE_BASIC_INFO _Info; if (!GetFileInformationByHandleEx(_Handle._Get(), FileBasicInfo, &_Info, sizeof(_Info))) { @@ -902,24 +901,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))) { - const DWORD _Error = GetLastError(); - if (_Error == ERROR_INVALID_PARAMETER) { - // Calling GetFileInformationByHandleEx with FileAttributeTagInfo fails on FAT file system with - // ERROR_INVALID_PARAMETER. Clear _Info.ReparseTag to indicate no symlinks are possible. - _Info.ReparseTag = 0; + _Stats->_Reparse_point_tag = __std_fs_reparse_tag{_TagInfo.ReparseTag}; } else { - return __std_win_error{_Error}; + _Stats->_Reparse_point_tag = __std_fs_reparse_tag{0}; } + _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)) { From 1ea171c6444fc6d261791b2d32cf0811ed3d3438 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Sat, 4 Dec 2021 12:17:22 +0700 Subject: [PATCH 3/4] use enum name instead of 0 --- stl/src/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/src/filesystem.cpp b/stl/src/filesystem.cpp index 52aae35da2..9f7ee10407 100644 --- a/stl/src/filesystem.cpp +++ b/stl/src/filesystem.cpp @@ -912,7 +912,7 @@ struct alignas(long long) _Aligned_file_attrs { _Stats->_Reparse_point_tag = __std_fs_reparse_tag{_TagInfo.ReparseTag}; } else { - _Stats->_Reparse_point_tag = __std_fs_reparse_tag{0}; + _Stats->_Reparse_point_tag = __std_fs_reparse_tag::_None; } _Flags &= ~__std_fs_stats_flags::_Reparse_tag; } From ba2db5518383ec319bb8bf5a8a083c2ade7ed789 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 6 Jan 2022 16:23:22 +0700 Subject: [PATCH 4/4] remove an obsolete comment --- stl/src/filesystem.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/stl/src/filesystem.cpp b/stl/src/filesystem.cpp index 9f7ee10407..f31227cdda 100644 --- a/stl/src/filesystem.cpp +++ b/stl/src/filesystem.cpp @@ -892,7 +892,6 @@ struct alignas(long long) _Aligned_file_attrs { constexpr auto _Standard_info_data = __std_fs_stats_flags::_File_size | __std_fs_stats_flags::_Link_count; if (_Bitmask_includes(_Flags, _Basic_info_data | __std_fs_stats_flags::_Reparse_tag)) { - // we have data FileBasicInfo can fill in, that FileAttributeTagInfo wouldn't exactly fill in FILE_BASIC_INFO _Info; if (!GetFileInformationByHandleEx(_Handle._Get(), FileBasicInfo, &_Info, sizeof(_Info))) { return __std_win_error{GetLastError()};