diff --git a/lib/nx/AciBinary.cpp b/lib/nx/AciBinary.cpp index 177512f..7b73205 100644 --- a/lib/nx/AciBinary.cpp +++ b/lib/nx/AciBinary.cpp @@ -3,7 +3,9 @@ nx::AciBinary::AciBinary() -{} +{ + clear(); +} nx::AciBinary::AciBinary(const AciBinary & other) { diff --git a/lib/nx/AciHeader.cpp b/lib/nx/AciHeader.cpp index bc52c6c..38ec15a 100644 --- a/lib/nx/AciHeader.cpp +++ b/lib/nx/AciHeader.cpp @@ -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; } diff --git a/lib/nx/AciHeader.h b/lib/nx/AciHeader.h index 5b76642..2dad344 100644 --- a/lib/nx/AciHeader.h +++ b/lib/nx/AciHeader.h @@ -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); diff --git a/lib/nx/AcidBinary.cpp b/lib/nx/AcidBinary.cpp new file mode 100644 index 0000000..f7f3432 --- /dev/null +++ b/lib/nx/AcidBinary.cpp @@ -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"); + } +} diff --git a/lib/nx/AcidBinary.h b/lib/nx/AcidBinary.h new file mode 100644 index 0000000..5ee1c1f --- /dev/null +++ b/lib/nx/AcidBinary.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include +#include +#include +#include + +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); + }; +} + diff --git a/lib/nx/FacBinary.cpp b/lib/nx/FacBinary.cpp index 778a546..d6a4f1d 100644 --- a/lib/nx/FacBinary.cpp +++ b/lib/nx/FacBinary.cpp @@ -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& FacBinary::getContentOwnerIds() const -{ - return mContentOwnerIds; -} - -void FacBinary::addContentOwnerId(u32 id) -{ - mContentOwnerIds.addElement(id); -} - -const fnd::List& 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& nx::FacBinary::getContentOwnerIdList() const +{ + return mContentOwnerIdList; +} + +void nx::FacBinary::setContentOwnerIdList(const fnd::List& list) +{ + mContentOwnerIdList = list; +} + +const fnd::List& nx::FacBinary::getSaveDataOwnerIdList() const +{ + return mSaveDataOwnerIdList; +} + +void nx::FacBinary::setSaveDataOwnerIdList(const fnd::List& list) +{ + mSaveDataOwnerIdList = list; +} diff --git a/lib/nx/FacBinary.h b/lib/nx/FacBinary.h index e15af88..a1ee9dd 100644 --- a/lib/nx/FacBinary.h +++ b/lib/nx/FacBinary.h @@ -5,38 +5,13 @@ #include #include + 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& getContentOwnerIds() const; - void addContentOwnerId(u32 id); + const fnd::List& getContentOwnerIdList() const; + void setContentOwnerIdList(const fnd::List& list); + + const fnd::List& getSaveDataOwnerIdList() const; + void setSaveDataOwnerIdList(const fnd::List& list); - const fnd::List& 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 mContentOwnerIds; - fnd::List mSaveDataOwnerIds; + fnd::List mContentOwnerIdList; + fnd::List mSaveDataOwnerIdList; - void clearVariables(); bool isEqual(const FacBinary& other) const; void copyFrom(const FacBinary& other); }; diff --git a/lib/nx/FacHeader.cpp b/lib/nx/FacHeader.cpp index e9f11aa..85d1660 100644 --- a/lib/nx/FacHeader.cpp +++ b/lib/nx/FacHeader.cpp @@ -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::getFsaRightsList() const { return mFsaRights; } -void nx::FacHeader::setFsaRights(u64 flag) +void nx::FacHeader::setFsaRightsList(const fnd::List& 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); diff --git a/lib/nx/FacHeader.h b/lib/nx/FacHeader.h index 5ffed50..1795b8c 100644 --- a/lib/nx/FacHeader.h +++ b/lib/nx/FacHeader.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include 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& getFsaRightsList() const; + void setFsaRightsList(const fnd::List& 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 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); diff --git a/lib/nx/KcBinary.cpp b/lib/nx/KcBinary.cpp index 45993d6..b0e932d 100644 --- a/lib/nx/KcBinary.cpp +++ b/lib/nx/KcBinary.cpp @@ -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) \ diff --git a/lib/nx/NcaHeader.cpp b/lib/nx/NcaHeader.cpp index 426d306..55dbd17 100644 --- a/lib/nx/NcaHeader.cpp +++ b/lib/nx/NcaHeader.cpp @@ -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) diff --git a/lib/nx/NcaHeader.h b/lib/nx/NcaHeader.h index e8c22de..bc62fff 100644 --- a/lib/nx/NcaHeader.h +++ b/lib/nx/NcaHeader.h @@ -149,7 +149,6 @@ namespace nx fnd::List mSections; fnd::List mAesKeys; - void clearVariables(); u64 blockNumToSize(u32 block_num) const; u32 sizeToBlockNum(u64 real_size) const; bool isEqual(const NcaHeader& other) const; diff --git a/lib/nx/NpdmBinary.cpp b/lib/nx/NpdmBinary.cpp new file mode 100644 index 0000000..43380eb --- /dev/null +++ b/lib/nx/NpdmBinary.cpp @@ -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(); +} diff --git a/lib/nx/NpdmBinary.h b/lib/nx/NpdmBinary.h new file mode 100644 index 0000000..9358455 --- /dev/null +++ b/lib/nx/NpdmBinary.h @@ -0,0 +1,55 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + + +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); + }; + +} diff --git a/lib/nx/NpdmHeader.cpp b/lib/nx/NpdmHeader.cpp index c1e56e5..d5f73dc 100644 --- a/lib/nx/NpdmHeader.cpp +++ b/lib/nx/NpdmHeader.cpp @@ -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; } diff --git a/lib/nx/NpdmHeader.h b/lib/nx/NpdmHeader.h index 2b49249..588fb83 100644 --- a/lib/nx/NpdmHeader.h +++ b/lib/nx/NpdmHeader.h @@ -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); diff --git a/lib/nx/SacBinary.cpp b/lib/nx/SacBinary.cpp index 5f3170b..5cab445 100644 --- a/lib/nx/SacBinary.cpp +++ b/lib/nx/SacBinary.cpp @@ -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& 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; diff --git a/lib/nx/SacBinary.h b/lib/nx/SacBinary.h index 4fd3a5b..f19b6e6 100644 --- a/lib/nx/SacBinary.h +++ b/lib/nx/SacBinary.h @@ -41,7 +41,6 @@ namespace nx // variables fnd::List mServices; - void clearVariables(); bool isEqual(const SacBinary& other) const; void copyFrom(const SacBinary& other); }; diff --git a/lib/nx/ThreadInfoEntry.cpp b/lib/nx/ThreadInfoEntry.cpp index 09f8f3d..fdddb95 100644 --- a/lib/nx/ThreadInfoEntry.cpp +++ b/lib/nx/ThreadInfoEntry.cpp @@ -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(); } diff --git a/lib/nx/ThreadInfoEntry.h b/lib/nx/ThreadInfoEntry.h index de0c349..98f5b4f 100644 --- a/lib/nx/ThreadInfoEntry.h +++ b/lib/nx/ThreadInfoEntry.h @@ -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; } }; } diff --git a/lib/nx/ThreadInfoHandler.cpp b/lib/nx/ThreadInfoHandler.cpp index 345397f..43e8983 100644 --- a/lib/nx/ThreadInfoHandler.cpp +++ b/lib/nx/ThreadInfoHandler.cpp @@ -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; } diff --git a/lib/nx/ThreadInfoHandler.h b/lib/nx/ThreadInfoHandler.h index c8381ae..ab451ce 100644 --- a/lib/nx/ThreadInfoHandler.h +++ b/lib/nx/ThreadInfoHandler.h @@ -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"; diff --git a/lib/nx/nx.vcxproj b/lib/nx/nx.vcxproj index 3da5155..5d75860 100644 --- a/lib/nx/nx.vcxproj +++ b/lib/nx/nx.vcxproj @@ -20,6 +20,7 @@ + @@ -39,6 +40,7 @@ + @@ -51,6 +53,7 @@ + @@ -68,6 +71,7 @@ + diff --git a/lib/nx/nx.vcxproj.filters b/lib/nx/nx.vcxproj.filters index 0907bee..0785a9e 100644 --- a/lib/nx/nx.vcxproj.filters +++ b/lib/nx/nx.vcxproj.filters @@ -33,9 +33,6 @@ Header Files - - Header Files - Header Files @@ -102,6 +99,15 @@ Header Files + + Header Files + + + Header Files + + + Header Files + @@ -116,9 +122,6 @@ Source Files - - Source Files - Source Files @@ -182,5 +185,14 @@ Source Files + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file