From dccb33ab0c33a1d90c4f4bba7b276b4fad0e286a Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Fri, 24 Apr 2020 14:42:16 -0400 Subject: [PATCH] PFS0 read improved. --- source/main.c | 18 ++++-------------- source/pfs0.c | 28 ++++++++++++++++++++++++---- source/pfs0.h | 10 +++------- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/source/main.c b/source/main.c index 6f00495..7d646f8 100644 --- a/source/main.c +++ b/source/main.c @@ -220,32 +220,22 @@ int main(int argc, char *argv[]) printf("pfs0 get entry by name succeeded\n"); consoleUpdate(NULL); - u64 main_npdm_offset = 0; - if (!pfs0GetEntryDataOffset(&pfs0_ctx, pfs0_entry, &main_npdm_offset)) - { - printf("pfs0 get entry data offset failed\n"); - goto out2; - } - - printf("main.npdm offset = 0x%lX\n", main_npdm_offset); - consoleUpdate(NULL); - tmp_file = fopen("sdmc:/nxdt_test/main.npdm", "wb"); if (tmp_file) { u64 blksize = 0x400000; u64 total = pfs0_entry->size; - printf("main.npdm created: 0x%lX\n", total); + printf("main.npdm created. Target size -> 0x%lX\n", total); consoleUpdate(NULL); for(u64 curpos = 0; curpos < total; curpos += blksize) { if (blksize > (total - curpos)) blksize = (total - curpos); - if (!ncaReadFsSection(pfs0_ctx.nca_fs_ctx, buf, blksize, main_npdm_offset + curpos)) + if (!pfs0ReadEntryData(&pfs0_ctx, pfs0_entry, buf, blksize, 0)) { - printf("nca read section failed\n"); + printf("pfs0 read entry data failed\n"); goto out2; } @@ -255,7 +245,7 @@ int main(int argc, char *argv[]) fclose(tmp_file); tmp_file = NULL; - printf("nca read main.npdm success\n"); + printf("pfs0 read main.npdm success\n"); } else { printf("main.npdm not created\n"); } diff --git a/source/pfs0.c b/source/pfs0.c index 8a1eea1..d4efc2b 100644 --- a/source/pfs0.c +++ b/source/pfs0.c @@ -58,8 +58,6 @@ bool pfs0InitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext /* Read partial PFS0 header */ u32 magic = 0; PartitionFileSystemHeader pfs0_header = {0}; - - u64 main_npdm_offset = 0; PartitionFileSystemEntry *main_npdm_entry = NULL; if (!ncaReadFsSection(nca_fs_ctx, &pfs0_header, sizeof(PartitionFileSystemHeader), out->offset)) @@ -100,8 +98,30 @@ bool pfs0InitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext } /* Check if we're dealing with an ExeFS section */ - if ((main_npdm_entry = pfs0GetEntryByName(out, "main.npdm")) != NULL && pfs0GetEntryDataOffset(out, main_npdm_entry, &main_npdm_offset) && \ - ncaReadFsSection(out->nca_fs_ctx, &magic, sizeof(u32), main_npdm_offset) && __builtin_bswap32(magic) == NPDM_META_MAGIC) out->is_exefs = true; + if ((main_npdm_entry = pfs0GetEntryByName(out, "main.npdm")) != NULL && pfs0ReadEntryData(out, main_npdm_entry, &magic, sizeof(u32), 0) && \ + __builtin_bswap32(magic) == NPDM_META_MAGIC) out->is_exefs = true; + + return true; +} + +bool pfs0ReadEntryData(PartitionFileSystemContext *ctx, PartitionFileSystemEntry *fs_entry, void *out, u64 read_size, u64 offset) +{ + if (!ctx || !ctx->nca_fs_ctx || !ctx->hash_info || !ctx->size || !ctx->header_size || !ctx->header || !fs_entry || fs_entry->offset >= ctx->size || \ + (fs_entry->offset + fs_entry->size) > ctx->size || !out || !read_size || offset >= fs_entry->size || (offset + read_size) > fs_entry->size) + { + LOGFILE("Invalid parameters!"); + return false; + } + + /* Calculate offset relative to the start of the NCA FS section */ + u64 section_offset = (ctx->offset + ctx->header_size + fs_entry->offset + offset); + + /* Read entry data */ + if (!ncaReadFsSection(ctx->nca_fs_ctx, out, read_size, section_offset)) + { + LOGFILE("Failed to read PFS0 entry data!"); + return false; + } return true; } diff --git a/source/pfs0.h b/source/pfs0.h index 7470ee7..e0cd171 100644 --- a/source/pfs0.h +++ b/source/pfs0.h @@ -59,6 +59,9 @@ static inline void pfs0FreeContext(PartitionFileSystemContext *ctx) memset(ctx, 0, sizeof(PartitionFileSystemContext)); } +/// Reads data from a previously retrieved PartitionFileSystemEntry using a PFS0 context. +bool pfs0ReadEntryData(PartitionFileSystemContext *ctx, PartitionFileSystemEntry *fs_entry, void *out, u64 read_size, u64 offset); + /// Miscellaneous functions. static inline u32 pfs0GetEntryCount(PartitionFileSystemContext *ctx) @@ -67,13 +70,6 @@ static inline u32 pfs0GetEntryCount(PartitionFileSystemContext *ctx) return ((PartitionFileSystemHeader*)ctx->header)->entry_count; } -static inline bool pfs0GetEntryDataOffset(PartitionFileSystemContext *ctx, PartitionFileSystemEntry *fs_entry, u64 *out_offset) -{ - if (!ctx || !ctx->header_size || !ctx->header || !fs_entry || !out_offset) return false; - *out_offset = (ctx->offset + ctx->header_size + fs_entry->offset); /* Relative to the start of the NCA FS section */ - return true; -} - static inline PartitionFileSystemEntry *pfs0GetEntryByIndex(PartitionFileSystemContext *ctx, u32 idx) { if (idx >= pfs0GetEntryCount(ctx)) return NULL;