mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-26 12:12:02 +00:00
Unified XML generator + finished NACP parsing.
Big thanks to 0Liam.
This commit is contained in:
parent
2859f26cb3
commit
e943e84380
10 changed files with 275 additions and 394 deletions
|
@ -12,9 +12,9 @@
|
|||
{
|
||||
fprintf(title_infos_txt, "Storage ID: 0x%02X\r\n", g_titleInfo[i].storage_id);
|
||||
fprintf(title_infos_txt, "Title ID: %016lX\r\n", g_titleInfo[i].meta_key.id);
|
||||
fprintf(title_infos_txt, "Version: %u (%u.%u.%u-%u.%u)\r\n", g_titleInfo[i].meta_key.version, g_titleInfo[i].dot_version.TitleVersion_Major, \
|
||||
g_titleInfo[i].dot_version.TitleVersion_Minor, g_titleInfo[i].dot_version.TitleVersion_Micro, g_titleInfo[i].dot_version.TitleVersion_MajorRelstep, \
|
||||
g_titleInfo[i].dot_version.TitleVersion_MinorRelstep);
|
||||
fprintf(title_infos_txt, "Version: %u (%u.%u.%u-%u.%u)\r\n", g_titleInfo[i].meta_key.version, g_titleInfo[i].version.TitleVersion_Major, \
|
||||
g_titleInfo[i].version.TitleVersion_Minor, g_titleInfo[i].version.TitleVersion_Micro, g_titleInfo[i].version.TitleVersion_MajorRelstep, \
|
||||
g_titleInfo[i].version.TitleVersion_MinorRelstep);
|
||||
fprintf(title_infos_txt, "Type: 0x%02X\r\n", g_titleInfo[i].meta_key.type);
|
||||
fprintf(title_infos_txt, "Install Type: 0x%02X\r\n", g_titleInfo[i].meta_key.install_type);
|
||||
fprintf(title_infos_txt, "Title Size: %s (0x%lX)\r\n", g_titleInfo[i].title_size_str, g_titleInfo[i].title_size);
|
||||
|
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* main.c
|
||||
*
|
||||
* Copyright (c) 2020, DarkMatterCore <pabloacurielz@gmail.com>.
|
||||
*
|
||||
* This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
|
||||
*
|
||||
* nxdumptool is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* nxdumptool is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "gamecard.h"
|
||||
#include "title.h"
|
||||
#include "nacp.h"
|
||||
|
||||
static void consolePrint(const char *text, ...)
|
||||
{
|
||||
va_list v;
|
||||
va_start(v, text);
|
||||
vfprintf(stdout, text, v);
|
||||
va_end(v);
|
||||
consoleUpdate(NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
LOGFILE(APP_TITLE " starting.");
|
||||
|
||||
consoleInit(NULL);
|
||||
|
||||
consolePrint("initializing...\n");
|
||||
|
||||
if (!utilsInitializeResources())
|
||||
{
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
u32 app_count = 0;
|
||||
TitleApplicationMetadata **app_metadata = NULL;
|
||||
TitleUserApplicationData user_app_data = {0};
|
||||
|
||||
u32 selected_idx = 0, page_size = 30, scroll = 0;
|
||||
bool exit_prompt = true;
|
||||
|
||||
NcaContext *nca_ctx = NULL;
|
||||
Ticket tik = {0};
|
||||
NacpContext nacp_ctx = {0};
|
||||
|
||||
app_metadata = titleGetApplicationMetadataEntries(false, &app_count);
|
||||
if (!app_metadata || !app_count)
|
||||
{
|
||||
consolePrint("app metadata failed\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
consolePrint("app metadata succeeded\n");
|
||||
|
||||
utilsSleep(1);
|
||||
|
||||
while(true)
|
||||
{
|
||||
consoleClear();
|
||||
printf("select an user application to generate a nacp xml for.\npress b to exit.\n\n");
|
||||
printf("title: %u / %u\n\n", selected_idx + 1, app_count);
|
||||
|
||||
for(u32 i = scroll; i < app_count; i++)
|
||||
{
|
||||
if (i >= (scroll + page_size)) break;
|
||||
printf("%s%016lX - %s\n", i == selected_idx ? " -> " : " ", app_metadata[i]->title_id, app_metadata[i]->lang_entry.name);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
consoleUpdate(NULL);
|
||||
|
||||
u64 btn_down = 0, btn_held = 0;
|
||||
while(true)
|
||||
{
|
||||
hidScanInput();
|
||||
btn_down = utilsHidKeysAllDown();
|
||||
btn_held = utilsHidKeysAllHeld();
|
||||
if (btn_down || btn_held) break;
|
||||
|
||||
if (titleIsGameCardInfoUpdated())
|
||||
{
|
||||
free(app_metadata);
|
||||
|
||||
app_metadata = titleGetApplicationMetadataEntries(false, &app_count);
|
||||
if (!app_metadata)
|
||||
{
|
||||
consolePrint("\napp metadata failed\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
selected_idx = scroll = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (btn_down & KEY_A)
|
||||
{
|
||||
if (!titleGetUserApplicationData(app_metadata[selected_idx]->title_id, &user_app_data) || !user_app_data.app_info)
|
||||
{
|
||||
consolePrint("\nthe selected title doesn't have available base content.\n");
|
||||
utilsSleep(3);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
} else
|
||||
if ((btn_down & KEY_DDOWN) || (btn_held & (KEY_LSTICK_DOWN | KEY_RSTICK_DOWN)))
|
||||
{
|
||||
selected_idx++;
|
||||
|
||||
if (selected_idx >= app_count)
|
||||
{
|
||||
if (btn_down & KEY_DDOWN)
|
||||
{
|
||||
selected_idx = scroll = 0;
|
||||
} else {
|
||||
selected_idx = (app_count - 1);
|
||||
}
|
||||
} else
|
||||
if (selected_idx >= (scroll + (page_size / 2)) && app_count > (scroll + page_size))
|
||||
{
|
||||
scroll++;
|
||||
}
|
||||
} else
|
||||
if ((btn_down & KEY_DUP) || (btn_held & (KEY_LSTICK_UP | KEY_RSTICK_UP)))
|
||||
{
|
||||
selected_idx--;
|
||||
|
||||
if (selected_idx == UINT32_MAX)
|
||||
{
|
||||
if (btn_down & KEY_DUP)
|
||||
{
|
||||
selected_idx = (app_count - 1);
|
||||
scroll = (app_count >= page_size ? (app_count - page_size) : 0);
|
||||
} else {
|
||||
selected_idx = 0;
|
||||
}
|
||||
} else
|
||||
if (selected_idx < (scroll + (page_size / 2)) && scroll > 0)
|
||||
{
|
||||
scroll--;
|
||||
}
|
||||
} else
|
||||
if (btn_down & KEY_B)
|
||||
{
|
||||
exit_prompt = false;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if (btn_held & (KEY_LSTICK_DOWN | KEY_RSTICK_DOWN | KEY_LSTICK_UP | KEY_RSTICK_UP)) svcSleepThread(50000000); // 50 ms
|
||||
}
|
||||
|
||||
consoleClear();
|
||||
consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id);
|
||||
|
||||
nca_ctx = calloc(1, sizeof(NcaContext));
|
||||
if (!nca_ctx)
|
||||
{
|
||||
consolePrint("nca ctx calloc failed\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
consolePrint("nca ctx calloc succeeded\n");
|
||||
|
||||
if (!ncaInitializeContext(nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
|
||||
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Control, 0), &tik))
|
||||
{
|
||||
consolePrint("Control nca initialize ctx failed\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
consolePrint("Control nca initialize ctx succeeded\n");
|
||||
|
||||
if (!nacpInitializeContext(&nacp_ctx, nca_ctx))
|
||||
{
|
||||
consolePrint("nacp initialize ctx failed\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
consolePrint("nacp initialize ctx succeeded\n");
|
||||
|
||||
if (nacpGenerateAuthoringToolXml(&nacp_ctx))
|
||||
{
|
||||
consolePrint("nacp xml succeeded\n");
|
||||
|
||||
FILE *xml_fd = NULL;
|
||||
char path[FS_MAX_PATH] = {0};
|
||||
|
||||
sprintf(path, "sdmc:/%s.nacp", nca_ctx->content_id_str);
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(nacp_ctx.data, 1, sizeof(_NacpStruct), xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
|
||||
sprintf(path, "sdmc:/%s.nacp.xml", nca_ctx->content_id_str);
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(nacp_ctx.authoring_tool_xml, 1, nacp_ctx.authoring_tool_xml_size, xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
|
||||
for(u8 i = 0; i < nacp_ctx.icon_count; i++)
|
||||
{
|
||||
NacpIconContext *icon_ctx = &(nacp_ctx.icon_ctx[i]);
|
||||
|
||||
sprintf(path, "sdmc:/%s.nx.%s.jpg", nca_ctx->content_id_str, nacpGetLanguageString(icon_ctx->language));
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(icon_ctx->icon_data, 1, icon_ctx->icon_size, xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
consolePrint("nacp xml failed\n");
|
||||
}
|
||||
|
||||
out2:
|
||||
if (exit_prompt)
|
||||
{
|
||||
consolePrint("press any button to exit\n");
|
||||
utilsWaitForButtonPress(KEY_NONE);
|
||||
}
|
||||
|
||||
nacpFreeContext(&nacp_ctx);
|
||||
|
||||
if (nca_ctx) free(nca_ctx);
|
||||
|
||||
if (app_metadata) free(app_metadata);
|
||||
|
||||
out:
|
||||
utilsCloseResources();
|
||||
|
||||
consoleExit(NULL);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
#include "gamecard.h"
|
||||
#include "title.h"
|
||||
#include "cnmt.h"
|
||||
#include "nacp.h"
|
||||
|
||||
static void consolePrint(const char *text, ...)
|
||||
{
|
||||
|
@ -60,7 +61,12 @@ int main(int argc, char *argv[])
|
|||
|
||||
NcaContext *nca_ctx = NULL;
|
||||
Ticket tik = {0};
|
||||
|
||||
ContentMetaContext cnmt_ctx = {0};
|
||||
NacpContext nacp_ctx = {0};
|
||||
|
||||
FILE *xml_fd = NULL;
|
||||
char path[FS_MAX_PATH] = {0};
|
||||
|
||||
app_metadata = titleGetApplicationMetadataEntries(false, &app_count);
|
||||
if (!app_metadata || !app_count)
|
||||
|
@ -182,6 +188,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
consolePrint("nca ctx calloc succeeded\n");
|
||||
|
||||
u32 meta_idx = (user_app_data.app_info->content_count - 1), control_idx = 0;
|
||||
|
||||
for(u32 i = 0, j = 0; i < user_app_data.app_info->content_count; i++)
|
||||
{
|
||||
if (user_app_data.app_info->content_infos[i].content_type == NcmContentType_Meta) continue;
|
||||
|
@ -193,12 +201,12 @@ int main(int argc, char *argv[])
|
|||
goto out2;
|
||||
}
|
||||
|
||||
if (user_app_data.app_info->content_infos[i].content_type == NcmContentType_Control && user_app_data.app_info->content_infos[i].id_offset == 0) control_idx = j;
|
||||
|
||||
consolePrint("%s nca initialize ctx succeeded\n", titleGetNcmContentTypeName(user_app_data.app_info->content_infos[i].content_type));
|
||||
j++;
|
||||
}
|
||||
|
||||
u32 meta_idx = (user_app_data.app_info->content_count - 1);
|
||||
|
||||
if (!ncaInitializeContext(&(nca_ctx[meta_idx]), user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
|
||||
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Meta, 0), &tik))
|
||||
{
|
||||
|
@ -208,6 +216,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
consolePrint("Meta nca initialize ctx succeeded\n");
|
||||
|
||||
sprintf(path, "sdmc:/%016lX_xml", app_metadata[selected_idx]->title_id);
|
||||
mkdir(path, 0777);
|
||||
|
||||
if (!cnmtInitializeContext(&cnmt_ctx, &(nca_ctx[meta_idx])))
|
||||
{
|
||||
consolePrint("cnmt initialize ctx failed\n");
|
||||
|
@ -220,21 +231,79 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
consolePrint("cnmt xml succeeded\n");
|
||||
|
||||
FILE *xml_fd = NULL;
|
||||
char path[FS_MAX_PATH] = {0};
|
||||
sprintf(path, "sdmc:/%016lX_xml/%s.cnmt", app_metadata[selected_idx]->title_id, nca_ctx[meta_idx].content_id_str);
|
||||
|
||||
sprintf(path, "sdmc:/%s.cnmt.xml", nca_ctx[meta_idx].content_id_str);
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(cnmt_ctx.raw_data, 1, cnmt_ctx.raw_data_size, xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
|
||||
sprintf(path, "sdmc:/%016lX_xml/%s.cnmt.xml", app_metadata[selected_idx]->title_id, nca_ctx[meta_idx].content_id_str);
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(cnmt_ctx.authoring_tool_xml, 1, cnmt_ctx.authoring_tool_xml_size, xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
} else {
|
||||
consolePrint("cnmt xml failed\n");
|
||||
}
|
||||
|
||||
if (!nacpInitializeContext(&nacp_ctx, &(nca_ctx[control_idx])))
|
||||
{
|
||||
consolePrint("nacp initialize ctx failed\n");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
consolePrint("nacp initialize ctx succeeded\n");
|
||||
|
||||
if (nacpGenerateAuthoringToolXml(&nacp_ctx, titleGetVersionInteger(&(user_app_data.app_info->version)), cnmtGetRequiredTitleVersion(&cnmt_ctx)))
|
||||
{
|
||||
consolePrint("nacp xml succeeded\n");
|
||||
|
||||
sprintf(path, "sdmc:/%016lX_xml/%s.nacp", app_metadata[selected_idx]->title_id, nca_ctx[control_idx].content_id_str);
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(nacp_ctx.data, 1, sizeof(_NacpStruct), xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
|
||||
sprintf(path, "sdmc:/%016lX_xml/%s.nacp.xml", app_metadata[selected_idx]->title_id, nca_ctx[control_idx].content_id_str);
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(nacp_ctx.authoring_tool_xml, 1, nacp_ctx.authoring_tool_xml_size, xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
|
||||
for(u8 i = 0; i < nacp_ctx.icon_count; i++)
|
||||
{
|
||||
NacpIconContext *icon_ctx = &(nacp_ctx.icon_ctx[i]);
|
||||
|
||||
sprintf(path, "sdmc:/%016lX_xml/%s.nx.%s.jpg", app_metadata[selected_idx]->title_id, nca_ctx[control_idx].content_id_str, nacpGetLanguageString(icon_ctx->language));
|
||||
|
||||
xml_fd = fopen(path, "wb");
|
||||
if (xml_fd)
|
||||
{
|
||||
fwrite(icon_ctx->icon_data, 1, icon_ctx->icon_size, xml_fd);
|
||||
fclose(xml_fd);
|
||||
xml_fd = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
consolePrint("nacp xml failed\n");
|
||||
}
|
||||
|
||||
out2:
|
||||
if (exit_prompt)
|
||||
{
|
|
@ -315,10 +315,10 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
|
|||
if (cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Application || cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Patch || \
|
||||
cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_AddOnContent)
|
||||
{
|
||||
u32 required_title_version = cnmtGetVersionInteger((ContentMetaVersion*)(cnmt_ctx->extended_header + sizeof(u64)));
|
||||
u32 required_title_version = cnmtGetRequiredTitleVersion(cnmt_ctx);
|
||||
const char *required_title_version_str = cnmtGetRequiredTitleVersionString(cnmt_ctx->packaged_header->content_meta_type);
|
||||
|
||||
u64 required_title_id = *((u64*)cnmt_ctx->extended_header);
|
||||
u64 required_title_id = cnmtGetRequiredTitleId(cnmt_ctx);
|
||||
const char *required_title_type_str = cnmtGetRequiredTitleTypeString(cnmt_ctx->packaged_header->content_meta_type);
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
|
|
|
@ -290,4 +290,18 @@ NX_INLINE u32 cnmtGetVersionInteger(ContentMetaVersion *version)
|
|||
return (version ? *((u32*)version) : 0);
|
||||
}
|
||||
|
||||
NX_INLINE u64 cnmtGetRequiredTitleId(ContentMetaContext *cnmt_ctx)
|
||||
{
|
||||
return ((cnmtIsValidContext(cnmt_ctx) && (cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Application || \
|
||||
cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Patch || cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_AddOnContent)) ? \
|
||||
*((u64*)cnmt_ctx->extended_header) : 0);
|
||||
}
|
||||
|
||||
NX_INLINE u32 cnmtGetRequiredTitleVersion(ContentMetaContext *cnmt_ctx)
|
||||
{
|
||||
return ((cnmtIsValidContext(cnmt_ctx) && (cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Application || \
|
||||
cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Patch || cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_AddOnContent)) ? \
|
||||
cnmtGetVersionInteger((ContentMetaVersion*)(cnmt_ctx->extended_header + sizeof(u64))) : 0);
|
||||
}
|
||||
|
||||
#endif /* __CNMT_H__ */
|
||||
|
|
272
source/nacp.c
272
source/nacp.c
|
@ -150,6 +150,12 @@ static const char *g_nacpStartupUserAccountOptionStrings[] = {
|
|||
[NacpStartupUserAccountOption_IsOptional] = "IsOptional"
|
||||
};
|
||||
|
||||
static const char *g_nacpPlayLogQueryCapabilityStrings[] = {
|
||||
[NacpPlayLogQueryCapability_None] = "None",
|
||||
[NacpPlayLogQueryCapability_WhiteList] = "WhiteList",
|
||||
[NacpPlayLogQueryCapability_All] = "All"
|
||||
};
|
||||
|
||||
static const char *g_nacpRepairStrings[] = {
|
||||
[NacpRepair_SuppressGameCardAccess] = "SuppressGameCardAccess"
|
||||
};
|
||||
|
@ -185,8 +191,9 @@ NX_INLINE bool nacpCheckBitflagField(const void *flag, u8 flag_bitcount, u8 idx)
|
|||
static bool nacpAddStringFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, const char *value);
|
||||
static bool nacpAddEnumFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u8 value, NacpStringFunction str_func);
|
||||
static bool nacpAddBitflagFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, const void *flag, u8 flag_width, u8 max_flag_idx, NacpStringFunction str_func);
|
||||
static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u64 value);
|
||||
static bool nacpAddU16FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u16 value, bool hex);
|
||||
static bool nacpAddU32FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u32 value);
|
||||
static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u64 value);
|
||||
|
||||
bool nacpInitializeContext(NacpContext *out, NcaContext *nca_ctx)
|
||||
{
|
||||
|
@ -319,7 +326,7 @@ end:
|
|||
return success;
|
||||
}
|
||||
|
||||
bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
||||
bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 required_system_version)
|
||||
{
|
||||
if (!nacpIsValidContext(nacp_ctx))
|
||||
{
|
||||
|
@ -341,7 +348,6 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
bool ndcc_sgc_available = false, ndcc_rgc_available = false;
|
||||
NacpNeighborDetectionClientConfiguration *ndcc = &(nacp->neighbor_detection_client_configuration);
|
||||
|
||||
bool raocsbd_available = false;
|
||||
NacpRequiredAddOnContentsSetBinaryDescriptor *raocsbd = &(nacp->required_add_on_contents_set_binary_descriptor);
|
||||
|
||||
bool success = false;
|
||||
|
@ -381,46 +387,37 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
/* StartupUserAccount. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccount", nacp->startup_user_account, &nacpGetStartupUserAccountString)) goto end;
|
||||
|
||||
/* StartupUserAccountOption. */
|
||||
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccountOption", &(nacp->startup_user_account_option_flag), sizeof(nacp->startup_user_account_option_flag), \
|
||||
NacpStartupUserAccountOption_Count, &nacpGetStartupUserAccountOptionString)) goto end;
|
||||
|
||||
/* UserAccountSwitchLock. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSwitchLock", nacp->user_account_switch_lock, &nacpGetUserAccountSwitchLockString)) goto end;
|
||||
|
||||
/* AddOnContentRegistrationType. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "AddOnContentRegistrationType", nacp->add_on_content_registration_type, &nacpGetAddOnContentRegistrationTypeString)) goto end;
|
||||
|
||||
/* AttributeFlag. */
|
||||
/* Attribute. */
|
||||
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Attribute", &(nacp->attribute_flag), sizeof(nacp->attribute_flag), NacpAttribute_Count, &nacpGetAttributeString)) goto end;
|
||||
|
||||
/* SupportedLanguage. */
|
||||
/* Even though this is a bitflag field, it doesn't follow the same format as the rest. */
|
||||
for(i = 0, count = 0; i < NacpLanguage_Count; i++)
|
||||
{
|
||||
if (!nacpCheckBitflagField(&(nacp->supported_language_flag), sizeof(nacp->supported_language_flag) * 8, i)) continue;
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SupportedLanguage", i, &nacpGetLanguageString)) goto end;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <SupportedLanguage />\n")) goto end;
|
||||
|
||||
/* ParentalControl. */
|
||||
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ParentalControl", &(nacp->parental_control_flag), sizeof(nacp->parental_control_flag), NacpParentalControl_Count, \
|
||||
&nacpGetParentalControlString)) goto end;
|
||||
|
||||
/* SupportedLanguage. */
|
||||
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SupportedLanguage", &(nacp->supported_language_flag), sizeof(nacp->supported_language_flag), NacpLanguage_Count, \
|
||||
&nacpGetLanguageString)) goto end;
|
||||
|
||||
/* Screenshot. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Screenshot", nacp->screenshot, &nacpGetScreenshotString)) goto end;
|
||||
|
||||
/* VideoCapture. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "VideoCapture", nacp->video_capture, &nacpGetVideoCaptureString)) goto end;
|
||||
|
||||
/* DataLossConfirmation. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DataLossConfirmation", nacp->data_loss_confirmation, &nacpGetDataLossConfirmationString)) goto end;
|
||||
|
||||
/* PlayLogPolicy. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayLogPolicy", nacp->play_log_policy, &nacpGetPlayLogPolicyString)) goto end;
|
||||
|
||||
/* PresenceGroupId. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PresenceGroupId", nacp->presence_group_id)) goto end;
|
||||
|
||||
/* RatingAge. */
|
||||
/* DisplayVersion. */
|
||||
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DisplayVersion", nacp->display_version)) goto end;
|
||||
|
||||
/* Rating. */
|
||||
for(i = 0, count = 0; i < NacpRatingAgeOrganization_Count; i++)
|
||||
{
|
||||
u8 age = *((u8*)&(nacp->rating_age) + i);
|
||||
|
@ -439,11 +436,11 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <Rating />\n")) goto end;
|
||||
|
||||
/* DisplayVersion. */
|
||||
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DisplayVersion", nacp->display_version)) goto end;
|
||||
/* DataLossConfirmation. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DataLossConfirmation", nacp->data_loss_confirmation, &nacpGetDataLossConfirmationString)) goto end;
|
||||
|
||||
/* AddOnContentBaseId. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "AddOnContentBaseId", nacp->add_on_content_base_id)) goto end;
|
||||
/* PlayLogPolicy. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayLogPolicy", nacp->play_log_policy, &nacpGetPlayLogPolicyString)) goto end;
|
||||
|
||||
/* SaveDataOwnerId. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SaveDataOwnerId", nacp->save_data_owner_id)) goto end;
|
||||
|
@ -466,6 +463,23 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
/* ApplicationErrorCodeCategory. */
|
||||
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ApplicationErrorCodeCategory", nacp->application_error_code_category)) goto end;
|
||||
|
||||
/* AddOnContentBaseId. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "AddOnContentBaseId", nacp->add_on_content_base_id)) goto end;
|
||||
|
||||
/* Version. */
|
||||
if (!nacpAddU32FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Version", version)) goto end;
|
||||
|
||||
/* ReleaseVersion and PrivateVersion. Unused but kept anyway. */
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <ReleaseVersion />\n" \
|
||||
" <PrivateVersion />\n")) goto end;
|
||||
|
||||
/* LogoType. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "LogoType", nacp->logo_type, &nacpGetLogoTypeString)) goto end;
|
||||
|
||||
/* RequiredSystemVersion. */
|
||||
if (!nacpAddU32FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RequiredSystemVersion", required_system_version)) goto end;
|
||||
|
||||
/* LocalCommunicationId. */
|
||||
for(i = 0, count = 0; i < 0x8; i++)
|
||||
{
|
||||
|
@ -476,23 +490,42 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <LocalCommunicationId />\n")) goto end;
|
||||
|
||||
/* LogoType. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "LogoType", nacp->logo_type, &nacpGetLogoTypeString)) goto end;
|
||||
|
||||
/* LogoHandling. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "LogoHandling", nacp->logo_handling, &nacpGetLogoHandlingString)) goto end;
|
||||
|
||||
/* RuntimeAddOnContentInstall. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RuntimeAddOnContentInstall", nacp->runtime_add_on_content_install, &nacpGetRuntimeAddOnContentInstallString)) goto end;
|
||||
/* Icon. */
|
||||
for(i = 0, count = 0; i < nacp_ctx->icon_count; i++)
|
||||
{
|
||||
NacpIconContext *icon_ctx = &(nacp_ctx->icon_ctx[i]);
|
||||
|
||||
/* Calculate icon hash. */
|
||||
sha256CalculateHash(icon_hash, icon_ctx->icon_data, icon_ctx->icon_size);
|
||||
|
||||
/* Generate icon hash string. Only the first half from the hash is used. */
|
||||
utilsGenerateHexStringFromData(icon_hash_str, SHA256_HASH_SIZE + 1, icon_hash, SHA256_HASH_SIZE / 2);
|
||||
|
||||
/* Add XML element. */
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <Icon>\n" \
|
||||
" <Language>%s</Language>\n" \
|
||||
" <IconPath />\n" \
|
||||
" <NxIconPath />\n" \
|
||||
" <RawIconHash />\n" \
|
||||
" <NxIconHash>%s</NxIconHash>\n" \
|
||||
" </Icon>\n", \
|
||||
nacpGetLanguageString(icon_ctx->language), \
|
||||
icon_hash_str)) goto end;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
/* RuntimeParameterDelivery. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RuntimeParameterDelivery", nacp->runtime_parameter_delivery, &nacpGetRuntimeParameterDeliveryString)) goto end;
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <Icon />\n")) goto end;
|
||||
|
||||
/* CrashReport. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CrashReport", nacp->crash_report, &nacpGetCrashReportString)) goto end;
|
||||
|
||||
/* Hdcp. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Hdcp", nacp->hdcp, &nacpGetHdcpString)) goto end;
|
||||
/* HtmlDocumentPath, LegalInformationFilePath and AccessibleUrlsFilePath. Unused but kept anyway. */
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <HtmlDocumentPath />\n" \
|
||||
" <LegalInformationFilePath />\n" \
|
||||
" <AccessibleUrlsFilePath />\n")) goto end;
|
||||
|
||||
/* SeedForPseudoDeviceId. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SeedForPseudoDeviceId", nacp->seed_for_pseudo_device_id)) goto end;
|
||||
|
@ -500,9 +533,8 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
/* BcatPassphrase. */
|
||||
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "BcatPassphrase", nacp->bcat_passphrase)) goto end;
|
||||
|
||||
/* StartupUserAccountOption. */
|
||||
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccountOption", &(nacp->startup_user_account_option_flag), sizeof(nacp->startup_user_account_option_flag), \
|
||||
NacpStartupUserAccountOption_Count, &nacpGetStartupUserAccountOptionString)) goto end;
|
||||
/* AddOnContentRegistrationType. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "AddOnContentRegistrationType", nacp->add_on_content_registration_type, &nacpGetAddOnContentRegistrationTypeString)) goto end;
|
||||
|
||||
/* UserAccountSaveDataSizeMax. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSaveDataSizeMax", nacp->user_account_save_data_size_max)) goto end;
|
||||
|
@ -531,6 +563,15 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
/* CacheStorageIndexMax. */
|
||||
if (!nacpAddU16FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CacheStorageIndexMax", nacp->cache_storage_index_max, true)) goto end;
|
||||
|
||||
/* Hdcp. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Hdcp", nacp->hdcp, &nacpGetHdcpString)) goto end;
|
||||
|
||||
/* CrashReport. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CrashReport", nacp->crash_report, &nacpGetCrashReportString)) goto end;
|
||||
|
||||
/* RuntimeAddOnContentInstall. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RuntimeAddOnContentInstall", nacp->runtime_add_on_content_install, &nacpGetRuntimeAddOnContentInstallString)) goto end;
|
||||
|
||||
/* PlayLogQueryableApplicationId. */
|
||||
for(i = 0, count = 0; i < 0x10; i++)
|
||||
{
|
||||
|
@ -541,6 +582,9 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <PlayLogQueryableApplicationId />\n")) goto end;
|
||||
|
||||
/* PlayLogQueryCapability. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayLogQueryCapability", nacp->play_log_query_capability, &nacpGetPlayLogQueryCapabilityString)) goto end;
|
||||
|
||||
/* Repair. */
|
||||
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Repair", &(nacp->repair_flag), sizeof(nacp->repair_flag), NacpRepair_Count, &nacpGetRepairString)) goto end;
|
||||
|
||||
|
@ -564,27 +608,27 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
{
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <NeighborDetectionClientConfiguration>\n")) goto end;
|
||||
|
||||
/* SendDataConfiguration. */
|
||||
/* SendGroupConfiguration. */
|
||||
utilsGenerateHexStringFromData(key_str, sizeof(key_str), ndcc->send_group_configuration.key, sizeof(ndcc->send_group_configuration.key));
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <SendDataConfiguration>\n" \
|
||||
" <DataId>0x%016lx</DataId>\n" \
|
||||
" <SendGroupConfiguration>\n" \
|
||||
" <GroupId>0x%016lx</GroupId>\n" \
|
||||
" <Key>%s</Key>\n" \
|
||||
" </SendDataConfiguration>\n", \
|
||||
" </SendGroupConfiguration>\n", \
|
||||
ndcc->send_group_configuration.group_id,
|
||||
key_str)) goto end;
|
||||
|
||||
/* ReceivableDataConfiguration. */
|
||||
/* ReceivableGroupConfiguration. */
|
||||
for(i = 0; i < 0x10; i++)
|
||||
{
|
||||
utilsGenerateHexStringFromData(key_str, sizeof(key_str), ndcc->receivable_group_configurations[i].key, sizeof(ndcc->receivable_group_configurations[i].key));
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <ReceivableDataConfiguration>\n" \
|
||||
" <DataId>0x%016lx</DataId>\n" \
|
||||
" <ReceivableGroupConfiguration>\n" \
|
||||
" <GroupId>0x%016lx</GroupId>\n" \
|
||||
" <Key>%s</Key>\n" \
|
||||
" </ReceivableDataConfiguration>\n", \
|
||||
" </ReceivableGroupConfiguration>\n", \
|
||||
ndcc->receivable_group_configurations[i].group_id,
|
||||
key_str)) goto end;
|
||||
}
|
||||
|
@ -603,32 +647,21 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
nacpGetJitConfigurationFlagString(nacp->jit_configuration.jit_configuration_flag),
|
||||
nacp->jit_configuration.memory_size)) goto end;
|
||||
|
||||
/* RequiredAddOnContentsSetBinaryDescriptor. */
|
||||
for(i = 0; i < 0x20; i++)
|
||||
/* RequiredAddOnContentsSet. */
|
||||
for(i = 0, count = 0; i < 0x20; i++)
|
||||
{
|
||||
if (!raocsbd->descriptors[i].NacpDescriptors_ContinueSet) continue;
|
||||
if ((raocsbd_available = (raocsbd->descriptors[i].NacpDescriptors_Index != 0))) break;
|
||||
if (!raocsbd->descriptors[i].NacpDescriptors_Index || !raocsbd->descriptors[i].NacpDescriptors_ContinueSet) continue;
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <RequiredAddOnContentsSet>\n" \
|
||||
" <Index>%u</Index>\n" \
|
||||
" </RequiredAddOnContentsSet>\n",
|
||||
raocsbd->descriptors[i].NacpDescriptors_Index)) goto end;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (raocsbd_available)
|
||||
{
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <RequiredAddOnContentsSetBinaryDescriptor>\n")) goto end;
|
||||
|
||||
for(i = 0; i < 0x20; i++)
|
||||
{
|
||||
if (!raocsbd->descriptors[i].NacpDescriptors_Index || !raocsbd->descriptors[i].NacpDescriptors_ContinueSet) continue;
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <Descriptor>\n" \
|
||||
" <Index>%u</Index>\n"
|
||||
" </Descriptor>\n",
|
||||
raocsbd->descriptors[i].NacpDescriptors_Index)) goto end;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " </RequiredAddOnContentsSetBinaryDescriptor>\n")) goto end;
|
||||
} else {
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <RequiredAddOnContentsSetBinaryDescriptor />\n")) goto end;
|
||||
}
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <RequiredAddOnContentsSet />\n")) goto end;
|
||||
|
||||
/* PlayReportPermission. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayReportPermission", nacp->play_report_permission, &nacpGetPlayReportPermissionString)) goto end;
|
||||
|
@ -639,30 +672,33 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx)
|
|||
/* CrashScreenshotForDev. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CrashScreenshotForDev", nacp->crash_screenshot_for_dev, &nacpGetCrashScreenshotForDevString)) goto end;
|
||||
|
||||
/* Icon. */
|
||||
for(i = 0, count = 0; i < nacp_ctx->icon_count; i++)
|
||||
/* AccessibleLaunchRequiredVersion. */
|
||||
for(i = 0, count = 0; i < 0x8; i++)
|
||||
{
|
||||
NacpIconContext *icon_ctx = &(nacp_ctx->icon_ctx[i]);
|
||||
if (!nacp->accessible_launch_required_version.application_id[i]) continue;
|
||||
|
||||
/* Calculate icon hash. */
|
||||
sha256CalculateHash(icon_hash, icon_ctx->icon_data, icon_ctx->icon_size);
|
||||
|
||||
/* Generate icon hash string. Only the first half from the hash is used. */
|
||||
utilsGenerateHexStringFromData(icon_hash_str, SHA256_HASH_SIZE + 1, icon_hash, SHA256_HASH_SIZE / 2);
|
||||
|
||||
/* Add XML element. */
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <Icon>\n" \
|
||||
" <Language>%s</Language>\n" \
|
||||
" <NxIconHash>%s</NxIconHash>\n" \
|
||||
" </Icon>\n", \
|
||||
nacpGetLanguageString(icon_ctx->language), \
|
||||
icon_hash_str)) goto end;
|
||||
" <AccessibleLaunchRequiredVersion>\n" \
|
||||
" <ApplicationId>0x%016lx</ApplicationId>\n" \
|
||||
" </AccessibleLaunchRequiredVersion>\n",
|
||||
nacp->accessible_launch_required_version.application_id[i])) goto end;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <Icon />\n")) goto end;
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <AccessibleLaunchRequiredVersion />\n")) goto end;
|
||||
|
||||
/* History. Unused but kept anyway. */
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <History />\n")) goto end;
|
||||
|
||||
/* RuntimeParameterDelivery. */
|
||||
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RuntimeParameterDelivery", nacp->runtime_parameter_delivery, &nacpGetRuntimeParameterDeliveryString)) goto end;
|
||||
|
||||
/* ApplicationId. */
|
||||
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ApplicationId", nacp_ctx->nca_ctx->header.program_id)) goto end;
|
||||
|
||||
/* FilterDescriptionFilePath. Unused but kept anyway. */
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <FilterDescriptionFilePath />\n")) goto end;
|
||||
|
||||
if (!(success = utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, "</Application>"))) goto end;
|
||||
|
||||
|
@ -770,6 +806,11 @@ const char *nacpGetStartupUserAccountOptionString(u8 startup_user_account_option
|
|||
return (startup_user_account_option < NacpStartupUserAccountOption_Count ? g_nacpStartupUserAccountOptionStrings[startup_user_account_option] : g_unknownString);
|
||||
}
|
||||
|
||||
const char *nacpGetPlayLogQueryCapabilityString(u8 play_log_query_capability)
|
||||
{
|
||||
return (play_log_query_capability < NacpPlayLogQueryCapability_Count ? g_nacpPlayLogQueryCapabilityStrings[play_log_query_capability] : g_unknownString);
|
||||
}
|
||||
|
||||
const char *nacpGetRepairString(u8 repair)
|
||||
{
|
||||
return (repair < NacpRepair_Count ? g_nacpRepairStrings[repair] : g_unknownString);
|
||||
|
@ -846,8 +887,6 @@ static bool nacpAddBitflagFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_s
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>", tag_name)) goto end;
|
||||
|
||||
for(i = 0; i < flag_width; i++)
|
||||
{
|
||||
if (flag_u8[i])
|
||||
|
@ -862,33 +901,22 @@ static bool nacpAddBitflagFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_s
|
|||
for(i = 0; i < max_flag_idx; i++)
|
||||
{
|
||||
if (!nacpCheckBitflagField(flag, flag_bitcount, i)) continue;
|
||||
if (count && !utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, ",")) goto end;
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, "%s", str_func(i))) goto end;
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%s</%s>\n", tag_name, str_func(i), tag_name)) goto end;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, "%s", g_unknownString)) goto end;
|
||||
} else {
|
||||
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, "None")) goto end;
|
||||
/* Edge case for new, unsupported flags. */
|
||||
if (!count) empty_flag = true;
|
||||
}
|
||||
|
||||
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, "</%s>\n", tag_name);
|
||||
if (empty_flag && !utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s />\n", tag_name)) goto end;
|
||||
|
||||
success = true;
|
||||
|
||||
end:
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u64 value)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !tag_name || !strlen(tag_name))
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>0x%016lx</%s>\n", tag_name, value, tag_name);
|
||||
}
|
||||
|
||||
static bool nacpAddU16FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u16 value, bool hex)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !tag_name || !strlen(tag_name))
|
||||
|
@ -900,3 +928,25 @@ static bool nacpAddU16FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size,
|
|||
return (hex ? utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>0x%04x</%s>\n", tag_name, value, tag_name) : \
|
||||
utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%u</%s>\n", tag_name, value, tag_name));
|
||||
}
|
||||
|
||||
static bool nacpAddU32FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u32 value)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !tag_name || !strlen(tag_name))
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%u</%s>\n", tag_name, value, tag_name);
|
||||
}
|
||||
|
||||
static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u64 value)
|
||||
{
|
||||
if (!xml_buf || !xml_buf_size || !tag_name || !strlen(tag_name))
|
||||
{
|
||||
LOGFILE("Invalid parameters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>0x%016lx</%s>\n", tag_name, value, tag_name);
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
u16 NacpDescriptors_Index : 15;
|
||||
u16 NacpDescriptors_ContinueSet : 1; ///< Called "flag" by Nintendo.
|
||||
u16 NacpDescriptors_ContinueSet : 1; ///< Called "flag" by Nintendo, which isn't really great...
|
||||
} NacpDescriptors;
|
||||
|
||||
typedef struct {
|
||||
|
@ -302,6 +302,10 @@ typedef enum {
|
|||
NacpCrashScreenshotForDev_Count = 2 ///< Not a real value.
|
||||
} NacpCrashScreenshotForDev;
|
||||
|
||||
typedef struct {
|
||||
u64 application_id[8];
|
||||
} NacpAccessibleLaunchRequiredVersion;
|
||||
|
||||
typedef struct {
|
||||
NacpTitle title[0x10];
|
||||
char isbn[0x25];
|
||||
|
@ -360,7 +364,9 @@ typedef struct {
|
|||
u8 play_report_permission; ///< NacpPlayReportPermission.
|
||||
u8 crash_screenshot_for_prod; ///< NacpCrashScreenshotForProd.
|
||||
u8 crash_screenshot_for_dev; ///< NacpCrashScreenshotForDev.
|
||||
u8 reserved_5[0xBFD];
|
||||
u8 reserved_5[0x5];
|
||||
NacpAccessibleLaunchRequiredVersion accessible_launch_required_version;
|
||||
u8 reserved_6[0xBB8];
|
||||
} _NacpStruct;
|
||||
|
||||
typedef struct {
|
||||
|
@ -388,9 +394,9 @@ typedef struct {
|
|||
/// Initializes a NacpContext using a previously initialized NcaContext (which must belong to a Control NCA).
|
||||
bool nacpInitializeContext(NacpContext *out, NcaContext *nca_ctx);
|
||||
|
||||
/// Generates an AuthoringTool-like XML using information from a previously initialized NacpContext.
|
||||
/// Generates an AuthoringTool-like XML using information from a previously initialized NacpContext, as well as the Application/Patch version and the required system version.
|
||||
/// If the function succeeds, XML data and size will get saved to the 'authoring_tool_xml' and 'authoring_tool_xml_size' members from the NacpContext.
|
||||
bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx);
|
||||
bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 required_system_version);
|
||||
|
||||
/// These functions return pointers to string representations of the input value.
|
||||
/// If the provided value is invalid, "Unknown" is returned.
|
||||
|
@ -412,6 +418,7 @@ const char *nacpGetRuntimeParameterDeliveryString(u8 runtime_parameter_delivery)
|
|||
const char *nacpGetCrashReportString(u8 crash_report);
|
||||
const char *nacpGetHdcpString(u8 hdcp);
|
||||
const char *nacpGetStartupUserAccountOptionString(u8 startup_user_account_option);
|
||||
const char *nacpGetPlayLogQueryCapabilityString(u8 play_log_query_capability);
|
||||
const char *nacpGetRepairString(u8 repair);
|
||||
const char *nacpGetRequiredNetworkServiceLicenseOnLaunchString(u8 required_network_service_license_on_launch);
|
||||
const char *nacpGetJitConfigurationFlagString(u64 jig_configuration_flag);
|
||||
|
|
|
@ -357,7 +357,13 @@ RomFileSystemFileEntry *romfsGetFileEntryByPath(RomFileSystemContext *ctx, const
|
|||
}
|
||||
|
||||
/* Retrieve file entry. */
|
||||
if (!(file_entry = romfsGetChildFileEntryByName(ctx, dir_entry, filename))) LOGFILE("Failed to retrieve file entry by name for \"%s\"! (\"%s\").", filename, path);
|
||||
if (!(file_entry = romfsGetChildFileEntryByName(ctx, dir_entry, filename)))
|
||||
{
|
||||
/* Only log error if we're not dealing with NACP icons. */
|
||||
int res = strncmp("/icon_", path, 6);
|
||||
if (res != 0 || (res == 0 && ((NcaContext*)ctx->nca_fs_ctx->nca_ctx)->content_type != NcmContentType_Control))
|
||||
LOGFILE("Failed to retrieve file entry by name for \"%s\"! (\"%s\").", filename, path);
|
||||
}
|
||||
|
||||
end:
|
||||
if (path_dup) free(path_dup);
|
||||
|
|
|
@ -1357,8 +1357,9 @@ static bool titleRetrieveContentMetaKeysFromDatabase(u8 storage_id)
|
|||
|
||||
/* Fill information. */
|
||||
cur_title_info->storage_id = storage_id;
|
||||
memcpy(&(cur_title_info->dot_version), &(meta_keys[i].version), sizeof(u32));
|
||||
memcpy(&(cur_title_info->meta_key), &(meta_keys[i]), sizeof(NcmContentMetaKey));
|
||||
memcpy(&(cur_title_info->version), &(meta_keys[i].version), sizeof(u32));
|
||||
|
||||
if (cur_title_info->meta_key.type <= NcmContentMetaType_Application) cur_title_info->app_metadata = titleFindApplicationMetadataByTitleId(meta_keys[i].id);
|
||||
|
||||
/* Retrieve content infos. */
|
||||
|
|
|
@ -52,8 +52,8 @@ typedef struct {
|
|||
/// Retrieved using ncm databases.
|
||||
typedef struct _TitleInfo {
|
||||
u8 storage_id; ///< NcmStorageId.
|
||||
TitleVersion dot_version; ///< Holds the same value from meta_key.version.
|
||||
NcmContentMetaKey meta_key; ///< Used with ncm calls.
|
||||
TitleVersion version; ///< Holds the same value from meta_key.version.
|
||||
u32 content_count; ///< Content info count.
|
||||
NcmContentInfo *content_infos; ///< Content info entries from this title.
|
||||
u64 title_size; ///< Total title size.
|
||||
|
|
Loading…
Reference in a new issue