2018-05-12 09:36:50 +00:00
|
|
|
#pragma once
|
|
|
|
#include <string>
|
2018-08-07 09:31:06 +00:00
|
|
|
#include <cstring>
|
2018-06-24 08:18:54 +00:00
|
|
|
#include <fnd/ISerialisable.h>
|
2018-05-12 09:36:50 +00:00
|
|
|
#include <fnd/List.h>
|
2018-08-07 07:17:51 +00:00
|
|
|
#include <nn/hac/cnmt.h>
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
namespace nn
|
|
|
|
{
|
|
|
|
namespace hac
|
2018-05-12 09:36:50 +00:00
|
|
|
{
|
|
|
|
class ContentMetaBinary :
|
2018-06-24 08:18:54 +00:00
|
|
|
public fnd::ISerialisable
|
2018-05-12 09:36:50 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct ContentInfo
|
|
|
|
{
|
2018-08-07 08:35:03 +00:00
|
|
|
fnd::sha::sSha256Hash hash;
|
2018-05-12 15:02:53 +00:00
|
|
|
byte_t nca_id[cnmt::kContentIdLen];
|
2018-05-12 09:36:50 +00:00
|
|
|
size_t size;
|
2018-05-12 15:02:53 +00:00
|
|
|
cnmt::ContentType type;
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const ContentInfo& other)
|
2018-05-12 09:36:50 +00:00
|
|
|
{
|
|
|
|
hash = other.hash;
|
2018-05-12 15:02:53 +00:00
|
|
|
memcpy(nca_id, other.nca_id, cnmt::kContentIdLen);
|
2018-05-12 09:36:50 +00:00
|
|
|
size = other.size;
|
|
|
|
type = other.type;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const ContentInfo& other) const
|
|
|
|
{
|
|
|
|
return (hash == other.hash) \
|
2018-05-12 15:02:53 +00:00
|
|
|
&& (memcmp(nca_id, other.nca_id, cnmt::kContentIdLen) == 0) \
|
2018-05-12 09:36:50 +00:00
|
|
|
&& (size == other.size) \
|
|
|
|
&& (type == other.type);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const ContentInfo& other) const
|
|
|
|
{
|
|
|
|
return !operator==(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ContentMetaInfo
|
|
|
|
{
|
|
|
|
uint64_t id;
|
|
|
|
uint32_t version;
|
2018-05-12 15:02:53 +00:00
|
|
|
cnmt::ContentMetaType type;
|
2018-05-12 09:36:50 +00:00
|
|
|
byte_t attributes;
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const ContentMetaInfo& other)
|
2018-05-12 09:36:50 +00:00
|
|
|
{
|
|
|
|
id = other.id;
|
|
|
|
version = other.version;
|
|
|
|
type = other.type;
|
|
|
|
attributes = other.attributes;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const ContentMetaInfo& other) const
|
|
|
|
{
|
|
|
|
return (id == other.id) \
|
|
|
|
&& (version == other.version) \
|
|
|
|
&& (type == other.type) \
|
|
|
|
&& (attributes == other.attributes);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const ContentMetaInfo& other) const
|
|
|
|
{
|
|
|
|
return !operator==(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-05-12 15:02:53 +00:00
|
|
|
struct ApplicationMetaExtendedHeader
|
|
|
|
{
|
|
|
|
uint64_t patch_id;
|
|
|
|
uint32_t required_system_version;
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const ApplicationMetaExtendedHeader& other)
|
2018-05-12 15:02:53 +00:00
|
|
|
{
|
|
|
|
patch_id = other.patch_id;
|
|
|
|
required_system_version = other.required_system_version;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const ApplicationMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return (patch_id == other.patch_id) \
|
|
|
|
&& (required_system_version == other.required_system_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const ApplicationMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return !operator==(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PatchMetaExtendedHeader
|
|
|
|
{
|
|
|
|
uint64_t application_id;
|
|
|
|
uint32_t required_system_version;
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const PatchMetaExtendedHeader& other)
|
2018-05-12 15:02:53 +00:00
|
|
|
{
|
|
|
|
application_id = other.application_id;
|
|
|
|
required_system_version = other.required_system_version;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const PatchMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return (application_id == other.application_id) \
|
|
|
|
&& (required_system_version == other.required_system_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const PatchMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return !operator==(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AddOnContentMetaExtendedHeader
|
|
|
|
{
|
|
|
|
uint64_t application_id;
|
|
|
|
uint32_t required_system_version;
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const AddOnContentMetaExtendedHeader& other)
|
2018-05-12 15:02:53 +00:00
|
|
|
{
|
|
|
|
application_id = other.application_id;
|
|
|
|
required_system_version = other.required_system_version;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const AddOnContentMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return (application_id == other.application_id) \
|
|
|
|
&& (required_system_version == other.required_system_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const AddOnContentMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return !operator==(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DeltaMetaExtendedHeader
|
|
|
|
{
|
|
|
|
uint64_t application_id;
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const DeltaMetaExtendedHeader& other)
|
2018-05-12 15:02:53 +00:00
|
|
|
{
|
|
|
|
application_id = other.application_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const DeltaMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return (application_id == other.application_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const DeltaMetaExtendedHeader& other) const
|
|
|
|
{
|
|
|
|
return !operator==(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-05-12 09:36:50 +00:00
|
|
|
ContentMetaBinary();
|
|
|
|
ContentMetaBinary(const ContentMetaBinary& other);
|
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
void operator=(const ContentMetaBinary& other);
|
|
|
|
bool operator==(const ContentMetaBinary& other) const;
|
|
|
|
bool operator!=(const ContentMetaBinary& other) const;
|
2018-05-12 09:36:50 +00:00
|
|
|
|
|
|
|
// export/import binary
|
2018-06-24 08:18:54 +00:00
|
|
|
void toBytes();
|
|
|
|
void fromBytes(const byte_t* bytes, size_t len);
|
|
|
|
const fnd::Vec<byte_t>& getBytes() const;
|
2018-05-12 09:36:50 +00:00
|
|
|
|
|
|
|
// variables
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
uint64_t getTitleId() const;
|
|
|
|
void setTitleId(uint64_t title_id);
|
|
|
|
|
|
|
|
uint32_t getTitleVersion() const;
|
|
|
|
void setTitleVersion(uint32_t version);
|
|
|
|
|
2018-05-12 15:02:53 +00:00
|
|
|
cnmt::ContentMetaType getType() const;
|
|
|
|
void setType(cnmt::ContentMetaType type);
|
2018-05-12 09:36:50 +00:00
|
|
|
|
|
|
|
byte_t getAttributes() const;
|
|
|
|
void setAttributes(byte_t attributes);
|
|
|
|
|
2018-05-12 15:02:53 +00:00
|
|
|
uint32_t getRequiredDownloadSystemVersion() const;
|
|
|
|
void setRequiredDownloadSystemVersion(uint32_t version);
|
|
|
|
|
|
|
|
const ApplicationMetaExtendedHeader& getApplicationMetaExtendedHeader() const;
|
|
|
|
void setApplicationMetaExtendedHeader(const ApplicationMetaExtendedHeader& exhdr);
|
|
|
|
|
|
|
|
const PatchMetaExtendedHeader& getPatchMetaExtendedHeader() const;
|
|
|
|
void setPatchMetaExtendedHeader(const PatchMetaExtendedHeader& exhdr);
|
|
|
|
|
|
|
|
const AddOnContentMetaExtendedHeader& getAddOnContentMetaExtendedHeader() const;
|
|
|
|
void setAddOnContentMetaExtendedHeader(const AddOnContentMetaExtendedHeader& exhdr);
|
|
|
|
|
|
|
|
const DeltaMetaExtendedHeader& getDeltaMetaExtendedHeader() const;
|
|
|
|
void setDeltaMetaExtendedHeader(const DeltaMetaExtendedHeader& exhdr);
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const fnd::List<nn::hac::ContentMetaBinary::ContentInfo>& getContentInfo() const;
|
|
|
|
void setContentInfo(const fnd::List<nn::hac::ContentMetaBinary::ContentInfo>& info);
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const fnd::List<nn::hac::ContentMetaBinary::ContentMetaInfo>& getContentMetaInfo() const;
|
|
|
|
void setContentMetaInfo(const fnd::List<nn::hac::ContentMetaBinary::ContentMetaInfo>& info);
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-06-24 08:18:54 +00:00
|
|
|
const fnd::Vec<byte_t>& getExtendedData() const;
|
|
|
|
void setExtendedData(const fnd::Vec<byte_t>& data);
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
const nn::hac::sDigest& getDigest() const;
|
|
|
|
void setDigest(const nn::hac::sDigest& digest);
|
2018-05-12 09:36:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
const std::string kModuleName = "CONTENT_META_BINARY";
|
|
|
|
|
|
|
|
// binary blob
|
2018-06-24 08:18:54 +00:00
|
|
|
fnd::Vec<byte_t> mRawBinary;
|
2018-05-12 09:36:50 +00:00
|
|
|
|
|
|
|
// variables
|
|
|
|
uint64_t mTitleId;
|
|
|
|
uint32_t mTitleVersion;
|
2018-05-12 15:02:53 +00:00
|
|
|
cnmt::ContentMetaType mType;
|
2018-05-12 09:36:50 +00:00
|
|
|
byte_t mAttributes;
|
2018-05-12 15:02:53 +00:00
|
|
|
uint32_t mRequiredDownloadSystemVersion;
|
2018-06-24 08:18:54 +00:00
|
|
|
fnd::Vec<byte_t> mExtendedHeader;
|
2018-05-12 15:02:53 +00:00
|
|
|
|
|
|
|
ApplicationMetaExtendedHeader mApplicationMetaExtendedHeader;
|
|
|
|
PatchMetaExtendedHeader mPatchMetaExtendedHeader;
|
|
|
|
AddOnContentMetaExtendedHeader mAddOnContentMetaExtendedHeader;
|
|
|
|
DeltaMetaExtendedHeader mDeltaMetaExtendedHeader;
|
|
|
|
|
2018-08-07 07:17:51 +00:00
|
|
|
fnd::List<nn::hac::ContentMetaBinary::ContentInfo> mContentInfo;
|
|
|
|
fnd::List<nn::hac::ContentMetaBinary::ContentMetaInfo> mContentMetaInfo;
|
2018-06-24 08:18:54 +00:00
|
|
|
fnd::Vec<byte_t> mExtendedData;
|
2018-08-07 07:17:51 +00:00
|
|
|
nn::hac::sDigest mDigest;
|
2018-05-12 09:36:50 +00:00
|
|
|
|
|
|
|
inline size_t getExtendedHeaderOffset() const { return sizeof(sContentMetaHeader); }
|
|
|
|
inline size_t getContentInfoOffset(size_t exhdrSize) const { return getExtendedHeaderOffset() + exhdrSize; }
|
|
|
|
inline size_t getContentMetaInfoOffset(size_t exhdrSize, size_t contentInfoNum) const { return getContentInfoOffset(exhdrSize) + contentInfoNum * sizeof(sContentInfo); }
|
|
|
|
inline size_t getExtendedDataOffset(size_t exhdrSize, size_t contentInfoNum, size_t contentMetaNum) const { return getContentMetaInfoOffset(exhdrSize, contentInfoNum) + contentMetaNum * sizeof(sContentMetaInfo); }
|
|
|
|
inline size_t getDigestOffset(size_t exhdrSize, size_t contentInfoNum, size_t contentMetaNum, size_t exdataSize) const { return getExtendedDataOffset(exhdrSize, contentInfoNum, contentMetaNum) + exdataSize; }
|
2018-05-12 15:02:53 +00:00
|
|
|
inline size_t getTotalSize(size_t exhdrSize, size_t contentInfoNum, size_t contentMetaNum, size_t exdataSize) const { return getDigestOffset(exhdrSize, contentInfoNum, contentMetaNum, exdataSize) + cnmt::kDigestLen; }
|
2018-05-12 09:36:50 +00:00
|
|
|
|
2018-05-12 15:02:53 +00:00
|
|
|
bool validateExtendedHeaderSize(cnmt::ContentMetaType type, size_t exhdrSize) const;
|
|
|
|
size_t getExtendedDataSize(cnmt::ContentMetaType type, const byte_t* data) const;
|
|
|
|
void validateBinary(const byte_t* bytes, size_t len) const;
|
2018-05-12 09:36:50 +00:00
|
|
|
};
|
2018-08-07 07:17:51 +00:00
|
|
|
}
|
2018-05-12 09:36:50 +00:00
|
|
|
}
|