mirror of
https://github.com/jakcron/nstool.git
synced 2024-12-22 18:55:29 +00:00
[nx] Add ContentMetaBinary
This commit is contained in:
parent
480a6225cc
commit
a02ba43292
149
lib/libnx/include/nx/ContentMetaBinary.h
Normal file
149
lib/libnx/include/nx/ContentMetaBinary.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/MemoryBlob.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nx/cmnt.h>
|
||||
|
||||
|
||||
namespace nx
|
||||
{
|
||||
class ContentMetaBinary :
|
||||
public fnd::ISerialiseableBinary
|
||||
{
|
||||
public:
|
||||
struct ContentInfo
|
||||
{
|
||||
crypto::sha::sSha256Hash hash;
|
||||
byte_t nca_id[cmnt::kContentIdLen];
|
||||
size_t size;
|
||||
cmnt::ContentType type;
|
||||
|
||||
ContentInfo& operator=(const ContentInfo& other)
|
||||
{
|
||||
hash = other.hash;
|
||||
memcpy(nca_id, other.nca_id, cmnt::kContentIdLen);
|
||||
size = other.size;
|
||||
type = other.type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const ContentInfo& other) const
|
||||
{
|
||||
return (hash == other.hash) \
|
||||
&& (memcmp(nca_id, other.nca_id, cmnt::kContentIdLen) == 0) \
|
||||
&& (size == other.size) \
|
||||
&& (type == other.type);
|
||||
}
|
||||
|
||||
bool operator!=(const ContentInfo& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct ContentMetaInfo
|
||||
{
|
||||
uint64_t id;
|
||||
uint32_t version;
|
||||
cmnt::ContentMetaType type;
|
||||
byte_t attributes;
|
||||
|
||||
ContentMetaInfo& operator=(const ContentMetaInfo& other)
|
||||
{
|
||||
id = other.id;
|
||||
version = other.version;
|
||||
type = other.type;
|
||||
attributes = other.attributes;
|
||||
return *this;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
ContentMetaBinary();
|
||||
ContentMetaBinary(const ContentMetaBinary& other);
|
||||
ContentMetaBinary(const byte_t* bytes, size_t len);
|
||||
|
||||
// to be used after export
|
||||
const byte_t* getBytes() const;
|
||||
size_t getSize() const;
|
||||
|
||||
// export/import binary
|
||||
void exportBinary();
|
||||
void importBinary(const byte_t* bytes, size_t len);
|
||||
|
||||
// variables
|
||||
void clear();
|
||||
|
||||
uint64_t getTitleId() const;
|
||||
void setTitleId(uint64_t title_id);
|
||||
|
||||
uint32_t getTitleVersion() const;
|
||||
void setTitleVersion(uint32_t version);
|
||||
|
||||
cmnt::ContentMetaType getType() const;
|
||||
void setType(cmnt::ContentMetaType type);
|
||||
|
||||
byte_t getAttributes() const;
|
||||
void setAttributes(byte_t attributes);
|
||||
|
||||
uint32_t getRequiredSystemVersion() const;
|
||||
void setRequiredSystemVersion(uint32_t version);
|
||||
|
||||
const fnd::List<nx::ContentMetaBinary::ContentInfo>& getContentInfo() const;
|
||||
void setContentInfo(const fnd::List<nx::ContentMetaBinary::ContentInfo>& info);
|
||||
|
||||
const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& getContentMetaInfo() const;
|
||||
void setContentMetaInfo(const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& info);
|
||||
|
||||
const fnd::MemoryBlob& getExtendedData() const;
|
||||
void setExtendedData(const fnd::MemoryBlob& data);
|
||||
|
||||
const nx::sDigest& getDigest() const;
|
||||
void setDigest(const nx::sDigest& digest);
|
||||
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "CONTENT_META_BINARY";
|
||||
|
||||
// binary blob
|
||||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// variables
|
||||
uint64_t mTitleId;
|
||||
uint32_t mTitleVersion;
|
||||
cmnt::ContentMetaType mType;
|
||||
byte_t mAttributes;
|
||||
uint32_t mRequiredSystemVersion;
|
||||
fnd::MemoryBlob mExtendedHeader;
|
||||
fnd::List<nx::ContentMetaBinary::ContentInfo> mContentInfo;
|
||||
fnd::List<nx::ContentMetaBinary::ContentMetaInfo> mContentMetaInfo;
|
||||
fnd::MemoryBlob mExtendedData;
|
||||
nx::sDigest mDigest;
|
||||
|
||||
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; }
|
||||
inline size_t getTotalSize(size_t exhdrSize, size_t contentInfoNum, size_t contentMetaNum, size_t exdataSize) const { return getDigestOffset(exhdrSize, contentInfoNum, contentMetaNum, exdataSize) + cmnt::kDigestLen; }
|
||||
|
||||
bool validateExtendedHeaderSize(cmnt::ContentMetaType type, size_t exhdrSize);
|
||||
size_t getExtendedDataSize(cmnt::ContentMetaType type, const byte_t* data);
|
||||
void validateBinary(const byte_t* bytes, size_t len);
|
||||
|
||||
bool isEqual(const ContentMetaBinary& other) const;
|
||||
void copyFrom(const ContentMetaBinary& other);
|
||||
};
|
||||
}
|
139
lib/libnx/include/nx/cmnt.h
Normal file
139
lib/libnx/include/nx/cmnt.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/types.h>
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <fnd/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
namespace cmnt
|
||||
{
|
||||
enum ContentType
|
||||
{
|
||||
TYPE_META = 0,
|
||||
TYPE_PROGRAM,
|
||||
TYPE_DATA,
|
||||
TYPE_CONTROL,
|
||||
TYPE_HTML_DOCUMENT,
|
||||
TYPE_LEGAL_INFORMATION,
|
||||
TYPE_DELTA_FRAGMENT
|
||||
};
|
||||
|
||||
enum ContentMetaType
|
||||
{
|
||||
METATYPE_SYSTEM_PROGRAM = 1,
|
||||
METATYPE_SYSTEM_DATA,
|
||||
METATYPE_SYSTEM_UPDATE,
|
||||
METATYPE_BOOT_IMAGE_PACKAGE,
|
||||
METATYPE_BOOT_IMAGE_PACKAGE_SAFE,
|
||||
|
||||
METATYPE_APPLICATION = 0x80,
|
||||
METATYPE_PATCH, // can have extended data
|
||||
METATYPE_ADD_ON_CONTENT,
|
||||
METATYPE_DELTA // can have extended data
|
||||
};
|
||||
|
||||
enum UpdateType
|
||||
{
|
||||
UPDATETYPE_APPLY_AS_DELTA,
|
||||
UPDATETYPE_OVERWRITE,
|
||||
UPDATETYPE_CREATE
|
||||
};
|
||||
|
||||
enum ContentMetaAttribute
|
||||
{
|
||||
ATTRIBUTE_NONE,
|
||||
ATTRIBUTE_INCLUDES_EX_FAT_DRIVER,
|
||||
ATTRIBUTE_REBOOTLESS
|
||||
};
|
||||
|
||||
static const uint32_t kRequiredSystemVersion = 335544320;
|
||||
static const uint32_t kDefaultVersion = 335545344;
|
||||
static const size_t kContentIdLen = 0x10;
|
||||
static const size_t kDigestLen = 0x20;
|
||||
}
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
/*
|
||||
struct sContentMeta
|
||||
{
|
||||
sContentMetaHeader hdr;
|
||||
byte_t exhdr[]; // optional
|
||||
sContentInfo info[];
|
||||
sContentMetaInfo meta[];
|
||||
byte_t extdata[];
|
||||
byte_t digest[32]
|
||||
};
|
||||
*/
|
||||
|
||||
struct sContentMetaHeader
|
||||
{
|
||||
le_uint64_t id;
|
||||
le_uint32_t version;
|
||||
byte_t type;
|
||||
byte_t reserved_0;
|
||||
le_uint16_t exhdr_size;
|
||||
le_uint16_t content_count;
|
||||
le_uint16_t content_meta_count;
|
||||
byte_t attributes;
|
||||
byte_t reserved_1[3];
|
||||
le_uint32_t required_system_version;
|
||||
byte_t reserved_2[4];
|
||||
};
|
||||
|
||||
struct sContentInfo
|
||||
{
|
||||
crypto::sha::sSha256Hash content_hash;
|
||||
byte_t content_id[cmnt::kContentIdLen];
|
||||
le_uint32_t size_lower;
|
||||
le_uint16_t size_higher;
|
||||
byte_t content_type;
|
||||
byte_t id_offset;
|
||||
};
|
||||
|
||||
struct sContentMetaInfo
|
||||
{
|
||||
le_uint64_t id;
|
||||
le_uint32_t version;
|
||||
byte_t type;
|
||||
byte_t attributes;
|
||||
byte_t reserved[2];
|
||||
};
|
||||
|
||||
struct sApplicationMetaExtendedHeader
|
||||
{
|
||||
le_uint64_t id;
|
||||
le_uint32_t required_system_version;
|
||||
byte_t reserved[4];
|
||||
};
|
||||
|
||||
struct sPatchMetaExtendedHeader
|
||||
{
|
||||
le_uint64_t id;
|
||||
le_uint32_t required_system_version;
|
||||
le_uint32_t extended_data_size;
|
||||
byte_t reserved[8];
|
||||
};
|
||||
|
||||
struct sAddOnContentMetaExtendedHeader
|
||||
{
|
||||
le_uint64_t id;
|
||||
le_uint32_t required_system_version;
|
||||
byte_t reserved[4];
|
||||
};
|
||||
|
||||
struct sDeltaMetaExtendedHeader
|
||||
{
|
||||
le_uint64_t id;
|
||||
le_uint32_t extended_data_size;
|
||||
byte_t reserved[4];
|
||||
};
|
||||
|
||||
struct sDigest
|
||||
{
|
||||
byte_t data[cmnt::kDigestLen];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
|
@ -24,6 +24,8 @@
|
|||
<ClInclude Include="include\nx\AcidBinary.h" />
|
||||
<ClInclude Include="include\nx\AciHeader.h" />
|
||||
<ClInclude Include="include\nx\AesKeygen.h" />
|
||||
<ClInclude Include="include\nx\cmnt.h" />
|
||||
<ClInclude Include="include\nx\ContentMetaBinary.h" />
|
||||
<ClInclude Include="include\nx\FacBinary.h" />
|
||||
<ClInclude Include="include\nx\FacHeader.h" />
|
||||
<ClInclude Include="include\nx\HandleTableSizeEntry.h" />
|
||||
|
@ -68,6 +70,7 @@
|
|||
<ClCompile Include="source\AcidBinary.cpp" />
|
||||
<ClCompile Include="source\AciHeader.cpp" />
|
||||
<ClCompile Include="source\AesKeygen.cpp" />
|
||||
<ClCompile Include="source\ContentMetaBinary.cpp" />
|
||||
<ClCompile Include="source\FacBinary.cpp" />
|
||||
<ClCompile Include="source\FacHeader.cpp" />
|
||||
<ClCompile Include="source\HandleTableSizeEntry.cpp" />
|
||||
|
|
|
@ -144,6 +144,12 @@
|
|||
<ClInclude Include="include\nx\hierarchicalsha256.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\nx\ContentMetaBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\nx\cmnt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="source\AciBinary.cpp">
|
||||
|
@ -245,6 +251,9 @@
|
|||
<ClCompile Include="source\XciUtils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\ContentMetaBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="makefile" />
|
||||
|
|
300
lib/libnx/source/ContentMetaBinary.cpp
Normal file
300
lib/libnx/source/ContentMetaBinary.cpp
Normal file
|
@ -0,0 +1,300 @@
|
|||
#include <nx/ContentMetaBinary.h>
|
||||
|
||||
nx::ContentMetaBinary::ContentMetaBinary()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
nx::ContentMetaBinary::ContentMetaBinary(const ContentMetaBinary & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
nx::ContentMetaBinary::ContentMetaBinary(const byte_t * bytes, size_t len)
|
||||
{
|
||||
importBinary(bytes, len);
|
||||
}
|
||||
|
||||
const byte_t * nx::ContentMetaBinary::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t nx::ContentMetaBinary::getSize() const
|
||||
{
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::exportBinary()
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len)
|
||||
{
|
||||
// clear member variables
|
||||
clear();
|
||||
|
||||
// validate layout
|
||||
validateBinary(bytes, len);
|
||||
|
||||
// get pointer to header structure
|
||||
const sContentMetaHeader* hdr = (const sContentMetaHeader*)bytes;
|
||||
|
||||
mTitleId = hdr->id.get();
|
||||
mTitleVersion = hdr->version.get();
|
||||
mType = (cmnt::ContentMetaType)hdr->type;
|
||||
mAttributes = hdr->attributes;
|
||||
mRequiredSystemVersion = hdr->required_system_version.get();
|
||||
size_t exdata_size = 0;
|
||||
|
||||
// save exheader
|
||||
if (hdr->exhdr_size.get() > 0)
|
||||
{
|
||||
mExtendedHeader.alloc(hdr->exhdr_size.get());
|
||||
memcpy(mExtendedHeader.getBytes(), bytes + getExtendedHeaderOffset(), hdr->exhdr_size.get());
|
||||
|
||||
exdata_size = getExtendedDataSize(mType, mExtendedHeader.getBytes());
|
||||
}
|
||||
|
||||
// save content info
|
||||
if (hdr->content_count.get() > 0)
|
||||
{
|
||||
const sContentInfo* info = (const sContentInfo*)(bytes + getContentInfoOffset(hdr->exhdr_size.get()));
|
||||
for (size_t i = 0; i < hdr->content_count.get(); i++)
|
||||
{
|
||||
mContentInfo[i].hash = info[i].content_hash;
|
||||
memcpy(mContentInfo[i].nca_id, info[i].content_id, cmnt::kContentIdLen);
|
||||
mContentInfo[i].size = (uint64_t)(info[i].size_lower.get()) | (uint64_t)(info[i].size_higher.get()) << 32;
|
||||
mContentInfo[i].type = (cmnt::ContentType)info[i].content_type;
|
||||
}
|
||||
}
|
||||
|
||||
// save content meta info
|
||||
if (hdr->content_meta_count.get() > 0)
|
||||
{
|
||||
const sContentMetaInfo* info = (const sContentMetaInfo*)(bytes + getContentMetaInfoOffset(hdr->exhdr_size.get(), hdr->content_count.get()));
|
||||
for (size_t i = 0; i < hdr->content_meta_count.get(); i++)
|
||||
{
|
||||
mContentMetaInfo[i].id = info[i].id.get();
|
||||
mContentMetaInfo[i].version = info[i].version.get();
|
||||
mContentMetaInfo[i].type = (cmnt::ContentMetaType)info[i].type;
|
||||
mContentMetaInfo[i].attributes = info[i].attributes;
|
||||
}
|
||||
}
|
||||
|
||||
// save exdata
|
||||
if (exdata_size > 0)
|
||||
{
|
||||
mExtendedData.alloc(exdata_size);
|
||||
memcpy(mExtendedData.getBytes(), bytes + getExtendedDataOffset(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get()), exdata_size);
|
||||
}
|
||||
|
||||
// save digest
|
||||
memcpy(mDigest.data, bytes + getDigestOffset(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), exdata_size), cmnt::kDigestLen);
|
||||
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::clear()
|
||||
{
|
||||
mBinaryBlob.clear();
|
||||
mTitleId = 0;
|
||||
mTitleVersion = 0;
|
||||
mType = cmnt::METATYPE_SYSTEM_PROGRAM;
|
||||
mAttributes = cmnt::ATTRIBUTE_NONE;
|
||||
mRequiredSystemVersion = 0;
|
||||
mExtendedHeader.clear();
|
||||
mContentInfo.clear();
|
||||
mContentMetaInfo.clear();
|
||||
mExtendedData.clear();
|
||||
memset(mDigest.data, 0, cmnt::kDigestLen);
|
||||
}
|
||||
|
||||
uint64_t nx::ContentMetaBinary::getTitleId() const
|
||||
{
|
||||
return mTitleId;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setTitleId(uint64_t title_id)
|
||||
{
|
||||
mTitleId = title_id;
|
||||
}
|
||||
|
||||
uint32_t nx::ContentMetaBinary::getTitleVersion() const
|
||||
{
|
||||
return mTitleVersion;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setTitleVersion(uint32_t version)
|
||||
{
|
||||
mTitleVersion = version;
|
||||
}
|
||||
|
||||
nx::cmnt::ContentMetaType nx::ContentMetaBinary::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setType(cmnt::ContentMetaType type)
|
||||
{
|
||||
mType = type;
|
||||
}
|
||||
|
||||
byte_t nx::ContentMetaBinary::getAttributes() const
|
||||
{
|
||||
return mAttributes;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setAttributes(byte_t attributes)
|
||||
{
|
||||
mAttributes = attributes;
|
||||
}
|
||||
|
||||
uint32_t nx::ContentMetaBinary::getRequiredSystemVersion() const
|
||||
{
|
||||
return mRequiredSystemVersion;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setRequiredSystemVersion(uint32_t version)
|
||||
{
|
||||
mRequiredSystemVersion = version;
|
||||
}
|
||||
|
||||
const fnd::List<nx::ContentMetaBinary::ContentInfo>& nx::ContentMetaBinary::getContentInfo() const
|
||||
{
|
||||
return mContentInfo;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setContentInfo(const fnd::List<nx::ContentMetaBinary::ContentInfo>& info)
|
||||
{
|
||||
mContentInfo = info;
|
||||
}
|
||||
|
||||
const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& nx::ContentMetaBinary::getContentMetaInfo() const
|
||||
{
|
||||
return mContentMetaInfo;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setContentMetaInfo(const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& info)
|
||||
{
|
||||
mContentMetaInfo = info;
|
||||
}
|
||||
|
||||
const fnd::MemoryBlob & nx::ContentMetaBinary::getExtendedData() const
|
||||
{
|
||||
return mExtendedData;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setExtendedData(const fnd::MemoryBlob & data)
|
||||
{
|
||||
mExtendedData = data;
|
||||
}
|
||||
|
||||
const nx::sDigest & nx::ContentMetaBinary::getDigest() const
|
||||
{
|
||||
return mDigest;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::setDigest(const nx::sDigest & digest)
|
||||
{
|
||||
|
||||
memcpy(mDigest.data, digest.data, cmnt::kDigestLen);
|
||||
}
|
||||
|
||||
bool nx::ContentMetaBinary::validateExtendedHeaderSize(cmnt::ContentMetaType type, size_t exhdrSize)
|
||||
{
|
||||
bool validSize = false;
|
||||
|
||||
if (type == cmnt::METATYPE_APPLICATION && exhdrSize == sizeof(sApplicationMetaExtendedHeader))
|
||||
validSize = true;
|
||||
else if (type == cmnt::METATYPE_PATCH && exhdrSize == sizeof(sPatchMetaExtendedHeader))
|
||||
validSize = true;
|
||||
else if (type == cmnt::METATYPE_ADD_ON_CONTENT && exhdrSize == sizeof(sAddOnContentMetaExtendedHeader))
|
||||
validSize = true;
|
||||
else if (type == cmnt::METATYPE_DELTA && exhdrSize == sizeof(sDeltaMetaExtendedHeader))
|
||||
validSize = true;
|
||||
|
||||
return validSize;
|
||||
}
|
||||
|
||||
size_t nx::ContentMetaBinary::getExtendedDataSize(cmnt::ContentMetaType type, const byte_t * data)
|
||||
{
|
||||
size_t exdata_len = 0;
|
||||
if (type == cmnt::METATYPE_PATCH)
|
||||
{
|
||||
const sPatchMetaExtendedHeader* exhdr = (const sPatchMetaExtendedHeader*)(data);
|
||||
exdata_len = exhdr->extended_data_size.get();
|
||||
}
|
||||
else if (type == cmnt::METATYPE_DELTA)
|
||||
{
|
||||
const sDeltaMetaExtendedHeader* exhdr = (const sDeltaMetaExtendedHeader*)(data);
|
||||
exdata_len = exhdr->extended_data_size.get();
|
||||
}
|
||||
return exdata_len;
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::validateBinary(const byte_t * bytes, size_t len)
|
||||
{
|
||||
// check if it is large enough to read the header
|
||||
if (len < sizeof(sContentMetaHeader))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Binary too small");
|
||||
}
|
||||
|
||||
// get pointer to header structure
|
||||
const sContentMetaHeader* hdr = (const sContentMetaHeader*)bytes;
|
||||
|
||||
// validate extended header size
|
||||
if (validateExtendedHeaderSize((cmnt::ContentMetaType)hdr->type, hdr->exhdr_size.get()) == false)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Invalid extended header size");
|
||||
}
|
||||
|
||||
// check binary size again for new minimum size
|
||||
if (len < getTotalSize(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), 0))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Binary too small");
|
||||
}
|
||||
|
||||
// check binary size again with extended data size
|
||||
if (len < getTotalSize(hdr->exhdr_size.get(), hdr->content_count.get(), hdr->content_meta_count.get(), getExtendedDataSize((cmnt::ContentMetaType)hdr->type, bytes + getExtendedHeaderOffset())))
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Binary too small");
|
||||
}
|
||||
}
|
||||
|
||||
bool nx::ContentMetaBinary::isEqual(const ContentMetaBinary & other) const
|
||||
{
|
||||
return (mTitleId == other.mTitleId) \
|
||||
&& (mTitleVersion == other.mTitleVersion) \
|
||||
&& (mType == other.mType) \
|
||||
&& (mAttributes == other.mAttributes) \
|
||||
&& (mRequiredSystemVersion == other.mRequiredSystemVersion) \
|
||||
&& (mExtendedHeader == other.mExtendedHeader) \
|
||||
&& (mContentInfo == other.mContentInfo) \
|
||||
&& (mContentMetaInfo == other.mContentMetaInfo) \
|
||||
&& (mExtendedData == other.mExtendedData) \
|
||||
&& (memcmp(mDigest.data, other.mDigest.data, cmnt::kDigestLen) == 0);
|
||||
}
|
||||
|
||||
void nx::ContentMetaBinary::copyFrom(const ContentMetaBinary & other)
|
||||
{
|
||||
if (other.getSize() > 0)
|
||||
{
|
||||
importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
clear();
|
||||
mTitleId = other.mTitleId;
|
||||
mTitleVersion = other.mTitleVersion;
|
||||
mType = other.mType;
|
||||
mAttributes = other.mAttributes;
|
||||
mRequiredSystemVersion = other.mRequiredSystemVersion;
|
||||
mExtendedHeader = other.mExtendedHeader;
|
||||
mContentInfo = other.mContentInfo;
|
||||
mContentMetaInfo = other.mContentMetaInfo;
|
||||
mExtendedData = other.mExtendedData;
|
||||
memcpy(mDigest.data, other.mDigest.data, cmnt::kDigestLen);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue