diff --git a/include/fs/archive_ext_save_data.hpp b/include/fs/archive_ext_save_data.hpp index 6e7fe65b..fec923b4 100644 --- a/include/fs/archive_ext_save_data.hpp +++ b/include/fs/archive_ext_save_data.hpp @@ -9,6 +9,7 @@ public: u64 getFreeBytes() override { Helpers::panic("ExtSaveData::GetFreeBytes unimplemented"); return 0; } std::string name() override { return "ExtSaveData::" + backingFolder; } + HorizonResult createDirectory(const FSPath& path) override; HorizonResult createFile(const FSPath& path, u64 size) override; HorizonResult deleteFile(const FSPath& path) override; diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 437a5ea4..42025a3e 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -84,6 +84,7 @@ class ServiceManager { void receiveNotification(u32 messagePointer); void registerClient(u32 messagePointer); void subscribe(u32 messagePointer); + void unsubscribe(u32 messagePointer); public: ServiceManager(std::span regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config); diff --git a/src/core/fs/archive_ext_save_data.cpp b/src/core/fs/archive_ext_save_data.cpp index c07f3353..87b3662b 100644 --- a/src/core/fs/archive_ext_save_data.cpp +++ b/src/core/fs/archive_ext_save_data.cpp @@ -87,6 +87,27 @@ FileDescriptor ExtSaveDataArchive::openFile(const FSPath& path, const FilePerms& return FileError; } +HorizonResult ExtSaveDataArchive::createDirectory(const FSPath& path) { + if (path.type == PathType::UTF16) { + if (!isPathSafe(path)) { + Helpers::panic("Unsafe path in ExtSaveData::OpenFile"); + } + + fs::path p = IOFile::getAppData() / backingFolder; + p += fs::path(path.utf16_string).make_preferred(); + + if (fs::is_directory(p)) return Result::FS::AlreadyExists; + if (fs::is_regular_file(p)) { + Helpers::panic("File path passed to ExtSaveData::CreateDirectory"); + } + + bool success = fs::create_directory(p); + return success ? Result::Success : Result::FS::UnexpectedFileOrDir; + } else { + Helpers::panic("Unimplemented ExtSaveData::CreateDirectory"); + } +} + std::string ExtSaveDataArchive::getExtSaveDataPathFromBinary(const FSPath& path) { // TODO: Remove punning here const u32 mediaType = *(u32*)&path.binary[0]; diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index cb93b627..54e3ecf9 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -79,6 +79,7 @@ void ServiceManager::handleSyncRequest(u32 messagePointer) { case Commands::RegisterClient: registerClient(messagePointer); break; case Commands::GetServiceHandle: getServiceHandle(messagePointer); break; case Commands::Subscribe: subscribe(messagePointer); break; + case Commands::Unsubscribe: unsubscribe(messagePointer); break; default: Helpers::panic("Unknown \"srv:\" command: %08X", header); } } @@ -178,6 +179,14 @@ void ServiceManager::subscribe(u32 messagePointer) { mem.write32(messagePointer + 4, Result::Success); } +void ServiceManager::unsubscribe(u32 messagePointer) { + u32 id = mem.read32(messagePointer + 4); + log("srv::Unsubscribe (id = %d) (stubbed)\n", id); + + mem.write32(messagePointer, IPC::responseHeader(0xA, 1, 0)); + mem.write32(messagePointer + 4, Result::Success); +} + void ServiceManager::sendCommandToService(u32 messagePointer, Handle handle) { switch (handle) { // Breaking alphabetical order a bit to place the ones I think are most common at the top