diff options
author | Hein-Pieter van Braam <hp@tmm.cx> | 2018-02-24 17:34:10 +0100 |
---|---|---|
committer | RĂ©mi Verschelde <rverschelde@gmail.com> | 2018-02-24 18:09:20 +0100 |
commit | 8cde69f5f2fa78ebd7651186eb8bd3abae9dfdd5 (patch) | |
tree | 0abe8847d38e35a339011f46d126914e9df36f7c | |
parent | bc4b7bc82e9a68975849de92ab6bdcd3f5ef4e62 (diff) |
Fix Windows file case changing
Windows APIs don't really provide a way to change a filename case. This
implements a little juggling to make this work. We first create a
guaranteed unique temporary file, we then replace the original file with
the temporary file and we finally rename it to the desired filename
case.
(cherry picked from commit d69d58deeaa523c6c38958b3956423ae8f814909)
-rw-r--r-- | drivers/windows/dir_access_windows.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 2e64b55430..cf4d82fb07 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -261,13 +261,30 @@ Error DirAccessWindows::rename(String p_path, String p_new_path) { p_new_path = fix_path(p_new_path); - if (file_exists(p_new_path)) { - if (remove(p_new_path) != OK) { + // If we're only changing file name case we need to do a little juggling + if (p_path.to_lower() == p_new_path.to_lower()) { + WCHAR tmpfile[MAX_PATH]; + + if (!GetTempFileNameW(fix_path(get_current_dir()).c_str(), NULL, 0, tmpfile)) { return FAILED; - }; - }; + } + + if (!::ReplaceFileW(tmpfile, p_path.c_str(), NULL, 0, NULL, NULL)) { + DeleteFileW(tmpfile); + return FAILED; + } - return ::_wrename(p_path.c_str(), p_new_path.c_str()) == 0 ? OK : FAILED; + return ::_wrename(tmpfile, p_new_path.c_str()) == 0 ? OK : FAILED; + + } else { + if (file_exists(p_new_path)) { + if (remove(p_new_path) != OK) { + return FAILED; + } + } + + return ::_wrename(p_path.c_str(), p_new_path.c_str()) == 0 ? OK : FAILED; + } } Error DirAccessWindows::remove(String p_path) { |