nca_metadata.h 2.9 KB

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