diff options
author | Zach Hilman <DarkLordZach@users.noreply.github.com> | 2018-07-06 16:51:32 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-07-06 16:51:32 +0200 |
commit | 77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2 (patch) | |
tree | 38ef6451732c5eecb0efdd198f3db4d33848453c /src/core/file_sys/content_archive.h | |
parent | Merge pull request #629 from Subv/depth_test (diff) | |
download | yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.gz yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.bz2 yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.lz yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.xz yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.zst yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.zip |
Diffstat (limited to 'src/core/file_sys/content_archive.h')
-rw-r--r-- | src/core/file_sys/content_archive.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h new file mode 100644 index 000000000..eb4ca1c18 --- /dev/null +++ b/src/core/file_sys/content_archive.h @@ -0,0 +1,89 @@ +// 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<u8, 0x100> rsa_signature_1; + std::array<u8, 0x100> 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<u8, 0x10> rights_id; + std::array<NCASectionTableEntry, 0x4> section_tables; + std::array<std::array<u8, 0x20>, 0x4> hash_tables; + std::array<std::array<u8, 0x10>, 0x4> key_area; + INSERT_PADDING_BYTES(0xC0); +}; +static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size."); + +static bool IsDirectoryExeFS(std::shared_ptr<FileSys::VfsDirectory> pfs) { + // According to switchbrew, an exefs must only contain these two files: + return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr; +} + +static 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<std::shared_ptr<VfsFile>> GetFiles() const override; + std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; + std::string GetName() const override; + std::shared_ptr<VfsDirectory> 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<VirtualDir> dirs; + std::vector<VirtualFile> files; + + VirtualFile romfs = nullptr; + VirtualDir exefs = nullptr; + VirtualFile file; + + NCAHeader header{}; + + Loader::ResultStatus status{}; +}; + +} // namespace FileSys |