From e0cf57d8a53d1eb455d9b3e1f31dcb5eaa78414f Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Mon, 21 Mar 2022 03:19:39 +0100 Subject: [PATCH] nca: SparseInfo support (part 2). Handle the has_sparse_flag wherever needed. --- include/core/nca.h | 2 +- source/core/nca.c | 8 ++++---- source/core/pfs.c | 2 +- source/core/romfs.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/core/nca.h b/include/core/nca.h index 6d42a4f..de62d76 100644 --- a/include/core/nca.h +++ b/include/core/nca.h @@ -450,7 +450,7 @@ bool ncaReadAesCtrExStorageFromBktrSection(NcaFsSectionContext *ctx, void *out, /// Input offset must be relative to the start of the NCA FS section. /// Output size and offset are guaranteed to be aligned to the AES sector size used by the encryption type from the FS section. /// Output offset is relative to the start of the NCA content file, making it easier to use the output encrypted block to seamlessly replace data while dumping a NCA. -/// This function isn't compatible with Patch RomFS sections. +/// This function doesn't support Patch RomFS sections, nor sections with Sparse and/or Compressed storage. /// Used internally by both ncaGenerateHierarchicalSha256Patch() and ncaGenerateHierarchicalIntegrityPatch(). void *ncaGenerateEncryptedFsSectionBlock(NcaFsSectionContext *ctx, const void *data, u64 data_size, u64 data_offset, u64 *out_block_size, u64 *out_block_offset); diff --git a/source/core/nca.c b/source/core/nca.c index 1ff2e34..e1006e7 100644 --- a/source/core/nca.c +++ b/source/core/nca.c @@ -390,8 +390,8 @@ bool ncaGenerateHierarchicalIntegrityPatch(NcaFsSectionContext *ctx, const void void ncaWriteHierarchicalIntegrityPatchToMemoryBuffer(NcaContext *ctx, NcaHierarchicalIntegrityPatch *patch, void *buf, u64 buf_size, u64 buf_offset) { - if (!ctx || !*(ctx->content_id_str) || ctx->content_size < NCA_FULL_HEADER_LENGTH || !patch || patch->written || memcmp(patch->content_id.c, ctx->content_id.c, 0x10) != 0 || !buf || !buf_size || \ - (buf_offset + buf_size) > ctx->content_size) return; + if (!ctx || !*(ctx->content_id_str) || ctx->content_size < NCA_FULL_HEADER_LENGTH || !patch || patch->written || memcmp(patch->content_id.c, ctx->content_id.c, 0x10) != 0 || \ + !buf || !buf_size || (buf_offset + buf_size) > ctx->content_size) return; patch->written = true; @@ -1026,7 +1026,7 @@ static bool ncaGenerateHashDataPatch(NcaFsSectionContext *ctx, const void *data, bool success = false; - if (!ctx || !ctx->enabled || !(nca_ctx = (NcaContext*)ctx->nca_ctx) || (!is_integrity_patch && (ctx->header.hash_type != NcaHashType_HierarchicalSha256 || \ + if (!ctx || !ctx->enabled || ctx->has_sparse_layer || !(nca_ctx = (NcaContext*)ctx->nca_ctx) || (!is_integrity_patch && (ctx->header.hash_type != NcaHashType_HierarchicalSha256 || \ !ctx->header.hash_data.hierarchical_sha256_data.hash_block_size || !(layer_count = ctx->header.hash_data.hierarchical_sha256_data.hash_region_count) || \ layer_count > NCA_HIERARCHICAL_SHA256_MAX_REGION_COUNT || !(last_layer_size = ctx->header.hash_data.hierarchical_sha256_data.hash_region[layer_count - 1].size))) || \ (is_integrity_patch && (ctx->header.hash_type != NcaHashType_HierarchicalIntegrity || \ @@ -1251,7 +1251,7 @@ static void *_ncaGenerateEncryptedFsSectionBlock(NcaFsSectionContext *ctx, const u8 *out = NULL; bool success = false; - if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || !ctx->nca_ctx || ctx->section_num >= NCA_FS_HEADER_COUNT || ctx->section_offset < sizeof(NcaHeader) || \ + if (!g_ncaCryptoBuffer || !ctx || !ctx->enabled || ctx->has_sparse_layer || !ctx->nca_ctx || ctx->section_num >= NCA_FS_HEADER_COUNT || ctx->section_offset < sizeof(NcaHeader) || \ ctx->section_type >= NcaFsSectionType_Invalid || ctx->encryption_type == NcaEncryptionType_Auto || ctx->encryption_type >= NcaEncryptionType_AesCtrEx || !data || !data_size || \ (data_offset + data_size) > ctx->section_size || !out_block_size || !out_block_offset) { diff --git a/source/core/pfs.c b/source/core/pfs.c index 42ea745..66a7c5d 100644 --- a/source/core/pfs.c +++ b/source/core/pfs.c @@ -51,7 +51,7 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext * /* Fill context. */ out->nca_fs_ctx = nca_fs_ctx; - if (!ncaValidateHierarchicalSha256Offsets(&(nca_fs_ctx->header.hash_data.hierarchical_sha256_data), nca_fs_ctx->section_size)) + if (!nca_fs_ctx->has_sparse_layer && !ncaValidateHierarchicalSha256Offsets(&(nca_fs_ctx->header.hash_data.hierarchical_sha256_data), nca_fs_ctx->section_size)) { LOG_MSG("Invalid HierarchicalSha256 block!"); goto end; diff --git a/source/core/romfs.c b/source/core/romfs.c index 0db9ed8..9b9a166 100644 --- a/source/core/romfs.c +++ b/source/core/romfs.c @@ -65,7 +65,7 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *nca_ out->offset = hash_region->offset; out->size = hash_region->size; } else { - if (!ncaValidateHierarchicalIntegrityOffsets(&(nca_fs_ctx->header.hash_data.integrity_meta_info), nca_fs_ctx->section_size)) + if (!nca_fs_ctx->has_sparse_layer && !ncaValidateHierarchicalIntegrityOffsets(&(nca_fs_ctx->header.hash_data.integrity_meta_info), nca_fs_ctx->section_size)) { LOG_MSG("Invalid HierarchicalIntegrity block!"); goto end;