hac2l: support printing the program nca's info inside an appfs/xci

This commit is contained in:
Michael Scire 2022-06-10 17:10:15 -07:00
parent 65843dec94
commit e0d1b3affd
4 changed files with 56 additions and 22 deletions

View File

@ -366,7 +366,40 @@ namespace ams::hactool {
}
}
/* TODO: Recursive processing? */
if (ctx->has_target) {
/* We have a target. Try to find a patch. */
if (auto patch_prog = ctx->apps.Find(ctx->target_app_id, ctx->target_version, ctx->target_index, ncm::ContentType::Program, ncm::ContentMetaType::Patch); patch_prog != ctx->apps.end()) {
/* Find a base app. */
if (auto same_app_prog = ctx->apps.Find(ctx->target_app_id, ctx->target_version, ctx->target_index, ncm::ContentType::Program, ncm::ContentMetaType::Application); same_app_prog != ctx->apps.end()) {
if (const auto process_res = this->ProcessAsNca(same_app_prog->GetData().storage, std::addressof(ctx->app_base_nca_ctx)); R_SUCCEEDED(process_res)) {
ctx->app_nca_ctx.base_reader = ctx->app_base_nca_ctx.reader;
} else {
fprintf(stderr, "[Warning]: Failed to process target base program nca: 2%03d-%04d\n", process_res.GetModule(), process_res.GetDescription());
}
} else if (auto zero_app_prog = ctx->apps.Find(ctx->target_app_id, 0, ctx->target_index, ncm::ContentType::Program, ncm::ContentMetaType::Application); zero_app_prog != ctx->apps.end()) {
if (const auto process_res = this->ProcessAsNca(zero_app_prog->GetData().storage, std::addressof(ctx->app_base_nca_ctx)); R_SUCCEEDED(process_res)) {
ctx->app_nca_ctx.base_reader = ctx->app_base_nca_ctx.reader;
} else {
fprintf(stderr, "[Warning]: Failed to process target base-0 program nca: 2%03d-%04d\n", process_res.GetModule(), process_res.GetDescription());
}
}
if (const auto process_res = this->ProcessAsNca(patch_prog->GetData().storage, std::addressof(ctx->app_nca_ctx)); R_FAILED(process_res)) {
fprintf(stderr, "[Warning]: Failed to process target patch program nca: 2%03d-%04d\n", process_res.GetModule(), process_res.GetDescription());
}
} else {
/* No patch, so we're working with a normal application. */
auto app_prog = ctx->apps.Find(ctx->target_app_id, ctx->target_version, ctx->target_index, ncm::ContentType::Program, ncm::ContentMetaType::Application);
AMS_ABORT_UNLESS(app_prog != ctx->apps.end());
/* Parse the app prog. */
if (const auto process_res = this->ProcessAsNca(app_prog->GetData().storage, std::addressof(ctx->app_nca_ctx)); R_FAILED(process_res)) {
fprintf(stderr, "[Warning]: Failed to process target program nca: 2%03d-%04d\n", process_res.GetModule(), process_res.GetDescription());
}
}
/* TODO: Parse control, etc? */
}
/* Print. */
if (ctx == std::addressof(local_ctx)) {
@ -407,6 +440,10 @@ namespace ams::hactool {
}
}
if (ctx.has_target) {
this->PrintAsNca(ctx.app_nca_ctx);
}
/* TODO */
AMS_UNUSED(ctx);
}

View File

@ -60,6 +60,7 @@ namespace ams::hactool {
struct ProcessAsNcaContext {
std::shared_ptr<fs::IStorage> storage;
std::shared_ptr<fssystem::NcaReader> reader;
std::shared_ptr<fssystem::NcaReader> base_reader;
s32 exefs_index = -1;
s32 romfs_index = -1;
std::array<bool, fssystem::NcaHeader::FsCountMax> has_sections{};
@ -88,6 +89,9 @@ namespace ams::hactool {
ncm::ApplicationId target_app_id;
u32 target_version;
u8 target_index;
ProcessAsNcaContext app_nca_ctx;
ProcessAsNcaContext app_base_nca_ctx;
};
struct ProcessAsXciContext {

View File

@ -132,10 +132,22 @@ namespace ams::hactool {
for (s32 i = 0; i < fssystem::NcaHeader::FsCountMax; ++i) {
ctx->storage_contexts[i].open_raw_storage = true;
const auto res = util::GetReference(g_storage_on_nca_creator).CreateWithContext(std::addressof(ctx->raw_sections[i]), std::addressof(ctx->splitters[i]), std::addressof(ctx->header_readers[i]), std::addressof(ctx->storage_contexts[i]), ctx->reader, i);
const auto res = [&]() -> Result {
if (ctx->base_reader != nullptr) {
R_RETURN(util::GetReference(g_storage_on_nca_creator).CreateWithPatchWithContext(std::addressof(ctx->raw_sections[i]), std::addressof(ctx->splitters[i]), std::addressof(ctx->header_readers[i]), std::addressof(ctx->storage_contexts[i]), ctx->base_reader, ctx->reader, i));
} else {
R_RETURN(util::GetReference(g_storage_on_nca_creator).CreateWithContext(std::addressof(ctx->raw_sections[i]), std::addressof(ctx->splitters[i]), std::addressof(ctx->header_readers[i]), std::addressof(ctx->storage_contexts[i]), ctx->reader, i));
}
}();
if (R_SUCCEEDED(res)) {
ctx->has_sections[i] = true;
if (ctx->header_readers[i].ExistsSparseLayer()) {
continue;
}
/* Try to open the non-raw section. */
const auto real_res = util::GetReference(g_storage_on_nca_creator).CreateByRawStorage(std::addressof(ctx->sections[i]), std::addressof(ctx->splitters[i]), std::addressof(ctx->header_readers[i]), std::shared_ptr<fs::IStorage>(ctx->raw_sections[i]), std::addressof(ctx->storage_contexts[i]), ctx->reader);
if (R_SUCCEEDED(real_res)) {

View File

@ -359,26 +359,7 @@ namespace ams::hactool {
}
if (ctx.secure_partition.fs != nullptr) {
s32 app_idx = -1;
ncm::ApplicationId cur_app_id{};
const char *field_name = "Programs";
for (const auto &entry : ctx.app_ctx.apps) {
if (entry.GetType() != ncm::ContentType::Program) {
continue;
}
if (app_idx == -1 || cur_app_id != entry.GetId()) {
++app_idx;
cur_app_id = entry.GetId();
}
this->PrintFormat(field_name, "{ Idx=%d, ProgramId=%016" PRIX64 ", Version=0x%08" PRIX32 ", IdOffset=%02" PRIX32 ", MetaType=%s }", app_idx, entry.GetId().value, entry.GetVersion(), entry.GetIdOffset(), entry.GetMetaType() == ncm::ContentMetaType::Patch ? "Patch" : "App");
field_name = "";
}
if (ctx.app_ctx.has_target) {
this->PrintFormat("Target", "{ ProgramId=%016" PRIX64 ", Version=0x%08" PRIX32 ", IdOffset=%02" PRIX32 " }", ctx.app_ctx.target_app_id.value, ctx.app_ctx.target_version, ctx.app_ctx.target_index);
}
this->PrintAsApplicationFileSystem(ctx.app_ctx);
}
AMS_UNUSED(ctx);