96463d0a55
Avoids the need to rebuild whatever includes the romfs factory header if the loader header ever changes. We also don't need to include the main core header. We can instead include the headers we specifically need.
113 lines
2.9 KiB
C++
113 lines
2.9 KiB
C++
// Copyright 2018 yuzu emulator team
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include "common/common_funcs.h"
|
|
#include "common/common_types.h"
|
|
#include "common/swap.h"
|
|
#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,
|
|
};
|
|
|
|
bool operator>=(TitleType lhs, TitleType rhs);
|
|
bool operator<=(TitleType lhs, TitleType rhs);
|
|
|
|
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:
|
|
CNMTHeader header;
|
|
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
|