2
0
Эх сурвалжийг харах

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)
Hein-Pieter van Braam 7 жил өмнө
parent
commit
8cde69f5f2

+ 22 - 5
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) {