mirror of
https://github.com/jakcron/nstool
synced 2024-11-23 05:59:29 +00:00
[nx] Update to new code style/design.
This commit is contained in:
parent
91c2d40111
commit
7a8d8e0fea
42 changed files with 1114 additions and 1593 deletions
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/MemoryBlob.h>
|
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <nx/AciHeader.h>
|
#include <nx/AciHeader.h>
|
||||||
#include <nx/FacBinary.h>
|
#include <nx/FacBinary.h>
|
||||||
|
@ -15,19 +14,15 @@ namespace nx
|
||||||
public:
|
public:
|
||||||
AciBinary();
|
AciBinary();
|
||||||
AciBinary(const AciBinary& other);
|
AciBinary(const AciBinary& other);
|
||||||
AciBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const AciBinary& other);
|
||||||
bool operator==(const AciBinary& other) const;
|
bool operator==(const AciBinary& other) const;
|
||||||
bool operator!=(const AciBinary& other) const;
|
bool operator!=(const AciBinary& other) const;
|
||||||
void operator=(const AciBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
virtual void exportBinary();
|
virtual void toBytes();
|
||||||
virtual void importBinary(const byte_t* bytes, size_t len);
|
virtual void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
@ -45,15 +40,12 @@ namespace nx
|
||||||
const std::string kModuleName = "ACI_BINARY";
|
const std::string kModuleName = "ACI_BINARY";
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
FacBinary mFac;
|
FacBinary mFac;
|
||||||
SacBinary mSac;
|
SacBinary mSac;
|
||||||
KcBinary mKc;
|
KcBinary mKc;
|
||||||
|
|
||||||
bool isEqual(const AciBinary& other) const;
|
|
||||||
void copyFrom(const AciBinary& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/aci.h>
|
#include <nx/aci.h>
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class AciHeader :
|
class AciHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum AciType
|
enum AciType
|
||||||
|
@ -42,19 +41,15 @@ namespace nx
|
||||||
|
|
||||||
AciHeader();
|
AciHeader();
|
||||||
AciHeader(const AciHeader& other);
|
AciHeader(const AciHeader& other);
|
||||||
AciHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const AciHeader& other);
|
||||||
bool operator==(const AciHeader& other) const;
|
bool operator==(const AciHeader& other) const;
|
||||||
bool operator!=(const AciHeader& other) const;
|
bool operator!=(const AciHeader& other) const;
|
||||||
void operator=(const AciHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
virtual void exportBinary();
|
virtual void toBytes();
|
||||||
virtual void importBinary(const byte_t* bytes, size_t len);
|
virtual void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
@ -91,7 +86,7 @@ namespace nx
|
||||||
const std::string kModuleName = "ACI_HEADER";
|
const std::string kModuleName = "ACI_HEADER";
|
||||||
|
|
||||||
// raw data
|
// raw data
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// ACI variables
|
// ACI variables
|
||||||
uint64_t mProgramId;
|
uint64_t mProgramId;
|
||||||
|
@ -109,8 +104,6 @@ namespace nx
|
||||||
sSection mFac, mSac, mKc;
|
sSection mFac, mSac, mKc;
|
||||||
|
|
||||||
void calculateSectionOffsets();
|
void calculateSectionOffsets();
|
||||||
bool isEqual(const AciHeader& other) const;
|
|
||||||
void copyFrom(const AciHeader& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/MemoryBlob.h>
|
|
||||||
#include <nx/AciBinary.h>
|
#include <nx/AciBinary.h>
|
||||||
#include <crypto/rsa.h>
|
#include <crypto/rsa.h>
|
||||||
|
|
||||||
|
@ -12,21 +11,17 @@ namespace nx
|
||||||
public:
|
public:
|
||||||
AcidBinary();
|
AcidBinary();
|
||||||
AcidBinary(const AcidBinary& other);
|
AcidBinary(const AcidBinary& other);
|
||||||
AcidBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const AcidBinary& other);
|
||||||
bool operator==(const AcidBinary& other) const;
|
bool operator==(const AcidBinary& other) const;
|
||||||
bool operator!=(const AcidBinary& other) const;
|
bool operator!=(const AcidBinary& other) const;
|
||||||
void operator=(const AcidBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
virtual void exportBinary();
|
void toBytes();
|
||||||
void signBinary(const crypto::rsa::sRsa2048Key& key);
|
void signBinary(const crypto::rsa::sRsa2048Key& key);
|
||||||
virtual void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
void verifyBinary(const crypto::rsa::sRsa2048Key& key) const;
|
void verifyBinary(const crypto::rsa::sRsa2048Key& key) const;
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
@ -38,13 +33,10 @@ namespace nx
|
||||||
const std::string kModuleName = "ACID_BINARY";
|
const std::string kModuleName = "ACID_BINARY";
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
crypto::rsa::sRsa2048Key mEmbeddedPublicKey;
|
crypto::rsa::sRsa2048Key mEmbeddedPublicKey;
|
||||||
|
|
||||||
bool isEqual(const AcidBinary& other) const;
|
|
||||||
void copyFrom(const AcidBinary& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/nacp.h>
|
#include <nx/nacp.h>
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class ApplicationControlPropertyBinary :
|
class ApplicationControlPropertyBinary :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sTitle
|
struct sTitle
|
||||||
|
@ -86,19 +85,15 @@ namespace nx
|
||||||
|
|
||||||
ApplicationControlPropertyBinary();
|
ApplicationControlPropertyBinary();
|
||||||
ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other);
|
ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other);
|
||||||
ApplicationControlPropertyBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const ApplicationControlPropertyBinary& other);
|
||||||
bool operator==(const ApplicationControlPropertyBinary& other) const;
|
bool operator==(const ApplicationControlPropertyBinary& other) const;
|
||||||
bool operator!=(const ApplicationControlPropertyBinary& other) const;
|
bool operator!=(const ApplicationControlPropertyBinary& other) const;
|
||||||
void operator=(const ApplicationControlPropertyBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -222,7 +217,7 @@ namespace nx
|
||||||
const std::string kModuleName = "APPLICATION_CONTROL_PROPERTY";
|
const std::string kModuleName = "APPLICATION_CONTROL_PROPERTY";
|
||||||
|
|
||||||
// raw data
|
// raw data
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
fnd::List<sTitle> mTitle;
|
fnd::List<sTitle> mTitle;
|
||||||
|
@ -263,8 +258,5 @@ namespace nx
|
||||||
nacp::PlayLogQueryCapability mPlayLogQueryCapability;
|
nacp::PlayLogQueryCapability mPlayLogQueryCapability;
|
||||||
nacp::RepairFlag mRepairFlag;
|
nacp::RepairFlag mRepairFlag;
|
||||||
byte_t mProgramIndex;
|
byte_t mProgramIndex;
|
||||||
|
|
||||||
bool isEqual(const ApplicationControlPropertyBinary& other) const;
|
|
||||||
void copyFrom(const ApplicationControlPropertyBinary& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <nx/cnmt.h>
|
#include <nx/cnmt.h>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class ContentMetaBinary :
|
class ContentMetaBinary :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct ContentInfo
|
struct ContentInfo
|
||||||
|
@ -18,13 +18,12 @@ namespace nx
|
||||||
size_t size;
|
size_t size;
|
||||||
cnmt::ContentType type;
|
cnmt::ContentType type;
|
||||||
|
|
||||||
ContentInfo& operator=(const ContentInfo& other)
|
void operator=(const ContentInfo& other)
|
||||||
{
|
{
|
||||||
hash = other.hash;
|
hash = other.hash;
|
||||||
memcpy(nca_id, other.nca_id, cnmt::kContentIdLen);
|
memcpy(nca_id, other.nca_id, cnmt::kContentIdLen);
|
||||||
size = other.size;
|
size = other.size;
|
||||||
type = other.type;
|
type = other.type;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ContentInfo& other) const
|
bool operator==(const ContentInfo& other) const
|
||||||
|
@ -48,13 +47,12 @@ namespace nx
|
||||||
cnmt::ContentMetaType type;
|
cnmt::ContentMetaType type;
|
||||||
byte_t attributes;
|
byte_t attributes;
|
||||||
|
|
||||||
ContentMetaInfo& operator=(const ContentMetaInfo& other)
|
void operator=(const ContentMetaInfo& other)
|
||||||
{
|
{
|
||||||
id = other.id;
|
id = other.id;
|
||||||
version = other.version;
|
version = other.version;
|
||||||
type = other.type;
|
type = other.type;
|
||||||
attributes = other.attributes;
|
attributes = other.attributes;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ContentMetaInfo& other) const
|
bool operator==(const ContentMetaInfo& other) const
|
||||||
|
@ -76,11 +74,10 @@ namespace nx
|
||||||
uint64_t patch_id;
|
uint64_t patch_id;
|
||||||
uint32_t required_system_version;
|
uint32_t required_system_version;
|
||||||
|
|
||||||
ApplicationMetaExtendedHeader& operator=(const ApplicationMetaExtendedHeader& other)
|
void operator=(const ApplicationMetaExtendedHeader& other)
|
||||||
{
|
{
|
||||||
patch_id = other.patch_id;
|
patch_id = other.patch_id;
|
||||||
required_system_version = other.required_system_version;
|
required_system_version = other.required_system_version;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ApplicationMetaExtendedHeader& other) const
|
bool operator==(const ApplicationMetaExtendedHeader& other) const
|
||||||
|
@ -100,11 +97,10 @@ namespace nx
|
||||||
uint64_t application_id;
|
uint64_t application_id;
|
||||||
uint32_t required_system_version;
|
uint32_t required_system_version;
|
||||||
|
|
||||||
PatchMetaExtendedHeader& operator=(const PatchMetaExtendedHeader& other)
|
void operator=(const PatchMetaExtendedHeader& other)
|
||||||
{
|
{
|
||||||
application_id = other.application_id;
|
application_id = other.application_id;
|
||||||
required_system_version = other.required_system_version;
|
required_system_version = other.required_system_version;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const PatchMetaExtendedHeader& other) const
|
bool operator==(const PatchMetaExtendedHeader& other) const
|
||||||
|
@ -124,11 +120,10 @@ namespace nx
|
||||||
uint64_t application_id;
|
uint64_t application_id;
|
||||||
uint32_t required_system_version;
|
uint32_t required_system_version;
|
||||||
|
|
||||||
AddOnContentMetaExtendedHeader& operator=(const AddOnContentMetaExtendedHeader& other)
|
void operator=(const AddOnContentMetaExtendedHeader& other)
|
||||||
{
|
{
|
||||||
application_id = other.application_id;
|
application_id = other.application_id;
|
||||||
required_system_version = other.required_system_version;
|
required_system_version = other.required_system_version;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const AddOnContentMetaExtendedHeader& other) const
|
bool operator==(const AddOnContentMetaExtendedHeader& other) const
|
||||||
|
@ -147,10 +142,9 @@ namespace nx
|
||||||
{
|
{
|
||||||
uint64_t application_id;
|
uint64_t application_id;
|
||||||
|
|
||||||
DeltaMetaExtendedHeader& operator=(const DeltaMetaExtendedHeader& other)
|
void operator=(const DeltaMetaExtendedHeader& other)
|
||||||
{
|
{
|
||||||
application_id = other.application_id;
|
application_id = other.application_id;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const DeltaMetaExtendedHeader& other) const
|
bool operator==(const DeltaMetaExtendedHeader& other) const
|
||||||
|
@ -166,15 +160,15 @@ namespace nx
|
||||||
|
|
||||||
ContentMetaBinary();
|
ContentMetaBinary();
|
||||||
ContentMetaBinary(const ContentMetaBinary& other);
|
ContentMetaBinary(const ContentMetaBinary& other);
|
||||||
ContentMetaBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
// to be used after export
|
void operator=(const ContentMetaBinary& other);
|
||||||
const byte_t* getBytes() const;
|
bool operator==(const ContentMetaBinary& other) const;
|
||||||
size_t getSize() const;
|
bool operator!=(const ContentMetaBinary& other) const;
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -212,8 +206,8 @@ namespace nx
|
||||||
const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& getContentMetaInfo() const;
|
const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& getContentMetaInfo() const;
|
||||||
void setContentMetaInfo(const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& info);
|
void setContentMetaInfo(const fnd::List<nx::ContentMetaBinary::ContentMetaInfo>& info);
|
||||||
|
|
||||||
const fnd::MemoryBlob& getExtendedData() const;
|
const fnd::Vec<byte_t>& getExtendedData() const;
|
||||||
void setExtendedData(const fnd::MemoryBlob& data);
|
void setExtendedData(const fnd::Vec<byte_t>& data);
|
||||||
|
|
||||||
const nx::sDigest& getDigest() const;
|
const nx::sDigest& getDigest() const;
|
||||||
void setDigest(const nx::sDigest& digest);
|
void setDigest(const nx::sDigest& digest);
|
||||||
|
@ -223,7 +217,7 @@ namespace nx
|
||||||
const std::string kModuleName = "CONTENT_META_BINARY";
|
const std::string kModuleName = "CONTENT_META_BINARY";
|
||||||
|
|
||||||
// binary blob
|
// binary blob
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
uint64_t mTitleId;
|
uint64_t mTitleId;
|
||||||
|
@ -231,7 +225,7 @@ namespace nx
|
||||||
cnmt::ContentMetaType mType;
|
cnmt::ContentMetaType mType;
|
||||||
byte_t mAttributes;
|
byte_t mAttributes;
|
||||||
uint32_t mRequiredDownloadSystemVersion;
|
uint32_t mRequiredDownloadSystemVersion;
|
||||||
fnd::MemoryBlob mExtendedHeader;
|
fnd::Vec<byte_t> mExtendedHeader;
|
||||||
|
|
||||||
ApplicationMetaExtendedHeader mApplicationMetaExtendedHeader;
|
ApplicationMetaExtendedHeader mApplicationMetaExtendedHeader;
|
||||||
PatchMetaExtendedHeader mPatchMetaExtendedHeader;
|
PatchMetaExtendedHeader mPatchMetaExtendedHeader;
|
||||||
|
@ -240,7 +234,7 @@ namespace nx
|
||||||
|
|
||||||
fnd::List<nx::ContentMetaBinary::ContentInfo> mContentInfo;
|
fnd::List<nx::ContentMetaBinary::ContentInfo> mContentInfo;
|
||||||
fnd::List<nx::ContentMetaBinary::ContentMetaInfo> mContentMetaInfo;
|
fnd::List<nx::ContentMetaBinary::ContentMetaInfo> mContentMetaInfo;
|
||||||
fnd::MemoryBlob mExtendedData;
|
fnd::Vec<byte_t> mExtendedData;
|
||||||
nx::sDigest mDigest;
|
nx::sDigest mDigest;
|
||||||
|
|
||||||
inline size_t getExtendedHeaderOffset() const { return sizeof(sContentMetaHeader); }
|
inline size_t getExtendedHeaderOffset() const { return sizeof(sContentMetaHeader); }
|
||||||
|
@ -253,8 +247,5 @@ namespace nx
|
||||||
bool validateExtendedHeaderSize(cnmt::ContentMetaType type, size_t exhdrSize) const;
|
bool validateExtendedHeaderSize(cnmt::ContentMetaType type, size_t exhdrSize) const;
|
||||||
size_t getExtendedDataSize(cnmt::ContentMetaType type, const byte_t* data) const;
|
size_t getExtendedDataSize(cnmt::ContentMetaType type, const byte_t* data) const;
|
||||||
void validateBinary(const byte_t* bytes, size_t len) const;
|
void validateBinary(const byte_t* bytes, size_t len) const;
|
||||||
|
|
||||||
bool isEqual(const ContentMetaBinary& other) const;
|
|
||||||
void copyFrom(const ContentMetaBinary& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/MemoryBlob.h>
|
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <nx/FacHeader.h>
|
#include <nx/FacHeader.h>
|
||||||
|
|
||||||
|
@ -13,19 +12,15 @@ namespace nx
|
||||||
public:
|
public:
|
||||||
FacBinary();
|
FacBinary();
|
||||||
FacBinary(const FacBinary& other);
|
FacBinary(const FacBinary& other);
|
||||||
FacBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const FacBinary& other);
|
||||||
bool operator==(const FacBinary& other) const;
|
bool operator==(const FacBinary& other) const;
|
||||||
bool operator!=(const FacBinary& other) const;
|
bool operator!=(const FacBinary& other) const;
|
||||||
void operator=(const FacBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -41,14 +36,11 @@ namespace nx
|
||||||
static const uint32_t kFacFormatVersion = 1;
|
static const uint32_t kFacFormatVersion = 1;
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
fnd::List<uint32_t> mContentOwnerIdList;
|
fnd::List<uint32_t> mContentOwnerIdList;
|
||||||
fnd::List<uint32_t> mSaveDataOwnerIdList;
|
fnd::List<uint32_t> mSaveDataOwnerIdList;
|
||||||
|
|
||||||
bool isEqual(const FacBinary& other) const;
|
|
||||||
void copyFrom(const FacBinary& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,49 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
#include <nx/fac.h>
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class FacHeader :
|
class FacHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum FsAccessFlag
|
struct sSection
|
||||||
{
|
{
|
||||||
FSA_APPLICATION_INFO,
|
size_t offset;
|
||||||
FSA_BOOT_MODE_CONTROL,
|
size_t size;
|
||||||
FSA_CALIBRATION,
|
|
||||||
FSA_SYSTEM_SAVE_DATA,
|
void operator=(const sSection& other)
|
||||||
FSA_GAME_CARD,
|
{
|
||||||
FSA_SAVE_DATA_BACKUP,
|
offset = other.offset;
|
||||||
FSA_SAVE_DATA_MANAGEMENT,
|
size = other.size;
|
||||||
FSA_BIS_ALL_RAW,
|
}
|
||||||
FSA_GAME_CARD_RAW,
|
|
||||||
FSA_GAME_CARD_PRIVATE,
|
bool operator==(const sSection& other) const
|
||||||
FSA_SET_TIME,
|
{
|
||||||
FSA_CONTENT_MANAGER,
|
return (offset == other.offset) \
|
||||||
FSA_IMAGE_MANAGER,
|
&& (size == other.size);
|
||||||
FSA_CREATE_SAVE_DATA,
|
}
|
||||||
FSA_SYSTEM_SAVE_DATA_MANAGEMENT,
|
|
||||||
FSA_BIS_FILE_SYSTEM,
|
bool operator!=(const sSection& other) const
|
||||||
FSA_SYSTEM_UPDATE,
|
{
|
||||||
FSA_SAVE_DATA_META,
|
return !operator==(other);
|
||||||
FSA_DEVICE_SAVE_CONTROL,
|
}
|
||||||
FSA_SETTINGS_CONTROL,
|
|
||||||
FSA_DEBUG = 62,
|
|
||||||
FSA_FULL_PERMISSION = 63,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
FacHeader();
|
FacHeader();
|
||||||
FacHeader(const FacHeader& other);
|
FacHeader(const FacHeader& other);
|
||||||
FacHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const FacHeader& other);
|
||||||
bool operator==(const FacHeader& other) const;
|
bool operator==(const FacHeader& other) const;
|
||||||
bool operator!=(const FacHeader& other) const;
|
bool operator!=(const FacHeader& other) const;
|
||||||
void operator=(const FacHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -59,49 +52,28 @@ namespace nx
|
||||||
uint32_t getFormatVersion() const;
|
uint32_t getFormatVersion() const;
|
||||||
void setFormatVersion(uint32_t version);
|
void setFormatVersion(uint32_t version);
|
||||||
|
|
||||||
const fnd::List<FsAccessFlag>& getFsaRightsList() const;
|
const fnd::List<fac::FsAccessFlag>& getFsaRightsList() const;
|
||||||
void setFsaRightsList(const fnd::List<FsAccessFlag>& list);
|
void setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list);
|
||||||
|
|
||||||
size_t getContentOwnerIdOffset() const;
|
const sSection& getContentOwnerIdPos() const;
|
||||||
size_t getContentOwnerIdSize() const;
|
|
||||||
void setContentOwnerIdSize(size_t size);
|
void setContentOwnerIdSize(size_t size);
|
||||||
|
|
||||||
size_t getSaveDataOwnerIdOffset() const;
|
const sSection& getSaveDataOwnerIdPos() const;;
|
||||||
size_t getSaveDataOwnerIdSize() const;
|
|
||||||
void setSaveDataOwnerIdSize(size_t size);
|
void setSaveDataOwnerIdSize(size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "FAC_HEADER";
|
const std::string kModuleName = "FAC_HEADER";
|
||||||
static const uint32_t kFacFormatVersion = 1;
|
|
||||||
|
|
||||||
#pragma pack (push, 1)
|
|
||||||
struct sFacHeader
|
|
||||||
{
|
|
||||||
le_uint32_t version; // default 1
|
|
||||||
le_uint64_t fac_flags;
|
|
||||||
struct sFacSection
|
|
||||||
{
|
|
||||||
le_uint32_t start;
|
|
||||||
le_uint32_t end;
|
|
||||||
} content_owner_ids, save_data_owner_ids; // the data for these follow later in binary. start/end relative to base of FacData instance
|
|
||||||
};
|
|
||||||
#pragma pack (pop)
|
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
uint32_t mVersion;
|
uint32_t mVersion;
|
||||||
fnd::List<FsAccessFlag> mFsaRights;
|
fnd::List<fac::FsAccessFlag> mFsaRights;
|
||||||
struct sSection
|
sSection mContentOwnerIdPos;
|
||||||
{
|
sSection mSaveDataOwnerIdPos;
|
||||||
size_t offset;
|
|
||||||
size_t size;
|
|
||||||
} mContentOwnerIdPos, mSaveDataOwnerIdPos;
|
|
||||||
|
|
||||||
void calculateOffsets();
|
void calculateOffsets();
|
||||||
bool isEqual(const FacHeader& other) const;
|
|
||||||
void copyFrom(const FacHeader& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <nx/hierarchicalintegrity.h>
|
#include <nx/hierarchicalintegrity.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class HierarchicalIntegrityHeader :
|
class HierarchicalIntegrityHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sLayer
|
struct sLayer
|
||||||
|
@ -36,19 +35,15 @@ namespace nx
|
||||||
|
|
||||||
HierarchicalIntegrityHeader();
|
HierarchicalIntegrityHeader();
|
||||||
HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader& other);
|
HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader& other);
|
||||||
HierarchicalIntegrityHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const HierarchicalIntegrityHeader& other);
|
||||||
bool operator==(const HierarchicalIntegrityHeader& other) const;
|
bool operator==(const HierarchicalIntegrityHeader& other) const;
|
||||||
bool operator!=(const HierarchicalIntegrityHeader& other) const;
|
bool operator!=(const HierarchicalIntegrityHeader& other) const;
|
||||||
void operator=(const HierarchicalIntegrityHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -62,14 +57,11 @@ namespace nx
|
||||||
const std::string kModuleName = "HIERARCHICAL_INTEGRITY_HEADER";
|
const std::string kModuleName = "HIERARCHICAL_INTEGRITY_HEADER";
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
fnd::List<sLayer> mLayerInfo;
|
fnd::List<sLayer> mLayerInfo;
|
||||||
fnd::List<crypto::sha::sSha256Hash> mMasterHashList;
|
fnd::List<crypto::sha::sSha256Hash> mMasterHashList;
|
||||||
|
|
||||||
bool isEqual(const HierarchicalIntegrityHeader& other) const;
|
|
||||||
void copyFrom(const HierarchicalIntegrityHeader& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,13 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <nx/hierarchicalsha256.h>
|
#include <nx/hierarchicalsha256.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class HierarchicalSha256Header :
|
class HierarchicalSha256Header :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sLayer
|
struct sLayer
|
||||||
|
@ -34,19 +33,15 @@ namespace nx
|
||||||
|
|
||||||
HierarchicalSha256Header();
|
HierarchicalSha256Header();
|
||||||
HierarchicalSha256Header(const HierarchicalSha256Header& other);
|
HierarchicalSha256Header(const HierarchicalSha256Header& other);
|
||||||
HierarchicalSha256Header(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const HierarchicalSha256Header& other);
|
||||||
bool operator==(const HierarchicalSha256Header& other) const;
|
bool operator==(const HierarchicalSha256Header& other) const;
|
||||||
bool operator!=(const HierarchicalSha256Header& other) const;
|
bool operator!=(const HierarchicalSha256Header& other) const;
|
||||||
void operator=(const HierarchicalSha256Header& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -63,15 +58,12 @@ namespace nx
|
||||||
const std::string kModuleName = "HIERARCHICAL_SHA256_HEADER";
|
const std::string kModuleName = "HIERARCHICAL_SHA256_HEADER";
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
crypto::sha::sSha256Hash mMasterHash;
|
crypto::sha::sSha256Hash mMasterHash;
|
||||||
size_t mHashBlockSize;
|
size_t mHashBlockSize;
|
||||||
fnd::List<sLayer> mLayerInfo;
|
fnd::List<sLayer> mLayerInfo;
|
||||||
|
|
||||||
bool isEqual(const HierarchicalSha256Header& other) const;
|
|
||||||
void copyFrom(const HierarchicalSha256Header& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/ThreadInfoHandler.h>
|
#include <nx/ThreadInfoHandler.h>
|
||||||
#include <nx/SystemCallHandler.h>
|
#include <nx/SystemCallHandler.h>
|
||||||
#include <nx/MemoryMappingHandler.h>
|
#include <nx/MemoryMappingHandler.h>
|
||||||
|
@ -16,24 +15,20 @@
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class KcBinary :
|
class KcBinary :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KcBinary();
|
KcBinary();
|
||||||
KcBinary(const KcBinary& other);
|
KcBinary(const KcBinary& other);
|
||||||
KcBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const KcBinary& other);
|
||||||
bool operator==(const KcBinary& other) const;
|
bool operator==(const KcBinary& other) const;
|
||||||
bool operator!=(const KcBinary& other) const;
|
bool operator!=(const KcBinary& other) const;
|
||||||
void operator=(const KcBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
virtual const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables (consider further abstraction?)
|
// variables (consider further abstraction?)
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -65,7 +60,7 @@ namespace nx
|
||||||
const std::string kModuleName = "KC_BINARY";
|
const std::string kModuleName = "KC_BINARY";
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
ThreadInfoHandler mThreadInfo;
|
ThreadInfoHandler mThreadInfo;
|
||||||
|
@ -76,11 +71,6 @@ namespace nx
|
||||||
KernelVersionHandler mKernelVersion;
|
KernelVersionHandler mKernelVersion;
|
||||||
HandleTableSizeHandler mHandleTableSize;
|
HandleTableSizeHandler mHandleTableSize;
|
||||||
MiscFlagsHandler mMiscFlags;
|
MiscFlagsHandler mMiscFlags;
|
||||||
|
|
||||||
|
|
||||||
void clearVariables();
|
|
||||||
bool isEqual(const KcBinary& other) const;
|
|
||||||
void copyFrom(const KcBinary& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,19 +49,18 @@ namespace nx
|
||||||
|
|
||||||
NcaHeader();
|
NcaHeader();
|
||||||
NcaHeader(const NcaHeader& other);
|
NcaHeader(const NcaHeader& other);
|
||||||
NcaHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const NcaHeader& other);
|
||||||
bool operator==(const NcaHeader& other) const;
|
bool operator==(const NcaHeader& other) const;
|
||||||
bool operator!=(const NcaHeader& other) const;
|
bool operator!=(const NcaHeader& other) const;
|
||||||
void operator=(const NcaHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
// to be used after export
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
size_t getSize() const;
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -95,7 +94,7 @@ namespace nx
|
||||||
const std::string kModuleName = "NCA_HEADER";
|
const std::string kModuleName = "NCA_HEADER";
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
FormatVersion mFormatVersion;
|
FormatVersion mFormatVersion;
|
||||||
|
@ -113,8 +112,6 @@ namespace nx
|
||||||
|
|
||||||
uint64_t blockNumToSize(uint32_t block_num) const;
|
uint64_t blockNumToSize(uint32_t block_num) const;
|
||||||
uint32_t sizeToBlockNum(uint64_t real_size) const;
|
uint32_t sizeToBlockNum(uint64_t real_size) const;
|
||||||
bool isEqual(const NcaHeader& other) const;
|
|
||||||
void copyFrom(const NcaHeader& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/MemoryBlob.h>
|
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <nx/NpdmHeader.h>
|
#include <nx/NpdmHeader.h>
|
||||||
#include <nx/AciBinary.h>
|
#include <nx/AciBinary.h>
|
||||||
|
@ -15,19 +14,15 @@ namespace nx
|
||||||
public:
|
public:
|
||||||
NpdmBinary();
|
NpdmBinary();
|
||||||
NpdmBinary(const NpdmBinary& other);
|
NpdmBinary(const NpdmBinary& other);
|
||||||
NpdmBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const NpdmBinary& other);
|
||||||
bool operator==(const NpdmBinary& other) const;
|
bool operator==(const NpdmBinary& other) const;
|
||||||
bool operator!=(const NpdmBinary& other) const;
|
bool operator!=(const NpdmBinary& other) const;
|
||||||
void operator=(const NpdmBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -41,14 +36,11 @@ namespace nx
|
||||||
const std::string kModuleName = "NPDM_BINARY";
|
const std::string kModuleName = "NPDM_BINARY";
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
AciBinary mAci;
|
AciBinary mAci;
|
||||||
AcidBinary mAcid;
|
AcidBinary mAcid;
|
||||||
|
|
||||||
bool isEqual(const NpdmBinary& other) const;
|
|
||||||
void copyFrom(const NpdmBinary& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/npdm.h>
|
#include <nx/npdm.h>
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class NpdmHeader :
|
class NpdmHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sSection
|
struct sSection
|
||||||
|
@ -36,19 +35,15 @@ namespace nx
|
||||||
|
|
||||||
NpdmHeader();
|
NpdmHeader();
|
||||||
NpdmHeader(const NpdmHeader& other);
|
NpdmHeader(const NpdmHeader& other);
|
||||||
NpdmHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const NpdmHeader& other);
|
||||||
bool operator==(const NpdmHeader& other) const;
|
bool operator==(const NpdmHeader& other) const;
|
||||||
bool operator!=(const NpdmHeader& other) const;
|
bool operator!=(const NpdmHeader& other) const;
|
||||||
void operator=(const NpdmHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -87,7 +82,7 @@ namespace nx
|
||||||
const std::string kModuleName = "NPDM_HEADER";
|
const std::string kModuleName = "NPDM_HEADER";
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
npdm::InstructionType mInstructionType;
|
npdm::InstructionType mInstructionType;
|
||||||
|
@ -102,8 +97,6 @@ namespace nx
|
||||||
sSection mAcidPos;
|
sSection mAcidPos;
|
||||||
|
|
||||||
void calculateOffsets();
|
void calculateOffsets();
|
||||||
bool isEqual(const NpdmHeader& other) const;
|
|
||||||
void copyFrom(const NpdmHeader& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <nx/nro.h>
|
#include <nx/nro.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class NroHeader :
|
class NroHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sRoCrt
|
struct sRoCrt
|
||||||
|
@ -75,19 +74,15 @@ namespace nx
|
||||||
|
|
||||||
NroHeader();
|
NroHeader();
|
||||||
NroHeader(const NroHeader& other);
|
NroHeader(const NroHeader& other);
|
||||||
NroHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const NroHeader& other);
|
||||||
bool operator==(const NroHeader& other) const;
|
bool operator==(const NroHeader& other) const;
|
||||||
bool operator!=(const NroHeader& other) const;
|
bool operator!=(const NroHeader& other) const;
|
||||||
void operator=(const NroHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -125,7 +120,7 @@ namespace nx
|
||||||
const std::string kModuleName = "NRO_HEADER";
|
const std::string kModuleName = "NRO_HEADER";
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
sRoCrt mRoCrt;
|
sRoCrt mRoCrt;
|
||||||
|
@ -138,10 +133,6 @@ namespace nx
|
||||||
sSection mRoEmbeddedInfo;
|
sSection mRoEmbeddedInfo;
|
||||||
sSection mRoDynStrInfo;
|
sSection mRoDynStrInfo;
|
||||||
sSection mRoDynSymInfo;
|
sSection mRoDynSymInfo;
|
||||||
|
|
||||||
// helpers
|
|
||||||
bool isEqual(const NroHeader& other) const;
|
|
||||||
void copyFrom(const NroHeader& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,13 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <nx/nso.h>
|
#include <nx/nso.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class NsoHeader :
|
class NsoHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sModuleId
|
struct sModuleId
|
||||||
|
@ -87,19 +86,15 @@ namespace nx
|
||||||
|
|
||||||
NsoHeader();
|
NsoHeader();
|
||||||
NsoHeader(const NsoHeader& other);
|
NsoHeader(const NsoHeader& other);
|
||||||
NsoHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const NsoHeader& other);
|
||||||
bool operator==(const NsoHeader& other) const;
|
bool operator==(const NsoHeader& other) const;
|
||||||
bool operator!=(const NsoHeader& other) const;
|
bool operator!=(const NsoHeader& other) const;
|
||||||
void operator=(const NsoHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -134,7 +129,7 @@ namespace nx
|
||||||
const std::string kModuleName = "NSO_HEADER";
|
const std::string kModuleName = "NSO_HEADER";
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
sModuleId mModuleId;
|
sModuleId mModuleId;
|
||||||
|
@ -146,10 +141,6 @@ namespace nx
|
||||||
sLayout mRoEmbeddedInfo;
|
sLayout mRoEmbeddedInfo;
|
||||||
sLayout mRoDynStrInfo;
|
sLayout mRoDynStrInfo;
|
||||||
sLayout mRoDynSymInfo;
|
sLayout mRoDynSymInfo;
|
||||||
|
|
||||||
// helpers
|
|
||||||
bool isEqual(const NsoHeader& other) const;
|
|
||||||
void copyFrom(const NsoHeader& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,16 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/pfs.h>
|
#include <nx/pfs.h>
|
||||||
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class PfsHeader :
|
class PfsHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum FsType
|
enum FsType
|
||||||
|
@ -64,24 +63,22 @@ namespace nx
|
||||||
|
|
||||||
PfsHeader();
|
PfsHeader();
|
||||||
PfsHeader(const PfsHeader& other);
|
PfsHeader(const PfsHeader& other);
|
||||||
PfsHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const PfsHeader& other);
|
||||||
bool operator==(const PfsHeader& other) const;
|
bool operator==(const PfsHeader& other) const;
|
||||||
bool operator!=(const PfsHeader& other) const;
|
bool operator!=(const PfsHeader& other) const;
|
||||||
void operator=(const PfsHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
// to be used after export
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
size_t getSize() const;
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
FsType getFsType() const;
|
FsType getFsType() const;
|
||||||
void setFsType(FsType type);
|
void setFsType(FsType type);
|
||||||
const fnd::List<sFile>& getFileList() const;
|
const fnd::List<sFile>& getFileList() const;
|
||||||
|
@ -92,7 +89,7 @@ namespace nx
|
||||||
const std::string kModuleName = "PFS_HEADER";
|
const std::string kModuleName = "PFS_HEADER";
|
||||||
|
|
||||||
// binary blob
|
// binary blob
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
FsType mFsType;
|
FsType mFsType;
|
||||||
|
@ -100,8 +97,6 @@ namespace nx
|
||||||
|
|
||||||
size_t getFileEntrySize(FsType fs_type);
|
size_t getFileEntrySize(FsType fs_type);
|
||||||
void calculateOffsets(size_t data_offset);
|
void calculateOffsets(size_t data_offset);
|
||||||
bool isEqual(const PfsHeader& other) const;
|
|
||||||
void copyFrom(const PfsHeader& other);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/SacEntry.h>
|
#include <nx/SacEntry.h>
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class SacBinary :
|
class SacBinary :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SacBinary();
|
SacBinary();
|
||||||
SacBinary(const SacBinary& other);
|
SacBinary(const SacBinary& other);
|
||||||
SacBinary(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const SacBinary& other);
|
||||||
bool operator==(const SacBinary& other) const;
|
bool operator==(const SacBinary& other) const;
|
||||||
bool operator!=(const SacBinary& other) const;
|
bool operator!=(const SacBinary& other) const;
|
||||||
void operator=(const SacBinary& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -36,13 +31,10 @@ namespace nx
|
||||||
const std::string kModuleName = "SAC_BINARY";
|
const std::string kModuleName = "SAC_BINARY";
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
fnd::List<SacEntry> mServices;
|
fnd::List<SacEntry> mServices;
|
||||||
|
|
||||||
bool isEqual(const SacBinary& other) const;
|
|
||||||
void copyFrom(const SacBinary& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,26 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class SacEntry :
|
class SacEntry :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SacEntry();
|
SacEntry();
|
||||||
SacEntry(const std::string& name, bool isServer);
|
SacEntry(const std::string& name, bool isServer);
|
||||||
SacEntry(const SacEntry& other);
|
SacEntry(const SacEntry& other);
|
||||||
|
|
||||||
|
void operator=(const SacEntry& other);
|
||||||
bool operator==(const SacEntry& other) const;
|
bool operator==(const SacEntry& other) const;
|
||||||
bool operator!=(const SacEntry& other) const;
|
bool operator!=(const SacEntry& other) const;
|
||||||
void operator=(const SacEntry& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -38,12 +34,12 @@ namespace nx
|
||||||
|
|
||||||
enum SacEntryFlag
|
enum SacEntryFlag
|
||||||
{
|
{
|
||||||
SAC_IS_SERVER = BIT(7),
|
SAC_IS_SERVER = _BIT(7),
|
||||||
SAC_NAME_LEN_MASK = BIT(7) - 1
|
SAC_NAME_LEN_MASK = _BIT(7) - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// raw binary
|
// raw binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
bool mIsServer;
|
bool mIsServer;
|
||||||
|
|
|
@ -1,30 +1,25 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <nx/xci.h>
|
#include <nx/xci.h>
|
||||||
#include <fnd/MemoryBlob.h>
|
#include <fnd/ISerialisable.h>
|
||||||
#include <fnd/List.h>
|
#include <fnd/List.h>
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
{
|
{
|
||||||
class XciHeader :
|
class XciHeader :
|
||||||
public fnd::ISerialiseableBinary
|
public fnd::ISerialisable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XciHeader();
|
XciHeader();
|
||||||
XciHeader(const XciHeader& other);
|
XciHeader(const XciHeader& other);
|
||||||
XciHeader(const byte_t* bytes, size_t len);
|
|
||||||
|
|
||||||
|
void operator=(const XciHeader& other);
|
||||||
bool operator==(const XciHeader& other) const;
|
bool operator==(const XciHeader& other) const;
|
||||||
bool operator!=(const XciHeader& other) const;
|
bool operator!=(const XciHeader& other) const;
|
||||||
void operator=(const XciHeader& other);
|
|
||||||
|
|
||||||
// to be used after export
|
|
||||||
const byte_t* getBytes() const;
|
|
||||||
size_t getSize() const;
|
|
||||||
|
|
||||||
// export/import binary
|
// export/import binary
|
||||||
void exportBinary();
|
void toBytes();
|
||||||
void importBinary(const byte_t* bytes, size_t len);
|
void fromBytes(const byte_t* bytes, size_t len);
|
||||||
|
const fnd::Vec<byte_t>& getBytes() const;
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -92,7 +87,7 @@ namespace nx
|
||||||
const std::string kModuleName = "XCI_HEADER";
|
const std::string kModuleName = "XCI_HEADER";
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
fnd::MemoryBlob mBinaryBlob;
|
fnd::Vec<byte_t> mRawBinary;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
uint32_t mRomAreaStartPage;
|
uint32_t mRomAreaStartPage;
|
||||||
|
@ -125,10 +120,6 @@ namespace nx
|
||||||
uint32_t mUppVersion;
|
uint32_t mUppVersion;
|
||||||
byte_t mUppHash[8];
|
byte_t mUppHash[8];
|
||||||
uint64_t mUppId;
|
uint64_t mUppId;
|
||||||
|
|
||||||
// helpers
|
|
||||||
bool isEqual(const XciHeader& other) const;
|
|
||||||
void copyFrom(const XciHeader& other);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fnd/types.h>
|
#include <fnd/types.h>
|
||||||
#include <crypto/aes.h>
|
|
||||||
#include <crypto/sha.h>
|
|
||||||
#include <fnd/ISerialiseableBinary.h>
|
|
||||||
#include <nx/macro.h>
|
#include <nx/macro.h>
|
||||||
|
|
||||||
namespace nx
|
namespace nx
|
||||||
|
|
49
lib/libnx/include/nx/fac.h
Normal file
49
lib/libnx/include/nx/fac.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
#include <fnd/types.h>
|
||||||
|
|
||||||
|
namespace nx
|
||||||
|
{
|
||||||
|
namespace fac
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t kFacFormatVersion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
struct sFacHeader
|
||||||
|
{
|
||||||
|
le_uint32_t version; // default 1
|
||||||
|
le_uint64_t fac_flags;
|
||||||
|
struct sFacSection
|
||||||
|
{
|
||||||
|
le_uint32_t start;
|
||||||
|
le_uint32_t end;
|
||||||
|
} content_owner_ids, save_data_owner_ids; // the data for these follow later in binary. start/end relative to base of FacData instance
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
}
|
|
@ -29,6 +29,7 @@
|
||||||
<ClInclude Include="include\nx\cnmt.h" />
|
<ClInclude Include="include\nx\cnmt.h" />
|
||||||
<ClInclude Include="include\nx\ContentMetaBinary.h" />
|
<ClInclude Include="include\nx\ContentMetaBinary.h" />
|
||||||
<ClInclude Include="include\nx\elf.h" />
|
<ClInclude Include="include\nx\elf.h" />
|
||||||
|
<ClInclude Include="include\nx\fac.h" />
|
||||||
<ClInclude Include="include\nx\FacBinary.h" />
|
<ClInclude Include="include\nx\FacBinary.h" />
|
||||||
<ClInclude Include="include\nx\FacHeader.h" />
|
<ClInclude Include="include\nx\FacHeader.h" />
|
||||||
<ClInclude Include="include\nx\HandleTableSizeEntry.h" />
|
<ClInclude Include="include\nx\HandleTableSizeEntry.h" />
|
||||||
|
|
|
@ -186,6 +186,9 @@
|
||||||
<ClInclude Include="include\nx\elf.h">
|
<ClInclude Include="include\nx\elf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\nx\fac.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="makefile" />
|
<None Include="makefile" />
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <nx/AciBinary.h>
|
#include <nx/AciBinary.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::AciBinary::AciBinary()
|
nx::AciBinary::AciBinary()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -9,96 +7,100 @@ nx::AciBinary::AciBinary()
|
||||||
|
|
||||||
nx::AciBinary::AciBinary(const AciBinary & other)
|
nx::AciBinary::AciBinary(const AciBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::AciBinary::AciBinary(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::AciBinary::operator==(const AciBinary & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::AciBinary::operator!=(const AciBinary & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::AciBinary::operator=(const AciBinary & other)
|
void nx::AciBinary::operator=(const AciBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size())
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AciHeader::operator=(other);
|
||||||
|
mFac = other.mFac;
|
||||||
|
mSac = other.mSac;
|
||||||
|
mKc = other.mKc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * nx::AciBinary::getBytes() const
|
bool nx::AciBinary::operator==(const AciBinary & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return (AciHeader::operator==(other)) \
|
||||||
|
&& (mFac == other.mFac) \
|
||||||
|
&& (mSac == other.mSac) \
|
||||||
|
&& (mKc == other.mKc);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::AciBinary::getSize() const
|
bool nx::AciBinary::operator!=(const AciBinary & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::AciBinary::exportBinary()
|
void nx::AciBinary::toBytes()
|
||||||
{
|
{
|
||||||
// export components
|
// export components
|
||||||
mFac.exportBinary();
|
mFac.toBytes();
|
||||||
mSac.exportBinary();
|
mSac.toBytes();
|
||||||
mKc.exportBinary();
|
mKc.toBytes();
|
||||||
|
|
||||||
// set sizes
|
// set sizes
|
||||||
setFacSize(mFac.getSize());
|
setFacSize(mFac.getBytes().size());
|
||||||
setSacSize(mSac.getSize());
|
setSacSize(mSac.getBytes().size());
|
||||||
setKcSize(mKc.getSize());
|
setKcSize(mKc.getBytes().size());
|
||||||
|
|
||||||
// export header
|
// export header
|
||||||
AciHeader::exportBinary();
|
AciHeader::toBytes();
|
||||||
|
|
||||||
// allocate binary
|
// allocate binary
|
||||||
mBinaryBlob.alloc(getAciSize());
|
mRawBinary.alloc(getAciSize());
|
||||||
|
|
||||||
// copy header
|
// copy header
|
||||||
memcpy(mBinaryBlob.getBytes(), AciHeader::getBytes(), AciHeader::getSize());
|
memcpy(mRawBinary.data(), AciHeader::getBytes().data(), AciHeader::getBytes().size());
|
||||||
|
|
||||||
// copy components
|
// copy components
|
||||||
memcpy(mBinaryBlob.getBytes() + getFacPos().offset, mFac.getBytes(), mFac.getSize());
|
memcpy(mRawBinary.data() + getFacPos().offset, mFac.getBytes().data(), mFac.getBytes().size());
|
||||||
memcpy(mBinaryBlob.getBytes() + getSacPos().offset, mSac.getBytes(), mSac.getSize());
|
memcpy(mRawBinary.data() + getSacPos().offset, mSac.getBytes().data(), mSac.getBytes().size());
|
||||||
memcpy(mBinaryBlob.getBytes() + getKcPos().offset, mKc.getBytes(), mKc.getSize());
|
memcpy(mRawBinary.data() + getKcPos().offset, mKc.getBytes().data(), mKc.getBytes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::AciBinary::importBinary(const byte_t * bytes, size_t len)
|
void nx::AciBinary::fromBytes(const byte_t * bytes, size_t len)
|
||||||
{
|
{
|
||||||
AciHeader::importBinary(bytes, len);
|
AciHeader::fromBytes(bytes, len);
|
||||||
|
|
||||||
if (getAciSize() > len)
|
if (getAciSize() > len)
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "ACI binary too small");
|
throw fnd::Exception(kModuleName, "ACI binary too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
mBinaryBlob.alloc(getAciSize());
|
mRawBinary.alloc(getAciSize());
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), bytes, mRawBinary.size());
|
||||||
|
|
||||||
if (getFacPos().size > 0)
|
if (getFacPos().size > 0)
|
||||||
{
|
{
|
||||||
mFac.importBinary(mBinaryBlob.getBytes() + getFacPos().offset, getFacPos().size);
|
mFac.fromBytes(mRawBinary.data() + getFacPos().offset, getFacPos().size);
|
||||||
}
|
}
|
||||||
if (getSacPos().size > 0)
|
if (getSacPos().size > 0)
|
||||||
{
|
{
|
||||||
mSac.importBinary(mBinaryBlob.getBytes() + getSacPos().offset, getSacPos().size);
|
mSac.fromBytes(mRawBinary.data() + getSacPos().offset, getSacPos().size);
|
||||||
}
|
}
|
||||||
if (getKcPos().size > 0)
|
if (getKcPos().size > 0)
|
||||||
{
|
{
|
||||||
mKc.importBinary(mBinaryBlob.getBytes() + getKcPos().offset, getKcPos().size);
|
mKc.fromBytes(mRawBinary.data() + getKcPos().offset, getKcPos().size);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::AciBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::AciBinary::clear()
|
void nx::AciBinary::clear()
|
||||||
{
|
{
|
||||||
AciHeader::clear();
|
AciHeader::clear();
|
||||||
|
mRawBinary.clear();
|
||||||
mFac.clear();
|
mFac.clear();
|
||||||
mSac.clear();
|
mSac.clear();
|
||||||
mKc.clear();
|
mKc.clear();
|
||||||
|
@ -133,26 +135,3 @@ void nx::AciBinary::setKc(const KcBinary & kc)
|
||||||
{
|
{
|
||||||
mKc = kc;
|
mKc = kc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::AciBinary::isEqual(const AciBinary & other) const
|
|
||||||
{
|
|
||||||
return (AciHeader::operator==(other)) \
|
|
||||||
&& (mFac == other.mFac) \
|
|
||||||
&& (mSac == other.mSac) \
|
|
||||||
&& (mKc == other.mKc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::AciBinary::copyFrom(const AciBinary & other)
|
|
||||||
{
|
|
||||||
if (other.getSize())
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AciHeader::operator=(other);
|
|
||||||
mFac = other.mFac;
|
|
||||||
mSac = other.mSac;
|
|
||||||
mKc = other.mKc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,33 +2,21 @@
|
||||||
|
|
||||||
using namespace nx;
|
using namespace nx;
|
||||||
|
|
||||||
void AciHeader::calculateSectionOffsets()
|
AciHeader::AciHeader()
|
||||||
{
|
{
|
||||||
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize);
|
clear();
|
||||||
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);
|
|
||||||
mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AciHeader::isEqual(const AciHeader & other) const
|
AciHeader::AciHeader(const AciHeader & other)
|
||||||
{
|
{
|
||||||
return (mHeaderOffset == other.mHeaderOffset) \
|
*this = other;
|
||||||
&& (mType == other.mType) \
|
|
||||||
&& (mIsProduction == other.mIsProduction) \
|
|
||||||
&& (mIsUnqualifiedApproval == other.mIsUnqualifiedApproval) \
|
|
||||||
&& (mAcidSize == other.mAcidSize) \
|
|
||||||
&& (mProgramIdMin == other.mProgramIdMin) \
|
|
||||||
&& (mProgramIdMax == other.mProgramIdMax) \
|
|
||||||
&& (mProgramId == other.mProgramId) \
|
|
||||||
&& (mFac == other.mFac) \
|
|
||||||
&& (mSac == other.mSac) \
|
|
||||||
&& (mKc == other.mKc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AciHeader::copyFrom(const AciHeader & other)
|
void AciHeader::operator=(const AciHeader & other)
|
||||||
{
|
{
|
||||||
if (other.getSize())
|
if (other.getBytes().size())
|
||||||
{
|
{
|
||||||
importBinary(other.getBytes(), other.getSize());
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -46,50 +34,30 @@ void AciHeader::copyFrom(const AciHeader & other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AciHeader::AciHeader()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
AciHeader::AciHeader(const AciHeader & other)
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
AciHeader::AciHeader(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AciHeader::operator==(const AciHeader & other) const
|
bool AciHeader::operator==(const AciHeader & other) const
|
||||||
{
|
{
|
||||||
return isEqual(other);
|
return (mHeaderOffset == other.mHeaderOffset) \
|
||||||
|
&& (mType == other.mType) \
|
||||||
|
&& (mIsProduction == other.mIsProduction) \
|
||||||
|
&& (mIsUnqualifiedApproval == other.mIsUnqualifiedApproval) \
|
||||||
|
&& (mAcidSize == other.mAcidSize) \
|
||||||
|
&& (mProgramIdMin == other.mProgramIdMin) \
|
||||||
|
&& (mProgramIdMax == other.mProgramIdMax) \
|
||||||
|
&& (mProgramId == other.mProgramId) \
|
||||||
|
&& (mFac == other.mFac) \
|
||||||
|
&& (mSac == other.mSac) \
|
||||||
|
&& (mKc == other.mKc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AciHeader::operator!=(const AciHeader & other) const
|
bool AciHeader::operator!=(const AciHeader & other) const
|
||||||
{
|
{
|
||||||
return !isEqual(other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AciHeader::operator=(const AciHeader & other)
|
void AciHeader::toBytes()
|
||||||
{
|
{
|
||||||
this->importBinary(other.getBytes(), other.getSize());
|
mRawBinary.alloc(sizeof(sAciHeader));
|
||||||
}
|
sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
|
||||||
|
|
||||||
const byte_t * AciHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AciHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AciHeader::exportBinary()
|
|
||||||
{
|
|
||||||
mBinaryBlob.alloc(sizeof(sAciHeader));
|
|
||||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
|
||||||
|
|
||||||
// set type
|
// set type
|
||||||
switch (mType)
|
switch (mType)
|
||||||
|
@ -135,7 +103,7 @@ void AciHeader::exportBinary()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AciHeader::importBinary(const byte_t * bytes, size_t len)
|
void AciHeader::fromBytes(const byte_t * bytes, size_t len)
|
||||||
{
|
{
|
||||||
if (len < sizeof(sAciHeader))
|
if (len < sizeof(sAciHeader))
|
||||||
{
|
{
|
||||||
|
@ -144,10 +112,10 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
mBinaryBlob.alloc(sizeof(sAciHeader));
|
mRawBinary.alloc(sizeof(sAciHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sAciHeader));
|
memcpy(mRawBinary.data(), bytes, sizeof(sAciHeader));
|
||||||
|
|
||||||
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
|
sAciHeader* hdr = (sAciHeader*)mRawBinary.data();
|
||||||
|
|
||||||
switch (hdr->signature.get())
|
switch (hdr->signature.get())
|
||||||
{
|
{
|
||||||
|
@ -192,9 +160,14 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
mKc.size = hdr->kc.size.get();
|
mKc.size = hdr->kc.size.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& AciHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::AciHeader::clear()
|
void nx::AciHeader::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mHeaderOffset = 0;
|
mHeaderOffset = 0;
|
||||||
mType = TYPE_ACI0;
|
mType = TYPE_ACI0;
|
||||||
mProgramId = 0;
|
mProgramId = 0;
|
||||||
|
@ -322,3 +295,10 @@ void AciHeader::setKcSize(size_t size)
|
||||||
{
|
{
|
||||||
mKc.size = size;
|
mKc.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AciHeader::calculateSectionOffsets()
|
||||||
|
{
|
||||||
|
mFac.offset = align(mHeaderOffset, aci::kAciAlignSize) + align(sizeof(sAciHeader), aci::kAciAlignSize);
|
||||||
|
mSac.offset = mFac.offset + align(mFac.size, aci::kAciAlignSize);
|
||||||
|
mKc.offset = mSac.offset + align(mSac.size, aci::kAciAlignSize);
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
#include <nx/AcidBinary.h>
|
#include <nx/AcidBinary.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::AcidBinary::AcidBinary()
|
nx::AcidBinary::AcidBinary()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -9,17 +7,106 @@ nx::AcidBinary::AcidBinary()
|
||||||
|
|
||||||
nx::AcidBinary::AcidBinary(const AcidBinary & other)
|
nx::AcidBinary::AcidBinary(const AcidBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::AcidBinary::AcidBinary(const byte_t * bytes, size_t len)
|
bool nx::AcidBinary::operator==(const AcidBinary & other) const
|
||||||
{
|
{
|
||||||
importBinary(bytes, len);
|
return AciBinary::operator==(other) \
|
||||||
|
&& (mEmbeddedPublicKey == other.mEmbeddedPublicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nx::AcidBinary::operator!=(const AcidBinary & other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::AcidBinary::operator=(const AcidBinary & other)
|
||||||
|
{
|
||||||
|
if (other.getBytes().size())
|
||||||
|
{
|
||||||
|
importBinary(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AciBinary::operator=(other);
|
||||||
|
mEmbeddedPublicKey = other.mEmbeddedPublicKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::AcidBinary::toBytes()
|
||||||
|
{
|
||||||
|
AciBinary::setHeaderOffset(crypto::rsa::kRsa2048Size); // not include signature
|
||||||
|
AciBinary::exportBinary();
|
||||||
|
mRawBinary.alloc(AciBinary::getBytes().size() + crypto::rsa::kRsa2048Size * 2);
|
||||||
|
|
||||||
|
memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size, mEmbeddedPublicKey.modulus, crypto::rsa::kRsa2048Size);
|
||||||
|
memcpy(mRawBinary.data() + crypto::rsa::kRsa2048Size * 2, AciBinary::getBytes().data(), AciBinary::getBytes().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::AcidBinary::signBinary(const crypto::rsa::sRsa2048Key & key)
|
||||||
|
{
|
||||||
|
if (mRawBinary.size() == 0)
|
||||||
|
{
|
||||||
|
exportBinary();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_t hash[crypto::sha::kSha256HashLen];
|
||||||
|
crypto::sha::Sha256(mRawBinary.data() + crypto::rsa::kRsa2048Size, mRawBinary.size() - crypto::rsa::kRsa2048Size, hash);
|
||||||
|
|
||||||
|
if (crypto::rsa::pkcs::rsaSign(key, crypto::sha::HASH_SHA256, hash, mRawBinary.data()) != 0)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Failed to sign ACID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::AcidBinary::fromBytes(const byte_t * 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::getBytes().size() + crypto::rsa::kRsa2048Size * 2;
|
||||||
|
if (acid_size > len)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "ACID binary too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
mRawBinary.alloc(acid_size);
|
||||||
|
memcpy(mRawBinary.data(), bytes, mRawBinary.size());
|
||||||
|
memcpy(mEmbeddedPublicKey.modulus, bytes + crypto::rsa::kRsa2048Size, crypto::rsa::kRsa2048Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::AcidBinary::verifyBinary(const crypto::rsa::sRsa2048Key & key) const
|
||||||
|
{
|
||||||
|
if (mRawBinary.size() == 0)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "No ACID binary exists to verify");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_t hash[crypto::sha::kSha256HashLen];
|
||||||
|
crypto::sha::Sha256(mRawBinary.data() + crypto::rsa::kRsa2048Size, mRawBinary.size() - crypto::rsa::kRsa2048Size, hash);
|
||||||
|
|
||||||
|
if (crypto::rsa::pss::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mRawBinary.data()) != 0)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "Failed to verify ACID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::AcidBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::AcidBinary::clear()
|
void nx::AcidBinary::clear()
|
||||||
{
|
{
|
||||||
AciBinary::clear();
|
AciBinary::clear();
|
||||||
|
mRawBinary.clear();
|
||||||
mEmbeddedPublicKey = crypto::rsa::sRsa2048Key();
|
mEmbeddedPublicKey = crypto::rsa::sRsa2048Key();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,111 +119,3 @@ void nx::AcidBinary::setNcaHeader2RsaKey(const crypto::rsa::sRsa2048Key & key)
|
||||||
{
|
{
|
||||||
mEmbeddedPublicKey = 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 byte_t * 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte_t 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 byte_t * 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) const
|
|
||||||
{
|
|
||||||
if (mBinaryBlob.getSize() == 0)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "No ACID binary exists to verify");
|
|
||||||
}
|
|
||||||
|
|
||||||
byte_t hash[crypto::sha::kSha256HashLen];
|
|
||||||
crypto::sha::Sha256(mBinaryBlob.getBytes() + crypto::rsa::kRsa2048Size, mBinaryBlob.getSize() - crypto::rsa::kRsa2048Size, hash);
|
|
||||||
|
|
||||||
if (crypto::rsa::pss::rsaVerify(key, crypto::sha::HASH_SHA256, hash, mBinaryBlob.getBytes()) != 0)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "Failed to verify ACID");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,17 +7,92 @@ nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary()
|
||||||
|
|
||||||
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other)
|
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const ApplicationControlPropertyBinary& other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::ApplicationControlPropertyBinary::ApplicationControlPropertyBinary(const byte_t* bytes, size_t len)
|
void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other)
|
||||||
{
|
{
|
||||||
importBinary(bytes, len);
|
clear();
|
||||||
|
mTitle = other.mTitle;
|
||||||
|
mIsbn = other.mIsbn;
|
||||||
|
mStartupUserAccount = other.mStartupUserAccount;
|
||||||
|
mTouchScreenUsageMode = other.mTouchScreenUsageMode;
|
||||||
|
mAocRegistrationType = other.mAocRegistrationType;
|
||||||
|
mAttributeFlag = other.mAttributeFlag;
|
||||||
|
mParentalControlFlag = other.mParentalControlFlag;
|
||||||
|
mScreenshotMode = other.mScreenshotMode;
|
||||||
|
mVideoCaptureMode = other.mVideoCaptureMode;
|
||||||
|
mDataLossConfirmation = other.mDataLossConfirmation;
|
||||||
|
mPlayLogPolicy = other.mPlayLogPolicy;
|
||||||
|
mPresenceGroupId = other.mPresenceGroupId;
|
||||||
|
mRatingAge = other.mRatingAge;
|
||||||
|
mDisplayVersion = other.mDisplayVersion;
|
||||||
|
mAocBaseId = other.mAocBaseId;
|
||||||
|
mSaveDatawOwnerId = other.mSaveDatawOwnerId;
|
||||||
|
mUserAccountSaveDataSize = other.mUserAccountSaveDataSize;
|
||||||
|
mDeviceSaveDataSize = other.mDeviceSaveDataSize;
|
||||||
|
mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize;
|
||||||
|
mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory;
|
||||||
|
mLocalCommunicationId = other.mLocalCommunicationId;
|
||||||
|
mLogoType = other.mLogoType;
|
||||||
|
mLogoHandling = other.mLogoHandling;
|
||||||
|
mRuntimeAocInstallMode = other.mRuntimeAocInstallMode;
|
||||||
|
mCrashReportMode = other.mCrashReportMode;
|
||||||
|
mHdcp = other.mHdcp;
|
||||||
|
mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId;
|
||||||
|
mBcatPassphase = other.mBcatPassphase;
|
||||||
|
mUserAccountSaveDataMax = other.mUserAccountSaveDataMax;
|
||||||
|
mDeviceSaveDataMax = other.mDeviceSaveDataMax;
|
||||||
|
mTemporaryStorageSize = other.mTemporaryStorageSize;
|
||||||
|
mCacheStorageSize = other.mCacheStorageSize;
|
||||||
|
mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax;
|
||||||
|
mCacheStorageIndex = other.mCacheStorageIndex;
|
||||||
|
mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId;
|
||||||
|
mPlayLogQueryCapability = other.mPlayLogQueryCapability;
|
||||||
|
mRepairFlag = other.mRepairFlag;
|
||||||
|
mProgramIndex = other.mProgramIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::ApplicationControlPropertyBinary::operator==(const ApplicationControlPropertyBinary& other) const
|
bool nx::ApplicationControlPropertyBinary::operator==(const ApplicationControlPropertyBinary& other) const
|
||||||
{
|
{
|
||||||
return isEqual(other);
|
return (mTitle == other.mTitle) \
|
||||||
|
&& (mIsbn == other.mIsbn) \
|
||||||
|
&& (mStartupUserAccount == other.mStartupUserAccount) \
|
||||||
|
&& (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \
|
||||||
|
&& (mAocRegistrationType == other.mAocRegistrationType) \
|
||||||
|
&& (mAttributeFlag == other.mAttributeFlag) \
|
||||||
|
&& (mParentalControlFlag == other.mParentalControlFlag) \
|
||||||
|
&& (mScreenshotMode == other.mScreenshotMode) \
|
||||||
|
&& (mVideoCaptureMode == other.mVideoCaptureMode) \
|
||||||
|
&& (mDataLossConfirmation == other.mDataLossConfirmation) \
|
||||||
|
&& (mPlayLogPolicy == other.mPlayLogPolicy) \
|
||||||
|
&& (mPresenceGroupId == other.mPresenceGroupId) \
|
||||||
|
&& (mRatingAge == other.mRatingAge) \
|
||||||
|
&& (mDisplayVersion == other.mDisplayVersion) \
|
||||||
|
&& (mAocBaseId == other.mAocBaseId) \
|
||||||
|
&& (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \
|
||||||
|
&& (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \
|
||||||
|
&& (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \
|
||||||
|
&& (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \
|
||||||
|
&& (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \
|
||||||
|
&& (mLocalCommunicationId == other.mLocalCommunicationId) \
|
||||||
|
&& (mLogoType == other.mLogoType) \
|
||||||
|
&& (mLogoHandling == other.mLogoHandling) \
|
||||||
|
&& (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \
|
||||||
|
&& (mCrashReportMode == other.mCrashReportMode) \
|
||||||
|
&& (mHdcp == other.mHdcp) \
|
||||||
|
&& (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \
|
||||||
|
&& (mBcatPassphase == other.mBcatPassphase) \
|
||||||
|
&& (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \
|
||||||
|
&& (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \
|
||||||
|
&& (mTemporaryStorageSize == other.mTemporaryStorageSize) \
|
||||||
|
&& (mCacheStorageSize == other.mCacheStorageSize) \
|
||||||
|
&& (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \
|
||||||
|
&& (mCacheStorageIndex == other.mCacheStorageIndex) \
|
||||||
|
&& (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \
|
||||||
|
&& (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \
|
||||||
|
&& (mRepairFlag == other.mRepairFlag) \
|
||||||
|
&& (mProgramIndex == other.mProgramIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPropertyBinary& other) const
|
bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPropertyBinary& other) const
|
||||||
|
@ -25,30 +100,15 @@ bool nx::ApplicationControlPropertyBinary::operator!=(const ApplicationControlPr
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::ApplicationControlPropertyBinary::operator=(const ApplicationControlPropertyBinary& other)
|
void nx::ApplicationControlPropertyBinary::toBytes()
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
mRawBinary.alloc(sizeof(nx::sApplicationControlProperty));
|
||||||
}
|
|
||||||
|
|
||||||
const byte_t* nx::ApplicationControlPropertyBinary::getBytes() const
|
sApplicationControlProperty* data = (sApplicationControlProperty*)mRawBinary.data();
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::ApplicationControlPropertyBinary::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::ApplicationControlPropertyBinary::exportBinary()
|
|
||||||
{
|
|
||||||
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty));
|
|
||||||
|
|
||||||
sApplicationControlProperty* data = (sApplicationControlProperty*)mBinaryBlob.getBytes();
|
|
||||||
|
|
||||||
// strings
|
// strings
|
||||||
uint32_t supported_langs = 0;
|
uint32_t supported_langs = 0;
|
||||||
for (size_t i = 0; i < mTitle.getSize(); i++)
|
for (size_t i = 0; i < mTitle.size(); i++)
|
||||||
{
|
{
|
||||||
supported_langs = _BIT(mTitle[i].language);
|
supported_langs = _BIT(mTitle[i].language);
|
||||||
strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength);
|
strncpy(data->title[mTitle[i].language].name, mTitle[i].name.c_str(), nacp::kNameLength);
|
||||||
|
@ -82,18 +142,18 @@ void nx::ApplicationControlPropertyBinary::exportBinary()
|
||||||
// misc params
|
// misc params
|
||||||
data->presence_group_id = mPresenceGroupId;
|
data->presence_group_id = mPresenceGroupId;
|
||||||
memset(data->rating_age, nacp::kUnusedAgeRating, nacp::kRatingAgeCount); // clear ratings
|
memset(data->rating_age, nacp::kUnusedAgeRating, nacp::kRatingAgeCount); // clear ratings
|
||||||
for (size_t i = 0; i < mRatingAge.getSize(); i++)
|
for (size_t i = 0; i < mRatingAge.size(); i++)
|
||||||
{
|
{
|
||||||
data->rating_age[mRatingAge[i].organisation] = mRatingAge[i].age;
|
data->rating_age[mRatingAge[i].organisation] = mRatingAge[i].age;
|
||||||
}
|
}
|
||||||
data->add_on_content_base_id = mAocBaseId;
|
data->add_on_content_base_id = mAocBaseId;
|
||||||
data->save_data_owner_id = mSaveDatawOwnerId;
|
data->save_data_owner_id = mSaveDatawOwnerId;
|
||||||
for (size_t i = 0; i < mLocalCommunicationId.getSize() && i < nacp::kLocalCommunicationIdCount; i++)
|
for (size_t i = 0; i < mLocalCommunicationId.size() && i < nacp::kLocalCommunicationIdCount; i++)
|
||||||
{
|
{
|
||||||
data->local_communication_id[i] = mLocalCommunicationId[i];
|
data->local_communication_id[i] = mLocalCommunicationId[i];
|
||||||
}
|
}
|
||||||
data->seed_for_pseudo_device_id = mSeedForPsuedoDeviceId;
|
data->seed_for_pseudo_device_id = mSeedForPsuedoDeviceId;
|
||||||
for (size_t i = 0; i < mPlayLogQueryableApplicationId.getSize() && i < nacp::kPlayLogQueryableApplicationIdCount; i++)
|
for (size_t i = 0; i < mPlayLogQueryableApplicationId.size() && i < nacp::kPlayLogQueryableApplicationIdCount; i++)
|
||||||
{
|
{
|
||||||
data->play_log_queryable_application_id[i] = mPlayLogQueryableApplicationId[i];
|
data->play_log_queryable_application_id[i] = mPlayLogQueryableApplicationId[i];
|
||||||
}
|
}
|
||||||
|
@ -116,7 +176,7 @@ void nx::ApplicationControlPropertyBinary::exportBinary()
|
||||||
data->cache_storage_data_and_journal_size_max = mCacheStorageDataAndJournalSizeMax;
|
data->cache_storage_data_and_journal_size_max = mCacheStorageDataAndJournalSizeMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, size_t len)
|
void nx::ApplicationControlPropertyBinary::fromBytes(const byte_t* bytes, size_t len)
|
||||||
{
|
{
|
||||||
if (len < sizeof(nx::sApplicationControlProperty))
|
if (len < sizeof(nx::sApplicationControlProperty))
|
||||||
{
|
{
|
||||||
|
@ -125,10 +185,10 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
mBinaryBlob.alloc(sizeof(nx::sApplicationControlProperty));
|
mRawBinary.alloc(sizeof(nx::sApplicationControlProperty));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), bytes, mRawBinary.size());
|
||||||
|
|
||||||
const sApplicationControlProperty* data = (const sApplicationControlProperty*)mBinaryBlob.getBytes();
|
const sApplicationControlProperty* data = (const sApplicationControlProperty*)mRawBinary.data();
|
||||||
|
|
||||||
// strings
|
// strings
|
||||||
for (size_t i = 0; i < nacp::kMaxLanguageCount; i++)
|
for (size_t i = 0; i < nacp::kMaxLanguageCount; i++)
|
||||||
|
@ -204,9 +264,14 @@ void nx::ApplicationControlPropertyBinary::importBinary(const byte_t* bytes, siz
|
||||||
mCacheStorageDataAndJournalSizeMax = (int64_t)data->cache_storage_data_and_journal_size_max.get();
|
mCacheStorageDataAndJournalSizeMax = (int64_t)data->cache_storage_data_and_journal_size_max.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::ApplicationControlPropertyBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::ApplicationControlPropertyBinary::clear()
|
void nx::ApplicationControlPropertyBinary::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mTitle.clear();
|
mTitle.clear();
|
||||||
mIsbn.clear();
|
mIsbn.clear();
|
||||||
mStartupUserAccount = nacp::USER_None;
|
mStartupUserAccount = nacp::USER_None;
|
||||||
|
@ -626,88 +691,3 @@ void nx::ApplicationControlPropertyBinary::setProgramIndex(byte_t var)
|
||||||
{
|
{
|
||||||
mProgramIndex = var;
|
mProgramIndex = var;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::ApplicationControlPropertyBinary::isEqual(const ApplicationControlPropertyBinary& other) const
|
|
||||||
{
|
|
||||||
return (mTitle == other.mTitle) \
|
|
||||||
&& (mIsbn == other.mIsbn) \
|
|
||||||
&& (mStartupUserAccount == other.mStartupUserAccount) \
|
|
||||||
&& (mTouchScreenUsageMode == other.mTouchScreenUsageMode) \
|
|
||||||
&& (mAocRegistrationType == other.mAocRegistrationType) \
|
|
||||||
&& (mAttributeFlag == other.mAttributeFlag) \
|
|
||||||
&& (mParentalControlFlag == other.mParentalControlFlag) \
|
|
||||||
&& (mScreenshotMode == other.mScreenshotMode) \
|
|
||||||
&& (mVideoCaptureMode == other.mVideoCaptureMode) \
|
|
||||||
&& (mDataLossConfirmation == other.mDataLossConfirmation) \
|
|
||||||
&& (mPlayLogPolicy == other.mPlayLogPolicy) \
|
|
||||||
&& (mPresenceGroupId == other.mPresenceGroupId) \
|
|
||||||
&& (mRatingAge == other.mRatingAge) \
|
|
||||||
&& (mDisplayVersion == other.mDisplayVersion) \
|
|
||||||
&& (mAocBaseId == other.mAocBaseId) \
|
|
||||||
&& (mSaveDatawOwnerId == other.mSaveDatawOwnerId) \
|
|
||||||
&& (mUserAccountSaveDataSize == other.mUserAccountSaveDataSize) \
|
|
||||||
&& (mDeviceSaveDataSize == other.mDeviceSaveDataSize) \
|
|
||||||
&& (mBcatDeliveryCacheStorageSize == other.mBcatDeliveryCacheStorageSize) \
|
|
||||||
&& (mApplicationErrorCodeCategory == other.mApplicationErrorCodeCategory) \
|
|
||||||
&& (mLocalCommunicationId == other.mLocalCommunicationId) \
|
|
||||||
&& (mLogoType == other.mLogoType) \
|
|
||||||
&& (mLogoHandling == other.mLogoHandling) \
|
|
||||||
&& (mRuntimeAocInstallMode == other.mRuntimeAocInstallMode) \
|
|
||||||
&& (mCrashReportMode == other.mCrashReportMode) \
|
|
||||||
&& (mHdcp == other.mHdcp) \
|
|
||||||
&& (mSeedForPsuedoDeviceId == other.mSeedForPsuedoDeviceId) \
|
|
||||||
&& (mBcatPassphase == other.mBcatPassphase) \
|
|
||||||
&& (mUserAccountSaveDataMax == other.mUserAccountSaveDataMax) \
|
|
||||||
&& (mDeviceSaveDataMax == other.mDeviceSaveDataMax) \
|
|
||||||
&& (mTemporaryStorageSize == other.mTemporaryStorageSize) \
|
|
||||||
&& (mCacheStorageSize == other.mCacheStorageSize) \
|
|
||||||
&& (mCacheStorageDataAndJournalSizeMax == other.mCacheStorageDataAndJournalSizeMax) \
|
|
||||||
&& (mCacheStorageIndex == other.mCacheStorageIndex) \
|
|
||||||
&& (mPlayLogQueryableApplicationId == other.mPlayLogQueryableApplicationId) \
|
|
||||||
&& (mPlayLogQueryCapability == other.mPlayLogQueryCapability) \
|
|
||||||
&& (mRepairFlag == other.mRepairFlag) \
|
|
||||||
&& (mProgramIndex == other.mProgramIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::ApplicationControlPropertyBinary::copyFrom(const ApplicationControlPropertyBinary& other)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
mTitle = other.mTitle;
|
|
||||||
mIsbn = other.mIsbn;
|
|
||||||
mStartupUserAccount = other.mStartupUserAccount;
|
|
||||||
mTouchScreenUsageMode = other.mTouchScreenUsageMode;
|
|
||||||
mAocRegistrationType = other.mAocRegistrationType;
|
|
||||||
mAttributeFlag = other.mAttributeFlag;
|
|
||||||
mParentalControlFlag = other.mParentalControlFlag;
|
|
||||||
mScreenshotMode = other.mScreenshotMode;
|
|
||||||
mVideoCaptureMode = other.mVideoCaptureMode;
|
|
||||||
mDataLossConfirmation = other.mDataLossConfirmation;
|
|
||||||
mPlayLogPolicy = other.mPlayLogPolicy;
|
|
||||||
mPresenceGroupId = other.mPresenceGroupId;
|
|
||||||
mRatingAge = other.mRatingAge;
|
|
||||||
mDisplayVersion = other.mDisplayVersion;
|
|
||||||
mAocBaseId = other.mAocBaseId;
|
|
||||||
mSaveDatawOwnerId = other.mSaveDatawOwnerId;
|
|
||||||
mUserAccountSaveDataSize = other.mUserAccountSaveDataSize;
|
|
||||||
mDeviceSaveDataSize = other.mDeviceSaveDataSize;
|
|
||||||
mBcatDeliveryCacheStorageSize = other.mBcatDeliveryCacheStorageSize;
|
|
||||||
mApplicationErrorCodeCategory = other.mApplicationErrorCodeCategory;
|
|
||||||
mLocalCommunicationId = other.mLocalCommunicationId;
|
|
||||||
mLogoType = other.mLogoType;
|
|
||||||
mLogoHandling = other.mLogoHandling;
|
|
||||||
mRuntimeAocInstallMode = other.mRuntimeAocInstallMode;
|
|
||||||
mCrashReportMode = other.mCrashReportMode;
|
|
||||||
mHdcp = other.mHdcp;
|
|
||||||
mSeedForPsuedoDeviceId = other.mSeedForPsuedoDeviceId;
|
|
||||||
mBcatPassphase = other.mBcatPassphase;
|
|
||||||
mUserAccountSaveDataMax = other.mUserAccountSaveDataMax;
|
|
||||||
mDeviceSaveDataMax = other.mDeviceSaveDataMax;
|
|
||||||
mTemporaryStorageSize = other.mTemporaryStorageSize;
|
|
||||||
mCacheStorageSize = other.mCacheStorageSize;
|
|
||||||
mCacheStorageDataAndJournalSizeMax = other.mCacheStorageDataAndJournalSizeMax;
|
|
||||||
mCacheStorageIndex = other.mCacheStorageIndex;
|
|
||||||
mPlayLogQueryableApplicationId = other.mPlayLogQueryableApplicationId;
|
|
||||||
mPlayLogQueryCapability = other.mPlayLogQueryCapability;
|
|
||||||
mRepairFlag = other.mRepairFlag;
|
|
||||||
mProgramIndex = other.mProgramIndex;
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ nx::ContentMetaBinary::ContentMetaBinary(const byte_t * bytes, size_t len)
|
||||||
|
|
||||||
const byte_t * nx::ContentMetaBinary::getBytes() const
|
const byte_t * nx::ContentMetaBinary::getBytes() const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return mRawBinary.getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::ContentMetaBinary::getSize() const
|
size_t nx::ContentMetaBinary::getSize() const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return mRawBinary.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::ContentMetaBinary::exportBinary()
|
void nx::ContentMetaBinary::exportBinary()
|
||||||
|
@ -118,7 +118,7 @@ void nx::ContentMetaBinary::importBinary(const byte_t * bytes, size_t len)
|
||||||
|
|
||||||
void nx::ContentMetaBinary::clear()
|
void nx::ContentMetaBinary::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mTitleId = 0;
|
mTitleId = 0;
|
||||||
mTitleVersion = 0;
|
mTitleVersion = 0;
|
||||||
mType = cnmt::METATYPE_SYSTEM_PROGRAM;
|
mType = cnmt::METATYPE_SYSTEM_PROGRAM;
|
||||||
|
|
|
@ -1,118 +1,100 @@
|
||||||
#include <nx/FacBinary.h>
|
#include <nx/FacBinary.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::FacBinary::FacBinary()
|
nx::FacBinary::FacBinary()
|
||||||
{}
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
nx::FacBinary::FacBinary(const FacBinary & other)
|
nx::FacBinary::FacBinary(const FacBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::FacBinary::FacBinary(const byte_t * 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)
|
void nx::FacBinary::operator=(const FacBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size())
|
||||||
}
|
|
||||||
|
|
||||||
const byte_t * nx::FacBinary::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::FacBinary::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::FacBinary::exportBinary()
|
|
||||||
{
|
|
||||||
FacHeader::setContentOwnerIdSize(mContentOwnerIdList.getSize() * sizeof(uint32_t));
|
|
||||||
FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.getSize() * sizeof(uint32_t));
|
|
||||||
FacHeader::exportBinary();
|
|
||||||
|
|
||||||
mBinaryBlob.alloc(getFacSize());
|
|
||||||
memcpy(mBinaryBlob.getBytes(), FacHeader::getBytes(), FacHeader::getSize());
|
|
||||||
|
|
||||||
uint32_t* rawContentOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset());
|
|
||||||
for (size_t i = 0; i < mContentOwnerIdList.getSize(); i++)
|
|
||||||
{
|
{
|
||||||
rawContentOwnerIds[i] = le_word(mContentOwnerIdList[i]);
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset());
|
|
||||||
for (size_t i = 0; i < mSaveDataOwnerIdList.getSize(); i++)
|
|
||||||
{
|
|
||||||
rawSaveDataOwnerIds[i] = le_word(mSaveDataOwnerIdList[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::FacBinary::importBinary(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
FacHeader::importBinary(bytes, len);
|
|
||||||
if (FacHeader::getFacSize() > len)
|
|
||||||
{
|
|
||||||
throw fnd::Exception(kModuleName, "FAC binary too small");
|
|
||||||
}
|
|
||||||
|
|
||||||
mBinaryBlob.alloc(FacHeader::getFacSize());
|
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
|
||||||
|
|
||||||
uint32_t* rawContentOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getContentOwnerIdOffset());
|
|
||||||
size_t rawContentOwnerIdNum = FacHeader::getContentOwnerIdSize() / sizeof(uint32_t);
|
|
||||||
for (size_t i = 0; i < rawContentOwnerIdNum; i++)
|
|
||||||
{
|
|
||||||
mContentOwnerIdList.addElement(le_word(rawContentOwnerIds[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t* rawSaveDataOwnerIds = (uint32_t*)(mBinaryBlob.getBytes() + FacHeader::getSaveDataOwnerIdOffset());
|
|
||||||
size_t rawSaveDataOwnerIdNum = FacHeader::getSaveDataOwnerIdSize() / sizeof(uint32_t);
|
|
||||||
for (size_t i = 0; i < rawSaveDataOwnerIdNum; i++)
|
|
||||||
{
|
|
||||||
mSaveDataOwnerIdList.addElement(le_word(rawSaveDataOwnerIds[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::FacBinary::isEqual(const FacBinary & other) const
|
|
||||||
{
|
|
||||||
return (FacHeader::operator==(other)) \
|
|
||||||
&& (mContentOwnerIdList == other.mContentOwnerIdList) \
|
|
||||||
&& (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::FacBinary::copyFrom(const FacBinary & other)
|
|
||||||
{
|
|
||||||
if (other.getSize())
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
FacHeader::operator=(other);
|
FacHeader::operator=(other);
|
||||||
mContentOwnerIdList = other.mContentOwnerIdList;
|
mContentOwnerIdList = other.mContentOwnerIdList;
|
||||||
mSaveDataOwnerIdList = other.mSaveDataOwnerIdList;
|
mSaveDataOwnerIdList = other.mSaveDataOwnerIdList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nx::FacBinary::operator==(const FacBinary & other) const
|
||||||
|
{
|
||||||
|
return (FacHeader::operator==(other)) \
|
||||||
|
&& (mContentOwnerIdList == other.mContentOwnerIdList) \
|
||||||
|
&& (mSaveDataOwnerIdList == other.mSaveDataOwnerIdList);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nx::FacBinary::operator!=(const FacBinary & other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::FacBinary::toBytes()
|
||||||
|
{
|
||||||
|
FacHeader::setContentOwnerIdSize(mContentOwnerIdList.size() * sizeof(uint32_t));
|
||||||
|
FacHeader::setSaveDataOwnerIdSize(mSaveDataOwnerIdList.size() * sizeof(uint32_t));
|
||||||
|
FacHeader::toBytes();
|
||||||
|
|
||||||
|
mRawBinary.alloc(getFacSize());
|
||||||
|
memcpy(mRawBinary.data(), FacHeader::getBytes().data(), FacHeader::getBytes().size());
|
||||||
|
|
||||||
|
uint32_t* rawContentOwnerIds = (uint32_t*)(mRawBinary.data() + FacHeader::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);
|
||||||
|
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::fromBytes(data, len);
|
||||||
|
if (FacHeader::getFacSize() > len)
|
||||||
|
{
|
||||||
|
throw fnd::Exception(kModuleName, "FAC binary too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
mRawBinary.alloc(FacHeader::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);
|
||||||
|
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);
|
||||||
|
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()
|
void nx::FacBinary::clear()
|
||||||
{
|
{
|
||||||
FacHeader::clear();
|
FacHeader::clear();
|
||||||
|
mRawBinary.clear();
|
||||||
mContentOwnerIdList.clear();
|
mContentOwnerIdList.clear();
|
||||||
mSaveDataOwnerIdList.clear();
|
mSaveDataOwnerIdList.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <nx/FacHeader.h>
|
#include <nx/FacHeader.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::FacHeader::FacHeader() :
|
nx::FacHeader::FacHeader() :
|
||||||
mFsaRights()
|
mFsaRights()
|
||||||
{
|
{
|
||||||
|
@ -11,55 +9,55 @@ nx::FacHeader::FacHeader() :
|
||||||
nx::FacHeader::FacHeader(const FacHeader & other) :
|
nx::FacHeader::FacHeader(const FacHeader & other) :
|
||||||
mFsaRights()
|
mFsaRights()
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::FacHeader::FacHeader(const byte_t * bytes, size_t len) :
|
|
||||||
mFsaRights()
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::FacHeader::operator==(const FacHeader & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::FacHeader::operator!=(const FacHeader & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FacHeader::operator=(const FacHeader & other)
|
void nx::FacHeader::operator=(const FacHeader & other)
|
||||||
{
|
{
|
||||||
copyFrom(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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * nx::FacHeader::getBytes() const
|
bool nx::FacHeader::operator==(const FacHeader & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return (mFsaRights == other.mFsaRights) \
|
||||||
|
&& (mContentOwnerIdPos.offset == other.mContentOwnerIdPos.offset) \
|
||||||
|
&& (mContentOwnerIdPos.size == other.mContentOwnerIdPos.size) \
|
||||||
|
&& (mSaveDataOwnerIdPos.offset == other.mSaveDataOwnerIdPos.offset) \
|
||||||
|
&& (mSaveDataOwnerIdPos.size == other.mSaveDataOwnerIdPos.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::FacHeader::getSize() const
|
bool nx::FacHeader::operator!=(const FacHeader & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FacHeader::exportBinary()
|
void nx::FacHeader::toBytes()
|
||||||
{
|
{
|
||||||
mBinaryBlob.alloc(sizeof(sFacHeader));
|
mRawBinary.alloc(sizeof(sFacHeader));
|
||||||
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
|
||||||
|
|
||||||
if (mVersion != kFacFormatVersion)
|
if (mVersion != fac::kFacFormatVersion)
|
||||||
{
|
{
|
||||||
fnd::Exception(kModuleName, "Unsupported format version");
|
fnd::Exception(kModuleName, "Unsupported format version");
|
||||||
}
|
}
|
||||||
hdr->version = (mVersion);
|
hdr->version = (mVersion);
|
||||||
|
|
||||||
uint64_t flag = 0;
|
uint64_t flag = 0;
|
||||||
for (size_t i = 0; i < mFsaRights.getSize(); i++)
|
for (size_t i = 0; i < mFsaRights.size(); i++)
|
||||||
{
|
{
|
||||||
flag |= BIT((uint64_t)mFsaRights[i]);
|
flag |= _BIT((uint64_t)mFsaRights[i]);
|
||||||
}
|
}
|
||||||
hdr->fac_flags = (flag);
|
hdr->fac_flags = (flag);
|
||||||
|
|
||||||
|
@ -70,18 +68,18 @@ void nx::FacHeader::exportBinary()
|
||||||
hdr->save_data_owner_ids.end = (uint32_t)(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size);
|
hdr->save_data_owner_ids.end = (uint32_t)(mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FacHeader::importBinary(const byte_t * bytes, size_t len)
|
void nx::FacHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
if (len < sizeof(sFacHeader))
|
if (len < sizeof(sFacHeader))
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "FAC header too small");
|
throw fnd::Exception(kModuleName, "FAC header too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
mBinaryBlob.alloc(sizeof(sFacHeader));
|
mRawBinary.alloc(sizeof(sFacHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
sFacHeader* hdr = (sFacHeader*)mBinaryBlob.getBytes();
|
sFacHeader* hdr = (sFacHeader*)mRawBinary.data();
|
||||||
|
|
||||||
if (hdr->version.get() != kFacFormatVersion)
|
if (hdr->version.get() != fac::kFacFormatVersion)
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "Unsupported FAC format version");
|
throw fnd::Exception(kModuleName, "Unsupported FAC format version");
|
||||||
}
|
}
|
||||||
|
@ -90,9 +88,9 @@ void nx::FacHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
clear();
|
clear();
|
||||||
for (uint64_t i = 0; i < 64; i++)
|
for (uint64_t i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
if ((hdr->fac_flags.get() >> i) & 1)
|
if (_HAS_BIT(hdr->fac_flags.get(), i))
|
||||||
{
|
{
|
||||||
mFsaRights.addElement((FsAccessFlag)i);
|
mFsaRights.addElement((fac::FsAccessFlag)i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mContentOwnerIdPos.offset = hdr->content_owner_ids.start.get();
|
mContentOwnerIdPos.offset = hdr->content_owner_ids.start.get();
|
||||||
|
@ -101,6 +99,11 @@ void nx::FacHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
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;
|
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()
|
void nx::FacHeader::clear()
|
||||||
{
|
{
|
||||||
mFsaRights.clear();
|
mFsaRights.clear();
|
||||||
|
@ -112,9 +115,9 @@ void nx::FacHeader::clear()
|
||||||
|
|
||||||
size_t nx::FacHeader::getFacSize() const
|
size_t nx::FacHeader::getFacSize() const
|
||||||
{
|
{
|
||||||
size_t savedata = getSaveDataOwnerIdOffset() + getSaveDataOwnerIdSize();
|
size_t savedata = mSaveDataOwnerIdPos.offset + mSaveDataOwnerIdPos.size;
|
||||||
size_t content = getContentOwnerIdOffset() + getContentOwnerIdSize();
|
size_t content = mContentOwnerIdPos.offset + mContentOwnerIdPos.size;
|
||||||
return MAX(MAX(savedata, content), sizeof(sFacHeader));
|
return _MAX(_MAX(savedata, content), sizeof(sFacHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nx::FacHeader::getFormatVersion() const
|
uint32_t nx::FacHeader::getFormatVersion() const
|
||||||
|
@ -127,28 +130,23 @@ void nx::FacHeader::setFormatVersion(uint32_t version)
|
||||||
mVersion = version;
|
mVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fnd::List<nx::FacHeader::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const
|
const fnd::List<nx::fac::FsAccessFlag>& nx::FacHeader::getFsaRightsList() const
|
||||||
{
|
{
|
||||||
return mFsaRights;
|
return mFsaRights;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FacHeader::setFsaRightsList(const fnd::List<FsAccessFlag>& list)
|
void nx::FacHeader::setFsaRightsList(const fnd::List<fac::FsAccessFlag>& list)
|
||||||
{
|
{
|
||||||
mFsaRights.clear();
|
mFsaRights.clear();
|
||||||
for (size_t i = 0; i < list.getSize(); i++)
|
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");
|
mFsaRights.hasElement(list[i]) ? mFsaRights.addElement(list[i]) : throw fnd::Exception(kModuleName, "FSA right already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::FacHeader::getContentOwnerIdOffset() const
|
const nx::FacHeader::sSection& nx::FacHeader::getContentOwnerIdPos() const
|
||||||
{
|
{
|
||||||
return mContentOwnerIdPos.offset;
|
return mContentOwnerIdPos;
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::FacHeader::getContentOwnerIdSize() const
|
|
||||||
{
|
|
||||||
return mContentOwnerIdPos.size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FacHeader::setContentOwnerIdSize(size_t size)
|
void nx::FacHeader::setContentOwnerIdSize(size_t size)
|
||||||
|
@ -156,14 +154,9 @@ void nx::FacHeader::setContentOwnerIdSize(size_t size)
|
||||||
mContentOwnerIdPos.size = size;
|
mContentOwnerIdPos.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::FacHeader::getSaveDataOwnerIdOffset() const
|
const nx::FacHeader::sSection& nx::FacHeader::getSaveDataOwnerIdPos() const
|
||||||
{
|
{
|
||||||
return mSaveDataOwnerIdPos.offset;
|
return mSaveDataOwnerIdPos;
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::FacHeader::getSaveDataOwnerIdSize() const
|
|
||||||
{
|
|
||||||
return mSaveDataOwnerIdPos.size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::FacHeader::setSaveDataOwnerIdSize(size_t size)
|
void nx::FacHeader::setSaveDataOwnerIdSize(size_t size)
|
||||||
|
@ -176,29 +169,3 @@ void nx::FacHeader::calculateOffsets()
|
||||||
mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4);
|
mContentOwnerIdPos.offset = align(sizeof(sFacHeader), 4);
|
||||||
mSaveDataOwnerIdPos.offset = mContentOwnerIdPos.offset + align(mContentOwnerIdPos.size, 4);
|
mSaveDataOwnerIdPos.offset = mContentOwnerIdPos.offset + align(mContentOwnerIdPos.size, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::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 nx::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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,45 +8,40 @@ nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader()
|
||||||
|
|
||||||
nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other)
|
nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::HierarchicalIntegrityHeader::operator=(const HierarchicalIntegrityHeader & other)
|
void nx::HierarchicalIntegrityHeader::operator=(const HierarchicalIntegrityHeader & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size() != 0)
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
mLayerInfo = other.mLayerInfo;
|
||||||
|
mMasterHashList = other.mMasterHashList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * nx::HierarchicalIntegrityHeader::getBytes() const
|
bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return (mLayerInfo == other.mLayerInfo) \
|
||||||
|
&& (mMasterHashList == other.mMasterHashList);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::HierarchicalIntegrityHeader::getSize() const
|
bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::HierarchicalIntegrityHeader::exportBinary()
|
void nx::HierarchicalIntegrityHeader::toBytes()
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
|
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t len)
|
void nx::HierarchicalIntegrityHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
std::stringstream error_str;
|
std::stringstream error_str;
|
||||||
|
|
||||||
|
@ -56,7 +51,7 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t
|
||||||
throw fnd::Exception(kModuleName, "Header too small");
|
throw fnd::Exception(kModuleName, "Header too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)bytes;
|
const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)data;
|
||||||
|
|
||||||
// Validate Header Sig "IVFC"
|
// Validate Header Sig "IVFC"
|
||||||
if (hdr->signature.get() != hierarchicalintegrity::kStructSig)
|
if (hdr->signature.get() != hierarchicalintegrity::kStructSig)
|
||||||
|
@ -92,24 +87,29 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy to internal storage
|
// copy to internal storage
|
||||||
mBinaryBlob.alloc(total_size);
|
mRawBinary.alloc(total_size);
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
// save layer info
|
// save layer info
|
||||||
const nx::sHierarchicalIntegrityLayerInfo* layer_info = (const nx::sHierarchicalIntegrityLayerInfo*)(mBinaryBlob.getBytes() + sizeof(nx::sHierarchicalIntegrityHeader));
|
const nx::sHierarchicalIntegrityLayerInfo* layer_info = (const nx::sHierarchicalIntegrityLayerInfo*)(mRawBinary.data() + sizeof(nx::sHierarchicalIntegrityHeader));
|
||||||
for (size_t i = 0; i < hierarchicalintegrity::kDefaultLayerNum; i++)
|
for (size_t i = 0; i < hierarchicalintegrity::kDefaultLayerNum; i++)
|
||||||
{
|
{
|
||||||
mLayerInfo.addElement({layer_info[i].offset.get(), layer_info[i].size.get(), layer_info[i].block_size.get()});
|
mLayerInfo.addElement({layer_info[i].offset.get(), layer_info[i].size.get(), layer_info[i].block_size.get()});
|
||||||
}
|
}
|
||||||
|
|
||||||
// save hash list
|
// save hash list
|
||||||
const crypto::sha::sSha256Hash* hash_list = (const crypto::sha::sSha256Hash*)(mBinaryBlob.getBytes() + master_hash_offset);
|
const crypto::sha::sSha256Hash* hash_list = (const crypto::sha::sSha256Hash*)(mRawBinary.data() + master_hash_offset);
|
||||||
for (size_t i = 0; i < hdr->master_hash_size.get()/sizeof(crypto::sha::sSha256Hash); i++)
|
for (size_t i = 0; i < hdr->master_hash_size.get()/sizeof(crypto::sha::sSha256Hash); i++)
|
||||||
{
|
{
|
||||||
mMasterHashList.addElement(hash_list[i]);
|
mMasterHashList.addElement(hash_list[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::HierarchicalIntegrityHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::HierarchicalIntegrityHeader::clear()
|
void nx::HierarchicalIntegrityHeader::clear()
|
||||||
{
|
{
|
||||||
mLayerInfo.clear();
|
mLayerInfo.clear();
|
||||||
|
@ -135,22 +135,3 @@ void nx::HierarchicalIntegrityHeader::setMasterHashList(const fnd::List<crypto::
|
||||||
{
|
{
|
||||||
mMasterHashList = master_hash_list;
|
mMasterHashList = master_hash_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::HierarchicalIntegrityHeader::isEqual(const HierarchicalIntegrityHeader & other) const
|
|
||||||
{
|
|
||||||
return (mLayerInfo == other.mLayerInfo) \
|
|
||||||
&& (mMasterHashList == other.mMasterHashList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::HierarchicalIntegrityHeader::copyFrom(const HierarchicalIntegrityHeader & other)
|
|
||||||
{
|
|
||||||
if (other.getSize() != 0)
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mLayerInfo = other.mLayerInfo;
|
|
||||||
mMasterHashList = other.mMasterHashList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <nx/HierarchicalSha256Header.h>
|
#include <nx/HierarchicalSha256Header.h>
|
||||||
|
|
||||||
|
|
||||||
nx::HierarchicalSha256Header::HierarchicalSha256Header()
|
nx::HierarchicalSha256Header::HierarchicalSha256Header()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -9,45 +8,41 @@ nx::HierarchicalSha256Header::HierarchicalSha256Header()
|
||||||
|
|
||||||
nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other)
|
nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::HierarchicalSha256Header::HierarchicalSha256Header(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::HierarchicalSha256Header::operator=(const HierarchicalSha256Header & other)
|
void nx::HierarchicalSha256Header::operator=(const HierarchicalSha256Header & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size() != 0)
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMasterHash = other.mMasterHash;
|
||||||
|
mHashBlockSize = other.mHashBlockSize;
|
||||||
|
mLayerInfo = other.mLayerInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * nx::HierarchicalSha256Header::getBytes() const
|
bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return (mMasterHash == other.mMasterHash) \
|
||||||
|
&& (mHashBlockSize == other.mHashBlockSize) \
|
||||||
|
&& (mLayerInfo == other.mLayerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::HierarchicalSha256Header::getSize() const
|
bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::HierarchicalSha256Header::exportBinary()
|
void nx::HierarchicalSha256Header::toBytes()
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
|
throw fnd::Exception(kModuleName, "exportBinary() not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len)
|
void nx::HierarchicalSha256Header::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
std::stringstream error_str;
|
std::stringstream error_str;
|
||||||
|
|
||||||
|
@ -56,7 +51,7 @@ void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len
|
||||||
throw fnd::Exception(kModuleName, "Header too small");
|
throw fnd::Exception(kModuleName, "Header too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)bytes;
|
const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)data;
|
||||||
|
|
||||||
if (hdr->layer_num.get() != nx::hierarchicalsha256::kDefaultLayerNum)
|
if (hdr->layer_num.get() != nx::hierarchicalsha256::kDefaultLayerNum)
|
||||||
{
|
{
|
||||||
|
@ -74,6 +69,11 @@ void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::HierarchicalSha256Header::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::HierarchicalSha256Header::clear()
|
void nx::HierarchicalSha256Header::clear()
|
||||||
{
|
{
|
||||||
memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash));
|
memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash));
|
||||||
|
@ -110,24 +110,3 @@ void nx::HierarchicalSha256Header::setLayerInfo(const fnd::List<sLayer>& layer_i
|
||||||
{
|
{
|
||||||
mLayerInfo = layer_info;
|
mLayerInfo = layer_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::HierarchicalSha256Header::isEqual(const HierarchicalSha256Header & other) const
|
|
||||||
{
|
|
||||||
return (mMasterHash == other.mMasterHash) \
|
|
||||||
&& (mHashBlockSize == other.mHashBlockSize) \
|
|
||||||
&& (mLayerInfo == other.mLayerInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::HierarchicalSha256Header::copyFrom(const HierarchicalSha256Header & other)
|
|
||||||
{
|
|
||||||
if (other.getSize() != 0)
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mMasterHash = other.mMasterHash;
|
|
||||||
mHashBlockSize = other.mHashBlockSize;
|
|
||||||
mLayerInfo = other.mLayerInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,46 +1,44 @@
|
||||||
#include <nx/KcBinary.h>
|
#include <nx/KcBinary.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::KcBinary::KcBinary()
|
nx::KcBinary::KcBinary()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
nx::KcBinary::KcBinary(const KcBinary & other)
|
nx::KcBinary::KcBinary(const KcBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::KcBinary::KcBinary(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::KcBinary::operator==(const KcBinary & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::KcBinary::operator!=(const KcBinary & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::KcBinary::operator=(const KcBinary & other)
|
void nx::KcBinary::operator=(const KcBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
clear();
|
||||||
|
mThreadInfo = other.mThreadInfo;
|
||||||
|
mSystemCalls = other.mSystemCalls;
|
||||||
|
mMemoryMap = other.mMemoryMap;
|
||||||
|
mInterupts = other.mInterupts;
|
||||||
|
mMiscParams = other.mMiscParams;
|
||||||
|
mKernelVersion = other.mKernelVersion;
|
||||||
|
mHandleTableSize = other.mHandleTableSize;
|
||||||
|
mMiscFlags = other.mMiscFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * nx::KcBinary::getBytes() const
|
bool nx::KcBinary::operator==(const KcBinary & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return (mThreadInfo == other.mThreadInfo) \
|
||||||
|
&& (mSystemCalls == other.mSystemCalls) \
|
||||||
|
&& (mMemoryMap == other.mMemoryMap) \
|
||||||
|
&& (mInterupts == other.mInterupts) \
|
||||||
|
&& (mMiscParams == other.mMiscParams) \
|
||||||
|
&& (mKernelVersion == other.mKernelVersion) \
|
||||||
|
&& (mHandleTableSize == other.mHandleTableSize) \
|
||||||
|
&& (mMiscFlags == other.mMiscFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nx::KcBinary::getSize() const
|
bool nx::KcBinary::operator!=(const KcBinary & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::KcBinary::exportBinary()
|
void nx::KcBinary::toBytes()
|
||||||
{
|
{
|
||||||
fnd::List<KernelCapability> caps;
|
fnd::List<KernelCapability> caps;
|
||||||
|
|
||||||
|
@ -55,23 +53,27 @@ void nx::KcBinary::exportBinary()
|
||||||
mMiscFlags.exportKernelCapabilityList(caps);
|
mMiscFlags.exportKernelCapabilityList(caps);
|
||||||
|
|
||||||
// allocate memory
|
// allocate memory
|
||||||
mBinaryBlob.alloc(caps.getSize() * sizeof(uint32_t));
|
mRawBinary.alloc(caps.size() * sizeof(uint32_t));
|
||||||
|
|
||||||
// write to binary
|
// write to binary
|
||||||
uint32_t* raw_caps = (uint32_t*)mBinaryBlob.getBytes();
|
uint32_t* raw_caps = (uint32_t*)mRawBinary.data();
|
||||||
for (size_t i = 0; i < caps.getSize(); i++)
|
for (size_t i = 0; i < caps.size(); i++)
|
||||||
{
|
{
|
||||||
raw_caps[i] = le_word(caps[i].getCap());
|
raw_caps[i] = le_word(caps[i].getCap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::KcBinary::importBinary(const byte_t * bytes, size_t len)
|
void nx::KcBinary::fromBytes(const byte_t * data, size_t len)
|
||||||
{
|
{
|
||||||
if ((len % sizeof(uint32_t)) != 0)
|
if ((len % sizeof(uint32_t)) != 0)
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "KernelCapability list must be aligned to 4 bytes");
|
throw fnd::Exception(kModuleName, "KernelCapability list must be aligned to 4 bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save copy of KcBinary
|
||||||
|
mRawBinary.alloc(len);
|
||||||
|
memcpy(mRawBinary.data(), data, len);
|
||||||
|
|
||||||
fnd::List<KernelCapability> threadInfoCaps;
|
fnd::List<KernelCapability> threadInfoCaps;
|
||||||
fnd::List<KernelCapability> systemCallCaps;
|
fnd::List<KernelCapability> systemCallCaps;
|
||||||
fnd::List<KernelCapability> memoryMapCaps;
|
fnd::List<KernelCapability> memoryMapCaps;
|
||||||
|
@ -81,8 +83,8 @@ void nx::KcBinary::importBinary(const byte_t * bytes, size_t len)
|
||||||
fnd::List<KernelCapability> handleTableSizeCaps;
|
fnd::List<KernelCapability> handleTableSizeCaps;
|
||||||
fnd::List<KernelCapability> miscFlagsCaps;
|
fnd::List<KernelCapability> miscFlagsCaps;
|
||||||
|
|
||||||
const uint32_t* raw_caps = (const uint32_t*)bytes;
|
const uint32_t* raw_caps = (const uint32_t*)mRawBinary.data();
|
||||||
size_t cap_num = len / sizeof(uint32_t);
|
size_t cap_num = mRawBinary.size() / sizeof(uint32_t);
|
||||||
KernelCapability cap;
|
KernelCapability cap;
|
||||||
for (size_t i = 0; i < cap_num; i++)
|
for (size_t i = 0; i < cap_num; i++)
|
||||||
{
|
{
|
||||||
|
@ -129,9 +131,14 @@ void nx::KcBinary::importBinary(const byte_t * bytes, size_t len)
|
||||||
mMiscFlags.importKernelCapabilityList(miscFlagsCaps);
|
mMiscFlags.importKernelCapabilityList(miscFlagsCaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::KcBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::KcBinary::clear()
|
void nx::KcBinary::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mThreadInfo.clear();
|
mThreadInfo.clear();
|
||||||
mSystemCalls.clear();
|
mSystemCalls.clear();
|
||||||
mMemoryMap.clear();
|
mMemoryMap.clear();
|
||||||
|
@ -221,27 +228,3 @@ nx::MiscFlagsHandler & nx::KcBinary::getMiscFlags()
|
||||||
{
|
{
|
||||||
return mMiscFlags;
|
return mMiscFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::KcBinary::isEqual(const KcBinary & other) const
|
|
||||||
{
|
|
||||||
return (mThreadInfo == other.mThreadInfo) \
|
|
||||||
&& (mSystemCalls == other.mSystemCalls) \
|
|
||||||
&& (mMemoryMap == other.mMemoryMap) \
|
|
||||||
&& (mInterupts == other.mInterupts) \
|
|
||||||
&& (mMiscParams == other.mMiscParams) \
|
|
||||||
&& (mKernelVersion == other.mKernelVersion) \
|
|
||||||
&& (mHandleTableSize == other.mHandleTableSize) \
|
|
||||||
&& (mMiscFlags == other.mMiscFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::KcBinary::copyFrom(const KcBinary & other)
|
|
||||||
{
|
|
||||||
mThreadInfo = other.mThreadInfo;
|
|
||||||
mSystemCalls = other.mSystemCalls;
|
|
||||||
mMemoryMap = other.mMemoryMap;
|
|
||||||
mInterupts = other.mInterupts;
|
|
||||||
mMiscParams = other.mMiscParams;
|
|
||||||
mKernelVersion = other.mKernelVersion;
|
|
||||||
mHandleTableSize = other.mHandleTableSize;
|
|
||||||
mMiscFlags = other.mMiscFlags;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,11 +2,61 @@
|
||||||
|
|
||||||
using namespace nx;
|
using namespace nx;
|
||||||
|
|
||||||
|
NcaHeader::NcaHeader()
|
||||||
void NcaHeader::exportBinary()
|
|
||||||
{
|
{
|
||||||
mBinaryBlob.alloc(sizeof(sNcaHeader));
|
clear();
|
||||||
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
|
}
|
||||||
|
|
||||||
|
NcaHeader::NcaHeader(const NcaHeader & other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NcaHeader::operator==(const NcaHeader & other) const
|
||||||
|
{
|
||||||
|
return (mDistributionType == other.mDistributionType) \
|
||||||
|
&& (mContentType == other.mContentType) \
|
||||||
|
&& (mKeyGeneration == other.mKeyGeneration) \
|
||||||
|
&& (mKaekIndex == other.mKaekIndex) \
|
||||||
|
&& (mContentSize == other.mContentSize) \
|
||||||
|
&& (mProgramId == other.mProgramId) \
|
||||||
|
&& (mContentIndex == other.mContentIndex) \
|
||||||
|
&& (mSdkAddonVersion == other.mSdkAddonVersion) \
|
||||||
|
&& (mPartitions == other.mPartitions) \
|
||||||
|
&& (mEncAesKeys == other.mEncAesKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NcaHeader::operator!=(const NcaHeader & other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NcaHeader::operator=(const NcaHeader & other)
|
||||||
|
{
|
||||||
|
if (other.getBytes().size())
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mRawBinary.clear();
|
||||||
|
mDistributionType = other.mDistributionType;
|
||||||
|
mContentType = other.mContentType;
|
||||||
|
mKeyGeneration = other.mKeyGeneration;
|
||||||
|
mKaekIndex = other.mKaekIndex;
|
||||||
|
mContentSize = other.mContentSize;
|
||||||
|
mProgramId = other.mProgramId;
|
||||||
|
mContentIndex = other.mContentIndex;
|
||||||
|
mSdkAddonVersion = other.mSdkAddonVersion;
|
||||||
|
mPartitions = other.mPartitions;
|
||||||
|
mEncAesKeys = other.mEncAesKeys;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NcaHeader::toBytes()
|
||||||
|
{
|
||||||
|
mRawBinary.alloc(sizeof(sNcaHeader));
|
||||||
|
sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data();
|
||||||
|
|
||||||
|
|
||||||
switch(mFormatVersion)
|
switch(mFormatVersion)
|
||||||
|
@ -41,7 +91,7 @@ void NcaHeader::exportBinary()
|
||||||
memcpy(hdr->rights_id, mRightsId, nca::kRightsIdLen);
|
memcpy(hdr->rights_id, mRightsId, nca::kRightsIdLen);
|
||||||
|
|
||||||
// TODO: properly reconstruct NCA layout? atm in hands of user
|
// TODO: properly reconstruct NCA layout? atm in hands of user
|
||||||
for (size_t i = 0; i < mPartitions.getSize(); i++)
|
for (size_t i = 0; i < mPartitions.size(); i++)
|
||||||
{
|
{
|
||||||
// determine partition index
|
// determine partition index
|
||||||
byte_t idx = mPartitions[i].index;
|
byte_t idx = mPartitions[i].index;
|
||||||
|
@ -60,7 +110,7 @@ void NcaHeader::exportBinary()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NcaHeader::importBinary(const byte_t * bytes, size_t len)
|
void NcaHeader::fromBytes(const byte_t * data, size_t len)
|
||||||
{
|
{
|
||||||
if (len < sizeof(sNcaHeader))
|
if (len < sizeof(sNcaHeader))
|
||||||
{
|
{
|
||||||
|
@ -69,10 +119,10 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
mBinaryBlob.alloc(sizeof(sNcaHeader));
|
mRawBinary.alloc(sizeof(sNcaHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, sizeof(sNcaHeader));
|
memcpy(mRawBinary.data(), data, sizeof(sNcaHeader));
|
||||||
|
|
||||||
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
|
sNcaHeader* hdr = (sNcaHeader*)mRawBinary.data();
|
||||||
|
|
||||||
switch(hdr->signature.get())
|
switch(hdr->signature.get())
|
||||||
{
|
{
|
||||||
|
@ -110,6 +160,11 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& NcaHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::NcaHeader::clear()
|
void nx::NcaHeader::clear()
|
||||||
{
|
{
|
||||||
mFormatVersion = NCA3_FORMAT;
|
mFormatVersion = NCA3_FORMAT;
|
||||||
|
@ -247,7 +302,7 @@ const fnd::List<NcaHeader::sPartition>& NcaHeader::getPartitions() const
|
||||||
void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions)
|
void NcaHeader::setPartitions(const fnd::List<NcaHeader::sPartition>& partitions)
|
||||||
{
|
{
|
||||||
mPartitions = partitions;
|
mPartitions = partitions;
|
||||||
if (mPartitions.getSize() >= nca::kPartitionNum)
|
if (mPartitions.size() >= nca::kPartitionNum)
|
||||||
{
|
{
|
||||||
throw fnd::Exception(kModuleName, "Too many NCA partitions");
|
throw fnd::Exception(kModuleName, "Too many NCA partitions");
|
||||||
}
|
}
|
||||||
|
@ -272,79 +327,3 @@ uint32_t NcaHeader::sizeToBlockNum(uint64_t real_size) const
|
||||||
{
|
{
|
||||||
return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize);
|
return (uint32_t)(align(real_size, nca::kSectorSize) / nca::kSectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NcaHeader::isEqual(const NcaHeader & other) const
|
|
||||||
{
|
|
||||||
return (mDistributionType == other.mDistributionType) \
|
|
||||||
&& (mContentType == other.mContentType) \
|
|
||||||
&& (mKeyGeneration == other.mKeyGeneration) \
|
|
||||||
&& (mKaekIndex == other.mKaekIndex) \
|
|
||||||
&& (mContentSize == other.mContentSize) \
|
|
||||||
&& (mProgramId == other.mProgramId) \
|
|
||||||
&& (mContentIndex == other.mContentIndex) \
|
|
||||||
&& (mSdkAddonVersion == other.mSdkAddonVersion) \
|
|
||||||
&& (mPartitions == other.mPartitions) \
|
|
||||||
&& (mEncAesKeys == other.mEncAesKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NcaHeader::copyFrom(const NcaHeader & other)
|
|
||||||
{
|
|
||||||
if (other.getSize())
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mBinaryBlob.clear();
|
|
||||||
mDistributionType = other.mDistributionType;
|
|
||||||
mContentType = other.mContentType;
|
|
||||||
mKeyGeneration = other.mKeyGeneration;
|
|
||||||
mKaekIndex = other.mKaekIndex;
|
|
||||||
mContentSize = other.mContentSize;
|
|
||||||
mProgramId = other.mProgramId;
|
|
||||||
mContentIndex = other.mContentIndex;
|
|
||||||
mSdkAddonVersion = other.mSdkAddonVersion;
|
|
||||||
mPartitions = other.mPartitions;
|
|
||||||
mEncAesKeys = other.mEncAesKeys;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NcaHeader::NcaHeader()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
NcaHeader::NcaHeader(const NcaHeader & other)
|
|
||||||
{
|
|
||||||
copyFrom(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
NcaHeader::NcaHeader(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NcaHeader::operator==(const NcaHeader & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NcaHeader::operator!=(const NcaHeader & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NcaHeader::operator=(const NcaHeader & other)
|
|
||||||
{
|
|
||||||
this->importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
const byte_t * NcaHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t NcaHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <nx/NpdmBinary.h>
|
#include <nx/NpdmBinary.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::NpdmBinary::NpdmBinary() :
|
nx::NpdmBinary::NpdmBinary() :
|
||||||
mAci(),
|
mAci(),
|
||||||
mAcid()
|
mAcid()
|
||||||
|
@ -13,47 +11,51 @@ nx::NpdmBinary::NpdmBinary(const NpdmBinary & other) :
|
||||||
mAci(),
|
mAci(),
|
||||||
mAcid()
|
mAcid()
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::NpdmBinary::NpdmBinary(const byte_t * 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)
|
void nx::NpdmBinary::operator=(const NpdmBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size())
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NpdmHeader::operator=(other);
|
||||||
|
mAci = other.mAci;
|
||||||
|
mAcid = other.mAcid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmBinary::exportBinary()
|
bool nx::NpdmBinary::operator==(const NpdmBinary & other) const
|
||||||
|
{
|
||||||
|
return (NpdmHeader::operator==(other)) \
|
||||||
|
&& (mAci == other.mAci) \
|
||||||
|
&& (mAcid == other.mAcid);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nx::NpdmBinary::operator!=(const NpdmBinary & other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmBinary::toBytes()
|
||||||
{
|
{
|
||||||
mAci.exportBinary();
|
mAci.exportBinary();
|
||||||
mAcid.exportBinary();
|
mAcid.exportBinary();
|
||||||
|
|
||||||
setAciSize(mAci.getSize());
|
setAciSize(mAci.getBytes().size());
|
||||||
setAcidSize(mAcid.getSize());
|
setAcidSize(mAcid.getBytes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmBinary::importBinary(const byte_t * bytes, size_t len)
|
void nx::NpdmBinary::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
// clear
|
// clear
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
// import header
|
// import header
|
||||||
NpdmHeader::importBinary(bytes, len);
|
NpdmHeader::fromBytes(data, len);
|
||||||
|
|
||||||
// check size
|
// check size
|
||||||
if (getNpdmSize() > len)
|
if (getNpdmSize() > len)
|
||||||
|
@ -62,19 +64,23 @@ void nx::NpdmBinary::importBinary(const byte_t * bytes, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// save local copy
|
// save local copy
|
||||||
mBinaryBlob.alloc(getNpdmSize());
|
mRawBinary.alloc(getNpdmSize());
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
// import Aci/Acid
|
// import Aci/Acid
|
||||||
if (getAciPos().size)
|
if (getAciPos().size)
|
||||||
{
|
{
|
||||||
mAci.importBinary(mBinaryBlob.getBytes() + getAciPos().offset, getAciPos().size);
|
mAci.importBinary(mRawBinary.data() + getAciPos().offset, getAciPos().size);
|
||||||
}
|
}
|
||||||
if (getAcidPos().size)
|
if (getAcidPos().size)
|
||||||
{
|
{
|
||||||
mAcid.importBinary(mBinaryBlob.getBytes() + getAcidPos().offset, getAcidPos().size);
|
mAcid.importBinary(mRawBinary.data() + getAcidPos().offset, getAcidPos().size);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::NpdmBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmBinary::clear()
|
void nx::NpdmBinary::clear()
|
||||||
|
@ -103,34 +109,3 @@ void nx::NpdmBinary::setAcid(const AcidBinary & acid)
|
||||||
{
|
{
|
||||||
mAcid = 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 byte_t * nx::NpdmBinary::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::NpdmBinary::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <nx/NpdmHeader.h>
|
#include <nx/NpdmHeader.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::NpdmHeader::NpdmHeader()
|
nx::NpdmHeader::NpdmHeader()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
@ -9,67 +7,18 @@ nx::NpdmHeader::NpdmHeader()
|
||||||
|
|
||||||
nx::NpdmHeader::NpdmHeader(const NpdmHeader & other)
|
nx::NpdmHeader::NpdmHeader(const NpdmHeader & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
nx::NpdmHeader::NpdmHeader(const byte_t * bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::NpdmHeader::operator==(const NpdmHeader & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::NpdmHeader::operator!=(const NpdmHeader & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmHeader::operator=(const NpdmHeader & other)
|
void nx::NpdmHeader::operator=(const NpdmHeader & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size())
|
||||||
}
|
|
||||||
|
|
||||||
const byte_t * nx::NpdmHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::NpdmHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::calculateOffsets()
|
|
||||||
{
|
|
||||||
mAcidPos.offset = align(sizeof(sNpdmHeader), npdm::kNpdmAlignSize);
|
|
||||||
mAciPos.offset = mAcidPos.offset + align(mAcidPos.size, npdm::kNpdmAlignSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::NpdmHeader::isEqual(const NpdmHeader & other) const
|
|
||||||
{
|
|
||||||
return (mInstructionType == other.mInstructionType) \
|
|
||||||
&& (mProcAddressSpaceType == other.mProcAddressSpaceType) \
|
|
||||||
&& (mMainThreadPriority == other.mMainThreadPriority) \
|
|
||||||
&& (mMainThreadCpuId == other.mMainThreadCpuId) \
|
|
||||||
&& (mVersion == other.mVersion) \
|
|
||||||
&& (mMainThreadStackSize == other.mMainThreadStackSize) \
|
|
||||||
&& (mName == other.mName) \
|
|
||||||
&& (mProductCode == other.mProductCode) \
|
|
||||||
&& (mAciPos == other.mAciPos) \
|
|
||||||
&& (mAcidPos == other.mAcidPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NpdmHeader::copyFrom(const NpdmHeader & other)
|
|
||||||
{
|
|
||||||
if (other.getSize())
|
|
||||||
{
|
{
|
||||||
importBinary(other.getBytes(), other.getSize());
|
fromBytes(other.getBytes().data, other.getBytes().size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
mInstructionType = other.mInstructionType;
|
mInstructionType = other.mInstructionType;
|
||||||
mProcAddressSpaceType = other.mProcAddressSpaceType;
|
mProcAddressSpaceType = other.mProcAddressSpaceType;
|
||||||
mMainThreadPriority = other.mMainThreadPriority;
|
mMainThreadPriority = other.mMainThreadPriority;
|
||||||
|
@ -83,10 +32,29 @@ void nx::NpdmHeader::copyFrom(const NpdmHeader & other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmHeader::exportBinary()
|
bool nx::NpdmHeader::operator==(const NpdmHeader & other) const
|
||||||
{
|
{
|
||||||
mBinaryBlob.alloc(sizeof(sNpdmHeader));
|
return (mInstructionType == other.mInstructionType) \
|
||||||
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes();
|
&& (mProcAddressSpaceType == other.mProcAddressSpaceType) \
|
||||||
|
&& (mMainThreadPriority == other.mMainThreadPriority) \
|
||||||
|
&& (mMainThreadCpuId == other.mMainThreadCpuId) \
|
||||||
|
&& (mVersion == other.mVersion) \
|
||||||
|
&& (mMainThreadStackSize == other.mMainThreadStackSize) \
|
||||||
|
&& (mName == other.mName) \
|
||||||
|
&& (mProductCode == other.mProductCode) \
|
||||||
|
&& (mAciPos == other.mAciPos) \
|
||||||
|
&& (mAcidPos == other.mAcidPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nx::NpdmHeader::operator!=(const NpdmHeader & other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::NpdmHeader::toBytes()
|
||||||
|
{
|
||||||
|
mRawBinary.alloc(sizeof(sNpdmHeader));
|
||||||
|
sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data();
|
||||||
|
|
||||||
hdr->signature = npdm::kNpdmStructSig;
|
hdr->signature = npdm::kNpdmStructSig;
|
||||||
byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf;
|
byte_t flag = ((byte_t)(mInstructionType & 1) | (byte_t)((mProcAddressSpaceType & 3) << 1)) & 0xf;
|
||||||
|
@ -105,7 +73,7 @@ void nx::NpdmHeader::exportBinary()
|
||||||
hdr->acid.size = (uint32_t)mAcidPos.size;
|
hdr->acid.size = (uint32_t)mAcidPos.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
|
void nx::NpdmHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
if (len < sizeof(sNpdmHeader))
|
if (len < sizeof(sNpdmHeader))
|
||||||
{
|
{
|
||||||
|
@ -114,9 +82,9 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
mBinaryBlob.alloc(sizeof(sNpdmHeader));
|
mRawBinary.alloc(sizeof(sNpdmHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes();
|
sNpdmHeader* hdr = (sNpdmHeader*)mRawBinary.data();
|
||||||
|
|
||||||
if (hdr->signature.get() != npdm::kNpdmStructSig)
|
if (hdr->signature.get() != npdm::kNpdmStructSig)
|
||||||
{
|
{
|
||||||
|
@ -146,9 +114,14 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
mAcidPos.size = hdr->acid.size.get();
|
mAcidPos.size = hdr->acid.size.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::NpdmHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::NpdmHeader::clear()
|
void nx::NpdmHeader::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mInstructionType = npdm::INSTR_64BIT;
|
mInstructionType = npdm::INSTR_64BIT;
|
||||||
mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT;
|
mProcAddressSpaceType = npdm::ADDR_SPACE_64BIT;
|
||||||
mMainThreadPriority = 0;
|
mMainThreadPriority = 0;
|
||||||
|
@ -282,3 +255,9 @@ void nx::NpdmHeader::setAcidSize(size_t size)
|
||||||
{
|
{
|
||||||
mAcidPos.size = size;
|
mAcidPos.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nx::NpdmHeader::calculateOffsets()
|
||||||
|
{
|
||||||
|
mAcidPos.offset = align(sizeof(sNpdmHeader), npdm::kNpdmAlignSize);
|
||||||
|
mAciPos.offset = mAcidPos.offset + align(mAcidPos.size, npdm::kNpdmAlignSize);
|
||||||
|
}
|
|
@ -7,17 +7,38 @@ nx::NroHeader::NroHeader()
|
||||||
|
|
||||||
nx::NroHeader::NroHeader(const NroHeader& other)
|
nx::NroHeader::NroHeader(const NroHeader& other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::NroHeader::NroHeader(const byte_t* bytes, size_t len)
|
void nx::NroHeader::operator=(const NroHeader& other)
|
||||||
{
|
{
|
||||||
importBinary(bytes, len);
|
clear();
|
||||||
|
mRoCrt = other.mRoCrt;
|
||||||
|
mNroSize = other.mNroSize;
|
||||||
|
mTextInfo = other.mTextInfo;
|
||||||
|
mTextInfo = other.mTextInfo;
|
||||||
|
mRoInfo = other.mRoInfo;
|
||||||
|
mDataInfo = other.mDataInfo;
|
||||||
|
mBssSize = other.mBssSize;
|
||||||
|
mModuleId = other.mModuleId;
|
||||||
|
mRoEmbeddedInfo = other.mRoEmbeddedInfo;
|
||||||
|
mRoDynStrInfo = other.mRoDynStrInfo;
|
||||||
|
mRoDynSymInfo = other.mRoDynSymInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::NroHeader::operator==(const NroHeader& other) const
|
bool nx::NroHeader::operator==(const NroHeader& other) const
|
||||||
{
|
{
|
||||||
return isEqual(other);
|
return (mRoCrt == other.mRoCrt) \
|
||||||
|
&& (mNroSize == other.mNroSize) \
|
||||||
|
&& (mTextInfo == other.mTextInfo) \
|
||||||
|
&& (mTextInfo == other.mTextInfo) \
|
||||||
|
&& (mRoInfo == other.mRoInfo) \
|
||||||
|
&& (mDataInfo == other.mDataInfo) \
|
||||||
|
&& (mBssSize == other.mBssSize) \
|
||||||
|
&& (mModuleId == other.mModuleId) \
|
||||||
|
&& (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \
|
||||||
|
&& (mRoDynStrInfo == other.mRoDynStrInfo) \
|
||||||
|
&& (mRoDynSymInfo == other.mRoDynSymInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::NroHeader::operator!=(const NroHeader& other) const
|
bool nx::NroHeader::operator!=(const NroHeader& other) const
|
||||||
|
@ -25,25 +46,10 @@ bool nx::NroHeader::operator!=(const NroHeader& other) const
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NroHeader::operator=(const NroHeader& other)
|
void nx::NroHeader::toBytes()
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
mRawBinary.alloc(sizeof(sNroHeader));
|
||||||
}
|
nx::sNroHeader* hdr = (nx::sNroHeader*)mRawBinary.data();
|
||||||
|
|
||||||
const byte_t* nx::NroHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::NroHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NroHeader::exportBinary()
|
|
||||||
{
|
|
||||||
mBinaryBlob.alloc(sizeof(sNroHeader));
|
|
||||||
nx::sNroHeader* hdr = (nx::sNroHeader*)mBinaryBlob.getBytes();
|
|
||||||
|
|
||||||
// set header identifers
|
// set header identifers
|
||||||
hdr->signature = nro::kNroSig;
|
hdr->signature = nro::kNroSig;
|
||||||
|
@ -87,7 +93,7 @@ void nx::NroHeader::exportBinary()
|
||||||
hdr->dyn_sym.size = mRoDynSymInfo.size;
|
hdr->dyn_sym.size = mRoDynSymInfo.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NroHeader::importBinary(const byte_t* bytes, size_t len)
|
void nx::NroHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
// check input data size
|
// check input data size
|
||||||
if (len < sizeof(sNroHeader))
|
if (len < sizeof(sNroHeader))
|
||||||
|
@ -99,11 +105,11 @@ void nx::NroHeader::importBinary(const byte_t* bytes, size_t len)
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
// allocate internal local binary copy
|
// allocate internal local binary copy
|
||||||
mBinaryBlob.alloc(sizeof(sNroHeader));
|
mRawBinary.alloc(sizeof(sNroHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
// get sNroHeader ptr
|
// get sNroHeader ptr
|
||||||
const nx::sNroHeader* hdr = (const nx::sNroHeader*)mBinaryBlob.getBytes();
|
const nx::sNroHeader* hdr = (const nx::sNroHeader*)mRawBinary.data();
|
||||||
|
|
||||||
// check NRO signature
|
// check NRO signature
|
||||||
if (hdr->signature.get() != nro::kNroSig)
|
if (hdr->signature.get() != nro::kNroSig)
|
||||||
|
@ -144,9 +150,14 @@ void nx::NroHeader::importBinary(const byte_t* bytes, size_t len)
|
||||||
mRoDynSymInfo.size = hdr->dyn_sym.size.get();
|
mRoDynSymInfo.size = hdr->dyn_sym.size.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::NroHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::NroHeader::clear()
|
void nx::NroHeader::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
memset(&mRoCrt, 0, sizeof(mRoCrt));
|
memset(&mRoCrt, 0, sizeof(mRoCrt));
|
||||||
memset(&mTextInfo, 0, sizeof(mTextInfo));
|
memset(&mTextInfo, 0, sizeof(mTextInfo));
|
||||||
memset(&mRoInfo, 0, sizeof(mRoInfo));
|
memset(&mRoInfo, 0, sizeof(mRoInfo));
|
||||||
|
@ -257,34 +268,3 @@ void nx::NroHeader::setRoDynSymInfo(const sSection& info)
|
||||||
{
|
{
|
||||||
mRoDynSymInfo = info;
|
mRoDynSymInfo = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::NroHeader::isEqual(const NroHeader& other) const
|
|
||||||
{
|
|
||||||
return (mRoCrt == other.mRoCrt) \
|
|
||||||
&& (mNroSize == other.mNroSize) \
|
|
||||||
&& (mTextInfo == other.mTextInfo) \
|
|
||||||
&& (mTextInfo == other.mTextInfo) \
|
|
||||||
&& (mRoInfo == other.mRoInfo) \
|
|
||||||
&& (mDataInfo == other.mDataInfo) \
|
|
||||||
&& (mBssSize == other.mBssSize) \
|
|
||||||
&& (mModuleId == other.mModuleId) \
|
|
||||||
&& (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \
|
|
||||||
&& (mRoDynStrInfo == other.mRoDynStrInfo) \
|
|
||||||
&& (mRoDynSymInfo == other.mRoDynSymInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NroHeader::copyFrom(const NroHeader& other)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
mRoCrt = other.mRoCrt;
|
|
||||||
mNroSize = other.mNroSize;
|
|
||||||
mTextInfo = other.mTextInfo;
|
|
||||||
mTextInfo = other.mTextInfo;
|
|
||||||
mRoInfo = other.mRoInfo;
|
|
||||||
mDataInfo = other.mDataInfo;
|
|
||||||
mBssSize = other.mBssSize;
|
|
||||||
mModuleId = other.mModuleId;
|
|
||||||
mRoEmbeddedInfo = other.mRoEmbeddedInfo;
|
|
||||||
mRoDynStrInfo = other.mRoDynStrInfo;
|
|
||||||
mRoDynSymInfo = other.mRoDynSymInfo;
|
|
||||||
}
|
|
|
@ -2,22 +2,40 @@
|
||||||
|
|
||||||
nx::NsoHeader::NsoHeader()
|
nx::NsoHeader::NsoHeader()
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::NsoHeader::NsoHeader(const NsoHeader& other)
|
nx::NsoHeader::NsoHeader(const NsoHeader& other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::NsoHeader::NsoHeader(const byte_t* bytes, size_t len)
|
void nx::NsoHeader::operator=(const NsoHeader& other)
|
||||||
{
|
{
|
||||||
importBinary(bytes, len);
|
clear();
|
||||||
|
mModuleId = other.mModuleId;
|
||||||
|
mBssSize = other.mBssSize;
|
||||||
|
mTextSegmentInfo = other.mTextSegmentInfo;
|
||||||
|
mRoSegmentInfo = other.mRoSegmentInfo;
|
||||||
|
mDataSegmentInfo = other.mDataSegmentInfo;
|
||||||
|
mModuleNameInfo = other.mModuleNameInfo;
|
||||||
|
mRoEmbeddedInfo = other.mRoEmbeddedInfo;
|
||||||
|
mRoDynStrInfo = other.mRoDynStrInfo;
|
||||||
|
mRoDynSymInfo = other.mRoDynSymInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool nx::NsoHeader::operator==(const NsoHeader& other) const
|
bool nx::NsoHeader::operator==(const NsoHeader& other) const
|
||||||
{
|
{
|
||||||
return isEqual(other);
|
return (mModuleId == other.mModuleId) \
|
||||||
|
&& (mBssSize == other.mBssSize) \
|
||||||
|
&& (mTextSegmentInfo == other.mTextSegmentInfo) \
|
||||||
|
&& (mRoSegmentInfo == other.mRoSegmentInfo) \
|
||||||
|
&& (mDataSegmentInfo == other.mDataSegmentInfo) \
|
||||||
|
&& (mModuleNameInfo == other.mModuleNameInfo) \
|
||||||
|
&& (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \
|
||||||
|
&& (mRoDynStrInfo == other.mRoDynStrInfo) \
|
||||||
|
&& (mRoDynSymInfo == other.mRoDynSymInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::NsoHeader::operator!=(const NsoHeader& other) const
|
bool nx::NsoHeader::operator!=(const NsoHeader& other) const
|
||||||
|
@ -25,25 +43,10 @@ bool nx::NsoHeader::operator!=(const NsoHeader& other) const
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NsoHeader::operator=(const NsoHeader& other)
|
void nx::NsoHeader::toBytes()
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
mRawBinary.alloc(sizeof(sNsoHeader));
|
||||||
}
|
nx::sNsoHeader* hdr = (nx::sNsoHeader*)mRawBinary.data();
|
||||||
|
|
||||||
const byte_t* nx::NsoHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::NsoHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::NsoHeader::exportBinary()
|
|
||||||
{
|
|
||||||
mBinaryBlob.alloc(sizeof(sNsoHeader));
|
|
||||||
nx::sNsoHeader* hdr = (nx::sNsoHeader*)mBinaryBlob.getBytes();
|
|
||||||
|
|
||||||
// set header identifers
|
// set header identifers
|
||||||
hdr->signature = nso::kNsoSig;
|
hdr->signature = nso::kNsoSig;
|
||||||
|
@ -122,7 +125,7 @@ void nx::NsoHeader::exportBinary()
|
||||||
hdr->flags = flags;
|
hdr->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len)
|
void nx::NsoHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
// check input data size
|
// check input data size
|
||||||
if (len < sizeof(sNsoHeader))
|
if (len < sizeof(sNsoHeader))
|
||||||
|
@ -134,11 +137,11 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len)
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
// allocate internal local binary copy
|
// allocate internal local binary copy
|
||||||
mBinaryBlob.alloc(sizeof(sNsoHeader));
|
mRawBinary.alloc(sizeof(sNsoHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
// get sNsoHeader ptr
|
// get sNsoHeader ptr
|
||||||
const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes();
|
const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mRawBinary.data();
|
||||||
|
|
||||||
// check NSO signature
|
// check NSO signature
|
||||||
if (hdr->signature.get() != nso::kNsoSig)
|
if (hdr->signature.get() != nso::kNsoSig)
|
||||||
|
@ -193,9 +196,14 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len)
|
||||||
mRoDynSymInfo.size = hdr->dyn_sym.size.get();
|
mRoDynSymInfo.size = hdr->dyn_sym.size.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::NsoHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::NsoHeader::clear()
|
void nx::NsoHeader::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
memset(&mModuleId, 0, sizeof(mModuleId));
|
memset(&mModuleId, 0, sizeof(mModuleId));
|
||||||
mBssSize = 0;
|
mBssSize = 0;
|
||||||
memset(&mTextSegmentInfo, 0, sizeof(mTextSegmentInfo));
|
memset(&mTextSegmentInfo, 0, sizeof(mTextSegmentInfo));
|
||||||
|
@ -296,29 +304,3 @@ void nx::NsoHeader::setRoDynSymInfo(const sLayout& info)
|
||||||
{
|
{
|
||||||
mRoDynSymInfo = info;
|
mRoDynSymInfo = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::NsoHeader::isEqual(const NsoHeader& other) const
|
|
||||||
{
|
|
||||||
return (mModuleId == other.mModuleId) \
|
|
||||||
&& (mBssSize == other.mBssSize) \
|
|
||||||
&& (mTextSegmentInfo == other.mTextSegmentInfo) \
|
|
||||||
&& (mRoSegmentInfo == other.mRoSegmentInfo) \
|
|
||||||
&& (mDataSegmentInfo == other.mDataSegmentInfo) \
|
|
||||||
&& (mModuleNameInfo == other.mModuleNameInfo) \
|
|
||||||
&& (mRoEmbeddedInfo == other.mRoEmbeddedInfo) \
|
|
||||||
&& (mRoDynStrInfo == other.mRoDynStrInfo) \
|
|
||||||
&& (mRoDynSymInfo == other.mRoDynSymInfo);
|
|
||||||
}
|
|
||||||
void nx::NsoHeader::copyFrom(const NsoHeader& other)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
mModuleId = other.mModuleId;
|
|
||||||
mBssSize = other.mBssSize;
|
|
||||||
mTextSegmentInfo = other.mTextSegmentInfo;
|
|
||||||
mRoSegmentInfo = other.mRoSegmentInfo;
|
|
||||||
mDataSegmentInfo = other.mDataSegmentInfo;
|
|
||||||
mModuleNameInfo = other.mModuleNameInfo;
|
|
||||||
mRoEmbeddedInfo = other.mRoEmbeddedInfo;
|
|
||||||
mRoDynStrInfo = other.mRoDynStrInfo;
|
|
||||||
mRoDynSymInfo = other.mRoDynSymInfo;
|
|
||||||
}
|
|
|
@ -1,37 +1,63 @@
|
||||||
#include <nx/PfsHeader.h>
|
#include <nx/PfsHeader.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nx::PfsHeader::PfsHeader()
|
nx::PfsHeader::PfsHeader()
|
||||||
{}
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
nx::PfsHeader::PfsHeader(const PfsHeader & other)
|
nx::PfsHeader::PfsHeader(const PfsHeader & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::PfsHeader::PfsHeader(const byte_t * bytes, size_t len)
|
void nx::PfsHeader::operator=(const PfsHeader & other)
|
||||||
{
|
{
|
||||||
importBinary(bytes, len);
|
if (other.getBytes().size())
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
mFsType = other.mFsType;
|
||||||
|
mFileList = other.mFileList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::PfsHeader::exportBinary()
|
bool nx::PfsHeader::operator==(const PfsHeader & other) const
|
||||||
|
{
|
||||||
|
return (mFsType == other.mFsType) \
|
||||||
|
&& (mFileList == other.mFileList);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nx::PfsHeader::operator!=(const PfsHeader & other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::PfsHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nx::PfsHeader::toBytes()
|
||||||
{
|
{
|
||||||
// calculate name table size
|
// calculate name table size
|
||||||
size_t name_table_size = 0;
|
size_t name_table_size = 0;
|
||||||
for (size_t i = 0; i < mFileList.getSize(); i++)
|
for (size_t i = 0; i < mFileList.size(); i++)
|
||||||
{
|
{
|
||||||
name_table_size += mFileList[i].name.length() + 1;
|
name_table_size += mFileList[i].name.length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pfs_header_size = align(sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.getSize() + name_table_size, pfs::kHeaderAlign);
|
size_t pfs_header_size = align(sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.size() + name_table_size, pfs::kHeaderAlign);
|
||||||
|
|
||||||
// align name_table_size
|
// align name_table_size
|
||||||
name_table_size = pfs_header_size - (sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.getSize());
|
name_table_size = pfs_header_size - (sizeof(sPfsHeader) + getFileEntrySize(mFsType) * mFileList.size());
|
||||||
|
|
||||||
// allocate pfs header binary
|
// allocate pfs header binary
|
||||||
mBinaryBlob.alloc(pfs_header_size);
|
mRawBinary.alloc(pfs_header_size);
|
||||||
sPfsHeader* hdr = (sPfsHeader*)mBinaryBlob.getBytes();
|
sPfsHeader* hdr = (sPfsHeader*)mRawBinary.data();
|
||||||
|
|
||||||
// set header fields
|
// set header fields
|
||||||
switch (mFsType)
|
switch (mFsType)
|
||||||
|
@ -44,18 +70,18 @@ void nx::PfsHeader::exportBinary()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr->file_num = (uint32_t)mFileList.getSize();
|
hdr->file_num = (uint32_t)mFileList.size();
|
||||||
hdr->name_table_size = (uint32_t)name_table_size;
|
hdr->name_table_size = (uint32_t)name_table_size;
|
||||||
|
|
||||||
// set file entries
|
// set file entries
|
||||||
if (mFsType == TYPE_PFS0)
|
if (mFsType == TYPE_PFS0)
|
||||||
{
|
{
|
||||||
sPfsFile* raw_files = (sPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader));
|
sPfsFile* raw_files = (sPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
|
||||||
char* raw_name_table = (char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sPfsFile) * mFileList.getSize());
|
char* raw_name_table = (char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sPfsFile) * mFileList.size());
|
||||||
size_t raw_name_table_pos = 0;
|
size_t raw_name_table_pos = 0;
|
||||||
|
|
||||||
calculateOffsets(pfs_header_size);
|
calculateOffsets(pfs_header_size);
|
||||||
for (size_t i = 0; i < mFileList.getSize(); i++)
|
for (size_t i = 0; i < mFileList.size(); i++)
|
||||||
{
|
{
|
||||||
raw_files[i].data_offset = (mFileList[i].offset - pfs_header_size);
|
raw_files[i].data_offset = (mFileList[i].offset - pfs_header_size);
|
||||||
raw_files[i].size = mFileList[i].size;
|
raw_files[i].size = mFileList[i].size;
|
||||||
|
@ -67,12 +93,12 @@ void nx::PfsHeader::exportBinary()
|
||||||
}
|
}
|
||||||
else if (mFsType == TYPE_HFS0)
|
else if (mFsType == TYPE_HFS0)
|
||||||
{
|
{
|
||||||
sHashedPfsFile* raw_files = (sHashedPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader));
|
sHashedPfsFile* raw_files = (sHashedPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
|
||||||
char* raw_name_table = (char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * mFileList.getSize());
|
char* raw_name_table = (char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * mFileList.size());
|
||||||
size_t raw_name_table_pos = 0;
|
size_t raw_name_table_pos = 0;
|
||||||
|
|
||||||
calculateOffsets(pfs_header_size);
|
calculateOffsets(pfs_header_size);
|
||||||
for (size_t i = 0; i < mFileList.getSize(); i++)
|
for (size_t i = 0; i < mFileList.size(); i++)
|
||||||
{
|
{
|
||||||
raw_files[i].data_offset = (mFileList[i].offset - pfs_header_size);
|
raw_files[i].data_offset = (mFileList[i].offset - pfs_header_size);
|
||||||
raw_files[i].size = mFileList[i].size;
|
raw_files[i].size = mFileList[i].size;
|
||||||
|
@ -87,7 +113,7 @@ void nx::PfsHeader::exportBinary()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
|
void nx::PfsHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
// check input length meets minimum size
|
// check input length meets minimum size
|
||||||
if (len < sizeof(sPfsHeader))
|
if (len < sizeof(sPfsHeader))
|
||||||
|
@ -96,9 +122,9 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// import minimum header
|
// import minimum header
|
||||||
mBinaryBlob.alloc(sizeof(sPfsHeader));
|
mRawBinary.alloc(sizeof(sPfsHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
const sPfsHeader* hdr = (const sPfsHeader*)mBinaryBlob.getBytes();
|
const sPfsHeader* hdr = (const sPfsHeader*)mRawBinary.data();
|
||||||
|
|
||||||
// check struct signature
|
// check struct signature
|
||||||
FsType fs_type;
|
FsType fs_type;
|
||||||
|
@ -124,9 +150,9 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// import full header
|
// import full header
|
||||||
mBinaryBlob.alloc(pfs_full_header_size);
|
mRawBinary.alloc(pfs_full_header_size);
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
hdr = (const sPfsHeader*)mBinaryBlob.getBytes();
|
hdr = (const sPfsHeader*)mRawBinary.data();
|
||||||
|
|
||||||
// clear variables
|
// clear variables
|
||||||
clear();
|
clear();
|
||||||
|
@ -135,8 +161,8 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
if (mFsType == TYPE_PFS0)
|
if (mFsType == TYPE_PFS0)
|
||||||
{
|
{
|
||||||
// get pointers to raw data
|
// get pointers to raw data
|
||||||
const sPfsFile* raw_files = (const sPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader));
|
const sPfsFile* raw_files = (const sPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
|
||||||
const char* raw_name_table = (const char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sPfsFile) * hdr->file_num.get());
|
const char* raw_name_table = (const char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sPfsFile) * hdr->file_num.get());
|
||||||
|
|
||||||
// process file entries
|
// process file entries
|
||||||
for (size_t i = 0; i < hdr->file_num.get(); i++)
|
for (size_t i = 0; i < hdr->file_num.get(); i++)
|
||||||
|
@ -151,8 +177,8 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
else if (mFsType == TYPE_HFS0)
|
else if (mFsType == TYPE_HFS0)
|
||||||
{
|
{
|
||||||
// get pointers to raw data
|
// get pointers to raw data
|
||||||
const sHashedPfsFile* raw_files = (const sHashedPfsFile*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader));
|
const sHashedPfsFile* raw_files = (const sHashedPfsFile*)(mRawBinary.data() + sizeof(sPfsHeader));
|
||||||
const char* raw_name_table = (const char*)(mBinaryBlob.getBytes() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * hdr->file_num.get());
|
const char* raw_name_table = (const char*)(mRawBinary.data() + sizeof(sPfsHeader) + sizeof(sHashedPfsFile) * hdr->file_num.get());
|
||||||
|
|
||||||
// process file entries
|
// process file entries
|
||||||
for (size_t i = 0; i < hdr->file_num.get(); i++)
|
for (size_t i = 0; i < hdr->file_num.get(); i++)
|
||||||
|
@ -171,7 +197,7 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
|
||||||
|
|
||||||
void nx::PfsHeader::clear()
|
void nx::PfsHeader::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mFsType = TYPE_PFS0;
|
mFsType = TYPE_PFS0;
|
||||||
mFileList.clear();
|
mFileList.clear();
|
||||||
}
|
}
|
||||||
|
@ -220,52 +246,8 @@ size_t nx::PfsHeader::getFileEntrySize(FsType fs_type)
|
||||||
|
|
||||||
void nx::PfsHeader::calculateOffsets(size_t data_offset)
|
void nx::PfsHeader::calculateOffsets(size_t data_offset)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < mFileList.getSize(); i++)
|
for (size_t i = 0; i < mFileList.size(); i++)
|
||||||
{
|
{
|
||||||
mFileList[i].offset = (i == 0) ? data_offset : mFileList[i - 1].offset + mFileList[i - 1].size;
|
mFileList[i].offset = (i == 0) ? data_offset : mFileList[i - 1].offset + mFileList[i - 1].size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::PfsHeader::isEqual(const PfsHeader & other) const
|
|
||||||
{
|
|
||||||
return (mFsType == other.mFsType) && (mFileList == other.mFileList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::PfsHeader::copyFrom(const PfsHeader & other)
|
|
||||||
{
|
|
||||||
if (other.getSize())
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
mFsType = other.mFsType;
|
|
||||||
mFileList = other.mFileList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::PfsHeader::operator==(const PfsHeader & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::PfsHeader::operator!=(const PfsHeader & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nx::PfsHeader::operator=(const PfsHeader & other)
|
|
||||||
{
|
|
||||||
copyFrom(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const byte_t * nx::PfsHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::PfsHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,76 +4,75 @@ using namespace nx;
|
||||||
|
|
||||||
SacBinary::SacBinary()
|
SacBinary::SacBinary()
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SacBinary::SacBinary(const SacBinary & other)
|
SacBinary::SacBinary(const SacBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
SacBinary::SacBinary(const byte_t * 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)
|
void SacBinary::operator=(const SacBinary & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().data())
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
mServices = other.mServices;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * SacBinary::getBytes() const
|
bool SacBinary::operator==(const SacBinary & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return mServices == other.mServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SacBinary::getSize() const
|
bool SacBinary::operator!=(const SacBinary & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SacBinary::exportBinary()
|
void SacBinary::toBytes()
|
||||||
{
|
{
|
||||||
size_t totalSize = 0;
|
size_t totalSize = 0;
|
||||||
for (size_t i = 0; i < mServices.getSize(); i++)
|
for (size_t i = 0; i < mServices.size(); i++)
|
||||||
{
|
{
|
||||||
mServices[i].exportBinary();
|
mServices[i].toBytes();
|
||||||
totalSize += mServices[i].getSize();
|
totalSize += mServices[i].getBytes().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
mBinaryBlob.alloc(totalSize);
|
mRawBinary.alloc(totalSize);
|
||||||
for (size_t i = 0, pos = 0; i < mServices.getSize(); pos += mServices[i].getSize(), i++)
|
for (size_t i = 0, pos = 0; i < mServices.size(); pos += mServices[i].getBytes().size(), i++)
|
||||||
{
|
{
|
||||||
memcpy((mBinaryBlob.getBytes() + pos), mServices[i].getBytes(), mServices[i].getSize());
|
memcpy((mRawBinary.data() + pos), mServices[i].getBytes().data(), mServices[i].getBytes().size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SacBinary::importBinary(const byte_t * bytes, size_t len)
|
void SacBinary::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
mBinaryBlob.alloc(len);
|
mRawBinary.alloc(len);
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
SacEntry svc;
|
SacEntry sac;
|
||||||
for (size_t pos = 0; pos < len; pos += mServices.atBack().getSize())
|
for (size_t pos = 0; pos < len; pos += mServices.atBack().getBytes().size())
|
||||||
{
|
{
|
||||||
svc.importBinary((const byte_t*)(mBinaryBlob.getBytes() + pos), len - pos);
|
sac.fromBytes((const byte_t*)(mRawBinary.data() + pos), len - pos);
|
||||||
mServices.addElement(svc);
|
mServices.addElement(sac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& SacBinary::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
void nx::SacBinary::clear()
|
void nx::SacBinary::clear()
|
||||||
{
|
{
|
||||||
mBinaryBlob.clear();
|
mRawBinary.clear();
|
||||||
mServices.clear();
|
mServices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,21 +85,3 @@ void SacBinary::addService(const SacEntry& service)
|
||||||
{
|
{
|
||||||
mServices.addElement(service);
|
mServices.addElement(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,52 +3,52 @@
|
||||||
using namespace nx;
|
using namespace nx;
|
||||||
|
|
||||||
SacEntry::SacEntry() :
|
SacEntry::SacEntry() :
|
||||||
mIsServer(false),
|
|
||||||
mName("")
|
|
||||||
{
|
{
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SacEntry::SacEntry(const std::string & name, bool isServer) :
|
SacEntry::SacEntry(const std::string & name, bool isServer) :
|
||||||
mIsServer(isServer),
|
mIsServer(isServer),
|
||||||
mName(name)
|
mName(name)
|
||||||
{
|
{
|
||||||
exportBinary();
|
toBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
SacEntry::SacEntry(const SacEntry & other)
|
SacEntry::SacEntry(const SacEntry & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
*this = other;
|
||||||
}
|
|
||||||
|
|
||||||
bool SacEntry::operator==(const SacEntry & other) const
|
|
||||||
{
|
|
||||||
return isEqual(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SacEntry::operator!=(const SacEntry & other) const
|
|
||||||
{
|
|
||||||
return !isEqual(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SacEntry::operator=(const SacEntry & other)
|
void SacEntry::operator=(const SacEntry & other)
|
||||||
{
|
{
|
||||||
copyFrom(other);
|
if (other.getBytes().size())
|
||||||
|
{
|
||||||
|
fromBytes(other.getBytes().data(), other.getBytes().size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
this->mIsServer = other.mIsServer;
|
||||||
|
this->mName = other.mName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const byte_t * SacEntry::getBytes() const
|
bool SacEntry::operator==(const SacEntry & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getBytes();
|
return (mIsServer == other.mIsServer) \
|
||||||
|
&& (mName == other.mName);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SacEntry::getSize() const
|
bool SacEntry::operator!=(const SacEntry & other) const
|
||||||
{
|
{
|
||||||
return mBinaryBlob.getSize();
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SacEntry::exportBinary()
|
|
||||||
|
void SacEntry::toBytes()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
mBinaryBlob.alloc(mName.size() + 1);
|
mRawBinary.alloc(mName.size() + 1);
|
||||||
}
|
}
|
||||||
catch (const fnd::Exception& e)
|
catch (const fnd::Exception& e)
|
||||||
{
|
{
|
||||||
|
@ -66,14 +66,14 @@ void SacEntry::exportBinary()
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy data into binary blob
|
// copy data into binary blob
|
||||||
mBinaryBlob[0] = (mIsServer ? SAC_IS_SERVER : 0) | ((mName.length()-1) & SAC_NAME_LEN_MASK); // bug?
|
mRawBinary[0] = (mIsServer ? SAC_IS_SERVER : 0) | ((mName.length()-1) & SAC_NAME_LEN_MASK); // bug?
|
||||||
memcpy(mBinaryBlob.getBytes() + 1, mName.c_str(), mName.length());
|
memcpy(mRawBinary.data() + 1, mName.c_str(), mName.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SacEntry::importBinary(const byte_t * bytes, size_t len)
|
void SacEntry::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
bool isServer = (bytes[0] & SAC_IS_SERVER) == SAC_IS_SERVER;
|
bool isServer = (data[0] & SAC_IS_SERVER) == SAC_IS_SERVER;
|
||||||
size_t nameLen = (bytes[0] & SAC_NAME_LEN_MASK) + 1; // bug?
|
size_t nameLen = (data[0] & SAC_NAME_LEN_MASK) + 1; // bug?
|
||||||
|
|
||||||
if (nameLen+1 > len)
|
if (nameLen+1 > len)
|
||||||
{
|
{
|
||||||
|
@ -89,11 +89,16 @@ void SacEntry::importBinary(const byte_t * bytes, size_t len)
|
||||||
throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)");
|
throw fnd::Exception(kModuleName, "Service name string too long (max 8 chars)");
|
||||||
}
|
}
|
||||||
|
|
||||||
mBinaryBlob.alloc(nameLen + 1);
|
mRawBinary.alloc(nameLen + 1);
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
mIsServer = isServer;
|
mIsServer = isServer;
|
||||||
mName = std::string((const char*)(mBinaryBlob.getBytes() + 1), nameLen);
|
mName = std::string((const char*)(mRawBinary.data() + 1), nameLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& SacEntry::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::SacEntry::clear()
|
void nx::SacEntry::clear()
|
||||||
|
@ -126,22 +131,3 @@ void SacEntry::setName(const std::string & name)
|
||||||
|
|
||||||
mName = name;
|
mName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SacEntry::isEqual(const SacEntry & other) const
|
|
||||||
{
|
|
||||||
return (mIsServer == other.mIsServer) \
|
|
||||||
&& (mName == other.mName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SacEntry::copyFrom(const SacEntry & other)
|
|
||||||
{
|
|
||||||
if (other.getSize())
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->mIsServer = other.mIsServer;
|
|
||||||
this->mName = other.mName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,39 +1,16 @@
|
||||||
#include <nx/XciHeader.h>
|
#include <nx/XciHeader.h>
|
||||||
|
|
||||||
bool nx::XciHeader::isEqual(const XciHeader& other) const
|
nx::XciHeader::XciHeader()
|
||||||
{
|
{
|
||||||
return ( mRomAreaStartPage == other.mRomAreaStartPage \
|
clear();
|
||||||
&& mBackupAreaStartPage == other.mBackupAreaStartPage \
|
|
||||||
&& mKekIndex == other.mKekIndex \
|
|
||||||
&& mTitleKeyDecIndex == other.mTitleKeyDecIndex \
|
|
||||||
&& mRomSize == other.mRomSize \
|
|
||||||
&& mCardHeaderVersion == other.mCardHeaderVersion \
|
|
||||||
&& mFlags == other.mFlags \
|
|
||||||
&& mPackageId == other.mPackageId \
|
|
||||||
&& mValidDataEndPage == other.mValidDataEndPage \
|
|
||||||
&& mAesCbcIv == other.mAesCbcIv \
|
|
||||||
&& mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \
|
|
||||||
&& mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \
|
|
||||||
&& mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \
|
|
||||||
&& mInitialDataHash == other.mInitialDataHash \
|
|
||||||
&& mSelSec == other.mSelSec \
|
|
||||||
&& mSelT1Key == other.mSelT1Key \
|
|
||||||
&& mSelKey == other.mSelKey \
|
|
||||||
&& mLimAreaPage == other.mLimAreaPage \
|
|
||||||
&& mFwVersion[0] == other.mFwVersion[0] \
|
|
||||||
&& mFwVersion[1] == other.mFwVersion[1] \
|
|
||||||
&& mAccCtrl1 == other.mAccCtrl1 \
|
|
||||||
&& mWait1TimeRead == other.mWait1TimeRead \
|
|
||||||
&& mWait2TimeRead == other.mWait2TimeRead \
|
|
||||||
&& mWait1TimeWrite == other.mWait1TimeWrite \
|
|
||||||
&& mWait2TimeWrite == other.mWait2TimeWrite \
|
|
||||||
&& mFwMode == other.mFwMode \
|
|
||||||
&& mUppVersion == other.mUppVersion \
|
|
||||||
&& memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \
|
|
||||||
&& mUppId == other.mUppId );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::XciHeader::copyFrom(const XciHeader& other)
|
nx::XciHeader::XciHeader(const XciHeader& other)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nx::XciHeader::operator=(const XciHeader& other)
|
||||||
{
|
{
|
||||||
mRomAreaStartPage = other.mRomAreaStartPage;
|
mRomAreaStartPage = other.mRomAreaStartPage;
|
||||||
mBackupAreaStartPage = other.mBackupAreaStartPage;
|
mBackupAreaStartPage = other.mBackupAreaStartPage;
|
||||||
|
@ -66,51 +43,50 @@ void nx::XciHeader::copyFrom(const XciHeader& other)
|
||||||
mUppId = other.mUppId;
|
mUppId = other.mUppId;
|
||||||
}
|
}
|
||||||
|
|
||||||
nx::XciHeader::XciHeader()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nx::XciHeader::XciHeader(const XciHeader& other)
|
|
||||||
{
|
|
||||||
importBinary(other.getBytes(), other.getSize());
|
|
||||||
}
|
|
||||||
nx::XciHeader::XciHeader(const byte_t* bytes, size_t len)
|
|
||||||
{
|
|
||||||
importBinary(bytes, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nx::XciHeader::operator==(const XciHeader& other) const
|
bool nx::XciHeader::operator==(const XciHeader& other) const
|
||||||
{
|
{
|
||||||
return isEqual(other);
|
return (mRomAreaStartPage == other.mRomAreaStartPage \
|
||||||
|
&& mBackupAreaStartPage == other.mBackupAreaStartPage \
|
||||||
|
&& mKekIndex == other.mKekIndex \
|
||||||
|
&& mTitleKeyDecIndex == other.mTitleKeyDecIndex \
|
||||||
|
&& mRomSize == other.mRomSize \
|
||||||
|
&& mCardHeaderVersion == other.mCardHeaderVersion \
|
||||||
|
&& mFlags == other.mFlags \
|
||||||
|
&& mPackageId == other.mPackageId \
|
||||||
|
&& mValidDataEndPage == other.mValidDataEndPage \
|
||||||
|
&& mAesCbcIv == other.mAesCbcIv \
|
||||||
|
&& mPartitionFsHeaderAddress == other.mPartitionFsHeaderAddress \
|
||||||
|
&& mPartitionFsHeaderSize == other.mPartitionFsHeaderSize \
|
||||||
|
&& mPartitionFsHeaderHash == other.mPartitionFsHeaderHash \
|
||||||
|
&& mInitialDataHash == other.mInitialDataHash \
|
||||||
|
&& mSelSec == other.mSelSec \
|
||||||
|
&& mSelT1Key == other.mSelT1Key \
|
||||||
|
&& mSelKey == other.mSelKey \
|
||||||
|
&& mLimAreaPage == other.mLimAreaPage \
|
||||||
|
&& mFwVersion[0] == other.mFwVersion[0] \
|
||||||
|
&& mFwVersion[1] == other.mFwVersion[1] \
|
||||||
|
&& mAccCtrl1 == other.mAccCtrl1 \
|
||||||
|
&& mWait1TimeRead == other.mWait1TimeRead \
|
||||||
|
&& mWait2TimeRead == other.mWait2TimeRead \
|
||||||
|
&& mWait1TimeWrite == other.mWait1TimeWrite \
|
||||||
|
&& mWait2TimeWrite == other.mWait2TimeWrite \
|
||||||
|
&& mFwMode == other.mFwMode \
|
||||||
|
&& mUppVersion == other.mUppVersion \
|
||||||
|
&& memcmp(mUppHash, other.mUppHash, xci::kUppHashLen) \
|
||||||
|
&& mUppId == other.mUppId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nx::XciHeader::operator!=(const XciHeader& other) const
|
bool nx::XciHeader::operator!=(const XciHeader& other) const
|
||||||
{
|
{
|
||||||
return isEqual(other) == false;
|
return !(*this == other);
|
||||||
}
|
|
||||||
void nx::XciHeader::operator=(const XciHeader& other)
|
|
||||||
{
|
|
||||||
copyFrom(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// to be used after export
|
void nx::XciHeader::toBytes()
|
||||||
const byte_t* nx::XciHeader::getBytes() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nx::XciHeader::getSize() const
|
|
||||||
{
|
|
||||||
return mBinaryBlob.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// export/import binary
|
|
||||||
void nx::XciHeader::exportBinary()
|
|
||||||
{
|
{
|
||||||
fnd::Exception(kModuleName, "exportBinary() not implemented");
|
fnd::Exception(kModuleName, "exportBinary() not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
|
void nx::XciHeader::fromBytes(const byte_t* data, size_t len)
|
||||||
{
|
{
|
||||||
// check input data size
|
// check input data size
|
||||||
if (len < sizeof(sXciHeader))
|
if (len < sizeof(sXciHeader))
|
||||||
|
@ -122,11 +98,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
// allocate internal local binary copy
|
// allocate internal local binary copy
|
||||||
mBinaryBlob.alloc(sizeof(sXciHeader));
|
mRawBinary.alloc(sizeof(sXciHeader));
|
||||||
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
|
memcpy(mRawBinary.data(), data, mRawBinary.size());
|
||||||
|
|
||||||
// get sXciHeader ptr
|
// get sXciHeader ptr
|
||||||
const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes();
|
const nx::sXciHeader* hdr = (const nx::sXciHeader*)mRawBinary.data();
|
||||||
|
|
||||||
// check XCI signature
|
// check XCI signature
|
||||||
if (hdr->signature.get() != xci::kXciSig)
|
if (hdr->signature.get() != xci::kXciSig)
|
||||||
|
@ -172,6 +148,11 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fnd::Vec<byte_t>& nx::XciHeader::getBytes() const
|
||||||
|
{
|
||||||
|
return mRawBinary;
|
||||||
|
}
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
void nx::XciHeader::clear()
|
void nx::XciHeader::clear()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue