mirror of
https://github.com/Atmosphere-NX/hac2l.git
synced 2025-06-21 11:12:39 +02:00
hac2l: support printing the program nca's info inside an appfs/xci
This commit is contained in:
parent
65843dec94
commit
e0d1b3affd
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user