From d69d58deeaa523c6c38958b3956423ae8f814909 Mon Sep 17 00:00:00 2001 From: Hein-Pieter van Braam Date: Sat, 24 Feb 2018 17:34:10 +0100 Subject: [PATCH] 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. --- drivers/windows/dir_access_windows.cpp | 29 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index 2e64b55430e..cf4d82fb078 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) { - return FAILED; - }; - }; + // 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]; - return ::_wrename(p_path.c_str(), p_new_path.c_str()) == 0 ? OK : FAILED; + 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(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) {