From 89b211c1462f9d3552bca8b52dec76a343ba18e9 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Mon, 12 Aug 2024 12:10:34 +0200 Subject: [PATCH] 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. --- include/core/gamecard.h | 4 +-- source/core/cnmt.c | 4 +-- source/core/nca.c | 56 ++++++++++++++++++----------------------- source/core/nxdt_log.c | 10 ++++---- 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/include/core/gamecard.h b/include/core/gamecard.h index 2df555e..4560cd6 100644 --- a/include/core/gamecard.h +++ b/include/core/gamecard.h @@ -172,8 +172,8 @@ typedef enum { typedef enum { GameCardFlags_None = 0, - GameCardFlags_AutoBoot = BIT(0), - GameCardFlags_HistoryErase = BIT(1), + 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), ///< Inserting the gamecard won't add any permanent icons to the HOME menu. GameCardFlags_RepairTool = BIT(2), GameCardFlags_DifferentRegionCupToTerraDevice = BIT(3), GameCardFlags_DifferentRegionCupToGlobalDevice = BIT(4), diff --git a/source/core/cnmt.c b/source/core/cnmt.c index eeac9d5..0068b82 100644 --- a/source/core/cnmt.c +++ b/source/core/cnmt.c @@ -289,7 +289,7 @@ bool cnmtVerifyContentHash(ContentMetaContext *cnmt_ctx, NcaContext *nca_ctx, co /* Check if we got a matching content ID. */ 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; } @@ -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. */ 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); diff --git a/source/core/nca.c b/source/core/nca.c index b8e232c..2fb7e8d 100644 --- a/source/core/nca.c +++ b/source/core/nca.c @@ -127,7 +127,7 @@ static const u8 g_nca0KeyAreaHash[SHA256_HASH_SIZE] = { /* 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); @@ -198,6 +198,7 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, out->title_type = meta_key->type; 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)); 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; } - if (out->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 secure hash FS partition!", nca_filename); - return false; - } - } - - return ncaInitializeContextCommon(out, storage_id, ncm_storage, tik); + return ncaInitializeContextCommon(out, storage_id, hfs_partition_type, ncm_storage, 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. */ - 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; 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. */ - /* Retrieve gamecard NCA offset. */ - 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); + return ncaInitializeContextCommon(out, NcmStorageId_GameCard, hfs_ctx->type, NULL, tik); } 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) { 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->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) { 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; @@ -578,9 +560,9 @@ const char *ncaGetFsSectionTypeName(NcaFsSectionContext *ctx) 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!"); return false; @@ -592,10 +574,22 @@ static bool ncaInitializeContextCommon(NcaContext *out, u8 storage_id, NcmConten out->storage_id = storage_id; 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. */ + 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. */ if (!ncaReadDecryptedHeader(out)) { diff --git a/source/core/nxdt_log.c b/source/core/nxdt_log.c index daf247d..9f77889 100644 --- a/source/core/nxdt_log.c +++ b/source/core/nxdt_log.c @@ -35,14 +35,14 @@ static s64 g_logFileOffset = 0; static char *g_logBuffer = NULL; 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_logLevelNames[] = { - [LOG_LEVEL_DEBUG] = "DEBUG", - [LOG_LEVEL_INFO] = "INFO", - [LOG_LEVEL_WARNING] = "WARNING", - [LOG_LEVEL_ERROR] = "ERROR" + [LOG_LEVEL_DEBUG] = "[DEBUG] ", + [LOG_LEVEL_INFO] = "[INFO] ", + [LOG_LEVEL_WARNING] = "[WARNING]", + [LOG_LEVEL_ERROR] = "[ERROR] " }; /* Function prototypes. */