From 0d6082e2411f93d12ce7c119f4c69fe86ff8843c Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sun, 19 Mar 2023 09:33:21 +0200 Subject: [PATCH] [FS] Add GetFormatInfo --- include/fs/archive_base.hpp | 14 +++++++++++++- include/services/fs.hpp | 1 + src/core/services/fs.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/fs/archive_base.hpp b/include/fs/archive_base.hpp index b3beb5ca..cdf3b66a 100644 --- a/include/fs/archive_base.hpp +++ b/include/fs/archive_base.hpp @@ -127,11 +127,18 @@ enum class DeleteFileResult : u32 { }; class ArchiveBase { +public: + struct FormatInfo { + u32 size; // Archive size + u32 numOfDirectories; // Number of directories + u32 numOfFiles; // Number of files + bool duplicateData; // Whether to duplicate data or not + }; + protected: using Handle = u32; static constexpr FileDescriptor NoFile = nullptr; static constexpr FileDescriptor FileError = std::nullopt; - Memory& mem; // Returns if a specified 3DS path in UTF16 or ASCII format is safe or not @@ -184,6 +191,11 @@ public: virtual u64 getFreeBytes() = 0; virtual CreateFileResult createFile(const FSPath& path, u64 size) = 0; virtual DeleteFileResult deleteFile(const FSPath& path) = 0; + virtual FormatInfo getFormatInfo(const FSPath& path) { + Helpers::panic("Unimplemented GetFormatInfo for %s archive", name().c_str()); + // Return a dummy struct just to avoid the UB of not returning anything, even if we panic + return FormatInfo{ .size = 0, .numOfDirectories = 0, .numOfFiles = 0, .duplicateData = false }; + } // Returns nullopt if opening the file failed, otherwise returns a file descriptor to it (nullptr if none is needed) virtual FileDescriptor openFile(const FSPath& path, const FilePerms& perms) = 0; diff --git a/include/services/fs.hpp b/include/services/fs.hpp index 40555e89..3b670d0b 100644 --- a/include/services/fs.hpp +++ b/include/services/fs.hpp @@ -35,6 +35,7 @@ class FSService { void createFile(u32 messagePointer); void closeArchive(u32 messagePointer); void deleteFile(u32 messagePointer); + void getFormatInfo(u32 messagePointer); void getPriority(u32 messagePointer); void initialize(u32 messagePointer); void initializeWithSdkVersion(u32 messagePointer); diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index 81bf19c3..0d33eb43 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -17,6 +17,7 @@ namespace FSCommands { OpenArchive = 0x080C00C2, CloseArchive = 0x080E0080, IsSdmcDetected = 0x08170000, + GetFormatInfo = 0x084500C2, InitializeWithSdkVersion = 0x08610042, SetPriority = 0x08620040, GetPriority = 0x08630000 @@ -115,6 +116,7 @@ void FSService::handleSyncRequest(u32 messagePointer) { case FSCommands::CreateFile: createFile(messagePointer); break; case FSCommands::CloseArchive: closeArchive(messagePointer); break; case FSCommands::DeleteFile: deleteFile(messagePointer); break; + case FSCommands::GetFormatInfo: getFormatInfo(messagePointer); break; case FSCommands::GetPriority: getPriority(messagePointer); break; case FSCommands::Initialize: initialize(messagePointer); break; case FSCommands::InitializeWithSdkVersion: initializeWithSdkVersion(messagePointer); break; @@ -288,6 +290,28 @@ void FSService::deleteFile(u32 messagePointer) { mem.write32(messagePointer + 4, static_cast(res)); } +void FSService::getFormatInfo(u32 messagePointer) { + const u32 archiveID = mem.read32(messagePointer + 4); + const u32 pathType = mem.read32(messagePointer + 8); + const u32 pathSize = mem.read32(messagePointer + 12); + const u32 pathPointer = mem.read32(messagePointer + 20); + + const auto path = readPath(pathType, pathPointer, pathSize); + log("FS::GetFormatInfo(archive ID = %d, archive path type = %d)\n", archiveID, pathType); + + ArchiveBase* archive = getArchiveFromID(archiveID); + if (archive == nullptr) [[unlikely]] { + Helpers::panic("OpenArchive: Tried to open unknown archive %d.", archiveID); + } + + ArchiveBase::FormatInfo info = archive->getFormatInfo(path); + mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 8, info.size); + mem.write32(messagePointer + 12, info.numOfDirectories); + mem.write32(messagePointer + 16, info.numOfFiles); + mem.write8(messagePointer + 20, info.duplicateData ? 1 : 0); +} + void FSService::getPriority(u32 messagePointer) { log("FS::GetPriority\n");