mirror of
https://github.com/jakcron/nstool
synced 2024-12-25 06:01:12 +00:00
[nx] Implemented NpdmBinary and associated child classes.
This commit is contained in:
parent
7dd27fd5c8
commit
99151507c6
24 changed files with 768 additions and 354 deletions
|
@ -3,7 +3,9 @@
|
|||
|
||||
|
||||
nx::AciBinary::AciBinary()
|
||||
{}
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
nx::AciBinary::AciBinary(const AciBinary & other)
|
||||
{
|
||||
|
|
|
@ -2,28 +2,17 @@
|
|||
|
||||
using namespace nx;
|
||||
|
||||
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);
|
||||
mFac.offset = align(mHeaderOffset, kAciAlignSize) + align(sizeof(sAciHeader), kAciAlignSize);
|
||||
mSac.offset = mFac.offset + align(mFac.size, kAciAlignSize);
|
||||
mKc.offset = mSac.offset + align(mSac.size, kAciAlignSize);
|
||||
}
|
||||
|
||||
bool AciHeader::isEqual(const AciHeader & other) const
|
||||
{
|
||||
return (mType == other.mType) \
|
||||
return (mHeaderOffset == other.mHeaderOffset) \
|
||||
&& (mType == other.mType) \
|
||||
&& (mAcidSize == other.mAcidSize) \
|
||||
&& (mProgramId == other.mProgramId) \
|
||||
&& (mFac == other.mFac) \
|
||||
|
@ -39,6 +28,7 @@ void AciHeader::copyFrom(const AciHeader & other)
|
|||
}
|
||||
else
|
||||
{
|
||||
mHeaderOffset = other.mHeaderOffset;
|
||||
mType = other.mType;
|
||||
mAcidSize = other.mAcidSize;
|
||||
mProgramId = other.mProgramId;
|
||||
|
@ -50,7 +40,7 @@ void AciHeader::copyFrom(const AciHeader & other)
|
|||
|
||||
AciHeader::AciHeader()
|
||||
{
|
||||
clearVariables();
|
||||
clear();
|
||||
}
|
||||
|
||||
AciHeader::AciHeader(const AciHeader & other)
|
||||
|
@ -106,17 +96,36 @@ void AciHeader::exportBinary()
|
|||
throw fnd::Exception(kModuleName, "Unexpected ACI type");
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
hdr->set_version(mFormatVersion);
|
||||
|
||||
if (mType == TYPE_ACI0)
|
||||
{
|
||||
// set program
|
||||
hdr->set_program_id(mProgramId);
|
||||
switch (mFormatVersion)
|
||||
{
|
||||
case(0):
|
||||
break;
|
||||
default:
|
||||
throw fnd::Exception(kModuleName, "Unsupported ACI0 version");
|
||||
}
|
||||
}
|
||||
else if (mType == TYPE_ACID)
|
||||
{
|
||||
hdr->set_version(mAcidVersion);
|
||||
switch (mAcidVersion)
|
||||
|
||||
switch (mFormatVersion)
|
||||
{
|
||||
case(0):
|
||||
mAcidSize = getAciSize();
|
||||
hdr->set_size(mAcidSize);
|
||||
hdr->set_program_id_min(0);
|
||||
hdr->set_program_id_max(0);
|
||||
|
@ -130,16 +139,6 @@ void AciHeader::exportBinary()
|
|||
throw fnd::Exception(kModuleName, "Unsupported ACID version");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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, size_t len)
|
||||
|
@ -149,7 +148,7 @@ void AciHeader::importBinary(const u8 * bytes, size_t len)
|
|||
throw fnd::Exception(kModuleName, "ACI header too small");
|
||||
}
|
||||
|
||||
clearVariables();
|
||||
clear();
|
||||
|
||||
mBinaryBlob.alloc(sizeof(sAciHeader));
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader));
|
||||
|
@ -173,16 +172,24 @@ void AciHeader::importBinary(const u8 * bytes, size_t len)
|
|||
if (mType == TYPE_ACI0)
|
||||
{
|
||||
mProgramId = hdr->program_id();
|
||||
mAcidVersion = 0;
|
||||
mFormatVersion = hdr->version();
|
||||
mAcidSize = 0;
|
||||
mProgramIdMin = 0;
|
||||
mProgramIdMax = 0;
|
||||
|
||||
switch (mFormatVersion)
|
||||
{
|
||||
case(0):
|
||||
break;
|
||||
default:
|
||||
throw fnd::Exception(kModuleName, "Unsupported ACI0 version");
|
||||
}
|
||||
}
|
||||
else if (mType == TYPE_ACID)
|
||||
{
|
||||
mProgramId = 0;
|
||||
mAcidVersion = hdr->version();
|
||||
switch (mAcidVersion)
|
||||
mFormatVersion = hdr->version();
|
||||
switch (mFormatVersion)
|
||||
{
|
||||
case(0):
|
||||
mAcidSize = hdr->size();
|
||||
|
@ -199,17 +206,28 @@ void AciHeader::importBinary(const u8 * bytes, size_t len)
|
|||
}
|
||||
}
|
||||
|
||||
mFac.offset = hdr->fac().offset();
|
||||
// the header offset is the MIN(sac.offset, fac.offset, kc.offset) - sizeof(sHeader)
|
||||
mHeaderOffset = MAX(MIN(hdr->sac().offset(), MIN(hdr->fac().offset(), hdr->kc().offset())), align(sizeof(sAciHeader), kAciAlignSize)) - align(sizeof(sAciHeader), kAciAlignSize);
|
||||
|
||||
mFac.offset = hdr->fac().offset() - mHeaderOffset;
|
||||
mFac.size = hdr->fac().size();
|
||||
mSac.offset = hdr->sac().offset();
|
||||
mSac.offset = hdr->sac().offset() - mHeaderOffset;
|
||||
mSac.size = hdr->sac().size();
|
||||
mKc.offset = hdr->kc().offset();
|
||||
mKc.offset = hdr->kc().offset() - mHeaderOffset;
|
||||
mKc.size = hdr->kc().size();
|
||||
}
|
||||
|
||||
void nx::AciHeader::clear()
|
||||
{
|
||||
clearVariables();
|
||||
mHeaderOffset = 0;
|
||||
mType = TYPE_ACI0;
|
||||
mProgramId = 0;
|
||||
mFac.offset = 0;
|
||||
mFac.size = 0;
|
||||
mSac.offset = 0;
|
||||
mSac.size = 0;
|
||||
mKc.offset = 0;
|
||||
mKc.size = 0;
|
||||
}
|
||||
|
||||
size_t nx::AciHeader::getAciSize() const
|
||||
|
@ -217,14 +235,14 @@ size_t nx::AciHeader::getAciSize() const
|
|||
return MAX(MAX(MAX(mSac.offset + mSac.size, mKc.offset + mKc.size), mFac.offset + mFac.size), sizeof(sAciHeader));
|
||||
}
|
||||
|
||||
u32 nx::AciHeader::getAcidVersion() const
|
||||
u32 nx::AciHeader::getFormatVersion() const
|
||||
{
|
||||
return mAcidVersion;
|
||||
return mFormatVersion;
|
||||
}
|
||||
|
||||
void nx::AciHeader::setAcidVersion(u32 version)
|
||||
void nx::AciHeader::setFormatVersion(u32 version)
|
||||
{
|
||||
mAcidVersion = version;
|
||||
mFormatVersion = version;
|
||||
}
|
||||
|
||||
size_t nx::AciHeader::getAcidSize() const
|
||||
|
@ -232,10 +250,12 @@ size_t nx::AciHeader::getAcidSize() const
|
|||
return mAcidSize;
|
||||
}
|
||||
|
||||
/*
|
||||
void nx::AciHeader::setAcidSize(size_t size)
|
||||
{
|
||||
mAcidSize = size;
|
||||
}
|
||||
*/
|
||||
|
||||
u64 nx::AciHeader::getProgramIdMin() const
|
||||
{
|
||||
|
@ -257,6 +277,11 @@ void nx::AciHeader::setProgramIdMax(u64 program_id)
|
|||
mProgramIdMax = program_id;
|
||||
}
|
||||
|
||||
void nx::AciHeader::setHeaderOffset(size_t offset)
|
||||
{
|
||||
mHeaderOffset = offset;
|
||||
}
|
||||
|
||||
AciHeader::AciType AciHeader::getAciType() const
|
||||
{
|
||||
return mType;
|
||||
|
@ -282,7 +307,7 @@ const AciHeader::sSection & AciHeader::getFacPos() const
|
|||
return mFac;
|
||||
}
|
||||
|
||||
void AciHeader::setFacSize(u32 size)
|
||||
void AciHeader::setFacSize(size_t size)
|
||||
{
|
||||
mFac.size = size;
|
||||
}
|
||||
|
@ -292,7 +317,7 @@ const AciHeader::sSection & AciHeader::getSacPos() const
|
|||
return mSac;
|
||||
}
|
||||
|
||||
void AciHeader::setSacSize(u32 size)
|
||||
void AciHeader::setSacSize(size_t size)
|
||||
{
|
||||
mSac.size = size;
|
||||
}
|
||||
|
@ -302,7 +327,7 @@ const AciHeader::sSection & AciHeader::getKcPos() const
|
|||
return mKc;
|
||||
}
|
||||
|
||||
void AciHeader::setKcSize(u32 size)
|
||||
void AciHeader::setKcSize(size_t size)
|
||||
{
|
||||
mKc.size = size;
|
||||
}
|
||||
|
|
|
@ -63,24 +63,25 @@ namespace nx
|
|||
void setProgramId(u64 program_id);
|
||||
|
||||
// ACID only
|
||||
u32 getAcidVersion() const;
|
||||
void setAcidVersion(u32 version);
|
||||
size_t getAcidSize() const;
|
||||
void setAcidSize(size_t size);
|
||||
//void setAcidSize(size_t size);
|
||||
u64 getProgramIdMin() const;
|
||||
void setProgramIdMin(u64 program_id);
|
||||
u64 getProgramIdMax() const;
|
||||
void setProgramIdMax(u64 program_id);
|
||||
|
||||
// ACID & ACI0
|
||||
void setHeaderOffset(size_t offset);
|
||||
AciType getAciType() const;
|
||||
void setAciType(AciType type);
|
||||
u32 getFormatVersion() const;
|
||||
void setFormatVersion(u32 version);
|
||||
const sSection& getFacPos() const;
|
||||
void setFacSize(u32 size);
|
||||
void setFacSize(size_t size);
|
||||
const sSection& getSacPos() const;
|
||||
void setSacSize(u32 size);
|
||||
void setSacSize(size_t size);
|
||||
const sSection& getKcPos() const;
|
||||
void setKcSize(u32 size);
|
||||
void setKcSize(size_t size);
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "ACI_HEADER";
|
||||
|
@ -94,8 +95,8 @@ namespace nx
|
|||
private:
|
||||
u8 signature_[4];
|
||||
u32 size_; // includes prefacing signature, set only in ACID since it is signed
|
||||
u8 reserved_0[4];
|
||||
u32 version_; // set in ACID only, v0 has size, but no pid range, v1 has no size by pid range
|
||||
u8 reserved_1[4];
|
||||
u64 program_id_; // set only in ACI0 (since ACID is generic)
|
||||
u64 program_id_max_;
|
||||
struct sAciSection
|
||||
|
@ -109,7 +110,7 @@ namespace nx
|
|||
|
||||
u32 size() const { return le_word(size_); }
|
||||
void set_size(u32 size) { size_ = le_word(size); }
|
||||
} fac_, sac_, kc_, reserved_3;
|
||||
} fac_, sac_, kc_;
|
||||
public:
|
||||
const char* signature() const { return (const char*)signature_; }
|
||||
void set_signature(const char* signature) { memcpy(signature_, signature, 4); }
|
||||
|
@ -147,16 +148,15 @@ namespace nx
|
|||
u64 mProgramId;
|
||||
|
||||
// ACID variables
|
||||
u32 mAcidVersion;
|
||||
size_t mAcidSize;
|
||||
u64 mProgramIdMin;
|
||||
u64 mProgramIdMax;
|
||||
|
||||
// ACI(D) variables
|
||||
size_t mHeaderOffset;
|
||||
AciType mType;
|
||||
u32 mFormatVersion;
|
||||
sSection mFac, mSac, mKc;
|
||||
|
||||
void clearVariables();
|
||||
void calculateSectionOffsets();
|
||||
bool isEqual(const AciHeader& other) const;
|
||||
void copyFrom(const AciHeader& other);
|
||||
|
|
142
lib/nx/AcidBinary.cpp
Normal file
142
lib/nx/AcidBinary.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include "AcidBinary.h"
|
||||
|
||||
|
||||
|
||||
nx::AcidBinary::AcidBinary()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
nx::AcidBinary::AcidBinary(const AcidBinary & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
nx::AcidBinary::AcidBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
importBinary(bytes, len);
|
||||
}
|
||||
|
||||
void nx::AcidBinary::clear()
|
||||
{
|
||||
AciBinary::clear();
|
||||
mEmbeddedPublicKey = crypto::rsa::sRsa2048Key();
|
||||
}
|
||||
|
||||
const crypto::rsa::sRsa2048Key & nx::AcidBinary::getPublicKey() const
|
||||
{
|
||||
return mEmbeddedPublicKey;
|
||||
}
|
||||
|
||||
void nx::AcidBinary::setPublicKey(const crypto::rsa::sRsa2048Key & key)
|
||||
{
|
||||
mEmbeddedPublicKey = key;
|
||||
}
|
||||
|
||||
bool nx::AcidBinary::isEqual(const AcidBinary & other) const
|
||||
{
|
||||
return AciBinary::operator==(other) \
|
||||
&& (mEmbeddedPublicKey == other.mEmbeddedPublicKey);
|
||||
}
|
||||
|
||||
void nx::AcidBinary::copyFrom(const AcidBinary & other)
|
||||
{
|
||||
if (other.getSize())
|
||||
{
|
||||
importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
AciBinary::operator=(other);
|
||||
mEmbeddedPublicKey = other.mEmbeddedPublicKey;
|
||||
}
|
||||
}
|
||||
|
||||
bool nx::AcidBinary::operator==(const AcidBinary & other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
bool nx::AcidBinary::operator!=(const AcidBinary & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::AcidBinary::operator=(const AcidBinary & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
const u8 * nx::AcidBinary::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t nx::AcidBinary::getSize() const
|
||||
{
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
||||
|
||||
void nx::AcidBinary::exportBinary()
|
||||
{
|
||||
AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature
|
||||
AciBinary::exportBinary();
|
||||
mBinaryBlob.alloc(AciBinary::getSize() + crypto::rsa::kRsa2048Size * 2);
|
||||
|
||||
memcpy(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size);
|
||||
memcpy(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size * 2, AciBinary::getBytes(), AciBinary::getSize());
|
||||
}
|
||||
|
||||
void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key)
|
||||
{
|
||||
if (mBinaryBlob.getSize() == 0)
|
||||
{
|
||||
exportBinary();
|
||||
}
|
||||
|
||||
u8 hash[crypto::sha::kSha256HashLen];
|
||||
crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash);
|
||||
|
||||
if (crypto::rsa::pkcs::rsaSign(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Failed to sign ACID");
|
||||
}
|
||||
}
|
||||
|
||||
void nx::AcidBinary::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
if (len <= crypto::rsa::kRsa2048Size*2)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "ACID binary too small");
|
||||
}
|
||||
|
||||
// import aci binary past sig + pubkey
|
||||
AciBinary::importBinary(bytes + crypto::rsa::kRsa2048Size * 2, len - crypto::rsa::kRsa2048Size * 2);
|
||||
|
||||
// save internal copy
|
||||
size_t acid_size = AciBinary::getSize() + crypto::rsa::kRsa2048Size * 2;
|
||||
if (acid_size > len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "ACID binary too small");
|
||||
}
|
||||
|
||||
mBinaryBlob.alloc(acid_size);
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
memcpy(mEmbeddedPublicKey.modulus, bytes + crypto::rsa::kRsa2048Size, crypto::rsa::kRsa2048Size);
|
||||
}
|
||||
|
||||
void nx::AcidBinary::verifyBinary(const crypto::rsa::sRsa2048Key & key)
|
||||
{
|
||||
if (mBinaryBlob.getSize() == 0)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "No ACID binary exists to verify");
|
||||
}
|
||||
|
||||
u8 hash[crypto::sha::kSha256HashLen];
|
||||
crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash);
|
||||
|
||||
if (crypto::rsa::pkcs::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Failed to verify ACID");
|
||||
}
|
||||
}
|
51
lib/nx/AcidBinary.h
Normal file
51
lib/nx/AcidBinary.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/memory_blob.h>
|
||||
#include <nx/ISerialiseableBinary.h>
|
||||
#include <nx/AciBinary.h>
|
||||
#include <crypto/rsa.h>
|
||||
|
||||
namespace nx
|
||||
{
|
||||
class AcidBinary :
|
||||
public AciBinary
|
||||
{
|
||||
public:
|
||||
AcidBinary();
|
||||
AcidBinary(const AcidBinary& other);
|
||||
AcidBinary(const u8* bytes, size_t len);
|
||||
|
||||
bool operator==(const AcidBinary& other) const;
|
||||
bool operator!=(const AcidBinary& other) const;
|
||||
void operator=(const AcidBinary& other);
|
||||
|
||||
// to be used after export
|
||||
const u8* getBytes() const;
|
||||
size_t getSize() const;
|
||||
|
||||
// export/import binary
|
||||
virtual void exportBinary();
|
||||
void signBinary(const crypto::rsa::sRsa2048Key& key);
|
||||
virtual void importBinary(const u8* bytes, size_t len);
|
||||
void verifyBinary(const crypto::rsa::sRsa2048Key& key);
|
||||
|
||||
// variables
|
||||
virtual void clear();
|
||||
|
||||
const crypto::rsa::sRsa2048Key& getPublicKey() const;
|
||||
void setPublicKey(const crypto::rsa::sRsa2048Key& key);
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "ACID_BINARY";
|
||||
|
||||
// raw binary
|
||||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// variables
|
||||
crypto::rsa::sRsa2048Key mEmbeddedPublicKey;
|
||||
|
||||
bool isEqual(const AcidBinary& other) const;
|
||||
void copyFrom(const AcidBinary& other);
|
||||
};
|
||||
}
|
||||
|
|
@ -1,156 +1,102 @@
|
|||
#include "FacBinary.h"
|
||||
|
||||
using namespace nx;
|
||||
|
||||
FacBinary::FacBinary() :
|
||||
mHeader()
|
||||
{
|
||||
clearVariables();
|
||||
}
|
||||
|
||||
FacBinary::FacBinary(const FacBinary & other)
|
||||
{
|
||||
importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
nx::FacBinary::FacBinary()
|
||||
{}
|
||||
|
||||
FacBinary::FacBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
importBinary(bytes, len);
|
||||
}
|
||||
|
||||
bool FacBinary::operator==(const FacBinary & other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
bool FacBinary::operator!=(const FacBinary & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void FacBinary::operator=(const FacBinary & other)
|
||||
nx::FacBinary::FacBinary(const FacBinary & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
const u8 * FacBinary::getBytes() const
|
||||
nx::FacBinary::FacBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
importBinary(bytes, len);
|
||||
}
|
||||
|
||||
bool nx::FacBinary::operator==(const FacBinary & other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
bool nx::FacBinary::operator!=(const FacBinary & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::FacBinary::operator=(const FacBinary & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
const u8 * nx::FacBinary::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t FacBinary::getSize() const
|
||||
size_t nx::FacBinary::getSize() const
|
||||
{
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
||||
|
||||
void FacBinary::exportBinary()
|
||||
void nx::FacBinary::exportBinary()
|
||||
{
|
||||
mHeader.setFsaRights(mFsaRights);
|
||||
mHeader.setContentOwnerIdSize(mContentOwnerIds.getSize() * sizeof(u32));
|
||||
mHeader.setSaveDataOwnerIdSize(mSaveDataOwnerIds.getSize() * sizeof(u32));
|
||||
mHeader.exportBinary();
|
||||
FacHeader::setContentOwnerIdSize(mContentOwnerIdList.getSize() * sizeof(u32));
|
||||
FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.getSize() * sizeof(u32));
|
||||
FacHeader::exportBinary();
|
||||
|
||||
mBinaryBlob.alloc(mHeader.getFacSize());
|
||||
memcpy(mBinaryBlob.getBytes(), mHeader.getBytes(), mHeader.getSize());
|
||||
mBinaryBlob.alloc(getFacSize());
|
||||
memcpy(mBinaryBlob.getBytes(), FacHeader::getBytes(), FacHeader::getSize());
|
||||
|
||||
u32* rawContentOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getContentOwnerIdOffset());
|
||||
for (size_t i = 0; i < mContentOwnerIds.getSize(); i++)
|
||||
u32* rawContentOwnerIds = (u32*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset());
|
||||
for (size_t i = 0; i < mContentOwnerIdList.getSize(); i++)
|
||||
{
|
||||
rawContentOwnerIds[i] = le_word(mContentOwnerIds[i]);
|
||||
rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]);
|
||||
}
|
||||
|
||||
u32* rawSaveDataOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getSaveDataOwnerIdOffset());
|
||||
for (size_t i = 0; i < mSaveDataOwnerIds.getSize(); i++)
|
||||
|
||||
u32* rawSaveDataOwnerIds = (u32*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset());
|
||||
for (size_t i = 0; i < mSaveDataOwnerIdList.getSize(); i++)
|
||||
{
|
||||
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIds[i]);
|
||||
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void FacBinary::importBinary(const u8 * bytes, size_t len)
|
||||
void nx::FacBinary::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
clearVariables();
|
||||
mHeader.importBinary(bytes, len);
|
||||
if (mHeader.getFacSize() > len)
|
||||
clear();
|
||||
FacHeader::importBinary(bytes, len);
|
||||
if (FacHeader::getFacSize() > len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "FAC binary too small");
|
||||
}
|
||||
|
||||
mBinaryBlob.alloc(mHeader.getFacSize());
|
||||
mBinaryBlob.alloc(FacHeader::getFacSize());
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
|
||||
mFsaRights = mHeader.getFsaRights();
|
||||
u32* rawContentOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getContentOwnerIdOffset());
|
||||
size_t rawContentOwnerIdNum = mHeader.getContentOwnerIdSize() / sizeof(u32);
|
||||
u32* rawContentOwnerIds = (u32*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset());
|
||||
size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdSize() / sizeof(u32);
|
||||
for (size_t i = 0; i < rawContentOwnerIdNum; i++)
|
||||
{
|
||||
addContentOwnerId(le_word(rawContentOwnerIds[i]));
|
||||
mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i]));
|
||||
}
|
||||
|
||||
u32* rawSaveDataOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getSaveDataOwnerIdOffset());
|
||||
size_t rawSaveDataOwnerIdNum = mHeader.getSaveDataOwnerIdSize() / sizeof(u32);
|
||||
u32* rawSaveDataOwnerIds = (u32*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset());
|
||||
size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdSize() / sizeof(u32);
|
||||
for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++)
|
||||
{
|
||||
addSaveDataOwnerId(le_word(rawSaveDataOwnerIds[i]));
|
||||
mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void nx::FacBinary::clear()
|
||||
bool nx::FacBinary::isEqual(const FacBinary & other) const
|
||||
{
|
||||
clearVariables();
|
||||
return (FacHeader::operator==(other)) \
|
||||
&& (mContentOwnerIdList == other.mContentOwnerIdList) \
|
||||
&& (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList);
|
||||
}
|
||||
|
||||
bool FacBinary::isPermissionSet(FsAccessFlag flag) const
|
||||
{
|
||||
return (mFsaRights & flag) == flag;
|
||||
}
|
||||
|
||||
void FacBinary::addPermission(FsAccessFlag flag)
|
||||
{
|
||||
mFsaRights |= flag;
|
||||
}
|
||||
|
||||
void FacBinary::removePermission(FsAccessFlag flag)
|
||||
{
|
||||
mFsaRights &= ~(u64)flag;
|
||||
}
|
||||
|
||||
const fnd::List<u32>& FacBinary::getContentOwnerIds() const
|
||||
{
|
||||
return mContentOwnerIds;
|
||||
}
|
||||
|
||||
void FacBinary::addContentOwnerId(u32 id)
|
||||
{
|
||||
mContentOwnerIds.addElement(id);
|
||||
}
|
||||
|
||||
const fnd::List<u32>& FacBinary::getSaveDataOwnerIds() const
|
||||
{
|
||||
return mSaveDataOwnerIds;
|
||||
}
|
||||
|
||||
void FacBinary::addSaveDataOwnerId(u32 id)
|
||||
{
|
||||
mSaveDataOwnerIds.addElement(id);
|
||||
}
|
||||
|
||||
void FacBinary::clearVariables()
|
||||
{
|
||||
mHeader = FacHeader();
|
||||
mFsaRights = 0;
|
||||
mContentOwnerIds.clear();
|
||||
mSaveDataOwnerIds.clear();
|
||||
}
|
||||
|
||||
bool FacBinary::isEqual(const FacBinary & other) const
|
||||
{
|
||||
return (mHeader == other.mHeader) \
|
||||
&& (mFsaRights == other.mFsaRights) \
|
||||
&& (mContentOwnerIds == other.mContentOwnerIds) \
|
||||
&& (mSaveDataOwnerIds == other.mSaveDataOwnerIds);
|
||||
}
|
||||
|
||||
void FacBinary::copyFrom(const FacBinary & other)
|
||||
void nx::FacBinary::copyFrom(const FacBinary & other)
|
||||
{
|
||||
if (other.getSize())
|
||||
{
|
||||
|
@ -158,10 +104,35 @@ void FacBinary::copyFrom(const FacBinary & other)
|
|||
}
|
||||
else
|
||||
{
|
||||
mBinaryBlob.clear();
|
||||
mHeader = other.mHeader;
|
||||
mFsaRights = other.mFsaRights;
|
||||
mContentOwnerIds = other.mContentOwnerIds;
|
||||
mSaveDataOwnerIds = other.mSaveDataOwnerIds;
|
||||
FacHeader::operator=(other);
|
||||
mContentOwnerIdList = other.mContentOwnerIdList;
|
||||
mSaveDataOwnerIdList = other.mSaveDataOwnerIdList;
|
||||
}
|
||||
}
|
||||
|
||||
void nx::FacBinary::clear()
|
||||
{
|
||||
FacHeader::clear();
|
||||
mContentOwnerIdList.clear();
|
||||
mSaveDataOwnerIdList.clear();
|
||||
}
|
||||
|
||||
const fnd::List<u32>& nx::FacBinary::getContentOwnerIdList() const
|
||||
{
|
||||
return mContentOwnerIdList;
|
||||
}
|
||||
|
||||
void nx::FacBinary::setContentOwnerIdList(const fnd::List<u32>& list)
|
||||
{
|
||||
mContentOwnerIdList = list;
|
||||
}
|
||||
|
||||
const fnd::List<u32>& nx::FacBinary::getSaveDataOwnerIdList() const
|
||||
{
|
||||
return mSaveDataOwnerIdList;
|
||||
}
|
||||
|
||||
void nx::FacBinary::setSaveDataOwnerIdList(const fnd::List<u32>& list)
|
||||
{
|
||||
mSaveDataOwnerIdList = list;
|
||||
}
|
||||
|
|
|
@ -5,38 +5,13 @@
|
|||
#include <nx/ISerialiseableBinary.h>
|
||||
#include <nx/FacHeader.h>
|
||||
|
||||
|
||||
namespace nx
|
||||
{
|
||||
class FacBinary :
|
||||
public ISerialiseableBinary
|
||||
public FacHeader
|
||||
{
|
||||
public:
|
||||
enum FsAccessFlag
|
||||
{
|
||||
FSA_APPLICATION_INFO = BIT(0),
|
||||
FSA_BOOT_MODE_CONTROL = BIT(1),
|
||||
FSA_CALIBRATION = BIT(2),
|
||||
FSA_SYSTEM_SAVE_DATA = BIT(3),
|
||||
FSA_GAME_CARD = BIT(4),
|
||||
FSA_SAVE_DATA_BACKUP = BIT(5),
|
||||
FSA_SAVE_DATA_MANAGEMENT = BIT(6),
|
||||
FSA_BIS_ALL_RAW = BIT(7),
|
||||
FSA_GAME_CARD_RAW = BIT(8),
|
||||
FSA_GAME_CARD_PRIVATE = BIT(9),
|
||||
FSA_SET_TIME = BIT(10),
|
||||
FSA_CONTENT_MANAGER = BIT(11),
|
||||
FSA_IMAGE_MANAGER = BIT(12),
|
||||
FSA_CREATE_SAVE_DATA = BIT(13),
|
||||
FSA_SYSTEM_SAVE_DATA_MANAGEMENT = BIT(14),
|
||||
FSA_BIS_FILE_SYSTEM = BIT(15),
|
||||
FSA_SYSTEM_UPDATE = BIT(16),
|
||||
FSA_SAVE_DATA_META = BIT(17),
|
||||
FSA_DEVICE_SAVE_CONTROL = BIT(19),
|
||||
FSA_SETTINGS_CONTROL = BIT(20),
|
||||
FSA_DEBUG = BIT(62),
|
||||
FSA_FULL_PERMISSION = BIT(63),
|
||||
};
|
||||
|
||||
FacBinary();
|
||||
FacBinary(const FacBinary& other);
|
||||
FacBinary(const u8* bytes, size_t len);
|
||||
|
@ -55,28 +30,24 @@ namespace nx
|
|||
|
||||
// variables
|
||||
void clear();
|
||||
bool isPermissionSet(FsAccessFlag flag) const;
|
||||
void addPermission(FsAccessFlag flag);
|
||||
void removePermission(FsAccessFlag flag);
|
||||
|
||||
const fnd::List<u32>& getContentOwnerIds() const;
|
||||
void addContentOwnerId(u32 id);
|
||||
const fnd::List<u32>& getContentOwnerIdList() const;
|
||||
void setContentOwnerIdList(const fnd::List<u32>& list);
|
||||
|
||||
const fnd::List<u32>& getSaveDataOwnerIdList() const;
|
||||
void setSaveDataOwnerIdList(const fnd::List<u32>& list);
|
||||
|
||||
const fnd::List<u32>& getSaveDataOwnerIds() const;
|
||||
void addSaveDataOwnerId(u32 id);
|
||||
private:
|
||||
const std::string kModuleName = "FAC_BINARY";
|
||||
static const u32 kFacFormatVersion = 1;
|
||||
|
||||
// raw binary
|
||||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// variables
|
||||
FacHeader mHeader;
|
||||
u64 mFsaRights;
|
||||
fnd::List<u32> mContentOwnerIds;
|
||||
fnd::List<u32> mSaveDataOwnerIds;
|
||||
fnd::List<u32> mContentOwnerIdList;
|
||||
fnd::List<u32> mSaveDataOwnerIdList;
|
||||
|
||||
void clearVariables();
|
||||
bool isEqual(const FacBinary& other) const;
|
||||
void copyFrom(const FacBinary& other);
|
||||
};
|
||||
|
|
|
@ -2,17 +2,20 @@
|
|||
|
||||
|
||||
|
||||
nx::FacHeader::FacHeader()
|
||||
nx::FacHeader::FacHeader() :
|
||||
mFsaRights()
|
||||
{
|
||||
clearVariables();
|
||||
clear();
|
||||
}
|
||||
|
||||
nx::FacHeader::FacHeader(const FacHeader & other)
|
||||
nx::FacHeader::FacHeader(const FacHeader & other) :
|
||||
mFsaRights()
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
nx::FacHeader::FacHeader(const u8 * bytes, size_t len)
|
||||
nx::FacHeader::FacHeader(const u8 * bytes, size_t len) :
|
||||
mFsaRights()
|
||||
{
|
||||
importBinary(bytes, len);
|
||||
}
|
||||
|
@ -47,8 +50,18 @@ void nx::FacHeader::exportBinary()
|
|||
mBinaryBlob.alloc(sizeof(sFacHeader));
|
||||
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
||||
|
||||
hdr->set_version(kFacFormatVersion);
|
||||
hdr->set_fac_flags(mFsaRights);
|
||||
if (mVersion != kFacFormatVersion)
|
||||
{
|
||||
fnd::Exception(kModuleName, "Unsupported format version");
|
||||
}
|
||||
hdr->set_version(mVersion);
|
||||
|
||||
u64 flag = 0;
|
||||
for (size_t i = 0; i < mFsaRights.getSize(); i++)
|
||||
{
|
||||
flag |= BIT((u64)mFsaRights[i]);
|
||||
}
|
||||
hdr->set_fac_flags(flag);
|
||||
|
||||
calculateOffsets();
|
||||
hdr->content_owner_ids().set_start(mContentOwnerIdPos.offset);
|
||||
|
@ -72,8 +85,16 @@ void nx::FacHeader::importBinary(const u8 * bytes, size_t len)
|
|||
{
|
||||
throw fnd::Exception(kModuleName, "Unsupported FAC format version");
|
||||
}
|
||||
mVersion = hdr->version();
|
||||
|
||||
mFsaRights = hdr->fac_flags();
|
||||
clear();
|
||||
for (u64 i = 0; i < 64; i++)
|
||||
{
|
||||
if ((hdr->fac_flags() >> i) & 1)
|
||||
{
|
||||
mFsaRights.addElement((FsAccessFlag)i);
|
||||
}
|
||||
}
|
||||
mContentOwnerIdPos.offset = hdr->content_owner_ids().start();
|
||||
mContentOwnerIdPos.size = hdr->content_owner_ids().end() > hdr->content_owner_ids().start() ? hdr->content_owner_ids().end() - hdr->content_owner_ids().start() : 0;
|
||||
mSaveDataOwnerIdPos.offset = hdr->save_data_owner_ids().start();
|
||||
|
@ -82,7 +103,11 @@ void nx::FacHeader::importBinary(const u8 * bytes, size_t len)
|
|||
|
||||
void nx::FacHeader::clear()
|
||||
{
|
||||
clearVariables();
|
||||
mFsaRights.clear();
|
||||
mContentOwnerIdPos.offset = 0;
|
||||
mContentOwnerIdPos.size = 0;
|
||||
mSaveDataOwnerIdPos.offset = 0;
|
||||
mSaveDataOwnerIdPos.size = 0;
|
||||
}
|
||||
|
||||
size_t nx::FacHeader::getFacSize() const
|
||||
|
@ -92,14 +117,28 @@ size_t nx::FacHeader::getFacSize() const
|
|||
return MAX(MAX(savedata, content), sizeof(sFacHeader));
|
||||
}
|
||||
|
||||
u64 nx::FacHeader::getFsaRights() const
|
||||
u32 nx::FacHeader::getFormatVersion() const
|
||||
{
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
void nx::FacHeader::setFormatVersion(u32 version)
|
||||
{
|
||||
mVersion = version;
|
||||
}
|
||||
|
||||
const fnd::List<nx::FacHeader::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const
|
||||
{
|
||||
return mFsaRights;
|
||||
}
|
||||
|
||||
void nx::FacHeader::setFsaRights(u64 flag)
|
||||
void nx::FacHeader::setFsaRightsList(const fnd::List<FsAccessFlag>& list)
|
||||
{
|
||||
mFsaRights = flag;
|
||||
mFsaRights.clear();
|
||||
for (size_t i = 0; i < list.getSize(); i++)
|
||||
{
|
||||
mFsaRights.hasElement(list[i]) ? mFsaRights.addElement(list[i]) : throw fnd::Exception(kModuleName, "FSA right already exists");
|
||||
}
|
||||
}
|
||||
|
||||
size_t nx::FacHeader::getContentOwnerIdOffset() const
|
||||
|
@ -132,15 +171,6 @@ void nx::FacHeader::setSaveDataOwnerIdSize(size_t size)
|
|||
mSaveDataOwnerIdPos.size = size;
|
||||
}
|
||||
|
||||
void nx::FacHeader::clearVariables()
|
||||
{
|
||||
mFsaRights = 0;
|
||||
mContentOwnerIdPos.offset = 0;
|
||||
mContentOwnerIdPos.size = 0;
|
||||
mSaveDataOwnerIdPos.offset = 0;
|
||||
mSaveDataOwnerIdPos.size = 0;
|
||||
}
|
||||
|
||||
void nx::FacHeader::calculateOffsets()
|
||||
{
|
||||
mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/memory_blob.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nx/ISerialiseableBinary.h>
|
||||
|
||||
namespace nx
|
||||
|
@ -9,6 +10,32 @@ namespace nx
|
|||
public ISerialiseableBinary
|
||||
{
|
||||
public:
|
||||
enum FsAccessFlag
|
||||
{
|
||||
FSA_APPLICATION_INFO,
|
||||
FSA_BOOT_MODE_CONTROL,
|
||||
FSA_CALIBRATION,
|
||||
FSA_SYSTEM_SAVE_DATA,
|
||||
FSA_GAME_CARD,
|
||||
FSA_SAVE_DATA_BACKUP,
|
||||
FSA_SAVE_DATA_MANAGEMENT,
|
||||
FSA_BIS_ALL_RAW,
|
||||
FSA_GAME_CARD_RAW,
|
||||
FSA_GAME_CARD_PRIVATE,
|
||||
FSA_SET_TIME,
|
||||
FSA_CONTENT_MANAGER,
|
||||
FSA_IMAGE_MANAGER,
|
||||
FSA_CREATE_SAVE_DATA,
|
||||
FSA_SYSTEM_SAVE_DATA_MANAGEMENT,
|
||||
FSA_BIS_FILE_SYSTEM,
|
||||
FSA_SYSTEM_UPDATE,
|
||||
FSA_SAVE_DATA_META,
|
||||
FSA_DEVICE_SAVE_CONTROL,
|
||||
FSA_SETTINGS_CONTROL,
|
||||
FSA_DEBUG = 62,
|
||||
FSA_FULL_PERMISSION = 63,
|
||||
};
|
||||
|
||||
FacHeader();
|
||||
FacHeader(const FacHeader& other);
|
||||
FacHeader(const u8* bytes, size_t len);
|
||||
|
@ -29,8 +56,11 @@ namespace nx
|
|||
void clear();
|
||||
size_t getFacSize() const;
|
||||
|
||||
u64 getFsaRights() const;
|
||||
void setFsaRights(u64 flag);
|
||||
u32 getFormatVersion() const;
|
||||
void setFormatVersion(u32 version);
|
||||
|
||||
const fnd::List<FsAccessFlag>& getFsaRightsList() const;
|
||||
void setFsaRightsList(const fnd::List<FsAccessFlag>& list);
|
||||
|
||||
size_t getContentOwnerIdOffset() const;
|
||||
size_t getContentOwnerIdSize() const;
|
||||
|
@ -81,14 +111,14 @@ namespace nx
|
|||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// variables
|
||||
u64 mFsaRights;
|
||||
u32 mVersion;
|
||||
fnd::List<FsAccessFlag> mFsaRights;
|
||||
struct sSection
|
||||
{
|
||||
size_t offset;
|
||||
size_t size;
|
||||
} mContentOwnerIdPos, mSaveDataOwnerIdPos;
|
||||
|
||||
void clearVariables();
|
||||
void calculateOffsets();
|
||||
bool isEqual(const FacHeader& other) const;
|
||||
void copyFrom(const FacHeader& other);
|
||||
|
|
|
@ -131,7 +131,15 @@ void nx::KcBinary::importBinary(const u8 * bytes, size_t len)
|
|||
|
||||
void nx::KcBinary::clear()
|
||||
{
|
||||
clearVariables();
|
||||
mBinaryBlob.clear();
|
||||
mThreadInfo.clear();
|
||||
mSystemCalls.clear();
|
||||
mMemoryMap.clear();
|
||||
mInterupts.clear();
|
||||
mMiscParams.clear();
|
||||
mKernelVersion.clear();
|
||||
mHandleTableSize.clear();
|
||||
mMiscFlags.clear();
|
||||
}
|
||||
|
||||
const nx::ThreadInfoHandler & nx::KcBinary::getThreadInfo() const
|
||||
|
@ -214,19 +222,6 @@ nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags()
|
|||
return mMiscFlags;
|
||||
}
|
||||
|
||||
void nx::KcBinary::clearVariables()
|
||||
{
|
||||
mBinaryBlob.clear();
|
||||
mThreadInfo.clear();
|
||||
mSystemCalls.clear();
|
||||
mMemoryMap.clear();
|
||||
mInterupts.clear();
|
||||
mMiscParams.clear();
|
||||
mKernelVersion.clear();
|
||||
mHandleTableSize.clear();
|
||||
mMiscFlags.clear();
|
||||
}
|
||||
|
||||
bool nx::KcBinary::isEqual(const KcBinary & other) const
|
||||
{
|
||||
return (mThreadInfo == other.mThreadInfo) \
|
||||
|
|
|
@ -41,7 +41,7 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
|
|||
throw fnd::Exception(kModuleName, "NCA header size is too small");
|
||||
}
|
||||
|
||||
clearVariables();
|
||||
clear();
|
||||
|
||||
mBinaryBlob.alloc(sizeof(sNcaHeader));
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sNcaHeader));
|
||||
|
@ -78,7 +78,12 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
|
|||
|
||||
void nx::NcaHeader::clear()
|
||||
{
|
||||
clearVariables();
|
||||
mBlockSize = 0;
|
||||
mNcaSize = 0;
|
||||
mProgramId = 0;
|
||||
mUnk0 = 0;
|
||||
mSections.clear();
|
||||
mAesKeys.clear();
|
||||
}
|
||||
|
||||
u64 NcaHeader::getNcaSize() const
|
||||
|
@ -135,16 +140,6 @@ void NcaHeader::addKey(const crypto::aes::sAes128Key & key)
|
|||
mAesKeys.addElement(key);
|
||||
}
|
||||
|
||||
void NcaHeader::clearVariables()
|
||||
{
|
||||
mBlockSize = 0;
|
||||
mNcaSize = 0;
|
||||
mProgramId = 0;
|
||||
mUnk0 = 0;
|
||||
mSections.clear();
|
||||
mAesKeys.clear();
|
||||
}
|
||||
|
||||
u64 NcaHeader::blockNumToSize(u32 block_num) const
|
||||
{
|
||||
return block_num*mBlockSize;
|
||||
|
@ -185,7 +180,7 @@ void NcaHeader::copyFrom(const NcaHeader & other)
|
|||
|
||||
NcaHeader::NcaHeader()
|
||||
{
|
||||
clearVariables();
|
||||
clear();
|
||||
}
|
||||
|
||||
NcaHeader::NcaHeader(const NcaHeader & other)
|
||||
|
|
|
@ -149,7 +149,6 @@ namespace nx
|
|||
fnd::List<sSection> mSections;
|
||||
fnd::List<crypto::aes::sAes128Key> mAesKeys;
|
||||
|
||||
void clearVariables();
|
||||
u64 blockNumToSize(u32 block_num) const;
|
||||
u32 sizeToBlockNum(u64 real_size) const;
|
||||
bool isEqual(const NcaHeader& other) const;
|
||||
|
|
136
lib/nx/NpdmBinary.cpp
Normal file
136
lib/nx/NpdmBinary.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include "NpdmBinary.h"
|
||||
|
||||
|
||||
|
||||
nx::NpdmBinary::NpdmBinary() :
|
||||
mAci(),
|
||||
mAcid()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
nx::NpdmBinary::NpdmBinary(const NpdmBinary & other) :
|
||||
mAci(),
|
||||
mAcid()
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
nx::NpdmBinary::NpdmBinary(const u8 * bytes, size_t len) :
|
||||
mAci(),
|
||||
mAcid()
|
||||
{
|
||||
importBinary(bytes, len);
|
||||
}
|
||||
|
||||
bool nx::NpdmBinary::operator==(const NpdmBinary & other) const
|
||||
{
|
||||
return isEqual(other);
|
||||
}
|
||||
|
||||
bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const
|
||||
{
|
||||
return !isEqual(other);
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::operator=(const NpdmBinary & other)
|
||||
{
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::exportBinary()
|
||||
{
|
||||
mAci.exportBinary();
|
||||
mAcid.exportBinary();
|
||||
|
||||
setAciSize(mAci.getSize());
|
||||
setAcidSize(mAcid.getSize());
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
// clear
|
||||
clear();
|
||||
|
||||
// import header
|
||||
NpdmHeader::importBinary(bytes, len);
|
||||
|
||||
// check size
|
||||
if (getNpdmSize() > len)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "NPDM binary too small");
|
||||
}
|
||||
|
||||
// save local copy
|
||||
mBinaryBlob.alloc(getNpdmSize());
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
|
||||
// import Aci/Acid
|
||||
if (getAciPos().size)
|
||||
{
|
||||
mAci.importBinary(mBinaryBlob.getBytes() + getAciPos().offset, getAciPos().size);
|
||||
}
|
||||
if (getAcidPos().size)
|
||||
{
|
||||
mAcid.importBinary(mBinaryBlob.getBytes() + getAcidPos().offset, getAcidPos().size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::clear()
|
||||
{
|
||||
NpdmHeader::clear();
|
||||
mAci.clear();
|
||||
mAcid.clear();
|
||||
}
|
||||
|
||||
const nx::AciBinary & nx::NpdmBinary::getAci() const
|
||||
{
|
||||
return mAci;
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::setAci(const AciBinary & aci)
|
||||
{
|
||||
mAci = aci;
|
||||
}
|
||||
|
||||
const nx::AcidBinary & nx::NpdmBinary::getAcid() const
|
||||
{
|
||||
return mAcid;
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::setAcid(const AcidBinary & acid)
|
||||
{
|
||||
mAcid = acid;
|
||||
}
|
||||
|
||||
bool nx::NpdmBinary::isEqual(const NpdmBinary & other) const
|
||||
{
|
||||
return (NpdmHeader::operator==(other)) \
|
||||
&& (mAci == other.mAci) \
|
||||
&& (mAcid == other.mAcid);
|
||||
}
|
||||
|
||||
void nx::NpdmBinary::copyFrom(const NpdmBinary & other)
|
||||
{
|
||||
if (other.getSize())
|
||||
{
|
||||
importBinary(other.getBytes(), other.getSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
NpdmHeader::operator=(other);
|
||||
mAci = other.mAci;
|
||||
mAcid = other.mAcid;
|
||||
}
|
||||
}
|
||||
|
||||
const u8 * nx::NpdmBinary::getBytes() const
|
||||
{
|
||||
return mBinaryBlob.getBytes();
|
||||
}
|
||||
|
||||
size_t nx::NpdmBinary::getSize() const
|
||||
{
|
||||
return mBinaryBlob.getSize();
|
||||
}
|
55
lib/nx/NpdmBinary.h
Normal file
55
lib/nx/NpdmBinary.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fnd/memory_blob.h>
|
||||
#include <fnd/List.h>
|
||||
#include <nx/ISerialiseableBinary.h>
|
||||
#include <nx/NpdmHeader.h>
|
||||
#include <nx/AciBinary.h>
|
||||
#include <nx/AcidBinary.h>
|
||||
|
||||
|
||||
namespace nx
|
||||
{
|
||||
class NpdmBinary :
|
||||
public NpdmHeader
|
||||
{
|
||||
public:
|
||||
NpdmBinary();
|
||||
NpdmBinary(const NpdmBinary& other);
|
||||
NpdmBinary(const u8* bytes, size_t len);
|
||||
|
||||
bool operator==(const NpdmBinary& other) const;
|
||||
bool operator!=(const NpdmBinary& other) const;
|
||||
void operator=(const NpdmBinary& other);
|
||||
|
||||
// to be used after export
|
||||
const u8* getBytes() const;
|
||||
size_t getSize() const;
|
||||
|
||||
// export/import binary
|
||||
void exportBinary();
|
||||
void importBinary(const u8* bytes, size_t len);
|
||||
|
||||
// variables
|
||||
void clear();
|
||||
|
||||
const AciBinary& getAci() const;
|
||||
void setAci(const AciBinary& aci);
|
||||
|
||||
const AcidBinary& getAcid() const;
|
||||
void setAcid(const AcidBinary& acid);
|
||||
private:
|
||||
const std::string kModuleName = "NPDM_BINARY";
|
||||
|
||||
// raw binary
|
||||
fnd::MemoryBlob mBinaryBlob;
|
||||
|
||||
// variables
|
||||
AciBinary mAci;
|
||||
AcidBinary mAcid;
|
||||
|
||||
bool isEqual(const NpdmBinary& other) const;
|
||||
void copyFrom(const NpdmBinary& other);
|
||||
};
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
nx::NpdmHeader::NpdmHeader()
|
||||
{
|
||||
clearVariables();
|
||||
clear();
|
||||
}
|
||||
|
||||
nx::NpdmHeader::NpdmHeader(const NpdmHeader & other)
|
||||
|
@ -42,23 +42,6 @@ size_t nx::NpdmHeader::getSize() const
|
|||
return mBinaryBlob.getSize();
|
||||
}
|
||||
|
||||
void nx::NpdmHeader::clearVariables()
|
||||
{
|
||||
mBinaryBlob.clear();
|
||||
mInstructionType = INSTR_64BIT;
|
||||
mProcAddressSpaceType = ADDR_SPACE_64BIT;
|
||||
mMainThreadPriority = 0;
|
||||
mMainThreadCoreNumber = 0;
|
||||
mVersion = 0;
|
||||
mMainThreadStackSize = 0;
|
||||
mName.clear();
|
||||
mProductCode.clear();
|
||||
mAciPos.offset = 0;
|
||||
mAciPos.size = 0;
|
||||
mAcidPos.offset = 0;
|
||||
mAcidPos.size = 0;
|
||||
}
|
||||
|
||||
void nx::NpdmHeader::calculateOffsets()
|
||||
{
|
||||
mAcidPos.offset = align(sizeof(sNpdmHeader), kNpdmAlignSize);
|
||||
|
@ -70,7 +53,7 @@ bool nx::NpdmHeader::isEqual(const NpdmHeader & other) const
|
|||
return (mInstructionType == other.mInstructionType) \
|
||||
&& (mProcAddressSpaceType == other.mProcAddressSpaceType) \
|
||||
&& (mMainThreadPriority == other.mMainThreadPriority) \
|
||||
&& (mMainThreadCoreNumber == other.mMainThreadCoreNumber) \
|
||||
&& (mMainThreadCpuId == other.mMainThreadCpuId) \
|
||||
&& (mVersion == other.mVersion) \
|
||||
&& (mMainThreadStackSize == other.mMainThreadStackSize) \
|
||||
&& (mName == other.mName) \
|
||||
|
@ -90,7 +73,7 @@ void nx::NpdmHeader::copyFrom(const NpdmHeader & other)
|
|||
mInstructionType = other.mInstructionType;
|
||||
mProcAddressSpaceType = other.mProcAddressSpaceType;
|
||||
mMainThreadPriority = other.mMainThreadPriority;
|
||||
mMainThreadCoreNumber = other.mMainThreadCoreNumber;
|
||||
mMainThreadCpuId = other.mMainThreadCpuId;
|
||||
mVersion = other.mVersion;
|
||||
mMainThreadStackSize = other.mMainThreadStackSize;
|
||||
mName = other.mName;
|
||||
|
@ -109,7 +92,7 @@ void nx::NpdmHeader::exportBinary()
|
|||
u8 flag = ((u8)(mInstructionType & 1) | (u8)((mProcAddressSpaceType & 3) << 1)) & 0xf;
|
||||
hdr->set_flags(flag);
|
||||
hdr->set_main_thread_priority(mMainThreadPriority);
|
||||
hdr->set_main_thread_core_number(mMainThreadCoreNumber);
|
||||
hdr->set_main_thread_cpu_id(mMainThreadCpuId);
|
||||
hdr->set_version(mVersion);
|
||||
hdr->set_main_thread_stack_size(mMainThreadStackSize);
|
||||
hdr->set_name(mName.c_str());
|
||||
|
@ -129,7 +112,7 @@ void nx::NpdmHeader::importBinary(const u8 * bytes, size_t len)
|
|||
throw fnd::Exception(kModuleName, "NPDM header too small");
|
||||
}
|
||||
|
||||
clearVariables();
|
||||
clear();
|
||||
|
||||
mBinaryBlob.alloc(sizeof(sNpdmHeader));
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
|
@ -144,11 +127,19 @@ void nx::NpdmHeader::importBinary(const u8 * bytes, size_t len)
|
|||
mInstructionType = (InstructionType)(flag & 1);
|
||||
mProcAddressSpaceType = (ProcAddrSpaceType)((flag >> 1) & 3);
|
||||
mMainThreadPriority = hdr->main_thread_priority();
|
||||
mMainThreadCoreNumber = hdr->main_thread_core_number();
|
||||
mMainThreadCpuId = hdr->main_thread_cpu_id();
|
||||
mVersion = hdr->version();
|
||||
mMainThreadStackSize = hdr->main_thread_stack_size();
|
||||
mName = std::string(hdr->name(), kNameMaxLen);
|
||||
if (mName[0] == '\0')
|
||||
{
|
||||
mName.clear();
|
||||
}
|
||||
mProductCode = std::string(hdr->product_code(), kProductCodeMaxLen);
|
||||
if (mProductCode[0] == '\0')
|
||||
{
|
||||
mProductCode.clear();
|
||||
}
|
||||
mAciPos.offset = hdr->aci().offset();
|
||||
mAciPos.size = hdr->aci().size();
|
||||
mAcidPos.offset = hdr->acid().offset();
|
||||
|
@ -157,7 +148,19 @@ void nx::NpdmHeader::importBinary(const u8 * bytes, size_t len)
|
|||
|
||||
void nx::NpdmHeader::clear()
|
||||
{
|
||||
clearVariables();
|
||||
mBinaryBlob.clear();
|
||||
mInstructionType = INSTR_64BIT;
|
||||
mProcAddressSpaceType = ADDR_SPACE_64BIT;
|
||||
mMainThreadPriority = 0;
|
||||
mMainThreadCpuId = 0;
|
||||
mVersion = 0;
|
||||
mMainThreadStackSize = 0;
|
||||
mName.clear();
|
||||
mProductCode.clear();
|
||||
mAciPos.offset = 0;
|
||||
mAciPos.size = 0;
|
||||
mAcidPos.offset = 0;
|
||||
mAcidPos.size = 0;
|
||||
}
|
||||
|
||||
size_t nx::NpdmHeader::getNpdmSize() const
|
||||
|
@ -200,14 +203,14 @@ void nx::NpdmHeader::setMainThreadPriority(u8 priority)
|
|||
mMainThreadPriority = priority;
|
||||
}
|
||||
|
||||
u8 nx::NpdmHeader::getMainThreadCoreNumber() const
|
||||
u8 nx::NpdmHeader::getMainThreadCpuId() const
|
||||
{
|
||||
return mMainThreadCoreNumber;
|
||||
return mMainThreadCpuId;
|
||||
}
|
||||
|
||||
void nx::NpdmHeader::setMainThreadCoreNumber(u8 core_num)
|
||||
void nx::NpdmHeader::setMainThreadCpuId(u8 core_num)
|
||||
{
|
||||
mMainThreadCoreNumber = core_num;
|
||||
mMainThreadCpuId = core_num;
|
||||
}
|
||||
|
||||
u32 nx::NpdmHeader::getVersion() const
|
||||
|
@ -265,7 +268,7 @@ const nx::NpdmHeader::sSection & nx::NpdmHeader::getAciPos() const
|
|||
return mAciPos;
|
||||
}
|
||||
|
||||
void nx::NpdmHeader::setSetAciSize(size_t size)
|
||||
void nx::NpdmHeader::setAciSize(size_t size)
|
||||
{
|
||||
mAciPos.size = size;
|
||||
}
|
||||
|
@ -275,7 +278,7 @@ const nx::NpdmHeader::sSection & nx::NpdmHeader::getAcidPos() const
|
|||
return mAcidPos;
|
||||
}
|
||||
|
||||
void nx::NpdmHeader::setSetAcidSize(size_t size)
|
||||
void nx::NpdmHeader::setAcidSize(size_t size)
|
||||
{
|
||||
mAcidPos.size = size;
|
||||
}
|
||||
|
|
|
@ -76,8 +76,8 @@ namespace nx
|
|||
u8 getMainThreadPriority() const;
|
||||
void setMainThreadPriority(u8 priority);
|
||||
|
||||
u8 getMainThreadCoreNumber() const;
|
||||
void setMainThreadCoreNumber(u8 core_num);
|
||||
u8 getMainThreadCpuId() const;
|
||||
void setMainThreadCpuId(u8 cpu_id);
|
||||
|
||||
u32 getVersion() const;
|
||||
void setVersion(u32 version);
|
||||
|
@ -92,10 +92,10 @@ namespace nx
|
|||
void setProductCode(const std::string& product_code);
|
||||
|
||||
const sSection& getAciPos() const;
|
||||
void setSetAciSize(size_t size);
|
||||
void setAciSize(size_t size);
|
||||
|
||||
const sSection& getAcidPos() const;
|
||||
void setSetAcidSize(size_t size);
|
||||
void setAcidSize(size_t size);
|
||||
private:
|
||||
const std::string kModuleName = "NPDM_HEADER";
|
||||
const std::string kNpdmStructSig = "META";
|
||||
|
@ -114,7 +114,7 @@ namespace nx
|
|||
u8 flags_;
|
||||
u8 reserved_1;
|
||||
u8 main_thread_priority_; // 0-63 inclusive
|
||||
u8 main_thread_core_number_;
|
||||
u8 main_thread_cpu_id_;
|
||||
u8 reserved_2[8];
|
||||
u32 version_;
|
||||
u32 main_thread_stack_size_; // default 4096
|
||||
|
@ -144,8 +144,8 @@ namespace nx
|
|||
u8 main_thread_priority() const { return main_thread_priority_; }
|
||||
void set_main_thread_priority(u8 priority) { main_thread_priority_ = priority; }
|
||||
|
||||
u8 main_thread_core_number() const { return main_thread_core_number_; }
|
||||
void set_main_thread_core_number(u8 core_number) { main_thread_core_number_ = core_number; }
|
||||
u8 main_thread_cpu_id() const { return main_thread_cpu_id_; }
|
||||
void set_main_thread_cpu_id(u8 cpu_id) { main_thread_cpu_id_ = cpu_id; }
|
||||
|
||||
u32 version() const { return le_word(version_); }
|
||||
void set_version(u32 version) { version_ = le_word(version); }
|
||||
|
@ -174,7 +174,7 @@ namespace nx
|
|||
InstructionType mInstructionType;
|
||||
ProcAddrSpaceType mProcAddressSpaceType;
|
||||
u8 mMainThreadPriority;
|
||||
u8 mMainThreadCoreNumber;
|
||||
u8 mMainThreadCpuId;
|
||||
u32 mVersion;
|
||||
u32 mMainThreadStackSize;
|
||||
std::string mName;
|
||||
|
@ -182,7 +182,6 @@ namespace nx
|
|||
sSection mAciPos;
|
||||
sSection mAcidPos;
|
||||
|
||||
void clearVariables();
|
||||
void calculateOffsets();
|
||||
bool isEqual(const NpdmHeader& other) const;
|
||||
void copyFrom(const NpdmHeader& other);
|
||||
|
|
|
@ -59,7 +59,7 @@ void SacBinary::exportBinary()
|
|||
|
||||
void SacBinary::importBinary(const u8 * bytes, size_t len)
|
||||
{
|
||||
clearVariables();
|
||||
clear();
|
||||
mBinaryBlob.alloc(len);
|
||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||
|
||||
|
@ -73,7 +73,8 @@ void SacBinary::importBinary(const u8 * bytes, size_t len)
|
|||
|
||||
void nx::SacBinary::clear()
|
||||
{
|
||||
clearVariables();
|
||||
mBinaryBlob.clear();
|
||||
mServices.clear();
|
||||
}
|
||||
|
||||
const fnd::List<SacEntry>& SacBinary::getServiceList() const
|
||||
|
@ -86,12 +87,6 @@ void SacBinary::addService(const SacEntry& service)
|
|||
mServices.addElement(service);
|
||||
}
|
||||
|
||||
void SacBinary::clearVariables()
|
||||
{
|
||||
mBinaryBlob.clear();
|
||||
mServices.clear();
|
||||
}
|
||||
|
||||
bool SacBinary::isEqual(const SacBinary & other) const
|
||||
{
|
||||
return mServices == other.mServices;
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace nx
|
|||
// variables
|
||||
fnd::List<SacEntry> mServices;
|
||||
|
||||
void clearVariables();
|
||||
bool isEqual(const SacBinary& other) const;
|
||||
void copyFrom(const SacBinary& other);
|
||||
};
|
||||
|
|
|
@ -6,16 +6,16 @@ nx::ThreadInfoEntry::ThreadInfoEntry() :
|
|||
mCap(kCapId),
|
||||
mMinPriority(kDefaultPriority),
|
||||
mMaxPriority(kDefaultPriority),
|
||||
mMinCoreNumber(kDefaultCoreNumber),
|
||||
mMaxCoreNumber(kDefaultCoreNumber)
|
||||
mMinCpuId(kDefaultCpuId),
|
||||
mMaxCpuId(kDefaultCpuId)
|
||||
{}
|
||||
|
||||
nx::ThreadInfoEntry::ThreadInfoEntry(const KernelCapability & kernel_cap) :
|
||||
mCap(kCapId),
|
||||
mMinPriority(kDefaultPriority),
|
||||
mMaxPriority(kDefaultPriority),
|
||||
mMinCoreNumber(kDefaultCoreNumber),
|
||||
mMaxCoreNumber(kDefaultCoreNumber)
|
||||
mMinCpuId(kDefaultCpuId),
|
||||
mMaxCpuId(kDefaultCpuId)
|
||||
{
|
||||
setKernelCapability(kernel_cap);
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ nx::ThreadInfoEntry::ThreadInfoEntry(u8 min_priority, u8 max_priority, u8 min_co
|
|||
mCap(kCapId),
|
||||
mMinPriority(kDefaultPriority),
|
||||
mMaxPriority(kDefaultPriority),
|
||||
mMinCoreNumber(kDefaultCoreNumber),
|
||||
mMaxCoreNumber(kDefaultCoreNumber)
|
||||
mMinCpuId(kDefaultCpuId),
|
||||
mMaxCpuId(kDefaultCpuId)
|
||||
{
|
||||
setMinPriority(min_priority);
|
||||
setMaxPriority(max_priority);
|
||||
setMinCoreNumber(min_core_number);
|
||||
setMaxCoreNumber(max_core_number);
|
||||
setMinCpuId(min_core_number);
|
||||
setMaxCpuId(max_core_number);
|
||||
}
|
||||
|
||||
const nx::KernelCapability & nx::ThreadInfoEntry::getKernelCapability() const
|
||||
|
@ -81,34 +81,34 @@ void nx::ThreadInfoEntry::setMaxPriority(u8 priority)
|
|||
updateCapField();
|
||||
}
|
||||
|
||||
u8 nx::ThreadInfoEntry::getMinCoreNumber() const
|
||||
u8 nx::ThreadInfoEntry::getMinCpuId() const
|
||||
{
|
||||
return mMinCoreNumber;
|
||||
return mMinCpuId;
|
||||
}
|
||||
|
||||
void nx::ThreadInfoEntry::setMinCoreNumber(u8 core_num)
|
||||
void nx::ThreadInfoEntry::setMinCpuId(u8 core_num)
|
||||
{
|
||||
if (core_num > kMaxVal)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Illegal MinCoreNumber (range 0-63)");
|
||||
}
|
||||
|
||||
mMinCoreNumber = core_num;
|
||||
mMinCpuId = core_num;
|
||||
updateCapField();
|
||||
}
|
||||
|
||||
u8 nx::ThreadInfoEntry::getMaxCoreNumber() const
|
||||
u8 nx::ThreadInfoEntry::getMaxCpuId() const
|
||||
{
|
||||
return mMaxCoreNumber;
|
||||
return mMaxCpuId;
|
||||
}
|
||||
|
||||
void nx::ThreadInfoEntry::setMaxCoreNumber(u8 core_num)
|
||||
void nx::ThreadInfoEntry::setMaxCpuId(u8 core_num)
|
||||
{
|
||||
if (core_num > kMaxVal)
|
||||
{
|
||||
throw fnd::Exception(kModuleName, "Illegal MaxCoreNumber (range 0-63)");
|
||||
}
|
||||
|
||||
mMaxCoreNumber = core_num;
|
||||
mMaxCpuId = core_num;
|
||||
updateCapField();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace nx
|
|||
public:
|
||||
ThreadInfoEntry();
|
||||
ThreadInfoEntry(const KernelCapability& kernel_cap);
|
||||
ThreadInfoEntry(u8 min_priority, u8 max_priority, u8 min_core_number, u8 max_core_number);
|
||||
ThreadInfoEntry(u8 min_priority, u8 max_priority, u8 min_cpu_id, u8 max_cpu_id);
|
||||
|
||||
// kernel capability
|
||||
const KernelCapability& getKernelCapability() const;
|
||||
|
@ -21,10 +21,10 @@ namespace nx
|
|||
void setMinPriority(u8 priority);
|
||||
u8 getMaxPriority() const;
|
||||
void setMaxPriority(u8 priority);
|
||||
u8 getMinCoreNumber() const;
|
||||
void setMinCoreNumber(u8 core_num);
|
||||
u8 getMaxCoreNumber() const;
|
||||
void setMaxCoreNumber(u8 core_num);
|
||||
u8 getMinCpuId() const;
|
||||
void setMinCpuId(u8 cpu_id);
|
||||
u8 getMaxCpuId() const;
|
||||
void setMaxCpuId(u8 cpu_id);
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "THREAD_INFO_ENTRY";
|
||||
|
@ -32,21 +32,21 @@ namespace nx
|
|||
static const u8 kValBits = 6;
|
||||
static const u8 kMaxVal = BIT(kValBits)-1;
|
||||
static const u8 kDefaultPriority = 6;
|
||||
static const u8 kDefaultCoreNumber = 8;
|
||||
static const u8 kDefaultCpuId = 8;
|
||||
|
||||
KernelCapability mCap;
|
||||
u8 mMinPriority;
|
||||
u8 mMaxPriority;
|
||||
u8 mMinCoreNumber;
|
||||
u8 mMaxCoreNumber;
|
||||
u8 mMinCpuId;
|
||||
u8 mMaxCpuId;
|
||||
|
||||
inline void updateCapField()
|
||||
{
|
||||
u32 field = 0;
|
||||
field |= (u32)(mMinPriority & kMaxVal) << (kValBits * 0);
|
||||
field |= (u32)(mMaxPriority & kMaxVal) << (kValBits * 1);
|
||||
field |= (u32)(mMinCoreNumber & kMaxVal) << (kValBits * 2);
|
||||
field |= (u32)(mMaxCoreNumber & kMaxVal) << (kValBits * 3);
|
||||
field |= (u32)(mMinCpuId & kMaxVal) << (kValBits * 2);
|
||||
field |= (u32)(mMaxCpuId & kMaxVal) << (kValBits * 3);
|
||||
mCap.setField(field);
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,8 @@ namespace nx
|
|||
u32 field = mCap.getField();
|
||||
mMinPriority = (field >> (kValBits * 0)) & kMaxVal;
|
||||
mMaxPriority = (field >> (kValBits * 1)) & kMaxVal;
|
||||
mMinCoreNumber = (field >> (kValBits * 2)) & kMaxVal;
|
||||
mMaxCoreNumber = (field >> (kValBits * 3)) & kMaxVal;
|
||||
mMinCpuId = (field >> (kValBits * 2)) & kMaxVal;
|
||||
mMaxCpuId = (field >> (kValBits * 3)) & kMaxVal;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ void nx::ThreadInfoHandler::clear()
|
|||
mIsSet = false;
|
||||
mEntry.setMaxPriority(0);
|
||||
mEntry.setMinPriority(0);
|
||||
mEntry.setMaxCoreNumber(0);
|
||||
mEntry.setMinCoreNumber(0);
|
||||
mEntry.setMaxCpuId(0);
|
||||
mEntry.setMinCpuId(0);
|
||||
}
|
||||
|
||||
bool nx::ThreadInfoHandler::isSet() const
|
||||
|
@ -80,25 +80,25 @@ void nx::ThreadInfoHandler::setMaxPriority(u8 priority)
|
|||
mIsSet = true;
|
||||
}
|
||||
|
||||
u8 nx::ThreadInfoHandler::getMinCoreNumber() const
|
||||
u8 nx::ThreadInfoHandler::getMinCpuId() const
|
||||
{
|
||||
return mEntry.getMinCoreNumber();
|
||||
return mEntry.getMinCpuId();
|
||||
}
|
||||
|
||||
void nx::ThreadInfoHandler::setMinCoreNumber(u8 core_num)
|
||||
void nx::ThreadInfoHandler::setMinCpuId(u8 core_num)
|
||||
{
|
||||
mEntry.setMinCoreNumber(core_num);
|
||||
mEntry.setMinCpuId(core_num);
|
||||
mIsSet = true;
|
||||
}
|
||||
|
||||
u8 nx::ThreadInfoHandler::getMaxCoreNumber() const
|
||||
u8 nx::ThreadInfoHandler::getMaxCpuId() const
|
||||
{
|
||||
return mEntry.getMaxCoreNumber();
|
||||
return mEntry.getMaxCpuId();
|
||||
}
|
||||
|
||||
void nx::ThreadInfoHandler::setMaxCoreNumber(u8 core_num)
|
||||
void nx::ThreadInfoHandler::setMaxCpuId(u8 core_num)
|
||||
{
|
||||
mEntry.setMaxCoreNumber(core_num);
|
||||
mEntry.setMaxCpuId(core_num);
|
||||
mIsSet = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ namespace nx
|
|||
void setMinPriority(u8 priority);
|
||||
u8 getMaxPriority() const;
|
||||
void setMaxPriority(u8 priority);
|
||||
u8 getMinCoreNumber() const;
|
||||
void setMinCoreNumber(u8 core_num);
|
||||
u8 getMaxCoreNumber() const;
|
||||
void setMaxCoreNumber(u8 core_num);
|
||||
u8 getMinCpuId() const;
|
||||
void setMinCpuId(u8 core_num);
|
||||
u8 getMaxCpuId() const;
|
||||
void setMaxCpuId(u8 core_num);
|
||||
|
||||
private:
|
||||
const std::string kModuleName = "THREAD_INFO_HANDLER";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AciBinary.h" />
|
||||
<ClInclude Include="AcidBinary.h" />
|
||||
<ClInclude Include="AciHeader.h" />
|
||||
<ClInclude Include="FacBinary.h" />
|
||||
<ClInclude Include="FacHeader.h" />
|
||||
|
@ -39,6 +40,7 @@
|
|||
<ClInclude Include="MiscFlagsHandler.h" />
|
||||
<ClInclude Include="MiscParamsEntry.h" />
|
||||
<ClInclude Include="MiscParamsHandler.h" />
|
||||
<ClInclude Include="NpdmBinary.h" />
|
||||
<ClInclude Include="NpdmHeader.h" />
|
||||
<ClInclude Include="NcaHeader.h" />
|
||||
<ClInclude Include="NXCrypto.h" />
|
||||
|
@ -51,6 +53,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AciBinary.cpp" />
|
||||
<ClCompile Include="AcidBinary.cpp" />
|
||||
<ClCompile Include="AciHeader.cpp" />
|
||||
<ClCompile Include="FacBinary.cpp" />
|
||||
<ClCompile Include="FacHeader.cpp" />
|
||||
|
@ -68,6 +71,7 @@
|
|||
<ClCompile Include="MiscFlagsHandler.cpp" />
|
||||
<ClCompile Include="MiscParamsEntry.cpp" />
|
||||
<ClCompile Include="MiscParamsHandler.cpp" />
|
||||
<ClCompile Include="NpdmBinary.cpp" />
|
||||
<ClCompile Include="NpdmHeader.cpp" />
|
||||
<ClCompile Include="NcaHeader.cpp" />
|
||||
<ClCompile Include="SacBinary.cpp" />
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
<ClInclude Include="FacHeader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FacBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SacBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -102,6 +99,15 @@
|
|||
<ClInclude Include="KcBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AcidBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FacBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NpdmBinary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="NcaHeader.cpp">
|
||||
|
@ -116,9 +122,6 @@
|
|||
<ClCompile Include="FacHeader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FacBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SacBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -182,5 +185,14 @@
|
|||
<ClCompile Include="KcBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AcidBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FacBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NpdmBinary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in a new issue