mirror of
https://github.com/jakcron/nstool
synced 2024-11-15 02:06:40 +00:00
Migrate to new extract system (incomplete) + submodule update.
This commit is contained in:
parent
71452fcf50
commit
162452655b
23 changed files with 367 additions and 79 deletions
2
deps/libfmt
vendored
2
deps/libfmt
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 53d084cc0c6ea61bbb535a873299b0ae5ff9a05d
|
Subproject commit ae6df0aead2fdaae8a0b117524a6eb036c8fa075
|
2
deps/libnintendo-hac
vendored
2
deps/libnintendo-hac
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit e93b71a2d2cebf060df00891fd8268f14288af63
|
Subproject commit 64adf7e5ee46355270e370231ea933ed82509915
|
2
deps/libtoolchain
vendored
2
deps/libtoolchain
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit d7b48027a93ef69b9c6b0d78fe392abc0bce5e68
|
Subproject commit ec4144330589b96c53adc10dac36f654821327a0
|
|
@ -48,6 +48,11 @@ void nstool::AssetProcess::setRomfsShowFsTree(bool show_fs_tree)
|
||||||
mRomfs.setShowFsTree(show_fs_tree);
|
mRomfs.setShowFsTree(show_fs_tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nstool::AssetProcess::setRomfsArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs)
|
||||||
|
{
|
||||||
|
mRomfs.setArchiveJobs(jobs);
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::AssetProcess::setRomfsExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs)
|
void nstool::AssetProcess::setRomfsExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs)
|
||||||
{
|
{
|
||||||
mRomfs.setExtractJobs(extract_jobs);
|
mRomfs.setExtractJobs(extract_jobs);
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
void setIconExtractPath(const tc::io::Path& path);
|
void setIconExtractPath(const tc::io::Path& path);
|
||||||
void setNacpExtractPath(const tc::io::Path& path);
|
void setNacpExtractPath(const tc::io::Path& path);
|
||||||
|
|
||||||
|
void setRomfsArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs);
|
||||||
void setRomfsShowFsTree(bool show_fs_tree);
|
void setRomfsShowFsTree(bool show_fs_tree);
|
||||||
void setRomfsExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
void setRomfsExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -14,6 +14,7 @@ nstool::FsProcess::FsProcess() :
|
||||||
mShowFsTree(false),
|
mShowFsTree(false),
|
||||||
mFsRootLabel(),
|
mFsRootLabel(),
|
||||||
mExtractJobs(),
|
mExtractJobs(),
|
||||||
|
mArchiveJobs(),
|
||||||
mDataCache(0x10000)
|
mDataCache(0x10000)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -26,6 +27,8 @@ void nstool::FsProcess::process()
|
||||||
throw tc::InvalidOperationException(mModuleLabel, "No input filesystem");
|
throw tc::InvalidOperationException(mModuleLabel, "No input filesystem");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processArchiveJobs();
|
||||||
|
|
||||||
if (mShowFsInfo)
|
if (mShowFsInfo)
|
||||||
{
|
{
|
||||||
fmt::print("[{:s}]\n", mFsFormatName.isSet() ? mFsFormatName.get() : "FileSystem/Info");
|
fmt::print("[{:s}]\n", mFsFormatName.isSet() ? mFsFormatName.get() : "FileSystem/Info");
|
||||||
|
@ -81,6 +84,115 @@ void nstool::FsProcess::setExtractJobs(const std::vector<nstool::ExtractJob>& ex
|
||||||
mExtractJobs = extract_jobs;
|
mExtractJobs = extract_jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nstool::FsProcess::setArchiveJobs(const std::vector<nstool::ArchiveJob>& archive_jobs)
|
||||||
|
{
|
||||||
|
mArchiveJobs = archive_jobs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::FsProcess::processArchiveJobs()
|
||||||
|
{
|
||||||
|
for (auto itr = mArchiveJobs.begin(); itr != mArchiveJobs.end(); itr++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
std::string archive_path_str, extract_base_path_str;
|
||||||
|
tc::io::PathUtil::pathToUnixUTF8(itr->archive_path, archive_path_str);
|
||||||
|
tc::io::PathUtil::pathToUnixUTF8(itr->extract_base_path, extract_base_path_str);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Qualify Archive Path
|
||||||
|
tc::io::Path qualified_archive_path;
|
||||||
|
bool is_dir = false, is_file = false;
|
||||||
|
if (!qualifyArchivePath(itr->archive_path, qualified_archive_path, is_dir, is_file))
|
||||||
|
{
|
||||||
|
std::string archive_path_str;
|
||||||
|
tc::io::PathUtil::pathToUnixUTF8(itr->archive_path, archive_path_str);
|
||||||
|
fmt::print("Path \"{}\" did not exist for this archive.\n", archive_path_str);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print
|
||||||
|
{
|
||||||
|
std::string qualified_archive_path_str;
|
||||||
|
tc::io::PathUtil::pathToUnixUTF8(qualified_archive_path, qualified_archive_path_str);
|
||||||
|
fmt::print("Path \"{}\" was valid, is_dir={}, is_file={}.\n", qualified_archive_path_str, is_dir, is_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (itr->job_action == ArchiveJob::JobAction::DoNothing)
|
||||||
|
{
|
||||||
|
fmt::print("DoNothing\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (itr->job_action == ArchiveJob::JobAction::ListFileTree)
|
||||||
|
{
|
||||||
|
fmt::print("ListFileTree\n");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (itr->job_action == ArchiveJob::JobAction::Extract)
|
||||||
|
{
|
||||||
|
fmt::print("Extract\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fmt::print("Unsupported ArchiveJob::JobAction\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nstool::FsProcess::qualifyArchivePath(const tc::io::Path& path, tc::io::Path& qualified_path, bool& is_dir, bool& is_file)
|
||||||
|
{
|
||||||
|
// test if the path is for a directory
|
||||||
|
try {
|
||||||
|
tc::io::sDirectoryListing dir_listing;
|
||||||
|
|
||||||
|
// getDirectoryListing will throw if this is not a directory
|
||||||
|
mInputFs->getDirectoryListing(path, dir_listing);
|
||||||
|
|
||||||
|
// set state and return
|
||||||
|
qualified_path = dir_listing.abs_path;
|
||||||
|
is_dir = true;
|
||||||
|
is_file = false;
|
||||||
|
return true;
|
||||||
|
} catch (tc::io::DirectoryNotFoundException&) {
|
||||||
|
// acceptable exception, just means directory didn't exist
|
||||||
|
}
|
||||||
|
|
||||||
|
// test if the path is for a file
|
||||||
|
try {
|
||||||
|
// opening the file will throw if the file doesn't exist
|
||||||
|
std::shared_ptr<tc::io::IStream> file_stream;
|
||||||
|
mInputFs->openFile(path, tc::io::FileMode::Open, tc::io::FileAccess::Read, file_stream);
|
||||||
|
|
||||||
|
// breakup the path into the parent directory path and file name
|
||||||
|
tc::io::Path parent_dir_path = path;
|
||||||
|
parent_dir_path.pop_back(); // remove the last element, which should be the file name (which should exist because opening the file worked)
|
||||||
|
|
||||||
|
std::string file_name = path.back();
|
||||||
|
|
||||||
|
// get the qualified file path
|
||||||
|
tc::io::sDirectoryListing dir_listing;
|
||||||
|
|
||||||
|
// getDirectoryListing will throw if this is not a directory
|
||||||
|
mInputFs->getDirectoryListing(parent_dir_path, dir_listing);
|
||||||
|
|
||||||
|
// set state
|
||||||
|
qualified_path = dir_listing.abs_path + file_name;
|
||||||
|
is_dir = false;
|
||||||
|
is_file = true;
|
||||||
|
return true;
|
||||||
|
} catch (tc::io::FileNotFoundException&) {
|
||||||
|
// acceptable exception, just means file didn't exist
|
||||||
|
}
|
||||||
|
|
||||||
|
qualified_path = tc::io::Path();
|
||||||
|
is_dir = false;
|
||||||
|
is_file = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::FsProcess::printFs()
|
void nstool::FsProcess::printFs()
|
||||||
{
|
{
|
||||||
fmt::print("[{:s}/Tree]\n", (mFsFormatName.isSet() ? mFsFormatName.get() : "FileSystem"));
|
fmt::print("[{:s}/Tree]\n", (mFsFormatName.isSet() ? mFsFormatName.get() : "FileSystem"));
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
void setShowFsTree(bool show_fs_tree);
|
void setShowFsTree(bool show_fs_tree);
|
||||||
void setFsRootLabel(const std::string& root_label);
|
void setFsRootLabel(const std::string& root_label);
|
||||||
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
||||||
|
void setArchiveJobs(const std::vector<nstool::ArchiveJob>& archive_jobs);
|
||||||
private:
|
private:
|
||||||
std::string mModuleLabel;
|
std::string mModuleLabel;
|
||||||
|
|
||||||
|
@ -37,10 +38,15 @@ private:
|
||||||
|
|
||||||
// extract jobs
|
// extract jobs
|
||||||
std::vector<nstool::ExtractJob> mExtractJobs;
|
std::vector<nstool::ExtractJob> mExtractJobs;
|
||||||
|
std::vector<nstool::ArchiveJob> mArchiveJobs;
|
||||||
|
|
||||||
// cache for file extract
|
// cache for file extract
|
||||||
tc::ByteData mDataCache;
|
tc::ByteData mDataCache;
|
||||||
|
|
||||||
|
void processArchiveJobs();
|
||||||
|
|
||||||
|
bool qualifyArchivePath(const tc::io::Path& path, tc::io::Path& qualified_path, bool& is_dir, bool& is_file);
|
||||||
|
|
||||||
void printFs();
|
void printFs();
|
||||||
void extractFs();
|
void extractFs();
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,12 @@ nstool::GameCardProcess::GameCardProcess() :
|
||||||
mFile(),
|
mFile(),
|
||||||
mCliOutputMode(true, false, false, false),
|
mCliOutputMode(true, false, false, false),
|
||||||
mVerify(false),
|
mVerify(false),
|
||||||
mListFs(false),
|
mIsTrueSdkXci(false),
|
||||||
|
mIsSdkXciEncrypted(false),
|
||||||
|
mGcHeaderOffset(0),
|
||||||
mProccessExtendedHeader(false),
|
mProccessExtendedHeader(false),
|
||||||
mRootPfs(),
|
mFileSystem(),
|
||||||
mExtractJobs()
|
mFsProcess()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +61,19 @@ void nstool::GameCardProcess::setVerifyMode(bool verify)
|
||||||
mVerify = verify;
|
mVerify = verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::GameCardProcess::setExtractJobs(const std::vector<nstool::ExtractJob> extract_jobs)
|
void nstool::GameCardProcess::setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs)
|
||||||
{
|
{
|
||||||
mExtractJobs = extract_jobs;
|
mFsProcess.setArchiveJobs(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::GameCardProcess::setShowFsTree(bool show_fs_tree)
|
void nstool::GameCardProcess::setShowFsTree(bool show_fs_tree)
|
||||||
{
|
{
|
||||||
mListFs = show_fs_tree;
|
mFsProcess.setShowFsTree(show_fs_tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::GameCardProcess::setExtractJobs(const std::vector<nstool::ExtractJob> extract_jobs)
|
||||||
|
{
|
||||||
|
mFsProcess.setExtractJobs(extract_jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::GameCardProcess::importHeader()
|
void nstool::GameCardProcess::importHeader()
|
||||||
|
@ -266,21 +273,16 @@ void nstool::GameCardProcess::processRootPfs()
|
||||||
std::shared_ptr<tc::io::IStream> gc_fs_raw = std::make_shared<tc::io::SubStream>(tc::io::SubStream(mFile, mHdr.getPartitionFsAddress(), nn::hac::GameCardUtil::blockToAddr(mHdr.getValidDataEndPage()+1) - mHdr.getPartitionFsAddress()));
|
std::shared_ptr<tc::io::IStream> gc_fs_raw = std::make_shared<tc::io::SubStream>(tc::io::SubStream(mFile, mHdr.getPartitionFsAddress(), nn::hac::GameCardUtil::blockToAddr(mHdr.getValidDataEndPage()+1) - mHdr.getPartitionFsAddress()));
|
||||||
|
|
||||||
auto gc_vfs_meta = nn::hac::GameCardFsMetaGenerator(gc_fs_raw, mHdr.getPartitionFsSize(), mVerify ? nn::hac::GameCardFsMetaGenerator::ValidationMode_Warn : nn::hac::GameCardFsMetaGenerator::ValidationMode_None);
|
auto gc_vfs_meta = nn::hac::GameCardFsMetaGenerator(gc_fs_raw, mHdr.getPartitionFsSize(), mVerify ? nn::hac::GameCardFsMetaGenerator::ValidationMode_Warn : nn::hac::GameCardFsMetaGenerator::ValidationMode_None);
|
||||||
std::shared_ptr<tc::io::IStorage> gc_vfs = std::make_shared<tc::io::VirtualFileSystem>(tc::io::VirtualFileSystem(gc_vfs_meta) );
|
mFileSystem = std::make_shared<tc::io::VirtualFileSystem>(tc::io::VirtualFileSystem(gc_vfs_meta) );
|
||||||
|
|
||||||
FsProcess fs_proc;
|
mFsProcess.setInputFileSystem(mFileSystem);
|
||||||
|
mFsProcess.setFsFormatName("PartitionFs");
|
||||||
fs_proc.setInputFileSystem(gc_vfs);
|
mFsProcess.setFsProperties({
|
||||||
fs_proc.setFsFormatName("PartitionFs");
|
|
||||||
fs_proc.setFsProperties({
|
|
||||||
fmt::format("Type: Nested HFS0"),
|
fmt::format("Type: Nested HFS0"),
|
||||||
fmt::format("DirNum: {:d}", gc_vfs_meta.dir_entries.empty() ? 0 : gc_vfs_meta.dir_entries.size() - 1), // -1 to not include root directory
|
fmt::format("DirNum: {:d}", gc_vfs_meta.dir_entries.empty() ? 0 : gc_vfs_meta.dir_entries.size() - 1), // -1 to not include root directory
|
||||||
fmt::format("FileNum: {:d}", gc_vfs_meta.file_entries.size())
|
fmt::format("FileNum: {:d}", gc_vfs_meta.file_entries.size())
|
||||||
});
|
});
|
||||||
fs_proc.setShowFsInfo(mCliOutputMode.show_basic_info);
|
mFsProcess.setShowFsInfo(mCliOutputMode.show_basic_info);
|
||||||
fs_proc.setShowFsTree(mListFs);
|
mFsProcess.setFsRootLabel(kXciMountPointName);
|
||||||
fs_proc.setFsRootLabel(kXciMountPointName);
|
mFsProcess.process();
|
||||||
fs_proc.setExtractJobs(mExtractJobs);
|
|
||||||
|
|
||||||
fs_proc.process();
|
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@ public:
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
// fs specific
|
// fs specific
|
||||||
|
void setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs);
|
||||||
void setShowFsTree(bool show_fs_tree);
|
void setShowFsTree(bool show_fs_tree);
|
||||||
void setExtractJobs(const std::vector<nstool::ExtractJob> extract_jobs);
|
void setExtractJobs(const std::vector<nstool::ExtractJob> extract_jobs);
|
||||||
private:
|
private:
|
||||||
|
@ -32,7 +33,6 @@ private:
|
||||||
KeyBag mKeyCfg;
|
KeyBag mKeyCfg;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
bool mListFs;
|
|
||||||
|
|
||||||
bool mIsTrueSdkXci;
|
bool mIsTrueSdkXci;
|
||||||
bool mIsSdkXciEncrypted;
|
bool mIsSdkXciEncrypted;
|
||||||
|
@ -42,8 +42,9 @@ private:
|
||||||
nn::hac::detail::sha256_hash_t mHdrHash;
|
nn::hac::detail::sha256_hash_t mHdrHash;
|
||||||
nn::hac::GameCardHeader mHdr;
|
nn::hac::GameCardHeader mHdr;
|
||||||
|
|
||||||
PfsProcess mRootPfs;
|
// fs processing
|
||||||
std::vector<nstool::ExtractJob> mExtractJobs;
|
std::shared_ptr<tc::io::IStorage> mFileSystem;
|
||||||
|
FsProcess mFsProcess;
|
||||||
|
|
||||||
void importHeader();
|
void importHeader();
|
||||||
void displayHeader();
|
void displayHeader();
|
||||||
|
|
|
@ -243,7 +243,7 @@ void nstool::KipProcess::displayKernelCap(const nn::hac::KernelCapabilityControl
|
||||||
}
|
}
|
||||||
if (kern.getMiscParams().isSet())
|
if (kern.getMiscParams().isSet())
|
||||||
{
|
{
|
||||||
fmt::print(" ProgramType: {:s} ({:d})\n", nn::hac::KernelCapabilityUtil::getProgramTypeAsString(kern.getMiscParams().getProgramType()), kern.getMiscParams().getProgramType());
|
fmt::print(" ProgramType: {:s} ({:d})\n", nn::hac::KernelCapabilityUtil::getProgramTypeAsString(kern.getMiscParams().getProgramType()), (uint32_t)kern.getMiscParams().getProgramType());
|
||||||
}
|
}
|
||||||
if (kern.getKernelVersion().isSet())
|
if (kern.getKernelVersion().isSet())
|
||||||
{
|
{
|
||||||
|
|
|
@ -169,7 +169,7 @@ void nstool::MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo&
|
||||||
if (rightFound == false)
|
if (rightFound == false)
|
||||||
{
|
{
|
||||||
|
|
||||||
fmt::print("[WARNING] ACI/FAC SaveDataOwnerId: FAIL (0x{:016x} ({:d}) not permitted)\n", aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i].id, aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i].access_type);
|
fmt::print("[WARNING] ACI/FAC SaveDataOwnerId: FAIL (0x{:016x} ({:d}) not permitted)\n", aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i].id, (uint32_t)aci.getFileSystemAccessControl().getSaveDataOwnerIdList()[i].access_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ void nstool::MetaProcess::validateAciFromAcid(const nn::hac::AccessControlInfo&
|
||||||
// check misc params
|
// check misc params
|
||||||
if (aci.getKernelCapabilities().getMiscParams().getProgramType() != acid.getKernelCapabilities().getMiscParams().getProgramType())
|
if (aci.getKernelCapabilities().getMiscParams().getProgramType() != acid.getKernelCapabilities().getMiscParams().getProgramType())
|
||||||
{
|
{
|
||||||
fmt::print("[WARNING] ACI/KC ProgramType: FAIL ({:d} not permitted)\n", aci.getKernelCapabilities().getMiscParams().getProgramType());
|
fmt::print("[WARNING] ACI/KC ProgramType: FAIL ({:d} not permitted)\n", (uint32_t)aci.getKernelCapabilities().getMiscParams().getProgramType());
|
||||||
}
|
}
|
||||||
// check kernel version
|
// check kernel version
|
||||||
uint32_t aciKernelVersion = (uint32_t)aci.getKernelCapabilities().getKernelVersion().getVerMajor() << 16 | (uint32_t)aci.getKernelCapabilities().getKernelVersion().getVerMinor();
|
uint32_t aciKernelVersion = (uint32_t)aci.getKernelCapabilities().getKernelVersion().getVerMajor() << 16 | (uint32_t)aci.getKernelCapabilities().getKernelVersion().getVerMinor();
|
||||||
|
@ -328,7 +328,7 @@ void nstool::MetaProcess::displayAciDescHdr(const nn::hac::AccessControlInfoDesc
|
||||||
fmt::print(" Flags: \n");
|
fmt::print(" Flags: \n");
|
||||||
fmt::print(" Production: {}\n", acid.getProductionFlag());
|
fmt::print(" Production: {}\n", acid.getProductionFlag());
|
||||||
fmt::print(" Unqualified Approval: {}\n", acid.getUnqualifiedApprovalFlag());
|
fmt::print(" Unqualified Approval: {}\n", acid.getUnqualifiedApprovalFlag());
|
||||||
fmt::print(" Memory Region: {:s} ({:d})\n", nn::hac::AccessControlInfoUtil::getMemoryRegionAsString(acid.getMemoryRegion()), acid.getMemoryRegion());
|
fmt::print(" Memory Region: {:s} ({:d})\n", nn::hac::AccessControlInfoUtil::getMemoryRegionAsString(acid.getMemoryRegion()), (uint32_t)acid.getMemoryRegion());
|
||||||
fmt::print(" ProgramID Restriction\n");
|
fmt::print(" ProgramID Restriction\n");
|
||||||
fmt::print(" Min: 0x{:016x}\n", acid.getProgramIdRestrict().min);
|
fmt::print(" Min: 0x{:016x}\n", acid.getProgramIdRestrict().min);
|
||||||
fmt::print(" Max: 0x{:016x}\n", acid.getProgramIdRestrict().max);
|
fmt::print(" Max: 0x{:016x}\n", acid.getProgramIdRestrict().max);
|
||||||
|
@ -347,7 +347,7 @@ void nstool::MetaProcess::displayFac(const nn::hac::FileSystemAccessControl& fac
|
||||||
std::string flag_string = nn::hac::FileSystemAccessUtil::getFsAccessFlagAsString(nn::hac::fac::FsAccessFlag(*itr));
|
std::string flag_string = nn::hac::FileSystemAccessUtil::getFsAccessFlagAsString(nn::hac::fac::FsAccessFlag(*itr));
|
||||||
if (mCliOutputMode.show_extended_info)
|
if (mCliOutputMode.show_extended_info)
|
||||||
{
|
{
|
||||||
fs_access_str_list.push_back(fmt::format("{:s} (bit {:d})", flag_string, *itr));
|
fs_access_str_list.push_back(fmt::format("{:s} (bit {:d})", flag_string, (uint32_t)*itr));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -445,7 +445,7 @@ void nstool::MetaProcess::displayKernelCap(const nn::hac::KernelCapabilityContro
|
||||||
}
|
}
|
||||||
if (kern.getMiscParams().isSet())
|
if (kern.getMiscParams().isSet())
|
||||||
{
|
{
|
||||||
fmt::print(" ProgramType: {:s} ({:d})\n", nn::hac::KernelCapabilityUtil::getProgramTypeAsString(kern.getMiscParams().getProgramType()), kern.getMiscParams().getProgramType());
|
fmt::print(" ProgramType: {:s} ({:d})\n", nn::hac::KernelCapabilityUtil::getProgramTypeAsString(kern.getMiscParams().getProgramType()), (uint32_t)kern.getMiscParams().getProgramType());
|
||||||
}
|
}
|
||||||
if (kern.getKernelVersion().isSet())
|
if (kern.getKernelVersion().isSet())
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,6 +69,11 @@ void nstool::NcaProcess::setVerifyMode(bool verify)
|
||||||
mVerify = verify;
|
mVerify = verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nstool::NcaProcess::setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs)
|
||||||
|
{
|
||||||
|
mFsProcess.setArchiveJobs(jobs);
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::NcaProcess::setShowFsTree(bool show_fs_tree)
|
void nstool::NcaProcess::setShowFsTree(bool show_fs_tree)
|
||||||
{
|
{
|
||||||
mFsProcess.setShowFsTree(show_fs_tree);
|
mFsProcess.setShowFsTree(show_fs_tree);
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
// fs specific
|
// fs specific
|
||||||
|
void setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs);
|
||||||
void setShowFsTree(bool show_fs_tree);
|
void setShowFsTree(bool show_fs_tree);
|
||||||
void setFsRootLabel(const std::string& root_label);
|
void setFsRootLabel(const std::string& root_label);
|
||||||
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
||||||
|
|
|
@ -64,6 +64,11 @@ void nstool::NroProcess::setAssetNacpExtractPath(const tc::io::Path& path)
|
||||||
mAssetProc.setNacpExtractPath(path);
|
mAssetProc.setNacpExtractPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nstool::NroProcess::setAssetRomfsArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs)
|
||||||
|
{
|
||||||
|
mAssetProc.setRomfsArchiveJobs(jobs);
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::NroProcess::setAssetRomfsShowFsTree(bool show_fs_tree)
|
void nstool::NroProcess::setAssetRomfsShowFsTree(bool show_fs_tree)
|
||||||
{
|
{
|
||||||
mAssetProc.setRomfsShowFsTree(show_fs_tree);
|
mAssetProc.setRomfsShowFsTree(show_fs_tree);
|
||||||
|
|
|
@ -25,6 +25,7 @@ public:
|
||||||
// for homebrew NROs with Asset blobs appended
|
// for homebrew NROs with Asset blobs appended
|
||||||
void setAssetIconExtractPath(const tc::io::Path& path);
|
void setAssetIconExtractPath(const tc::io::Path& path);
|
||||||
void setAssetNacpExtractPath(const tc::io::Path& path);
|
void setAssetNacpExtractPath(const tc::io::Path& path);
|
||||||
|
void setAssetRomfsArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs);
|
||||||
void setAssetRomfsShowFsTree(bool show_fs_tree);
|
void setAssetRomfsShowFsTree(bool show_fs_tree);
|
||||||
void setAssetRomfsExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
void setAssetRomfsExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,11 @@ void nstool::PfsProcess::setVerifyMode(bool verify)
|
||||||
mVerify = verify;
|
mVerify = verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nstool::PfsProcess::setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs)
|
||||||
|
{
|
||||||
|
mFsProcess.setArchiveJobs(jobs);
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::PfsProcess::setShowFsTree(bool show_fs_tree)
|
void nstool::PfsProcess::setShowFsTree(bool show_fs_tree)
|
||||||
{
|
{
|
||||||
mFsProcess.setShowFsTree(show_fs_tree);
|
mFsProcess.setShowFsTree(show_fs_tree);
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
// fs specific
|
// fs specific
|
||||||
|
void setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs);
|
||||||
void setShowFsTree(bool show_fs_tree);
|
void setShowFsTree(bool show_fs_tree);
|
||||||
void setFsRootLabel(const std::string& root_label);
|
void setFsRootLabel(const std::string& root_label);
|
||||||
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
||||||
|
|
|
@ -112,6 +112,11 @@ void nstool::RomfsProcess::setVerifyMode(bool verify)
|
||||||
mVerify = verify;
|
mVerify = verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs)
|
||||||
|
{
|
||||||
|
mFsProcess.setArchiveJobs(jobs);
|
||||||
|
}
|
||||||
|
|
||||||
void nstool::RomfsProcess::setFsRootLabel(const std::string& root_label)
|
void nstool::RomfsProcess::setFsRootLabel(const std::string& root_label)
|
||||||
{
|
{
|
||||||
mFsProcess.setFsRootLabel(root_label);
|
mFsProcess.setFsRootLabel(root_label);
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
// fs specific
|
// fs specific
|
||||||
|
void setArchiveJobs(const std::vector<nstool::ArchiveJob>& jobs);
|
||||||
void setFsRootLabel(const std::string& root_label);
|
void setFsRootLabel(const std::string& root_label);
|
||||||
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
void setExtractJobs(const std::vector<nstool::ExtractJob>& extract_jobs);
|
||||||
void setShowFsTree(bool show_fs_tree);
|
void setShowFsTree(bool show_fs_tree);
|
||||||
|
|
177
src/Settings.cpp
177
src/Settings.cpp
|
@ -9,8 +9,6 @@
|
||||||
#include <tc/io/FileStream.h>
|
#include <tc/io/FileStream.h>
|
||||||
#include <tc/io/StreamSource.h>
|
#include <tc/io/StreamSource.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <nn/hac/ContentArchiveUtil.h>
|
#include <nn/hac/ContentArchiveUtil.h>
|
||||||
#include <nn/hac/AesKeygen.h>
|
#include <nn/hac/AesKeygen.h>
|
||||||
#include <nn/hac/define/gc.h>
|
#include <nn/hac/define/gc.h>
|
||||||
|
@ -42,6 +40,11 @@ public:
|
||||||
throw tc::InvalidOperationException("getOptionStrings() not defined for UnkOptionHandler.");
|
throw tc::InvalidOperationException("getOptionStrings() not defined for UnkOptionHandler.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
throw tc::InvalidOperationException("getOptionRegexPatterns() not defined for UnkOptionHandler.");
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
throw tc::Exception(mModuleLabel, "Unrecognized option: \"" + option + "\"");
|
throw tc::Exception(mModuleLabel, "Unrecognized option: \"" + option + "\"");
|
||||||
|
@ -55,7 +58,8 @@ class DeprecatedOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
public:
|
public:
|
||||||
DeprecatedOptionHandler(const std::string& warn_message, const std::vector<std::string>& opts) :
|
DeprecatedOptionHandler(const std::string& warn_message, const std::vector<std::string>& opts) :
|
||||||
mWarnMessage(warn_message),
|
mWarnMessage(warn_message),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -63,6 +67,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
fmt::print("[WARNING] Option \"{}\" is deprecated.{}{}\n", option, (mWarnMessage.empty() ? "" : " "), mWarnMessage);
|
fmt::print("[WARNING] Option \"{}\" is deprecated.{}{}\n", option, (mWarnMessage.empty() ? "" : " "), mWarnMessage);
|
||||||
|
@ -70,6 +79,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::string mWarnMessage;
|
std::string mWarnMessage;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlagOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class FlagOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -77,7 +87,8 @@ class FlagOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
public:
|
public:
|
||||||
FlagOptionHandler(bool& flag, const std::vector<std::string>& opts) :
|
FlagOptionHandler(bool& flag, const std::vector<std::string>& opts) :
|
||||||
mFlag(flag),
|
mFlag(flag),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -85,6 +96,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 0)
|
if (params.size() != 0)
|
||||||
|
@ -97,6 +113,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool& mFlag;
|
bool& mFlag;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SingleParamStringOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class SingleParamStringOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -104,7 +121,8 @@ class SingleParamStringOptionHandler : public tc::cli::OptionParser::IOptionHand
|
||||||
public:
|
public:
|
||||||
SingleParamStringOptionHandler(tc::Optional<std::string>& param, const std::vector<std::string>& opts) :
|
SingleParamStringOptionHandler(tc::Optional<std::string>& param, const std::vector<std::string>& opts) :
|
||||||
mParam(param),
|
mParam(param),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -112,6 +130,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -124,6 +147,7 @@ public:
|
||||||
private:
|
private:
|
||||||
tc::Optional<std::string>& mParam;
|
tc::Optional<std::string>& mParam;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SingleParamPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class SingleParamPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -131,7 +155,8 @@ class SingleParamPathOptionHandler : public tc::cli::OptionParser::IOptionHandle
|
||||||
public:
|
public:
|
||||||
SingleParamPathOptionHandler(tc::Optional<tc::io::Path>& param, const std::vector<std::string>& opts) :
|
SingleParamPathOptionHandler(tc::Optional<tc::io::Path>& param, const std::vector<std::string>& opts) :
|
||||||
mParam(param),
|
mParam(param),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -139,6 +164,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -151,6 +181,7 @@ public:
|
||||||
private:
|
private:
|
||||||
tc::Optional<tc::io::Path>& mParam;
|
tc::Optional<tc::io::Path>& mParam;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SingleParamSizetOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class SingleParamSizetOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -158,7 +189,8 @@ class SingleParamSizetOptionHandler : public tc::cli::OptionParser::IOptionHandl
|
||||||
public:
|
public:
|
||||||
SingleParamSizetOptionHandler(size_t& param, const std::vector<std::string>& opts) :
|
SingleParamSizetOptionHandler(size_t& param, const std::vector<std::string>& opts) :
|
||||||
mParam(param),
|
mParam(param),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -166,6 +198,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -178,6 +215,7 @@ public:
|
||||||
private:
|
private:
|
||||||
size_t& mParam;
|
size_t& mParam;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SingleParamAesKeyOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class SingleParamAesKeyOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -185,7 +223,8 @@ class SingleParamAesKeyOptionHandler : public tc::cli::OptionParser::IOptionHand
|
||||||
public:
|
public:
|
||||||
SingleParamAesKeyOptionHandler(tc::Optional<nstool::KeyBag::aes128_key_t>& param, const std::vector<std::string>& opts) :
|
SingleParamAesKeyOptionHandler(tc::Optional<nstool::KeyBag::aes128_key_t>& param, const std::vector<std::string>& opts) :
|
||||||
mParam(param),
|
mParam(param),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -193,6 +232,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -214,6 +258,7 @@ public:
|
||||||
private:
|
private:
|
||||||
tc::Optional<nstool::KeyBag::aes128_key_t>& mParam;
|
tc::Optional<nstool::KeyBag::aes128_key_t>& mParam;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileTypeOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class FileTypeOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -221,7 +266,8 @@ class FileTypeOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
public:
|
public:
|
||||||
FileTypeOptionHandler(nstool::Settings::FileType& param, const std::vector<std::string>& opts) :
|
FileTypeOptionHandler(nstool::Settings::FileType& param, const std::vector<std::string>& opts) :
|
||||||
mParam(param),
|
mParam(param),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -229,6 +275,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -310,6 +361,7 @@ public:
|
||||||
private:
|
private:
|
||||||
nstool::Settings::FileType& mParam;
|
nstool::Settings::FileType& mParam;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstructionTypeOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class InstructionTypeOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
@ -317,7 +369,8 @@ class InstructionTypeOptionHandler : public tc::cli::OptionParser::IOptionHandle
|
||||||
public:
|
public:
|
||||||
InstructionTypeOptionHandler(bool& param, const std::vector<std::string>& opts) :
|
InstructionTypeOptionHandler(bool& param, const std::vector<std::string>& opts) :
|
||||||
mParam(param),
|
mParam(param),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -325,6 +378,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -348,14 +406,16 @@ public:
|
||||||
private:
|
private:
|
||||||
bool& mParam;
|
bool& mParam;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExtractDataPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class ListArchiveJobPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExtractDataPathOptionHandler(std::vector<nstool::ExtractJob>& jobs, const std::vector<std::string>& opts) :
|
ListArchiveJobPathOptionHandler(std::vector<nstool::ArchiveJob>& jobs, const std::vector<std::string>& opts) :
|
||||||
mJobs(jobs),
|
mJobs(jobs),
|
||||||
mOptStrings(opts)
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const std::vector<std::string>& getOptionStrings() const
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
@ -363,15 +423,60 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
|
{
|
||||||
|
if (params.size() == 0)
|
||||||
|
{
|
||||||
|
mJobs.push_back({nstool::ArchiveJob::JobAction::ListFileTree, tc::io::Path("/"), tc::io::Path(), false});
|
||||||
|
}
|
||||||
|
else if (params.size() == 1)
|
||||||
|
{
|
||||||
|
mJobs.push_back({nstool::ArchiveJob::JobAction::ListFileTree, tc::io::Path(params[0]), tc::io::Path(), false});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw tc::ArgumentOutOfRangeException(fmt::format("Option \"{:s}\" requires one parameter in the format \"{:s} [<internal path>]\".", option, option));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::vector<nstool::ArchiveJob>& mJobs;
|
||||||
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExtractArchiveJobPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExtractArchiveJobPathOptionHandler(std::vector<nstool::ArchiveJob>& jobs, const std::vector<std::string>& opts) :
|
||||||
|
mJobs(jobs),
|
||||||
|
mOptStrings(opts),
|
||||||
|
mOptRegex()
|
||||||
|
{}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionStrings() const
|
||||||
|
{
|
||||||
|
return mOptStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() == 1)
|
if (params.size() == 1)
|
||||||
{
|
{
|
||||||
mJobs.push_back({tc::io::Path("/"), tc::io::Path(params[0])});
|
mJobs.push_back({nstool::ArchiveJob::JobAction::Extract, tc::io::Path("/"), tc::io::Path(params[0]), false});
|
||||||
}
|
}
|
||||||
else if (params.size() == 2)
|
else if (params.size() == 2)
|
||||||
{
|
{
|
||||||
mJobs.push_back({tc::io::Path(params[0]), tc::io::Path(params[1])});
|
mJobs.push_back({nstool::ArchiveJob::JobAction::Extract, tc::io::Path(params[0]), tc::io::Path(params[1]), false});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -379,16 +484,18 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::vector<nstool::ExtractJob>& mJobs;
|
std::vector<nstool::ArchiveJob>& mJobs;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CustomExtractDataPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
class CustomExtractArchiveJobPathOptionHandler : public tc::cli::OptionParser::IOptionHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CustomExtractDataPathOptionHandler(std::vector<nstool::ExtractJob>& jobs, const std::vector<std::string>& opts, const tc::io::Path& custom_path) :
|
CustomExtractArchiveJobPathOptionHandler(std::vector<nstool::ArchiveJob>& jobs, const std::vector<std::string>& opts, const tc::io::Path& custom_path) :
|
||||||
mJobs(jobs),
|
mJobs(jobs),
|
||||||
mOptStrings(opts),
|
mOptStrings(opts),
|
||||||
|
mOptRegex(),
|
||||||
mCustomPath(custom_path)
|
mCustomPath(custom_path)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -397,6 +504,11 @@ public:
|
||||||
return mOptStrings;
|
return mOptStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getOptionRegexPatterns() const
|
||||||
|
{
|
||||||
|
return mOptRegex;
|
||||||
|
}
|
||||||
|
|
||||||
void processOption(const std::string& option, const std::vector<std::string>& params)
|
void processOption(const std::string& option, const std::vector<std::string>& params)
|
||||||
{
|
{
|
||||||
if (params.size() != 1)
|
if (params.size() != 1)
|
||||||
|
@ -417,13 +529,13 @@ public:
|
||||||
{
|
{
|
||||||
fmt::print("Consider using \"-x {:s} {:s}\" instead.\n", custom_path_str, params[0]);
|
fmt::print("Consider using \"-x {:s} {:s}\" instead.\n", custom_path_str, params[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mJobs.push_back({mCustomPath, tc::io::Path(params[0])});
|
mJobs.push_back({nstool::ArchiveJob::JobAction::Extract, mCustomPath, tc::io::Path(params[0]), false});
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::vector<nstool::ExtractJob>& mJobs;
|
std::vector<nstool::ArchiveJob>& mJobs;
|
||||||
std::vector<std::string> mOptStrings;
|
std::vector<std::string> mOptStrings;
|
||||||
|
std::vector<std::string> mOptRegex;
|
||||||
tc::io::Path mCustomPath;
|
tc::io::Path mCustomPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -536,6 +648,7 @@ void nstool::SettingsInitializer::parse_args(const std::vector<std::string>& arg
|
||||||
|
|
||||||
// register handler for deprecated options DeprecatedOptionHandler
|
// register handler for deprecated options DeprecatedOptionHandler
|
||||||
// none just yet
|
// none just yet
|
||||||
|
//opts.registerOptionHandler(std::shared_ptr<DeprecatedOptionHandler>(new DeprecatedOptionHandler("warning message here", {"--dep-option"})));
|
||||||
|
|
||||||
// get option flags
|
// get option flags
|
||||||
opts.registerOptionHandler(std::shared_ptr<FlagOptionHandler>(new FlagOptionHandler(mShowLayout, {"--showlayout"})));
|
opts.registerOptionHandler(std::shared_ptr<FlagOptionHandler>(new FlagOptionHandler(mShowLayout, {"--showlayout"})));
|
||||||
|
@ -560,21 +673,21 @@ void nstool::SettingsInitializer::parse_args(const std::vector<std::string>& arg
|
||||||
opts.registerOptionHandler(std::shared_ptr<InstructionTypeOptionHandler>(new InstructionTypeOptionHandler(code.is_64bit_instruction, { "--insttype" })));
|
opts.registerOptionHandler(std::shared_ptr<InstructionTypeOptionHandler>(new InstructionTypeOptionHandler(code.is_64bit_instruction, { "--insttype" })));
|
||||||
|
|
||||||
// fs options
|
// fs options
|
||||||
opts.registerOptionHandler(std::shared_ptr<FlagOptionHandler>(new FlagOptionHandler(fs.show_fs_tree, { "--fstree", "--listfs" })));
|
opts.registerOptionHandler(std::shared_ptr<ListArchiveJobPathOptionHandler>(new ListArchiveJobPathOptionHandler(fs.archive_jobs, { "--fstree", "--listfs" })));
|
||||||
opts.registerOptionHandler(std::shared_ptr<ExtractDataPathOptionHandler>(new ExtractDataPathOptionHandler(fs.extract_jobs, { "-x", "--extract" })));
|
opts.registerOptionHandler(std::shared_ptr<ExtractArchiveJobPathOptionHandler>(new ExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "-x", "--extract" })));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--fsdir" }, tc::io::Path("/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--fsdir" }, tc::io::Path("/"))));
|
||||||
|
|
||||||
// xci options
|
// xci options
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--update" }, tc::io::Path("/update/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--update" }, tc::io::Path("/update/"))));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--normal" }, tc::io::Path("/normal/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--normal" }, tc::io::Path("/normal/"))));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--secure" }, tc::io::Path("/secure/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--secure" }, tc::io::Path("/secure/"))));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--logo" }, tc::io::Path("/logo/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--logo" }, tc::io::Path("/logo/"))));
|
||||||
|
|
||||||
// nca options
|
// nca options
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--part0" }, tc::io::Path("/0/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--part0" }, tc::io::Path("/0/"))));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--part1" }, tc::io::Path("/1/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--part1" }, tc::io::Path("/1/"))));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--part2" }, tc::io::Path("/2/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--part2" }, tc::io::Path("/2/"))));
|
||||||
opts.registerOptionHandler(std::shared_ptr<CustomExtractDataPathOptionHandler>(new CustomExtractDataPathOptionHandler(fs.extract_jobs, { "--part3" }, tc::io::Path("/3/"))));
|
opts.registerOptionHandler(std::shared_ptr<CustomExtractArchiveJobPathOptionHandler>(new CustomExtractArchiveJobPathOptionHandler(fs.archive_jobs, { "--part3" }, tc::io::Path("/3/"))));
|
||||||
|
|
||||||
// kip options
|
// kip options
|
||||||
opts.registerOptionHandler(std::shared_ptr<SingleParamPathOptionHandler>(new SingleParamPathOptionHandler(kip.extract_path, { "--kipdir" })));
|
opts.registerOptionHandler(std::shared_ptr<SingleParamPathOptionHandler>(new SingleParamPathOptionHandler(kip.extract_path, { "--kipdir" })));
|
||||||
|
|
|
@ -56,27 +56,14 @@ struct Settings
|
||||||
// Generic FS options
|
// Generic FS options
|
||||||
struct FsOptions
|
struct FsOptions
|
||||||
{
|
{
|
||||||
|
// legacy
|
||||||
bool show_fs_tree;
|
bool show_fs_tree;
|
||||||
std::vector<ExtractJob> extract_jobs;
|
std::vector<ExtractJob> extract_jobs;
|
||||||
|
|
||||||
|
// new
|
||||||
|
std::vector<ArchiveJob> archive_jobs;
|
||||||
} fs;
|
} fs;
|
||||||
|
|
||||||
// XCI options
|
|
||||||
struct XciOptions
|
|
||||||
{
|
|
||||||
tc::Optional<tc::io::Path> update_extract_path;
|
|
||||||
tc::Optional<tc::io::Path> logo_extract_path;
|
|
||||||
tc::Optional<tc::io::Path> normal_extract_path;
|
|
||||||
tc::Optional<tc::io::Path> secure_extract_path;
|
|
||||||
} xci;
|
|
||||||
|
|
||||||
// NCA options
|
|
||||||
struct NcaOptions
|
|
||||||
{
|
|
||||||
tc::Optional<tc::io::Path> part0_extract_path;
|
|
||||||
tc::Optional<tc::io::Path> part1_extract_path;
|
|
||||||
tc::Optional<tc::io::Path> part2_extract_path;
|
|
||||||
tc::Optional<tc::io::Path> part3_extract_path;
|
|
||||||
} nca;
|
|
||||||
|
|
||||||
// KIP options
|
// KIP options
|
||||||
struct KipOptions
|
struct KipOptions
|
||||||
|
@ -107,6 +94,7 @@ struct Settings
|
||||||
|
|
||||||
fs.show_fs_tree = false;
|
fs.show_fs_tree = false;
|
||||||
fs.extract_jobs = std::vector<ExtractJob>();
|
fs.extract_jobs = std::vector<ExtractJob>();
|
||||||
|
fs.archive_jobs = std::vector<ArchiveJob>();
|
||||||
|
|
||||||
kip.extract_path = tc::Optional<tc::io::Path>();
|
kip.extract_path = tc::Optional<tc::io::Path>();
|
||||||
|
|
||||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -37,6 +37,8 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
obj.setCliOutputMode(set.opt.cli_output_mode);
|
obj.setCliOutputMode(set.opt.cli_output_mode);
|
||||||
obj.setVerifyMode(set.opt.verify);
|
obj.setVerifyMode(set.opt.verify);
|
||||||
|
|
||||||
|
obj.setArchiveJobs(set.fs.archive_jobs);
|
||||||
|
|
||||||
obj.setShowFsTree(set.fs.show_fs_tree);
|
obj.setShowFsTree(set.fs.show_fs_tree);
|
||||||
obj.setExtractJobs(set.fs.extract_jobs);
|
obj.setExtractJobs(set.fs.extract_jobs);
|
||||||
|
|
||||||
|
@ -51,6 +53,8 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
obj.setCliOutputMode(set.opt.cli_output_mode);
|
obj.setCliOutputMode(set.opt.cli_output_mode);
|
||||||
obj.setVerifyMode(set.opt.verify);
|
obj.setVerifyMode(set.opt.verify);
|
||||||
|
|
||||||
|
obj.setArchiveJobs(set.fs.archive_jobs);
|
||||||
|
|
||||||
obj.setShowFsTree(set.fs.show_fs_tree);
|
obj.setShowFsTree(set.fs.show_fs_tree);
|
||||||
obj.setExtractJobs(set.fs.extract_jobs);
|
obj.setExtractJobs(set.fs.extract_jobs);
|
||||||
|
|
||||||
|
@ -65,6 +69,8 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
obj.setCliOutputMode(set.opt.cli_output_mode);
|
obj.setCliOutputMode(set.opt.cli_output_mode);
|
||||||
obj.setVerifyMode(set.opt.verify);
|
obj.setVerifyMode(set.opt.verify);
|
||||||
|
|
||||||
|
obj.setArchiveJobs(set.fs.archive_jobs);
|
||||||
|
|
||||||
obj.setShowFsTree(set.fs.show_fs_tree);
|
obj.setShowFsTree(set.fs.show_fs_tree);
|
||||||
obj.setExtractJobs(set.fs.extract_jobs);
|
obj.setExtractJobs(set.fs.extract_jobs);
|
||||||
|
|
||||||
|
@ -79,6 +85,8 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
obj.setCliOutputMode(set.opt.cli_output_mode);
|
obj.setCliOutputMode(set.opt.cli_output_mode);
|
||||||
obj.setVerifyMode(set.opt.verify);
|
obj.setVerifyMode(set.opt.verify);
|
||||||
|
|
||||||
|
obj.setArchiveJobs(set.fs.archive_jobs);
|
||||||
|
|
||||||
obj.setShowFsTree(set.fs.show_fs_tree);
|
obj.setShowFsTree(set.fs.show_fs_tree);
|
||||||
obj.setExtractJobs(set.fs.extract_jobs);
|
obj.setExtractJobs(set.fs.extract_jobs);
|
||||||
|
|
||||||
|
@ -136,6 +144,8 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
if (set.aset.nacp_extract_path.isSet())
|
if (set.aset.nacp_extract_path.isSet())
|
||||||
obj.setAssetNacpExtractPath(set.aset.nacp_extract_path.get());
|
obj.setAssetNacpExtractPath(set.aset.nacp_extract_path.get());
|
||||||
|
|
||||||
|
obj.setAssetRomfsArchiveJobs(set.fs.archive_jobs);
|
||||||
|
|
||||||
obj.setAssetRomfsShowFsTree(set.fs.show_fs_tree);
|
obj.setAssetRomfsShowFsTree(set.fs.show_fs_tree);
|
||||||
obj.setAssetRomfsExtractJobs(set.fs.extract_jobs);
|
obj.setAssetRomfsExtractJobs(set.fs.extract_jobs);
|
||||||
|
|
||||||
|
|
26
src/types.h
26
src/types.h
|
@ -24,6 +24,32 @@ struct CliOutputMode
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ArchiveJob
|
||||||
|
{
|
||||||
|
/* Common Job Properties */
|
||||||
|
enum class JobAction {
|
||||||
|
DoNothing,
|
||||||
|
ListFileTree,
|
||||||
|
Extract
|
||||||
|
};
|
||||||
|
JobAction job_action; // action taken by job processor
|
||||||
|
tc::io::Path archive_path; // path within archive to process
|
||||||
|
|
||||||
|
/* Extract Job Properties */
|
||||||
|
tc::io::Path extract_base_path; // path to base directory to extract
|
||||||
|
bool preserve_archive_path; // recreate archive path when extracting
|
||||||
|
|
||||||
|
ArchiveJob() : job_action(JobAction::DoNothing), archive_path(), extract_base_path(), preserve_archive_path(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ArchiveJob(JobAction job_action, const tc::io::Path& archive_path, const tc::io::Path& extract_base_path, bool preserve_archive_path) :
|
||||||
|
job_action(job_action),
|
||||||
|
archive_path(archive_path),
|
||||||
|
extract_base_path(extract_base_path),
|
||||||
|
preserve_archive_path(preserve_archive_path)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
struct ExtractJob {
|
struct ExtractJob {
|
||||||
tc::io::Path virtual_path;
|
tc::io::Path virtual_path;
|
||||||
tc::io::Path extract_path;
|
tc::io::Path extract_path;
|
||||||
|
|
Loading…
Reference in a new issue