mirror of
https://github.com/jakcron/nstool.git
synced 2024-12-22 18:55:29 +00:00
[nx] Added SacBinary, FacHeader, FacBinary.
This commit is contained in:
parent
844a46c83a
commit
724fc26349
167
lib/nx/FacBinary.cpp
Normal file
167
lib/nx/FacBinary.cpp
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
#include "FacBinary.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FacBinary::FacBinary() :
|
||||||
|
mHeader()
|
||||||
|
{
|
||||||
|
clearVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
FacBinary::FacBinary(const FacBinary & other)
|
||||||
|
{
|
||||||
|
importBinary(other.getBytes(), other.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 * FacBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mBinaryBlob.getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FacBinary::getSize() const
|
||||||
|
{
|
||||||
|
return mBinaryBlob.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::exportBinary()
|
||||||
|
{
|
||||||
|
mHeader.setFsaRights(mFsaRights);
|
||||||
|
mHeader.setContentOwnerIdSize(mContentOwnerIds.getSize() * sizeof(u32));
|
||||||
|
mHeader.setSaveDataOwnerIdSize(mSaveDataOwnerIds.getSize() * sizeof(u32));
|
||||||
|
mHeader.exportBinary();
|
||||||
|
|
||||||
|
mBinaryBlob.alloc(mHeader.getFacSize());
|
||||||
|
memcpy(mBinaryBlob.getBytes(), mHeader.getBytes(), mHeader.getSize());
|
||||||
|
|
||||||
|
u32* rawContentOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getContentOwnerIdOffset());
|
||||||
|
for (size_t i = 0; i < mContentOwnerIds.getSize(); i++)
|
||||||
|
{
|
||||||
|
rawContentOwnerIds[i] = le_word(mContentOwnerIds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32* rawSaveDataOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getSaveDataOwnerIdOffset());
|
||||||
|
for (size_t i = 0; i < mSaveDataOwnerIds.getSize(); i++)
|
||||||
|
{
|
||||||
|
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIds[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::importBinary(const u8 * bytes)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Unsupported operation. importBinary(const u8* bytes) is not supported for variable size structures.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::importBinary(const u8 * bytes, size_t len)
|
||||||
|
{
|
||||||
|
clearVariables();
|
||||||
|
mHeader.importBinary(bytes, len);
|
||||||
|
if (mHeader.getFacSize() > len)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "FAC binary too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
mBinaryBlob.alloc(mHeader.getFacSize());
|
||||||
|
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||||
|
|
||||||
|
mFsaRights = mHeader.getFsaRights();
|
||||||
|
u32* rawContentOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getContentOwnerIdOffset());
|
||||||
|
size_t rawContentOwnerIdNum = mHeader.getContentOwnerIdSize() / sizeof(u32);
|
||||||
|
for (size_t i = 0; i < rawContentOwnerIdNum; i++)
|
||||||
|
{
|
||||||
|
addContentOwnerId(le_word(rawContentOwnerIds[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32* rawSaveDataOwnerIds = (u32*)(mBinaryBlob.getBytes() + mHeader.getSaveDataOwnerIdOffset());
|
||||||
|
size_t rawSaveDataOwnerIdNum = mHeader.getSaveDataOwnerIdSize() / sizeof(u32);
|
||||||
|
for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++)
|
||||||
|
{
|
||||||
|
addSaveDataOwnerId(le_word(rawSaveDataOwnerIds[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FacBinary::isPermissionSet(FsAccessFlag flag) const
|
||||||
|
{
|
||||||
|
return (mFsaRights & flag) == flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::addPermission(FsAccessFlag flag)
|
||||||
|
{
|
||||||
|
mFsaRights |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::removePermission(FsAccessFlag flag)
|
||||||
|
{
|
||||||
|
mFsaRights &= ~(u64)flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::List<u32>& FacBinary::getContentOwnerIds() const
|
||||||
|
{
|
||||||
|
return mContentOwnerIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::addContentOwnerId(u32 id)
|
||||||
|
{
|
||||||
|
mContentOwnerIds.addElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::List<u32>& FacBinary::getSaveDataOwnerIds() const
|
||||||
|
{
|
||||||
|
return mSaveDataOwnerIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::addSaveDataOwnerId(u32 id)
|
||||||
|
{
|
||||||
|
mSaveDataOwnerIds.addElement(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::clearVariables()
|
||||||
|
{
|
||||||
|
mHeader = FacHeader();
|
||||||
|
mFsaRights = 0;
|
||||||
|
mContentOwnerIds.clear();
|
||||||
|
mSaveDataOwnerIds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FacBinary::isEqual(const FacBinary & other) const
|
||||||
|
{
|
||||||
|
return (mHeader == other.mHeader) \
|
||||||
|
&& (mFsaRights == other.mFsaRights) \
|
||||||
|
&& (mContentOwnerIds == other.mContentOwnerIds) \
|
||||||
|
&& (mSaveDataOwnerIds == other.mSaveDataOwnerIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacBinary::copyFrom(const FacBinary & other)
|
||||||
|
{
|
||||||
|
if (other.getSize())
|
||||||
|
{
|
||||||
|
importBinary(other.getBytes(), other.getSize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mBinaryBlob.clear();
|
||||||
|
mHeader = other.mHeader;
|
||||||
|
mFsaRights = other.mFsaRights;
|
||||||
|
mContentOwnerIds = other.mContentOwnerIds;
|
||||||
|
mSaveDataOwnerIds = other.mSaveDataOwnerIds;
|
||||||
|
}
|
||||||
|
}
|
81
lib/nx/FacBinary.h
Normal file
81
lib/nx/FacBinary.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <fnd/memory_blob.h>
|
||||||
|
#include <fnd/List.h>
|
||||||
|
#include <nx/ISerialiseableBinary.h>
|
||||||
|
#include <nx/FacHeader.h>
|
||||||
|
|
||||||
|
class FacBinary :
|
||||||
|
public ISerialiseableBinary
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
bool operator==(const FacBinary& other) const;
|
||||||
|
bool operator!=(const FacBinary& other) const;
|
||||||
|
void operator=(const FacBinary& other);
|
||||||
|
|
||||||
|
// to be used after export
|
||||||
|
const u8* getBytes() const;
|
||||||
|
size_t getSize() const;
|
||||||
|
|
||||||
|
// export/import binary
|
||||||
|
void exportBinary();
|
||||||
|
void importBinary(const u8* bytes);
|
||||||
|
void importBinary(const u8* bytes, size_t len);
|
||||||
|
|
||||||
|
// variables
|
||||||
|
bool isPermissionSet(FsAccessFlag flag) const;
|
||||||
|
void addPermission(FsAccessFlag flag);
|
||||||
|
void removePermission(FsAccessFlag flag);
|
||||||
|
|
||||||
|
const fnd::List<u32>& getContentOwnerIds() const;
|
||||||
|
void addContentOwnerId(u32 id);
|
||||||
|
|
||||||
|
const fnd::List<u32>& getSaveDataOwnerIds() const;
|
||||||
|
void addSaveDataOwnerId(u32 id);
|
||||||
|
private:
|
||||||
|
const std::string kModuleName = "FAC_BINARY";
|
||||||
|
|
||||||
|
// raw binary
|
||||||
|
fnd::MemoryBlob mBinaryBlob;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
FacHeader mHeader;
|
||||||
|
u64 mFsaRights;
|
||||||
|
fnd::List<u32> mContentOwnerIds;
|
||||||
|
fnd::List<u32> mSaveDataOwnerIds;
|
||||||
|
|
||||||
|
void clearVariables();
|
||||||
|
bool isEqual(const FacBinary& other) const;
|
||||||
|
void copyFrom(const FacBinary& other);
|
||||||
|
};
|
||||||
|
|
171
lib/nx/FacHeader.cpp
Normal file
171
lib/nx/FacHeader.cpp
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
#include "FacHeader.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FacHeader::FacHeader()
|
||||||
|
{
|
||||||
|
clearVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
FacHeader::FacHeader(const FacHeader & other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
FacHeader::FacHeader(const u8 * bytes)
|
||||||
|
{
|
||||||
|
importBinary(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FacHeader::operator==(const FacHeader & other) const
|
||||||
|
{
|
||||||
|
return isEqual(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FacHeader::operator!=(const FacHeader & other) const
|
||||||
|
{
|
||||||
|
return !isEqual(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::operator=(const FacHeader & other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 * FacHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mBinaryBlob.getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FacHeader::getSize() const
|
||||||
|
{
|
||||||
|
return mBinaryBlob.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::exportBinary()
|
||||||
|
{
|
||||||
|
mBinaryBlob.alloc(sizeof(sFacHeader));
|
||||||
|
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
||||||
|
|
||||||
|
hdr->set_version(kFacFormatVersion);
|
||||||
|
hdr->set_fac_flags(mFsaRights);
|
||||||
|
|
||||||
|
calculateOffsets();
|
||||||
|
hdr->content_owner_ids().set_start(mContentOwnerIdPos.offset);
|
||||||
|
hdr->content_owner_ids().set_end(mContentOwnerIdPos.offset + mContentOwnerIdPos.size);
|
||||||
|
hdr->save_data_owner_ids().set_start(mSaveDataOwnerIdPos.offset);
|
||||||
|
hdr->save_data_owner_ids().set_end(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::importBinary(const u8 * bytes)
|
||||||
|
{
|
||||||
|
mBinaryBlob.alloc(sizeof(sFacHeader));
|
||||||
|
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||||
|
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
||||||
|
|
||||||
|
if (hdr->version() != kFacFormatVersion)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Unsupported FAC format version");
|
||||||
|
}
|
||||||
|
|
||||||
|
mFsaRights = hdr->fac_flags();
|
||||||
|
mContentOwnerIdPos.offset = hdr->content_owner_ids().start();
|
||||||
|
mContentOwnerIdPos.size = hdr->content_owner_ids().end() - hdr->content_owner_ids().start();
|
||||||
|
mSaveDataOwnerIdPos.offset = hdr->save_data_owner_ids().start();
|
||||||
|
mSaveDataOwnerIdPos.size = hdr->save_data_owner_ids().end() - hdr->save_data_owner_ids().start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::importBinary(const u8 * bytes, size_t len)
|
||||||
|
{
|
||||||
|
if (len < sizeof(sFacHeader))
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "FAC header too small");
|
||||||
|
}
|
||||||
|
importBinary(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 FacHeader::getFacSize() const
|
||||||
|
{
|
||||||
|
return getSaveDataOwnerIdOffset() + getSaveDataOwnerIdSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 FacHeader::getFsaRights() const
|
||||||
|
{
|
||||||
|
return mFsaRights;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::setFsaRights(u64 flag)
|
||||||
|
{
|
||||||
|
mFsaRights = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FacHeader::getContentOwnerIdOffset() const
|
||||||
|
{
|
||||||
|
return mContentOwnerIdPos.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FacHeader::getContentOwnerIdSize() const
|
||||||
|
{
|
||||||
|
return mContentOwnerIdPos.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::setContentOwnerIdSize(size_t size)
|
||||||
|
{
|
||||||
|
mContentOwnerIdPos.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FacHeader::getSaveDataOwnerIdOffset() const
|
||||||
|
{
|
||||||
|
return mSaveDataOwnerIdPos.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FacHeader::getSaveDataOwnerIdSize() const
|
||||||
|
{
|
||||||
|
return mSaveDataOwnerIdPos.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::setSaveDataOwnerIdSize(size_t size)
|
||||||
|
{
|
||||||
|
mSaveDataOwnerIdPos.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::clearVariables()
|
||||||
|
{
|
||||||
|
mFsaRights = 0;
|
||||||
|
mContentOwnerIdPos.offset = 0;
|
||||||
|
mContentOwnerIdPos.size = 0;
|
||||||
|
mSaveDataOwnerIdPos.offset = 0;
|
||||||
|
mSaveDataOwnerIdPos.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::calculateOffsets()
|
||||||
|
{
|
||||||
|
mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4);
|
||||||
|
mSaveDataOwnerIdPos.offset = mContentOwnerIdPos.offset + align(mContentOwnerIdPos.size, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FacHeader::isEqual(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FacHeader::copyFrom(const FacHeader & other)
|
||||||
|
{
|
||||||
|
if (other.getSize())
|
||||||
|
{
|
||||||
|
importBinary(other.getBytes(), other.getSize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mBinaryBlob.clear();
|
||||||
|
mFsaRights = other.mFsaRights;
|
||||||
|
mContentOwnerIdPos.offset = other.mContentOwnerIdPos.offset;
|
||||||
|
mContentOwnerIdPos.size = other.mContentOwnerIdPos.size;
|
||||||
|
mSaveDataOwnerIdPos.offset = other.mSaveDataOwnerIdPos.offset;
|
||||||
|
mSaveDataOwnerIdPos.size = other.mSaveDataOwnerIdPos.size;
|
||||||
|
}
|
||||||
|
}
|
93
lib/nx/FacHeader.h
Normal file
93
lib/nx/FacHeader.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <fnd/memory_blob.h>
|
||||||
|
#include <nx/ISerialiseableBinary.h>
|
||||||
|
|
||||||
|
class FacHeader :
|
||||||
|
public ISerialiseableBinary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FacHeader();
|
||||||
|
FacHeader(const FacHeader& other);
|
||||||
|
FacHeader(const u8* bytes);
|
||||||
|
|
||||||
|
bool operator==(const FacHeader& other) const;
|
||||||
|
bool operator!=(const FacHeader& other) const;
|
||||||
|
void operator=(const FacHeader& other);
|
||||||
|
|
||||||
|
// to be used after export
|
||||||
|
const u8* getBytes() const;
|
||||||
|
size_t getSize() const;
|
||||||
|
|
||||||
|
// export/import binary
|
||||||
|
void exportBinary();
|
||||||
|
void importBinary(const u8* bytes);
|
||||||
|
void importBinary(const u8* bytes, size_t len);
|
||||||
|
|
||||||
|
// variables
|
||||||
|
u64 getFacSize() const;
|
||||||
|
|
||||||
|
u64 getFsaRights() const;
|
||||||
|
void setFsaRights(u64 flag);
|
||||||
|
|
||||||
|
size_t getContentOwnerIdOffset() const;
|
||||||
|
size_t getContentOwnerIdSize() const;
|
||||||
|
void setContentOwnerIdSize(size_t size);
|
||||||
|
|
||||||
|
size_t getSaveDataOwnerIdOffset() const;
|
||||||
|
size_t getSaveDataOwnerIdSize() const;
|
||||||
|
void setSaveDataOwnerIdSize(size_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string kModuleName = "FAC_HEADER";
|
||||||
|
static const u32 kFacFormatVersion = 1;
|
||||||
|
|
||||||
|
#pragma pack (push, 1)
|
||||||
|
struct sFacHeader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
u32 version_; // default 1
|
||||||
|
u64 fac_flags_;
|
||||||
|
struct sFacSection
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
u32 start_;
|
||||||
|
u32 end_;
|
||||||
|
public:
|
||||||
|
u32 start() const { return le_word(start_); }
|
||||||
|
void set_start(u32 start) { start_ = le_word(start); }
|
||||||
|
|
||||||
|
u32 end() const { return le_word(end_); }
|
||||||
|
void set_end(u32 end) { end_ = le_word(end); }
|
||||||
|
} content_owner_ids_, save_data_owner_ids_; // the data for these follow later in binary. start/end relative to base of FacData instance
|
||||||
|
public:
|
||||||
|
u32 version() const { return le_word(version_); }
|
||||||
|
void set_version(u32 version) { version_ = le_word(version); }
|
||||||
|
|
||||||
|
u64 fac_flags() const { return le_dword(fac_flags_); }
|
||||||
|
void set_fac_flags(u64 fac_flags) { fac_flags_ = le_dword(fac_flags); }
|
||||||
|
|
||||||
|
const sFacSection& content_owner_ids() const { return content_owner_ids_; }
|
||||||
|
sFacSection& content_owner_ids() { return content_owner_ids_; }
|
||||||
|
|
||||||
|
const sFacSection& save_data_owner_ids() const { return save_data_owner_ids_; }
|
||||||
|
sFacSection& save_data_owner_ids() { return save_data_owner_ids_; }
|
||||||
|
};
|
||||||
|
#pragma pack (pop)
|
||||||
|
|
||||||
|
// raw binary
|
||||||
|
fnd::MemoryBlob mBinaryBlob;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
u64 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);
|
||||||
|
};
|
||||||
|
|
111
lib/nx/SacBinary.cpp
Normal file
111
lib/nx/SacBinary.cpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#include "SacBinary.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SacBinary::SacBinary()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SacBinary::SacBinary(const SacBinary & other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
SacBinary::SacBinary(const u8 * bytes, size_t len)
|
||||||
|
{
|
||||||
|
importBinary(bytes, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SacBinary::operator==(const SacBinary & other) const
|
||||||
|
{
|
||||||
|
return isEqual(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SacBinary::operator!=(const SacBinary & other) const
|
||||||
|
{
|
||||||
|
return !isEqual(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SacBinary::operator=(const SacBinary & other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8 * SacBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mBinaryBlob.getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SacBinary::getSize() const
|
||||||
|
{
|
||||||
|
return mBinaryBlob.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SacBinary::exportBinary()
|
||||||
|
{
|
||||||
|
size_t totalSize = 0;
|
||||||
|
for (size_t i = 0; i < mServices.getSize(); i++)
|
||||||
|
{
|
||||||
|
mServices[i].exportBinary();
|
||||||
|
totalSize += mServices[i].getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
mBinaryBlob.alloc(totalSize);
|
||||||
|
for (size_t i = 0, pos = 0; i < mServices.getSize(); pos += mServices[i].getSize(), i++)
|
||||||
|
{
|
||||||
|
memcpy((mBinaryBlob.getBytes() + pos), mServices[i].getBytes(), mServices[i].getSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SacBinary::importBinary(const u8 * bytes)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Unsupported operation. importBinary(const u8* bytes) is not supported for variable size structures.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SacBinary::importBinary(const u8 * bytes, size_t len)
|
||||||
|
{
|
||||||
|
clearVariables();
|
||||||
|
mBinaryBlob.alloc(len);
|
||||||
|
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
||||||
|
|
||||||
|
SacEntry svc;
|
||||||
|
for (size_t pos = 0; pos < len; pos += mServices.atBack().getSize())
|
||||||
|
{
|
||||||
|
svc.importBinary((const u8*)(mBinaryBlob.getBytes() + pos), len - pos);
|
||||||
|
mServices.addElement(svc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::List<SacEntry>& SacBinary::getServiceList() const
|
||||||
|
{
|
||||||
|
return mServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SacBinary::copyFrom(const SacBinary & other)
|
||||||
|
{
|
||||||
|
if (other.getSize())
|
||||||
|
{
|
||||||
|
importBinary(other.getBytes(), other.getSize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->mBinaryBlob.clear();
|
||||||
|
this->mServices = other.mServices;
|
||||||
|
}
|
||||||
|
}
|
46
lib/nx/SacBinary.h
Normal file
46
lib/nx/SacBinary.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <fnd/memory_blob.h>
|
||||||
|
#include <fnd/List.h>
|
||||||
|
#include <nx/ISerialiseableBinary.h>
|
||||||
|
#include <nx/SacEntry.h>
|
||||||
|
|
||||||
|
class SacBinary :
|
||||||
|
public ISerialiseableBinary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SacBinary();
|
||||||
|
SacBinary(const SacBinary& other);
|
||||||
|
SacBinary(const u8* bytes, size_t len);
|
||||||
|
|
||||||
|
bool operator==(const SacBinary& other) const;
|
||||||
|
bool operator!=(const SacBinary& other) const;
|
||||||
|
void operator=(const SacBinary& other);
|
||||||
|
|
||||||
|
// to be used after export
|
||||||
|
const u8* getBytes() const;
|
||||||
|
size_t getSize() const;
|
||||||
|
|
||||||
|
// export/import binary
|
||||||
|
void exportBinary();
|
||||||
|
void importBinary(const u8* bytes);
|
||||||
|
void importBinary(const u8* bytes, size_t len);
|
||||||
|
|
||||||
|
// variables
|
||||||
|
const fnd::List<SacEntry>& getServiceList() const;
|
||||||
|
void addService(const SacEntry& service);
|
||||||
|
private:
|
||||||
|
const std::string kModuleName = "SAC_BINARY";
|
||||||
|
|
||||||
|
// raw binary
|
||||||
|
fnd::MemoryBlob mBinaryBlob;
|
||||||
|
|
||||||
|
// variables
|
||||||
|
fnd::List<SacEntry> mServices;
|
||||||
|
|
||||||
|
void clearVariables();
|
||||||
|
bool isEqual(const SacBinary& other) const;
|
||||||
|
void copyFrom(const SacBinary& other);
|
||||||
|
};
|
||||||
|
|
|
@ -20,14 +20,20 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="AciHeader.h" />
|
<ClInclude Include="AciHeader.h" />
|
||||||
|
<ClInclude Include="FacBinary.h" />
|
||||||
|
<ClInclude Include="FacHeader.h" />
|
||||||
<ClInclude Include="ISerialiseableBinary.h" />
|
<ClInclude Include="ISerialiseableBinary.h" />
|
||||||
<ClInclude Include="NcaHeader.h" />
|
<ClInclude Include="NcaHeader.h" />
|
||||||
<ClInclude Include="NXCrypto.h" />
|
<ClInclude Include="NXCrypto.h" />
|
||||||
|
<ClInclude Include="SacBinary.h" />
|
||||||
<ClInclude Include="SacEntry.h" />
|
<ClInclude Include="SacEntry.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="AciHeader.cpp" />
|
<ClCompile Include="AciHeader.cpp" />
|
||||||
|
<ClCompile Include="FacBinary.cpp" />
|
||||||
|
<ClCompile Include="FacHeader.cpp" />
|
||||||
<ClCompile Include="NcaHeader.cpp" />
|
<ClCompile Include="NcaHeader.cpp" />
|
||||||
|
<ClCompile Include="SacBinary.cpp" />
|
||||||
<ClCompile Include="SacEntry.cpp" />
|
<ClCompile Include="SacEntry.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
|
|
|
@ -30,6 +30,15 @@
|
||||||
<ClInclude Include="ISerialiseableBinary.h">
|
<ClInclude Include="ISerialiseableBinary.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FacHeader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="FacBinary.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="SacBinary.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="NcaHeader.cpp">
|
<ClCompile Include="NcaHeader.cpp">
|
||||||
|
@ -41,5 +50,14 @@
|
||||||
<ClCompile Include="SacEntry.cpp">
|
<ClCompile Include="SacEntry.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FacHeader.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FacBinary.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="SacBinary.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in a new issue