nca_metadata.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <vector>
  6. #include "common/common_funcs.h"
  7. #include "common/common_types.h"
  8. #include "common/swap.h"
  9. #include "core/file_sys/vfs/vfs_types.h"
  10. namespace FileSys {
  11. class CNMT;
  12. struct CNMTHeader;
  13. struct OptionalHeader;
  14. enum class TitleType : u8 {
  15. SystemProgram = 0x01,
  16. SystemDataArchive = 0x02,
  17. SystemUpdate = 0x03,
  18. FirmwarePackageA = 0x04,
  19. FirmwarePackageB = 0x05,
  20. Application = 0x80,
  21. Update = 0x81,
  22. AOC = 0x82,
  23. DeltaTitle = 0x83,
  24. };
  25. enum class ContentRecordType : u8 {
  26. Meta = 0,
  27. Program = 1,
  28. Data = 2,
  29. Control = 3,
  30. HtmlDocument = 4,
  31. LegalInformation = 5,
  32. DeltaFragment = 6,
  33. };
  34. struct ContentRecord {
  35. std::array<u8, 0x20> hash;
  36. std::array<u8, 0x10> nca_id;
  37. std::array<u8, 0x6> size;
  38. ContentRecordType type;
  39. INSERT_PADDING_BYTES(1);
  40. };
  41. static_assert(sizeof(ContentRecord) == 0x38, "ContentRecord has incorrect size.");
  42. constexpr ContentRecord EMPTY_META_CONTENT_RECORD{{}, {}, {}, ContentRecordType::Meta, {}};
  43. struct MetaRecord {
  44. u64_le title_id;
  45. u32_le title_version;
  46. TitleType type;
  47. u8 install_byte;
  48. INSERT_PADDING_BYTES(2);
  49. };
  50. static_assert(sizeof(MetaRecord) == 0x10, "MetaRecord has incorrect size.");
  51. struct OptionalHeader {
  52. u64_le title_id;
  53. u64_le minimum_version;
  54. };
  55. static_assert(sizeof(OptionalHeader) == 0x10, "OptionalHeader has incorrect size.");
  56. struct CNMTHeader {
  57. u64_le title_id;
  58. u32_le title_version;
  59. TitleType type;
  60. u8 reserved;
  61. u16_le table_offset;
  62. u16_le number_content_entries;
  63. u16_le number_meta_entries;
  64. u8 attributes;
  65. std::array<u8, 2> reserved2;
  66. u8 is_committed;
  67. u32_le required_download_system_version;
  68. std::array<u8, 4> reserved3;
  69. };
  70. static_assert(sizeof(CNMTHeader) == 0x20, "CNMTHeader has incorrect size.");
  71. // A class representing the format used by NCA metadata files, typically named {}.cnmt.nca or
  72. // meta0.ncd. These describe which NCA's belong with which titles in the registered cache.
  73. class CNMT {
  74. public:
  75. explicit CNMT(VirtualFile file);
  76. CNMT(CNMTHeader header_, OptionalHeader opt_header_,
  77. std::vector<ContentRecord> content_records_, std::vector<MetaRecord> meta_records_);
  78. ~CNMT();
  79. const CNMTHeader& GetHeader() const;
  80. u64 GetTitleID() const;
  81. u32 GetTitleVersion() const;
  82. TitleType GetType() const;
  83. const std::vector<ContentRecord>& GetContentRecords() const;
  84. const std::vector<MetaRecord>& GetMetaRecords() const;
  85. bool UnionRecords(const CNMT& other);
  86. std::vector<u8> Serialize() const;
  87. private:
  88. CNMTHeader header;
  89. OptionalHeader opt_header;
  90. std::vector<ContentRecord> content_records;
  91. std::vector<MetaRecord> meta_records;
  92. // TODO(DarkLordZach): According to switchbrew, for Patch-type there is additional data
  93. // after the table. This is not documented, unfortunately.
  94. };
  95. } // namespace FileSys