From f93acfad07cba0fc336567aad8f9bbc400ca1230 Mon Sep 17 00:00:00 2001 From: jakcron Date: Sun, 23 Sep 2018 11:29:22 +0800 Subject: [PATCH] [nstool] Improve fnd::IFile ptr handling/sharing with fnd::SharedPtr --- programs/nstool/source/AesCtrWrappedIFile.cpp | 25 +++------- programs/nstool/source/AesCtrWrappedIFile.h | 7 ++- programs/nstool/source/AssetProcess.cpp | 35 +++++-------- programs/nstool/source/AssetProcess.h | 7 ++- programs/nstool/source/CnmtProcess.cpp | 20 ++------ programs/nstool/source/CnmtProcess.h | 7 ++- programs/nstool/source/EsTikProcess.cpp | 20 ++------ programs/nstool/source/EsTikProcess.h | 7 ++- .../nstool/source/HashTreeWrappedIFile.cpp | 28 ++++------- programs/nstool/source/HashTreeWrappedIFile.h | 9 ++-- programs/nstool/source/NacpProcess.cpp | 20 ++------ programs/nstool/source/NacpProcess.h | 7 ++- programs/nstool/source/NcaProcess.cpp | 50 +++++-------------- programs/nstool/source/NcaProcess.h | 11 ++-- programs/nstool/source/NpdmProcess.cpp | 20 ++------ programs/nstool/source/NpdmProcess.h | 7 ++- programs/nstool/source/NroProcess.cpp | 30 ++++------- programs/nstool/source/NroProcess.h | 8 ++- programs/nstool/source/NsoProcess.cpp | 32 ++++-------- programs/nstool/source/NsoProcess.h | 8 ++- .../nstool/source/OffsetAdjustedIFile.cpp | 20 ++------ programs/nstool/source/OffsetAdjustedIFile.h | 7 ++- programs/nstool/source/PfsProcess.cpp | 26 +++------- programs/nstool/source/PfsProcess.h | 7 ++- programs/nstool/source/PkiCertProcess.cpp | 20 ++------ programs/nstool/source/PkiCertProcess.h | 7 ++- programs/nstool/source/RomfsProcess.cpp | 26 +++------- programs/nstool/source/RomfsProcess.h | 7 ++- programs/nstool/source/XciProcess.cpp | 24 +++------ programs/nstool/source/XciProcess.h | 7 ++- programs/nstool/source/main.cpp | 27 +++++----- 31 files changed, 179 insertions(+), 357 deletions(-) diff --git a/programs/nstool/source/AesCtrWrappedIFile.cpp b/programs/nstool/source/AesCtrWrappedIFile.cpp index 06ea584..3acebd7 100644 --- a/programs/nstool/source/AesCtrWrappedIFile.cpp +++ b/programs/nstool/source/AesCtrWrappedIFile.cpp @@ -1,7 +1,6 @@ #include "AesCtrWrappedIFile.h" -AesCtrWrappedIFile::AesCtrWrappedIFile(fnd::IFile* file, bool ownIfile, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr) : - mOwnIFile(ownIfile), +AesCtrWrappedIFile::AesCtrWrappedIFile(const fnd::SharedPtr& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr) : mFile(file), mKey(key), mBaseCtr(ctr), @@ -10,17 +9,9 @@ AesCtrWrappedIFile::AesCtrWrappedIFile(fnd::IFile* file, bool ownIfile, const fn mCache.alloc(kCacheSizeAllocSize); } -AesCtrWrappedIFile::~AesCtrWrappedIFile() -{ - if (mOwnIFile) - { - delete mFile; - } -} - size_t AesCtrWrappedIFile::size() { - return mFile->size(); + return (*mFile)->size(); } void AesCtrWrappedIFile::seek(size_t offset) @@ -44,8 +35,8 @@ void AesCtrWrappedIFile::read(byte_t* out, size_t len) //printf("[%x] AesCtrWrappedIFile::read() CACHE READ: readlen=%" PRIx64 "\n", this, read_len); - mFile->seek(read_pos); - mFile->read(mCache.data(), kCacheSizeAllocSize); + (*mFile)->seek(read_pos); + (*mFile)->read(mCache.data(), kCacheSizeAllocSize); fnd::aes::AesIncrementCounter(mBaseCtr.iv, read_pos>>4, mCurrentCtr.iv); fnd::aes::AesCtr(mCache.data(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.data()); @@ -81,8 +72,8 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len) fnd::aes::AesIncrementCounter(mBaseCtr.iv, write_pos>>4, mCurrentCtr.iv); fnd::aes::AesCtr(mCache.data(), kCacheSizeAllocSize, mKey.key, mCurrentCtr.iv, mCache.data()); - mFile->seek(write_pos); - mFile->write(mCache.data(), kCacheSizeAllocSize); + (*mFile)->seek(write_pos); + (*mFile)->write(mCache.data(), kCacheSizeAllocSize); } seek(mFileOffset + len); @@ -92,7 +83,7 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len) { memcpy(mScratch.data() + mBlockOffset, out + (i * kAesCtrScratchSize), kAesCtrScratchSize); fnd::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data()); - mFile->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize); + (*mFile)->write(mScratch.data() + mBlockOffset, kAesCtrScratchSize); } if (len % kAesCtrScratchSize) @@ -101,7 +92,7 @@ void AesCtrWrappedIFile::write(const byte_t* in, size_t len) size_t write_pos = ((len / kAesCtrScratchSize) * kAesCtrScratchSize); memcpy(mScratch.data() + mBlockOffset, out + write_pos, write_len); fnd::aes::AesCtr(mScratch.data(), kAesCtrScratchAllocSize, mKey.key, mCurrentCtr.iv, mScratch.data()); - mFile->write(mScratch.data() + mBlockOffset, write_len); + (*mFile)->write(mScratch.data() + mBlockOffset, write_len); } */ seek(mFileOffset + len); diff --git a/programs/nstool/source/AesCtrWrappedIFile.h b/programs/nstool/source/AesCtrWrappedIFile.h index 1703bc8..0404cca 100644 --- a/programs/nstool/source/AesCtrWrappedIFile.h +++ b/programs/nstool/source/AesCtrWrappedIFile.h @@ -1,12 +1,12 @@ #include +#include #include #include class AesCtrWrappedIFile : public fnd::IFile { public: - AesCtrWrappedIFile(fnd::IFile* file, bool ownIfile, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr); - ~AesCtrWrappedIFile(); + AesCtrWrappedIFile(const fnd::SharedPtr& file, const fnd::aes::sAes128Key& key, const fnd::aes::sAesIvCtr& ctr); size_t size(); void seek(size_t offset); @@ -19,8 +19,7 @@ private: static const size_t kCacheSize = 0x10000; static const size_t kCacheSizeAllocSize = kCacheSize + fnd::aes::kAesBlockSize; - bool mOwnIFile; - fnd::IFile* mFile; + fnd::SharedPtr mFile; fnd::aes::sAes128Key mKey; fnd::aes::sAesIvCtr mBaseCtr, mCurrentCtr; size_t mFileOffset; diff --git a/programs/nstool/source/AssetProcess.cpp b/programs/nstool/source/AssetProcess.cpp index 0128ee1..a218f20 100644 --- a/programs/nstool/source/AssetProcess.cpp +++ b/programs/nstool/source/AssetProcess.cpp @@ -7,20 +7,10 @@ AssetProcess::AssetProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { - -} - -AssetProcess::~AssetProcess() -{ - if (mOwnIFile) - { - delete mFile; - } } void AssetProcess::process() @@ -31,10 +21,9 @@ void AssetProcess::process() processSections(); } -void AssetProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void AssetProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void AssetProcess::setCliOutputMode(CliOutputMode type) @@ -72,18 +61,18 @@ void AssetProcess::importHeader() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - if (mFile->size() < sizeof(nn::hac::sAssetHeader)) + if ((*mFile)->size() < sizeof(nn::hac::sAssetHeader)) { throw fnd::Exception(kModuleName, "Corrupt ASET: file too small"); } scratch.alloc(sizeof(nn::hac::sAssetHeader)); - mFile->read(scratch.data(), 0, scratch.size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mHdr.fromBytes(scratch.data(), scratch.size()); } @@ -92,21 +81,21 @@ void AssetProcess::processSections() { if (mHdr.getIconInfo().size > 0 && mIconExtractPath.isSet) { - if ((mHdr.getIconInfo().size + mHdr.getIconInfo().offset) > mFile->size()) + if ((mHdr.getIconInfo().size + mHdr.getIconInfo().offset) > (*mFile)->size()) throw fnd::Exception(kModuleName, "ASET geometry for icon beyond file size"); fnd::SimpleFile outfile(mIconExtractPath.var, fnd::SimpleFile::Create); fnd::Vec cache; cache.alloc(mHdr.getIconInfo().size); - mFile->read(cache.data(), mHdr.getIconInfo().offset, cache.size()); + (*mFile)->read(cache.data(), mHdr.getIconInfo().offset, cache.size()); outfile.write(cache.data(), cache.size()); outfile.close(); } if (mHdr.getNacpInfo().size > 0) { - if ((mHdr.getNacpInfo().size + mHdr.getNacpInfo().offset) > mFile->size()) + if ((mHdr.getNacpInfo().size + mHdr.getNacpInfo().offset) > (*mFile)->size()) throw fnd::Exception(kModuleName, "ASET geometry for nacp beyond file size"); if (mNacpExtractPath.isSet) @@ -115,12 +104,12 @@ void AssetProcess::processSections() fnd::Vec cache; cache.alloc(mHdr.getNacpInfo().size); - mFile->read(cache.data(), mHdr.getNacpInfo().offset, cache.size()); + (*mFile)->read(cache.data(), mHdr.getNacpInfo().offset, cache.size()); outfile.write(cache.data(), cache.size()); outfile.close(); } - mNacp.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size), true); + mNacp.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getNacpInfo().offset, mHdr.getNacpInfo().size)); mNacp.setCliOutputMode(mCliOutputMode); mNacp.setVerifyMode(mVerify); @@ -129,10 +118,10 @@ void AssetProcess::processSections() if (mHdr.getRomfsInfo().size > 0) { - if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > mFile->size()) + if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > (*mFile)->size()) throw fnd::Exception(kModuleName, "ASET geometry for romfs beyond file size"); - mRomfs.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size), true); + mRomfs.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size)); mRomfs.setCliOutputMode(mCliOutputMode); mRomfs.setVerifyMode(mVerify); diff --git a/programs/nstool/source/AssetProcess.h b/programs/nstool/source/AssetProcess.h index 64efbc7..7364d15 100644 --- a/programs/nstool/source/AssetProcess.h +++ b/programs/nstool/source/AssetProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "NacpProcess.h" #include "RomfsProcess.h" @@ -12,11 +13,10 @@ class AssetProcess { public: AssetProcess(); - ~AssetProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -30,8 +30,7 @@ public: private: const std::string kModuleName = "AssetProcess"; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/CnmtProcess.cpp b/programs/nstool/source/CnmtProcess.cpp index 29caeb4..8abc73d 100644 --- a/programs/nstool/source/CnmtProcess.cpp +++ b/programs/nstool/source/CnmtProcess.cpp @@ -5,21 +5,12 @@ #include "CnmtProcess.h" CnmtProcess::CnmtProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -CnmtProcess::~CnmtProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void CnmtProcess::process() { importCnmt(); @@ -28,10 +19,9 @@ void CnmtProcess::process() displayCnmt(); } -void CnmtProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void CnmtProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void CnmtProcess::setCliOutputMode(CliOutputMode type) @@ -53,13 +43,13 @@ void CnmtProcess::importCnmt() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - scratch.alloc(mFile->size()); - mFile->read(scratch.data(), 0, scratch.size()); + scratch.alloc((*mFile)->size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mCnmt.fromBytes(scratch.data(), scratch.size()); } diff --git a/programs/nstool/source/CnmtProcess.h b/programs/nstool/source/CnmtProcess.h index 2fbcd15..4fa561c 100644 --- a/programs/nstool/source/CnmtProcess.h +++ b/programs/nstool/source/CnmtProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "common.h" @@ -10,11 +11,10 @@ class CnmtProcess { public: CnmtProcess(); - ~CnmtProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -23,8 +23,7 @@ public: private: const std::string kModuleName = "CnmtProcess"; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/EsTikProcess.cpp b/programs/nstool/source/EsTikProcess.cpp index 4832276..b3d1c73 100644 --- a/programs/nstool/source/EsTikProcess.cpp +++ b/programs/nstool/source/EsTikProcess.cpp @@ -9,21 +9,12 @@ EsTikProcess::EsTikProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -EsTikProcess::~EsTikProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void EsTikProcess::process() { importTicket(); @@ -35,10 +26,9 @@ void EsTikProcess::process() displayTicket(); } -void EsTikProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void EsTikProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void EsTikProcess::setKeyCfg(const KeyConfiguration& keycfg) @@ -66,13 +56,13 @@ void EsTikProcess::importTicket() fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - scratch.alloc(mFile->size()); - mFile->read(scratch.data(), 0, scratch.size()); + scratch.alloc((*mFile)->size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mTik.fromBytes(scratch.data(), scratch.size()); } diff --git a/programs/nstool/source/EsTikProcess.h b/programs/nstool/source/EsTikProcess.h index 94f5b05..cf3e36e 100644 --- a/programs/nstool/source/EsTikProcess.h +++ b/programs/nstool/source/EsTikProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -13,11 +14,10 @@ class EsTikProcess { public: EsTikProcess(); - ~EsTikProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setKeyCfg(const KeyConfiguration& keycfg); void setCertificateChain(const fnd::List>& certs); void setCliOutputMode(CliOutputMode mode); @@ -26,8 +26,7 @@ public: private: const std::string kModuleName = "EsTikProcess"; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; KeyConfiguration mKeyCfg; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/HashTreeWrappedIFile.cpp b/programs/nstool/source/HashTreeWrappedIFile.cpp index 7ff7e7c..a69acb2 100644 --- a/programs/nstool/source/HashTreeWrappedIFile.cpp +++ b/programs/nstool/source/HashTreeWrappedIFile.cpp @@ -2,8 +2,7 @@ #include "HashTreeWrappedIFile.h" #include "OffsetAdjustedIFile.h" -HashTreeWrappedIFile::HashTreeWrappedIFile(fnd::IFile* file, bool ownIFile, const HashTreeMeta& hdr) : - mOwnIFile(ownIFile), +HashTreeWrappedIFile::HashTreeWrappedIFile(const fnd::SharedPtr& file, const HashTreeMeta& hdr) : mFile(file), mData(nullptr), mDataHashLayer(), @@ -12,18 +11,9 @@ HashTreeWrappedIFile::HashTreeWrappedIFile(fnd::IFile* file, bool ownIFile, cons initialiseDataLayer(hdr); } -HashTreeWrappedIFile::~HashTreeWrappedIFile() -{ - if (mOwnIFile) - { - delete mFile; - } - delete mData; -} - size_t HashTreeWrappedIFile::size() { - return mData->size(); + return (*mData)->size(); } void HashTreeWrappedIFile::seek(size_t offset) @@ -118,7 +108,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) cur.alloc(align(layer.size, layer.block_size)); // read layer - mFile->read(cur.data(), layer.offset, layer.size); + (*mFile)->read(cur.data(), layer.offset, layer.size); // validate blocks size_t validate_size; @@ -145,7 +135,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) } // generate reader for data layer - mData = new OffsetAdjustedIFile(mFile, SHARED_IFILE, hdr.getDataLayer().offset, hdr.getDataLayer().size); + mData = new OffsetAdjustedIFile(mFile, hdr.getDataLayer().offset, hdr.getDataLayer().size); mDataOffset = 0; mDataBlockSize = hdr.getDataLayer().block_size; @@ -160,17 +150,17 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr) void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num) { - mData->seek(block_offset * mDataBlockSize); + (*mData)->seek(block_offset * mDataBlockSize); fnd::sha::sSha256Hash hash; // determine read size size_t read_len = 0; - if ((block_offset + block_num) == getBlockNum(mData->size())) + if ((block_offset + block_num) == getBlockNum((*mData)->size())) { - read_len = (block_num-1) * mDataBlockSize + getRemanderBlockReadSize(mData->size()); + read_len = (block_num-1) * mDataBlockSize + getRemanderBlockReadSize((*mData)->size()); memset(mCache.data(), 0, block_num * mDataBlockSize); } - else if ((block_offset + block_num) < getBlockNum(mData->size())) + else if ((block_offset + block_num) < getBlockNum((*mData)->size())) { read_len = block_num * mDataBlockSize; } @@ -180,7 +170,7 @@ void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num) } // read - mData->read(mCache.data(), block_offset * mDataBlockSize, read_len); + (*mData)->read(mCache.data(), block_offset * mDataBlockSize, read_len); if (block_num > mCacheBlockNum) { diff --git a/programs/nstool/source/HashTreeWrappedIFile.h b/programs/nstool/source/HashTreeWrappedIFile.h index 6e97181..dd3f70c 100644 --- a/programs/nstool/source/HashTreeWrappedIFile.h +++ b/programs/nstool/source/HashTreeWrappedIFile.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include #include "HashTreeMeta.h" @@ -9,8 +10,7 @@ class HashTreeWrappedIFile : public fnd::IFile { public: - HashTreeWrappedIFile(fnd::IFile* file, bool ownIFile, const HashTreeMeta& hdr); - ~HashTreeWrappedIFile(); + HashTreeWrappedIFile(const fnd::SharedPtr& file, const HashTreeMeta& hdr); size_t size(); void seek(size_t offset); @@ -23,11 +23,10 @@ private: static const size_t kDefaultCacheSize = 0x10000; std::stringstream mErrorSs; - bool mOwnIFile; - fnd::IFile* mFile; + fnd::SharedPtr mFile; // data file - fnd::IFile* mData; + fnd::SharedPtr mData; size_t mDataOffset; size_t mDataBlockSize; fnd::List mDataHashLayer; diff --git a/programs/nstool/source/NacpProcess.cpp b/programs/nstool/source/NacpProcess.cpp index fb6d5bf..2d3b02f 100644 --- a/programs/nstool/source/NacpProcess.cpp +++ b/programs/nstool/source/NacpProcess.cpp @@ -6,21 +6,12 @@ #include "NacpProcess.h" NacpProcess::NacpProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -NacpProcess::~NacpProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void NacpProcess::process() { importNacp(); @@ -29,10 +20,9 @@ void NacpProcess::process() displayNacp(); } -void NacpProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void NacpProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void NacpProcess::setCliOutputMode(CliOutputMode type) @@ -54,13 +44,13 @@ void NacpProcess::importNacp() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - scratch.alloc(mFile->size()); - mFile->read(scratch.data(), 0, scratch.size()); + scratch.alloc((*mFile)->size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mNacp.fromBytes(scratch.data(), scratch.size()); } diff --git a/programs/nstool/source/NacpProcess.h b/programs/nstool/source/NacpProcess.h index 0e6aed3..8a5064c 100644 --- a/programs/nstool/source/NacpProcess.h +++ b/programs/nstool/source/NacpProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "common.h" @@ -10,11 +11,10 @@ class NacpProcess { public: NacpProcess(); - ~NacpProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -23,8 +23,7 @@ public: private: const std::string kModuleName = "NacpProcess"; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/NcaProcess.cpp b/programs/nstool/source/NcaProcess.cpp index f637e17..aa4f504 100644 --- a/programs/nstool/source/NcaProcess.cpp +++ b/programs/nstool/source/NcaProcess.cpp @@ -13,8 +13,7 @@ #include "HashTreeWrappedIFile.h" NcaProcess::NcaProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false), mListFs(false) @@ -22,23 +21,6 @@ NcaProcess::NcaProcess() : for (size_t i = 0; i < nn::hac::nca::kPartitionNum; i++) { mPartitionPath[i].doExtract = false; - mPartitions[i].reader = nullptr; - } -} - -NcaProcess::~NcaProcess() -{ - if (mOwnIFile) - { - delete mFile; - } - - for (size_t i = 0; i < nn::hac::nca::kPartitionNum; i++) - { - if (mPartitions[i].reader != nullptr) - { - delete mPartitions[i].reader; - } } } @@ -65,10 +47,9 @@ void NcaProcess::process() processPartitions(); } -void NcaProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void NcaProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void NcaProcess::setKeyCfg(const KeyConfiguration& keycfg) @@ -117,13 +98,13 @@ void NcaProcess::setListFs(bool list_fs) void NcaProcess::importHeader() { - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } // read header block - mFile->read((byte_t*)&mHdrBlock, 0, sizeof(nn::hac::sNcaHeaderBlock)); + (*mFile)->read((byte_t*)&mHdrBlock, 0, sizeof(nn::hac::sNcaHeaderBlock)); // decrypt header block fnd::aes::sAesXts128Key header_key; @@ -299,13 +280,13 @@ void NcaProcess::generatePartitionConfiguration() // create reader based on encryption type0 if (info.enc_type == nn::hac::nca::CRYPT_NONE) { - info.reader = new OffsetAdjustedIFile(mFile, SHARED_IFILE, info.offset, info.size); + info.reader = new OffsetAdjustedIFile(mFile, info.offset, info.size); } else if (info.enc_type == nn::hac::nca::CRYPT_AESCTR) { if (mContentKey.aes_ctr.isSet == false) throw fnd::Exception(kModuleName, "AES-CTR Key was not determined"); - info.reader = new OffsetAdjustedIFile(new AesCtrWrappedIFile(mFile, SHARED_IFILE, mContentKey.aes_ctr.var, info.aes_ctr), OWN_IFILE, info.offset, info.size); + info.reader = new OffsetAdjustedIFile(new AesCtrWrappedIFile(mFile, mContentKey.aes_ctr.var, info.aes_ctr), info.offset, info.size); } else if (info.enc_type == nn::hac::nca::CRYPT_AESXTS || info.enc_type == nn::hac::nca::CRYPT_AESCTREX) { @@ -323,9 +304,7 @@ void NcaProcess::generatePartitionConfiguration() // filter out unrecognised hash types, and hash based readers if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256 || info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY) { - fnd::IFile* tmp = info.reader; - info.reader = nullptr; - info.reader = new HashTreeWrappedIFile(tmp, OWN_IFILE, info.hash_tree_meta); + info.reader = new HashTreeWrappedIFile(info.reader, info.hash_tree_meta); } else if (info.hash_type != nn::hac::nca::HASH_NONE) { @@ -337,9 +316,6 @@ void NcaProcess::generatePartitionConfiguration() catch (const fnd::Exception& e) { info.fail_reason = std::string(e.error()); - if (info.reader != nullptr) - delete info.reader; - info.reader = nullptr; } } } @@ -359,10 +335,10 @@ void NcaProcess::validateNcaSignatures() { if (mPartitions[nn::hac::nca::PARTITION_CODE].format_type == nn::hac::nca::FORMAT_PFS0) { - if (mPartitions[nn::hac::nca::PARTITION_CODE].reader != nullptr) + if (*mPartitions[nn::hac::nca::PARTITION_CODE].reader != nullptr) { PfsProcess exefs; - exefs.setInputFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, SHARED_IFILE); + exefs.setInputFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader); exefs.setCliOutputMode(0); exefs.process(); @@ -372,7 +348,7 @@ void NcaProcess::validateNcaSignatures() const nn::hac::PfsHeader::sFile& file = exefs.getPfsHeader().getFileList().getElement(kNpdmExefsPath); NpdmProcess npdm; - npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, SHARED_IFILE, file.offset, file.size), OWN_IFILE); + npdm.setInputFile(new OffsetAdjustedIFile(mPartitions[nn::hac::nca::PARTITION_CODE].reader, file.offset, file.size)); npdm.setCliOutputMode(0); npdm.process(); @@ -513,7 +489,7 @@ void NcaProcess::processPartitions() struct sPartitionInfo& partition = mPartitions[index]; // if the reader is null, skip - if (partition.reader == nullptr) + if (*partition.reader == nullptr) { std::cout << "[WARNING] NCA Partition " << std::dec << index << " not readable."; if (partition.fail_reason.empty() == false) @@ -527,7 +503,7 @@ void NcaProcess::processPartitions() if (partition.format_type == nn::hac::nca::FORMAT_PFS0) { PfsProcess pfs; - pfs.setInputFile(partition.reader, SHARED_IFILE); + pfs.setInputFile(partition.reader); pfs.setCliOutputMode(mCliOutputMode); pfs.setListFs(mListFs); if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM) @@ -546,7 +522,7 @@ void NcaProcess::processPartitions() else if (partition.format_type == nn::hac::nca::FORMAT_ROMFS) { RomfsProcess romfs; - romfs.setInputFile(partition.reader, SHARED_IFILE); + romfs.setInputFile(partition.reader); romfs.setCliOutputMode(mCliOutputMode); romfs.setListFs(mListFs); if (mHdr.getContentType() == nn::hac::nca::TYPE_PROGRAM) diff --git a/programs/nstool/source/NcaProcess.h b/programs/nstool/source/NcaProcess.h index f467945..c5b0429 100644 --- a/programs/nstool/source/NcaProcess.h +++ b/programs/nstool/source/NcaProcess.h @@ -1,7 +1,8 @@ #pragma once #include #include -#include +#include +#include #include #include "HashTreeMeta.h" #include "KeyConfiguration.h" @@ -13,12 +14,11 @@ class NcaProcess { public: NcaProcess(); - ~NcaProcess(); void process(); // generic - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setKeyCfg(const KeyConfiguration& keycfg); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -35,8 +35,7 @@ private: const std::string kNpdmExefsPath = "main.npdm"; // user options - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; KeyConfiguration mKeyCfg; CliOutputMode mCliOutputMode; bool mVerify; @@ -92,7 +91,7 @@ private: struct sPartitionInfo { - fnd::IFile* reader; + fnd::SharedPtr reader; std::string fail_reason; size_t offset; size_t size; diff --git a/programs/nstool/source/NpdmProcess.cpp b/programs/nstool/source/NpdmProcess.cpp index 71b9f14..c397b2e 100644 --- a/programs/nstool/source/NpdmProcess.cpp +++ b/programs/nstool/source/NpdmProcess.cpp @@ -3,21 +3,12 @@ #include "NpdmProcess.h" NpdmProcess::NpdmProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -NpdmProcess::~NpdmProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void NpdmProcess::process() { importNpdm(); @@ -50,10 +41,9 @@ void NpdmProcess::process() } } -void NpdmProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void NpdmProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void NpdmProcess::setKeyCfg(const KeyConfiguration& keycfg) @@ -80,13 +70,13 @@ void NpdmProcess::importNpdm() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - scratch.alloc(mFile->size()); - mFile->read(scratch.data(), 0, scratch.size()); + scratch.alloc((*mFile)->size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mNpdm.fromBytes(scratch.data(), scratch.size()); } diff --git a/programs/nstool/source/NpdmProcess.h b/programs/nstool/source/NpdmProcess.h index a203c0e..b4868bd 100644 --- a/programs/nstool/source/NpdmProcess.h +++ b/programs/nstool/source/NpdmProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "KeyConfiguration.h" @@ -11,11 +12,10 @@ class NpdmProcess { public: NpdmProcess(); - ~NpdmProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setKeyCfg(const KeyConfiguration& keycfg); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -25,8 +25,7 @@ public: private: const std::string kModuleName = "NpdmProcess"; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; KeyConfiguration mKeyCfg; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/NroProcess.cpp b/programs/nstool/source/NroProcess.cpp index 577cc95..83c1edb 100644 --- a/programs/nstool/source/NroProcess.cpp +++ b/programs/nstool/source/NroProcess.cpp @@ -8,21 +8,12 @@ #include "NroProcess.h" NroProcess::NroProcess(): - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -NroProcess::~NroProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void NroProcess::process() { importHeader(); @@ -37,10 +28,9 @@ void NroProcess::process() mAssetProc.process(); } -void NroProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void NroProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void NroProcess::setCliOutputMode(CliOutputMode type) @@ -97,27 +87,27 @@ void NroProcess::importHeader() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - if (mFile->size() < sizeof(nn::hac::sNroHeader)) + if ((*mFile)->size() < sizeof(nn::hac::sNroHeader)) { throw fnd::Exception(kModuleName, "Corrupt NRO: file too small"); } scratch.alloc(sizeof(nn::hac::sNroHeader)); - mFile->read(scratch.data(), 0, scratch.size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mHdr.fromBytes(scratch.data(), scratch.size()); // setup homebrew extension nn::hac::sNroHeader* raw_hdr = (nn::hac::sNroHeader*)scratch.data(); - if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nn::hac::nro::kNroHomebrewStructMagic && mFile->size() > mHdr.getNroSize()) + if (((le_uint64_t*)raw_hdr->reserved_0)->get() == nn::hac::nro::kNroHomebrewStructMagic && (*mFile)->size() > mHdr.getNroSize()) { mIsHomebrewNro = true; - mAssetProc.setInputFile(new OffsetAdjustedIFile(mFile, false, mHdr.getNroSize(), mFile->size() - mHdr.getNroSize()), true); + mAssetProc.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getNroSize(), (*mFile)->size() - mHdr.getNroSize())); mAssetProc.setCliOutputMode(mCliOutputMode); mAssetProc.setVerifyMode(mVerify); } @@ -128,11 +118,11 @@ void NroProcess::importHeader() void NroProcess::importCodeSegments() { mTextBlob.alloc(mHdr.getTextInfo().size); - mFile->read(mTextBlob.data(), mHdr.getTextInfo().memory_offset, mTextBlob.size()); + (*mFile)->read(mTextBlob.data(), mHdr.getTextInfo().memory_offset, mTextBlob.size()); mRoBlob.alloc(mHdr.getRoInfo().size); - mFile->read(mRoBlob.data(), mHdr.getRoInfo().memory_offset, mRoBlob.size()); + (*mFile)->read(mRoBlob.data(), mHdr.getRoInfo().memory_offset, mRoBlob.size()); mDataBlob.alloc(mHdr.getDataInfo().size); - mFile->read(mDataBlob.data(), mHdr.getDataInfo().memory_offset, mDataBlob.size()); + (*mFile)->read(mDataBlob.data(), mHdr.getDataInfo().memory_offset, mDataBlob.size()); } void NroProcess::displayHeader() diff --git a/programs/nstool/source/NroProcess.h b/programs/nstool/source/NroProcess.h index 7d27553..4ddd1eb 100644 --- a/programs/nstool/source/NroProcess.h +++ b/programs/nstool/source/NroProcess.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include "AssetProcess.h" @@ -14,11 +15,10 @@ class NroProcess { public: NroProcess(); - ~NroProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -36,9 +36,7 @@ public: private: const std::string kModuleName = "NroProcess"; - fnd::IFile* mFile; - bool mOwnIFile; - + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/NsoProcess.cpp b/programs/nstool/source/NsoProcess.cpp index c99cd78..11261c6 100644 --- a/programs/nstool/source/NsoProcess.cpp +++ b/programs/nstool/source/NsoProcess.cpp @@ -7,21 +7,12 @@ #include "NsoProcess.h" NsoProcess::NsoProcess(): - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -NsoProcess::~NsoProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void NsoProcess::process() { importHeader(); @@ -32,10 +23,9 @@ void NsoProcess::process() processRoMeta(); } -void NsoProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void NsoProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void NsoProcess::setCliOutputMode(CliOutputMode type) @@ -72,18 +62,18 @@ void NsoProcess::importHeader() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - if (mFile->size() < sizeof(nn::hac::sNsoHeader)) + if ((*mFile)->size() < sizeof(nn::hac::sNsoHeader)) { throw fnd::Exception(kModuleName, "Corrupt NSO: file too small"); } scratch.alloc(sizeof(nn::hac::sNsoHeader)); - mFile->read(scratch.data(), 0, scratch.size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mHdr.fromBytes(scratch.data(), scratch.size()); } @@ -98,7 +88,7 @@ void NsoProcess::importCodeSegments() if (mHdr.getTextSegmentInfo().is_compressed) { scratch.alloc(mHdr.getTextSegmentInfo().file_layout.size); - mFile->read(scratch.data(), mHdr.getTextSegmentInfo().file_layout.offset, scratch.size()); + (*mFile)->read(scratch.data(), mHdr.getTextSegmentInfo().file_layout.offset, scratch.size()); mTextBlob.alloc(mHdr.getTextSegmentInfo().memory_layout.size); fnd::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mTextBlob.data(), (uint32_t)mTextBlob.size(), decompressed_len); if (decompressed_len != mTextBlob.size()) @@ -109,7 +99,7 @@ void NsoProcess::importCodeSegments() else { mTextBlob.alloc(mHdr.getTextSegmentInfo().file_layout.size); - mFile->read(mTextBlob.data(), mHdr.getTextSegmentInfo().file_layout.offset, mTextBlob.size()); + (*mFile)->read(mTextBlob.data(), mHdr.getTextSegmentInfo().file_layout.offset, mTextBlob.size()); } if (mHdr.getTextSegmentInfo().is_hashed) { @@ -124,7 +114,7 @@ void NsoProcess::importCodeSegments() if (mHdr.getRoSegmentInfo().is_compressed) { scratch.alloc(mHdr.getRoSegmentInfo().file_layout.size); - mFile->read(scratch.data(), mHdr.getRoSegmentInfo().file_layout.offset, scratch.size()); + (*mFile)->read(scratch.data(), mHdr.getRoSegmentInfo().file_layout.offset, scratch.size()); mRoBlob.alloc(mHdr.getRoSegmentInfo().memory_layout.size); fnd::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mRoBlob.data(), (uint32_t)mRoBlob.size(), decompressed_len); if (decompressed_len != mRoBlob.size()) @@ -135,7 +125,7 @@ void NsoProcess::importCodeSegments() else { mRoBlob.alloc(mHdr.getRoSegmentInfo().file_layout.size); - mFile->read(mRoBlob.data(), mHdr.getRoSegmentInfo().file_layout.offset, mRoBlob.size()); + (*mFile)->read(mRoBlob.data(), mHdr.getRoSegmentInfo().file_layout.offset, mRoBlob.size()); } if (mHdr.getRoSegmentInfo().is_hashed) { @@ -150,7 +140,7 @@ void NsoProcess::importCodeSegments() if (mHdr.getDataSegmentInfo().is_compressed) { scratch.alloc(mHdr.getDataSegmentInfo().file_layout.size); - mFile->read(scratch.data(), mHdr.getDataSegmentInfo().file_layout.offset, scratch.size()); + (*mFile)->read(scratch.data(), mHdr.getDataSegmentInfo().file_layout.offset, scratch.size()); mDataBlob.alloc(mHdr.getDataSegmentInfo().memory_layout.size); fnd::lz4::decompressData(scratch.data(), (uint32_t)scratch.size(), mDataBlob.data(), (uint32_t)mDataBlob.size(), decompressed_len); if (decompressed_len != mDataBlob.size()) @@ -161,7 +151,7 @@ void NsoProcess::importCodeSegments() else { mDataBlob.alloc(mHdr.getDataSegmentInfo().file_layout.size); - mFile->read(mDataBlob.data(), mHdr.getDataSegmentInfo().file_layout.offset, mDataBlob.size()); + (*mFile)->read(mDataBlob.data(), mHdr.getDataSegmentInfo().file_layout.offset, mDataBlob.size()); } if (mHdr.getDataSegmentInfo().is_hashed) { diff --git a/programs/nstool/source/NsoProcess.h b/programs/nstool/source/NsoProcess.h index a74beaf..88170ae 100644 --- a/programs/nstool/source/NsoProcess.h +++ b/programs/nstool/source/NsoProcess.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -13,11 +14,10 @@ class NsoProcess { public: NsoProcess(); - ~NsoProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -29,9 +29,7 @@ public: private: const std::string kModuleName = "NsoProcess"; - fnd::IFile* mFile; - bool mOwnIFile; - + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; nn::hac::npdm::InstructionType mInstructionType; diff --git a/programs/nstool/source/OffsetAdjustedIFile.cpp b/programs/nstool/source/OffsetAdjustedIFile.cpp index ad127f1..4891b39 100644 --- a/programs/nstool/source/OffsetAdjustedIFile.cpp +++ b/programs/nstool/source/OffsetAdjustedIFile.cpp @@ -1,21 +1,11 @@ #include "OffsetAdjustedIFile.h" -OffsetAdjustedIFile::OffsetAdjustedIFile(fnd::IFile* file, bool ownIFile, size_t offset, size_t size) : - mOwnIFile(ownIFile), +OffsetAdjustedIFile::OffsetAdjustedIFile(const fnd::SharedPtr& file, size_t offset, size_t size) : mFile(file), mBaseOffset(offset), mCurrentOffset(0), mSize(size) { - -} - -OffsetAdjustedIFile::~OffsetAdjustedIFile() -{ - if (mOwnIFile) - { - delete mFile; - } } size_t OffsetAdjustedIFile::size() @@ -31,8 +21,8 @@ void OffsetAdjustedIFile::seek(size_t offset) void OffsetAdjustedIFile::read(byte_t* out, size_t len) { // assert proper position in file - mFile->seek(mCurrentOffset + mBaseOffset); - mFile->read(out, len); + (*mFile)->seek(mCurrentOffset + mBaseOffset); + (*mFile)->read(out, len); seek(mCurrentOffset + len); } @@ -45,8 +35,8 @@ void OffsetAdjustedIFile::read(byte_t* out, size_t offset, size_t len) void OffsetAdjustedIFile::write(const byte_t* out, size_t len) { // assert proper position in file - mFile->seek(mCurrentOffset + mBaseOffset); - mFile->write(out, len); + (*mFile)->seek(mCurrentOffset + mBaseOffset); + (*mFile)->write(out, len); seek(mCurrentOffset + len); } diff --git a/programs/nstool/source/OffsetAdjustedIFile.h b/programs/nstool/source/OffsetAdjustedIFile.h index 4c68558..be3f582 100644 --- a/programs/nstool/source/OffsetAdjustedIFile.h +++ b/programs/nstool/source/OffsetAdjustedIFile.h @@ -1,10 +1,10 @@ #include +#include class OffsetAdjustedIFile : public fnd::IFile { public: - OffsetAdjustedIFile(fnd::IFile* file, bool ownIFile, size_t offset, size_t size); - ~OffsetAdjustedIFile(); + OffsetAdjustedIFile(const fnd::SharedPtr& file, size_t offset, size_t size); size_t size(); void seek(size_t offset); @@ -13,8 +13,7 @@ public: void write(const byte_t* out, size_t len); void write(const byte_t* out, size_t offset, size_t len); private: - bool mOwnIFile; - fnd::IFile* mFile; + fnd::SharedPtr mFile; size_t mBaseOffset, mCurrentOffset; size_t mSize; }; \ No newline at end of file diff --git a/programs/nstool/source/PfsProcess.cpp b/programs/nstool/source/PfsProcess.cpp index f878a4f..999b487 100644 --- a/programs/nstool/source/PfsProcess.cpp +++ b/programs/nstool/source/PfsProcess.cpp @@ -5,8 +5,7 @@ #include "PfsProcess.h" PfsProcess::PfsProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false), mExtractPath(), @@ -17,14 +16,6 @@ PfsProcess::PfsProcess() : { } -PfsProcess::~PfsProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void PfsProcess::process() { importHeader(); @@ -41,10 +32,9 @@ void PfsProcess::process() extractFs(); } -void PfsProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void PfsProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void PfsProcess::setCliOutputMode(CliOutputMode type) @@ -82,14 +72,14 @@ void PfsProcess::importHeader() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } // open minimum header to get full header size scratch.alloc(sizeof(nn::hac::sPfsHeader)); - mFile->read(scratch.data(), 0, scratch.size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); if (validateHeaderMagic(((nn::hac::sPfsHeader*)scratch.data())) == false) { throw fnd::Exception(kModuleName, "Corrupt Header"); @@ -98,7 +88,7 @@ void PfsProcess::importHeader() // open minimum header to get full header size scratch.alloc(pfsHeaderSize); - mFile->read(scratch.data(), 0, scratch.size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); mPfs.fromBytes(scratch.data(), scratch.size()); } @@ -162,7 +152,7 @@ void PfsProcess::validateHfs() for (size_t i = 0; i < file.size(); i++) { mCache.alloc(file[i].hash_protected_size); - mFile->read(mCache.data(), file[i].offset, file[i].hash_protected_size); + (*mFile)->read(mCache.data(), file[i].offset, file[i].hash_protected_size); fnd::sha::Sha256(mCache.data(), file[i].hash_protected_size, hash.bytes); if (hash != file[i].hash) { @@ -193,10 +183,10 @@ void PfsProcess::extractFs() printf("extract=[%s]\n", file_path.c_str()); outFile.open(file_path, outFile.Create); - mFile->seek(file[i].offset); + (*mFile)->seek(file[i].offset); for (size_t j = 0; j < ((file[i].size / kCacheSize) + ((file[i].size % kCacheSize) != 0)); j++) { - mFile->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize)); + (*mFile)->read(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize)); outFile.write(mCache.data(), _MIN(file[i].size - (kCacheSize * j),kCacheSize)); } outFile.close(); diff --git a/programs/nstool/source/PfsProcess.h b/programs/nstool/source/PfsProcess.h index 562dd21..bf9d61c 100644 --- a/programs/nstool/source/PfsProcess.h +++ b/programs/nstool/source/PfsProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "common.h" @@ -10,12 +11,11 @@ class PfsProcess { public: PfsProcess(); - ~PfsProcess(); void process(); // generic - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -30,8 +30,7 @@ private: const std::string kModuleName = "PfsProcess"; static const size_t kCacheSize = 0x10000; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/PkiCertProcess.cpp b/programs/nstool/source/PkiCertProcess.cpp index f9912a3..b3610f0 100644 --- a/programs/nstool/source/PkiCertProcess.cpp +++ b/programs/nstool/source/PkiCertProcess.cpp @@ -7,21 +7,12 @@ #include "PkiValidator.h" PkiCertProcess::PkiCertProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false) { } -PkiCertProcess::~PkiCertProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void PkiCertProcess::process() { importCerts(); @@ -33,10 +24,9 @@ void PkiCertProcess::process() displayCerts(); } -void PkiCertProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void PkiCertProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void PkiCertProcess::setKeyCfg(const KeyConfiguration& keycfg) @@ -58,13 +48,13 @@ void PkiCertProcess::importCerts() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } - scratch.alloc(mFile->size()); - mFile->read(scratch.data(), 0, scratch.size()); + scratch.alloc((*mFile)->size()); + (*mFile)->read(scratch.data(), 0, scratch.size()); nn::pki::SignedData cert; for (size_t f_pos = 0; f_pos < scratch.size(); f_pos += cert.getBytes().size()) diff --git a/programs/nstool/source/PkiCertProcess.h b/programs/nstool/source/PkiCertProcess.h index c281ae7..88ed54d 100644 --- a/programs/nstool/source/PkiCertProcess.h +++ b/programs/nstool/source/PkiCertProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -13,11 +14,10 @@ class PkiCertProcess { public: PkiCertProcess(); - ~PkiCertProcess(); void process(); - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setKeyCfg(const KeyConfiguration& keycfg); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -26,8 +26,7 @@ private: const std::string kModuleName = "PkiCertProcess"; static const size_t kSmallHexDumpLen = 0x10; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; KeyConfiguration mKeyCfg; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/RomfsProcess.cpp b/programs/nstool/source/RomfsProcess.cpp index cf68257..aba23fe 100644 --- a/programs/nstool/source/RomfsProcess.cpp +++ b/programs/nstool/source/RomfsProcess.cpp @@ -6,8 +6,7 @@ #include "RomfsProcess.h" RomfsProcess::RomfsProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false), mExtractPath(), @@ -22,14 +21,6 @@ RomfsProcess::RomfsProcess() : mRootDir.file_list.clear(); } -RomfsProcess::~RomfsProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void RomfsProcess::process() { resolveRomfs(); @@ -45,10 +36,9 @@ void RomfsProcess::process() extractFs(); } -void RomfsProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void RomfsProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void RomfsProcess::setCliOutputMode(CliOutputMode type) @@ -163,10 +153,10 @@ void RomfsProcess::extractDir(const std::string& path, const sDirectory& dir) std::cout << "extract=[" << file_path << "]" << std::endl; outFile.open(file_path, outFile.Create); - mFile->seek(dir.file_list[i].offset); + (*mFile)->seek(dir.file_list[i].offset); for (size_t j = 0; j < ((dir.file_list[i].size / kCacheSize) + ((dir.file_list[i].size % kCacheSize) != 0)); j++) { - mFile->read(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize)); + (*mFile)->read(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize)); outFile.write(mCache.data(), _MIN(dir.file_list[i].size - (kCacheSize * j),kCacheSize)); } outFile.close(); @@ -258,13 +248,13 @@ void RomfsProcess::importDirectory(uint32_t dir_offset, sDirectory& dir) void RomfsProcess::resolveRomfs() { - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } // read header - mFile->read((byte_t*)&mHdr, 0, sizeof(nn::hac::sRomfsHeader)); + (*mFile)->read((byte_t*)&mHdr, 0, sizeof(nn::hac::sRomfsHeader)); // logic check on the header layout if (validateHeaderLayout(&mHdr) == false) @@ -274,13 +264,13 @@ void RomfsProcess::resolveRomfs() // read directory nodes mDirNodes.alloc(mHdr.sections[nn::hac::romfs::DIR_NODE_TABLE].size.get()); - mFile->read(mDirNodes.data(), mHdr.sections[nn::hac::romfs::DIR_NODE_TABLE].offset.get(), mDirNodes.size()); + (*mFile)->read(mDirNodes.data(), mHdr.sections[nn::hac::romfs::DIR_NODE_TABLE].offset.get(), mDirNodes.size()); //printf("[RAW DIR NODES]\n"); //fnd::SimpleTextOutput::hxdStyleDump(mDirNodes.data(), mDirNodes.size()); // read file nodes mFileNodes.alloc(mHdr.sections[nn::hac::romfs::FILE_NODE_TABLE].size.get()); - mFile->read(mFileNodes.data(), mHdr.sections[nn::hac::romfs::FILE_NODE_TABLE].offset.get(), mFileNodes.size()); + (*mFile)->read(mFileNodes.data(), mHdr.sections[nn::hac::romfs::FILE_NODE_TABLE].offset.get(), mFileNodes.size()); //printf("[RAW FILE NODES]\n"); //fnd::SimpleTextOutput::hxdStyleDump(mFileNodes.data(), mFileNodes.size()); diff --git a/programs/nstool/source/RomfsProcess.h b/programs/nstool/source/RomfsProcess.h index 7132bba..9edb32c 100644 --- a/programs/nstool/source/RomfsProcess.h +++ b/programs/nstool/source/RomfsProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -77,12 +78,11 @@ public: }; RomfsProcess(); - ~RomfsProcess(); void process(); // generic - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -96,8 +96,7 @@ private: const std::string kModuleName = "RomfsProcess"; static const size_t kCacheSize = 0x10000; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/XciProcess.cpp b/programs/nstool/source/XciProcess.cpp index b68b32b..7fed532 100644 --- a/programs/nstool/source/XciProcess.cpp +++ b/programs/nstool/source/XciProcess.cpp @@ -6,8 +6,7 @@ #include "XciProcess.h" XciProcess::XciProcess() : - mFile(nullptr), - mOwnIFile(false), + mFile(), mCliOutputMode(_BIT(OUTPUT_BASIC)), mVerify(false), mListFs(false), @@ -16,14 +15,6 @@ XciProcess::XciProcess() : { } -XciProcess::~XciProcess() -{ - if (mOwnIFile) - { - delete mFile; - } -} - void XciProcess::process() { importHeader(); @@ -43,10 +34,9 @@ void XciProcess::process() processPartitionPfs(); } -void XciProcess::setInputFile(fnd::IFile* file, bool ownIFile) +void XciProcess::setInputFile(const fnd::SharedPtr& file) { mFile = file; - mOwnIFile = ownIFile; } void XciProcess::setKeyCfg(const KeyConfiguration& keycfg) @@ -78,13 +68,13 @@ void XciProcess::importHeader() { fnd::Vec scratch; - if (mFile == nullptr) + if (*mFile == nullptr) { throw fnd::Exception(kModuleName, "No file reader set."); } // read header page - mFile->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sXciHeaderPage)); + (*mFile)->read((byte_t*)&mHdrPage, 0, sizeof(nn::hac::sXciHeaderPage)); // allocate memory for and decrypt sXciHeader scratch.alloc(sizeof(nn::hac::sXciHeader)); @@ -193,7 +183,7 @@ bool XciProcess::validateRegionOfFile(size_t offset, size_t len, const byte_t* t fnd::Vec scratch; fnd::sha::sSha256Hash calc_hash; scratch.alloc(len); - mFile->read(scratch.data(), offset, scratch.size()); + (*mFile)->read(scratch.data(), offset, scratch.size()); fnd::sha::Sha256(scratch.data(), scratch.size(), calc_hash.bytes); return calc_hash.compare(test_hash); } @@ -216,7 +206,7 @@ void XciProcess::processRootPfs() { std::cout << "[WARNING] XCI Root HFS0: FAIL (bad hash)" << std::endl; } - mRootPfs.setInputFile(new OffsetAdjustedIFile(mFile, SHARED_IFILE, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize()), OWN_IFILE); + mRootPfs.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress(), mHdr.getPartitionFsSize())); mRootPfs.setListFs(mListFs); mRootPfs.setVerifyMode(false); mRootPfs.setCliOutputMode(mCliOutputMode); @@ -236,7 +226,7 @@ void XciProcess::processPartitionPfs() } PfsProcess tmp; - tmp.setInputFile(new OffsetAdjustedIFile(mFile, SHARED_IFILE, mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].size), OWN_IFILE); + tmp.setInputFile(new OffsetAdjustedIFile(mFile, mHdr.getPartitionFsAddress() + rootPartitions[i].offset, rootPartitions[i].size)); tmp.setListFs(mListFs); tmp.setVerifyMode(mVerify); tmp.setCliOutputMode(mCliOutputMode); diff --git a/programs/nstool/source/XciProcess.h b/programs/nstool/source/XciProcess.h index bb9009c..6e034e7 100644 --- a/programs/nstool/source/XciProcess.h +++ b/programs/nstool/source/XciProcess.h @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "KeyConfiguration.h" @@ -13,12 +14,11 @@ class XciProcess { public: XciProcess(); - ~XciProcess(); void process(); // generic - void setInputFile(fnd::IFile* file, bool ownIFile); + void setInputFile(const fnd::SharedPtr& file); void setKeyCfg(const KeyConfiguration& keycfg); void setCliOutputMode(CliOutputMode type); void setVerifyMode(bool verify); @@ -31,8 +31,7 @@ private: const std::string kModuleName = "XciProcess"; const std::string kXciMountPointName = "gamecard:/"; - fnd::IFile* mFile; - bool mOwnIFile; + fnd::SharedPtr mFile; KeyConfiguration mKeyCfg; CliOutputMode mCliOutputMode; bool mVerify; diff --git a/programs/nstool/source/main.cpp b/programs/nstool/source/main.cpp index 9659241..0e087c0 100644 --- a/programs/nstool/source/main.cpp +++ b/programs/nstool/source/main.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "UserSettings.h" #include "XciProcess.h" @@ -35,11 +36,13 @@ int main(int argc, char** argv) try { user_set.parseCmdArgs(args); + fnd::SharedPtr inputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read)); + if (user_set.getFileType() == FILE_XCI) { XciProcess xci; - xci.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + xci.setInputFile(inputFile); xci.setKeyCfg(user_set.getKeyCfg()); xci.setCliOutputMode(user_set.getCliOutputMode()); @@ -61,7 +64,7 @@ int main(int argc, char** argv) { PfsProcess pfs; - pfs.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + pfs.setInputFile(inputFile); pfs.setCliOutputMode(user_set.getCliOutputMode()); pfs.setVerifyMode(user_set.isVerifyFile()); @@ -75,7 +78,7 @@ int main(int argc, char** argv) { RomfsProcess romfs; - romfs.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + romfs.setInputFile(inputFile); romfs.setCliOutputMode(user_set.getCliOutputMode()); romfs.setVerifyMode(user_set.isVerifyFile()); @@ -89,7 +92,7 @@ int main(int argc, char** argv) { NcaProcess nca; - nca.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + nca.setInputFile(inputFile); nca.setKeyCfg(user_set.getKeyCfg()); nca.setCliOutputMode(user_set.getCliOutputMode()); nca.setVerifyMode(user_set.isVerifyFile()); @@ -111,7 +114,7 @@ int main(int argc, char** argv) { NpdmProcess npdm; - npdm.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + npdm.setInputFile(inputFile); npdm.setKeyCfg(user_set.getKeyCfg()); npdm.setCliOutputMode(user_set.getCliOutputMode()); npdm.setVerifyMode(user_set.isVerifyFile()); @@ -122,7 +125,7 @@ int main(int argc, char** argv) { CnmtProcess cnmt; - cnmt.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + cnmt.setInputFile(inputFile); cnmt.setCliOutputMode(user_set.getCliOutputMode()); cnmt.setVerifyMode(user_set.isVerifyFile()); @@ -132,7 +135,7 @@ int main(int argc, char** argv) { NsoProcess obj; - obj.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + obj.setInputFile(inputFile); obj.setCliOutputMode(user_set.getCliOutputMode()); obj.setVerifyMode(user_set.isVerifyFile()); @@ -146,7 +149,7 @@ int main(int argc, char** argv) { NroProcess obj; - obj.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + obj.setInputFile(inputFile); obj.setCliOutputMode(user_set.getCliOutputMode()); obj.setVerifyMode(user_set.isVerifyFile()); @@ -169,7 +172,7 @@ int main(int argc, char** argv) { NacpProcess nacp; - nacp.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + nacp.setInputFile(inputFile); nacp.setCliOutputMode(user_set.getCliOutputMode()); nacp.setVerifyMode(user_set.isVerifyFile()); @@ -179,7 +182,7 @@ int main(int argc, char** argv) { PkiCertProcess cert; - cert.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + cert.setInputFile(inputFile); cert.setKeyCfg(user_set.getKeyCfg()); cert.setCliOutputMode(user_set.getCliOutputMode()); cert.setVerifyMode(user_set.isVerifyFile()); @@ -190,7 +193,7 @@ int main(int argc, char** argv) { EsTikProcess tik; - tik.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + tik.setInputFile(inputFile); tik.setKeyCfg(user_set.getKeyCfg()); tik.setCertificateChain(user_set.getCertificateChain()); tik.setCliOutputMode(user_set.getCliOutputMode()); @@ -202,7 +205,7 @@ int main(int argc, char** argv) { AssetProcess obj; - obj.setInputFile(new fnd::SimpleFile(user_set.getInputPath(), fnd::SimpleFile::Read), OWN_IFILE); + obj.setInputFile(inputFile); obj.setCliOutputMode(user_set.getCliOutputMode()); obj.setVerifyMode(user_set.isVerifyFile());