From 9ee7543f9a796d3a73d17d1b8832741cf3529ce8 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sun, 20 Aug 2023 13:55:38 +0300 Subject: [PATCH] Moar SDMC --- include/fs/archive_sdmc.hpp | 3 + src/core/fs/archive_save_data.cpp | 10 ++- src/core/fs/archive_sdmc.cpp | 112 +++++++++++++++++++++++------- 3 files changed, 96 insertions(+), 29 deletions(-) diff --git a/include/fs/archive_sdmc.hpp b/include/fs/archive_sdmc.hpp index 23cbe600..4aa80eab 100644 --- a/include/fs/archive_sdmc.hpp +++ b/include/fs/archive_sdmc.hpp @@ -13,8 +13,11 @@ public: HorizonResult createFile(const FSPath& path, u64 size) override; HorizonResult deleteFile(const FSPath& path) override; + HorizonResult createDirectory(const FSPath& path) override; Rust::Result openArchive(const FSPath& path) override; + Rust::Result openDirectory(const FSPath& path) override; + FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override; }; \ No newline at end of file diff --git a/src/core/fs/archive_save_data.cpp b/src/core/fs/archive_save_data.cpp index 97ae3229..aa94cdc4 100644 --- a/src/core/fs/archive_save_data.cpp +++ b/src/core/fs/archive_save_data.cpp @@ -39,14 +39,17 @@ HorizonResult SaveDataArchive::createFile(const FSPath& path, u64 size) { HorizonResult SaveDataArchive::createDirectory(const FSPath& path) { if (path.type == PathType::UTF16) { - if (!isPathSafe(path)) + if (!isPathSafe(path)) { Helpers::panic("Unsafe path in SaveData::OpenFile"); + } fs::path p = IOFile::getAppData() / "SaveData"; p += fs::path(path.utf16_string).make_preferred(); - if (fs::is_directory(p)) + if (fs::is_directory(p)) { return Result::FS::AlreadyExists; + } + if (fs::is_regular_file(p)) { Helpers::panic("File path passed to SaveData::CreateDirectory"); } @@ -128,8 +131,9 @@ FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& pe Rust::Result SaveDataArchive::openDirectory(const FSPath& path) { if (path.type == PathType::UTF16) { - if (!isPathSafe(path)) + if (!isPathSafe(path)) { Helpers::panic("Unsafe path in SaveData::OpenDirectory"); + } fs::path p = IOFile::getAppData() / "SaveData"; p += fs::path(path.utf16_string).make_preferred(); diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index c8e4ebb3..ee5c8ffb 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -14,43 +14,103 @@ HorizonResult SDMCArchive::deleteFile(const FSPath& path) { } FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) { - if (path.type == PathType::ASCII) { - if (!isPathSafe(path)) { - Helpers::panic("Unsafe path in SaveData::OpenFile"); + FilePerms realPerms = perms; + // SD card always has read permission + realPerms.raw |= (1 << 0); + + if ((realPerms.create() && !realPerms.write())) { + Helpers::panic("[SDMC] Unsupported flags for OpenFile"); + } + + std::filesystem::path p = IOFile::getAppData() / "SDMC"; + + switch (path.type) { + case PathType::ASCII: + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); + } + + p += fs::path(path.string).make_preferred(); + break; + + case PathType::UTF16: + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); + } + + p += fs::path(path.utf16_string).make_preferred(); + break; + + default: Helpers::panic("SDMCArchive::OpenFile: Failed. Path type: %d", path.type); return FileError; + } + + const char* permString = perms.write() ? "r+b" : "rb"; + + if (fs::exists(p)) { // Return file descriptor if the file exists + IOFile file(p.string().c_str(), permString); + return file.isOpen() ? file.getHandle() : FileError; + } else { + // If the file is not found, create it if the create flag is on + if (realPerms.create()) { + IOFile file(p.string().c_str(), "wb"); // Create file + file.close(); // Close it + + file.open(p.string().c_str(), permString); // Reopen with proper perms + return file.isOpen() ? file.getHandle() : FileError; + } else { + return FileError; } + } +} - FilePerms realPerms = perms; - // SD card always has read permission - realPerms.raw |= (1 << 0); - - if ((realPerms.create() && !realPerms.write())) { - Helpers::panic("[SaveData] Unsupported flags for OpenFile"); +HorizonResult SDMCArchive::createDirectory(const FSPath& path) { + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SDMCArchive::OpenFile"); } fs::path p = IOFile::getAppData() / "SDMC"; - p += fs::path(path.string).make_preferred(); + p += fs::path(path.utf16_string).make_preferred(); - const char* permString = perms.write() ? "r+b" : "rb"; + if (fs::is_directory(p)) { + return Result::FS::AlreadyExists; + } - if (fs::exists(p)) { // Return file descriptor if the file exists - IOFile file(p.string().c_str(), permString); - return file.isOpen() ? file.getHandle() : FileError; + if (fs::is_regular_file(p)) { + Helpers::panic("File path passed to SDMCArchive::CreateDirectory"); + } + + std::error_code ec; + bool success = fs::create_directory(p, ec); + return success ? Result::Success : Result::FS::UnexpectedFileOrDir; + } else { + Helpers::panic("Unimplemented SDMC::CreateDirectory path type"); + } +} + +Rust::Result SDMCArchive::openDirectory(const FSPath& path) { + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SaveData::OpenDirectory"); + } + + fs::path p = IOFile::getAppData() / "SDMC"; + p += fs::path(path.utf16_string).make_preferred(); + + if (fs::is_regular_file(p)) { + printf("SDMC: OpenDirectory used with a file path"); + return Err(Result::FS::UnexpectedFileOrDir); + } + + if (fs::is_directory(p)) { + return Ok(DirectorySession(this, p)); } else { - // If the file is not found, create it if the create flag is on - if (realPerms.create()) { - IOFile file(p.string().c_str(), "wb"); // Create file - file.close(); // Close it - - file.open(p.string().c_str(), permString); // Reopen with proper perms - return file.isOpen() ? file.getHandle() : FileError; - } else { - return FileError; - } + return Err(Result::FS::FileNotFoundAlt); } } - Helpers::panic("SDMCArchive::OpenFile: Failed"); - return FileError; + Helpers::panic("SDMCArchive::OpenDirectory: Unimplemented path type"); + return Err(Result::Success); } Rust::Result SDMCArchive::openArchive(const FSPath& path) {