1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-11-22 18:26:39 +00:00

More changes.

* gc_dumper: fixed Card ID Set dumping.

* nacp: updated structs and enums to match latest changes (big thanks to @0Liam !), added helper macros.

* cnmt: added helper macros.

* program_info: added helper macros.

* exception_handler: added helper macros.

* nxdt_utils: only create output directories if the app isn't a PoC build.

* todo: changed task priority order. Sparse/compressed section support is mandatory and must be implemented ASAP.
This commit is contained in:
Pablo Curiel 2022-03-18 17:48:16 +01:00
parent 9604b5923d
commit 7189943680
9 changed files with 476 additions and 362 deletions

View file

@ -696,11 +696,11 @@ static bool saveGameCardIdSet(void)
crc = crc32Calculate(&id_set, sizeof(FsGameCardIdSet));
snprintf(path, MAX_ELEMENTS(path), " (Card ID Set) (%08X).bin", crc);
if (!saveFileData(filename, &id_set, sizeof(FsGameCardIdSet))) goto end;
filename = generateOutputFileName(path);
if (!filename) goto end;
if (!saveFileData(filename, &id_set, sizeof(FsGameCardIdSet))) goto end;
printf("successfully saved gamecard id set as \"%s\"\n", filename);
success = true;

View file

@ -49,7 +49,12 @@ typedef enum {
typedef enum {
NacpUserAccountSwitchLock_Disable = 0,
NacpUserAccountSwitchLock_Enable = 1,
NacpUserAccountSwitchLock_Count = 2 ///< Total values supported by this enum.
NacpUserAccountSwitchLock_Count = 2, ///< Total values supported by this enum.
// Old.
NacpTouchScreenUsage_None = 0,
NacpTouchScreenUsage_Supported = 1,
NacpTouchScreenUsage_Required = 2
} NacpUserAccountSwitchLock;
typedef enum {
@ -61,7 +66,8 @@ typedef enum {
typedef enum {
NacpAttribute_Demo = BIT(0),
NacpAttribute_RetailInteractiveDisplay = BIT(1),
NacpAttribute_Count = 2 ///< Total values supported by this enum.
NacpAttribute_DownloadPlay = BIT(2), ///< Removed.
NacpAttribute_Count = 3 ///< Total values supported by this enum.
} NacpAttribute;
/// Indexes used to access NACP Title structs.
@ -216,6 +222,14 @@ typedef enum {
NacpRuntimeParameterDelivery_Count = 3 ///< Total values supported by this enum.
} NacpRuntimeParameterDelivery;
typedef enum {
NacpAppropriateAgeForChina_None = 0,
NacpAppropriateAgeForChina_Age8 = 1,
NacpAppropriateAgeForChina_Age12 = 2,
NacpAppropriateAgeForChina_Age16 = 3,
NacpAppropriateAgeForChina_Count = 4 ///< Total values supported by this enum.
} NacpAppropriateAgeForChina;
typedef enum {
NacpUndecidedParameter75b8b_A = 0,
NacpUndecidedParameter75b8b_B = 1,
@ -239,6 +253,17 @@ typedef enum {
NacpStartupUserAccountOption_Count = 1 ///< Total values supported by this enum.
} NacpStartupUserAccountOption;
typedef enum {
NacpRuntimeUpgrade_Deny = 0,
NacpRuntimeUpgrade_Allow = 1,
NacpRuntimeUpgrade_Count = 2 ///< Total values supported by this enum.
} NacpRuntimeUpgrade;
typedef enum {
NacpSupportingLimitedLicenses_Demo = BIT(1),
NacpSupportingLimitedLicenses_Count = 1 ///< Total values supported by this enum.
} NacpSupportingLimitedLicenses;
typedef enum {
NacpPlayLogQueryCapability_None = 0,
NacpPlayLogQueryCapability_WhiteList = 1,
@ -257,9 +282,8 @@ typedef enum {
} NacpRequiredNetworkServiceLicenseOnLaunch;
typedef enum {
NacpJitConfigurationFlag_None = 0,
NacpJitConfigurationFlag_Enabled = 1,
NacpJitConfigurationFlag_Count = 2 ///< Total values supported by this enum.
NacpJitConfigurationFlag_Enabled = BIT_LONG(0),
NacpJitConfigurationFlag_Count = 1 ///< Total values supported by this enum.
} NacpJitConfigurationFlag;
typedef struct {
@ -269,23 +293,27 @@ typedef struct {
NXDT_ASSERT(NacpJitConfiguration, 0x10);
typedef enum {
NacpRequiredAddOnContentsSetDescriptorFlag_None = 0,
NacpRequiredAddOnContentsSetDescriptorFlag_Continue = 1
} NacpRequiredAddOnContentsSetDescriptorFlag;
typedef struct {
u16 index : 15;
u16 continue_set : 1; ///< Called "flag" by Nintendo, which isn't really great.
} NacpDescriptors;
u16 flag : 1; ///< NacpRequiredAddOnContentsSetDescriptorFlag.
} NacpRequiredAddOnContentsSetDescriptor;
NXDT_ASSERT(NacpDescriptors, 0x2);
NXDT_ASSERT(NacpRequiredAddOnContentsSetDescriptor, 0x2);
typedef struct {
NacpDescriptors descriptors[0x20];
NacpRequiredAddOnContentsSetDescriptor descriptors[0x20];
} NacpRequiredAddOnContentsSetBinaryDescriptor;
NXDT_ASSERT(NacpRequiredAddOnContentsSetBinaryDescriptor, 0x40);
typedef enum {
NacpPlayReportPermission_None = 0,
NacpPlayReportPermission_TargetMarketing = 1,
NacpPlayReportPermission_Count = 2 ///< Total values supported by this enum.
NacpPlayReportPermission_TargetMarketing = BIT(0),
NacpPlayReportPermission_Count = 1 ///< Total values supported by this enum.
} NacpPlayReportPermission;
typedef enum {
@ -300,6 +328,16 @@ typedef enum {
NacpCrashScreenshotForDev_Count = 2 ///< Total values supported by this enum.
} NacpCrashScreenshotForDev;
typedef enum {
NacpContentsAvailabilityTransitionPolicy_NoPolicy = 0,
NacpContentsAvailabilityTransitionPolicy_Stable = 1,
NacpContentsAvailabilityTransitionPolicy_Changeable = 2,
NacpContentsAvailabilityTransitionPolicy_Count = 3, ///< Total values supported by this enum.
// Old.
NacpContentsAvailabilityTransitionPolicy_Legacy = NacpContentsAvailabilityTransitionPolicy_NoPolicy
} NacpContentsAvailabilityTransitionPolicy;
typedef struct {
u64 application_id[8];
} NacpAccessibleLaunchRequiredVersion;
@ -310,7 +348,7 @@ typedef struct {
NacpTitle title[0x10];
char isbn[0x25];
u8 startup_user_account; ///< NacpStartupUserAccount.
u8 user_account_switch_lock; ///< NacpUserAccountSwitchLock. Old: touch_screen_usage (None, Supported, Required).
u8 user_account_switch_lock; ///< NacpUserAccountSwitchLock.
u8 add_on_content_registration_type; ///< NacpAddOnContentRegistrationType.
u32 attribute; ///< NacpAttribute.
u32 supported_language; ///< NacpSupportedLanguage.
@ -335,14 +373,14 @@ typedef struct {
u8 logo_handling; ///< NacpLogoHandling.
u8 runtime_add_on_content_install; ///< NacpRuntimeAddOnContentInstall.
u8 runtime_parameter_delivery; ///< NacpRuntimeParameterDelivery.
u8 reserved_1;
u8 appropriate_age_for_china; ///< NacpAppropriateAgeForChina.
u8 undecided_parameter_75b8b; ///< NacpUndecidedParameter75b8b.
u8 crash_report; ///< NacpCrashReport.
u8 hdcp; ///< NacpHdcp.
u64 seed_for_pseudo_device_id;
char bcat_passphrase[0x41];
u8 startup_user_account_option; ///< NacpStartupUserAccountOption.
u8 reserved_2[0x6];
u8 reserved_for_user_account_save_data_operation[0x6];
s64 user_account_save_data_size_max;
s64 user_account_save_data_journal_size_max;
s64 device_save_data_size_max;
@ -352,22 +390,25 @@ typedef struct {
s64 cache_storage_journal_size;
s64 cache_storage_data_and_journal_size_max;
u16 cache_storage_index_max;
u8 reserved_3[0x6];
u8 reserved_1[0x1];
u8 runtime_upgrade; ///< NacpRuntimeUpgrade.
u32 supporting_limited_licenses; ///< NacpSupportingLimitedLicenses.
u64 play_log_queryable_application_id[0x10];
u8 play_log_query_capability; ///< NacpPlayLogQueryCapability.
u8 repair; ///< NacpRepair.
u8 program_index;
u8 required_network_service_license_on_launch; ///< NacpRequiredNetworkServiceLicenseOnLaunch.
u8 reserved_4[0x4];
u8 reserved_2[0x4];
NacpNeighborDetectionClientConfiguration neighbor_detection_client_configuration;
NacpJitConfiguration jit_configuration;
NacpRequiredAddOnContentsSetBinaryDescriptor required_add_on_contents_set_binary_descriptor;
u8 play_report_permission; ///< NacpPlayReportPermission.
u8 crash_screenshot_for_prod; ///< NacpCrashScreenshotForProd.
u8 crash_screenshot_for_dev; ///< NacpCrashScreenshotForDev.
u8 reserved_5[0x5];
u8 contents_availability_transition_policy; ///< NacpContentsAvailabilityTransitionPolicy.
u8 reserved_3[0x4];
NacpAccessibleLaunchRequiredVersion accessible_launch_required_version;
u8 reserved_6[0xBB8];
u8 reserved_4[0xBB8];
} _NacpStruct;
NXDT_ASSERT(_NacpStruct, 0x4000);
@ -413,8 +454,13 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
/// These functions return pointers to string representations of the input flag/value index (e.g. nacpGetLanguageString(NacpLanguage_AmericanEnglish) -> "AmericanEnglish").
/// If the input flag/value index is invalid, "Unknown" will be returned.
/// If dealing with a bitflag field such as NacpAttribute, NacpSupportedLanguage, etc., the provided value must be a 0-based index to the desired flag and not a bitmask from its enum.
/// (e.g. NacpAttribute_RetailInteractiveDisplay -> Use 1 instead).
/// If dealing with a bitflag field such as:
/// * NacpAttribute
/// * NacpSupportedLanguage
/// * NacpParentalControl
/// * NacpStartupUserAccountOption
/// * NacpRepair
/// Then, the provided value must be a 0-based index to the desired flag and not a bitmask from its enum (e.g. NacpAttribute_RetailInteractiveDisplay -> use 1 instead).
const char *nacpGetLanguageString(u8 language); /// Can also be used for NacpSupportedLanguage flags with values from the NacpLanguage enum.
const char *nacpGetStartupUserAccountString(u8 startup_user_account);
const char *nacpGetUserAccountSwitchLockString(u8 user_account_switch_lock);
@ -430,17 +476,18 @@ const char *nacpGetLogoTypeString(u8 logo_type);
const char *nacpGetLogoHandlingString(u8 logo_handling);
const char *nacpGetRuntimeAddOnContentInstallString(u8 runtime_add_on_content_install);
const char *nacpGetRuntimeParameterDeliveryString(u8 runtime_parameter_delivery);
const char *nacpGetAppropriateAgeForChina(u8 appropriate_age_for_china);
const char *nacpGetUndecidedParameter75b8bString(u8 undecided_parameter_75b8b);
const char *nacpGetCrashReportString(u8 crash_report);
const char *nacpGetHdcpString(u8 hdcp);
const char *nacpGetStartupUserAccountOptionString(u8 startup_user_account_option);
const char *nacpGetRuntimeUpgradeString(u8 runtime_upgrade);
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); ///< Uses an input u64 value.
const char *nacpGetPlayReportPermissionString(u8 play_report_permission);
const char *nacpGetCrashScreenshotForProdString(u8 crash_screenshot_for_prod);
const char *nacpGetCrashScreenshotForDevString(u8 crash_screenshot_for_dev);
const char *nacpGetContentsAvailabilityTransitionPolicyString(u8 contents_availability_transition_policy);
/// Helper inline functions.

@ -1 +1 @@
Subproject commit d6afc3c2ba17158553397d1f1d3a607da661f2ba
Subproject commit 0580fc38903546a99cc09e4f16418a3863e067b0

View file

@ -23,7 +23,10 @@
#include "cnmt.h"
#include "title.h"
/* Helper macros. */
#define CNMT_MINIMUM_FILENAME_LENGTH 23 /* Content Meta Type + "_" + Title ID + ".cnmt". */
#define CNMT_ADD_FMT_STR(fmt, ...) utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, fmt, ##__VA_ARGS__)
/* Global variables. */
@ -367,31 +370,33 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
cnmt_ctx->authoring_tool_xml = NULL;
cnmt_ctx->authoring_tool_xml_size = 0;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
if (!CNMT_ADD_FMT_STR("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
"<ContentMeta>\n" \
" <Type>%s</Type>\n" \
" <Id>0x%016lx</Id>\n" \
" <Version>%u</Version>\n" \
" <ReleaseVersion />\n" \
" <PrivateVersion />\n",
" <ReleaseVersion>%u</ReleaseVersion>\n" \
" <PrivateVersion>%u</PrivateVersion>\n", \
titleGetNcmContentMetaTypeName(cnmt_ctx->packaged_header->content_meta_type), \
cnmt_ctx->packaged_header->title_id, \
cnmt_ctx->packaged_header->version.value)) goto end;
cnmt_ctx->packaged_header->version.value, \
cnmt_ctx->packaged_header->version.application_version.release_ver, \
cnmt_ctx->packaged_header->version.application_version.private_ver)) goto end;
/* ContentMetaAttribute. */
for(i = 0; i < ContentMetaAttribute_Count; i++)
{
if (!(cnmt_ctx->packaged_header->content_meta_attribute & (u8)BIT(i))) continue;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <ContentMetaAttribute>%s</ContentMetaAttribute>\n", g_cnmtAttributeStrings[i])) goto end;
if (!CNMT_ADD_FMT_STR(" <ContentMetaAttribute>%s</ContentMetaAttribute>\n", g_cnmtAttributeStrings[i])) goto end;
count++;
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <ContentMetaAttribute />\n")) goto end;
if (!count && !CNMT_ADD_FMT_STR(" <ContentMetaAttribute />\n")) goto end;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <RequiredDownloadSystemVersion>%u</RequiredDownloadSystemVersion>\n", \
cnmt_ctx->packaged_header->required_download_system_version.value)) goto end;
/* RequiredDownloadSystemVersion. */
if (!CNMT_ADD_FMT_STR(" <RequiredDownloadSystemVersion>%u</RequiredDownloadSystemVersion>\n", cnmt_ctx->packaged_header->required_download_system_version.value)) goto end;
/* Contents. */
for(i = 0; i < nca_ctx_count; i++)
{
NcaContext *cur_nca_ctx = &(nca_ctx[i]);
@ -417,8 +422,7 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
goto end;
}
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <Content>\n" \
if (!CNMT_ADD_FMT_STR(" <Content>\n" \
" <Type>%s</Type>\n" \
" <Id>%s</Id>\n" \
" <Size>%lu</Size>\n" \
@ -436,8 +440,8 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
utilsGenerateHexStringFromData(digest_str, sizeof(digest_str), cnmt_ctx->digest, CNMT_DIGEST_SIZE, false);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <ContentMeta />\n" \
/* ContentMeta, Digest, KeyGenerationMin, KeepGeneration and KeepGenerationSpecified. */
if (!CNMT_ADD_FMT_STR(" <ContentMeta />\n" \
" <Digest>%s</Digest>\n" \
" <KeyGenerationMin>%u</KeyGenerationMin>\n" \
" <KeepGeneration />\n" \
@ -445,6 +449,8 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
digest_str, \
cnmt_ctx->nca_ctx->key_generation)) goto end;
/* RequiredSystemVersion (Application, Patch) / RequiredApplicationVersion (AddOnContent). */
/* PatchId (Application) / ApplicationId (Patch, AddOnContent). */
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)
{
@ -454,21 +460,20 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
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, \
" <%s>%u</%s>\n" \
if (!CNMT_ADD_FMT_STR(" <%s>%u</%s>\n" \
" <%s>0x%016lx</%s>\n", \
required_title_version_str, required_title_version, required_title_version_str, \
required_title_type_str, required_title_id, required_title_type_str)) goto end;
}
/* RequiredApplicationVersion (Application). */
if (cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Application)
{
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <RequiredApplicationVersion>%u</RequiredApplicationVersion>\n", \
if (!CNMT_ADD_FMT_STR(" <RequiredApplicationVersion>%u</RequiredApplicationVersion>\n", \
((ContentMetaApplicationMetaExtendedHeader*)cnmt_ctx->extended_header)->required_application_version.value)) goto end;
}
if (!(success = utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, "</ContentMeta>"))) goto end;
if (!(success = CNMT_ADD_FMT_STR("</ContentMeta>"))) goto end;
/* Update CNMT context. */
cnmt_ctx->authoring_tool_xml = xml_buf;

View file

@ -23,6 +23,23 @@
#include "nacp.h"
#include "title.h"
/* Helper macros. */
#define NACP_ADD_FMT_STR_T1(fmt, ...) utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, fmt, ##__VA_ARGS__)
#define NACP_ADD_FMT_STR_T2(fmt, ...) utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, fmt, ##__VA_ARGS__)
#define NACP_ADD_STR(tag_name, value) nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, tag_name, value)
#define NACP_ADD_ENUM(tag_name, value, str_func) nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, tag_name, value, \
&str_func)
#define NACP_ADD_BITFLAG(tag_name, flag, flag_width, max_flag_idx, str_func, allow_empty_str) nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, tag_name, flag, \
flag_width, max_flag_idx, &(str_func), \
allow_empty_str)
#define NACP_ADD_U16(tag_name, value, hex, prefix) nacpAddU16FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, tag_name, value, hex, \
prefix)
#define NACP_ADD_U32(tag_name, value, hex, prefix) nacpAddU32FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, tag_name, value, hex, \
prefix)
#define NACP_ADD_U64(tag_name, value, hex, prefix) nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, tag_name, value, hex, \
prefix)
/* Type definitions. */
typedef const char *(*NacpStringFunction)(u8 value); /* Used while adding fields to the AuthoringTool-like XML. */
@ -68,7 +85,8 @@ static const char *g_nacpAddOnContentRegistrationTypeStrings[NacpAddOnContentReg
static const char *g_nacpAttributeStrings[NacpAttribute_Count] = {
"Demo",
"RetailInteractiveDisplay"
"RetailInteractiveDisplay",
"DownloadPlay"
};
static const char *g_nacpParentalControlStrings[NacpParentalControl_Count] = {
@ -137,6 +155,13 @@ static const char *g_nacpRuntimeParameterDeliveryStrings[NacpRuntimeParameterDel
"OnRestart"
};
static const char *g_nacpAppropriateAgeForChinaStrings[NacpAppropriateAgeForChina_Count] = {
"None",
"Age8",
"Age12",
"Age16"
};
static const char *g_nacpUndecidedParameter75b8bStrings[NacpUndecidedParameter75b8b_Count] = {
"a",
"b"
@ -156,6 +181,11 @@ static const char *g_nacpStartupUserAccountOptionStrings[NacpStartupUserAccountO
"IsOptional"
};
static const char *g_nacpRuntimeUpgradeStrings[NacpRuntimeUpgrade_Count] = {
"Deny",
"Allow"
};
static const char *g_nacpPlayLogQueryCapabilityStrings[NacpPlayLogQueryCapability_Count] = {
"None",
"WhiteList",
@ -170,16 +200,6 @@ static const char *g_nacpRequiredNetworkServiceLicenseOnLaunchStrings[NacpRequir
"Common"
};
static const char *g_nacpJitConfigurationFlagStrings[NacpJitConfigurationFlag_Count] = {
"false",
"true"
};
static const char *g_nacpPlayReportPermissionStrings[NacpPlayReportPermission_Count] = {
"Deny",
"Allow"
};
static const char *g_nacpCrashScreenshotForProdStrings[NacpCrashScreenshotForProd_Count] = {
"Deny",
"Allow"
@ -190,13 +210,19 @@ static const char *g_nacpCrashScreenshotForDevStrings[NacpCrashScreenshotForDev_
"Allow"
};
static const char *g_nacpContentsAvailabilityTransitionPolicyStrings[NacpContentsAvailabilityTransitionPolicy_Count] = {
"NoPolicy",
"Stable",
"Changeable"
};
/* Function prototypes. */
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 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, bool allow_empty_str);
static bool nacpAddU16FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u16 value, bool hex, bool prefix);
static bool nacpAddU32FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u32 value, bool hex, bool prefix);
static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u64 value, bool hex, bool prefix);
@ -424,6 +450,8 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
_NacpStruct *nacp = nacp_ctx->data;
Version app_ver = { .value = version };
u8 i = 0, count = 0;
char *xml_buf = NULL;
u64 xml_buf_size = 0;
@ -437,6 +465,9 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
NacpNeighborDetectionClientConfiguration *ndcc = &(nacp->neighbor_detection_client_configuration);
NacpRequiredAddOnContentsSetBinaryDescriptor *raocsbd = &(nacp->required_add_on_contents_set_binary_descriptor);
bool raocsbd_available = false;
bool alrv_available = false;
bool success = false;
@ -445,8 +476,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
nacp_ctx->authoring_tool_xml = NULL;
nacp_ctx->authoring_tool_xml_size = 0;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
if (!NACP_ADD_FMT_STR_T1("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
"<Application>\n")) goto end;
/* Title. */
@ -455,8 +485,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
NacpTitle *title = &(nacp->title[i]);
if (!*(title->name) || !*(title->publisher)) continue;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <Title>\n" \
if (!NACP_ADD_FMT_STR_T1(" <Title>\n" \
" <Language>%s</Language>\n" \
" <Name>%s</Name>\n" \
" <Publisher>%s</Publisher>\n" \
@ -468,43 +497,41 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
count++;
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <Title />\n")) goto end;
if (!count && !NACP_ADD_FMT_STR_T1(" <Title />\n")) goto end;
/* Isbn. */
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Isbn", nacp->isbn)) goto end;
if (!NACP_ADD_STR("Isbn", nacp->isbn)) goto end;
/* StartupUserAccount. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccount", nacp->startup_user_account, &nacpGetStartupUserAccountString)) goto end;
if (!NACP_ADD_ENUM("StartupUserAccount", nacp->startup_user_account, nacpGetStartupUserAccountString)) goto end;
/* StartupUserAccountOption. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccountOption", &(nacp->startup_user_account_option), sizeof(nacp->startup_user_account_option), \
NacpStartupUserAccountOption_Count, &nacpGetStartupUserAccountOptionString)) goto end;
if (!NACP_ADD_BITFLAG("StartupUserAccountOption", &(nacp->startup_user_account_option), sizeof(nacp->startup_user_account_option), NacpStartupUserAccountOption_Count, \
nacpGetStartupUserAccountOptionString, true)) goto end;
/* UserAccountSwitchLock. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSwitchLock", nacp->user_account_switch_lock, &nacpGetUserAccountSwitchLockString)) goto end;
if (!NACP_ADD_ENUM("UserAccountSwitchLock", nacp->user_account_switch_lock, nacpGetUserAccountSwitchLockString)) goto end;
/* Attribute. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Attribute", &(nacp->attribute), sizeof(nacp->attribute), NacpAttribute_Count, &nacpGetAttributeString)) goto end;
if (!NACP_ADD_BITFLAG("Attribute", &(nacp->attribute), sizeof(nacp->attribute), NacpAttribute_Count, nacpGetAttributeString, false)) goto end;
/* ParentalControl. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ParentalControl", &(nacp->parental_control), sizeof(nacp->parental_control), NacpParentalControl_Count, \
&nacpGetParentalControlString)) goto end;
if (!NACP_ADD_BITFLAG("ParentalControl", &(nacp->parental_control), sizeof(nacp->parental_control), NacpParentalControl_Count, nacpGetParentalControlString, false)) goto end;
/* SupportedLanguage. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SupportedLanguage", &(nacp->supported_language), sizeof(nacp->supported_language), NacpSupportedLanguage_Count, \
&nacpGetLanguageString)) goto end;
if (!NACP_ADD_BITFLAG("SupportedLanguage", &(nacp->supported_language), sizeof(nacp->supported_language), NacpSupportedLanguage_Count, nacpGetLanguageString, false)) goto end;
/* Screenshot. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Screenshot", nacp->screenshot, &nacpGetScreenshotString)) goto end;
if (!NACP_ADD_ENUM("Screenshot", nacp->screenshot, nacpGetScreenshotString)) goto end;
/* VideoCapture. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "VideoCapture", nacp->video_capture, &nacpGetVideoCaptureString)) goto end;
if (!NACP_ADD_ENUM("VideoCapture", nacp->video_capture, nacpGetVideoCaptureString)) goto end;
/* PresenceGroupId. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PresenceGroupId", nacp->presence_group_id, true, true)) goto end;
if (!NACP_ADD_U64("PresenceGroupId", nacp->presence_group_id, true, true)) goto end;
/* DisplayVersion. */
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DisplayVersion", nacp->display_version)) goto end;
if (!NACP_ADD_STR("DisplayVersion", nacp->display_version)) goto end;
/* Rating. */
for(i = 0, count = 0; i < NacpRatingAgeOrganization_Count; i++)
@ -512,8 +539,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
s8 age = *(((s8*)&(nacp->rating_age)) + i);
if (age < 0) continue;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <Rating>\n" \
if (!NACP_ADD_FMT_STR_T1(" <Rating>\n" \
" <Organization>%s</Organization>\n" \
" <Age>%d</Age>\n" \
" </Rating>\n", \
@ -523,67 +549,65 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
count++;
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <Rating />\n")) goto end;
if (!count && !NACP_ADD_FMT_STR_T1(" <Rating />\n")) goto end;
/* DataLossConfirmation. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DataLossConfirmation", nacp->data_loss_confirmation, &nacpGetDataLossConfirmationString)) goto end;
if (!NACP_ADD_ENUM("DataLossConfirmation", nacp->data_loss_confirmation, nacpGetDataLossConfirmationString)) goto end;
/* PlayLogPolicy. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayLogPolicy", nacp->play_log_policy, &nacpGetPlayLogPolicyString)) goto end;
if (!NACP_ADD_ENUM("PlayLogPolicy", nacp->play_log_policy, nacpGetPlayLogPolicyString)) goto end;
/* SaveDataOwnerId. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SaveDataOwnerId", nacp->save_data_owner_id, true, true)) goto end;
if (!NACP_ADD_U64("SaveDataOwnerId", nacp->save_data_owner_id, true, true)) goto end;
/* UserAccountSaveDataSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSaveDataSize", (u64)nacp->user_account_save_data_size, true, true)) goto end;
if (!NACP_ADD_U64("UserAccountSaveDataSize", (u64)nacp->user_account_save_data_size, true, true)) goto end;
/* UserAccountSaveDataJournalSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSaveDataJournalSize", (u64)nacp->user_account_save_data_journal_size, true, true)) goto end;
if (!NACP_ADD_U64("UserAccountSaveDataJournalSize", (u64)nacp->user_account_save_data_journal_size, true, true)) goto end;
/* UserAccountSaveDataTotalSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSaveDataTotalSize", (u64)(nacp->user_account_save_data_size + nacp->user_account_save_data_journal_size), true, true)) goto end;
if (!NACP_ADD_U64("UserAccountSaveDataTotalSize", (u64)(nacp->user_account_save_data_size + nacp->user_account_save_data_journal_size), true, true)) goto end;
/* DeviceSaveDataSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DeviceSaveDataSize", (u64)nacp->device_save_data_size, true, true)) goto end;
if (!NACP_ADD_U64("DeviceSaveDataSize", (u64)nacp->device_save_data_size, true, true)) goto end;
/* DeviceSaveDataJournalSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DeviceSaveDataJournalSize", (u64)nacp->device_save_data_journal_size, true, true)) goto end;
if (!NACP_ADD_U64("DeviceSaveDataJournalSize", (u64)nacp->device_save_data_journal_size, true, true)) goto end;
/* BcatDeliveryCacheStorageSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "BcatDeliveryCacheStorageSize", (u64)nacp->bcat_delivery_cache_storage_size, true, true)) goto end;
if (!NACP_ADD_U64("BcatDeliveryCacheStorageSize", (u64)nacp->bcat_delivery_cache_storage_size, true, true)) goto end;
/* ApplicationErrorCodeCategory. */
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ApplicationErrorCodeCategory", nacp->application_error_code_category)) goto end;
if (!NACP_ADD_STR("ApplicationErrorCodeCategory", nacp->application_error_code_category)) goto end;
/* AddOnContentBaseId. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "AddOnContentBaseId", nacp->add_on_content_base_id, true, true)) goto end;
if (!NACP_ADD_U64("AddOnContentBaseId", nacp->add_on_content_base_id, true, true)) goto end;
/* Version. */
if (!nacpAddU32FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Version", version, false, false)) goto end;
if (!NACP_ADD_U32("Version", version, false, false)) goto end;
/* ReleaseVersion and PrivateVersion. Unused but kept anyway. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <ReleaseVersion />\n" \
" <PrivateVersion />\n")) goto end;
/* ReleaseVersion. */
if (!NACP_ADD_U32("ReleaseVersion", app_ver.application_version.release_ver, false, false)) goto end;
/* PrivateVersion. */
if (!NACP_ADD_U32("PrivateVersion", app_ver.application_version.private_ver, false, false)) goto end;
/* LogoType. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "LogoType", nacp->logo_type, &nacpGetLogoTypeString)) goto end;
if (!NACP_ADD_ENUM("LogoType", nacp->logo_type, nacpGetLogoTypeString)) goto end;
/* RequiredSystemVersion. */
if (!nacpAddU32FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RequiredSystemVersion", required_system_version, false, false)) goto end;
if (!NACP_ADD_U32("RequiredSystemVersion", required_system_version, false, false)) goto end;
/* LocalCommunicationId. */
for(i = 0, count = 0; i < 0x8; i++)
for(i = 0; i < 0x8; i++)
{
if (!nacp->local_communication_id[i]) continue;
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "LocalCommunicationId", nacp->local_communication_id[i], true, true)) goto end;
count++;
if (!NACP_ADD_U64("LocalCommunicationId", nacp->local_communication_id[i], true, true)) goto end;
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <LocalCommunicationId />\n")) goto end;
/* LogoHandling. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "LogoHandling", nacp->logo_handling, &nacpGetLogoHandlingString)) goto end;
if (!NACP_ADD_ENUM("LogoHandling", nacp->logo_handling, nacpGetLogoHandlingString)) goto end;
/* Icon. */
for(i = 0, count = 0; i < nacp_ctx->icon_count; i++)
@ -597,12 +621,11 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
utilsGenerateHexStringFromData(icon_hash_str, sizeof(icon_hash_str), icon_hash, sizeof(icon_hash) / 2, false);
/* Add XML element. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <Icon>\n" \
if (!NACP_ADD_FMT_STR_T1(" <Icon>\n" \
" <Language>%s</Language>\n" \
" <IconPath />\n" \
/*" <IconPath />\n" \
" <NxIconPath />\n" \
" <RawIconHash />\n" \
" <RawIconHash />\n" \*/
" <NxIconHash>%s</NxIconHash>\n" \
" </Icon>\n", \
nacpGetLanguageString(icon_ctx->language), \
@ -611,87 +634,83 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
count++;
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <Icon />\n")) goto end;
if (!count && !NACP_ADD_FMT_STR_T1(" <Icon />\n")) 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;
if (!NACP_ADD_FMT_STR_T1(" <HtmlDocumentPath UseEnvironmentVariable=\"false\" />\n" \
" <LegalInformationFilePath UseEnvironmentVariable=\"false\" />\n" \
" <AccessibleUrlsFilePath UseEnvironmentVariable=\"false\" />\n")) goto end;
/* SeedForPseudoDeviceId. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SeedForPseudoDeviceId", nacp->seed_for_pseudo_device_id, true, false)) goto end;
if (!NACP_ADD_U64("SeedForPseudoDeviceId", nacp->seed_for_pseudo_device_id, true, false)) goto end;
/* BcatPassphrase. */
if (!nacpAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "BcatPassphrase", nacp->bcat_passphrase)) goto end;
if (!NACP_ADD_STR("BcatPassphrase", nacp->bcat_passphrase)) goto end;
/* AddOnContentRegistrationType. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "AddOnContentRegistrationType", nacp->add_on_content_registration_type, &nacpGetAddOnContentRegistrationTypeString)) goto end;
if (!NACP_ADD_ENUM("AddOnContentRegistrationType", nacp->add_on_content_registration_type, nacpGetAddOnContentRegistrationTypeString)) goto end;
/* UserAccountSaveDataSizeMax. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSaveDataSizeMax", (u64)nacp->user_account_save_data_size_max, true, true)) goto end;
if (!NACP_ADD_U64("UserAccountSaveDataSizeMax", (u64)nacp->user_account_save_data_size_max, true, true)) goto end;
/* UserAccountSaveDataJournalSizeMax. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSaveDataJournalSizeMax", (u64)nacp->user_account_save_data_journal_size_max, true, true)) goto end;
if (!NACP_ADD_U64("UserAccountSaveDataJournalSizeMax", (u64)nacp->user_account_save_data_journal_size_max, true, true)) goto end;
/* DeviceSaveDataSizeMax. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DeviceSaveDataSizeMax", (u64)nacp->device_save_data_size_max, true, true)) goto end;
if (!NACP_ADD_U64("DeviceSaveDataSizeMax", (u64)nacp->device_save_data_size_max, true, true)) goto end;
/* DeviceSaveDataJournalSizeMax. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "DeviceSaveDataJournalSizeMax", (u64)nacp->device_save_data_journal_size_max, true, true)) goto end;
if (!NACP_ADD_U64("DeviceSaveDataJournalSizeMax", (u64)nacp->device_save_data_journal_size_max, true, true)) goto end;
/* TemporaryStorageSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "TemporaryStorageSize", (u64)nacp->temporary_storage_size, true, true)) goto end;
if (!NACP_ADD_U64("TemporaryStorageSize", (u64)nacp->temporary_storage_size, true, true)) goto end;
/* CacheStorageSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CacheStorageSize", (u64)nacp->cache_storage_size, true, true)) goto end;
if (!NACP_ADD_U64("CacheStorageSize", (u64)nacp->cache_storage_size, true, true)) goto end;
/* CacheStorageJournalSize. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CacheStorageJournalSize", (u64)nacp->cache_storage_journal_size, true, true)) goto end;
if (!NACP_ADD_U64("CacheStorageJournalSize", (u64)nacp->cache_storage_journal_size, true, true)) goto end;
/* CacheStorageDataAndJournalSizeMax. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CacheStorageDataAndJournalSizeMax", (u64)nacp->cache_storage_data_and_journal_size_max, true, true)) goto end;
if (!NACP_ADD_U64("CacheStorageDataAndJournalSizeMax", (u64)nacp->cache_storage_data_and_journal_size_max, true, true)) goto end;
/* CacheStorageIndexMax. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CacheStorageIndexMax", (u64)nacp->cache_storage_index_max, true, true)) goto end;
if (!NACP_ADD_U64("CacheStorageIndexMax", (u64)nacp->cache_storage_index_max, true, true)) goto end;
/* Hdcp. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Hdcp", nacp->hdcp, &nacpGetHdcpString)) goto end;
if (!NACP_ADD_ENUM("Hdcp", nacp->hdcp, nacpGetHdcpString)) goto end;
/* CrashReport. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CrashReport", nacp->crash_report, &nacpGetCrashReportString)) goto end;
if (!NACP_ADD_ENUM("CrashReport", nacp->crash_report, nacpGetCrashReportString)) goto end;
/* CrashScreenshotForProd. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CrashScreenshotForProd", nacp->crash_screenshot_for_prod, &nacpGetCrashScreenshotForProdString)) goto end;
if (!NACP_ADD_ENUM("CrashScreenshotForProd", nacp->crash_screenshot_for_prod, nacpGetCrashScreenshotForProdString)) goto end;
/* CrashScreenshotForDev. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "CrashScreenshotForDev", nacp->crash_screenshot_for_dev, &nacpGetCrashScreenshotForDevString)) goto end;
if (!NACP_ADD_ENUM("CrashScreenshotForDev", nacp->crash_screenshot_for_dev, nacpGetCrashScreenshotForDevString)) goto end;
/* RuntimeAddOnContentInstall. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RuntimeAddOnContentInstall", nacp->runtime_add_on_content_install, &nacpGetRuntimeAddOnContentInstallString)) goto end;
if (!NACP_ADD_ENUM("RuntimeAddOnContentInstall", nacp->runtime_add_on_content_install, nacpGetRuntimeAddOnContentInstallString)) goto end;
/* PlayLogQueryableApplicationId. */
for(i = 0, count = 0; i < 0x10; i++)
for(i = 0; i < 0x10; i++)
{
if (!nacp->play_log_queryable_application_id[i]) continue;
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayLogQueryableApplicationId", nacp->play_log_queryable_application_id[i], true, true)) goto end;
count++;
if (!NACP_ADD_U64("PlayLogQueryableApplicationId", nacp->play_log_queryable_application_id[i], true, true)) goto end;
}
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;
if (!NACP_ADD_ENUM("PlayLogQueryCapability", nacp->play_log_query_capability, nacpGetPlayLogQueryCapabilityString)) goto end;
/* Repair. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Repair", &(nacp->repair), sizeof(nacp->repair), NacpRepair_Count, &nacpGetRepairString)) goto end;
if (!NACP_ADD_BITFLAG("Repair", &(nacp->repair), sizeof(nacp->repair), NacpRepair_Count, nacpGetRepairString, false)) goto end;
/* ProgramIndex. */
if (!nacpAddU16FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ProgramIndex", nacp->program_index, false, false)) goto end;
if (!NACP_ADD_U16("ProgramIndex", nacp->program_index, false, false)) goto end;
/* RequiredNetworkServiceLicenseOnLaunch. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RequiredNetworkServiceLicenseOnLaunch", &(nacp->required_network_service_license_on_launch), \
sizeof(nacp->required_network_service_license_on_launch), NacpRequiredNetworkServiceLicenseOnLaunch_Count, &nacpGetRequiredNetworkServiceLicenseOnLaunchString)) goto end;
if (!NACP_ADD_BITFLAG("RequiredNetworkServiceLicenseOnLaunch", &(nacp->required_network_service_license_on_launch), sizeof(nacp->required_network_service_license_on_launch), \
NacpRequiredNetworkServiceLicenseOnLaunch_Count, nacpGetRequiredNetworkServiceLicenseOnLaunchString, false)) goto end;
/* NeighborDetectionClientConfiguration. */
ndcc_sgc_available = (ndcc->send_group_configuration.group_id && memcmp(ndcc->send_group_configuration.key, null_key, sizeof(null_key)));
@ -704,13 +723,12 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
if (ndcc_sgc_available || ndcc_rgc_available)
{
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <NeighborDetectionClientConfiguration>\n")) goto end;
if (!NACP_ADD_FMT_STR_T1(" <NeighborDetectionClientConfiguration>\n")) goto end;
/* SendGroupConfiguration. */
utilsGenerateHexStringFromData(key_str, sizeof(key_str), ndcc->send_group_configuration.key, sizeof(ndcc->send_group_configuration.key), false);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <SendGroupConfiguration>\n" \
if (!NACP_ADD_FMT_STR_T1(" <SendGroupConfiguration>\n" \
" <GroupId>0x%016lx</GroupId>\n" \
" <Key>%s</Key>\n" \
" </SendGroupConfiguration>\n", \
@ -724,8 +742,7 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
utilsGenerateHexStringFromData(key_str, sizeof(key_str), rgc->key, sizeof(rgc->key), false);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <ReceivableGroupConfiguration>\n" \
if (!NACP_ADD_FMT_STR_T1(" <ReceivableGroupConfiguration>\n" \
" <GroupId>0x%016lx</GroupId>\n" \
" <Key>%s</Key>\n" \
" </ReceivableGroupConfiguration>\n", \
@ -733,76 +750,114 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
key_str)) goto end;
}
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " </NeighborDetectionClientConfiguration>\n")) goto end;
} else {
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <NeighborDetectionClientConfiguration />\n")) goto end;
if (!NACP_ADD_FMT_STR_T1(" </NeighborDetectionClientConfiguration>\n")) goto end;
}
/* JitConfiguration. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <Jit>\n" \
if (!NACP_ADD_FMT_STR_T1(" <Jit>\n" \
" <IsEnabled>%s</IsEnabled>\n" \
" <MemorySize>%lu</MemorySize>\n" \
" </Jit>\n", \
nacpGetJitConfigurationFlagString(nacp->jit_configuration.jit_configuration_flag), \
(nacp->jit_configuration.jit_configuration_flag & NacpJitConfigurationFlag_Enabled) ? "true" : "false", \
nacp->jit_configuration.memory_size)) goto end;
/* History. Unused but kept anyway. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <History />\n")) goto end;
/* History. */
//if (!NACP_ADD_FMT_STR_T1(" <History />\n")) goto end;
/* RuntimeParameterDelivery. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RuntimeParameterDelivery", nacp->runtime_parameter_delivery, &nacpGetRuntimeParameterDeliveryString)) goto end;
if (!NACP_ADD_ENUM("RuntimeParameterDelivery", nacp->runtime_parameter_delivery, nacpGetRuntimeParameterDeliveryString)) goto end;
/* AppropriateAgeForChina. */
if (!NACP_ADD_ENUM("AppropriateAgeForChina", nacp->appropriate_age_for_china, nacpGetAppropriateAgeForChina)) goto end;
/* RequiredAddOnContentsSet. */
for(i = 0, count = 0; i < 0x20; i++)
for(i = 0; i < 0x20; i++)
{
NacpDescriptors *descriptor = &(raocsbd->descriptors[i]);
if (!descriptor->index || !descriptor->continue_set) continue;
NacpRequiredAddOnContentsSetDescriptor *descriptor = &(raocsbd->descriptors[i]);
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <RequiredAddOnContentsSet>\n" \
" <Index>%u</Index>\n" \
" </RequiredAddOnContentsSet>\n", \
descriptor->index)) goto end;
count++;
if (descriptor->index)
{
raocsbd_available = true;
break;
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <RequiredAddOnContentsSet />\n")) goto end;
if (descriptor->flag != NacpRequiredAddOnContentsSetDescriptorFlag_Continue) break;
}
if (raocsbd_available)
{
if (!NACP_ADD_FMT_STR_T1(" <RequiredAddOnContentsSet>\n")) goto end;
for(i = 0; i < 0x20; i++)
{
NacpRequiredAddOnContentsSetDescriptor *descriptor = &(raocsbd->descriptors[i]);
if (!descriptor->index) continue;
if (!NACP_ADD_FMT_STR_T1(" <Index>%u</Index>\n", descriptor->index)) goto end;
if (descriptor->flag != NacpRequiredAddOnContentsSetDescriptorFlag_Continue) break;
}
if (!NACP_ADD_FMT_STR_T1(" </RequiredAddOnContentsSet>\n")) goto end;
}
/* PlayReportPermission. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <PlayReportPermission>\n" \
if (!NACP_ADD_FMT_STR_T1(" <PlayReportPermission>\n" \
" <TargetMarketing>%s</TargetMarketing>\n" \
" </PlayReportPermission>\n", \
nacpGetPlayReportPermissionString(nacp->play_report_permission))) goto end;
(nacp->play_report_permission & NacpPlayReportPermission_TargetMarketing) ? "Allow" : "Deny")) goto end;
/* AccessibleLaunchRequiredVersion. */
for(i = 0, count = 0; i < 0x8; i++)
for(i = 0; i < 0x8; i++)
{
if (!nacp->accessible_launch_required_version.application_id[i]) continue;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <AccessibleLaunchRequiredVersion>\n" \
" <ApplicationId>0x%016lx</ApplicationId>\n" \
" </AccessibleLaunchRequiredVersion>\n", \
nacp->accessible_launch_required_version.application_id[i])) goto end;
count++;
if (nacp->accessible_launch_required_version.application_id[i])
{
alrv_available = true;
break;
}
}
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <AccessibleLaunchRequiredVersion />\n")) goto end;
if (alrv_available)
{
if (!NACP_ADD_FMT_STR_T1(" <AccessibleLaunchRequiredVersion>\n")) goto end;
for(i = 0; i < 0x8; i++)
{
u64 id = nacp->accessible_launch_required_version.application_id[i];
if (!id) continue;
if (!NACP_ADD_FMT_STR_T1(" <ApplicationId>0x%016lx</ApplicationId>\n", id)) goto end;
}
if (!NACP_ADD_FMT_STR_T1(" </AccessibleLaunchRequiredVersion>\n")) goto end;
} else {
if (!NACP_ADD_FMT_STR_T1(" <AccessibleLaunchRequiredVersion />\n")) goto end;
}
/* UndecidedParameter75b8b. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UndecidedParameter75b8b", nacp->undecided_parameter_75b8b, &nacpGetUndecidedParameter75b8bString)) goto end;
if (!NACP_ADD_ENUM("UndecidedParameter75b8b", nacp->undecided_parameter_75b8b, nacpGetUndecidedParameter75b8bString)) goto end;
/* ApplicationId. */
if (!nacpAddU64FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ApplicationId", nacp_ctx->nca_ctx->header.program_id, true, true)) goto end;
if (!NACP_ADD_U64("ApplicationId", nacp_ctx->nca_ctx->header.program_id, true, true)) goto end;
/* FilterDescriptionFilePath. Unused but kept anyway. */
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <FilterDescriptionFilePath />\n")) goto end;
/* FilterDescriptionFilePath and CompressionFileConfigurationFilePath. */
/*if (!NACP_ADD_FMT_STR_T1(" <FilterDescriptionFilePath />\n" \
" <CompressionFileConfigurationFilePath />\n")) goto end;*/
if (!(success = utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, "</Application>"))) goto end;
/* ContentsAvailabilityTransitionPolicy. */
if (!NACP_ADD_ENUM("ContentsAvailabilityTransitionPolicy", nacp->contents_availability_transition_policy, nacpGetContentsAvailabilityTransitionPolicyString)) goto end;
/* LimitedLicenseSettings. */
if (!NACP_ADD_FMT_STR_T1(" <LimitedLicenseSettings>\n" \
" <RuntimeUpgrade>%s</RuntimeUpgrade>\n" \
" <SupportingLimitedLicenses>\n" \
" <LimitedLicense>%s</LimitedLicense>\n" \
" </SupportingLimitedLicenses>\n" \
" </LimitedLicenseSettings>\n", \
nacpGetRuntimeUpgradeString(nacp->runtime_upgrade), \
(nacp->supporting_limited_licenses & NacpSupportingLimitedLicenses_Demo) ? "Demo" : "None")) goto end;
if (!(success = NACP_ADD_FMT_STR_T1("</Application>"))) goto end;
/* Update NACP context. */
nacp_ctx->authoring_tool_xml = xml_buf;
@ -893,6 +948,11 @@ const char *nacpGetRuntimeParameterDeliveryString(u8 runtime_parameter_delivery)
return (runtime_parameter_delivery < NacpRuntimeParameterDelivery_Count ? g_nacpRuntimeParameterDeliveryStrings[runtime_parameter_delivery] : g_unknownString);
}
const char *nacpGetAppropriateAgeForChina(u8 appropriate_age_for_china)
{
return (appropriate_age_for_china < NacpAppropriateAgeForChina_Count ? g_nacpAppropriateAgeForChinaStrings[appropriate_age_for_china] : g_unknownString);
}
const char *nacpGetUndecidedParameter75b8bString(u8 undecided_parameter_75b8b)
{
return (undecided_parameter_75b8b < NacpUndecidedParameter75b8b_Count ? g_nacpUndecidedParameter75b8bStrings[undecided_parameter_75b8b] : g_unknownString);
@ -913,6 +973,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 *nacpGetRuntimeUpgradeString(u8 runtime_upgrade)
{
return (runtime_upgrade < NacpRuntimeUpgrade_Count ? g_nacpRuntimeUpgradeStrings[runtime_upgrade] : 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);
@ -929,16 +994,6 @@ const char *nacpGetRequiredNetworkServiceLicenseOnLaunchString(u8 required_netwo
g_nacpRequiredNetworkServiceLicenseOnLaunchStrings[required_network_service_license_on_launch] : g_unknownString);
}
const char *nacpGetJitConfigurationFlagString(u64 jig_configuration_flag)
{
return (jig_configuration_flag < NacpJitConfigurationFlag_Count ? g_nacpJitConfigurationFlagStrings[jig_configuration_flag] : g_unknownString);
}
const char *nacpGetPlayReportPermissionString(u8 play_report_permission)
{
return (play_report_permission < NacpPlayReportPermission_Count ? g_nacpPlayReportPermissionStrings[play_report_permission] : g_unknownString);
}
const char *nacpGetCrashScreenshotForProdString(u8 crash_screenshot_for_prod)
{
return (crash_screenshot_for_prod < NacpCrashScreenshotForProd_Count ? g_nacpCrashScreenshotForProdStrings[crash_screenshot_for_prod] : g_unknownString);
@ -949,6 +1004,12 @@ const char *nacpGetCrashScreenshotForDevString(u8 crash_screenshot_for_dev)
return (crash_screenshot_for_dev < NacpCrashScreenshotForDev_Count ? g_nacpCrashScreenshotForDevStrings[crash_screenshot_for_dev] : g_unknownString);
}
const char *nacpGetContentsAvailabilityTransitionPolicyString(u8 contents_availability_transition_policy)
{
return (contents_availability_transition_policy < NacpContentsAvailabilityTransitionPolicy_Count ? \
g_nacpContentsAvailabilityTransitionPolicyStrings[contents_availability_transition_policy] : g_unknownString);
}
NX_INLINE bool nacpCheckBitflagField(const void *flag, u8 flag_bitcount, u8 idx)
{
if (!flag || !flag_bitcount || !IS_POWER_OF_TWO(flag_bitcount) || idx >= flag_bitcount) return false;
@ -966,8 +1027,7 @@ static bool nacpAddStringFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_si
return false;
}
return (*value ? utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%s</%s>\n", tag_name, value, tag_name) : \
utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s />\n", tag_name));
return (*value ? NACP_ADD_FMT_STR_T2(" <%s>%s</%s>\n", tag_name, value, tag_name) : NACP_ADD_FMT_STR_T2(" <%s />\n", tag_name));
}
static bool nacpAddEnumFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u8 value, NacpStringFunction str_func)
@ -978,10 +1038,10 @@ static bool nacpAddEnumFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size
return false;
}
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%s</%s>\n", tag_name, str_func(value), tag_name);
return NACP_ADD_FMT_STR_T2(" <%s>%s</%s>\n", tag_name, str_func(value), tag_name);
}
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 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, bool allow_empty_str)
{
u8 flag_bitcount = 0, i = 0, count = 0;
const u8 *flag_u8 = (const u8*)flag;
@ -1008,7 +1068,7 @@ 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 (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%s</%s>\n", tag_name, str_func(i), tag_name)) goto end;
if (!NACP_ADD_FMT_STR_T2(" <%s>%s</%s>\n", tag_name, str_func(i), tag_name)) goto end;
count++;
}
@ -1016,7 +1076,7 @@ static bool nacpAddBitflagFieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_s
if (!count) empty_flag = true;
}
if (empty_flag && !utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s />\n", tag_name)) goto end;
if (empty_flag && allow_empty_str && !NACP_ADD_FMT_STR_T2(" <%s />\n", tag_name)) goto end;
success = true;
@ -1034,7 +1094,7 @@ static bool nacpAddU16FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size,
const char *str = (hex ? (prefix ? " <%s>0x%04x</%s>\n" : " <%s>%04x</%s>\n") : " <%s>%u</%s>\n");
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, str, tag_name, value, tag_name);
return NACP_ADD_FMT_STR_T2(str, tag_name, value, tag_name);
}
static bool nacpAddU32FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u32 value, bool hex, bool prefix)
@ -1047,7 +1107,7 @@ static bool nacpAddU32FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size,
const char *str = (hex ? (prefix ? " <%s>0x%08x</%s>\n" : " <%s>%08x</%s>\n") : " <%s>%u</%s>\n");
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, str, tag_name, value, tag_name);
return NACP_ADD_FMT_STR_T2(str, tag_name, value, tag_name);
}
static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, const char *tag_name, u64 value, bool hex, bool prefix)
@ -1060,5 +1120,5 @@ static bool nacpAddU64FieldToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size,
const char *str = (hex ? (prefix ? " <%s>0x%016lx</%s>\n" : " <%s>%016lx</%s>\n") : " <%s>%lu</%s>\n");
return utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, str, tag_name, value, tag_name);
return NACP_ADD_FMT_STR_T2(str, tag_name, value, tag_name);
}

View file

@ -159,7 +159,8 @@ bool utilsInitializeResources(const int program_argc, const char **program_argv)
LOG_MSG("Running under %s mode.", _utilsAppletModeCheck() ? "applet" : "title override");
/* Create output directories (SD card only). */
utilsCreateOutputDirectories(NULL);
/* TODO: remove the APP_TITLE check whenever we're ready for a release. */
if (!strcasecmp(APP_TITLE, "nxdumptool")) utilsCreateOutputDirectories(NULL);
if (g_appLaunchPath)
{

View file

@ -25,6 +25,11 @@
#include "program_info.h"
#include "elf_symbol.h"
/* Helper macros. */
#define PI_ADD_FMT_STR_T1(fmt, ...) utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, fmt, ##__VA_ARGS__)
#define PI_ADD_FMT_STR_T2(fmt, ...) utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, fmt, ##__VA_ARGS__)
/* Global variables. */
static const char *g_trueString = "True", *g_falseString = "False";
@ -203,15 +208,13 @@ bool programInfoGenerateAuthoringToolXml(ProgramInfoContext *program_info_ctx)
/* Get SDK version and build type strings. */
if (!programInfoGetSdkVersionAndBuildTypeFromSdkNso(program_info_ctx, &sdk_version, &build_type)) goto end;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
if (!PI_ADD_FMT_STR_T1("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
"<ProgramInfo>\n")) goto end;
/* SdkVersion. */
if (!programInfoAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SdkVersion", sdk_version)) goto end;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <ToolVersion />\n" /* Impossible to get. */ \
if (!PI_ADD_FMT_STR_T1(" <ToolVersion />\n" /* Impossible to get. */ \
" <NxAddonVersion>%s</NxAddonVersion>\n" \
" <PatchToolVersion />\n" /* Impossible to get. */ \
" <BuildTarget>%u</BuildTarget>\n", \
@ -221,8 +224,7 @@ bool programInfoGenerateAuthoringToolXml(ProgramInfoContext *program_info_ctx)
/* BuildType. */
if (!programInfoAddStringFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "BuildType", build_type)) goto end;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <EnableDeadStrip />\n" /* Impossible to get. */ \
if (!PI_ADD_FMT_STR_T1(" <EnableDeadStrip />\n" /* Impossible to get. */ \
" <EnableDeadStripSpecified />\n" /* Impossible to get. */ \
" <Desc>%s</Desc>\n" \
" <DescFileName />\n" /* Impossible to get. */ \
@ -252,8 +254,7 @@ bool programInfoGenerateAuthoringToolXml(ProgramInfoContext *program_info_ctx)
/* FsAccessControlData. */
if (!programInfoAddFsAccessControlDataToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx)) goto end;
if (!(success = utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <EnableGlobalDestructor />\n" /* Impossible to get. */ \
if (!(success = PI_ADD_FMT_STR_T1(" <EnableGlobalDestructor />\n" /* Impossible to get. */ \
" <EnableGlobalDestructorSpecified />\n" /* Impossible to get. */ \
" <IncludeNssFile />\n" /* Impossible to get. */ \
" <IncludeNssFileSpecified />\n" /* Impossible to get. */ \
@ -397,11 +398,11 @@ static bool programInfoAddNsoApiListToAuthoringToolXml(char **xml_buf, u64 *xml_
/* Append an empty XML element if no entries for this API list exist. */
if (!api_list_exists)
{
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%sList />\n", api_list_tag);
success = PI_ADD_FMT_STR_T2(" <%sList />\n", api_list_tag);
goto end;
}
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%sList>\n", api_list_tag)) goto end;
if (!PI_ADD_FMT_STR_T2(" <%sList>\n", api_list_tag)) goto end;
/* Retrieve full API list. */
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
@ -415,8 +416,7 @@ static bool programInfoAddNsoApiListToAuthoringToolXml(char **xml_buf, u64 *xml_
if (programInfoIsApiInfoEntryValid(sdk_prefix, sdk_prefix_len, sdk_entry, &sdk_entry_vender, &sdk_entry_vender_len, &sdk_entry_name, false))
{
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, \
" <%s>\n" \
if (!PI_ADD_FMT_STR_T2(" <%s>\n" \
" <%sName>%s</%sName>\n" \
" <VenderName>%.*s</VenderName>\n" \
" <NsoName>%s</NsoName>\n" \
@ -432,7 +432,7 @@ static bool programInfoAddNsoApiListToAuthoringToolXml(char **xml_buf, u64 *xml_
}
}
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " </%sList>\n", api_list_tag);
success = PI_ADD_FMT_STR_T2(" </%sList>\n", api_list_tag);
end:
return success;
@ -466,8 +466,7 @@ static bool programInfoAddStringFieldToAuthoringToolXml(char **xml_buf, u64 *xml
return false;
}
return ((value && *value) ? utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s>%s</%s>\n", tag_name, value, tag_name) : \
utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <%s />\n", tag_name));
return ((value && *value) ? PI_ADD_FMT_STR_T2(" <%s>%s</%s>\n", tag_name, value, tag_name) : PI_ADD_FMT_STR_T2(" <%s />\n", tag_name));
}
static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_buf_size, ProgramInfoContext *program_info_ctx)
@ -488,8 +487,8 @@ static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_
for(u32 i = 0; i < program_info_ctx->nso_count; i++)
{
nso_ctx = &(program_info_ctx->nso_ctx[i]);
if (nso_ctx->nso_filename && !strcmp(nso_ctx->nso_filename, "main") && nso_ctx->rodata_dynstr_section && nso_ctx->rodata_dynstr_section_size && nso_ctx->rodata_dynsym_section && \
nso_ctx->rodata_dynsym_section_size) break;
if (nso_ctx->nso_filename && !strcmp(nso_ctx->nso_filename, "main") && nso_ctx->rodata_dynstr_section && nso_ctx->rodata_dynstr_section_size && \
nso_ctx->rodata_dynsym_section && nso_ctx->rodata_dynsym_section_size) break;
nso_ctx = NULL;
}
@ -511,7 +510,7 @@ static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_
/* Bail out if we couldn't find any valid symbols. */
if (!symbols_exist) goto end;
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <UnresolvedApiList>\n")) goto end;
if (!PI_ADD_FMT_STR_T2(" <UnresolvedApiList>\n")) goto end;
/* Parse ELF dynamic symbol table to retrieve the symbol strings. */
for(u64 i = 0; i < nso_ctx->rodata_dynsym_section_size; i += symbol_size)
@ -520,8 +519,7 @@ static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_
if (!programInfoIsElfSymbolValid(nso_ctx->rodata_dynsym_section + i, nso_ctx->rodata_dynstr_section, nso_ctx->rodata_dynstr_section_size, is_64bit, &symbol_str)) continue;
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, \
" <UnresolvedApi>\n" \
if (!PI_ADD_FMT_STR_T2(" <UnresolvedApi>\n" \
" <ApiName>%s</ApiName>\n" \
" <NsoName>%s</NsoName>\n" \
" </UnresolvedApi>\n", \
@ -529,11 +527,11 @@ static bool programInfoAddNsoSymbolsToAuthoringToolXml(char **xml_buf, u64 *xml_
nso_ctx->nso_filename)) goto end;
}
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " </UnresolvedApiList>\n");
success = PI_ADD_FMT_STR_T2(" </UnresolvedApiList>\n");
end:
/* Append an empty XML element if no valid symbols exist. */
if (!success && (!nso_ctx || !symbols_exist)) success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <UnresolvedApiList />\n");
if (!success && (!nso_ctx || !symbols_exist)) success = PI_ADD_FMT_STR_T2(" <UnresolvedApiList />\n");
return success;
}
@ -592,13 +590,12 @@ static bool programInfoAddFsAccessControlDataToAuthoringToolXml(char **xml_buf,
/* Padding to a 0x4-byte boundary is needed. Each accessibility field takes up a single byte, so we can get away with it by aligning the ID count. */
save_data_owner_ids = (u64*)((u8*)save_data_owner_block + sizeof(NpdmFsAccessControlDataSaveDataOwnerBlock) + ALIGN_UP(save_data_owner_block->save_data_owner_id_count, 0x4));
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <FsAccessControlData>\n")) goto end;
if (!PI_ADD_FMT_STR_T2(" <FsAccessControlData>\n")) goto end;
/* Append save data owner IDs. */
for(u32 i = 0; i < save_data_owner_block->save_data_owner_id_count; i++)
{
if (!utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, \
" <SaveDataOwnerIds>\n" \
if (!PI_ADD_FMT_STR_T2(" <SaveDataOwnerIds>\n" \
" <Accessibility>%s</Accessibility>\n" \
" <Id>0x%016lx</Id>\n" \
" </SaveDataOwnerIds>\n", \
@ -606,11 +603,11 @@ static bool programInfoAddFsAccessControlDataToAuthoringToolXml(char **xml_buf,
save_data_owner_ids[i])) goto end;
}
success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " </FsAccessControlData>\n");
success = PI_ADD_FMT_STR_T2(" </FsAccessControlData>\n");
end:
/* Append an empty XML element if no FS access control data exists. */
if (!success && !sdo_data_available) success = utilsAppendFormattedStringToBuffer(xml_buf, xml_buf_size, " <FsAccessControlData />\n");
if (!success && !sdo_data_available) success = PI_ADD_FMT_STR_T2(" <FsAccessControlData />\n");
return success;
}

View file

@ -24,9 +24,12 @@
#include <nxdt_utils.h>
#include <borealis.hpp>
/* Helper macros. */
#define FP_MASK 0xFFFFFFFFFF000000UL
#define STACK_TRACE_SIZE 0x20
#define IS_HB_ADDR(x) (info.addr && info.size && (x) >= info.addr && (x) < (info.addr + info.size))
#define EH_ADD_FMT_STR(fmt, ...) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, fmt, ##__VA_ARGS__)
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
@ -168,45 +171,45 @@ extern "C" {
break;
}
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "Type: %s (0x%X)\r\n", error_desc_str.c_str(), ctx->error_desc);
EH_ADD_FMT_STR("Type: %s (0x%X)\r\n", error_desc_str.c_str(), ctx->error_desc);
/* Log CPU registers. */
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "Registers:");
EH_ADD_FMT_STR("Registers:");
for(size_t i = 0; i < MAX_ELEMENTS(ctx->cpu_gprs); i++)
{
u64 reg = ctx->cpu_gprs[i].x;
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n X%02lu: 0x%lX", i, reg);
if (IS_HB_ADDR(reg)) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, " (BASE + 0x%lX)", reg - info.addr);
EH_ADD_FMT_STR("\r\n X%02lu: 0x%lX", i, reg);
if (IS_HB_ADDR(reg)) EH_ADD_FMT_STR(" (BASE + 0x%lX)", reg - info.addr);
}
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n FP: 0x%lX", ctx->fp.x);
if (IS_HB_ADDR(ctx->fp.x)) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, " (BASE + 0x%lX)", ctx->fp.x - info.addr);
EH_ADD_FMT_STR("\r\n FP: 0x%lX", ctx->fp.x);
if (IS_HB_ADDR(ctx->fp.x)) EH_ADD_FMT_STR(" (BASE + 0x%lX)", ctx->fp.x - info.addr);
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n LR: 0x%lX", ctx->lr.x);
if (IS_HB_ADDR(ctx->lr.x)) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, " (BASE + 0x%lX)", ctx->lr.x - info.addr);
EH_ADD_FMT_STR("\r\n LR: 0x%lX", ctx->lr.x);
if (IS_HB_ADDR(ctx->lr.x)) EH_ADD_FMT_STR(" (BASE + 0x%lX)", ctx->lr.x - info.addr);
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n SP: 0x%lX", ctx->sp.x);
if (IS_HB_ADDR(ctx->sp.x)) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, " (BASE + 0x%lX)", ctx->sp.x - info.addr);
EH_ADD_FMT_STR("\r\n SP: 0x%lX", ctx->sp.x);
if (IS_HB_ADDR(ctx->sp.x)) EH_ADD_FMT_STR(" (BASE + 0x%lX)", ctx->sp.x - info.addr);
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n PC: 0x%lX", ctx->pc.x);
if (IS_HB_ADDR(ctx->pc.x)) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, " (BASE + 0x%lX)", ctx->pc.x - info.addr);
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n");
EH_ADD_FMT_STR("\r\n PC: 0x%lX", ctx->pc.x);
if (IS_HB_ADDR(ctx->pc.x)) EH_ADD_FMT_STR(" (BASE + 0x%lX)", ctx->pc.x - info.addr);
EH_ADD_FMT_STR("\r\n");
/* Unwind stack. */
if (nxdt::utils::UnwindStack(stack_trace, &stack_trace_size, STACK_TRACE_SIZE, ctx->fp.x))
{
/* Log stack trace. */
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "Stack Trace:");
EH_ADD_FMT_STR("Stack Trace:");
for(u32 i = 0; i < stack_trace_size; i++)
{
u64 addr = stack_trace[i];
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n [%02u]: 0x%lX", stack_trace_size - i - 1, addr);
if (IS_HB_ADDR(addr)) utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, " (BASE + 0x%lX)", addr - info.addr);
EH_ADD_FMT_STR("\r\n [%02u]: 0x%lX", stack_trace_size - i - 1, addr);
if (IS_HB_ADDR(addr)) EH_ADD_FMT_STR(" (BASE + 0x%lX)", addr - info.addr);
}
utilsAppendFormattedStringToBuffer(&exception_str, &exception_str_size, "\r\n");
EH_ADD_FMT_STR("\r\n");
}
/* Write log string. */
@ -216,7 +219,8 @@ extern "C" {
if (exception_str) free(exception_str);
/* Abort program execution. */
crash_str = (g_borealisInitialized ? i18n::getStr("generic/exception_triggered"_i18n, error_desc_str, ctx->error_desc) : fmt::format("Fatal exception triggered!\nReason: {} (0x{:X}).", error_desc_str, ctx->error_desc));
crash_str = (g_borealisInitialized ? i18n::getStr("generic/exception_triggered"_i18n, error_desc_str, ctx->error_desc) : \
fmt::format("Fatal exception triggered!\nReason: {} (0x{:X}).", error_desc_str, ctx->error_desc));
crash_str += (fmt::format("\nPC: 0x{:X}", ctx->pc.x) + (IS_HB_ADDR(ctx->pc.x) ? fmt::format(" (BASE + 0x{:X}).", ctx->pc.x - info.addr) : "."));
nxdt::utils::AbortProgramExecution(crash_str);
}

View file

@ -1,11 +1,11 @@
todo:
nca: support for sparse sections
nca: support for compressed fs sections
log: verbosity levels
log: nxlink output for advanced users
nca: support for compressed fs sections?
nca: support for sparse sections?
title: more functions for title lookup? (filters, patches / aoc, etc.)
title: more functions for content lookup? (based on id)
title: parse the update partition from gamecards (if available) to generate ncmcontentinfo data for all update titles