aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-04-10 20:07:49 +0200
committerGitHub Enterprise <[email protected]>2025-04-10 20:07:49 +0200
commit81fb756a872817c625aef2b19c6b05a77a514587 (patch)
treefe02055df361119de00416e411209ddc7adeea4b /src/zencore/filesystem.cpp
parentmultpart download crash (#353) (diff)
downloadzen-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.cpp101
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)
{