diff options
| author | Dan Engelbrecht <[email protected]> | 2025-04-10 20:07:49 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-04-10 20:07:49 +0200 |
| commit | 81fb756a872817c625aef2b19c6b05a77a514587 (patch) | |
| tree | fe02055df361119de00416e411209ddc7adeea4b /src/zencore/filesystem.cpp | |
| parent | multpart download crash (#353) (diff) | |
| download | zen-81fb756a872817c625aef2b19c6b05a77a514587.tar.xz zen-81fb756a872817c625aef2b19c6b05a77a514587.zip | |
filesystem retry fixes (#354)
* add more forgiving retries with filesystem
* fall back to FindFirstFile if access prevents us from using GetFileAttributes
* only validate hash if we have a complete payload in http client
* changelog
Diffstat (limited to 'src/zencore/filesystem.cpp')
| -rw-r--r-- | src/zencore/filesystem.cpp | 101 |
1 files changed, 67 insertions, 34 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index 4ec563ba3..8ee21d9ab 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -251,6 +251,51 @@ MakeFileModeReadOnly(uint32_t FileMode, bool ReadOnly) return ReadOnly ? (FileMode & ~FileModeWriteEnableFlags) : (FileMode | FileModeWriteEnableFlags); } +#if ZEN_PLATFORM_WINDOWS + +static DWORD +WinGetFileAttributes(const std::filesystem::path& Path, std::error_code& Ec) +{ + DWORD Attributes = ::GetFileAttributes(Path.native().c_str()); + if (Attributes == INVALID_FILE_ATTRIBUTES) + { + DWORD LastError = GetLastError(); + switch (LastError) + { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_BAD_NETPATH: + case ERROR_INVALID_DRIVE: + break; + case ERROR_ACCESS_DENIED: + { + WIN32_FIND_DATA FindData; + HANDLE FindHandle = ::FindFirstFile(Path.native().c_str(), &FindData); + if (FindHandle == INVALID_HANDLE_VALUE) + { + DWORD LastFindError = GetLastError(); + if (LastFindError != ERROR_FILE_NOT_FOUND) + { + Ec = MakeErrorCode(LastError); + } + } + else + { + CloseHandle(FindHandle); + Attributes = FindData.dwFileAttributes; + } + } + break; + default: + Ec = MakeErrorCode(LastError); + break; + } + } + return Attributes; +} + +#endif // ZEN_PLATFORM_WINDOWS + bool RemoveDirNative(const std::filesystem::path& Path, std::error_code& Ec) { @@ -286,7 +331,12 @@ RemoveFileNative(const std::filesystem::path& Path, bool ForceRemoveReadOnlyFile { if (ForceRemoveReadOnlyFiles) { - DWORD FileAttributes = ::GetFileAttributes(NativePath); + DWORD FileAttributes = WinGetFileAttributes(NativePath, Ec); + if (Ec) + { + return false; + } + if ((FileAttributes != INVALID_FILE_ATTRIBUTES) && IsFileAttributeReadOnly(FileAttributes) != 0) { ::SetFileAttributes(NativePath, MakeFileAttributeReadOnly(FileAttributes, false)); @@ -1597,21 +1647,13 @@ bool IsFile(const std::filesystem::path& Path, std::error_code& Ec) { #if ZEN_PLATFORM_WINDOWS - DWORD Attributes = ::GetFileAttributes(Path.native().c_str()); + DWORD Attributes = WinGetFileAttributes(Path, Ec); + if (Ec) + { + return false; + } if (Attributes == INVALID_FILE_ATTRIBUTES) { - DWORD LastError = GetLastError(); - switch (LastError) - { - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - case ERROR_BAD_NETPATH: - case ERROR_INVALID_DRIVE: - break; - default: - Ec = MakeErrorCode(LastError); - break; - } return false; } return (Attributes & FILE_ATTRIBUTE_DIRECTORY) == 0; @@ -1651,21 +1693,13 @@ bool IsDir(const std::filesystem::path& Path, std::error_code& Ec) { #if ZEN_PLATFORM_WINDOWS - DWORD Attributes = ::GetFileAttributes(Path.native().c_str()); + DWORD Attributes = WinGetFileAttributes(Path, Ec); + if (Ec) + { + return false; + } if (Attributes == INVALID_FILE_ATTRIBUTES) { - DWORD LastError = GetLastError(); - switch (LastError) - { - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - case ERROR_BAD_NETPATH: - case ERROR_INVALID_DRIVE: - break; - default: - Ec = MakeErrorCode(LastError); - break; - } return false; } return (Attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; @@ -2492,13 +2526,7 @@ PickDefaultSystemRootDirectory() uint32_t GetFileAttributes(const std::filesystem::path& Filename, std::error_code& Ec) { - DWORD Attributes = ::GetFileAttributes(Filename.native().c_str()); - if (Attributes == INVALID_FILE_ATTRIBUTES) - { - Ec = MakeErrorCodeFromLastError(); - return 0; - } - return (uint32_t)Attributes; + return WinGetFileAttributes(Filename, Ec); } uint32_t @@ -2594,6 +2622,11 @@ SetFileReadOnly(const std::filesystem::path& Filename, bool ReadOnly, std::error { return false; } + if (CurrentAttributes == INVALID_FILE_ATTRIBUTES) + { + Ec = MakeErrorCode(ERROR_FILE_NOT_FOUND); + return false; + } uint32_t NewAttributes = MakeFileAttributeReadOnly(CurrentAttributes, ReadOnly); if (CurrentAttributes != NewAttributes) { |