mirror of
https://github.com/jakcron/nstool
synced 2024-12-26 22:51:11 +00:00
Port RomfsProcess to libtoolchain.
This commit is contained in:
parent
d373132e08
commit
35cb707487
6 changed files with 159 additions and 108 deletions
2
deps/libnintendo-hac
vendored
2
deps/libnintendo-hac
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 22e80406394a7bc0bcd2a9cc52a67be654239007
|
Subproject commit a4bef5a52859625027f75b71d802b1a53af18534
|
|
@ -35,7 +35,7 @@ void nstool::AssetProcess::setVerifyMode(bool verify)
|
||||||
|
|
||||||
void nstool::AssetProcess::setListFs(bool list)
|
void nstool::AssetProcess::setListFs(bool list)
|
||||||
{
|
{
|
||||||
//mRomfs.setListFs(list);
|
mRomfs.setListFs(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstool::AssetProcess::setIconExtractPath(const tc::io::Path& path)
|
void nstool::AssetProcess::setIconExtractPath(const tc::io::Path& path)
|
||||||
|
@ -50,7 +50,7 @@ void nstool::AssetProcess::setNacpExtractPath(const tc::io::Path& path)
|
||||||
|
|
||||||
void nstool::AssetProcess::setRomfsExtractPath(const tc::io::Path& path)
|
void nstool::AssetProcess::setRomfsExtractPath(const tc::io::Path& path)
|
||||||
{
|
{
|
||||||
//mRomfs.setExtractPath(path);
|
mRomfs.setExtractPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +82,10 @@ void nstool::AssetProcess::processSections()
|
||||||
if ((mHdr.getIconInfo().size + mHdr.getIconInfo().offset) > file_size)
|
if ((mHdr.getIconInfo().size + mHdr.getIconInfo().offset) > file_size)
|
||||||
throw tc::Exception(mModuleName, "ASET geometry for icon beyond file size");
|
throw tc::Exception(mModuleName, "ASET geometry for icon beyond file size");
|
||||||
|
|
||||||
|
std::string icon_extract_path_str;
|
||||||
|
tc::io::PathUtil::pathToUnixUTF8(mIconExtractPath.get(), icon_extract_path_str);
|
||||||
|
|
||||||
|
fmt::print("Saving {:s}...", icon_extract_path_str);
|
||||||
writeSubStreamToFile(mFile, mHdr.getIconInfo().offset, mHdr.getIconInfo().size, mIconExtractPath.get());
|
writeSubStreamToFile(mFile, mHdr.getIconInfo().offset, mHdr.getIconInfo().size, mIconExtractPath.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,11 +111,11 @@ void nstool::AssetProcess::processSections()
|
||||||
if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > file_size)
|
if ((mHdr.getRomfsInfo().size + mHdr.getRomfsInfo().offset) > file_size)
|
||||||
throw tc::Exception(mModuleName, "ASET geometry for romfs beyond file size");
|
throw tc::Exception(mModuleName, "ASET geometry for romfs beyond file size");
|
||||||
|
|
||||||
//mRomfs.setInputFile(std::make_shared<tc::io::SubStream>(mFile, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size));
|
mRomfs.setInputFile(std::make_shared<tc::io::SubStream>(mFile, mHdr.getRomfsInfo().offset, mHdr.getRomfsInfo().size));
|
||||||
//mRomfs.setCliOutputMode(mCliOutputMode);
|
mRomfs.setCliOutputMode(mCliOutputMode);
|
||||||
//mRomfs.setVerifyMode(mVerify);
|
mRomfs.setVerifyMode(mVerify);
|
||||||
|
|
||||||
//mRomfs.process();
|
mRomfs.process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ private:
|
||||||
|
|
||||||
nn::hac::AssetHeader mHdr;
|
nn::hac::AssetHeader mHdr;
|
||||||
NacpProcess mNacp;
|
NacpProcess mNacp;
|
||||||
//RomfsProcess mRomfs;
|
RomfsProcess mRomfs;
|
||||||
|
|
||||||
void importHeader();
|
void importHeader();
|
||||||
void processSections();
|
void processSections();
|
||||||
|
|
134
src/RomfsProcess.cpp
Normal file
134
src/RomfsProcess.cpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#include "RomfsProcess.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include <tc/io/VirtualFileSystem.h>
|
||||||
|
#include <nn/hac/RomFsMetaGenerator.h>
|
||||||
|
|
||||||
|
|
||||||
|
nstool::RomfsProcess::RomfsProcess() :
|
||||||
|
mModuleName("nstool::RomfsProcess"),
|
||||||
|
mFile(),
|
||||||
|
mCliOutputMode(true, false, false, false),
|
||||||
|
mVerify(false),
|
||||||
|
mDirNum(0),
|
||||||
|
mFileNum(0),
|
||||||
|
mFileSystem(),
|
||||||
|
mFsProcess()
|
||||||
|
{
|
||||||
|
mFsProcess.setFsLabel("RomFS");
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::process()
|
||||||
|
{
|
||||||
|
importHeader();
|
||||||
|
|
||||||
|
if (mCliOutputMode.show_basic_info)
|
||||||
|
{
|
||||||
|
displayHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
mFsProcess.process();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setInputFile(const std::shared_ptr<tc::io::IStream>& file)
|
||||||
|
{
|
||||||
|
mFile = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setCliOutputMode(CliOutputMode type)
|
||||||
|
{
|
||||||
|
mCliOutputMode = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setVerifyMode(bool verify)
|
||||||
|
{
|
||||||
|
mVerify = verify;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setMountPointName(const std::string& mount_name)
|
||||||
|
{
|
||||||
|
mFsProcess.setFsLabel(mount_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setExtractPath(const tc::io::Path& path)
|
||||||
|
{
|
||||||
|
mFsProcess.setExtractPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::setListFs(bool list_fs)
|
||||||
|
{
|
||||||
|
mFsProcess.setCliOutputMode(list_fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<tc::io::IStorage>& nstool::RomfsProcess::getFileSystem() const
|
||||||
|
{
|
||||||
|
return mFileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::importHeader()
|
||||||
|
{
|
||||||
|
if (mFile == nullptr)
|
||||||
|
{
|
||||||
|
throw tc::Exception(mModuleName, "No file reader set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
tc::ByteData scratch;
|
||||||
|
|
||||||
|
// read base header to determine complete header size
|
||||||
|
if (mFile->length() < tc::io::IOUtil::castSizeToInt64(sizeof(nn::hac::sRomfsHeader)))
|
||||||
|
{
|
||||||
|
throw tc::Exception(mModuleName, "Corrupt RomFs: File too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
mFile->seek(0, tc::io::SeekOrigin::Begin);
|
||||||
|
mFile->read((byte_t*)&mRomfsHeader, sizeof(mRomfsHeader));
|
||||||
|
if (mRomfsHeader.header_size.unwrap() != sizeof(nn::hac::sRomfsHeader) ||
|
||||||
|
mRomfsHeader.dir_hash_bucket.offset.unwrap() != sizeof(nn::hac::sRomfsHeader) ||
|
||||||
|
mRomfsHeader.data_offset.unwrap() != align<int64_t>(mRomfsHeader.header_size.unwrap(), nn::hac::romfs::kRomfsHeaderAlign))
|
||||||
|
{
|
||||||
|
throw tc::ArgumentOutOfRangeException("nn::hac::RomFsMetaGenerator", "Corrupt RomFs: RomFsHeader is corrupted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get dir entry ptr
|
||||||
|
tc::ByteData dir_entry_table = tc::ByteData(tc::io::IOUtil::castInt64ToSize(mRomfsHeader.dir_entry.size.unwrap()));
|
||||||
|
mFile->seek(mRomfsHeader.dir_entry.offset.unwrap(), tc::io::SeekOrigin::Begin);
|
||||||
|
mFile->read(dir_entry_table.data(), dir_entry_table.size());
|
||||||
|
|
||||||
|
// get file entry ptr
|
||||||
|
tc::ByteData file_entry_table = tc::ByteData(tc::io::IOUtil::castInt64ToSize(mRomfsHeader.file_entry.size.unwrap()));
|
||||||
|
mFile->seek(mRomfsHeader.file_entry.offset.unwrap(), tc::io::SeekOrigin::Begin);
|
||||||
|
mFile->read(file_entry_table.data(), file_entry_table.size());
|
||||||
|
|
||||||
|
// count dir num
|
||||||
|
mDirNum = 0;
|
||||||
|
for (uint32_t v_addr = 0; size_t(v_addr) < dir_entry_table.size();)
|
||||||
|
{
|
||||||
|
uint32_t total_size = sizeof(nn::hac::sRomfsDirEntry) + align<uint32_t>(((nn::hac::sRomfsDirEntry*)(dir_entry_table.data() + v_addr))->name_size.unwrap(), 4);
|
||||||
|
|
||||||
|
mDirNum += 1;
|
||||||
|
|
||||||
|
v_addr += total_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// count file num
|
||||||
|
mFileNum = 0;
|
||||||
|
for (uint32_t v_addr = 0; size_t(v_addr) < file_entry_table.size();)
|
||||||
|
{
|
||||||
|
uint32_t total_size = sizeof(nn::hac::sRomfsFileEntry) + align<uint32_t>(((nn::hac::sRomfsFileEntry*)(file_entry_table.data() + v_addr))->name_size.unwrap(), 4);
|
||||||
|
|
||||||
|
mFileNum += 1;
|
||||||
|
|
||||||
|
v_addr += total_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create virtual filesystem
|
||||||
|
mFileSystem = std::make_shared<tc::io::VirtualFileSystem>(tc::io::VirtualFileSystem(nn::hac::RomFsMetaGenerator(mFile)));
|
||||||
|
mFsProcess.setInputFileSystem(mFileSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nstool::RomfsProcess::displayHeader()
|
||||||
|
{
|
||||||
|
fmt::print("[RomFS]\n");
|
||||||
|
fmt::print(" DirNum: {:d}\n", mDirNum);
|
||||||
|
fmt::print(" FileNum: {:d}\n", mFileNum);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "FsProcess.h"
|
||||||
|
|
||||||
#include <nn/hac/define/romfs.h>
|
#include <nn/hac/define/romfs.h>
|
||||||
|
|
||||||
|
@ -8,71 +9,6 @@ namespace nstool {
|
||||||
class RomfsProcess
|
class RomfsProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct sDirectory;
|
|
||||||
struct sFile;
|
|
||||||
|
|
||||||
struct sDirectory
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
std::vector<sDirectory> dir_list;
|
|
||||||
std::vector<sFile> file_list;
|
|
||||||
|
|
||||||
void operator=(const sDirectory& other)
|
|
||||||
{
|
|
||||||
name = other.name;
|
|
||||||
dir_list = other.dir_list;
|
|
||||||
file_list = other.file_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const sDirectory& other) const
|
|
||||||
{
|
|
||||||
return (name == other.name) \
|
|
||||||
&& (dir_list == other.dir_list) \
|
|
||||||
&& (file_list == other.file_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const sDirectory& other) const
|
|
||||||
{
|
|
||||||
return !operator==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const std::string& other) const
|
|
||||||
{
|
|
||||||
return (name == other);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sFile
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
int64_t offset;
|
|
||||||
int64_t size;
|
|
||||||
|
|
||||||
void operator=(const sFile& other)
|
|
||||||
{
|
|
||||||
name = other.name;
|
|
||||||
offset = other.offset;
|
|
||||||
size = other.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const sFile& other) const
|
|
||||||
{
|
|
||||||
return (name == other.name) \
|
|
||||||
&& (offset == other.offset) \
|
|
||||||
&& (size == other.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const sFile& other) const
|
|
||||||
{
|
|
||||||
return !operator==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const std::string& other) const
|
|
||||||
{
|
|
||||||
return (name == other);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
RomfsProcess();
|
RomfsProcess();
|
||||||
|
|
||||||
void process();
|
void process();
|
||||||
|
@ -82,55 +18,31 @@ public:
|
||||||
void setCliOutputMode(CliOutputMode type);
|
void setCliOutputMode(CliOutputMode type);
|
||||||
void setVerifyMode(bool verify);
|
void setVerifyMode(bool verify);
|
||||||
|
|
||||||
// romfs specific
|
// pfs specific
|
||||||
void setMountPointName(const std::string& mount_name);
|
void setMountPointName(const std::string& mount_name);
|
||||||
void setExtractPath(const tc::io::Path& path);
|
void setExtractPath(const tc::io::Path& path);
|
||||||
void setListFs(bool list_fs);
|
void setListFs(bool list_fs);
|
||||||
|
|
||||||
const sDirectory& getRootDir() const;
|
const std::shared_ptr<tc::io::IStorage>& getFileSystem() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string kModuleName = "RomfsProcess";
|
|
||||||
static const size_t kCacheSize = 0x10000;
|
static const size_t kCacheSize = 0x10000;
|
||||||
|
|
||||||
|
std::string mModuleName;
|
||||||
|
|
||||||
std::shared_ptr<tc::io::IStream> mFile;
|
std::shared_ptr<tc::io::IStream> mFile;
|
||||||
CliOutputMode mCliOutputMode;
|
CliOutputMode mCliOutputMode;
|
||||||
bool mShowBasicInfo;
|
|
||||||
bool mShowExtendedInfo;
|
|
||||||
bool mShowLayoutInfo;
|
|
||||||
bool mShowKeydata;
|
|
||||||
bool mVerbose;
|
|
||||||
bool mVerify;
|
bool mVerify;
|
||||||
|
|
||||||
tc::Optional<tc::io::Path> mExtractPath;
|
nn::hac::sRomfsHeader mRomfsHeader;
|
||||||
std::string mMountName;
|
|
||||||
bool mListFs;
|
|
||||||
|
|
||||||
tc::ByteData mCache;
|
|
||||||
|
|
||||||
size_t mDirNum;
|
size_t mDirNum;
|
||||||
size_t mFileNum;
|
size_t mFileNum;
|
||||||
nn::hac::sRomfsHeader mHdr;
|
|
||||||
tc::ByteData mDirNodes;
|
|
||||||
tc::ByteData mFileNodes;
|
|
||||||
sDirectory mRootDir;
|
|
||||||
|
|
||||||
inline nn::hac::sRomfsDirEntry* get_dir_node(uint32_t offset) { return (nn::hac::sRomfsDirEntry*)(mDirNodes.data() + offset); }
|
std::shared_ptr<tc::io::IStorage> mFileSystem;
|
||||||
inline nn::hac::sRomfsFileEntry* get_file_node(uint32_t offset) { return (nn::hac::sRomfsFileEntry*)(mFileNodes.data() + offset); }
|
FsProcess mFsProcess;
|
||||||
|
|
||||||
|
|
||||||
void printTab(size_t tab) const;
|
|
||||||
void displayFile(const sFile& file, size_t tab) const;
|
|
||||||
void displayDir(const sDirectory& dir, size_t tab) const;
|
|
||||||
|
|
||||||
|
void importHeader();
|
||||||
void displayHeader();
|
void displayHeader();
|
||||||
void displayFs();
|
|
||||||
|
|
||||||
void extractDir(const std::string& path, const sDirectory& dir);
|
|
||||||
void extractFs();
|
|
||||||
|
|
||||||
bool validateHeaderLayout(const nn::hac::sRomfsHeader* hdr) const;
|
|
||||||
void importDirectory(uint32_t dir_offset, sDirectory& dir);
|
|
||||||
void resolveRomfs();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
//#include "GameCardProcess.h"
|
//#include "GameCardProcess.h"
|
||||||
#include "PfsProcess.h"
|
#include "PfsProcess.h"
|
||||||
//#include "RomfsProcess.h"
|
#include "RomfsProcess.h"
|
||||||
//#include "NcaProcess.h"
|
//#include "NcaProcess.h"
|
||||||
//#include "MetaProcess.h"
|
//#include "MetaProcess.h"
|
||||||
#include "CnmtProcess.h"
|
#include "CnmtProcess.h"
|
||||||
|
@ -64,7 +64,7 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
|
|
||||||
obj.process();
|
obj.process();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else if (set.infile.filetype == nstool::Settings::FILE_TYPE_ROMFS)
|
else if (set.infile.filetype == nstool::Settings::FILE_TYPE_ROMFS)
|
||||||
{
|
{
|
||||||
nstool::RomfsProcess obj;
|
nstool::RomfsProcess obj;
|
||||||
|
@ -79,6 +79,7 @@ int umain(const std::vector<std::string>& args, const std::vector<std::string>&
|
||||||
|
|
||||||
obj.process();
|
obj.process();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else if (set.infile.filetype == nstool::Settings::FILE_TYPE_NCA)
|
else if (set.infile.filetype == nstool::Settings::FILE_TYPE_NCA)
|
||||||
{
|
{
|
||||||
nstool::NcaProcess obj;
|
nstool::NcaProcess obj;
|
||||||
|
|
Loading…
Reference in a new issue