From 8ac190686fb88115238c828999e6e2ca68bffc25 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Mon, 4 Jul 2022 02:01:12 +0200 Subject: [PATCH] romfs: use new NCA storage interface. --- include/core/romfs.h | 15 +++++++++------ source/core/pfs.c | 4 ++-- source/core/romfs.c | 40 +++++++++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/include/core/romfs.h b/include/core/romfs.h index cae3861..ecf5b74 100644 --- a/include/core/romfs.h +++ b/include/core/romfs.h @@ -24,7 +24,7 @@ #ifndef __ROMFS_H__ #define __ROMFS_H__ -#include "nca.h" +#include "nca_storage.h" #ifdef __cplusplus extern "C" { @@ -107,7 +107,7 @@ typedef struct { NXDT_ASSERT(RomFileSystemFileEntry, 0x20); 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; ///< RomFS offset (relative to the start of the NCA FS section). u64 size; ///< RomFS size. RomFileSystemHeader header; ///< RomFS header. @@ -174,6 +174,7 @@ bool romfsGenerateFileEntryPatch(RomFileSystemContext *ctx, RomFileSystemFileEnt NX_INLINE void romfsFreeContext(RomFileSystemContext *ctx) { if (!ctx) return; + ncaStorageFreeContext(&(ctx->storage_ctx)); if (ctx->dir_table) free(ctx->dir_table); if (ctx->file_table) free(ctx->file_table); memset(ctx, 0, sizeof(RomFileSystemContext)); @@ -193,15 +194,17 @@ NX_INLINE RomFileSystemFileEntry *romfsGetFileEntryByOffset(RomFileSystemContext NX_INLINE void romfsWriteFileEntryPatchToMemoryBuffer(RomFileSystemContext *ctx, RomFileSystemFileEntryPatch *patch, void *buf, u64 buf_size, u64 buf_offset) { - if (!ctx || !ctx->nca_fs_ctx || !patch || (!patch->use_old_format_patch && ctx->nca_fs_ctx->section_type == NcaFsSectionType_Nca0RomFs) || \ - (patch->use_old_format_patch && ctx->nca_fs_ctx->section_type != NcaFsSectionType_Nca0RomFs)) return; + if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || !patch || (!patch->use_old_format_patch && ctx->storage_ctx.nca_fs_ctx->section_type == NcaFsSectionType_Nca0RomFs) || \ + (patch->use_old_format_patch && ctx->storage_ctx.nca_fs_ctx->section_type != NcaFsSectionType_Nca0RomFs)) return; + + NcaContext *nca_ctx = (NcaContext*)ctx->storage_ctx.nca_fs_ctx->nca_ctx; if (patch->use_old_format_patch) { - ncaWriteHierarchicalSha256PatchToMemoryBuffer((NcaContext*)ctx->nca_fs_ctx->nca_ctx, &(patch->old_format_patch), buf, buf_size, buf_offset); + ncaWriteHierarchicalSha256PatchToMemoryBuffer(nca_ctx, &(patch->old_format_patch), buf, buf_size, buf_offset); patch->written = patch->old_format_patch.written; } else { - ncaWriteHierarchicalIntegrityPatchToMemoryBuffer((NcaContext*)ctx->nca_fs_ctx->nca_ctx, &(patch->cur_format_patch), buf, buf_size, buf_offset); + ncaWriteHierarchicalIntegrityPatchToMemoryBuffer(nca_ctx, &(patch->cur_format_patch), buf, buf_size, buf_offset); patch->written = patch->cur_format_patch.written; } } diff --git a/source/core/pfs.c b/source/core/pfs.c index c6ff3b3..3b630c7 100644 --- a/source/core/pfs.c +++ b/source/core/pfs.c @@ -226,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 || !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) + if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || ctx->storage_ctx.base_storage_type != NcaStorageBaseStorageType_Regular || !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; diff --git a/source/core/romfs.c b/source/core/romfs.c index 3d6b440..e172e2a 100644 --- a/source/core/romfs.c +++ b/source/core/romfs.c @@ -46,9 +46,15 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *nca_ /* Free output context beforehand. */ romfsFreeContext(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 RomFS 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 romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *nca_ } /* Read RomFS header. */ - if (!ncaReadFsSection(nca_fs_ctx, &(out->header), sizeof(RomFileSystemHeader), out->offset)) + if (!ncaStorageRead(storage_ctx, &(out->header), sizeof(RomFileSystemHeader), out->offset)) { LOG_MSG("Failed to read RomFS header!"); goto end; @@ -88,7 +94,7 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *nca_ goto end; } - if (!ncaReadFsSection(nca_fs_ctx, out->dir_table, out->dir_table_size, out->offset + dir_table_offset)) + if (!ncaStorageRead(storage_ctx, out->dir_table, out->dir_table_size, out->offset + dir_table_offset)) { LOG_MSG("Failed to read RomFS directory entries table!"); goto end; @@ -112,7 +118,7 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *nca_ goto end; } - if (!ncaReadFsSection(nca_fs_ctx, out->file_table, out->file_table_size, out->offset + file_table_offset)) + if (!ncaStorageRead(storage_ctx, out->file_table, out->file_table_size, out->offset + file_table_offset)) { LOG_MSG("Failed to read RomFS file entries table!"); goto end; @@ -143,14 +149,14 @@ end: bool romfsReadFileSystemData(RomFileSystemContext *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 filesystem 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 RomFS data!"); return false; @@ -304,14 +310,16 @@ RomFileSystemFileEntry *romfsGetFileEntryByPath(RomFileSystemContext *ctx, const char *path_dup = NULL, *filename = NULL; RomFileSystemFileEntry *file_entry = NULL; RomFileSystemDirectoryEntry *dir_entry = NULL; + NcaContext *nca_ctx = NULL; - if (!ctx || !ctx->file_table || !ctx->file_table_size || !ctx->nca_fs_ctx || !ctx->nca_fs_ctx->nca_ctx || !path || *path != '/' || (path_len = strlen(path)) <= 1) + if (!ctx || !ctx->file_table || !ctx->file_table_size || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || !(nca_ctx = (NcaContext*)ctx->storage_ctx.nca_fs_ctx->nca_ctx) || \ + !path || *path != '/' || (path_len = strlen(path)) <= 1) { LOG_MSG("Invalid parameters!"); return NULL; } - content_type = ((NcaContext*)ctx->nca_fs_ctx->nca_ctx)->content_type; + content_type = nca_ctx->content_type; /* Duplicate path. */ if (!(path_dup = strdup(path))) @@ -496,29 +504,31 @@ bool romfsGeneratePathFromFileEntry(RomFileSystemContext *ctx, RomFileSystemFile bool romfsGenerateFileEntryPatch(RomFileSystemContext *ctx, RomFileSystemFileEntry *file_entry, const void *data, u64 data_size, u64 data_offset, RomFileSystemFileEntryPatch *out) { - if (!ctx || !ctx->nca_fs_ctx || !ctx->body_offset || (ctx->nca_fs_ctx->section_type != NcaFsSectionType_Nca0RomFs && ctx->nca_fs_ctx->section_type != NcaFsSectionType_RomFs) || !file_entry || \ + if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || ctx->storage_ctx.base_storage_type != NcaStorageBaseStorageType_Regular || !ctx->body_offset || \ + (ctx->storage_ctx.nca_fs_ctx->section_type != NcaFsSectionType_Nca0RomFs && ctx->storage_ctx.nca_fs_ctx->section_type != NcaFsSectionType_RomFs) || !file_entry || \ !file_entry->size || (file_entry->offset + file_entry->size) > ctx->size || !data || !data_size || (data_offset + data_size) > file_entry->size || !out) { LOG_MSG("Invalid parameters!"); return false; } - bool success = false; + NcaFsSectionContext *nca_fs_ctx = ctx->storage_ctx.nca_fs_ctx; u64 fs_offset = (ctx->body_offset + file_entry->offset + data_offset); + bool success = false; - if (ctx->nca_fs_ctx->section_type == NcaFsSectionType_Nca0RomFs) + if (nca_fs_ctx->section_type == NcaFsSectionType_Nca0RomFs) { out->use_old_format_patch = true; - success = ncaGenerateHierarchicalSha256Patch(ctx->nca_fs_ctx, data, data_size, fs_offset, &(out->old_format_patch)); + success = ncaGenerateHierarchicalSha256Patch(nca_fs_ctx, data, data_size, fs_offset, &(out->old_format_patch)); } else { out->use_old_format_patch = false; - success = ncaGenerateHierarchicalIntegrityPatch(ctx->nca_fs_ctx, data, data_size, fs_offset, &(out->cur_format_patch)); + success = ncaGenerateHierarchicalIntegrityPatch(nca_fs_ctx, data, data_size, fs_offset, &(out->cur_format_patch)); } out->written = false; if (!success) LOG_MSG("Failed to generate 0x%lX bytes Hierarchical%s patch at offset 0x%lX for RomFS file entry!", data_size, \ - ctx->nca_fs_ctx->section_type == NcaFsSectionType_Nca0RomFs ? "Sha256" : "Integrity", fs_offset); + nca_fs_ctx->section_type == NcaFsSectionType_Nca0RomFs ? "Sha256" : "Integrity", fs_offset); return success; }