From c2a8f025b35d86c151fe39ecac9c40d2954d3ba0 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Mon, 4 Jul 2022 01:36:01 +0200 Subject: [PATCH] pfs: use new NCA storage interface. --- include/core/nca_storage.h | 8 ++++++++ include/core/pfs.h | 9 +++++---- source/core/bktr.c | 5 +++-- source/core/nca_storage.c | 6 ------ source/core/npdm.c | 5 +++-- source/core/nso.c | 5 +++-- source/core/pfs.c | 24 +++++++++++++++--------- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/include/core/nca_storage.h b/include/core/nca_storage.h index d6ef9af..38cd341 100644 --- a/include/core/nca_storage.h +++ b/include/core/nca_storage.h @@ -61,6 +61,14 @@ bool ncaStorageRead(NcaStorageContext *ctx, void *out, u64 read_size, u64 offset /// Frees a previously initialized NCA storage context. void ncaStorageFreeContext(NcaStorageContext *ctx); +/// Helper inline functions. + +NX_INLINE bool ncaStorageIsValidContext(NcaStorageContext *ctx) +{ + return (ctx && ctx->base_storage_type >= NcaStorageBaseStorageType_Regular && ctx->base_storage_type <= NcaStorageBaseStorageType_Compressed && ctx->nca_fs_ctx && \ + ctx->nca_fs_ctx->enabled); +} + #ifdef __cplusplus } #endif diff --git a/include/core/pfs.h b/include/core/pfs.h index 44f45fe..e9570dd 100644 --- a/include/core/pfs.h +++ b/include/core/pfs.h @@ -24,7 +24,7 @@ #ifndef __PFS_H__ #define __PFS_H__ -#include "nca.h" +#include "nca_storage.h" #ifdef __cplusplus extern "C" { @@ -52,7 +52,7 @@ NXDT_ASSERT(PartitionFileSystemEntry, 0x18); /// Used with Partition FS sections from NCAs. typedef struct { - NcaFsSectionContext *nca_fs_ctx; ///< Used to read NCA FS section data. + NcaStorageContext storage_ctx; ///< Used to read NCA FS section data. u64 offset; ///< Partition offset (relative to the start of the NCA FS section). u64 size; ///< Partition size. bool is_exefs; ///< ExeFS flag. @@ -106,6 +106,7 @@ bool pfsWriteFileContextHeaderToMemoryBuffer(PartitionFileSystemFileContext *ctx NX_INLINE void pfsFreeContext(PartitionFileSystemContext *ctx) { if (!ctx) return; + ncaStorageFreeContext(&(ctx->storage_ctx)); if (ctx->header) free(ctx->header); memset(ctx, 0, sizeof(PartitionFileSystemContext)); } @@ -153,8 +154,8 @@ NX_INLINE PartitionFileSystemEntry *pfsGetEntryByName(PartitionFileSystemContext NX_INLINE void pfsWriteEntryPatchToMemoryBuffer(PartitionFileSystemContext *ctx, NcaHierarchicalSha256Patch *patch, void *buf, u64 buf_size, u64 buf_offset) { - if (!ctx || !ctx->nca_fs_ctx) return; - ncaWriteHierarchicalSha256PatchToMemoryBuffer((NcaContext*)ctx->nca_fs_ctx->nca_ctx, patch, buf, buf_size, buf_offset); + if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx))) return; + ncaWriteHierarchicalSha256PatchToMemoryBuffer((NcaContext*)ctx->storage_ctx.nca_fs_ctx->nca_ctx, patch, buf, buf_size, buf_offset); } NX_INLINE void pfsFreeEntryPatch(NcaHierarchicalSha256Patch *patch) diff --git a/source/core/bktr.c b/source/core/bktr.c index 149c69c..62af187 100644 --- a/source/core/bktr.c +++ b/source/core/bktr.c @@ -871,12 +871,12 @@ static bool bktrReadSubStorage(BucketTreeSubStorage *substorage, BucketTreeSubSt return false; } - BucketTreeContext *ctx = (BucketTreeContext*)substorage->bktr_ctx; - NcaFsSectionContext *nca_fs_ctx = substorage->nca_fs_ctx; bool success = false; if (substorage->type == BucketTreeSubStorageType_Regular) { + NcaFsSectionContext *nca_fs_ctx = substorage->nca_fs_ctx; + if (params->parent_storage_type == BucketTreeStorageType_AesCtrEx) { /* Perform a read on the target NCA using AesCtrEx crypto. */ @@ -890,6 +890,7 @@ static bool bktrReadSubStorage(BucketTreeSubStorage *substorage, BucketTreeSubSt } } else { /* Perform a read on the target BucketTree storage. */ + BucketTreeContext *ctx = (BucketTreeContext*)substorage->bktr_ctx; success = bktrReadStorage(ctx, params->buffer, params->size, params->offset); } diff --git a/source/core/nca_storage.c b/source/core/nca_storage.c index 23e53c5..1940a21 100644 --- a/source/core/nca_storage.c +++ b/source/core/nca_storage.c @@ -244,9 +244,3 @@ end: return success; } - -NX_INLINE bool ncaStorageIsValidContext(NcaStorageContext *ctx) -{ - return (ctx && ctx->base_storage_type >= NcaStorageBaseStorageType_Regular && ctx->base_storage_type <= NcaStorageBaseStorageType_Compressed && ctx->nca_fs_ctx && \ - ctx->nca_fs_ctx->enabled); -} diff --git a/source/core/npdm.c b/source/core/npdm.c index 633ea29..7ef1d99 100644 --- a/source/core/npdm.c +++ b/source/core/npdm.c @@ -30,8 +30,9 @@ bool npdmInitializeContext(NpdmContext *out, PartitionFileSystemContext *pfs_ctx bool success = false, dump_meta_header = false, dump_acid_header = false, dump_aci_header = false; PartitionFileSystemEntry *pfs_entry = NULL; - if (!out || !pfs_ctx || !pfs_ctx->nca_fs_ctx || !(nca_ctx = (NcaContext*)pfs_ctx->nca_fs_ctx->nca_ctx) || nca_ctx->content_type != NcmContentType_Program || !pfs_ctx->offset || !pfs_ctx->size || \ - !pfs_ctx->is_exefs || pfs_ctx->header_size <= sizeof(PartitionFileSystemHeader) || !pfs_ctx->header) + if (!out || !pfs_ctx || !ncaStorageIsValidContext(&(pfs_ctx->storage_ctx)) || !(nca_ctx = (NcaContext*)pfs_ctx->storage_ctx.nca_fs_ctx->nca_ctx) || \ + nca_ctx->content_type != NcmContentType_Program || !pfs_ctx->offset || !pfs_ctx->size || !pfs_ctx->is_exefs || \ + pfs_ctx->header_size <= sizeof(PartitionFileSystemHeader) || !pfs_ctx->header) { LOG_MSG("Invalid parameters!"); return false; diff --git a/source/core/nso.c b/source/core/nso.c index 0d51973..1383fa8 100644 --- a/source/core/nso.c +++ b/source/core/nso.c @@ -35,8 +35,9 @@ bool nsoInitializeContext(NsoContext *out, PartitionFileSystemContext *pfs_ctx, u8 *rodata_buf = NULL; bool success = false, dump_nso_header = false; - if (!out || !pfs_ctx || !pfs_ctx->nca_fs_ctx || !(nca_ctx = (NcaContext*)pfs_ctx->nca_fs_ctx->nca_ctx) || nca_ctx->content_type != NcmContentType_Program || !pfs_ctx->offset || !pfs_ctx->size || \ - !pfs_ctx->is_exefs || pfs_ctx->header_size <= sizeof(PartitionFileSystemHeader) || !pfs_ctx->header || !pfs_entry) + if (!out || !pfs_ctx || !ncaStorageIsValidContext(&(pfs_ctx->storage_ctx)) || !(nca_ctx = (NcaContext*)pfs_ctx->storage_ctx.nca_fs_ctx->nca_ctx) || \ + nca_ctx->content_type != NcmContentType_Program || !pfs_ctx->offset || !pfs_ctx->size || !pfs_ctx->is_exefs || \ + pfs_ctx->header_size <= sizeof(PartitionFileSystemHeader) || !pfs_ctx->header || !pfs_entry) { LOG_MSG("Invalid parameters!"); return false; diff --git a/source/core/pfs.c b/source/core/pfs.c index 0595ad4..c6ff3b3 100644 --- a/source/core/pfs.c +++ b/source/core/pfs.c @@ -46,9 +46,15 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext * /* Free output context beforehand. */ pfsFreeContext(out); - /* Fill context. */ - out->nca_fs_ctx = nca_fs_ctx; + /* Initialize NCA storage context. */ + NcaStorageContext *storage_ctx = &(out->storage_ctx); + if (!ncaStorageInitializeContext(storage_ctx, nca_fs_ctx)) + { + LOG_MSG("Failed to initialize NCA storage context!"); + goto end; + } + /* Get Partition FS offset and size. */ if (!ncaGetFsSectionHashTargetProperties(nca_fs_ctx, &(out->offset), &(out->size))) { LOG_MSG("Failed to get target hash layer properties!"); @@ -56,7 +62,7 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext * } /* Read partial Partition FS header. */ - if (!ncaReadFsSection(nca_fs_ctx, &pfs_header, sizeof(PartitionFileSystemHeader), out->offset)) + if (!ncaStorageRead(storage_ctx, &pfs_header, sizeof(PartitionFileSystemHeader), out->offset)) { LOG_MSG("Failed to read partial Partition FS header!"); goto end; @@ -89,7 +95,7 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext * } /* Read full Partition FS header. */ - if (!ncaReadFsSection(nca_fs_ctx, out->header, out->header_size, out->offset)) + if (!ncaStorageRead(storage_ctx, out->header, out->header_size, out->offset)) { LOG_MSG("Failed to read full Partition FS header!"); goto end; @@ -115,14 +121,14 @@ end: bool pfsReadPartitionData(PartitionFileSystemContext *ctx, void *out, u64 read_size, u64 offset) { - if (!ctx || !ctx->nca_fs_ctx || !ctx->size || !out || !read_size || (offset + read_size) > ctx->size) + if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || !ctx->size || !out || !read_size || (offset + read_size) > ctx->size) { LOG_MSG("Invalid parameters!"); return false; } /* Read partition data. */ - if (!ncaReadFsSection(ctx->nca_fs_ctx, out, read_size, ctx->offset + offset)) + if (!ncaStorageRead(&(ctx->storage_ctx), out, read_size, ctx->offset + offset)) { LOG_MSG("Failed to read Partition FS data!"); return false; @@ -220,8 +226,8 @@ bool pfsGetTotalDataSize(PartitionFileSystemContext *ctx, u64 *out_size) bool pfsGenerateEntryPatch(PartitionFileSystemContext *ctx, PartitionFileSystemEntry *fs_entry, const void *data, u64 data_size, u64 data_offset, NcaHierarchicalSha256Patch *out) { - if (!ctx || !ctx->nca_fs_ctx || !ctx->header_size || !ctx->header || !fs_entry || !fs_entry->size || (fs_entry->offset + fs_entry->size) > ctx->size || !data || !data_size || \ - (data_offset + data_size) > fs_entry->size || !out) + if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || !ctx->header_size || !ctx->header || !fs_entry || !fs_entry->size || \ + (fs_entry->offset + fs_entry->size) > ctx->size || !data || !data_size || (data_offset + data_size) > fs_entry->size || !out) { LOG_MSG("Invalid parameters!"); return false; @@ -229,7 +235,7 @@ bool pfsGenerateEntryPatch(PartitionFileSystemContext *ctx, PartitionFileSystemE u64 partition_offset = (ctx->header_size + fs_entry->offset + data_offset); - if (!ncaGenerateHierarchicalSha256Patch(ctx->nca_fs_ctx, data, data_size, partition_offset, out)) + if (!ncaGenerateHierarchicalSha256Patch(ctx->storage_ctx.nca_fs_ctx, data, data_size, partition_offset, out)) { LOG_MSG("Failed to generate 0x%lX bytes HierarchicalSha256 patch at offset 0x%lX for Partition FS entry!", data_size, partition_offset); return false;