diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-01-12 17:03:08 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2018-01-12 17:03:52 -0300 |
commit | e56b3439a5e8bf56c4b843e044a96f1446564745 (patch) | |
tree | dc559452c69569605594054b80868e3bb9103800 /drivers/windows/file_access_windows.cpp | |
parent | d486cae7016c77af114d8019abf37c57e8bba386 (diff) | |
download | redot-engine-e56b3439a5e8bf56c4b843e044a96f1446564745.tar.gz |
Attempt renaming multiple times on safe file save, and make the behavior optional. Fixes #14339.
Diffstat (limited to 'drivers/windows/file_access_windows.cpp')
-rw-r--r-- | drivers/windows/file_access_windows.cpp | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index dbffac8ebd..832d75b17d 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -31,6 +31,7 @@ #ifdef WINDOWS_ENABLED #include "file_access_windows.h" +#include "os/os.h" #include "shlwapi.h" #include <windows.h> @@ -115,25 +116,35 @@ void FileAccessWindows::close() { //_wunlink(save_path.c_str()); //unlink if exists //int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str()); - bool rename_error; + bool rename_error = true; + int attempts = 4; + while (rename_error && attempts) { + // This workaround of trying multiple times is added to deal with paranoid Windows + // antiviruses that love reading just written files even if they are not executable, thus + // locking the file and preventing renaming from happening. #ifdef UWP_ENABLED - // UWP has no PathFileExists, so we check attributes instead - DWORD fileAttr; + // UWP has no PathFileExists, so we check attributes instead + DWORD fileAttr; - fileAttr = GetFileAttributesW(save_path.c_str()); - if (INVALID_FILE_ATTRIBUTES == fileAttr) { + fileAttr = GetFileAttributesW(save_path.c_str()); + if (INVALID_FILE_ATTRIBUTES == fileAttr) { #else - if (!PathFileExistsW(save_path.c_str())) { + if (!PathFileExistsW(save_path.c_str())) { #endif - //creating new file - rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0; - } else { - //atomic replace for existing file - rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL); - } - if (rename_error && close_fail_notify) { - close_fail_notify(save_path); + //creating new file + rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0; + } else { + //atomic replace for existing file + rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL); + } + if (rename_error && close_fail_notify) { + close_fail_notify(save_path); + } + if (rename_error) { + attempts--; + OS::get_singleton()->delay_usec(1000000); //wait 100msec and try again + } } save_path = ""; |