hac2l: support extracting pfs contents to directory

This commit is contained in:
Michael Scire 2024-10-30 00:18:04 -07:00
parent 62685237e8
commit 217f047375
4 changed files with 40 additions and 0 deletions

View File

@ -176,6 +176,8 @@ namespace ams::hactool {
MakeOptionHandler("updatedir", "[xci] Specify xci update hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.update_partition_out_dir), arg); }),
MakeOptionHandler("logodir", "[xci] Specify xci logo hfs0 directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.logo_partition_out_dir), arg); }),
MakeOptionHandler("listupdate", "[xci] List update details.", [] (Options &options) { options.list_update = true; }),
MakeOptionHandler("pfsdir", "[pfs] Specify pfs directory path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.nsp_out_dir_path), arg); }),
MakeOptionHandler("nspdir", "[pfs] Specify nsp directory path. Synonym for pfsdir.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.nsp_out_dir_path), arg); }),
MakeOptionHandler("ciphertext", "[unused] Specify ciphertext output path.", [] (Options &options, const char *arg) { return CreateFilePath(std::addressof(options.ciphertext_out_path), arg); }),
};

View File

@ -62,6 +62,7 @@ namespace ams::hactool {
const char *romfs_out_file_path = nullptr;
const char *romfs_out_dir_path = nullptr;
const char *ini_out_dir_path = nullptr;
const char *nsp_out_dir_path = nullptr;
const char *default_out_dir_path = nullptr;
const char *default_out_file_path = nullptr;
const char *plaintext_out_path = nullptr;

View File

@ -130,6 +130,7 @@ namespace ams::hactool {
std::shared_ptr<fs::IStorage> storage;
std::shared_ptr<fs::fsa::IFileSystem> fs;
u32 magic;
bool is_exefs;
ProcessAsNpdmContext npdm_ctx;

View File

@ -29,6 +29,9 @@ namespace ams::hactool {
/* Set the fs. */
ctx->storage = std::move(storage);
/* Read the magic. */
R_TRY(ctx->storage->Read(0, std::addressof(ctx->magic), sizeof(ctx->magic)));
/* Mount the partition filesystem. */
{
/* Allocate the fs. */
@ -87,6 +90,20 @@ namespace ams::hactool {
}
void Processor::PrintAsPfs(ProcessAsPfsContext &ctx) {
{
auto _ = this->PrintHeader("PartitionFileSystem");
this->PrintMagic(ctx.magic);
{
auto _ = this->PrintHeader("Files");
char print_prefix[1_KB + 5];
std::memset(print_prefix, ' ', WidthToPrintFieldValue);
util::TSNPrintf(print_prefix, sizeof(print_prefix), "%s%s", m_indent_buffer, "pfs:");
PrintDirectory(ctx.fs, print_prefix, "/");
}
}
if (ctx.is_exefs) {
this->PrintAsNpdm(ctx.npdm_ctx);
} else {
@ -95,6 +112,25 @@ namespace ams::hactool {
}
void Processor::SaveAsPfs(ProcessAsPfsContext &ctx) {
/* Save pfs contents. */
{
/* Determine path to extract to. */
const char *dir_path = nullptr;
if (dir_path == nullptr && ctx.is_exefs && m_options.exefs_out_dir_path != nullptr) {
dir_path = m_options.exefs_out_dir_path;
}
if (dir_path == nullptr && m_options.nsp_out_dir_path != nullptr) {
dir_path = m_options.nsp_out_dir_path;
}
if (dir_path == nullptr && m_options.default_out_dir_path != nullptr) {
dir_path = m_options.default_out_dir_path;
}
/* If we have a path, extract to it. */
if (dir_path != nullptr) {
ExtractDirectory(m_local_fs, ctx.fs, "pfs:", dir_path, "/");
}
}
if (ctx.is_exefs) {
this->SaveAsNpdm(ctx.npdm_ctx);
} else {