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:
parent
9604b5923d
commit
7189943680
9 changed files with 476 additions and 362 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -106,7 +112,7 @@ typedef enum {
|
|||
NacpSupportedLanguage_TraditionalChinese = BIT(13),
|
||||
NacpSupportedLanguage_SimplifiedChinese = BIT(14),
|
||||
NacpSupportedLanguage_BrazilianPortuguese = BIT(15),
|
||||
NacpSupportedLanguage_Count = 16, ///< Total values supported by this enum. Should always match NacpLanguage_Count.
|
||||
NacpSupportedLanguage_Count = 16, ///< Total values supported by this enum. Should always match NacpLanguage_Count.
|
||||
|
||||
///< Old.
|
||||
NacpSupportedLanguage_Taiwanese = NacpSupportedLanguage_TraditionalChinese,
|
||||
|
@ -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 struct {
|
||||
u16 index : 15;
|
||||
u16 continue_set : 1; ///< Called "flag" by Nintendo, which isn't really great.
|
||||
} NacpDescriptors;
|
||||
|
||||
NXDT_ASSERT(NacpDescriptors, 0x2);
|
||||
typedef enum {
|
||||
NacpRequiredAddOnContentsSetDescriptorFlag_None = 0,
|
||||
NacpRequiredAddOnContentsSetDescriptorFlag_Continue = 1
|
||||
} NacpRequiredAddOnContentsSetDescriptorFlag;
|
||||
|
||||
typedef struct {
|
||||
NacpDescriptors descriptors[0x20];
|
||||
u16 index : 15;
|
||||
u16 flag : 1; ///< NacpRequiredAddOnContentsSetDescriptorFlag.
|
||||
} NacpRequiredAddOnContentsSetDescriptor;
|
||||
|
||||
NXDT_ASSERT(NacpRequiredAddOnContentsSetDescriptor, 0x2);
|
||||
|
||||
typedef struct {
|
||||
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
|
|
@ -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" \
|
||||
"<ContentMeta>\n" \
|
||||
" <Type>%s</Type>\n" \
|
||||
" <Id>0x%016lx</Id>\n" \
|
||||
" <Version>%u</Version>\n" \
|
||||
" <ReleaseVersion />\n" \
|
||||
" <PrivateVersion />\n",
|
||||
titleGetNcmContentMetaTypeName(cnmt_ctx->packaged_header->content_meta_type), \
|
||||
cnmt_ctx->packaged_header->title_id, \
|
||||
cnmt_ctx->packaged_header->version.value)) goto end;
|
||||
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>%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, \
|
||||
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,34 +422,35 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <Content>\n" \
|
||||
" <Type>%s</Type>\n" \
|
||||
" <Id>%s</Id>\n" \
|
||||
" <Size>%lu</Size>\n" \
|
||||
" <Hash>%s</Hash>\n" \
|
||||
" <KeyGeneration>%u</KeyGeneration>\n" \
|
||||
" <IdOffset>%u</IdOffset>\n" \
|
||||
" </Content>\n", \
|
||||
titleGetNcmContentTypeName(cur_nca_ctx->content_type), \
|
||||
cur_nca_ctx->content_id_str, \
|
||||
cur_nca_ctx->content_size, \
|
||||
cur_nca_ctx->hash_str, \
|
||||
cur_nca_ctx->key_generation, \
|
||||
cur_nca_ctx->id_offset)) goto end;
|
||||
if (!CNMT_ADD_FMT_STR(" <Content>\n" \
|
||||
" <Type>%s</Type>\n" \
|
||||
" <Id>%s</Id>\n" \
|
||||
" <Size>%lu</Size>\n" \
|
||||
" <Hash>%s</Hash>\n" \
|
||||
" <KeyGeneration>%u</KeyGeneration>\n" \
|
||||
" <IdOffset>%u</IdOffset>\n" \
|
||||
" </Content>\n", \
|
||||
titleGetNcmContentTypeName(cur_nca_ctx->content_type), \
|
||||
cur_nca_ctx->content_id_str, \
|
||||
cur_nca_ctx->content_size, \
|
||||
cur_nca_ctx->hash_str, \
|
||||
cur_nca_ctx->key_generation, \
|
||||
cur_nca_ctx->id_offset)) goto end;
|
||||
}
|
||||
|
||||
utilsGenerateHexStringFromData(digest_str, sizeof(digest_str), cnmt_ctx->digest, CNMT_DIGEST_SIZE, false);
|
||||
|
||||
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
|
||||
" <ContentMeta />\n" \
|
||||
" <Digest>%s</Digest>\n" \
|
||||
" <KeyGenerationMin>%u</KeyGenerationMin>\n" \
|
||||
" <KeepGeneration />\n" \
|
||||
" <KeepGenerationSpecified />\n", \
|
||||
digest_str, \
|
||||
cnmt_ctx->nca_ctx->key_generation)) goto end;
|
||||
/* ContentMeta, Digest, KeyGenerationMin, KeepGeneration and KeepGenerationSpecified. */
|
||||
if (!CNMT_ADD_FMT_STR(" <ContentMeta />\n" \
|
||||
" <Digest>%s</Digest>\n" \
|
||||
" <KeyGenerationMin>%u</KeyGenerationMin>\n" \
|
||||
" <KeepGeneration />\n" \
|
||||
" <KeepGenerationSpecified />\n", \
|
||||
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" \
|
||||
" <%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;
|
||||
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", \
|
||||
((ContentMetaApplicationMetaExtendedHeader*)cnmt_ctx->extended_header)->required_application_version.value)) goto end;
|
||||
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;
|
||||
|
|
|
@ -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,9 +476,8 @@ 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" \
|
||||
"<Application>\n")) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" \
|
||||
"<Application>\n")) goto end;
|
||||
|
||||
/* Title. */
|
||||
for(i = 0, count = 0; i < NacpLanguage_Count; i++)
|
||||
|
@ -455,56 +485,53 @@ 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" \
|
||||
" <Language>%s</Language>\n" \
|
||||
" <Name>%s</Name>\n" \
|
||||
" <Publisher>%s</Publisher>\n" \
|
||||
" </Title>\n", \
|
||||
nacpGetLanguageString(i), \
|
||||
title->name, \
|
||||
title->publisher)) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <Title>\n" \
|
||||
" <Language>%s</Language>\n" \
|
||||
" <Name>%s</Name>\n" \
|
||||
" <Publisher>%s</Publisher>\n" \
|
||||
" </Title>\n", \
|
||||
nacpGetLanguageString(i), \
|
||||
title->name, \
|
||||
title->publisher)) goto end;
|
||||
|
||||
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,78 +539,75 @@ 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" \
|
||||
" <Organization>%s</Organization>\n" \
|
||||
" <Age>%d</Age>\n" \
|
||||
" </Rating>\n", \
|
||||
nacpGetRatingAgeOrganizationString(i), \
|
||||
age)) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <Rating>\n" \
|
||||
" <Organization>%s</Organization>\n" \
|
||||
" <Age>%d</Age>\n" \
|
||||
" </Rating>\n", \
|
||||
nacpGetRatingAgeOrganizationString(i), \
|
||||
age)) goto end;
|
||||
|
||||
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,101 +621,96 @@ 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" \
|
||||
" <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;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <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++;
|
||||
}
|
||||
|
||||
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,18 +723,17 @@ 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" \
|
||||
" <GroupId>0x%016lx</GroupId>\n" \
|
||||
" <Key>%s</Key>\n" \
|
||||
" </SendGroupConfiguration>\n", \
|
||||
ndcc->send_group_configuration.group_id, \
|
||||
key_str)) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <SendGroupConfiguration>\n" \
|
||||
" <GroupId>0x%016lx</GroupId>\n" \
|
||||
" <Key>%s</Key>\n" \
|
||||
" </SendGroupConfiguration>\n", \
|
||||
ndcc->send_group_configuration.group_id, \
|
||||
key_str)) goto end;
|
||||
|
||||
/* ReceivableGroupConfiguration. */
|
||||
for(i = 0; i < 0x10; i++)
|
||||
|
@ -724,85 +742,122 @@ 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" \
|
||||
" <GroupId>0x%016lx</GroupId>\n" \
|
||||
" <Key>%s</Key>\n" \
|
||||
" </ReceivableGroupConfiguration>\n", \
|
||||
rgc->group_id, \
|
||||
key_str)) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <ReceivableGroupConfiguration>\n" \
|
||||
" <GroupId>0x%016lx</GroupId>\n" \
|
||||
" <Key>%s</Key>\n" \
|
||||
" </ReceivableGroupConfiguration>\n", \
|
||||
rgc->group_id, \
|
||||
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" \
|
||||
" <IsEnabled>%s</IsEnabled>\n" \
|
||||
" <MemorySize>%lu</MemorySize>\n" \
|
||||
" </Jit>\n", \
|
||||
nacpGetJitConfigurationFlagString(nacp->jit_configuration.jit_configuration_flag), \
|
||||
nacp->jit_configuration.memory_size)) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <Jit>\n" \
|
||||
" <IsEnabled>%s</IsEnabled>\n" \
|
||||
" <MemorySize>%lu</MemorySize>\n" \
|
||||
" </Jit>\n", \
|
||||
(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;
|
||||
if (descriptor->index)
|
||||
{
|
||||
raocsbd_available = true;
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
if (descriptor->flag != NacpRequiredAddOnContentsSetDescriptorFlag_Continue) break;
|
||||
}
|
||||
|
||||
if (!count && !utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, " <RequiredAddOnContentsSet />\n")) goto end;
|
||||
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" \
|
||||
" <TargetMarketing>%s</TargetMarketing>\n" \
|
||||
" </PlayReportPermission>\n", \
|
||||
nacpGetPlayReportPermissionString(nacp->play_report_permission))) goto end;
|
||||
if (!NACP_ADD_FMT_STR_T1(" <PlayReportPermission>\n" \
|
||||
" <TargetMarketing>%s</TargetMarketing>\n" \
|
||||
" </PlayReportPermission>\n", \
|
||||
(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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,36 +208,33 @@ 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" \
|
||||
"<ProgramInfo>\n")) goto end;
|
||||
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. */ \
|
||||
" <NxAddonVersion>%s</NxAddonVersion>\n" \
|
||||
" <PatchToolVersion />\n" /* Impossible to get. */ \
|
||||
" <BuildTarget>%u</BuildTarget>\n", \
|
||||
sdk_version, \
|
||||
is_64bit ? 64 : 32)) goto end;
|
||||
|
||||
if (!PI_ADD_FMT_STR_T1(" <ToolVersion />\n" /* Impossible to get. */ \
|
||||
" <NxAddonVersion>%s</NxAddonVersion>\n" \
|
||||
" <PatchToolVersion />\n" /* Impossible to get. */ \
|
||||
" <BuildTarget>%u</BuildTarget>\n", \
|
||||
sdk_version, \
|
||||
is_64bit ? 64 : 32)) goto end;
|
||||
|
||||
/* 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. */ \
|
||||
" <EnableDeadStripSpecified />\n" /* Impossible to get. */ \
|
||||
" <Desc>%s</Desc>\n" \
|
||||
" <DescFileName />\n" /* Impossible to get. */ \
|
||||
" <DescFlags>\n" \
|
||||
" <Production>%s</Production>\n" \
|
||||
" <UnqualifiedApproval>%s</UnqualifiedApproval>\n" \
|
||||
" </DescFlags>\n", \
|
||||
npdm_acid_b64, \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.production ? g_trueString : g_falseString, \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.unqualified_approval ? g_trueString : g_falseString)) goto end;
|
||||
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. */ \
|
||||
" <DescFlags>\n" \
|
||||
" <Production>%s</Production>\n" \
|
||||
" <UnqualifiedApproval>%s</UnqualifiedApproval>\n" \
|
||||
" </DescFlags>\n", \
|
||||
npdm_acid_b64, \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.production ? g_trueString : g_falseString, \
|
||||
program_info_ctx->npdm_ctx.acid_header->flags.unqualified_approval ? g_trueString : g_falseString)) goto end;
|
||||
|
||||
/* MiddlewareList. */
|
||||
if (!programInfoAddNsoApiListToAuthoringToolXml(&xml_buf, &xml_buf_size, program_info_ctx, "Middleware", "Module", "SDK MW")) goto end;
|
||||
|
@ -252,14 +254,13 @@ 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. */ \
|
||||
" <EnableGlobalDestructorSpecified />\n" /* Impossible to get. */ \
|
||||
" <IncludeNssFile />\n" /* Impossible to get. */ \
|
||||
" <IncludeNssFileSpecified />\n" /* Impossible to get. */ \
|
||||
" <History />\n" /* Impossible to get. */ \
|
||||
" <TargetTriplet />\n" /* Impossible to get. */ \
|
||||
"</ProgramInfo>"))) goto end;
|
||||
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. */ \
|
||||
" <History />\n" /* Impossible to get. */ \
|
||||
" <TargetTriplet />\n" /* Impossible to get. */ \
|
||||
"</ProgramInfo>"))) goto end;
|
||||
|
||||
/* Update ProgramInfo context. */
|
||||
program_info_ctx->authoring_tool_xml = xml_buf;
|
||||
|
@ -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,24 +416,23 @@ 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" \
|
||||
" <%sName>%s</%sName>\n" \
|
||||
" <VenderName>%.*s</VenderName>\n" \
|
||||
" <NsoName>%s</NsoName>\n" \
|
||||
" </%s>\n", \
|
||||
api_list_tag, \
|
||||
api_entry_prefix, sdk_entry_name, api_entry_prefix, \
|
||||
sdk_entry_vender_len, sdk_entry_vender, \
|
||||
nso_ctx->nso_filename, \
|
||||
api_list_tag)) goto end;
|
||||
if (!PI_ADD_FMT_STR_T2(" <%s>\n" \
|
||||
" <%sName>%s</%sName>\n" \
|
||||
" <VenderName>%.*s</VenderName>\n" \
|
||||
" <NsoName>%s</NsoName>\n" \
|
||||
" </%s>\n", \
|
||||
api_list_tag, \
|
||||
api_entry_prefix, sdk_entry_name, api_entry_prefix, \
|
||||
sdk_entry_vender_len, sdk_entry_vender, \
|
||||
nso_ctx->nso_filename, \
|
||||
api_list_tag)) goto end;
|
||||
}
|
||||
|
||||
j += strlen(sdk_entry);
|
||||
}
|
||||
}
|
||||
|
||||
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,20 +519,19 @@ 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" \
|
||||
" <ApiName>%s</ApiName>\n" \
|
||||
" <NsoName>%s</NsoName>\n" \
|
||||
" </UnresolvedApi>\n", \
|
||||
symbol_str, \
|
||||
nso_ctx->nso_filename)) goto end;
|
||||
if (!PI_ADD_FMT_STR_T2(" <UnresolvedApi>\n" \
|
||||
" <ApiName>%s</ApiName>\n" \
|
||||
" <NsoName>%s</NsoName>\n" \
|
||||
" </UnresolvedApi>\n", \
|
||||
symbol_str, \
|
||||
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,25 +590,24 @@ 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" \
|
||||
" <Accessibility>%s</Accessibility>\n" \
|
||||
" <Id>0x%016lx</Id>\n" \
|
||||
" </SaveDataOwnerIds>\n", \
|
||||
g_facAccessibilityStrings[save_data_owner_block->accessibility[i] & 0x3], \
|
||||
save_data_owner_ids[i])) goto end;
|
||||
if (!PI_ADD_FMT_STR_T2(" <SaveDataOwnerIds>\n" \
|
||||
" <Accessibility>%s</Accessibility>\n" \
|
||||
" <Id>0x%016lx</Id>\n" \
|
||||
" </SaveDataOwnerIds>\n", \
|
||||
g_facAccessibilityStrings[save_data_owner_block->accessibility[i] & 0x3], \
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
#include <nxdt_utils.h>
|
||||
#include <borealis.hpp>
|
||||
|
||||
#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))
|
||||
/* 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);
|
||||
}
|
||||
|
|
6
todo.txt
6
todo.txt
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue