From efe0655f05093a5fdc1414196ef4772bcfc9d103 Mon Sep 17 00:00:00 2001 From: jakcron Date: Fri, 29 Jun 2018 00:20:56 +0800 Subject: [PATCH] [nx|nstool] Replace FacHeader & FacBinary --- .../include/nx/AccessControlInfoBinary.h | 8 +- .../include/nx/AccessControlInfoDescBinary.h | 12 +- lib/libnx/include/nx/FacHeader.h | 77 ------- ...nary.h => FileSystemAccessControlBinary.h} | 29 +-- lib/libnx/include/nx/fac.h | 1 + lib/libnx/source/AccessControlInfoBinary.cpp | 4 +- .../source/AccessControlInfoDescBinary.cpp | 4 +- lib/libnx/source/FacBinary.cpp | 150 ------------- lib/libnx/source/FacHeader.cpp | 166 -------------- .../source/FileSystemAccessControlBinary.cpp | 205 ++++++++++++++++++ programs/nstool/source/NpdmProcess.cpp | 10 +- programs/nstool/source/NpdmProcess.h | 2 +- 12 files changed, 245 insertions(+), 423 deletions(-) delete mode 100644 lib/libnx/include/nx/FacHeader.h rename lib/libnx/include/nx/{FacBinary.h => FileSystemAccessControlBinary.h} (56%) delete mode 100644 lib/libnx/source/FacBinary.cpp delete mode 100644 lib/libnx/source/FacHeader.cpp create mode 100644 lib/libnx/source/FileSystemAccessControlBinary.cpp diff --git a/lib/libnx/include/nx/AccessControlInfoBinary.h b/lib/libnx/include/nx/AccessControlInfoBinary.h index 3eedace..9743374 100644 --- a/lib/libnx/include/nx/AccessControlInfoBinary.h +++ b/lib/libnx/include/nx/AccessControlInfoBinary.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -30,8 +30,8 @@ namespace nx uint64_t getProgramId() const; void setProgramId(uint64_t program_id); - const nx::FacBinary& getFileSystemAccessControl() const; - void setFileSystemAccessControl(const FacBinary& fac); + const nx::FileSystemAccessControlBinary& getFileSystemAccessControl() const; + void setFileSystemAccessControl(const FileSystemAccessControlBinary& fac); const nx::SacBinary& getServiceAccessControl() const; void setServiceAccessControl(const SacBinary& sac); @@ -46,7 +46,7 @@ namespace nx // variables uint64_t mProgramId; - nx::FacBinary mFileSystemAccessControl; + nx::FileSystemAccessControlBinary mFileSystemAccessControl; nx::SacBinary mServiceAccessControl; nx::KcBinary mKernelCapabilities; }; diff --git a/lib/libnx/include/nx/AccessControlInfoDescBinary.h b/lib/libnx/include/nx/AccessControlInfoDescBinary.h index 362bb22..dc72356 100644 --- a/lib/libnx/include/nx/AccessControlInfoDescBinary.h +++ b/lib/libnx/include/nx/AccessControlInfoDescBinary.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -63,13 +63,13 @@ namespace nx const sProgramIdRestrict& getProgramIdRestrict() const; void setProgramIdRestrict(const sProgramIdRestrict& pid_restrict); - const FacBinary& getFileSystemAccessControl() const; - void setFileSystemAccessControl(const FacBinary& fac); + const nx::FileSystemAccessControlBinary& getFileSystemAccessControl() const; + void setFileSystemAccessControl(const FileSystemAccessControlBinary& fac); - const SacBinary& getServiceAccessControl() const; + const nx::SacBinary& getServiceAccessControl() const; void setServiceAccessControl(const SacBinary& sac); - const KcBinary& getKernelCapabilities() const; + const nx::KcBinary& getKernelCapabilities() const; void setKernelCapabilities(const KcBinary& kc); private: const std::string kModuleName = "ACCESS_CONTROL_INFO_DESC_BINARY"; @@ -81,7 +81,7 @@ namespace nx crypto::rsa::sRsa2048Key mNcaHeaderSignature2Key; fnd::List mFlags; sProgramIdRestrict mProgramIdRestrict; - nx::FacBinary mFileSystemAccessControl; + nx::FileSystemAccessControlBinary mFileSystemAccessControl; nx::SacBinary mServiceAccessControl; nx::KcBinary mKernelCapabilities; }; diff --git a/lib/libnx/include/nx/FacHeader.h b/lib/libnx/include/nx/FacHeader.h deleted file mode 100644 index 08ab345..0000000 --- a/lib/libnx/include/nx/FacHeader.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#include -#include -#include -#include - -namespace nx -{ - class FacHeader : - public fnd::ISerialisable - { - public: - struct sSection - { - size_t offset; - size_t size; - - void operator=(const sSection& other) - { - offset = other.offset; - size = other.size; - } - - bool operator==(const sSection& other) const - { - return (offset == other.offset) \ - && (size == other.size); - } - - bool operator!=(const sSection& other) const - { - return !operator==(other); - } - }; - - FacHeader(); - FacHeader(const FacHeader& other); - - void operator=(const FacHeader& other); - bool operator==(const FacHeader& other) const; - bool operator!=(const FacHeader& other) const; - - // export/import binary - void toBytes(); - void fromBytes(const byte_t* bytes, size_t len); - const fnd::Vec& getBytes() const; - - // variables - void clear(); - size_t getFacSize() const; - - uint32_t getFormatVersion() const; - void setFormatVersion(uint32_t version); - - const fnd::List& getFsaRightsList() const; - void setFsaRightsList(const fnd::List& list); - - const sSection& getContentOwnerIdPos() const; - void setContentOwnerIdPos(const sSection& pos); - - const sSection& getSaveDataOwnerIdPos() const;; - void setSaveDataOwnerIdPos(const sSection& pos); - - private: - const std::string kModuleName = "FAC_HEADER"; - - // raw binary - fnd::Vec mRawBinary; - - // variables - uint32_t mVersion; - fnd::List mFsaRights; - sSection mContentOwnerIdPos; - sSection mSaveDataOwnerIdPos; - }; -} - diff --git a/lib/libnx/include/nx/FacBinary.h b/lib/libnx/include/nx/FileSystemAccessControlBinary.h similarity index 56% rename from lib/libnx/include/nx/FacBinary.h rename to lib/libnx/include/nx/FileSystemAccessControlBinary.h index 1d38e23..3a822bc 100644 --- a/lib/libnx/include/nx/FacBinary.h +++ b/lib/libnx/include/nx/FileSystemAccessControlBinary.h @@ -1,30 +1,34 @@ #pragma once #include +#include #include #include #include + namespace nx { - class FacBinary : - public fnd::ISerialisable + class FileSystemAccessControlBinary : public fnd::ISerialisable { public: - FacBinary(); - FacBinary(const FacBinary& other); + FileSystemAccessControlBinary(); + FileSystemAccessControlBinary(const FileSystemAccessControlBinary& other); - void operator=(const FacBinary& other); - bool operator==(const FacBinary& other) const; - bool operator!=(const FacBinary& other) const; + void operator=(const FileSystemAccessControlBinary& other); + bool operator==(const FileSystemAccessControlBinary& other) const; + bool operator!=(const FileSystemAccessControlBinary& other) const; // export/import binary void toBytes(); - void fromBytes(const byte_t* bytes, size_t len); + void fromBytes(const byte_t* data, size_t len); const fnd::Vec& getBytes() const; // variables void clear(); + uint32_t getFormatVersion() const; + void setFormatVersion(uint32_t version); + const fnd::List& getFsaRightsList() const; void setFsaRightsList(const fnd::List& list); @@ -33,17 +37,16 @@ namespace nx const fnd::List& getSaveDataOwnerIdList() const; void setSaveDataOwnerIdList(const fnd::List& list); - private: - const std::string kModuleName = "FAC_BINARY"; + const std::string kModuleName = "FILE_SYSTEM_ACCESS_CONTROL_BINARY"; - // raw binary + // raw data fnd::Vec mRawBinary; // variables + uint32_t mVersion; fnd::List mFsaRights; fnd::List mContentOwnerIdList; fnd::List mSaveDataOwnerIdList; }; -} - +} \ No newline at end of file diff --git a/lib/libnx/include/nx/fac.h b/lib/libnx/include/nx/fac.h index 4202698..06ed970 100644 --- a/lib/libnx/include/nx/fac.h +++ b/lib/libnx/include/nx/fac.h @@ -32,6 +32,7 @@ namespace nx }; static const uint32_t kFacFormatVersion = 1; + static const size_t kSectionAlignSize = 4; } #pragma pack(push,1) diff --git a/lib/libnx/source/AccessControlInfoBinary.cpp b/lib/libnx/source/AccessControlInfoBinary.cpp index bdf3460..6839500 100644 --- a/lib/libnx/source/AccessControlInfoBinary.cpp +++ b/lib/libnx/source/AccessControlInfoBinary.cpp @@ -141,12 +141,12 @@ void nx::AccessControlInfoBinary::setProgramId(uint64_t program_id) mProgramId = program_id; } -const nx::FacBinary& nx::AccessControlInfoBinary::getFileSystemAccessControl() const +const nx::FileSystemAccessControlBinary& nx::AccessControlInfoBinary::getFileSystemAccessControl() const { return mFileSystemAccessControl; } -void nx::AccessControlInfoBinary::setFileSystemAccessControl(const nx::FacBinary& fac) +void nx::AccessControlInfoBinary::setFileSystemAccessControl(const nx::FileSystemAccessControlBinary& fac) { mFileSystemAccessControl = fac; } diff --git a/lib/libnx/source/AccessControlInfoDescBinary.cpp b/lib/libnx/source/AccessControlInfoDescBinary.cpp index 7fa7310..28b2085 100644 --- a/lib/libnx/source/AccessControlInfoDescBinary.cpp +++ b/lib/libnx/source/AccessControlInfoDescBinary.cpp @@ -219,12 +219,12 @@ void nx::AccessControlInfoDescBinary::setProgramIdRestrict(const sProgramIdRestr mProgramIdRestrict = pid_restrict; } -const nx::FacBinary& nx::AccessControlInfoDescBinary::getFileSystemAccessControl() const +const nx::FileSystemAccessControlBinary& nx::AccessControlInfoDescBinary::getFileSystemAccessControl() const { return mFileSystemAccessControl; } -void nx::AccessControlInfoDescBinary::setFileSystemAccessControl(const nx::FacBinary& fac) +void nx::AccessControlInfoDescBinary::setFileSystemAccessControl(const nx::FileSystemAccessControlBinary& fac) { mFileSystemAccessControl = fac; } diff --git a/lib/libnx/source/FacBinary.cpp b/lib/libnx/source/FacBinary.cpp deleted file mode 100644 index cf391af..0000000 --- a/lib/libnx/source/FacBinary.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include - -nx::FacBinary::FacBinary() -{ - clear(); -} - -nx::FacBinary::FacBinary(const FacBinary & other) -{ - *this = other; -} - -void nx::FacBinary::operator=(const FacBinary & other) -{ - if (other.getBytes().size()) - { - fromBytes(other.getBytes().data(), other.getBytes().size()); - } - else - { - clear(); - mFsaRights = other.mFsaRights; - mContentOwnerIdList = other.mContentOwnerIdList; - mSaveDataOwnerIdList = other.mSaveDataOwnerIdList; - } -} - -bool nx::FacBinary::operator==(const FacBinary & other) const -{ - return (mFsaRights == other.mFsaRights) \ - && (mContentOwnerIdList == other.mContentOwnerIdList) \ - && (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList); -} - -bool nx::FacBinary::operator!=(const FacBinary & other) const -{ - return !(*this == other); -} - -void nx::FacBinary::toBytes() -{ - FacHeader hdr; - - FacHeader::sSection content_id_list_pos, savedata_owner_id_list_pos; - - content_id_list_pos.size = mContentOwnerIdList.size() * sizeof(uint32_t); - content_id_list_pos.offset = align(sizeof(sFacHeader), 4); - savedata_owner_id_list_pos.size = mSaveDataOwnerIdList.size() * sizeof(uint32_t); - savedata_owner_id_list_pos.offset = content_id_list_pos.offset + align(content_id_list_pos.size, 4); - - hdr.setFormatVersion(fac::kFacFormatVersion); - hdr.setFsaRightsList(mFsaRights); - hdr.setContentOwnerIdPos(content_id_list_pos); - hdr.setSaveDataOwnerIdPos(savedata_owner_id_list_pos); - hdr.toBytes(); - - mRawBinary.alloc(hdr.getFacSize()); - memcpy(mRawBinary.data(), hdr.getBytes().data(), hdr.getBytes().size()); - - uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + content_id_list_pos.offset); - for (size_t i = 0; i < mContentOwnerIdList.size(); i++) - { - rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]); - } - - uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mRawBinary.data() + savedata_owner_id_list_pos.offset); - for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++) - { - rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]); - } -} - -void nx::FacBinary::fromBytes(const byte_t* data, size_t len) -{ - clear(); - - FacHeader hdr; - hdr.fromBytes(data, len); - - mFsaRights = hdr.getFsaRightsList(); - - if (hdr.getFacSize() > len) - { - throw fnd::Exception(kModuleName, "FAC binary too small"); - } - - mRawBinary.alloc(hdr.getFacSize()); - memcpy(mRawBinary.data(), data, mRawBinary.size()); - - 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() + 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])); - } -} - -const fnd::Vec& nx::FacBinary::getBytes() const -{ - return mRawBinary; -} - -void nx::FacBinary::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; -} - -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/libnx/source/FacHeader.cpp b/lib/libnx/source/FacHeader.cpp deleted file mode 100644 index d1a06b3..0000000 --- a/lib/libnx/source/FacHeader.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include - -nx::FacHeader::FacHeader() : - mFsaRights() -{ - clear(); -} - -nx::FacHeader::FacHeader(const FacHeader & other) : - mFsaRights() -{ - *this = other; -} - -void nx::FacHeader::operator=(const FacHeader & other) -{ - if (other.getBytes().size()) - { - fromBytes(other.getBytes().data(), other.getBytes().size()); - } - else - { - clear(); - mFsaRights = other.mFsaRights; - mContentOwnerIdPos.offset = other.mContentOwnerIdPos.offset; - mContentOwnerIdPos.size = other.mContentOwnerIdPos.size; - mSaveDataOwnerIdPos.offset = other.mSaveDataOwnerIdPos.offset; - mSaveDataOwnerIdPos.size = other.mSaveDataOwnerIdPos.size; - } -} - -bool nx::FacHeader::operator==(const FacHeader & other) const -{ - return (mFsaRights == other.mFsaRights) \ - && (mContentOwnerIdPos.offset == other.mContentOwnerIdPos.offset) \ - && (mContentOwnerIdPos.size == other.mContentOwnerIdPos.size) \ - && (mSaveDataOwnerIdPos.offset == other.mSaveDataOwnerIdPos.offset) \ - && (mSaveDataOwnerIdPos.size == other.mSaveDataOwnerIdPos.size); -} - -bool nx::FacHeader::operator!=(const FacHeader & other) const -{ - return !(*this == other); -} - -void nx::FacHeader::toBytes() -{ - mRawBinary.alloc(sizeof(sFacHeader)); - sFacHeader* hdr = (sFacHeader*)mRawBinary.data(); - - if (mVersion != fac::kFacFormatVersion) - { - fnd::Exception(kModuleName, "Unsupported format version"); - } - hdr->version = (mVersion); - - uint64_t flag = 0; - for (size_t i = 0; i < mFsaRights.size(); i++) - { - flag |= _BIT((uint64_t)mFsaRights[i]); - } - hdr->fac_flags = (flag); - - hdr->content_owner_ids.start = (uint32_t)(mContentOwnerIdPos.offset); - hdr->content_owner_ids.end = (uint32_t)(mContentOwnerIdPos.offset + mContentOwnerIdPos.size); - hdr->save_data_owner_ids.start = (uint32_t)(mSaveDataOwnerIdPos.offset); - hdr->save_data_owner_ids.end = (uint32_t)(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size); -} - -void nx::FacHeader::fromBytes(const byte_t* data, size_t len) -{ - if (len < sizeof(sFacHeader)) - { - throw fnd::Exception(kModuleName, "FAC header too small"); - } - - // clear internal members - clear(); - - mRawBinary.alloc(sizeof(sFacHeader)); - memcpy(mRawBinary.data(), data, mRawBinary.size()); - sFacHeader* hdr = (sFacHeader*)mRawBinary.data(); - - if (hdr->version.get() != fac::kFacFormatVersion) - { - throw fnd::Exception(kModuleName, "Unsupported FAC format version"); - } - mVersion = hdr->version.get(); - - for (uint64_t i = 0; i < 64; i++) - { - if (_HAS_BIT(hdr->fac_flags.get(), i)) - { - mFsaRights.addElement((fac::FsAccessFlag)i); - } - } - mContentOwnerIdPos.offset = hdr->content_owner_ids.start.get(); - mContentOwnerIdPos.size = hdr->content_owner_ids.end.get() > hdr->content_owner_ids.start.get() ? hdr->content_owner_ids.end.get() - hdr->content_owner_ids.start.get() : 0; - mSaveDataOwnerIdPos.offset = hdr->save_data_owner_ids.start.get(); - mSaveDataOwnerIdPos.size = hdr->save_data_owner_ids.end.get() > hdr->save_data_owner_ids.start.get() ? hdr->save_data_owner_ids.end.get() - hdr->save_data_owner_ids.start.get() : 0; -} - -const fnd::Vec& nx::FacHeader::getBytes() const -{ - return mRawBinary; -} - -void nx::FacHeader::clear() -{ - mFsaRights.clear(); - mContentOwnerIdPos.offset = 0; - mContentOwnerIdPos.size = 0; - mSaveDataOwnerIdPos.offset = 0; - mSaveDataOwnerIdPos.size = 0; -} - -size_t nx::FacHeader::getFacSize() const -{ - size_t savedata = mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size; - size_t content = mContentOwnerIdPos.offset + mContentOwnerIdPos.size; - return _MAX(_MAX(savedata, content), sizeof(sFacHeader)); -} - -uint32_t nx::FacHeader::getFormatVersion() const -{ - return mVersion; -} - -void nx::FacHeader::setFormatVersion(uint32_t version) -{ - mVersion = version; -} - -const fnd::List& nx::FacHeader::getFsaRightsList() const -{ - return mFsaRights; -} - -void nx::FacHeader::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 nx::FacHeader::sSection& nx::FacHeader::getContentOwnerIdPos() const -{ - return mContentOwnerIdPos; -} - -void nx::FacHeader::setContentOwnerIdPos(const sSection& pos) -{ - mContentOwnerIdPos = pos; -} - -const nx::FacHeader::sSection& nx::FacHeader::getSaveDataOwnerIdPos() const -{ - return mSaveDataOwnerIdPos; -} - -void nx::FacHeader::setSaveDataOwnerIdPos(const sSection& pos) -{ - mSaveDataOwnerIdPos = pos; -} \ No newline at end of file diff --git a/lib/libnx/source/FileSystemAccessControlBinary.cpp b/lib/libnx/source/FileSystemAccessControlBinary.cpp new file mode 100644 index 0000000..60b1971 --- /dev/null +++ b/lib/libnx/source/FileSystemAccessControlBinary.cpp @@ -0,0 +1,205 @@ +#include + +#include + +nx::FileSystemAccessControlBinary::FileSystemAccessControlBinary() +{ + clear(); +} + +nx::FileSystemAccessControlBinary::FileSystemAccessControlBinary(const FileSystemAccessControlBinary & other) +{ + *this = other; +} + +void nx::FileSystemAccessControlBinary::operator=(const FileSystemAccessControlBinary & other) +{ + mRawBinary = other.mRawBinary; + mVersion = other.mVersion; + mFsaRights = other.mFsaRights; + mContentOwnerIdList = other.mContentOwnerIdList; + mSaveDataOwnerIdList = other.mSaveDataOwnerIdList; +} + +bool nx::FileSystemAccessControlBinary::operator==(const FileSystemAccessControlBinary & other) const +{ + return (mVersion == other.mVersion) \ + && (mFsaRights == other.mFsaRights) \ + && (mContentOwnerIdList == other.mContentOwnerIdList) \ + && (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList); +} + +bool nx::FileSystemAccessControlBinary::operator!=(const FileSystemAccessControlBinary & other) const +{ + return !(*this == other); +} + +void nx::FileSystemAccessControlBinary::toBytes() +{ + // determine section layout + struct sLayout { + uint32_t offset, size; + } content, savedata; + + content.offset = align(sizeof(sFacHeader), fac::kSectionAlignSize); + content.size = (uint32_t)(mContentOwnerIdList.size() * sizeof(uint32_t)); + savedata.offset = content.offset + align(content.size, fac::kSectionAlignSize); + savedata.size = (uint32_t)(mSaveDataOwnerIdList.size() * sizeof(uint32_t)); + + // get total size + size_t total_size = _MAX(_MAX(content.offset + content.size, savedata.offset + savedata.size), align(sizeof(sFacHeader), fac::kSectionAlignSize)); + + mRawBinary.alloc(total_size); + sFacHeader* hdr = (sFacHeader*)mRawBinary.data(); + + // set type + hdr->version = mVersion; + + // flags + uint64_t flag = 0; + for (size_t i = 0; i < mFsaRights.size(); i++) + { + flag |= _BIT((uint64_t)mFsaRights[i]); + } + hdr->fac_flags = flag; + + // set offset/size + hdr->content_owner_ids.start = content.offset; + if (content.size > 0) + hdr->content_owner_ids.end = content.offset + content.size; + hdr->save_data_owner_ids.start = savedata.offset; + if (savedata.size > 0) + hdr->save_data_owner_ids.end = savedata.offset + savedata.size; + + // set ids + le_uint32_t* content_owner_ids = (le_uint32_t*)(mRawBinary.data() + content.offset); + for (size_t i = 0; i < mContentOwnerIdList.size(); i++) + { + content_owner_ids[i] = mContentOwnerIdList[i]; + } + + le_uint32_t* save_data_owner_ids = (le_uint32_t*)(mRawBinary.data() + savedata.offset); + for (size_t i = 0; i < mSaveDataOwnerIdList.size(); i++) + { + save_data_owner_ids[i] = mSaveDataOwnerIdList[i]; + } +} + +void nx::FileSystemAccessControlBinary::fromBytes(const byte_t* data, size_t len) +{ + // check size + if (len < sizeof(sFacHeader)) + { + throw fnd::Exception(kModuleName, "FileSystemAccessControlInfo binary is too small"); + } + + // clear variables + clear(); + + // save a copy of the header + sFacHeader hdr; + memcpy((void*)&hdr, data, sizeof(sFacHeader)); + + // check format version + if (hdr.version.get() != fac::kFacFormatVersion) + { + throw fnd::Exception(kModuleName, "FileSystemAccessControlInfo format version unsupported"); + } + + // get total size + size_t total_size = _MAX(_MAX(hdr.content_owner_ids.end.get(), hdr.save_data_owner_ids.end.get()), align(sizeof(sFacHeader), fac::kSectionAlignSize)); + + // validate binary size + if (len < total_size) + { + throw fnd::Exception(kModuleName, "FileSystemAccessControlInfo binary is too small"); + } + + // allocate memory + mRawBinary.alloc(total_size); + memcpy(mRawBinary.data(), data, mRawBinary.size()); + + // save variables + mVersion = hdr.version.get(); + for (size_t i = 0; i < 64; i++) + { + if (_HAS_BIT(hdr.fac_flags.get(), i)) + { + mFsaRights.addElement((fac::FsAccessFlag)i); + } + } + + // save ids + if (hdr.content_owner_ids.end.get() > hdr.content_owner_ids.start.get()) + { + le_uint32_t* content_owner_ids = (le_uint32_t*)(mRawBinary.data() + hdr.content_owner_ids.start.get()); + size_t content_owner_id_num = (hdr.content_owner_ids.end.get() - hdr.content_owner_ids.start.get()) / sizeof(uint32_t); + for (size_t i = 0; i < content_owner_id_num; i++) + { + mContentOwnerIdList.addElement(content_owner_ids[i].get()); + } + } + if (hdr.save_data_owner_ids.end.get() > hdr.save_data_owner_ids.start.get()) + { + le_uint32_t* save_data_owner_ids = (le_uint32_t*)(mRawBinary.data() + hdr.save_data_owner_ids.start.get()); + size_t save_data_owner_id_num = (hdr.save_data_owner_ids.end.get() - hdr.save_data_owner_ids.start.get()) / sizeof(uint32_t); + for (size_t i = 0; i < save_data_owner_id_num; i++) + { + mSaveDataOwnerIdList.addElement(save_data_owner_ids[i].get()); + } + } +} + +const fnd::Vec& nx::FileSystemAccessControlBinary::getBytes() const +{ + return mRawBinary; +} + +void nx::FileSystemAccessControlBinary::clear() +{ + mRawBinary.clear(); + mVersion = 0; + mFsaRights.clear(); + mContentOwnerIdList.clear(); + mSaveDataOwnerIdList.clear(); +} + +uint32_t nx::FileSystemAccessControlBinary::getFormatVersion() const +{ + return mVersion; +} + +void nx::FileSystemAccessControlBinary::setFormatVersion(uint32_t format_version) +{ + mVersion = format_version; +} + +const fnd::List& nx::FileSystemAccessControlBinary::getFsaRightsList() const +{ + return mFsaRights; +} + +void nx::FileSystemAccessControlBinary::setFsaRightsList(const fnd::List& list) +{ + mFsaRights = list; +} + +const fnd::List& nx::FileSystemAccessControlBinary::getContentOwnerIdList() const +{ + return mContentOwnerIdList; +} + +void nx::FileSystemAccessControlBinary::setContentOwnerIdList(const fnd::List& list) +{ + mContentOwnerIdList = list; +} + +const fnd::List& nx::FileSystemAccessControlBinary::getSaveDataOwnerIdList() const +{ + return mSaveDataOwnerIdList; +} + +void nx::FileSystemAccessControlBinary::setSaveDataOwnerIdList(const fnd::List& list) +{ + mSaveDataOwnerIdList = list; +} \ No newline at end of file diff --git a/programs/nstool/source/NpdmProcess.cpp b/programs/nstool/source/NpdmProcess.cpp index 30b12f0..65fc8a8 100644 --- a/programs/nstool/source/NpdmProcess.cpp +++ b/programs/nstool/source/NpdmProcess.cpp @@ -570,9 +570,10 @@ void NpdmProcess::displayAciDescHdr(const nx::AccessControlInfoDescBinary& acid) printf(" Max: 0x%016" PRIx64 "\n", acid.getProgramIdRestrict().max); } -void NpdmProcess::displayFac(const nx::FacBinary& fac) +void NpdmProcess::displayFac(const nx::FileSystemAccessControlBinary& fac) { printf("[FS Access Control]\n"); + printf(" Format Version: %d\n", fac.getFormatVersion()); if (fac.getFsaRightsList().size()) { @@ -583,7 +584,12 @@ void NpdmProcess::displayFac(const nx::FacBinary& fac) { printf("%s ", i != 0 ? "\n" : ""); } - printf("%s%s", kFsaFlag[fac.getFsaRightsList()[i]].c_str(), fac.getFsaRightsList()[i] != fac.getFsaRightsList().atBack() ? ", " : "\n"); + printf("%s", kFsaFlag[fac.getFsaRightsList()[i]].c_str()); + if (_HAS_BIT(mCliOutputMode, OUTPUT_EXTENDED)) + printf(" (mask 0x%" PRIx64 ")", _BIT(fac.getFsaRightsList()[i])); + printf("%s", fac.getFsaRightsList()[i] != fac.getFsaRightsList().atBack() ? ", " : "\n"); + + } } else diff --git a/programs/nstool/source/NpdmProcess.h b/programs/nstool/source/NpdmProcess.h index b0b977c..9997f9b 100644 --- a/programs/nstool/source/NpdmProcess.h +++ b/programs/nstool/source/NpdmProcess.h @@ -38,7 +38,7 @@ private: void displayNpdmHeader(const nx::NpdmHeader& hdr); void displayAciHdr(const nx::AccessControlInfoBinary& aci); void displayAciDescHdr(const nx::AccessControlInfoDescBinary& aci); - void displayFac(const nx::FacBinary& fac); + void displayFac(const nx::FileSystemAccessControlBinary& fac); void displaySac(const nx::SacBinary& sac); void displayKernelCap(const nx::KcBinary& kern); }; \ No newline at end of file