diff options
-rw-r--r-- | drivers/windows/file_access_windows.cpp | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 726e0fdc5a..9885d9d7ee 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -32,6 +32,7 @@ #include "file_access_windows.h" +#include "core/config/project_settings.h" #include "core/os/os.h" #include "core/string/print_string.h" @@ -121,19 +122,63 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) { // Windows is case insensitive, but all other platforms are sensitive to it // To ease cross-platform development, we issue a warning if users try to access // a file using the wrong case (which *works* on Windows, but won't on other - // platforms). - if (p_mode_flags == READ) { - WIN32_FIND_DATAW d; - HANDLE fnd = FindFirstFileW((LPCWSTR)(path.utf16().get_data()), &d); - if (fnd != INVALID_HANDLE_VALUE) { - String fname = String::utf16((const char16_t *)(d.cFileName)); - if (!fname.is_empty()) { - String base_file = path.get_file(); - if (base_file != fname && base_file.findn(fname) == 0) { - WARN_PRINT("Case mismatch opening requested file '" + base_file + "', stored as '" + fname + "' in the filesystem. This file will not open when exported to other case-sensitive platforms."); + // platforms), we only check for relative paths, or paths in res:// or user://, + // other paths aren't likely to be portable anyway. + if (p_mode_flags == READ && (p_path.is_relative_path() || get_access_type() != ACCESS_FILESYSTEM)) { + String base_path = path; + String working_path; + String proper_path; + + if (get_access_type() == ACCESS_RESOURCES) { + if (ProjectSettings::get_singleton()) { + working_path = ProjectSettings::get_singleton()->get_resource_path(); + if (!working_path.is_empty()) { + base_path = working_path.path_to_file(base_path); } } + proper_path = "res://"; + } else if (get_access_type() == ACCESS_USERDATA) { + working_path = OS::get_singleton()->get_user_data_dir(); + if (!working_path.is_empty()) { + base_path = working_path.path_to_file(base_path); + } + proper_path = "user://"; + } + + WIN32_FIND_DATAW d; + Vector<String> parts = base_path.split("/"); + + bool mismatch = false; + + for (const String &part : parts) { + working_path = working_path.path_join(part); + + // Skip if relative. + if (part == "." || part == "..") { + proper_path = proper_path.path_join(part); + continue; + } + + HANDLE fnd = FindFirstFileW((LPCWSTR)(working_path.utf16().get_data()), &d); + + if (fnd == INVALID_HANDLE_VALUE) { + mismatch = false; + break; + } + + const String fname = String::utf16((const char16_t *)(d.cFileName)); + FindClose(fnd); + + if (!mismatch) { + mismatch = (part != fname && part.findn(fname) == 0); + } + + proper_path = proper_path.path_join(fname); + } + + if (mismatch) { + WARN_PRINT("Case mismatch opening requested file '" + p_path + "', stored as '" + proper_path + "' in the filesystem. This file will not open when exported to other case-sensitive platforms."); } } #endif |