summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys/content_archive.h
diff options
context:
space:
mode:
authorZach Hilman <DarkLordZach@users.noreply.github.com>2018-07-06 16:51:32 +0200
committerbunnei <bunneidev@gmail.com>2018-07-06 16:51:32 +0200
commit77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2 (patch)
tree38ef6451732c5eecb0efdd198f3db4d33848453c /src/core/file_sys/content_archive.h
parentMerge pull request #629 from Subv/depth_test (diff)
downloadyuzu-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.h89
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