From 29aff8d5ab46c8d0199aa4bfa7eeff5d4fa2d7ef Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 18 Jul 2018 21:07:11 -0400 Subject: Virtual Filesystem 2: Electric Boogaloo (#676) * Virtual Filesystem * Fix delete bug and documentate * Review fixes + other stuff * Fix puyo regression --- src/core/file_sys/content_archive.h | 95 +++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/core/file_sys/content_archive.h (limited to 'src/core/file_sys/content_archive.h') diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h new file mode 100644 index 000000000..129a70b97 --- /dev/null +++ b/src/core/file_sys/content_archive.h @@ -0,0 +1,95 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/swap.h" +#include "core/file_sys/partition_filesystem.h" + +namespace FileSys { + +enum class NCAContentType : u8 { + Program = 0, + Meta = 1, + Control = 2, + Manual = 3, + Data = 4, +}; + +struct NCASectionTableEntry { + u32_le media_offset; + u32_le media_end_offset; + INSERT_PADDING_BYTES(0x8); +}; +static_assert(sizeof(NCASectionTableEntry) == 0x10, "NCASectionTableEntry has incorrect size."); + +struct NCAHeader { + std::array rsa_signature_1; + std::array rsa_signature_2; + u32_le magic; + u8 is_system; + NCAContentType content_type; + u8 crypto_type; + u8 key_index; + u64_le size; + u64_le title_id; + INSERT_PADDING_BYTES(0x4); + u32_le sdk_version; + u8 crypto_type_2; + INSERT_PADDING_BYTES(15); + std::array rights_id; + std::array section_tables; + std::array, 0x4> hash_tables; + std::array, 0x4> key_area; + INSERT_PADDING_BYTES(0xC0); +}; +static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size."); + +inline bool IsDirectoryExeFS(std::shared_ptr pfs) { + // According to switchbrew, an exefs must only contain these two files: + return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr; +} + +inline bool IsValidNCA(const NCAHeader& header) { + return header.magic == Common::MakeMagic('N', 'C', 'A', '2') || + header.magic == Common::MakeMagic('N', 'C', 'A', '3'); +} + +// An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner. +// After construction, use GetStatus to determine if the file is valid and ready to be used. +class NCA : public ReadOnlyVfsDirectory { +public: + explicit NCA(VirtualFile file); + Loader::ResultStatus GetStatus() const; + + std::vector> GetFiles() const override; + std::vector> GetSubdirectories() const override; + std::string GetName() const override; + std::shared_ptr GetParentDirectory() const override; + + NCAContentType GetType() const; + u64 GetTitleId() const; + + VirtualFile GetRomFS() const; + VirtualDir GetExeFS() const; + +protected: + bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; + +private: + std::vector dirs; + std::vector files; + + VirtualFile romfs = nullptr; + VirtualDir exefs = nullptr; + VirtualFile file; + + NCAHeader header{}; + + Loader::ResultStatus status{}; +}; + +} // namespace FileSys -- cgit v1.2.3