diff --git a/lib/libnx/include/nx/FacBinary.h b/lib/libnx/include/nx/FacBinary.h index bba22a6..1d38e23 100644 --- a/lib/libnx/include/nx/FacBinary.h +++ b/lib/libnx/include/nx/FacBinary.h @@ -1,13 +1,13 @@ #pragma once #include +#include #include -#include - +#include namespace nx { class FacBinary : - public FacHeader + public fnd::ISerialisable { public: FacBinary(); @@ -25,6 +25,9 @@ namespace nx // variables void clear(); + const fnd::List& getFsaRightsList() const; + void setFsaRightsList(const fnd::List& list); + const fnd::List& getContentOwnerIdList() const; void setContentOwnerIdList(const fnd::List& list); @@ -33,12 +36,12 @@ namespace nx private: const std::string kModuleName = "FAC_BINARY"; - static const uint32_t kFacFormatVersion = 1; // raw binary fnd::Vec mRawBinary; // variables + fnd::List mFsaRights; fnd::List mContentOwnerIdList; fnd::List mSaveDataOwnerIdList; }; diff --git a/lib/libnx/source/FacBinary.cpp b/lib/libnx/source/FacBinary.cpp index b557d4c..f2f68db 100644 --- a/lib/libnx/source/FacBinary.cpp +++ b/lib/libnx/source/FacBinary.cpp @@ -1,4 +1,5 @@ #include +#include nx::FacBinary::FacBinary() { @@ -19,7 +20,7 @@ void nx::FacBinary::operator=(const FacBinary & other) else { clear(); - FacHeader::operator=(other); + mFsaRights = other.mFsaRights; mContentOwnerIdList = other.mContentOwnerIdList; mSaveDataOwnerIdList = other.mSaveDataOwnerIdList; } @@ -27,7 +28,7 @@ void nx::FacBinary::operator=(const FacBinary & other) bool nx::FacBinary::operator==(const FacBinary & other) const { - return (FacHeader::operator==(other)) \ + return (mFsaRights == other.mFsaRights) \ && (mContentOwnerIdList == other.mContentOwnerIdList) \ && (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList); } @@ -39,20 +40,24 @@ bool nx::FacBinary::operator!=(const FacBinary & other) const void nx::FacBinary::toBytes() { - FacHeader::setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t)); - FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t)); - FacHeader::toBytes(); + FacHeader hdr; - mRawBinary.alloc(getFacSize()); - memcpy(mRawBinary.data(), FacHeader::getBytes().data(), FacHeader::getBytes().size()); + hdr.setFormatVersion(fac::kFacFormatVersion); + hdr.setFsaRightsList(mFsaRights); + hdr.setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t)); + hdr.setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t)); + hdr.toBytes(); - uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset); + mRawBinary.alloc(hdr.getFacSize()); + memcpy(mRawBinary.data(), hdr.getBytes().data(), hdr.getBytes().size()); + + uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getContentOwnerIdPos().offset); for (size_t i = 0; i < mContentOwnerIdList.size(); i++) { rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]); } - uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset); + uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getSaveDataOwnerIdPos().offset); for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++) { rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]); @@ -62,24 +67,29 @@ void nx::FacBinary::toBytes() void nx::FacBinary::fromBytes(const byte_t* data, size_t len) { clear(); - FacHeader::fromBytes(data, len); - if (FacHeader::getFacSize() > len) + + FacHeader hdr; + hdr.fromBytes(data, len); + + mFsaRights = hdr.getFsaRightsList(); + + if (hdr.getFacSize() > len) { throw fnd::Exception(kModuleName, "FAC binary too small"); } - mRawBinary.alloc(FacHeader::getFacSize()); + mRawBinary.alloc(hdr.getFacSize()); memcpy(mRawBinary.data(), data, mRawBinary.size()); - uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getContentOwnerIdPos().offset); - size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdPos().size / sizeof(uint32_t); + uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getContentOwnerIdPos().offset); + size_t rawContentOwnerIdNum = hdr.getContentOwnerIdPos().size / sizeof(uint32_t); for (size_t i = 0; i < rawContentOwnerIdNum; i++) { mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i])); } - uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::getSaveDataOwnerIdPos().offset); - size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdPos().size / sizeof(uint32_t); + uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + hdr.getSaveDataOwnerIdPos().offset); + size_t rawSaveDataOwnerIdNum = hdr.getSaveDataOwnerIdPos().size / sizeof(uint32_t); for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++) { mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i])); @@ -93,12 +103,25 @@ const fnd::Vec& nx::FacBinary::getBytes() const void nx::FacBinary::clear() { - FacHeader::clear(); mRawBinary.clear(); mContentOwnerIdList.clear(); mSaveDataOwnerIdList.clear(); } +const fnd::List& nx::FacBinary::getFsaRightsList() const +{ + return mFsaRights; +} + +void nx::FacBinary::setFsaRightsList(const fnd::List& list) +{ + mFsaRights.clear(); + for (size_t i = 0; i < list.size(); i++) + { + mFsaRights.hasElement(list[i]) ? mFsaRights.addElement(list[i]) : throw fnd::Exception(kModuleName, "FSA right already exists"); + } +} + const fnd::List& nx::FacBinary::getContentOwnerIdList() const { return mContentOwnerIdList; diff --git a/programs/nstool/source/NpdmProcess.cpp b/programs/nstool/source/NpdmProcess.cpp index f727a75..f003a72 100644 --- a/programs/nstool/source/NpdmProcess.cpp +++ b/programs/nstool/source/NpdmProcess.cpp @@ -316,12 +316,6 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi printf("[WARNING] ACI ProgramId: FAIL (Outside Legal Range)\n"); } - // Check FAC - if (aci.getFac().getFormatVersion() != acid.getFac().getFormatVersion()) - { - printf("[WARNING] ACI/FAC FormatVersion: FAIL (%d != %d (expected))\n", aci.getFac().getFormatVersion(),acid.getFac().getFormatVersion()); - } - for (size_t i = 0; i < aci.getFac().getFsaRightsList().size(); i++) { bool fsaRightFound = false; @@ -382,7 +376,6 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi if (rightFound == false) { - printf("[WARNING] ACI/SAC ServiceList: FAIL (%s%s not permitted)\n", aci.getSac().getServiceList()[i].getName().c_str(), aci.getSac().getServiceList()[i].isServer()? " (Server)" : ""); } } @@ -391,19 +384,19 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi // check thread info if (aci.getKc().getThreadInfo().getMaxCpuId() != acid.getKc().getThreadInfo().getMaxCpuId()) { - printf("[WARNING] ACI/KC ThreadInfo/MaxCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxCpuId()); + printf("[WARNING] ACI/KC ThreadInfo/MaxCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxCpuId()); } if (aci.getKc().getThreadInfo().getMinCpuId() != acid.getKc().getThreadInfo().getMinCpuId()) { - printf("[WARNING] ACI/KC ThreadInfo/MinCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinCpuId()); + printf("[WARNING] ACI/KC ThreadInfo/MinCpuId: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinCpuId()); } if (aci.getKc().getThreadInfo().getMaxPriority() != acid.getKc().getThreadInfo().getMaxPriority()) { - printf("[WARNING] ACI/KC ThreadInfo/MaxPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxPriority()); + printf("[WARNING] ACI/KC ThreadInfo/MaxPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMaxPriority()); } if (aci.getKc().getThreadInfo().getMinPriority() != acid.getKc().getThreadInfo().getMinPriority()) { - printf("[WARNING] ACI/KC ThreadInfo/MinPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinPriority()); + printf("[WARNING] ACI/KC ThreadInfo/MinPriority: FAIL (%d not permitted)\n", aci.getKc().getThreadInfo().getMinPriority()); } // check system calls for (size_t i = 0; i < aci.getKc().getSystemCalls().getSystemCalls().size(); i++) @@ -417,7 +410,6 @@ void NpdmProcess::validateAciFromAcid(const nx::AciBinary& aci, const nx::AcidBi if (rightFound == false) { - printf("[WARNING] ACI/KC SystemCallList: FAIL (%s not permitted)\n", kSysCall[aci.getKc().getSystemCalls().getSystemCalls()[i]].c_str()); } } @@ -547,7 +539,6 @@ void NpdmProcess::displayAciHdr(const nx::AciHeader& aci) void NpdmProcess::displayFac(const nx::FacBinary& fac) { printf("[FS Access Control]\n"); - printf(" Format Version: %d\n", fac.getFormatVersion()); if (fac.getFsaRightsList().size()) {