mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-26 12:12:02 +00:00
pfs: use new NCA storage interface.
This commit is contained in:
parent
cc17c4a458
commit
c2a8f025b3
7 changed files with 37 additions and 25 deletions
|
@ -61,6 +61,14 @@ bool ncaStorageRead(NcaStorageContext *ctx, void *out, u64 read_size, u64 offset
|
||||||
/// Frees a previously initialized NCA storage context.
|
/// Frees a previously initialized NCA storage context.
|
||||||
void ncaStorageFreeContext(NcaStorageContext *ctx);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#ifndef __PFS_H__
|
#ifndef __PFS_H__
|
||||||
#define __PFS_H__
|
#define __PFS_H__
|
||||||
|
|
||||||
#include "nca.h"
|
#include "nca_storage.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -52,7 +52,7 @@ NXDT_ASSERT(PartitionFileSystemEntry, 0x18);
|
||||||
|
|
||||||
/// Used with Partition FS sections from NCAs.
|
/// Used with Partition FS sections from NCAs.
|
||||||
typedef struct {
|
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 offset; ///< Partition offset (relative to the start of the NCA FS section).
|
||||||
u64 size; ///< Partition size.
|
u64 size; ///< Partition size.
|
||||||
bool is_exefs; ///< ExeFS flag.
|
bool is_exefs; ///< ExeFS flag.
|
||||||
|
@ -106,6 +106,7 @@ bool pfsWriteFileContextHeaderToMemoryBuffer(PartitionFileSystemFileContext *ctx
|
||||||
NX_INLINE void pfsFreeContext(PartitionFileSystemContext *ctx)
|
NX_INLINE void pfsFreeContext(PartitionFileSystemContext *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
|
ncaStorageFreeContext(&(ctx->storage_ctx));
|
||||||
if (ctx->header) free(ctx->header);
|
if (ctx->header) free(ctx->header);
|
||||||
memset(ctx, 0, sizeof(PartitionFileSystemContext));
|
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)
|
NX_INLINE void pfsWriteEntryPatchToMemoryBuffer(PartitionFileSystemContext *ctx, NcaHierarchicalSha256Patch *patch, void *buf, u64 buf_size, u64 buf_offset)
|
||||||
{
|
{
|
||||||
if (!ctx || !ctx->nca_fs_ctx) return;
|
if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx))) return;
|
||||||
ncaWriteHierarchicalSha256PatchToMemoryBuffer((NcaContext*)ctx->nca_fs_ctx->nca_ctx, patch, buf, buf_size, buf_offset);
|
ncaWriteHierarchicalSha256PatchToMemoryBuffer((NcaContext*)ctx->storage_ctx.nca_fs_ctx->nca_ctx, patch, buf, buf_size, buf_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
NX_INLINE void pfsFreeEntryPatch(NcaHierarchicalSha256Patch *patch)
|
NX_INLINE void pfsFreeEntryPatch(NcaHierarchicalSha256Patch *patch)
|
||||||
|
|
|
@ -871,12 +871,12 @@ static bool bktrReadSubStorage(BucketTreeSubStorage *substorage, BucketTreeSubSt
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BucketTreeContext *ctx = (BucketTreeContext*)substorage->bktr_ctx;
|
|
||||||
NcaFsSectionContext *nca_fs_ctx = substorage->nca_fs_ctx;
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if (substorage->type == BucketTreeSubStorageType_Regular)
|
if (substorage->type == BucketTreeSubStorageType_Regular)
|
||||||
{
|
{
|
||||||
|
NcaFsSectionContext *nca_fs_ctx = substorage->nca_fs_ctx;
|
||||||
|
|
||||||
if (params->parent_storage_type == BucketTreeStorageType_AesCtrEx)
|
if (params->parent_storage_type == BucketTreeStorageType_AesCtrEx)
|
||||||
{
|
{
|
||||||
/* Perform a read on the target NCA using AesCtrEx crypto. */
|
/* Perform a read on the target NCA using AesCtrEx crypto. */
|
||||||
|
@ -890,6 +890,7 @@ static bool bktrReadSubStorage(BucketTreeSubStorage *substorage, BucketTreeSubSt
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Perform a read on the target BucketTree storage. */
|
/* Perform a read on the target BucketTree storage. */
|
||||||
|
BucketTreeContext *ctx = (BucketTreeContext*)substorage->bktr_ctx;
|
||||||
success = bktrReadStorage(ctx, params->buffer, params->size, params->offset);
|
success = bktrReadStorage(ctx, params->buffer, params->size, params->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,9 +244,3 @@ end:
|
||||||
|
|
||||||
return success;
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
bool success = false, dump_meta_header = false, dump_acid_header = false, dump_aci_header = false;
|
||||||
PartitionFileSystemEntry *pfs_entry = NULL;
|
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 || \
|
if (!out || !pfs_ctx || !ncaStorageIsValidContext(&(pfs_ctx->storage_ctx)) || !(nca_ctx = (NcaContext*)pfs_ctx->storage_ctx.nca_fs_ctx->nca_ctx) || \
|
||||||
!pfs_ctx->is_exefs || pfs_ctx->header_size <= sizeof(PartitionFileSystemHeader) || !pfs_ctx->header)
|
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!");
|
LOG_MSG("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,8 +35,9 @@ bool nsoInitializeContext(NsoContext *out, PartitionFileSystemContext *pfs_ctx,
|
||||||
u8 *rodata_buf = NULL;
|
u8 *rodata_buf = NULL;
|
||||||
bool success = false, dump_nso_header = false;
|
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 || \
|
if (!out || !pfs_ctx || !ncaStorageIsValidContext(&(pfs_ctx->storage_ctx)) || !(nca_ctx = (NcaContext*)pfs_ctx->storage_ctx.nca_fs_ctx->nca_ctx) || \
|
||||||
!pfs_ctx->is_exefs || pfs_ctx->header_size <= sizeof(PartitionFileSystemHeader) || !pfs_ctx->header || !pfs_entry)
|
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!");
|
LOG_MSG("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -46,9 +46,15 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext *
|
||||||
/* Free output context beforehand. */
|
/* Free output context beforehand. */
|
||||||
pfsFreeContext(out);
|
pfsFreeContext(out);
|
||||||
|
|
||||||
/* Fill context. */
|
/* Initialize NCA storage context. */
|
||||||
out->nca_fs_ctx = nca_fs_ctx;
|
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)))
|
if (!ncaGetFsSectionHashTargetProperties(nca_fs_ctx, &(out->offset), &(out->size)))
|
||||||
{
|
{
|
||||||
LOG_MSG("Failed to get target hash layer properties!");
|
LOG_MSG("Failed to get target hash layer properties!");
|
||||||
|
@ -56,7 +62,7 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read partial Partition FS header. */
|
/* 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!");
|
LOG_MSG("Failed to read partial Partition FS header!");
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -89,7 +95,7 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read full Partition FS header. */
|
/* 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!");
|
LOG_MSG("Failed to read full Partition FS header!");
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -115,14 +121,14 @@ end:
|
||||||
|
|
||||||
bool pfsReadPartitionData(PartitionFileSystemContext *ctx, void *out, u64 read_size, u64 offset)
|
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!");
|
LOG_MSG("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read partition data. */
|
/* 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!");
|
LOG_MSG("Failed to read Partition FS data!");
|
||||||
return false;
|
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)
|
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 || \
|
if (!ctx || !ncaStorageIsValidContext(&(ctx->storage_ctx)) || !ctx->header_size || !ctx->header || !fs_entry || !fs_entry->size || \
|
||||||
(data_offset + data_size) > fs_entry->size || !out)
|
(fs_entry->offset + fs_entry->size) > ctx->size || !data || !data_size || (data_offset + data_size) > fs_entry->size || !out)
|
||||||
{
|
{
|
||||||
LOG_MSG("Invalid parameters!");
|
LOG_MSG("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
|
@ -229,7 +235,7 @@ bool pfsGenerateEntryPatch(PartitionFileSystemContext *ctx, PartitionFileSystemE
|
||||||
|
|
||||||
u64 partition_offset = (ctx->header_size + fs_entry->offset + data_offset);
|
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);
|
LOG_MSG("Failed to generate 0x%lX bytes HierarchicalSha256 patch at offset 0x%lX for Partition FS entry!", data_size, partition_offset);
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue