From 7c2167e0f231d26c8b17b7a04b5b8e7ea97e24e9 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 13 Sep 2023 23:21:30 +0300 Subject: [PATCH] Add SystemSaveData::OpenFile and split up frd:u and frd:a --- include/fs/archive_system_save_data.hpp | 5 +-- include/kernel/handles.hpp | 6 ++-- include/services/frd.hpp | 9 ++++-- src/core/fs/archive_system_save_data.cpp | 40 +++++++++++++++++++++++- src/core/services/frd.cpp | 2 +- src/core/services/fs.cpp | 5 +++ src/core/services/service_manager.cpp | 6 ++-- 7 files changed, 61 insertions(+), 12 deletions(-) diff --git a/include/fs/archive_system_save_data.hpp b/include/fs/archive_system_save_data.hpp index 2c39401e..f4aa3f06 100644 --- a/include/fs/archive_system_save_data.hpp +++ b/include/fs/archive_system_save_data.hpp @@ -26,10 +26,7 @@ class SystemSaveDataArchive : public ArchiveBase { Rust::Result openArchive(const FSPath& path) override; //Rust::Result openDirectory(const FSPath& path) override; - FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override { - Helpers::panic("Unimplemented OpenFile for SystemSaveData archive"); - return {}; - } + FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override { Helpers::panic("Unimplemented ReadFile for SystemSaveData archive"); diff --git a/include/kernel/handles.hpp b/include/kernel/handles.hpp index 749534b8..9a53eb3d 100644 --- a/include/kernel/handles.hpp +++ b/include/kernel/handles.hpp @@ -25,7 +25,8 @@ namespace KernelHandles { HID, // HID service (Handles input-related things including gyro. Does NOT handle New3DS controls or CirclePadPro) HTTP, // HTTP service (Handles HTTP requests) IR_USER, // One of 3 infrared communication services - FRD, // Friend service (Miiverse friend service) + FRD_A, // Friend service (Miiverse friend service) + FRD_U, FS, // Filesystem service GPU, // GPU service LCD, // LCD service (Used for configuring the displays) @@ -82,7 +83,8 @@ namespace KernelHandles { case HID: return "HID"; case HTTP: return "HTTP"; case IR_USER: return "IR:USER"; - case FRD: return "FRD"; + case FRD_A: return "FRD:A"; + case FRD_U: return "FRD:U"; case FS: return "FS"; case GPU: return "GSP::GPU"; case LCD: return "GSP::LCD"; diff --git a/include/services/frd.hpp b/include/services/frd.hpp index 65eb7041..46a6e272 100644 --- a/include/services/frd.hpp +++ b/include/services/frd.hpp @@ -15,7 +15,6 @@ struct FriendKey { static_assert(sizeof(FriendKey) == 16); class FRDService { - Handle handle = KernelHandles::FRD; Memory& mem; MAKE_LOG_FUNCTION(log, frdLogger) @@ -48,7 +47,13 @@ class FRDService { static_assert(sizeof(Profile) == 8); public: + enum class Type { + A, // frd:a + N, // frd:n + U, // frd:u + }; + FRDService(Memory& mem) : mem(mem) {} void reset(); - void handleSyncRequest(u32 messagePointer); + void handleSyncRequest(u32 messagePointer, Type type); }; \ No newline at end of file diff --git a/src/core/fs/archive_system_save_data.cpp b/src/core/fs/archive_system_save_data.cpp index ed931ec1..fea46d2c 100644 --- a/src/core/fs/archive_system_save_data.cpp +++ b/src/core/fs/archive_system_save_data.cpp @@ -4,9 +4,47 @@ namespace fs = std::filesystem; Rust::Result SystemSaveDataArchive::openArchive(const FSPath& path) { - if (path.type != PathType::Empty) { + if (path.type != PathType::Binary) { Helpers::panic("Unimplemented path type for SystemSaveData::OpenArchive"); } return Ok((ArchiveBase*)this); +} + +FileDescriptor SystemSaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) { + // TODO: Validate this. Temporarily copied from SaveData archive + + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in SystemSaveData::OpenFile"); + } + + if (perms.raw == 0 || (perms.create() && !perms.write())) { + Helpers::panic("[SystemSaveData] Unsupported flags for OpenFile"); + } + + fs::path p = IOFile::getAppData() / ".." / "SharedFiles" / "SystemSaveData"; + p += fs::path(path.utf16_string).make_preferred(); + + 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 (perms.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; + } + } + } + + Helpers::panic("SystemSaveData::OpenFile: Failed"); + return FileError; } \ No newline at end of file diff --git a/src/core/services/frd.cpp b/src/core/services/frd.cpp index d4a439df..fecb3322 100644 --- a/src/core/services/frd.cpp +++ b/src/core/services/frd.cpp @@ -27,7 +27,7 @@ namespace FRDCommands { void FRDService::reset() { loggedIn = false; } -void FRDService::handleSyncRequest(u32 messagePointer) { +void FRDService::handleSyncRequest(u32 messagePointer, FRDService::Type type) { const u32 command = mem.read32(messagePointer); switch (command) { case FRDCommands::AttachToEventNotification: attachToEventNotification(messagePointer); break; diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 964ab237..0ecc792b 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -53,6 +53,7 @@ void FSService::initializeFilesystem() { const auto savePath = IOFile::getAppData() / "SaveData"; // Create SaveData const auto formatPath = IOFile::getAppData() / "FormatInfo"; // Create folder for storing archive formatting info + const auto systemSaveDataPath = IOFile::getAppData() / ".." / "SharedFiles" / "SystemSaveData"; namespace fs = std::filesystem; @@ -71,6 +72,10 @@ void FSService::initializeFilesystem() { if (!fs::is_directory(formatPath)) { fs::create_directories(formatPath); } + + if (!fs::is_directory(systemSaveDataPath)) { + fs::create_directories(systemSaveDataPath); + } } ArchiveBase* FSService::getArchiveFromID(u32 id, const FSPath& archivePath) { diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 3696b0d1..e70a36ac 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -111,7 +111,8 @@ static std::map serviceMap = { { "hid:USER", KernelHandles::HID }, { "http:C", KernelHandles::HTTP }, { "ir:USER", KernelHandles::IR_USER }, - { "frd:u", KernelHandles::FRD }, + { "frd:a", KernelHandles::FRD_A }, + { "frd:u", KernelHandles::FRD_U }, { "fs:USER", KernelHandles::FS }, { "gsp::Gpu", KernelHandles::GPU }, { "gsp::Lcd", KernelHandles::LCD }, @@ -211,7 +212,8 @@ void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { case KernelHandles::HID: hid.handleSyncRequest(messagePointer); break; case KernelHandles::HTTP: http.handleSyncRequest(messagePointer); break; case KernelHandles::IR_USER: ir_user.handleSyncRequest(messagePointer); break; - case KernelHandles::FRD: frd.handleSyncRequest(messagePointer); break; + case KernelHandles::FRD_A: frd.handleSyncRequest(messagePointer, FRDService::Type::A); break; + case KernelHandles::FRD_U: frd.handleSyncRequest(messagePointer, FRDService::Type::U); break; case KernelHandles::LCD: gsp_lcd.handleSyncRequest(messagePointer); break; case KernelHandles::LDR_RO: ldr.handleSyncRequest(messagePointer); break; case KernelHandles::MCU_HWC: mcu_hwc.handleSyncRequest(messagePointer); break;