2017-07-05 15:39:41 +00:00
|
|
|
#include "AciHeader.h"
|
|
|
|
|
2017-07-06 11:17:21 +00:00
|
|
|
using namespace nx;
|
|
|
|
|
2017-07-05 15:39:41 +00:00
|
|
|
void AciHeader::clearVariables()
|
|
|
|
{
|
|
|
|
mType = TYPE_ACI0;
|
|
|
|
mProgramId = 0;
|
|
|
|
mFac.offset = 0;
|
|
|
|
mFac.size = 0;
|
|
|
|
mSac.offset = 0;
|
|
|
|
mSac.size = 0;
|
|
|
|
mKc.offset = 0;
|
|
|
|
mKc.size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::calculateSectionOffsets()
|
|
|
|
{
|
|
|
|
mFac.offset = align(sizeof(sAciHeader), kAciAlignSize);
|
|
|
|
mSac.offset = mFac.offset + align(mFac.size, kAciAlignSize);
|
|
|
|
mKc.offset = mSac.offset + align(mSac.size, kAciAlignSize);
|
|
|
|
}
|
|
|
|
|
2017-07-06 10:56:52 +00:00
|
|
|
bool AciHeader::isEqual(const AciHeader & other) const
|
|
|
|
{
|
|
|
|
return (mType == other.mType) \
|
|
|
|
&& (mProgramId == other.mProgramId) \
|
2017-07-06 23:56:49 +00:00
|
|
|
&& (mFac == other.mFac) \
|
|
|
|
&& (mSac == other.mSac) \
|
|
|
|
&& (mKc == other.mKc);
|
2017-07-06 10:56:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::copyFrom(const AciHeader & other)
|
|
|
|
{
|
|
|
|
if (other.getSize())
|
|
|
|
{
|
|
|
|
importBinary(other.getBytes(), other.getSize());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mType = other.mType;
|
|
|
|
mProgramId = other.mProgramId;
|
2017-07-06 23:56:49 +00:00
|
|
|
mFac = other.mFac;
|
|
|
|
mSac = other.mSac;
|
|
|
|
mKc = other.mKc;
|
2017-07-06 10:56:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-06 03:30:27 +00:00
|
|
|
AciHeader::AciHeader()
|
|
|
|
{
|
|
|
|
clearVariables();
|
|
|
|
}
|
|
|
|
|
|
|
|
AciHeader::AciHeader(const AciHeader & other)
|
|
|
|
{
|
|
|
|
importBinary(other.getBytes(), other.getSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
AciHeader::AciHeader(const u8 * bytes)
|
|
|
|
{
|
|
|
|
importBinary(bytes);
|
|
|
|
}
|
|
|
|
|
2017-07-06 10:56:52 +00:00
|
|
|
bool AciHeader::operator==(const AciHeader & other) const
|
|
|
|
{
|
|
|
|
return isEqual(other);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AciHeader::operator!=(const AciHeader & other) const
|
2017-07-06 03:30:27 +00:00
|
|
|
{
|
2017-07-06 10:56:52 +00:00
|
|
|
return !isEqual(other);
|
2017-07-06 03:30:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::operator=(const AciHeader & other)
|
|
|
|
{
|
|
|
|
this->importBinary(other.getBytes(), other.getSize());
|
|
|
|
}
|
|
|
|
|
2017-07-05 15:39:41 +00:00
|
|
|
const u8 * AciHeader::getBytes() const
|
|
|
|
{
|
2017-07-06 03:30:27 +00:00
|
|
|
return mBinaryBlob.getBytes();
|
2017-07-05 15:39:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t AciHeader::getSize() const
|
|
|
|
{
|
2017-07-06 03:30:27 +00:00
|
|
|
return mBinaryBlob.getSize();
|
2017-07-05 15:39:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::exportBinary()
|
|
|
|
{
|
|
|
|
mBinaryBlob.alloc(sizeof(sAciHeader));
|
2017-07-06 03:30:27 +00:00
|
|
|
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
2017-07-05 15:39:41 +00:00
|
|
|
|
|
|
|
// set type
|
|
|
|
switch (mType)
|
|
|
|
{
|
|
|
|
case (TYPE_ACI0):
|
|
|
|
hdr->set_signature(kAciStructSig.c_str());
|
|
|
|
break;
|
|
|
|
case (TYPE_ACID):
|
|
|
|
hdr->set_signature(kAciDescStructSig.c_str());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw fnd::Exception(kModuleName, "Unexpected ACI type");
|
|
|
|
}
|
|
|
|
|
|
|
|
// set program
|
|
|
|
hdr->set_program_id(mProgramId);
|
|
|
|
|
|
|
|
// set offset/size
|
|
|
|
calculateSectionOffsets();
|
|
|
|
hdr->fac().set_offset(mFac.offset);
|
|
|
|
hdr->fac().set_size(mFac.size);
|
|
|
|
hdr->sac().set_offset(mSac.offset);
|
|
|
|
hdr->sac().set_size(mSac.size);
|
|
|
|
hdr->kc().set_offset(mKc.offset);
|
|
|
|
hdr->kc().set_size(mKc.size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::importBinary(const u8 * bytes)
|
|
|
|
{
|
|
|
|
clearVariables();
|
|
|
|
|
|
|
|
mBinaryBlob.alloc(sizeof(sAciHeader));
|
2017-07-06 03:30:27 +00:00
|
|
|
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader));
|
2017-07-05 15:39:41 +00:00
|
|
|
|
2017-07-06 03:30:27 +00:00
|
|
|
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
2017-07-05 15:39:41 +00:00
|
|
|
|
|
|
|
if (memcmp(hdr->signature(), kAciStructSig.c_str(), 4) == 0)
|
|
|
|
{
|
|
|
|
mType = TYPE_ACI0;
|
|
|
|
}
|
|
|
|
else if (memcmp(hdr->signature(), kAciDescStructSig.c_str(), 4) == 0)
|
|
|
|
{
|
|
|
|
mType = TYPE_ACID;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "ACI header corrupt");
|
|
|
|
}
|
|
|
|
|
|
|
|
mProgramId = hdr->program_id();
|
|
|
|
mFac.offset = hdr->fac().offset();
|
|
|
|
mFac.size = hdr->fac().size();
|
|
|
|
mSac.offset = hdr->sac().offset();
|
|
|
|
mSac.size = hdr->sac().size();
|
|
|
|
mKc.offset = hdr->kc().offset();
|
|
|
|
mKc.size = hdr->kc().size();
|
|
|
|
}
|
|
|
|
|
2017-07-06 03:30:27 +00:00
|
|
|
void AciHeader::importBinary(const u8 * bytes, size_t len)
|
|
|
|
{
|
|
|
|
if (len < sizeof(sAciHeader))
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "ACI header too small");
|
|
|
|
}
|
|
|
|
importBinary(bytes);
|
|
|
|
}
|
|
|
|
|
2017-07-05 15:39:41 +00:00
|
|
|
AciHeader::AciType AciHeader::getAciType() const
|
|
|
|
{
|
|
|
|
return mType;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::setAciType(AciType type)
|
|
|
|
{
|
|
|
|
mType = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
u64 AciHeader::getProgramId() const
|
|
|
|
{
|
|
|
|
return mProgramId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::setProgramId(u64 program_id)
|
|
|
|
{
|
|
|
|
mProgramId = program_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
const AciHeader::sSection & AciHeader::getFileAccessControl() const
|
|
|
|
{
|
|
|
|
return mFac;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::setFileAccessControl(u32 size)
|
|
|
|
{
|
|
|
|
mFac.size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
const AciHeader::sSection & AciHeader::getServiceAccessControl() const
|
|
|
|
{
|
|
|
|
return mSac;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::setServiceAccessControl(u32 size)
|
|
|
|
{
|
|
|
|
mSac.size = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
const AciHeader::sSection & AciHeader::getKernelCapabilities() const
|
|
|
|
{
|
|
|
|
return mKc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AciHeader::setKernelCapabilities(u32 size)
|
|
|
|
{
|
|
|
|
mKc.size = size;
|
|
|
|
}
|