[nx|nstool] Replace FacHeader & FacBinary

This commit is contained in:
jakcron 2018-06-29 00:20:56 +08:00
parent 123f85c01f
commit efe0655f05
12 changed files with 245 additions and 423 deletions

View file

@ -3,7 +3,7 @@
#include <fnd/types.h> #include <fnd/types.h>
#include <fnd/ISerialisable.h> #include <fnd/ISerialisable.h>
#include <nx/aci.h> #include <nx/aci.h>
#include <nx/FacBinary.h> #include <nx/FileSystemAccessControlBinary.h>
#include <nx/SacBinary.h> #include <nx/SacBinary.h>
#include <nx/KcBinary.h> #include <nx/KcBinary.h>
@ -30,8 +30,8 @@ namespace nx
uint64_t getProgramId() const; uint64_t getProgramId() const;
void setProgramId(uint64_t program_id); void setProgramId(uint64_t program_id);
const nx::FacBinary& getFileSystemAccessControl() const; const nx::FileSystemAccessControlBinary& getFileSystemAccessControl() const;
void setFileSystemAccessControl(const FacBinary& fac); void setFileSystemAccessControl(const FileSystemAccessControlBinary& fac);
const nx::SacBinary& getServiceAccessControl() const; const nx::SacBinary& getServiceAccessControl() const;
void setServiceAccessControl(const SacBinary& sac); void setServiceAccessControl(const SacBinary& sac);
@ -46,7 +46,7 @@ namespace nx
// variables // variables
uint64_t mProgramId; uint64_t mProgramId;
nx::FacBinary mFileSystemAccessControl; nx::FileSystemAccessControlBinary mFileSystemAccessControl;
nx::SacBinary mServiceAccessControl; nx::SacBinary mServiceAccessControl;
nx::KcBinary mKernelCapabilities; nx::KcBinary mKernelCapabilities;
}; };

View file

@ -4,7 +4,7 @@
#include <fnd/List.h> #include <fnd/List.h>
#include <fnd/ISerialisable.h> #include <fnd/ISerialisable.h>
#include <nx/aci.h> #include <nx/aci.h>
#include <nx/FacBinary.h> #include <nx/FileSystemAccessControlBinary.h>
#include <nx/SacBinary.h> #include <nx/SacBinary.h>
#include <nx/KcBinary.h> #include <nx/KcBinary.h>
@ -63,13 +63,13 @@ namespace nx
const sProgramIdRestrict& getProgramIdRestrict() const; const sProgramIdRestrict& getProgramIdRestrict() const;
void setProgramIdRestrict(const sProgramIdRestrict& pid_restrict); void setProgramIdRestrict(const sProgramIdRestrict& pid_restrict);
const FacBinary& getFileSystemAccessControl() const; const nx::FileSystemAccessControlBinary& getFileSystemAccessControl() const;
void setFileSystemAccessControl(const FacBinary& fac); void setFileSystemAccessControl(const FileSystemAccessControlBinary& fac);
const SacBinary& getServiceAccessControl() const; const nx::SacBinary& getServiceAccessControl() const;
void setServiceAccessControl(const SacBinary& sac); void setServiceAccessControl(const SacBinary& sac);
const KcBinary& getKernelCapabilities() const; const nx::KcBinary& getKernelCapabilities() const;
void setKernelCapabilities(const KcBinary& kc); void setKernelCapabilities(const KcBinary& kc);
private: private:
const std::string kModuleName = "ACCESS_CONTROL_INFO_DESC_BINARY"; const std::string kModuleName = "ACCESS_CONTROL_INFO_DESC_BINARY";
@ -81,7 +81,7 @@ namespace nx
crypto::rsa::sRsa2048Key mNcaHeaderSignature2Key; crypto::rsa::sRsa2048Key mNcaHeaderSignature2Key;
fnd::List<aci::Flag> mFlags; fnd::List<aci::Flag> mFlags;
sProgramIdRestrict mProgramIdRestrict; sProgramIdRestrict mProgramIdRestrict;
nx::FacBinary mFileSystemAccessControl; nx::FileSystemAccessControlBinary mFileSystemAccessControl;
nx::SacBinary mServiceAccessControl; nx::SacBinary mServiceAccessControl;
nx::KcBinary mKernelCapabilities; nx::KcBinary mKernelCapabilities;
}; };

View file

@ -1,77 +0,0 @@
#pragma once
#include <string>
#include <fnd/ISerialisable.h>
#include <fnd/List.h>
#include <nx/fac.h>
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<byte_t>& getBytes() const;
// variables
void clear();
size_t getFacSize() const;
uint32_t getFormatVersion() const;
void setFormatVersion(uint32_t version);
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& 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<byte_t> mRawBinary;
// variables
uint32_t mVersion;
fnd::List<fac::FsAccessFlag> mFsaRights;
sSection mContentOwnerIdPos;
sSection mSaveDataOwnerIdPos;
};
}

View file

@ -1,30 +1,34 @@
#pragma once #pragma once
#include <string> #include <string>
#include <fnd/types.h>
#include <fnd/ISerialisable.h> #include <fnd/ISerialisable.h>
#include <fnd/List.h> #include <fnd/List.h>
#include <nx/fac.h> #include <nx/fac.h>
namespace nx namespace nx
{ {
class FacBinary : class FileSystemAccessControlBinary : public fnd::ISerialisable
public fnd::ISerialisable
{ {
public: public:
FacBinary(); FileSystemAccessControlBinary();
FacBinary(const FacBinary& other); FileSystemAccessControlBinary(const FileSystemAccessControlBinary& other);
void operator=(const FacBinary& other); void operator=(const FileSystemAccessControlBinary& other);
bool operator==(const FacBinary& other) const; bool operator==(const FileSystemAccessControlBinary& other) const;
bool operator!=(const FacBinary& other) const; bool operator!=(const FileSystemAccessControlBinary& other) const;
// export/import binary // export/import binary
void toBytes(); void toBytes();
void fromBytes(const byte_t* bytes, size_t len); void fromBytes(const byte_t* data, size_t len);
const fnd::Vec<byte_t>& getBytes() const; const fnd::Vec<byte_t>& getBytes() const;
// variables // variables
void clear(); void clear();
uint32_t getFormatVersion() const;
void setFormatVersion(uint32_t version);
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const; const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list); void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
@ -33,17 +37,16 @@ namespace nx
const fnd::List<uint32_t>& getSaveDataOwnerIdList() const; const fnd::List<uint32_t>& getSaveDataOwnerIdList() const;
void setSaveDataOwnerIdList(const fnd::List<uint32_t>& list); void setSaveDataOwnerIdList(const fnd::List<uint32_t>& list);
private: private:
const std::string kModuleName = "FAC_BINARY"; const std::string kModuleName = "FILE_SYSTEM_ACCESS_CONTROL_BINARY";
// raw binary // raw data
fnd::Vec<byte_t> mRawBinary; fnd::Vec<byte_t> mRawBinary;
// variables // variables
uint32_t mVersion;
fnd::List<fac::FsAccessFlag> mFsaRights; fnd::List<fac::FsAccessFlag> mFsaRights;
fnd::List<uint32_t> mContentOwnerIdList; fnd::List<uint32_t> mContentOwnerIdList;
fnd::List<uint32_t> mSaveDataOwnerIdList; fnd::List<uint32_t> mSaveDataOwnerIdList;
}; };
} }

View file

@ -32,6 +32,7 @@ namespace nx
}; };
static const uint32_t kFacFormatVersion = 1; static const uint32_t kFacFormatVersion = 1;
static const size_t kSectionAlignSize = 4;
} }
#pragma pack(push,1) #pragma pack(push,1)

View file

@ -141,12 +141,12 @@ void nx::AccessControlInfoBinary::setProgramId(uint64_t program_id)
mProgramId = program_id; mProgramId = program_id;
} }
const nx::FacBinary& nx::AccessControlInfoBinary::getFileSystemAccessControl() const const nx::FileSystemAccessControlBinary& nx::AccessControlInfoBinary::getFileSystemAccessControl() const
{ {
return mFileSystemAccessControl; return mFileSystemAccessControl;
} }
void nx::AccessControlInfoBinary::setFileSystemAccessControl(const nx::FacBinary& fac) void nx::AccessControlInfoBinary::setFileSystemAccessControl(const nx::FileSystemAccessControlBinary& fac)
{ {
mFileSystemAccessControl = fac; mFileSystemAccessControl = fac;
} }

View file

@ -219,12 +219,12 @@ void nx::AccessControlInfoDescBinary::setProgramIdRestrict(const sProgramIdRestr
mProgramIdRestrict = pid_restrict; mProgramIdRestrict = pid_restrict;
} }
const nx::FacBinary& nx::AccessControlInfoDescBinary::getFileSystemAccessControl() const const nx::FileSystemAccessControlBinary& nx::AccessControlInfoDescBinary::getFileSystemAccessControl() const
{ {
return mFileSystemAccessControl; return mFileSystemAccessControl;
} }
void nx::AccessControlInfoDescBinary::setFileSystemAccessControl(const nx::FacBinary& fac) void nx::AccessControlInfoDescBinary::setFileSystemAccessControl(const nx::FileSystemAccessControlBinary& fac)
{ {
mFileSystemAccessControl = fac; mFileSystemAccessControl = fac;
} }

View file

@ -1,150 +0,0 @@
#include <nx/FacBinary.h>
#include <nx/FacHeader.h>
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<byte_t>& nx::FacBinary::getBytes() const
{
return mRawBinary;
}
void nx::FacBinary::clear()
{
mRawBinary.clear();
mContentOwnerIdList.clear();
mSaveDataOwnerIdList.clear();
}
const fnd::List<nx::fac::FsAccessFlag>& nx::FacBinary::getFsaRightsList() const
{
return mFsaRights;
}
void nx::FacBinary::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& 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<uint32_t>& nx::FacBinary::getContentOwnerIdList() const
{
return mContentOwnerIdList;
}
void nx::FacBinary::setContentOwnerIdList(const fnd::List<uint32_t>& list)
{
mContentOwnerIdList = list;
}
const fnd::List<uint32_t>& nx::FacBinary::getSaveDataOwnerIdList() const
{
return mSaveDataOwnerIdList;
}
void nx::FacBinary::setSaveDataOwnerIdList(const fnd::List<uint32_t>& list)
{
mSaveDataOwnerIdList = list;
}

View file

@ -1,166 +0,0 @@
#include <nx/FacHeader.h>
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<byte_t>& 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::fac::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const
{
return mFsaRights;
}
void nx::FacHeader::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& 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;
}

View file

@ -0,0 +1,205 @@
#include <nx/FileSystemAccessControlBinary.h>
#include <fnd/SimpleTextOutput.h>
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<byte_t>& 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::fac::FsAccessFlag>& nx::FileSystemAccessControlBinary::getFsaRightsList() const
{
return mFsaRights;
}
void nx::FileSystemAccessControlBinary::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list)
{
mFsaRights = list;
}
const fnd::List<uint32_t>& nx::FileSystemAccessControlBinary::getContentOwnerIdList() const
{
return mContentOwnerIdList;
}
void nx::FileSystemAccessControlBinary::setContentOwnerIdList(const fnd::List<uint32_t>& list)
{
mContentOwnerIdList = list;
}
const fnd::List<uint32_t>& nx::FileSystemAccessControlBinary::getSaveDataOwnerIdList() const
{
return mSaveDataOwnerIdList;
}
void nx::FileSystemAccessControlBinary::setSaveDataOwnerIdList(const fnd::List<uint32_t>& list)
{
mSaveDataOwnerIdList = list;
}

View file

@ -570,9 +570,10 @@ void NpdmProcess::displayAciDescHdr(const nx::AccessControlInfoDescBinary& acid)
printf(" Max: 0x%016" PRIx64 "\n", acid.getProgramIdRestrict().max); 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("[FS Access Control]\n");
printf(" Format Version: %d\n", fac.getFormatVersion());
if (fac.getFsaRightsList().size()) if (fac.getFsaRightsList().size())
{ {
@ -583,7 +584,12 @@ void NpdmProcess::displayFac(const nx::FacBinary& fac)
{ {
printf("%s ", i != 0 ? "\n" : ""); 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 else

View file

@ -38,7 +38,7 @@ private:
void displayNpdmHeader(const nx::NpdmHeader& hdr); void displayNpdmHeader(const nx::NpdmHeader& hdr);
void displayAciHdr(const nx::AccessControlInfoBinary& aci); void displayAciHdr(const nx::AccessControlInfoBinary& aci);
void displayAciDescHdr(const nx::AccessControlInfoDescBinary& 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 displaySac(const nx::SacBinary& sac);
void displayKernelCap(const nx::KcBinary& kern); void displayKernelCap(const nx::KcBinary& kern);
}; };