From 313620cad9646c963289fdfcf88527b9b59783f9 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Tue, 23 Jan 2024 21:56:24 +0200 Subject: [PATCH] Implement SDMC Write-Only archive --- include/fs/archive_sdmc.hpp | 6 ++++-- include/services/fs.hpp | 7 ++++--- src/core/fs/archive_sdmc.cpp | 17 +++++++++++++++-- src/core/services/fs.cpp | 1 + 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/include/fs/archive_sdmc.hpp b/include/fs/archive_sdmc.hpp index 4aa80eabb..f63731c48 100644 --- a/include/fs/archive_sdmc.hpp +++ b/include/fs/archive_sdmc.hpp @@ -5,8 +5,10 @@ using Result::HorizonResult; class SDMCArchive : public ArchiveBase { -public: - SDMCArchive(Memory& mem) : ArchiveBase(mem) {} + bool isWriteOnly = false; // There's 2 variants of the SDMC archive: Regular one (Read/Write) and write-only + + public: + SDMCArchive(Memory& mem, bool writeOnly = false) : ArchiveBase(mem), isWriteOnly(writeOnly) {} u64 getFreeBytes() override { return 1_GB; } std::string name() override { return "SDMC"; } diff --git a/include/services/fs.hpp b/include/services/fs.hpp index 4d879e7f1..4a6131215 100644 --- a/include/services/fs.hpp +++ b/include/services/fs.hpp @@ -26,6 +26,7 @@ class FSService { SelfNCCHArchive selfNcch; SaveDataArchive saveData; SDMCArchive sdmc; + SDMCArchive sdmcWriteOnly; NCCHArchive ncch; // UserSaveData archives @@ -82,9 +83,9 @@ class FSService { public: FSService(Memory& mem, Kernel& kernel, const EmulatorConfig& config) - : mem(mem), saveData(mem), sharedExtSaveData_nand(mem, "../SharedFiles/NAND", true), extSaveData_sdmc(mem, "SDMC"), sdmc(mem), selfNcch(mem), - ncch(mem), userSaveData1(mem, ArchiveID::UserSaveData1), userSaveData2(mem, ArchiveID::UserSaveData2), kernel(kernel), config(config), - systemSaveData(mem) {} + : mem(mem), saveData(mem), sharedExtSaveData_nand(mem, "../SharedFiles/NAND", true), extSaveData_sdmc(mem, "SDMC"), sdmc(mem), + sdmcWriteOnly(mem, true), selfNcch(mem), ncch(mem), userSaveData1(mem, ArchiveID::UserSaveData1), + userSaveData2(mem, ArchiveID::UserSaveData2), kernel(kernel), config(config), systemSaveData(mem) {} void reset(); void handleSyncRequest(u32 messagePointer); diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index 232335d07..6c34de7ae 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -45,8 +45,16 @@ HorizonResult SDMCArchive::deleteFile(const FSPath& path) { FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) { FilePerms realPerms = perms; - // SD card always has read permission - realPerms.raw |= (1 << 0); + + if (isWriteOnly) { + if (perms.read()) { + Helpers::warn("SDMC: Read flag is not allowed in SDMC Write-Only archive"); + return FileError; + } + } else { + // Regular SDMC archive always has read permission + realPerms.raw |= (1 << 0); + } if ((realPerms.create() && !realPerms.write())) { Helpers::panic("[SDMC] Unsupported flags for OpenFile"); @@ -130,6 +138,11 @@ HorizonResult SDMCArchive::createDirectory(const FSPath& path) { } Rust::Result SDMCArchive::openDirectory(const FSPath& path) { + if (isWriteOnly) { + Helpers::warn("SDMC: OpenDirectory is not allowed in SDMC Write-Only archive"); + return Err(Result::FS::UnexpectedFileOrDir); + } + if (path.type == PathType::UTF16) { if (!isPathSafe(path)) { Helpers::panic("Unsafe path in SaveData::OpenDirectory"); diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 264abcabb..2e1029586 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -97,6 +97,7 @@ ArchiveBase* FSService::getArchiveFromID(u32 id, const FSPath& archivePath) { case ArchiveID::SystemSaveData: return &systemSaveData; case ArchiveID::SDMC: return &sdmc; + case ArchiveID::SDMCWriteOnly: return &sdmcWriteOnly; case ArchiveID::SavedataAndNcch: return &ncch; // This can only access NCCH outside of FSPXI default: Helpers::panic("Unknown archive. ID: %d\n", id);