mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-09 12:11:44 +00:00
nca: fix impl issues in ncaInitializeContextCommon()
Other changes include: * cnmt, nca: handle NcmContentId elements in a more uniform way. * gamecard: add some comments to the GameCardFlags enum. * nxdt_log: make sure log messages are horizontally aligned.
This commit is contained in:
parent
a06a511ce7
commit
89b211c146
4 changed files with 34 additions and 40 deletions
|
@ -172,8 +172,8 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GameCardFlags_None = 0,
|
GameCardFlags_None = 0,
|
||||||
GameCardFlags_AutoBoot = BIT(0),
|
GameCardFlags_AutoBoot = BIT(0), ///< The gamecard is capable of autobooting if it's inserted into the console before powering it up.
|
||||||
GameCardFlags_HistoryErase = BIT(1),
|
GameCardFlags_HistoryErase = BIT(1), ///< Inserting the gamecard won't add any permanent icons to the HOME menu.
|
||||||
GameCardFlags_RepairTool = BIT(2),
|
GameCardFlags_RepairTool = BIT(2),
|
||||||
GameCardFlags_DifferentRegionCupToTerraDevice = BIT(3),
|
GameCardFlags_DifferentRegionCupToTerraDevice = BIT(3),
|
||||||
GameCardFlags_DifferentRegionCupToGlobalDevice = BIT(4),
|
GameCardFlags_DifferentRegionCupToGlobalDevice = BIT(4),
|
||||||
|
|
|
@ -289,7 +289,7 @@ bool cnmtVerifyContentHash(ContentMetaContext *cnmt_ctx, NcaContext *nca_ctx, co
|
||||||
/* Check if we got a matching content ID. */
|
/* Check if we got a matching content ID. */
|
||||||
packaged_content_info = &(cnmt_ctx->packaged_content_info[i]);
|
packaged_content_info = &(cnmt_ctx->packaged_content_info[i]);
|
||||||
|
|
||||||
if (!memcmp(packaged_content_info->info.content_id.c, nca_ctx->content_id.c, sizeof(nca_ctx->content_id.c))) break;
|
if (!memcmp(&(packaged_content_info->info.content_id), &(nca_ctx->content_id), sizeof(NcmContentId))) break;
|
||||||
|
|
||||||
packaged_content_info = NULL;
|
packaged_content_info = NULL;
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
|
||||||
/* Non-Meta NCAs: check if their content IDs are part of the packaged content info entries from the CNMT. */
|
/* Non-Meta NCAs: check if their content IDs are part of the packaged content info entries from the CNMT. */
|
||||||
for(j = 0; j < cnmt_ctx->packaged_header->content_count; j++)
|
for(j = 0; j < cnmt_ctx->packaged_header->content_count; j++)
|
||||||
{
|
{
|
||||||
if (!memcmp(cnmt_ctx->packaged_content_info[j].info.content_id.c, cur_nca_ctx->content_id.c, 0x10)) break;
|
if (!memcmp(&(cnmt_ctx->packaged_content_info[j].info.content_id), &(cur_nca_ctx->content_id), sizeof(NcmContentId))) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
invalid_nca = (j >= cnmt_ctx->packaged_header->content_count);
|
invalid_nca = (j >= cnmt_ctx->packaged_header->content_count);
|
||||||
|
|
|
@ -127,7 +127,7 @@ static const u8 g_nca0KeyAreaHash[SHA256_HASH_SIZE] = {
|
||||||
|
|
||||||
/* Function prototypes. */
|
/* Function prototypes. */
|
||||||
|
|
||||||
static bool ncaInitializeContextCommon(NcaContext *out, u8 storage_id, NcmContentStorage *ncm_storage, Ticket *tik);
|
static bool ncaInitializeContextCommon(NcaContext *out, u8 storage_id, u8 hfs_partition_type, NcmContentStorage *ncm_storage, Ticket *tik);
|
||||||
|
|
||||||
NX_INLINE bool ncaIsFsInfoEntryValid(NcaFsInfo *fs_info);
|
NX_INLINE bool ncaIsFsInfoEntryValid(NcaFsInfo *fs_info);
|
||||||
|
|
||||||
|
@ -198,6 +198,7 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
||||||
out->title_type = meta_key->type;
|
out->title_type = meta_key->type;
|
||||||
|
|
||||||
memcpy(&(out->content_id), &(content_info->content_id), sizeof(NcmContentId));
|
memcpy(&(out->content_id), &(content_info->content_id), sizeof(NcmContentId));
|
||||||
|
utilsGenerateHexString(out->content_id_str, sizeof(out->content_id_str), out->content_id.c, sizeof(out->content_id.c), false);
|
||||||
|
|
||||||
ncmContentInfoSizeToU64(content_info, &(out->content_size));
|
ncmContentInfoSizeToU64(content_info, &(out->content_size));
|
||||||
utilsGenerateFormattedSizeString((double)out->content_size, out->content_size_str, sizeof(out->content_size_str));
|
utilsGenerateFormattedSizeString((double)out->content_size, out->content_size_str, sizeof(out->content_size_str));
|
||||||
|
@ -211,21 +212,7 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out->storage_id == NcmStorageId_GameCard)
|
return ncaInitializeContextCommon(out, storage_id, hfs_partition_type, ncm_storage, tik);
|
||||||
{
|
|
||||||
/* Generate gamecard NCA filename. */
|
|
||||||
char nca_filename[0x30] = {0};
|
|
||||||
sprintf(nca_filename, "%s.%s", out->content_id_str, out->content_type == NcmContentType_Meta ? "cnmt.nca" : "nca");
|
|
||||||
|
|
||||||
/* Retrieve gamecard NCA offset. */
|
|
||||||
if (!gamecardGetHashFileSystemEntryInfoByName(hfs_partition_type, nca_filename, &(out->gamecard_offset), NULL))
|
|
||||||
{
|
|
||||||
LOG_MSG_ERROR("Error retrieving offset for \"%s\" entry in secure hash FS partition!", nca_filename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ncaInitializeContextCommon(out, storage_id, ncm_storage, tik);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ncaInitializeContextByHashFileSystemEntry(NcaContext *out, HashFileSystemContext *hfs_ctx, HashFileSystemEntry *hfs_entry, Ticket *tik)
|
bool ncaInitializeContextByHashFileSystemEntry(NcaContext *out, HashFileSystemContext *hfs_ctx, HashFileSystemEntry *hfs_entry, Ticket *tik)
|
||||||
|
@ -254,21 +241,16 @@ bool ncaInitializeContextByHashFileSystemEntry(NcaContext *out, HashFileSystemCo
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill NCA context. */
|
/* Fill NCA context. */
|
||||||
utilsParseHexString(&(out->content_id), sizeof(out->content_id), hfs_entry_name, NCA_CONTENT_ID_STR_LENGTH);
|
utilsParseHexString(out->content_id.c, sizeof(out->content_id.c), hfs_entry_name, NCA_CONTENT_ID_STR_LENGTH);
|
||||||
|
snprintf(out->content_id_str, sizeof(out->content_id_str), "%.*s", NCA_CONTENT_ID_STR_LENGTH, hfs_entry_name);
|
||||||
|
//LOG_DATA_DEBUG(&(out->content_id), sizeof(NcmContentId), "Parsed ID (%s):", out->content_id_str);
|
||||||
|
|
||||||
out->content_size = hfs_entry->size;
|
out->content_size = hfs_entry->size;
|
||||||
utilsGenerateFormattedSizeString((double)out->content_size, out->content_size_str, sizeof(out->content_size_str));
|
utilsGenerateFormattedSizeString((double)out->content_size, out->content_size_str, sizeof(out->content_size_str));
|
||||||
|
|
||||||
if (hfs_entry_name_len == NCA_HFS_META_NAME_LENGTH) out->content_type = NcmContentType_Meta; /* Set Meta as the content type if we know it. */
|
if (hfs_entry_name_len == NCA_HFS_META_NAME_LENGTH) out->content_type = NcmContentType_Meta; /* Set Meta as the content type if we know it. */
|
||||||
|
|
||||||
/* Retrieve gamecard NCA offset. */
|
return ncaInitializeContextCommon(out, NcmStorageId_GameCard, hfs_ctx->type, NULL, tik);
|
||||||
if (!gamecardGetHashFileSystemEntryInfoByName(hfs_ctx->type, hfs_entry_name, &(out->gamecard_offset), NULL))
|
|
||||||
{
|
|
||||||
LOG_MSG_ERROR("Error retrieving offset for \"%s\" entry in %s hash FS partition!", hfs_entry_name, hfsGetPartitionNameString(hfs_ctx->type));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ncaInitializeContextCommon(out, NcmStorageId_GameCard, NULL, tik);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ncaReadContentFile(NcaContext *ctx, void *out, u64 read_size, u64 offset)
|
bool ncaReadContentFile(NcaContext *ctx, void *out, u64 read_size, u64 offset)
|
||||||
|
@ -365,7 +347,7 @@ bool ncaGenerateHierarchicalSha256Patch(NcaFsSectionContext *ctx, const void *da
|
||||||
void ncaWriteHierarchicalSha256PatchToMemoryBuffer(NcaContext *ctx, NcaHierarchicalSha256Patch *patch, void *buf, u64 buf_size, u64 buf_offset)
|
void ncaWriteHierarchicalSha256PatchToMemoryBuffer(NcaContext *ctx, NcaHierarchicalSha256Patch *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 || \
|
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, sizeof(NcmContentId)) != 0 || !patch->hash_region_count || \
|
memcmp(&(patch->content_id), &(ctx->content_id), sizeof(NcmContentId)) != 0 || !patch->hash_region_count || \
|
||||||
patch->hash_region_count > NCA_HIERARCHICAL_SHA256_MAX_REGION_COUNT || !buf || !buf_size || (buf_offset + buf_size) > ctx->content_size) return;
|
patch->hash_region_count > NCA_HIERARCHICAL_SHA256_MAX_REGION_COUNT || !buf || !buf_size || (buf_offset + buf_size) > ctx->content_size) return;
|
||||||
|
|
||||||
patch->written = true;
|
patch->written = true;
|
||||||
|
@ -390,7 +372,7 @@ bool ncaGenerateHierarchicalIntegrityPatch(NcaFsSectionContext *ctx, const void
|
||||||
void ncaWriteHierarchicalIntegrityPatchToMemoryBuffer(NcaContext *ctx, NcaHierarchicalIntegrityPatch *patch, void *buf, u64 buf_size, u64 buf_offset)
|
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 || \
|
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, sizeof(NcmContentId)) != 0 || !buf || !buf_size || (buf_offset + buf_size) > ctx->content_size) return;
|
memcmp(&(patch->content_id), &(ctx->content_id), sizeof(NcmContentId)) != 0 || !buf || !buf_size || (buf_offset + buf_size) > ctx->content_size) return;
|
||||||
|
|
||||||
patch->written = true;
|
patch->written = true;
|
||||||
|
|
||||||
|
@ -578,9 +560,9 @@ const char *ncaGetFsSectionTypeName(NcaFsSectionContext *ctx)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ncaInitializeContextCommon(NcaContext *out, u8 storage_id, NcmContentStorage *ncm_storage, Ticket *tik)
|
static bool ncaInitializeContextCommon(NcaContext *out, u8 storage_id, u8 hfs_partition_type, NcmContentStorage *ncm_storage, Ticket *tik)
|
||||||
{
|
{
|
||||||
if (!out || out->content_size < NCA_FULL_HEADER_LENGTH)
|
if (!out || !*(out->content_id_str) || out->content_size < NCA_FULL_HEADER_LENGTH || (storage_id != NcmStorageId_GameCard && !ncm_storage))
|
||||||
{
|
{
|
||||||
LOG_MSG_ERROR("Invalid parameters!");
|
LOG_MSG_ERROR("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
|
@ -592,10 +574,22 @@ static bool ncaInitializeContextCommon(NcaContext *out, u8 storage_id, NcmConten
|
||||||
out->storage_id = storage_id;
|
out->storage_id = storage_id;
|
||||||
out->ncm_storage = (out->storage_id != NcmStorageId_GameCard ? ncm_storage : NULL);
|
out->ncm_storage = (out->storage_id != NcmStorageId_GameCard ? ncm_storage : NULL);
|
||||||
|
|
||||||
utilsGenerateHexString(out->content_id_str, sizeof(out->content_id_str), out->content_id.c, sizeof(out->content_id.c), false);
|
|
||||||
|
|
||||||
utilsGenerateHexString(out->hash_str, sizeof(out->hash_str), out->hash, sizeof(out->hash), false); /* Placeholder, needs to be manually calculated. */
|
utilsGenerateHexString(out->hash_str, sizeof(out->hash_str), out->hash, sizeof(out->hash), false); /* Placeholder, needs to be manually calculated. */
|
||||||
|
|
||||||
|
if (storage_id == NcmStorageId_GameCard)
|
||||||
|
{
|
||||||
|
/* Generate gamecard NCA filename. */
|
||||||
|
char nca_filename[0x30] = {0};
|
||||||
|
sprintf(nca_filename, "%s.%s", out->content_id_str, out->content_type == NcmContentType_Meta ? "cnmt.nca" : "nca");
|
||||||
|
|
||||||
|
/* Retrieve gamecard NCA offset. */
|
||||||
|
if (!gamecardGetHashFileSystemEntryInfoByName(hfs_partition_type, nca_filename, &(out->gamecard_offset), NULL))
|
||||||
|
{
|
||||||
|
LOG_MSG_ERROR("Error retrieving offset for \"%s\" entry in %s hash FS partition!", nca_filename, hfsGetPartitionNameString(hfs_partition_type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Read decrypted NCA header and NCA FS section headers. */
|
/* Read decrypted NCA header and NCA FS section headers. */
|
||||||
if (!ncaReadDecryptedHeader(out))
|
if (!ncaReadDecryptedHeader(out))
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,14 +35,14 @@ static s64 g_logFileOffset = 0;
|
||||||
static char *g_logBuffer = NULL;
|
static char *g_logBuffer = NULL;
|
||||||
static size_t g_logBufferLength = 0;
|
static size_t g_logBufferLength = 0;
|
||||||
|
|
||||||
static const char *g_logStrFormat = "[%d-%02d-%02d %02d:%02d:%02d.%09lu] [%s] %s|%d|%s -> ";
|
static const char *g_logStrFormat = "[%d-%02d-%02d %02d:%02d:%02d.%09lu] %s %s|%d|%s -> ";
|
||||||
static const char *g_logSessionSeparator = "________________________________________________________________\r\n";
|
static const char *g_logSessionSeparator = "________________________________________________________________\r\n";
|
||||||
|
|
||||||
static const char *g_logLevelNames[] = {
|
static const char *g_logLevelNames[] = {
|
||||||
[LOG_LEVEL_DEBUG] = "DEBUG",
|
[LOG_LEVEL_DEBUG] = "[DEBUG] ",
|
||||||
[LOG_LEVEL_INFO] = "INFO",
|
[LOG_LEVEL_INFO] = "[INFO] ",
|
||||||
[LOG_LEVEL_WARNING] = "WARNING",
|
[LOG_LEVEL_WARNING] = "[WARNING]",
|
||||||
[LOG_LEVEL_ERROR] = "ERROR"
|
[LOG_LEVEL_ERROR] = "[ERROR] "
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function prototypes. */
|
/* Function prototypes. */
|
||||||
|
|
Loading…
Reference in a new issue