Merge pull request #15 from jakcron/struct-magic-refactor

[nx|nstool] Changed struct magic from strings to words.
This commit is contained in:
Jack 2018-06-03 15:44:30 +08:00 committed by GitHub
commit 4c9d0e5f37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 74 additions and 62 deletions

View file

@ -4,13 +4,14 @@
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
namespace aci namespace aci
{ {
const std::string kAciStructSig = "ACI0"; static const uint32_t kAciStructSig = _MAKE_STRUCT_SIGNATURE("ACI0");
const std::string kAciDescStructSig = "ACID"; static const uint32_t kAciDescStructSig = _MAKE_STRUCT_SIGNATURE("ACID");
static const size_t kAciAlignSize = 0x10; static const size_t kAciAlignSize = 0x10;
enum Flags enum Flags
@ -22,7 +23,7 @@ namespace nx
#pragma pack(push,1) #pragma pack(push,1)
struct sAciHeader struct sAciHeader
{ {
char signature[4]; le_uint32_t signature;
le_uint32_t size; // includes prefacing signature, set only in ACID made by SDK (it enables easy resigning) le_uint32_t size; // includes prefacing signature, set only in ACID made by SDK (it enables easy resigning)
byte_t reserved_0[4]; byte_t reserved_0[4];
le_uint32_t flags; // set in ACID only le_uint32_t flags; // set in ACID only

View file

@ -3,13 +3,14 @@
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
// Also known to the public as IVFC // Also known to the public as IVFC
namespace hierarchicalintegrity namespace hierarchicalintegrity
{ {
const std::string kStructSig = "IVFC"; static const uint32_t kStructSig = _MAKE_STRUCT_SIGNATURE("IVFC");
static const uint32_t kRomfsTypeId = 0x20000; static const uint32_t kRomfsTypeId = 0x20000;
static const size_t kDefaultLayerNum = 6; static const size_t kDefaultLayerNum = 6;
static const size_t kHeaderAlignLen = 0x20; static const size_t kHeaderAlignLen = 0x20;
@ -18,7 +19,7 @@ namespace nx
#pragma pack(push,1) #pragma pack(push,1)
struct sHierarchicalIntegrityHeader struct sHierarchicalIntegrityHeader
{ {
char signature[4]; le_uint32_t signature;
le_uint32_t type_id; le_uint32_t type_id;
le_uint32_t master_hash_size; le_uint32_t master_hash_size;
le_uint32_t layer_num; le_uint32_t layer_num;

View file

@ -0,0 +1,3 @@
#pragma once
#define _MAKE_STRUCT_SIGNATURE(x) ((uint32_t)(x[3]) << 24 | (uint32_t)(x[2]) << 16 | (uint32_t)(x[1]) << 8 | (uint32_t)(x[0]))

View file

@ -5,13 +5,14 @@
#include <crypto/sha.h> #include <crypto/sha.h>
#include <crypto/rsa.h> #include <crypto/rsa.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
namespace nca namespace nca
{ {
const std::string kNca2Sig = "NCA2"; static const uint32_t kNca2Sig = _MAKE_STRUCT_SIGNATURE("NCA2");
const std::string kNca3Sig = "NCA3"; static const uint32_t kNca3Sig = _MAKE_STRUCT_SIGNATURE("NCA3");
static const size_t kSectorSize = 0x200; static const size_t kSectorSize = 0x200;
static const size_t kPartitionNum = 4; static const size_t kPartitionNum = 4;
static const size_t kHeaderSectorNum = 6; static const size_t kHeaderSectorNum = 6;
@ -88,7 +89,7 @@ namespace nx
#pragma pack(push,1) #pragma pack(push,1)
struct sNcaHeader struct sNcaHeader
{ {
char signature[4]; le_uint32_t signature;
byte_t distribution_type; byte_t distribution_type;
byte_t content_type; byte_t content_type;
byte_t key_generation; byte_t key_generation;

View file

@ -4,12 +4,13 @@
#include <crypto/aes.h> #include <crypto/aes.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
namespace npdm namespace npdm
{ {
const std::string kNpdmStructSig = "META"; static const uint32_t kNpdmStructSig = _MAKE_STRUCT_SIGNATURE("META");
static const size_t kNameMaxLen = 0x10; static const size_t kNameMaxLen = 0x10;
static const size_t kProductCodeMaxLen = 0x10; static const size_t kProductCodeMaxLen = 0x10;
static const uint32_t kMaxPriority = BIT(6) -1 ; static const uint32_t kMaxPriority = BIT(6) -1 ;
@ -33,7 +34,7 @@ namespace nx
struct sNpdmHeader struct sNpdmHeader
{ {
char signature[4]; le_uint32_t signature;
byte_t reserved_0[8]; byte_t reserved_0[8];
byte_t flags; byte_t flags;
byte_t reserved_1; byte_t reserved_1;

View file

@ -4,12 +4,13 @@
#include <fnd/List.h> #include <fnd/List.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
namespace nso namespace nso
{ {
const std::string kNsoSig = "NSO0"; static const uint32_t kNsoSig = _MAKE_STRUCT_SIGNATURE("NSO0");
enum HeaderFlags enum HeaderFlags
{ {
@ -41,7 +42,7 @@ namespace nx
struct sNsoHeader struct sNsoHeader
{ {
char signature[4]; le_uint32_t signature;
le_uint32_t format_version; le_uint32_t format_version;
byte_t reserved_1[4]; byte_t reserved_1[4];
le_uint32_t flags; le_uint32_t flags;

View file

@ -2,20 +2,21 @@
#include <fnd/types.h> #include <fnd/types.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
namespace pfs namespace pfs
{ {
const std::string kPfsSig = "PFS0"; static const uint32_t kPfsSig = _MAKE_STRUCT_SIGNATURE("PFS0");
const std::string kHashedPfsSig = "HFS0"; static const uint32_t kHashedPfsSig = _MAKE_STRUCT_SIGNATURE("HFS0");
static const size_t kHeaderAlign = 64; static const size_t kHeaderAlign = 64;
} }
#pragma pack(push,1) #pragma pack(push,1)
struct sPfsHeader struct sPfsHeader
{ {
char signature[4]; le_uint32_t signature;
le_uint32_t file_num; le_uint32_t file_num;
le_uint32_t name_table_size; le_uint32_t name_table_size;
byte_t padding[4]; byte_t padding[4];

View file

@ -6,12 +6,13 @@
#include <crypto/sha.h> #include <crypto/sha.h>
#include <crypto/rsa.h> #include <crypto/rsa.h>
#include <fnd/ISerialiseableBinary.h> #include <fnd/ISerialiseableBinary.h>
#include <nx/macro.h>
namespace nx namespace nx
{ {
namespace xci namespace xci
{ {
const std::string kXciSig = "HEAD"; static const uint32_t kXciSig = _MAKE_STRUCT_SIGNATURE("HEAD");
static const uint32_t kHeaderEncOffset = 0x90; static const uint32_t kHeaderEncOffset = 0x90;
static const uint32_t kHeaderEncSize = 0x70; static const uint32_t kHeaderEncSize = 0x70;
static const uint32_t kPageSize = 0x200; static const uint32_t kPageSize = 0x200;
@ -68,7 +69,7 @@ namespace nx
#pragma pack(push,1) #pragma pack(push,1)
struct sXciHeader struct sXciHeader
{ {
char signature[4]; le_uint32_t signature;
le_uint32_t rom_area_start_page; le_uint32_t rom_area_start_page;
le_uint32_t backup_area_start_page; le_uint32_t backup_area_start_page;
byte_t key_flag; byte_t key_flag;

View file

@ -95,10 +95,10 @@ void AciHeader::exportBinary()
switch (mType) switch (mType)
{ {
case (TYPE_ACI0): case (TYPE_ACI0):
memcpy(hdr->signature, aci::kAciStructSig.c_str(), 4); hdr->signature = aci::kAciStructSig;
break; break;
case (TYPE_ACID): case (TYPE_ACID):
memcpy(hdr->signature, aci::kAciDescStructSig.c_str(), 4); hdr->signature = aci::kAciDescStructSig;
break; break;
default: default:
throw fnd::Exception(kModuleName, "Unexpected ACI type"); throw fnd::Exception(kModuleName, "Unexpected ACI type");
@ -149,16 +149,15 @@ void AciHeader::importBinary(const byte_t * bytes, size_t len)
sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes(); sAciHeader* hdr = (sAciHeader*)mBinaryBlob.getBytes();
if (std::string(hdr->signature, 4) == aci::kAciStructSig) switch (hdr->signature.get())
{ {
case (aci::kAciStructSig):
mType = TYPE_ACI0; mType = TYPE_ACI0;
} break;
else if (std::string(hdr->signature, 4) == aci::kAciDescStructSig) case (aci::kAciDescStructSig):
{
mType = TYPE_ACID; mType = TYPE_ACID;
} break;
else default:
{
throw fnd::Exception(kModuleName, "ACI header corrupt"); throw fnd::Exception(kModuleName, "ACI header corrupt");
} }

View file

@ -59,7 +59,7 @@ void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t
const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)bytes; const nx::sHierarchicalIntegrityHeader* hdr = (const nx::sHierarchicalIntegrityHeader*)bytes;
// Validate Header Sig "IVFC" // Validate Header Sig "IVFC"
if (std::string(hdr->signature, 4) != hierarchicalintegrity::kStructSig) if (hdr->signature.get() != hierarchicalintegrity::kStructSig)
{ {
throw fnd::Exception(kModuleName, "Invalid struct magic"); throw fnd::Exception(kModuleName, "Invalid struct magic");
} }

View file

@ -12,10 +12,10 @@ void NcaHeader::exportBinary()
switch(mFormatVersion) switch(mFormatVersion)
{ {
case (NCA2_FORMAT): case (NCA2_FORMAT):
strncpy(hdr->signature, nca::kNca2Sig.c_str(), 4); hdr->signature = nca::kNca2Sig;
break; break;
case (NCA3_FORMAT): case (NCA3_FORMAT):
strncpy(hdr->signature, nca::kNca3Sig.c_str(), 4); hdr->signature = nca::kNca3Sig;
break; break;
default: default:
throw fnd::Exception(kModuleName, "Unsupported format version"); throw fnd::Exception(kModuleName, "Unsupported format version");
@ -74,17 +74,14 @@ void NcaHeader::importBinary(const byte_t * bytes, size_t len)
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes(); sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
std::string sig = std::string(hdr->signature, 4); switch(hdr->signature.get())
if (sig == nca::kNca2Sig)
{
mFormatVersion = NCA2_FORMAT;
}
else if (sig == nca::kNca3Sig)
{
mFormatVersion = NCA3_FORMAT;
}
else
{ {
case (nca::kNca2Sig) :
mFormatVersion = NCA2_FORMAT;
break;
case (nca::kNca3Sig) :
mFormatVersion = NCA3_FORMAT;
break;
throw fnd::Exception(kModuleName, "NCA header corrupt"); throw fnd::Exception(kModuleName, "NCA header corrupt");
} }

View file

@ -9,7 +9,7 @@ void nx::NcaUtils::decryptNcaHeader(const byte_t* src, byte_t* dst, const crypto
crypto::aes::AesXtsMakeTweak(tweak, 1); crypto::aes::AesXtsMakeTweak(tweak, 1);
crypto::aes::AesXtsDecryptSector(src + sectorToOffset(1), nx::nca::kSectorSize, key.key[0], key.key[1], tweak, raw_hdr); crypto::aes::AesXtsDecryptSector(src + sectorToOffset(1), nx::nca::kSectorSize, key.key[0], key.key[1], tweak, raw_hdr);
bool useNca2SectorIndex = memcmp(((nx::sNcaHeader*)(raw_hdr))->signature, nx::nca::kNca2Sig.c_str(), 4) == 0; bool useNca2SectorIndex = ((nx::sNcaHeader*)(raw_hdr))->signature.get() == nx::nca::kNca2Sig;
// decrypt whole header // decrypt whole header
for (size_t i = 0; i < nx::nca::kHeaderSectorNum; i++) for (size_t i = 0; i < nx::nca::kHeaderSectorNum; i++)

View file

@ -88,7 +88,7 @@ void nx::NpdmHeader::exportBinary()
mBinaryBlob.alloc(sizeof(sNpdmHeader)); mBinaryBlob.alloc(sizeof(sNpdmHeader));
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes();
memcpy(hdr->signature, npdm::kNpdmStructSig.c_str(), 4); 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;
hdr->flags = flag; hdr->flags = flag;
hdr->main_thread_priority = mMainThreadPriority; hdr->main_thread_priority = mMainThreadPriority;
@ -118,7 +118,7 @@ void nx::NpdmHeader::importBinary(const byte_t * bytes, size_t len)
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize()); memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes(); sNpdmHeader* hdr = (sNpdmHeader*)mBinaryBlob.getBytes();
if (std::string(hdr->signature, 4) != npdm::kNpdmStructSig) if (hdr->signature.get() != npdm::kNpdmStructSig)
{ {
throw fnd::Exception(kModuleName, "NPDM header corrupt"); throw fnd::Exception(kModuleName, "NPDM header corrupt");
} }

View file

@ -46,7 +46,7 @@ void nx::NsoHeader::exportBinary()
nx::sNsoHeader* hdr = (nx::sNsoHeader*)mBinaryBlob.getBytes(); nx::sNsoHeader* hdr = (nx::sNsoHeader*)mBinaryBlob.getBytes();
// set header identifers // set header identifers
memcpy(hdr->signature, nso::kNsoSig.c_str(), 4); hdr->signature = nso::kNsoSig;
hdr->format_version = nso::kDefaultFormatVersion; hdr->format_version = nso::kDefaultFormatVersion;
// variable to store flags before commiting to header // variable to store flags before commiting to header
@ -141,7 +141,7 @@ void nx::NsoHeader::importBinary(const byte_t* bytes, size_t len)
const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes(); const nx::sNsoHeader* hdr = (const nx::sNsoHeader*)mBinaryBlob.getBytes();
// check NSO signature // check NSO signature
if (std::string(hdr->signature, 4) != nso::kNsoSig) if (hdr->signature.get() != nso::kNsoSig)
{ {
throw fnd::Exception(kModuleName, "NSO header corrupt (unrecognised header signature)"); throw fnd::Exception(kModuleName, "NSO header corrupt (unrecognised header signature)");
} }

View file

@ -37,10 +37,10 @@ void nx::PfsHeader::exportBinary()
switch (mFsType) switch (mFsType)
{ {
case (TYPE_PFS0): case (TYPE_PFS0):
strncpy(hdr->signature, pfs::kPfsSig.c_str(), 4); hdr->signature = pfs::kPfsSig;
break; break;
case (TYPE_HFS0): case (TYPE_HFS0):
strncpy(hdr->signature, pfs::kHashedPfsSig.c_str(), 4); hdr->signature = pfs::kHashedPfsSig;
break; break;
} }
@ -102,12 +102,17 @@ void nx::PfsHeader::importBinary(const byte_t * bytes, size_t len)
// check struct signature // check struct signature
FsType fs_type; FsType fs_type;
if (memcmp(hdr->signature, pfs::kPfsSig.c_str(), 4) == 0) switch(hdr->signature.get())
fs_type = TYPE_PFS0; {
else if (memcmp(hdr->signature, pfs::kHashedPfsSig.c_str(), 4) == 0) case (pfs::kPfsSig):
fs_type = TYPE_HFS0; fs_type = TYPE_PFS0;
else break;
throw fnd::Exception(kModuleName, "PFS header corrupt"); case (pfs::kHashedPfsSig):
fs_type = TYPE_HFS0;
break;
default:
throw fnd::Exception(kModuleName, "PFS header corrupt");
}
// determine complete header size // determine complete header size
size_t pfs_full_header_size = sizeof(sPfsHeader) + getFileEntrySize(fs_type) * hdr->file_num.get() + hdr->name_table_size.get(); size_t pfs_full_header_size = sizeof(sPfsHeader) + getFileEntrySize(fs_type) * hdr->file_num.get() + hdr->name_table_size.get();

View file

@ -129,7 +129,7 @@ void nx::XciHeader::importBinary(const byte_t* bytes, size_t len)
const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes(); const nx::sXciHeader* hdr = (const nx::sXciHeader*)mBinaryBlob.getBytes();
// check XCI signature // check XCI signature
if (std::string(hdr->signature, 4) != xci::kXciSig) if (hdr->signature.get() != xci::kXciSig)
{ {
throw fnd::Exception(kModuleName, "XCI header corrupt"); throw fnd::Exception(kModuleName, "XCI header corrupt");
} }

View file

@ -124,7 +124,7 @@ void PfsProcess::displayFs()
size_t PfsProcess::determineHeaderSize(const nx::sPfsHeader* hdr) size_t PfsProcess::determineHeaderSize(const nx::sPfsHeader* hdr)
{ {
size_t fileEntrySize = 0; size_t fileEntrySize = 0;
if (std::string(hdr->signature, 4) == nx::pfs::kPfsSig) if (hdr->signature.get() == nx::pfs::kPfsSig)
fileEntrySize = sizeof(nx::sPfsFile); fileEntrySize = sizeof(nx::sPfsFile);
else else
fileEntrySize = sizeof(nx::sHashedPfsFile); fileEntrySize = sizeof(nx::sHashedPfsFile);
@ -134,7 +134,7 @@ size_t PfsProcess::determineHeaderSize(const nx::sPfsHeader* hdr)
bool PfsProcess::validateHeaderMagic(const nx::sPfsHeader* hdr) bool PfsProcess::validateHeaderMagic(const nx::sPfsHeader* hdr)
{ {
return std::string(hdr->signature, 4) == nx::pfs::kPfsSig || std::string(hdr->signature, 4) == nx::pfs::kHashedPfsSig; return hdr->signature.get() == nx::pfs::kPfsSig || hdr->signature.get() == nx::pfs::kHashedPfsSig;
} }
void PfsProcess::validateHfs() void PfsProcess::validateHfs()

View file

@ -650,27 +650,28 @@ FileType UserSettings::determineFileTypeFromFile(const std::string& path)
#define _ASSERT_SIZE(size) (scratch.getSize() >= (size)) #define _ASSERT_SIZE(size) (scratch.getSize() >= (size))
// test npdm // test npdm
if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && std::string(_QUICK_CAST(nx::sXciHeaderPage, 0)->header.signature, 4) == nx::xci::kXciSig) if (_ASSERT_SIZE(sizeof(nx::sXciHeaderPage)) && _QUICK_CAST(nx::sXciHeaderPage, 0)->header.signature.get() == nx::xci::kXciSig)
file_type = FILE_XCI; file_type = FILE_XCI;
// test pfs0 // test pfs0
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && std::string(_QUICK_CAST(nx::sPfsHeader, 0)->signature, 4) == nx::pfs::kPfsSig) else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _QUICK_CAST(nx::sPfsHeader, 0)->signature.get() == nx::pfs::kPfsSig)
file_type = FILE_PARTITIONFS; file_type = FILE_PARTITIONFS;
// test hfs0 // test hfs0
else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && std::string(_QUICK_CAST(nx::sPfsHeader, 0)->signature, 4) == nx::pfs::kHashedPfsSig) else if (_ASSERT_SIZE(sizeof(nx::sPfsHeader)) && _QUICK_CAST(nx::sPfsHeader, 0)->signature.get() == nx::pfs::kHashedPfsSig)
file_type = FILE_PARTITIONFS; file_type = FILE_PARTITIONFS;
// test romfs // test romfs
else if (_ASSERT_SIZE(sizeof(nx::sRomfsHeader)) && _QUICK_CAST(nx::sRomfsHeader, 0)->header_size.get() == sizeof(nx::sRomfsHeader) && _QUICK_CAST(nx::sRomfsHeader, 0)->sections[1].offset.get() == (_QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].offset.get() + _QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].size.get())) else if (_ASSERT_SIZE(sizeof(nx::sRomfsHeader)) && _QUICK_CAST(nx::sRomfsHeader, 0)->header_size.get() == sizeof(nx::sRomfsHeader) && _QUICK_CAST(nx::sRomfsHeader, 0)->sections[1].offset.get() == (_QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].offset.get() + _QUICK_CAST(nx::sRomfsHeader, 0)->sections[0].size.get()))
file_type = FILE_ROMFS; file_type = FILE_ROMFS;
// test nca2 // test nca2
else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && std::string(nca_header->signature, 4) == nx::nca::kNca2Sig) else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && nca_header->signature.get() == nx::nca::kNca2Sig)
file_type = FILE_NCA; file_type = FILE_NCA;
// test nca3 // test nca3
else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && std::string(nca_header->signature, 4) == nx::nca::kNca3Sig) else if (_ASSERT_SIZE(nx::nca::kHeaderSize) && nca_header->signature.get() == nx::nca::kNca3Sig)
file_type = FILE_NCA; file_type = FILE_NCA;
// test npdm // test npdm
else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && std::string(_QUICK_CAST(nx::sNpdmHeader, 0)->signature, 4) == nx::npdm::kNpdmStructSig) else if (_ASSERT_SIZE(sizeof(nx::sNpdmHeader)) && _QUICK_CAST(nx::sNpdmHeader, 0)->signature.get() == nx::npdm::kNpdmStructSig)
file_type = FILE_NPDM; file_type = FILE_NPDM;
else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && std::string(_QUICK_CAST(nx::sNsoHeader, 0)->signature, 4) == nx::nso::kNsoSig) // test nso
else if (_ASSERT_SIZE(sizeof(nx::sNsoHeader)) && _QUICK_CAST(nx::sNsoHeader, 0)->signature.get() == nx::nso::kNsoSig)
file_type = FILE_NSO; file_type = FILE_NSO;
// else unrecognised // else unrecognised
else else