summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys/nca_metadata.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_sys/nca_metadata.h')
-rw-r--r--src/core/file_sys/nca_metadata.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/core/file_sys/nca_metadata.h b/src/core/file_sys/nca_metadata.h
new file mode 100644
index 000000000..7b0725f36
--- /dev/null
+++ b/src/core/file_sys/nca_metadata.h
@@ -0,0 +1,105 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include "core/file_sys/vfs.h"
+
+namespace FileSys {
+class CNMT;
+
+struct CNMTHeader;
+struct OptionalHeader;
+
+enum class TitleType : u8 {
+ SystemProgram = 0x01,
+ SystemDataArchive = 0x02,
+ SystemUpdate = 0x03,
+ FirmwarePackageA = 0x04,
+ FirmwarePackageB = 0x05,
+ Application = 0x80,
+ Update = 0x81,
+ AOC = 0x82,
+ DeltaTitle = 0x83,
+};
+
+enum class ContentRecordType : u8 {
+ Meta = 0,
+ Program = 1,
+ Data = 2,
+ Control = 3,
+ Manual = 4,
+ Legal = 5,
+ Patch = 6,
+};
+
+struct ContentRecord {
+ std::array<u8, 0x20> hash;
+ std::array<u8, 0x10> nca_id;
+ std::array<u8, 0x6> size;
+ ContentRecordType type;
+ INSERT_PADDING_BYTES(1);
+};
+static_assert(sizeof(ContentRecord) == 0x38, "ContentRecord has incorrect size.");
+
+constexpr ContentRecord EMPTY_META_CONTENT_RECORD{{}, {}, {}, ContentRecordType::Meta, {}};
+
+struct MetaRecord {
+ u64_le title_id;
+ u32_le title_version;
+ TitleType type;
+ u8 install_byte;
+ INSERT_PADDING_BYTES(2);
+};
+static_assert(sizeof(MetaRecord) == 0x10, "MetaRecord has incorrect size.");
+
+struct OptionalHeader {
+ u64_le title_id;
+ u64_le minimum_version;
+};
+static_assert(sizeof(OptionalHeader) == 0x10, "OptionalHeader has incorrect size.");
+
+struct CNMTHeader {
+ u64_le title_id;
+ u32_le title_version;
+ TitleType type;
+ INSERT_PADDING_BYTES(1);
+ u16_le table_offset;
+ u16_le number_content_entries;
+ u16_le number_meta_entries;
+ INSERT_PADDING_BYTES(12);
+};
+static_assert(sizeof(CNMTHeader) == 0x20, "CNMTHeader has incorrect size.");
+
+// A class representing the format used by NCA metadata files, typically named {}.cnmt.nca or
+// meta0.ncd. These describe which NCA's belong with which titles in the registered cache.
+class CNMT {
+public:
+ explicit CNMT(VirtualFile file);
+ CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentRecord> content_records,
+ std::vector<MetaRecord> meta_records);
+
+ u64 GetTitleID() const;
+ u32 GetTitleVersion() const;
+ TitleType GetType() const;
+
+ const std::vector<ContentRecord>& GetContentRecords() const;
+ const std::vector<MetaRecord>& GetMetaRecords() const;
+
+ bool UnionRecords(const CNMT& other);
+ std::vector<u8> Serialize() const;
+
+private:
+ VirtualFile file;
+ std::unique_ptr<CNMTHeader> header;
+ std::unique_ptr<OptionalHeader> opt_header;
+ std::vector<ContentRecord> content_records;
+ std::vector<MetaRecord> meta_records;
+
+ // TODO(DarkLordZach): According to switchbrew, for Patch-type there is additional data
+ // after the table. This is not documented, unfortunately.
+};
+
+} // namespace FileSys