From a0974c18cd4a445940c737bf52904db3fc56c39e Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sun, 15 Jan 2023 05:39:03 +0100 Subject: [PATCH] RiivolutionPatcher: Use capitalization of file that exists in the host file system if possible. Fixes https://bugs.dolphin-emu.org/issues/13138 --- Source/Core/DiscIO/RiivolutionPatcher.cpp | 30 ++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Source/Core/DiscIO/RiivolutionPatcher.cpp b/Source/Core/DiscIO/RiivolutionPatcher.cpp index f12664710d..0f9bbec3ca 100644 --- a/Source/Core/DiscIO/RiivolutionPatcher.cpp +++ b/Source/Core/DiscIO/RiivolutionPatcher.cpp @@ -64,7 +64,8 @@ FileDataLoaderHostFS::MakeAbsoluteFromRelative(std::string_view external_relativ return std::nullopt; #endif - std::string result = external_relative_path.starts_with('/') ? m_sd_root : m_patch_root; + const std::string& root = external_relative_path.starts_with('/') ? m_sd_root : m_patch_root; + std::string result = root; std::string_view work = external_relative_path; // Strip away all leading and trailing path separators. @@ -116,6 +117,33 @@ FileDataLoaderHostFS::MakeAbsoluteFromRelative(std::string_view external_relativ // Append path element to result string. result += '/'; result += element; + + // Riivolution assumes a case-insensitive file system, which means it's possible that an XML + // file references a 'file.bin' but the actual file is named 'File.bin' or 'FILE.BIN'. To + // preserve this behavior, we modify the file path to match any existing file in the file + // system, if one exists. + if (!::File::Exists(result)) + { + // Drop path element again so we can search in the directory. + result.erase(result.size() - element.size(), element.size()); + + // Re-attach an element that actually matches the capitalization in the host filesystem. + auto possible_files = ::File::ScanDirectoryTree(result, false); + bool found = false; + for (auto& f : possible_files.children) + { + if (Common::CaseInsensitiveEquals(element, f.virtualName)) + { + result += f.virtualName; + found = true; + break; + } + } + + // If there isn't any file that matches just use the given element. + if (!found) + result += element; + } } // If this was the last path element, we're done.