FileSystem: Add a case-insensitive match for nvm and mec file loading.

This commit is contained in:
Ty Lamontagne 2024-11-29 11:57:39 -05:00 committed by Ty
parent e8dbcc31aa
commit a60489b6fd
4 changed files with 51 additions and 6 deletions

View File

@ -994,6 +994,37 @@ std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode, Error*
#endif #endif
} }
std::FILE* FileSystem::OpenCFileTryIgnoreCase(const char* filename, const char* mode, Error* error)
{
#if defined(_WIN32) || defined(__APPLE__)
return OpenCFile(filename, mode, error);
#else
std::FILE* fp = std::fopen(filename, mode);
const auto cur_errno = errno;
if (!fp)
{
const auto dir = std::string(Path::GetDirectory(filename));
FindResultsArray files;
if (FindFiles(dir.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &files))
{
for (auto& file : files)
{
if (StringUtil::compareNoCase(file.FileName, filename))
{
fp = std::fopen(file.FileName.c_str(), mode);
break;
}
}
}
}
if (!fp)
Error::SetErrno(error, cur_errno);
return fp;
#endif
}
int FileSystem::OpenFDFile(const char* filename, int flags, int mode, Error* error) int FileSystem::OpenFDFile(const char* filename, int flags, int mode, Error* error)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -1015,6 +1046,11 @@ FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFile(const char* filename, c
return ManagedCFilePtr(OpenCFile(filename, mode, error)); return ManagedCFilePtr(OpenCFile(filename, mode, error));
} }
FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFileTryIgnoreCase(const char* filename, const char* mode, Error* error)
{
return ManagedCFilePtr(OpenCFileTryIgnoreCase(filename, mode, error));
}
std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode, Error* error) std::FILE* FileSystem::OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode, Error* error)
{ {
#ifdef _WIN32 #ifdef _WIN32

View File

@ -106,7 +106,16 @@ namespace FileSystem
/// open files /// open files
using ManagedCFilePtr = std::unique_ptr<std::FILE, FileDeleter>; using ManagedCFilePtr = std::unique_ptr<std::FILE, FileDeleter>;
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode, Error* error = nullptr); ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode, Error* error = nullptr);
// Tries to open a file using the given filename, but if that fails searches
// the directory for a file with a case-insensitive match.
// This is the same as OpenManagedCFile on Windows and MacOS
ManagedCFilePtr OpenManagedCFileTryIgnoreCase(const char* filename, const char* mode, Error* error = nullptr);
std::FILE* OpenCFile(const char* filename, const char* mode, Error* error = nullptr); std::FILE* OpenCFile(const char* filename, const char* mode, Error* error = nullptr);
// Tries to open a file using the given filename, but if that fails searches
// the directory for a file with a case-insensitive match.
// This is the same as OpenCFile on Windows and MacOS
std::FILE* OpenCFileTryIgnoreCase(const char* filename, const char* mode, Error* error = nullptr);
int FSeek64(std::FILE* fp, s64 offset, int whence); int FSeek64(std::FILE* fp, s64 offset, int whence);
s64 FTell64(std::FILE* fp); s64 FTell64(std::FILE* fp);
s64 FSize64(std::FILE* fp); s64 FSize64(std::FILE* fp);

View File

@ -155,7 +155,7 @@ void cdvdLoadNVRAM()
{ {
Error error; Error error;
const std::string nvmfile = cdvdGetNVRAMPath(); const std::string nvmfile = cdvdGetNVRAMPath();
auto fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "rb", &error); auto fp = FileSystem::OpenManagedCFileTryIgnoreCase(nvmfile.c_str(), "rb", &error);
if (!fp || std::fread(s_nvram, sizeof(s_nvram), 1, fp.get()) != 1) if (!fp || std::fread(s_nvram, sizeof(s_nvram), 1, fp.get()) != 1)
{ {
ERROR_LOG("Failed to open or read NVRAM at {}: {}", Path::GetFileName(nvmfile), error.GetDescription()); ERROR_LOG("Failed to open or read NVRAM at {}: {}", Path::GetFileName(nvmfile), error.GetDescription());
@ -178,7 +178,7 @@ void cdvdLoadNVRAM()
// Also load the mechacon version while we're here. // Also load the mechacon version while we're here.
const std::string mecfile = Path::ReplaceExtension(BiosPath, "mec"); const std::string mecfile = Path::ReplaceExtension(BiosPath, "mec");
fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "rb", &error); fp = FileSystem::OpenManagedCFileTryIgnoreCase(mecfile.c_str(), "rb", &error);
if (!fp || std::fread(&s_mecha_version, sizeof(s_mecha_version), 1, fp.get()) != 1) if (!fp || std::fread(&s_mecha_version, sizeof(s_mecha_version), 1, fp.get()) != 1)
{ {
s_mecha_version = DEFAULT_MECHA_VERSION; s_mecha_version = DEFAULT_MECHA_VERSION;
@ -186,7 +186,7 @@ void cdvdLoadNVRAM()
ERROR_LOG("Failed to open or read MEC file at {}: {}, creating default.", Path::GetFileName(nvmfile), ERROR_LOG("Failed to open or read MEC file at {}: {}, creating default.", Path::GetFileName(nvmfile),
error.GetDescription()); error.GetDescription());
fp.reset(); fp.reset();
fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "wb"); fp = FileSystem::OpenManagedCFileTryIgnoreCase(mecfile.c_str(), "wb");
if (!fp || std::fwrite(&s_mecha_version, sizeof(s_mecha_version), 1, fp.get()) != 1) if (!fp || std::fwrite(&s_mecha_version, sizeof(s_mecha_version), 1, fp.get()) != 1)
Host::ReportErrorAsync("Error", "Failed to write MEC file. Check your BIOS setup/permission settings."); Host::ReportErrorAsync("Error", "Failed to write MEC file. Check your BIOS setup/permission settings.");
} }
@ -197,10 +197,10 @@ void cdvdSaveNVRAM()
{ {
Error error; Error error;
const std::string nvmfile = cdvdGetNVRAMPath(); const std::string nvmfile = cdvdGetNVRAMPath();
auto fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "r+b", &error); auto fp = FileSystem::OpenManagedCFileTryIgnoreCase(nvmfile.c_str(), "r+b", &error);
if (!fp) if (!fp)
{ {
fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "w+b", &error); fp = FileSystem::OpenManagedCFileTryIgnoreCase(nvmfile.c_str(), "w+b", &error);
if (!fp) [[unlikely]] if (!fp) [[unlikely]]
{ {
ERROR_LOG("Failed to open NVRAM at {} for updating: {}", Path::GetFileName(nvmfile), error.GetDescription()); ERROR_LOG("Failed to open NVRAM at {} for updating: {}", Path::GetFileName(nvmfile), error.GetDescription());

View File

@ -226,7 +226,7 @@ static void LoadExtraRom(const char* ext, u32 offset, u32 size)
BiosRom.resize(offset + size); BiosRom.resize(offset + size);
auto fp = FileSystem::OpenManagedCFile(Bios1.c_str(), "rb"); auto fp = FileSystem::OpenManagedCFileTryIgnoreCase(Bios1.c_str(), "rb");
if (!fp || std::fread(&BiosRom[offset], static_cast<size_t>(std::min<s64>(size, filesize)), 1, fp.get()) != 1) if (!fp || std::fread(&BiosRom[offset], static_cast<size_t>(std::min<s64>(size, filesize)), 1, fp.get()) != 1)
{ {
Console.Warning("BIOS Warning: %s could not be read (permission denied?)", ext); Console.Warning("BIOS Warning: %s could not be read (permission denied?)", ext);