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.
This commit is contained in:
Hein-Pieter van Braam 2018-02-24 17:34:10 +01:00
parent 34591f9451
commit d69d58deea
1 changed files with 23 additions and 6 deletions

View File

@ -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) {