From 88793eceea4fd23a86a3dea597104f10042f4114 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Sun, 31 Jan 2021 05:16:05 -0400 Subject: [PATCH] Populate app_metadata pointer in TitleInfo elements that aren't system titles or user applications. --- code_templates/dump_title_infos.c | 5 ++--- code_templates/nsp_dumper_stor.c | 2 +- code_templates/nsp_dumper_usb.c | 2 +- source/title.c | 34 +++++++++++++++++-------------- source/title.h | 17 +++++++++++++++- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/code_templates/dump_title_infos.c b/code_templates/dump_title_infos.c index 948df0d..eddab1d 100644 --- a/code_templates/dump_title_infos.c +++ b/code_templates/dump_title_infos.c @@ -38,10 +38,9 @@ fprintf(title_infos_txt, " ID Offset: 0x%02X\r\n", g_titleInfo[i].content_infos[j].id_offset); } - if ((g_titleInfo[i].meta_key.type == NcmContentMetaType_Application && g_titleInfo[i].app_metadata) || ((g_titleInfo[i].meta_key.type == NcmContentMetaType_Patch || \ - g_titleInfo[i].meta_key.type == NcmContentMetaType_AddOnContent) && g_titleInfo[i].parent && g_titleInfo[i].parent->app_metadata)) + if (g_titleInfo[i].app_metadata) { - TitleApplicationMetadata *app_metadata = (g_titleInfo[i].meta_key.type == NcmContentMetaType_Application ? g_titleInfo[i].app_metadata : g_titleInfo[i].parent->app_metadata); + TitleApplicationMetadata *app_metadata = g_titleInfo[i].app_metadata; if (strlen(app_metadata->lang_entry.name)) fprintf(title_infos_txt, "Name: %s\r\n", app_metadata->lang_entry.name); if (strlen(app_metadata->lang_entry.author)) fprintf(title_infos_txt, "Author: %s\r\n", app_metadata->lang_entry.author); diff --git a/code_templates/nsp_dumper_stor.c b/code_templates/nsp_dumper_stor.c index f77efa6..ab0c06c 100644 --- a/code_templates/nsp_dumper_stor.c +++ b/code_templates/nsp_dumper_stor.c @@ -75,7 +75,7 @@ static void nspDump(TitleInfo *title_info, u64 free_space) consoleClear(); - TitleApplicationMetadata *app_metadata = (title_info->app_metadata ? title_info->app_metadata : ((title_info->parent && title_info->parent->app_metadata) ? title_info->parent->app_metadata : NULL)); + TitleApplicationMetadata *app_metadata = title_info->app_metadata; printf("%s info:\n\n", title_info->meta_key.type == NcmContentMetaType_Application ? "base application" : \ (title_info->meta_key.type == NcmContentMetaType_Patch ? "update" : "dlc")); diff --git a/code_templates/nsp_dumper_usb.c b/code_templates/nsp_dumper_usb.c index ef81ba4..ebacd59 100644 --- a/code_templates/nsp_dumper_usb.c +++ b/code_templates/nsp_dumper_usb.c @@ -70,7 +70,7 @@ static void nspDump(TitleInfo *title_info) consoleClear(); - TitleApplicationMetadata *app_metadata = (title_info->app_metadata ? title_info->app_metadata : ((title_info->parent && title_info->parent->app_metadata) ? title_info->parent->app_metadata : NULL)); + TitleApplicationMetadata *app_metadata = title_info->app_metadata; printf("%s info:\n\n", title_info->meta_key.type == NcmContentMetaType_Application ? "base application" : \ (title_info->meta_key.type == NcmContentMetaType_Patch ? "update" : "dlc")); diff --git a/source/title.c b/source/title.c index d62d94a..ad98c65 100644 --- a/source/title.c +++ b/source/title.c @@ -756,7 +756,6 @@ char *titleGenerateFileName(const TitleInfo *title_info, u8 name_convention, u8 char *filename = NULL; char title_name[0x400] = {0}; - TitleApplicationMetadata *app_metadata = NULL; if (!title_info || title_info->meta_key.type < NcmContentMetaType_Application || title_info->meta_key.type > NcmContentMetaType_Delta || name_convention > TitleFileNameConvention_IdAndVersionOnly || \ (name_convention == TitleFileNameConvention_Full && illegal_char_replace_type > TitleFileNameIllegalCharReplaceType_KeepAsciiCharsOnly)) @@ -767,17 +766,12 @@ char *titleGenerateFileName(const TitleInfo *title_info, u8 name_convention, u8 u8 type = (title_info->meta_key.type - 0x80); - /* Retrieve application metadata. */ - /* System titles and user applications: just retrieve the app_metadata pointer from the input TitleInfo. */ - /* Patches and add-on contents: retrieve the app_metadata pointer from the parent TitleInfo if it's available. */ - app_metadata = (title_info->meta_key.type <= NcmContentMetaType_Application ? title_info->app_metadata : (title_info->parent ? title_info->parent->app_metadata : NULL)); - /* Generate filename for this title. */ if (name_convention == TitleFileNameConvention_Full) { - if (app_metadata && *(app_metadata->lang_entry.name)) + if (title_info->app_metadata && *(title_info->app_metadata->lang_entry.name)) { - sprintf(title_name, "%s ", app_metadata->lang_entry.name); + sprintf(title_name, "%s ", title_info->app_metadata->lang_entry.name); if (illegal_char_replace_type) utilsReplaceIllegalCharacters(title_name, illegal_char_replace_type == TitleFileNameIllegalCharReplaceType_KeepAsciiCharsOnly); } @@ -1390,7 +1384,13 @@ static bool titleRetrieveContentMetaKeysFromDatabase(u8 storage_id) memcpy(&(cur_title_info->meta_key), &(meta_keys[i]), sizeof(NcmContentMetaKey)); cur_title_info->version.value = cur_title_info->meta_key.version; - if (cur_title_info->meta_key.type <= NcmContentMetaType_Application) cur_title_info->app_metadata = titleFindApplicationMetadataByTitleId(cur_title_info->meta_key.id); + /* Retrieve application metadata. */ + u64 app_id = (cur_title_info->meta_key.type <= NcmContentMetaType_Application ? cur_title_info->meta_key.id : \ + (cur_title_info->meta_key.type == NcmContentMetaType_Patch ? titleGetApplicationIdByPatchId(cur_title_info->meta_key.id) : \ + (cur_title_info->meta_key.type == NcmContentMetaType_AddOnContent ? titleGetApplicationIdByAddOnContentId(cur_title_info->meta_key.id) : \ + titleGetApplicationIdByDeltaId(cur_title_info->meta_key.id)))); + + cur_title_info->app_metadata = titleFindApplicationMetadataByTitleId(app_id); /* Retrieve content infos. */ if (titleGetContentInfosFromTitle(storage_id, &(cur_title_info->meta_key), &(cur_title_info->content_infos), &(cur_title_info->content_count))) @@ -1677,12 +1677,16 @@ static bool titleRefreshGameCardTitleInfo(void) { TitleInfo *cur_title_info = &(g_titleInfo[i]); - /* Skip current title if it's not an application. */ - if (cur_title_info->meta_key.type != NcmContentMetaType_Application) continue; - gamecard_app_count++; + u64 app_id = (cur_title_info->meta_key.type <= NcmContentMetaType_Application ? cur_title_info->meta_key.id : \ + (cur_title_info->meta_key.type == NcmContentMetaType_Patch ? titleGetApplicationIdByPatchId(cur_title_info->meta_key.id) : \ + (cur_title_info->meta_key.type == NcmContentMetaType_AddOnContent ? titleGetApplicationIdByAddOnContentId(cur_title_info->meta_key.id) : \ + titleGetApplicationIdByDeltaId(cur_title_info->meta_key.id)))); - /* Check if we already have an application metadata entry for this title ID. */ - if ((cur_title_info->app_metadata = titleFindApplicationMetadataByTitleId(cur_title_info->meta_key.id)) != NULL) + /* Update gamecard application count (if needed). */ + if (cur_title_info->meta_key.type == NcmContentMetaType_Application) gamecard_app_count++; + + /* Do not proceed if application metadata has already been retrieved, or if we can successfully retrieve it. */ + if (cur_title_info->app_metadata != NULL || (cur_title_info->app_metadata = titleFindApplicationMetadataByTitleId(app_id)) != NULL) { gamecard_metadata_count++; continue; @@ -1705,7 +1709,7 @@ static bool titleRefreshGameCardTitleInfo(void) } /* Retrieve application metadata. */ - if (!titleRetrieveApplicationMetadataByTitleId(cur_title_info->meta_key.id, &(g_appMetadata[g_appMetadataCount]))) continue; + if (!titleRetrieveApplicationMetadataByTitleId(app_id, &(g_appMetadata[g_appMetadataCount]))) continue; cur_title_info->app_metadata = &(g_appMetadata[g_appMetadataCount++]); gamecard_metadata_count++; diff --git a/source/title.h b/source/title.h index 4f5586f..72ecd39 100644 --- a/source/title.h +++ b/source/title.h @@ -49,7 +49,7 @@ typedef struct _TitleInfo { NcmContentInfo *content_infos; ///< Content info entries from this title. u64 size; ///< Total title size. char size_str[32]; ///< Total title size string. - TitleApplicationMetadata *app_metadata; ///< Only available for system titles and applications. + TitleApplicationMetadata *app_metadata; ///< User application metadata. struct _TitleInfo *parent, *previous, *next; ///< Used with TitleInfo entries from user applications, patches and add-on contents. The parent pointer is unused in user applications. } TitleInfo; @@ -196,6 +196,21 @@ NX_INLINE bool titleCheckIfAddOnContentIdsAreSiblings(u64 aoc_id_1, u64 aoc_id_2 return (app_id_1 == app_id_2 && titleCheckIfAddOnContentIdBelongsToApplicationId(app_id_1, aoc_id_1) && titleCheckIfAddOnContentIdBelongsToApplicationId(app_id_2, aoc_id_2)); } +NX_INLINE u64 titleGetDeltaIdByApplicationId(u64 app_id) +{ + return (app_id + TITLE_DELTA_TYPE_VALUE); +} + +NX_INLINE u64 titleGetApplicationIdByDeltaId(u64 delta_id) +{ + return (delta_id - TITLE_DELTA_TYPE_VALUE); +} + +NX_INLINE bool titleCheckIfDeltaIdBelongsToApplicationId(u64 app_id, u64 delta_id) +{ + return (delta_id == titleGetDeltaIdByApplicationId(app_id)); +} + NX_INLINE u32 titleGetContentCountByType(TitleInfo *info, u8 content_type) { if (!info || !info->content_count || !info->content_infos || content_type > NcmContentType_DeltaFragment) return 0;