Skip to content

Commit

Permalink
FileSystem: Add a case-insensitive match for nvm and mec file loading.
Browse files Browse the repository at this point in the history
  • Loading branch information
F0bes committed Nov 29, 2024
1 parent c31f324 commit bd5ecfd
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 6 deletions.
36 changes: 36 additions & 0 deletions common/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,37 @@ std::FILE* FileSystem::OpenCFile(const char* filename, const char* mode, Error*
#endif
}

std::FILE* FileSystem::OpenCFileTryIgnoreCase(const char* filename, const char* mode, Error* error)
{
#ifdef _WIN32
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)
{
#ifdef _WIN32
Expand All @@ -1015,6 +1046,11 @@ FileSystem::ManagedCFilePtr FileSystem::OpenManagedCFile(const char* filename, c
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)
{
#ifdef _WIN32
Expand Down
9 changes: 9 additions & 0 deletions common/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,16 @@ namespace FileSystem
/// open files
using ManagedCFilePtr = std::unique_ptr<std::FILE, FileDeleter>;
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
ManagedCFilePtr OpenManagedCFileTryIgnoreCase(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
std::FILE* OpenCFileTryIgnoreCase(const char* filename, const char* mode, Error* error = nullptr);

int FSeek64(std::FILE* fp, s64 offset, int whence);
s64 FTell64(std::FILE* fp);
s64 FSize64(std::FILE* fp);
Expand Down
10 changes: 5 additions & 5 deletions pcsx2/CDVD/CDVD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void cdvdLoadNVRAM()
{
Error error;
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)
{
ERROR_LOG("Failed to open or read NVRAM at {}: {}", Path::GetFileName(nvmfile), error.GetDescription());
Expand All @@ -178,15 +178,15 @@ void cdvdLoadNVRAM()

// Also load the mechacon version while we're here.
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)
{
s_mecha_version = DEFAULT_MECHA_VERSION;

ERROR_LOG("Failed to open or read MEC file at {}: {}, creating default.", Path::GetFileName(nvmfile),
error.GetDescription());
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)
Host::ReportErrorAsync("Error", "Failed to write MEC file. Check your BIOS setup/permission settings.");
}
Expand All @@ -197,10 +197,10 @@ void cdvdSaveNVRAM()
{
Error error;
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)
{
fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "w+b", &error);
fp = FileSystem::OpenManagedCFileTryIgnoreCase(nvmfile.c_str(), "w+b", &error);
if (!fp) [[unlikely]]
{
ERROR_LOG("Failed to open NVRAM at {} for updating: {}", Path::GetFileName(nvmfile), error.GetDescription());
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/ps2/BiosTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ static void LoadExtraRom(const char* ext, u32 offset, u32 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)
{
Console.Warning("BIOS Warning: %s could not be read (permission denied?)", ext);
Expand Down

0 comments on commit bd5ecfd

Please sign in to comment.