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

Codestyle fixes + prepare code for NPDM support.

This commit is contained in:
Pablo Curiel 2020-10-08 14:31:09 -04:00
parent e943e84380
commit 1c15a096b5
17 changed files with 306 additions and 320 deletions

View file

@ -12,9 +12,9 @@
{
fprintf(title_infos_txt, "Storage ID: 0x%02X\r\n", g_titleInfo[i].storage_id);
fprintf(title_infos_txt, "Title ID: %016lX\r\n", g_titleInfo[i].meta_key.id);
fprintf(title_infos_txt, "Version: %u (%u.%u.%u-%u.%u)\r\n", g_titleInfo[i].meta_key.version, g_titleInfo[i].version.TitleVersion_Major, \
g_titleInfo[i].version.TitleVersion_Minor, g_titleInfo[i].version.TitleVersion_Micro, g_titleInfo[i].version.TitleVersion_MajorRelstep, \
g_titleInfo[i].version.TitleVersion_MinorRelstep);
fprintf(title_infos_txt, "Version: %u (%u.%u.%u-%u.%u)\r\n", g_titleInfo[i].meta_key.version, g_titleInfo[i].version.major, \
g_titleInfo[i].version.minor, g_titleInfo[i].version.micro, g_titleInfo[i].version.major_relstep, \
g_titleInfo[i].version.minor_relstep);
fprintf(title_infos_txt, "Type: 0x%02X\r\n", g_titleInfo[i].meta_key.type);
fprintf(title_infos_txt, "Install Type: 0x%02X\r\n", g_titleInfo[i].meta_key.install_type);
fprintf(title_infos_txt, "Title Size: %s (0x%lX)\r\n", g_titleInfo[i].title_size_str, g_titleInfo[i].title_size);

View file

@ -262,7 +262,7 @@ int main(int argc, char *argv[])
consolePrint("nacp initialize ctx succeeded\n");
if (nacpGenerateAuthoringToolXml(&nacp_ctx, titleGetVersionInteger(&(user_app_data.app_info->version)), cnmtGetRequiredTitleVersion(&cnmt_ctx)))
if (nacpGenerateAuthoringToolXml(&nacp_ctx, user_app_data.app_info->version.value, cnmtGetRequiredTitleVersion(&cnmt_ctx)))
{
consolePrint("nacp xml succeeded\n");
@ -311,6 +311,8 @@ out2:
utilsWaitForButtonPress(KEY_NONE);
}
nacpFreeContext(&nacp_ctx);
cnmtFreeContext(&cnmt_ctx);
if (nca_ctx) free(nca_ctx);

View file

@ -261,8 +261,8 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
" <RequiredDownloadSystemVersion>%u</RequiredDownloadSystemVersion>\n", \
titleGetNcmContentMetaTypeName(cnmt_ctx->packaged_header->content_meta_type), \
cnmt_ctx->packaged_header->title_id, \
cnmtGetVersionInteger(&(cnmt_ctx->packaged_header->version)), \
cnmtGetVersionInteger(&(cnmt_ctx->packaged_header->required_download_system_version)))) goto end;
cnmt_ctx->packaged_header->version.value,
cnmt_ctx->packaged_header->required_download_system_version.value)) goto end;
for(i = 0; i < nca_ctx_count; i++)
{
@ -336,7 +336,7 @@ bool cnmtGenerateAuthoringToolXml(ContentMetaContext *cnmt_ctx, NcaContext *nca_
{
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <RequiredApplicationVersion>%u</RequiredApplicationVersion>\n", \
cnmtGetVersionInteger((ContentMetaVersion*)(cnmt_ctx->extended_header + sizeof(u64) + sizeof(u32))))) goto end;
((VersionType1*)(cnmt_ctx->extended_header + sizeof(u64) + sizeof(u32)))->value)) goto end;
}
if (!(success = utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, "</ContentMeta>"))) goto end;

View file

@ -27,15 +27,6 @@
#define CNMT_DIGEST_SIZE SHA256_HASH_SIZE
/// Used to display version numbers in dot notation: "{Major}.{Minor}.{Micro}-{MajorRelstep}.{MinorRelstep}".
typedef struct {
u32 ContentMetaVersion_MinorRelstep : 8;
u32 ContentMetaVersion_MajorRelstep : 8;
u32 ContentMetaVersion_Micro : 4;
u32 ContentMetaVersion_Minor : 6;
u32 ContentMetaVersion_Major : 6;
} ContentMetaVersion;
/// Equivalent to NcmContentMetaAttribute.
typedef enum {
ContentMetaAttribute_IncludesExFatDriver = BIT(0),
@ -43,9 +34,8 @@ typedef enum {
ContentMetaAttribute_Compacted = BIT(2)
} ContentMetaAttribute;
typedef struct {
u8 ContentMetaInstallState_Committed : 1;
u8 ContentMetaInstallState_Reserved : 7;
typedef enum {
ContentMetaInstallState_Committed = BIT(0)
} ContentMetaInstallState;
/// Extended variation of NcmContentMetaHeader. This is essentially the start of every CNMT file.
@ -55,7 +45,7 @@ typedef struct {
/// Finally, a 0x20 byte long digest is appended to the EOF.
typedef struct {
u64 title_id;
ContentMetaVersion version;
VersionType1 version;
u8 content_meta_type; ///< NcmContentMetaType.
u8 reserved_1;
u16 extended_header_size; ///< Must match the size from the extended header struct for this content meta type (SystemUpdate, Application, Patch, AddOnContent, Delta).
@ -64,8 +54,8 @@ typedef struct {
u8 content_meta_attribute; ///< ContentMetaAttribute.
u8 storage_id; ///< NcmStorageId.
u8 content_install_type; ///< NcmContentInstallType.
ContentMetaInstallState install_state;
ContentMetaVersion required_download_system_version;
u8 install_state; ///< ContentMetaInstallState.
VersionType1 required_download_system_version;
u8 reserved_2[0x4];
} ContentMetaPackagedContentMetaHeader;
@ -76,27 +66,27 @@ typedef struct {
} ContentMetaSystemUpdateMetaExtendedHeader;
/// Extended header for Application titles.
/// Equivalent to NcmApplicationMetaExtendedHeader, but using ContentMetaVersion structs.
/// Equivalent to NcmApplicationMetaExtendedHeader, but using VersionType1 structs.
typedef struct {
u64 patch_id;
ContentMetaVersion required_system_version;
ContentMetaVersion required_application_version;
VersionType1 required_system_version;
VersionType1 required_application_version;
} ContentMetaApplicationMetaExtendedHeader;
/// Extended header for Patch titles.
/// Equivalent to NcmPatchMetaExtendedHeader, but using a ContentMetaVersion struct.
/// Equivalent to NcmPatchMetaExtendedHeader, but using a VersionType1 struct.
typedef struct {
u64 application_id;
ContentMetaVersion required_system_version;
VersionType1 required_system_version;
u32 extended_data_size;
u8 reserved[0x8];
} ContentMetaPatchMetaExtendedHeader;
/// Extended header for AddOnContent titles.
/// Equivalent to NcmAddOnContentMetaExtendedHeader, but using a ContentMetaVersion struct.
/// Equivalent to NcmAddOnContentMetaExtendedHeader, but using a VersionType1 struct.
typedef struct {
u64 application_id;
ContentMetaVersion required_application_version;
VersionType1 required_application_version;
u8 reserved[0x4];
} ContentMetaAddOnContentMetaExtendedHeader;
@ -168,8 +158,8 @@ typedef struct {
typedef struct {
u64 source_patch_id;
u64 destination_patch_id;
ContentMetaVersion source_version;
ContentMetaVersion destination_version;
VersionType1 source_version;
VersionType1 destination_version;
u64 download_size;
u8 reserved[0x8];
} ContentMetaPatchDeltaHistory;
@ -177,8 +167,8 @@ typedef struct {
typedef struct {
u64 source_patch_id;
u64 destination_patch_id;
ContentMetaVersion source_version;
ContentMetaVersion destination_version;
VersionType1 source_version;
VersionType1 destination_version;
u16 fragment_set_count;
u8 reserved_1[0x6];
u16 content_info_count;
@ -191,6 +181,7 @@ typedef enum {
ContentMetaUpdateType_Create = 2
} ContentMetaUpdateType;
#pragma pack(push, 1)
typedef struct {
NcmContentId source_content_id;
NcmContentId destination_content_id;
@ -199,10 +190,11 @@ typedef struct {
u32 destination_size_low;
u16 destination_size_high;
u16 fragment_count;
NcmContentType fragment_target_content_type;
u8 fragment_target_content_type; ///< NcmContentType.
u8 update_type; ///< ContentMetaUpdateType.
u8 reserved[0x4];
} ContentMetaFragmentSet;
#pragma pack(pop)
typedef struct {
u16 content_info_index;
@ -216,8 +208,8 @@ typedef struct {
typedef struct {
u64 source_patch_id;
u64 destination_patch_id;
ContentMetaVersion source_version;
ContentMetaVersion destination_version;
VersionType1 source_version;
VersionType1 destination_version;
u16 fragment_set_count;
u8 reserved[0x6];
} ContentMetaDeltaMetaExtendedDataHeader;
@ -285,11 +277,6 @@ NX_INLINE bool cnmtGenerateNcaPatch(ContentMetaContext *cnmt_ctx)
return (cnmtIsValidContext(cnmt_ctx) && pfsGenerateEntryPatch(&(cnmt_ctx->pfs_ctx), cnmt_ctx->pfs_entry, cnmt_ctx->raw_data, cnmt_ctx->raw_data_size, 0, &(cnmt_ctx->nca_patch)));
}
NX_INLINE u32 cnmtGetVersionInteger(ContentMetaVersion *version)
{
return (version ? *((u32*)version) : 0);
}
NX_INLINE u64 cnmtGetRequiredTitleId(ContentMetaContext *cnmt_ctx)
{
return ((cnmtIsValidContext(cnmt_ctx) && (cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Application || \
@ -301,7 +288,7 @@ NX_INLINE u32 cnmtGetRequiredTitleVersion(ContentMetaContext *cnmt_ctx)
{
return ((cnmtIsValidContext(cnmt_ctx) && (cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Application || \
cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_Patch || cnmt_ctx->packaged_header->content_meta_type == NcmContentMetaType_AddOnContent)) ? \
cnmtGetVersionInteger((ContentMetaVersion*)(cnmt_ctx->extended_header + sizeof(u64))) : 0);
((VersionType1*)(cnmt_ctx->extended_header + sizeof(u64)))->value : 0);
}
#endif /* __CNMT_H__ */

55
source/common.h Normal file
View file

@ -0,0 +1,55 @@
/*
* common.h
*
* Copyright (c) 2020, DarkMatterCore <pabloacurielz@gmail.com>.
*
* This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
*
* nxdumptool is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* nxdumptool is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __COMMON_H__
#define __COMMON_H__
/// Used to store version numbers expressed in dot notation: "{major}.{minor}.{micro}-{major_relstep}.{minor_relstep}".
/// Referenced by multiple header files.
typedef struct {
union {
struct {
u32 minor_relstep : 8;
u32 major_relstep : 8;
u32 micro : 4;
u32 minor : 6;
u32 major : 6;
};
u32 value;
};
} VersionType1;
/// Used to store version numbers expressed in dot notation: "{major}.{minor}.{micro}-{relstep}".
/// Only used by GameCardFwMode and NcaSdkAddOnVersion.
typedef struct {
union {
struct {
u32 relstep : 8;
u32 micro : 8;
u32 minor : 8;
u32 major : 8;
};
u32 value;
};
} VersionType2;
#endif /* __COMMON_H__ */

View file

@ -27,7 +27,7 @@
/// Located at offset 0x7000 in the gamecard image.
typedef struct {
u8 signature[0x100]; ///< RSA-2048 PKCS #1 signature over the rest of the data.
u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the data.
u32 magic; ///< "CERT".
u8 reserved_1[0x4];
u8 kek_index;

View file

@ -118,21 +118,6 @@ typedef enum {
GameCardCompatibilityType_Terra = 1
} GameCardCompatibilityType;
typedef struct {
u32 GameCardFwMode_Relstep : 8;
u32 GameCardFwMode_Micro : 8;
u32 GameCardFwMode_Minor : 8;
u32 GameCardFwMode_Major : 8;
} GameCardFwMode;
typedef struct {
u32 GameCardCupVersion_MinorRelstep : 8;
u32 GameCardCupVersion_MajorRelstep : 8;
u32 GameCardCupVersion_Micro : 4;
u32 GameCardCupVersion_Minor : 6;
u32 GameCardCupVersion_Major : 6;
} GameCardCupVersion;
/// Encrypted using AES-128-CBC with the XCI header key (found in FS program memory under newer versions of HOS) and the IV from `GameCardHeader`.
/// Key hashes for documentation purposes:
/// Production XCI header key hash: 2E36CC55157A351090A73E7AE77CF581F69B0B6E48FB066C984879A6ED7D2E96
@ -144,8 +129,8 @@ typedef struct {
u32 wait_2_time_read; ///< Always 0.
u32 wait_1_time_write; ///< Always 0.
u32 wait_2_time_write; ///< Always 0.
GameCardFwMode fw_mode;
GameCardCupVersion cup_version;
VersionType2 fw_mode;
VersionType1 cup_version;
u8 compatibility_type; ///< GameCardCompatibilityType.
u8 reserved_1[0x3];
u64 cup_hash;
@ -155,7 +140,7 @@ typedef struct {
/// Placed after the `GameCardKeyArea` section.
typedef struct {
u8 signature[0x100]; ///< RSA-2048 PKCS #1 signature over the rest of the header.
u8 signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over the rest of the header.
u32 magic; ///< "HEAD".
u32 secure_area_start_address; ///< Expressed in GAMECARD_MEDIA_UNIT_SIZE blocks.
u32 backup_area_start_address; ///< Always 0xFFFFFFFF.

View file

@ -30,158 +30,158 @@ typedef const char *(*NacpStringFunction)(u8 value); /* Used while adding fie
static const char *g_unknownString = "Unknown";
static const char *g_nacpLanguageStrings[] = {
[NacpLanguage_AmericanEnglish] = "AmericanEnglish",
[NacpLanguage_BritishEnglish] = "BritishEnglish",
[NacpLanguage_Japanese] = "Japanese",
[NacpLanguage_French] = "French",
[NacpLanguage_German] = "German",
[NacpLanguage_LatinAmericanSpanish] = "LatinAmericanSpanish",
[NacpLanguage_Spanish] = "Spanish",
[NacpLanguage_Italian] = "Italian",
[NacpLanguage_Dutch] = "Dutch",
[NacpLanguage_CanadianFrench] = "CanadianFrench",
[NacpLanguage_Portuguese] = "Portuguese",
[NacpLanguage_Russian] = "Russian",
[NacpLanguage_Korean] = "Korean",
[NacpLanguage_TraditionalChinese] = "TraditionalChinese",
[NacpLanguage_SimplifiedChinese] = "SimplifiedChinese",
[NacpLanguage_BrazilianPortuguese] = "BrazilianPortuguese"
static const char *g_nacpLanguageStrings[NacpLanguage_Count] = {
"AmericanEnglish",
"BritishEnglish",
"Japanese",
"French",
"German",
"LatinAmericanSpanish",
"Spanish",
"Italian",
"Dutch",
"CanadianFrench",
"Portuguese",
"Russian",
"Korean",
"TraditionalChinese",
"SimplifiedChinese",
"BrazilianPortuguese"
};
static const char *g_nacpStartupUserAccountStrings[] = {
[NacpStartupUserAccount_None] = "None",
[NacpStartupUserAccount_Required] = "Required",
[NacpStartupUserAccount_RequiredWithNetworkServiceAccountAvailable] = "RequiredWithNetworkServiceAccountAvailable"
static const char *g_nacpStartupUserAccountStrings[NacpStartupUserAccount_Count] = {
"None",
"Required",
"RequiredWithNetworkServiceAccountAvailable"
};
static const char *g_nacpUserAccountSwitchLockStrings[] = {
[NacpUserAccountSwitchLock_Disable] = "Disable",
[NacpUserAccountSwitchLock_Enable] = "Enable"
static const char *g_nacpUserAccountSwitchLockStrings[NacpUserAccountSwitchLock_Count] = {
"Disable",
"Enable"
};
static const char *g_nacpAddOnContentRegistrationTypeStrings[] = {
[NacpAddOnContentRegistrationType_AllOnLaunch] = "AllOnLaunch",
[NacpAddOnContentRegistrationType_OnDemand] = "OnDemand"
static const char *g_nacpAddOnContentRegistrationTypeStrings[NacpAddOnContentRegistrationType_Count] = {
"AllOnLaunch",
"OnDemand"
};
static const char *g_nacpAttributeStrings[] = {
[NacpAttribute_Demo] = "Demo",
[NacpAttribute_RetailInteractiveDisplay] = "RetailInteractiveDisplay"
static const char *g_nacpAttributeStrings[NacpAttribute_Count] = {
"Demo",
"RetailInteractiveDisplay"
};
static const char *g_nacpParentalControlStrings[] = {
[NacpParentalControl_FreeCommunication] = "FreeCommunication"
static const char *g_nacpParentalControlStrings[NacpParentalControl_Count] = {
"FreeCommunication"
};
static const char *g_nacpScreenshotStrings[] = {
[NacpScreenshot_Allow] = "Allow",
[NacpScreenshot_Deny] = "Deny"
static const char *g_nacpScreenshotStrings[NacpScreenshot_Count] = {
"Allow",
"Deny"
};
static const char *g_nacpVideoCaptureStrings[] = {
[NacpVideoCapture_Disable] = "Disable",
[NacpVideoCapture_Manual] = "Manual",
[NacpVideoCapture_Enable] = "Enable"
static const char *g_nacpVideoCaptureStrings[NacpVideoCapture_Count] = {
"Disable",
"Manual",
"Enable"
};
static const char *g_nacpDataLossConfirmationStrings[] = {
[NacpDataLossConfirmation_None] = "None",
[NacpDataLossConfirmation_Required] = "Required"
static const char *g_nacpDataLossConfirmationStrings[NacpDataLossConfirmation_Count] = {
"None",
"Required"
};
static const char *g_nacpPlayLogPolicyStrings[] = {
[NacpPlayLogPolicy_Open] = "Open",
[NacpPlayLogPolicy_LogOnly] = "LogOnly",
[NacpPlayLogPolicy_None] = "None",
[NacpPlayLogPolicy_Closed] = "Closed"
static const char *g_nacpPlayLogPolicyStrings[NacpPlayLogPolicy_Count] = {
"Open",
"LogOnly",
"None",
"Closed"
};
static const char *g_nacpRatingAgeOrganizationStrings[] = {
[NacpRatingAgeOrganization_CERO] = "CERO",
[NacpRatingAgeOrganization_GRACGCRB] = "GRACGCRB",
[NacpRatingAgeOrganization_GSRMR] = "GSRMR",
[NacpRatingAgeOrganization_ESRB] = "ESRB",
[NacpRatingAgeOrganization_ClassInd] = "ClassInd",
[NacpRatingAgeOrganization_USK] = "USK",
[NacpRatingAgeOrganization_PEGI] = "PEGI",
[NacpRatingAgeOrganization_PEGIPortugal] = "PEGIPortugal",
[NacpRatingAgeOrganization_PEGIBBFC] = "PEGIBBFC",
[NacpRatingAgeOrganization_Russian] = "Russian",
[NacpRatingAgeOrganization_ACB] = "ACB",
[NacpRatingAgeOrganization_OFLC] = "OFLC",
[NacpRatingAgeOrganization_IARCGeneric] = "IARCGeneric"
static const char *g_nacpRatingAgeOrganizationStrings[NacpRatingAgeOrganization_Count] = {
"CERO",
"GRACGCRB",
"GSRMR",
"ESRB",
"ClassInd",
"USK",
"PEGI",
"PEGIPortugal",
"PEGIBBFC",
"Russian",
"ACB",
"OFLC",
"IARCGeneric"
};
static const char *g_nacpLogoTypeStrings[] = {
[NacpLogoType_LicensedByNintendo] = "LicensedByNintendo",
[NacpLogoType_DistributedByNintendo] = "DistributedByNintendo",
[NacpLogoType_Nintendo] = "Nintendo"
static const char *g_nacpLogoTypeStrings[NacpLogoType_Count] = {
"LicensedByNintendo",
"DistributedByNintendo",
"Nintendo"
};
static const char *g_nacpLogoHandlingStrings[] = {
[NacpLogoHandling_Auto] = "Auto",
[NacpLogoHandling_Manual] = "Manual"
static const char *g_nacpLogoHandlingStrings[NacpLogoHandling_Count] = {
"Auto",
"Manual"
};
static const char *g_nacpRuntimeAddOnContentInstallStrings[] = {
[NacpRuntimeAddOnContentInstall_Deny] = "Deny",
[NacpRuntimeAddOnContentInstall_AllowAppend] = "AllowAppend",
[NacpRuntimeAddOnContentInstall_AllowAppendButDontDownloadWhenUsingNetwork] = "AllowAppendButDontDownloadWhenUsingNetwork"
static const char *g_nacpRuntimeAddOnContentInstallStrings[NacpRuntimeAddOnContentInstall_Count] = {
"Deny",
"AllowAppend",
"AllowAppendButDontDownloadWhenUsingNetwork"
};
static const char *g_nacpNacpRuntimeParameterDeliveryStrings[] = {
[NacpRuntimeParameterDelivery_Always] = "Always",
[NacpRuntimeParameterDelivery_AlwaysIfUserStateMatched] = "AlwaysIfUserStateMatched",
[NacpRuntimeParameterDelivery_OnRestart] = "OnRestart"
static const char *g_nacpNacpRuntimeParameterDeliveryStrings[NacpRuntimeParameterDelivery_Count] = {
"Always",
"AlwaysIfUserStateMatched",
"OnRestart"
};
static const char *g_nacpCrashReportStrings[] = {
[NacpCrashReport_Deny] = "Deny",
[NacpCrashReport_Allow] = "Allow"
static const char *g_nacpCrashReportStrings[NacpCrashReport_Count] = {
"Deny",
"Allow"
};
static const char *g_nacpHdcpStrings[] = {
[NacpHdcp_None] = "None",
[NacpHdcp_Required] = "Required"
static const char *g_nacpHdcpStrings[NacpHdcp_Count] = {
"None",
"Required"
};
static const char *g_nacpStartupUserAccountOptionStrings[] = {
[NacpStartupUserAccountOption_IsOptional] = "IsOptional"
static const char *g_nacpStartupUserAccountOptionStrings[NacpStartupUserAccountOption_Count] = {
"IsOptional"
};
static const char *g_nacpPlayLogQueryCapabilityStrings[] = {
[NacpPlayLogQueryCapability_None] = "None",
[NacpPlayLogQueryCapability_WhiteList] = "WhiteList",
[NacpPlayLogQueryCapability_All] = "All"
static const char *g_nacpPlayLogQueryCapabilityStrings[NacpPlayLogQueryCapability_Count] = {
"None",
"WhiteList",
"All"
};
static const char *g_nacpRepairStrings[] = {
[NacpRepair_SuppressGameCardAccess] = "SuppressGameCardAccess"
static const char *g_nacpRepairStrings[NacpRepair_Count] = {
"SuppressGameCardAccess"
};
static const char *g_nacpRequiredNetworkServiceLicenseOnLaunchStrings[] = {
[NacpRequiredNetworkServiceLicenseOnLaunch_Common] = "RequiredNetworkServiceLicenseOnLaunch"
static const char *g_nacpRequiredNetworkServiceLicenseOnLaunchStrings[NacpRequiredNetworkServiceLicenseOnLaunch_Count] = {
"Common"
};
static const char *g_nacpJitConfigurationFlagStrings[] = {
[NacpJitConfigurationFlag_None] = "None",
[NacpJitConfigurationFlag_Enabled] = "Enabled"
static const char *g_nacpJitConfigurationFlagStrings[NacpJitConfigurationFlag_Count] = {
"None",
"Enabled"
};
static const char *g_nacpPlayReportPermissionStrings[] = {
[NacpPlayReportPermission_None] = "None",
[NacpPlayReportPermission_TargetMarketing] = "TargetMarketing"
static const char *g_nacpPlayReportPermissionStrings[NacpPlayReportPermission_Count] = {
"None",
"TargetMarketing"
};
static const char *g_nacpCrashScreenshotForProdStrings[] = {
[NacpCrashScreenshotForProd_Deny] = "Deny",
[NacpCrashScreenshotForProd_Allow] = "Allow"
static const char *g_nacpCrashScreenshotForProdStrings[NacpCrashScreenshotForProd_Count] = {
"Deny",
"Allow"
};
static const char *g_nacpCrashScreenshotForDevStrings[] = {
[NacpCrashScreenshotForDev_Deny] = "Deny",
[NacpCrashScreenshotForDev_Allow] = "Allow"
static const char *g_nacpCrashScreenshotForDevStrings[NacpCrashScreenshotForDev_Count] = {
"Deny",
"Allow"
};
/* Function prototypes. */
@ -260,12 +260,12 @@ bool nacpInitializeContext(NacpContext *out, NcaContext *nca_ctx)
out->nca_ctx = nca_ctx;
/* Retrieve NACP icon data. */
for(u8 i = 0; i < NacpLanguage_Count; i++)
for(u8 i = 0; i < NacpSupportedLanguage_Count; i++)
{
NacpIconContext *icon_ctx = NULL;
/* Check if the current language is supported. */
if (!nacpCheckBitflagField(&(out->data->supported_language_flag), sizeof(out->data->supported_language_flag) * 8, i)) continue;
if (!nacpCheckBitflagField(&(out->data->supported_language), sizeof(out->data->supported_language) * 8, i)) continue;
/* Get language string. */
language_str = nacpGetLanguageString(i);
@ -388,21 +388,21 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccount", nacp->startup_user_account, &nacpGetStartupUserAccountString)) goto end;
/* StartupUserAccountOption. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccountOption", &(nacp->startup_user_account_option_flag), sizeof(nacp->startup_user_account_option_flag), \
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "StartupUserAccountOption", &(nacp->startup_user_account_option), sizeof(nacp->startup_user_account_option), \
NacpStartupUserAccountOption_Count, &nacpGetStartupUserAccountOptionString)) goto end;
/* UserAccountSwitchLock. */
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "UserAccountSwitchLock", nacp->user_account_switch_lock, &nacpGetUserAccountSwitchLockString)) goto end;
/* Attribute. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Attribute", &(nacp->attribute_flag), sizeof(nacp->attribute_flag), NacpAttribute_Count, &nacpGetAttributeString)) goto end;
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Attribute", &(nacp->attribute), sizeof(nacp->attribute), NacpAttribute_Count, &nacpGetAttributeString)) goto end;
/* ParentalControl. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ParentalControl", &(nacp->parental_control_flag), sizeof(nacp->parental_control_flag), NacpParentalControl_Count, \
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ParentalControl", &(nacp->parental_control), sizeof(nacp->parental_control), NacpParentalControl_Count, \
&nacpGetParentalControlString)) goto end;
/* SupportedLanguage. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SupportedLanguage", &(nacp->supported_language_flag), sizeof(nacp->supported_language_flag), NacpLanguage_Count, \
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "SupportedLanguage", &(nacp->supported_language), sizeof(nacp->supported_language), NacpSupportedLanguage_Count, \
&nacpGetLanguageString)) goto end;
/* Screenshot. */
@ -586,14 +586,14 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
if (!nacpAddEnumFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "PlayLogQueryCapability", nacp->play_log_query_capability, &nacpGetPlayLogQueryCapabilityString)) goto end;
/* Repair. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Repair", &(nacp->repair_flag), sizeof(nacp->repair_flag), NacpRepair_Count, &nacpGetRepairString)) goto end;
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "Repair", &(nacp->repair), sizeof(nacp->repair), NacpRepair_Count, &nacpGetRepairString)) goto end;
/* ProgramIndex. */
if (!nacpAddU16FieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "ProgramIndex", nacp->program_index, false)) goto end;
/* RequiredNetworkServiceLicenseOnLaunch. */
if (!nacpAddBitflagFieldToAuthoringToolXml(&xml_buf, &xml_buf_size, "RequiredNetworkServiceLicenseOnLaunch", &(nacp->required_network_service_license_on_launch_flag), \
sizeof(nacp->required_network_service_license_on_launch_flag), NacpRequiredNetworkServiceLicenseOnLaunch_Count, &nacpGetRequiredNetworkServiceLicenseOnLaunchString)) goto end;
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;
/* NeighborDetectionClientConfiguration. */
ndcc_sgc_available = (ndcc->send_group_configuration.group_id && memcmp(ndcc->send_group_configuration.key, null_key, sizeof(null_key)));
@ -650,13 +650,13 @@ bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 requir
/* RequiredAddOnContentsSet. */
for(i = 0, count = 0; i < 0x20; i++)
{
if (!raocsbd->descriptors[i].NacpDescriptors_Index || !raocsbd->descriptors[i].NacpDescriptors_ContinueSet) continue;
if (!raocsbd->descriptors[i].index || !raocsbd->descriptors[i].continue_set) continue;
if (!utilsAppendFormattedStringToBuffer(&xml_buf, &xml_buf_size, \
" <RequiredAddOnContentsSet>\n" \
" <Index>%u</Index>\n" \
" </RequiredAddOnContentsSet>\n",
raocsbd->descriptors[i].NacpDescriptors_Index)) goto end;
raocsbd->descriptors[i].index)) goto end;
count++;
}

View file

@ -36,35 +36,28 @@ typedef enum {
NacpStartupUserAccount_None = 0,
NacpStartupUserAccount_Required = 1,
NacpStartupUserAccount_RequiredWithNetworkServiceAccountAvailable = 2,
NacpStartupUserAccount_Count = 3 ///< Not a real value.
NacpStartupUserAccount_Count = 3 ///< Total values supported by this enum.
} NacpStartupUserAccount;
typedef enum {
NacpUserAccountSwitchLock_Disable = 0,
NacpUserAccountSwitchLock_Enable = 1,
NacpUserAccountSwitchLock_Count = 2 ///< Not a real value.
NacpUserAccountSwitchLock_Count = 2 ///< Total values supported by this enum.
} NacpUserAccountSwitchLock;
typedef enum {
NacpAddOnContentRegistrationType_AllOnLaunch = 0,
NacpAddOnContentRegistrationType_OnDemand = 1,
NacpAddOnContentRegistrationType_Count = 2 ///< Not a real value.
NacpAddOnContentRegistrationType_Count = 2 ///< Total values supported by this enum.
} NacpAddOnContentRegistrationType;
/// Indexes used to access NACP attribute info.
typedef enum {
NacpAttribute_Demo = 0,
NacpAttribute_RetailInteractiveDisplay = 1,
NacpAttribute_Count = 2 ///< Not a real value.
NacpAttribute_Demo = BIT(0),
NacpAttribute_RetailInteractiveDisplay = BIT(1),
NacpAttribute_Count = 2 ///< Total values supported by this enum.
} NacpAttribute;
typedef struct {
u32 NacpAttributeFlag_Demo : 1;
u32 NacpAttributeFlag_RetailInteractiveDisplay : 1;
u32 NacpAttributeFlag_Reserved : 30;
} NacpAttributeFlag;
/// Indexes used to access NACP language info.
/// Indexes used to access NACP Title structs.
typedef enum {
NacpLanguage_AmericanEnglish = 0,
NacpLanguage_BritishEnglish = 1,
@ -82,51 +75,45 @@ typedef enum {
NacpLanguage_TraditionalChinese = 13,
NacpLanguage_SimplifiedChinese = 14,
NacpLanguage_BrazilianPortuguese = 15,
NacpLanguage_Count = 16 ///< Not a real value.
NacpLanguage_Count = 16 ///< Total values supported by this enum.
} NacpLanguage;
typedef struct {
u32 NacpSupportedLanguageFlag_AmericanEnglish : 1;
u32 NacpSupportedLanguageFlag_BritishEnglish : 1;
u32 NacpSupportedLanguageFlag_Japanese : 1;
u32 NacpSupportedLanguageFlag_French : 1;
u32 NacpSupportedLanguageFlag_German : 1;
u32 NacpSupportedLanguageFlag_LatinAmericanSpanish : 1;
u32 NacpSupportedLanguageFlag_Spanish : 1;
u32 NacpSupportedLanguageFlag_Italian : 1;
u32 NacpSupportedLanguageFlag_Dutch : 1;
u32 NacpSupportedLanguageFlag_CanadianFrench : 1;
u32 NacpSupportedLanguageFlag_Portuguese : 1;
u32 NacpSupportedLanguageFlag_Russian : 1;
u32 NacpSupportedLanguageFlag_Korean : 1;
u32 NacpSupportedLanguageFlag_TraditionalChinese : 1; ///< Old: NacpSupportedLanguageFlag_Taiwanese.
u32 NacpSupportedLanguageFlag_SimplifiedChinese : 1; ///< Old: NacpSupportedLanguageFlag_Chinese.
u32 NacpSupportedLanguageFlag_BrazilianPortuguese : 1;
u32 NacpSupportedLanguageFlag_Reserved : 16;
} NacpSupportedLanguageFlag;
/// Indexes used to access NACP parental control info.
typedef enum {
NacpParentalControl_FreeCommunication = 0,
NacpParentalControl_Count = 1 ///< Not a real value.
} NacpParentalControl;
NacpSupportedLanguage_AmericanEnglish = BIT(0),
NacpSupportedLanguage_BritishEnglish = BIT(1),
NacpSupportedLanguage_Japanese = BIT(2),
NacpSupportedLanguage_French = BIT(3),
NacpSupportedLanguage_German = BIT(4),
NacpSupportedLanguage_LatinAmericanSpanish = BIT(5),
NacpSupportedLanguage_Spanish = BIT(6),
NacpSupportedLanguage_Italian = BIT(7),
NacpSupportedLanguage_Dutch = BIT(8),
NacpSupportedLanguage_CanadianFrench = BIT(9),
NacpSupportedLanguage_Portuguese = BIT(10),
NacpSupportedLanguage_Russian = BIT(11),
NacpSupportedLanguage_Korean = BIT(12),
NacpSupportedLanguage_TraditionalChinese = BIT(13), ///< Old: NacpSupportedLanguage_Taiwanese.
NacpSupportedLanguage_SimplifiedChinese = BIT(14), ///< Old: NacpSupportedLanguage_Chinese.
NacpSupportedLanguage_BrazilianPortuguese = BIT(15),
NacpSupportedLanguage_Count = 16 ///< Total values supported by this enum. Should always match NacpLanguage_Count.
} NacpSupportedLanguage;
typedef struct {
u32 NacpParentalControlFlag_FreeCommunication : 1;
u32 NacpParentalControlFlag_Reserved : 31;
} NacpParentalControlFlag;
typedef enum {
NacpParentalControl_FreeCommunication = BIT(0),
NacpParentalControl_Count = 1 ///< Total values supported by this enum.
} NacpParentalControl;
typedef enum {
NacpScreenshot_Allow = 0,
NacpScreenshot_Deny = 1,
NacpScreenshot_Count = 2 ///< Not a real value.
NacpScreenshot_Count = 2 ///< Total values supported by this enum.
} NacpScreenshot;
typedef enum {
NacpVideoCapture_Disable = 0,
NacpVideoCapture_Manual = 1,
NacpVideoCapture_Enable = 2,
NacpVideoCapture_Count = 3, ///< Not a real value.
NacpVideoCapture_Count = 3, ///< Total values supported by this enum.
/// Old.
NacpVideoCapture_Deny = NacpVideoCapture_Disable,
@ -136,7 +123,7 @@ typedef enum {
typedef enum {
NacpDataLossConfirmation_None = 0,
NacpDataLossConfirmation_Required = 1,
NacpDataLossConfirmation_Count = 2 ///< Not a real value.
NacpDataLossConfirmation_Count = 2 ///< Total values supported by this enum.
} NacpDataLossConfirmation;
typedef enum {
@ -144,13 +131,13 @@ typedef enum {
NacpPlayLogPolicy_LogOnly = 1,
NacpPlayLogPolicy_None = 2,
NacpPlayLogPolicy_Closed = 3,
NacpPlayLogPolicy_Count = 4, ///< Not a real value.
NacpPlayLogPolicy_Count = 4, ///< Total values supported by this enum.
/// Old.
NacpPlayLogPolicy_All = NacpPlayLogPolicy_Open
} NacpPlayLogPolicy;
/// Indexes used to access NACP rating age info.
/// Indexes used to access NACP RatingAge info.
typedef enum {
NacpRatingAgeOrganization_CERO = 0,
NacpRatingAgeOrganization_GRACGCRB = 1,
@ -165,7 +152,7 @@ typedef enum {
NacpRatingAgeOrganization_ACB = 10,
NacpRatingAgeOrganization_OFLC = 11,
NacpRatingAgeOrganization_IARCGeneric = 12,
NacpRatingAgeOrganization_Count = 13 ///< Not a real value.
NacpRatingAgeOrganization_Count = 13 ///< Total values supported by this enum.
} NacpRatingAgeOrganization;
typedef struct {
@ -189,85 +176,67 @@ typedef enum {
NacpLogoType_LicensedByNintendo = 0,
NacpLogoType_DistributedByNintendo = 1, ///< Removed.
NacpLogoType_Nintendo = 2,
NacpLogoType_Count = 3 ///< Not a real value.
NacpLogoType_Count = 3 ///< Total values supported by this enum.
} NacpLogoType;
typedef enum {
NacpLogoHandling_Auto = 0,
NacpLogoHandling_Manual = 1,
NacpLogoHandling_Count = 2 ///< Not a real value.
NacpLogoHandling_Count = 2 ///< Total values supported by this enum.
} NacpLogoHandling;
typedef enum {
NacpRuntimeAddOnContentInstall_Deny = 0,
NacpRuntimeAddOnContentInstall_AllowAppend = 1,
NacpRuntimeAddOnContentInstall_AllowAppendButDontDownloadWhenUsingNetwork = 2,
NacpRuntimeAddOnContentInstall_Count = 3 ///< Not a real value.
NacpRuntimeAddOnContentInstall_Count = 3 ///< Total values supported by this enum.
} NacpRuntimeAddOnContentInstall;
typedef enum {
NacpRuntimeParameterDelivery_Always = 0,
NacpRuntimeParameterDelivery_AlwaysIfUserStateMatched = 1,
NacpRuntimeParameterDelivery_OnRestart = 2,
NacpRuntimeParameterDelivery_Count = 3 ///< Not a real value.
NacpRuntimeParameterDelivery_Count = 3 ///< Total values supported by this enum.
} NacpRuntimeParameterDelivery;
typedef enum {
NacpCrashReport_Deny = 0,
NacpCrashReport_Allow = 1,
NacpCrashReport_Count = 2 ///< Not a real value.
NacpCrashReport_Count = 2 ///< Total values supported by this enum.
} NacpCrashReport;
typedef enum {
NacpHdcp_None = 0,
NacpHdcp_Required = 1,
NacpHdcp_Count = 2 ///< Not a real value.
NacpHdcp_Count = 2 ///< Total values supported by this enum.
} NacpHdcp;
/// Indexes used to access NACP startup user account option info.
typedef enum {
NacpStartupUserAccountOption_IsOptional = 0,
NacpStartupUserAccountOption_Count = 1 ///< Not a real value.
NacpStartupUserAccountOption_IsOptional = BIT(0),
NacpStartupUserAccountOption_Count = 1 ///< Total values supported by this enum.
} NacpStartupUserAccountOption;
typedef struct {
u8 NacpStartupUserAccountOptionFlag_IsOptional : 1;
u8 NacpStartupUserAccountOptionFlag_Reserved : 7;
} NacpStartupUserAccountOptionFlag;
typedef enum {
NacpPlayLogQueryCapability_None = 0,
NacpPlayLogQueryCapability_WhiteList = 1,
NacpPlayLogQueryCapability_All = 2,
NacpPlayLogQueryCapability_Count = 3 ///< Not a real value.
NacpPlayLogQueryCapability_Count = 3 ///< Total values supported by this enum.
} NacpPlayLogQueryCapability;
/// Indexes used to access NACP repair info.
typedef enum {
NacpRepair_SuppressGameCardAccess = 0,
NacpRepair_Count = 1 ///< Not a real value.
NacpRepair_SuppressGameCardAccess = BIT(0),
NacpRepair_Count = 1 ///< Total values supported by this enum.
} NacpRepair;
typedef struct {
u8 NacpRepairFlag_SuppressGameCardAccess : 1;
u8 NacpRepairFlag_Reserved : 7;
} NacpRepairFlag;
/// Indexes used to access NACP required network service license on launch info.
typedef enum {
NacpRequiredNetworkServiceLicenseOnLaunch_Common = 0,
NacpRequiredNetworkServiceLicenseOnLaunch_Count = 1 ///< Not a real value.
NacpRequiredNetworkServiceLicenseOnLaunch_Common = BIT(0),
NacpRequiredNetworkServiceLicenseOnLaunch_Count = 1 ///< Total values supported by this enum.
} NacpRequiredNetworkServiceLicenseOnLaunch;
typedef struct {
u8 NacpRequiredNetworkServiceLicenseOnLaunchFlag_Common : 1;
u8 NacpRequiredNetworkServiceLicenseOnLaunchFlag_Reserved : 7;
} NacpRequiredNetworkServiceLicenseOnLaunchFlag;
typedef enum {
NacpJitConfigurationFlag_None = 0,
NacpJitConfigurationFlag_Enabled = 1,
NacpJitConfigurationFlag_Count = 2 ///< Not a real value.
NacpJitConfigurationFlag_Count = 2 ///< Total values supported by this enum.
} NacpJitConfigurationFlag;
typedef struct {
@ -276,8 +245,8 @@ typedef struct {
} NacpJitConfiguration;
typedef struct {
u16 NacpDescriptors_Index : 15;
u16 NacpDescriptors_ContinueSet : 1; ///< Called "flag" by Nintendo, which isn't really great...
u16 index : 15;
u16 continue_set : 1; ///< Called "flag" by Nintendo, which isn't really great...
} NacpDescriptors;
typedef struct {
@ -287,19 +256,19 @@ typedef struct {
typedef enum {
NacpPlayReportPermission_None = 0,
NacpPlayReportPermission_TargetMarketing = 1,
NacpPlayReportPermission_Count = 2 ///< Not a real value.
NacpPlayReportPermission_Count = 2 ///< Total values supported by this enum.
} NacpPlayReportPermission;
typedef enum {
NacpCrashScreenshotForProd_Deny = 0,
NacpCrashScreenshotForProd_Allow = 1,
NacpCrashScreenshotForProd_Count = 2 ///< Not a real value.
NacpCrashScreenshotForProd_Count = 2 ///< Total values supported by this enum.
} NacpCrashScreenshotForProd;
typedef enum {
NacpCrashScreenshotForDev_Deny = 0,
NacpCrashScreenshotForDev_Allow = 1,
NacpCrashScreenshotForDev_Count = 2 ///< Not a real value.
NacpCrashScreenshotForDev_Count = 2 ///< Total values supported by this enum.
} NacpCrashScreenshotForDev;
typedef struct {
@ -312,9 +281,9 @@ typedef struct {
u8 startup_user_account; ///< NacpStartupUserAccount.
u8 user_account_switch_lock; ///< NacpUserAccountSwitchLock. Old: touch_screen_usage (None, Supported, Required).
u8 add_on_content_registration_type; ///< NacpAddOnContentRegistrationType.
NacpAttributeFlag attribute_flag;
NacpSupportedLanguageFlag supported_language_flag;
NacpParentalControlFlag parental_control_flag;
u32 attribute; ///< NacpAttribute.
u32 supported_language; ///< NacpSupportedLanguage.
u32 parental_control; ///< NacpParentalControl.
u8 screenshot; ///< NacpScreenshot.
u8 video_capture; ///< NacpVideoCapture.
u8 data_loss_confirmation; ///< NacpDataLossConfirmation.
@ -340,7 +309,7 @@ typedef struct {
u8 hdcp; ///< NacpHdcp.
u64 seed_for_pseudo_device_id;
char bcat_passphrase[0x41];
NacpStartupUserAccountOptionFlag startup_user_account_option_flag;
u8 startup_user_account_option; ///< NacpStartupUserAccountOption.
u8 reserved_2[0x6];
u64 user_account_save_data_size_max;
u64 user_account_save_data_journal_size_max;
@ -354,9 +323,9 @@ typedef struct {
u8 reserved_3[0x6];
u64 play_log_queryable_application_id[0x10];
u8 play_log_query_capability; ///< NacpPlayLogQueryCapability.
NacpRepairFlag repair_flag;
u8 repair; ///< NacpRepair.
u8 program_index;
NacpRequiredNetworkServiceLicenseOnLaunchFlag required_network_service_license_on_launch_flag;
u8 required_network_service_license_on_launch; ///< NacpRequiredNetworkServiceLicenseOnLaunch.
u8 reserved_4[0x4];
NacpNeighborDetectionClientConfiguration neighbor_detection_client_configuration;
NacpJitConfiguration jit_configuration;
@ -398,9 +367,11 @@ bool nacpInitializeContext(NacpContext *out, NcaContext *nca_ctx);
/// If the function succeeds, XML data and size will get saved to the 'authoring_tool_xml' and 'authoring_tool_xml_size' members from the NacpContext.
bool nacpGenerateAuthoringToolXml(NacpContext *nacp_ctx, u32 version, u32 required_system_version);
/// These functions return pointers to string representations of the input value.
/// If the provided value is invalid, "Unknown" is returned.
const char *nacpGetLanguageString(u8 language);
/// 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).
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);
const char *nacpGetAddOnContentRegistrationTypeString(u8 add_on_content_registration_type);
@ -421,7 +392,7 @@ const char *nacpGetStartupUserAccountOptionString(u8 startup_user_account_option
const char *nacpGetPlayLogQueryCapabilityString(u8 play_log_query_capability);
const char *nacpGetRepairString(u8 repair);
const char *nacpGetRequiredNetworkServiceLicenseOnLaunchString(u8 required_network_service_license_on_launch);
const char *nacpGetJitConfigurationFlagString(u64 jig_configuration_flag);
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);

View file

@ -73,13 +73,6 @@ typedef enum {
NcaKeyAreaEncryptionKeyIndex_System = 2
} NcaKeyAreaEncryptionKeyIndex;
typedef struct {
u32 NcaSdkAddOnVersion_Relstep : 8;
u32 NcaSdkAddOnVersion_Micro : 8;
u32 NcaSdkAddOnVersion_Minor : 8;
u32 NcaSdkAddOnVersion_Major : 8;
} NcaSdkAddOnVersion;
/// 'NcaKeyGeneration_Current' will always point to the last known key generation value.
typedef enum {
NcaKeyGeneration_301_302 = 3,
@ -119,8 +112,8 @@ typedef struct {
/// First 0x400 bytes from every NCA.
typedef struct {
u8 main_signature[0x100]; ///< RSA-PSS signature over header with fixed key.
u8 acid_signature[0x100]; ///< RSA-PSS signature over header with key in NPDM.
u8 main_signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over header using a fixed key.
u8 acid_signature[0x100]; ///< RSA-2048-PSS with SHA-256 signature over header using the ACID public key from the NPDM in ExeFS. Only used in Program NCAs.
u32 magic; ///< "NCA0" / "NCA2" / "NCA3".
u8 distribution_type; ///< NcaDistributionType.
u8 content_type; ///< NcaContentType.
@ -129,7 +122,7 @@ typedef struct {
u64 content_size;
u64 program_id;
u32 content_index;
NcaSdkAddOnVersion sdk_addon_version;
VersionType2 sdk_addon_version;
u8 key_generation; ///< NcaKeyGeneration.
u8 main_signature_key_generation;
u8 reserved[0xE];

View file

@ -20,6 +20,9 @@
#include "utils.h"
#include "pfs.h"
//#include "npdm.h"
#define NPDM_META_MAGIC 0x4D455441 /* "META". */
bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext *nca_fs_ctx)
{
@ -56,7 +59,7 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext *
out->offset = hash_region->offset;
out->size = hash_region->size;
/* Read partial PFS header. */
/* Read partial Partition FS header. */
if (!ncaReadFsSection(nca_fs_ctx, &pfs_header, sizeof(PartitionFileSystemHeader), out->offset))
{
LOGFILE("Failed to read partial Partition FS header!");
@ -167,7 +170,8 @@ bool pfsGetEntryIndexByName(PartitionFileSystemContext *ctx, const char *name, u
}
}
//LOGFILE("Unable to find Partition FS entry \"%s\"!", name);
/* Only log error if we're not dealing with a NPDM. */
if (name_len != 9 || strcmp(name, "main.npdm") != 0) LOGFILE("Unable to find Partition FS entry \"%s\"!", name);
return false;
}

View file

@ -32,7 +32,7 @@
/* Global variables. */
/// Self-generated private key.
static const char g_rsa2048CustomAcidPrivateKey[] = "-----BEGIN RSA PRIVATE KEY-----\r\n"
static const char g_rsa2048CustomPrivateKey[] = "-----BEGIN RSA PRIVATE KEY-----\r\n"
"MIIEowIBAAKCAQEAvVRzt+8mE7oE4RkmSh3ws4CGlBj7uhHkfwCpPFsn4TNVdLRo\r\n"
"YYY17jQYWTtcOYPMcHxwUpgJyspGN8QGXEkJqY8jILv2eO0jBGtg7Br2afUBp6/x\r\n"
"BOMT2RlYVX6H4a1UA19Hzmcn+T1hdDwS6oBYpi8rJSm0+q+yB34dueNkVsk4eKbj\r\n"
@ -61,7 +61,8 @@ static const char g_rsa2048CustomAcidPrivateKey[] = "-----BEGIN RSA PRIVATE KEY-
"-----END RSA PRIVATE KEY-----\r\n";
/// Self-generated public key.
static const u8 g_rsa2048CustomAcidPublicKey[] = {
/// Used to verify signatures generated with g_rsa2048CustomPrivateKey.
static const u8 g_rsa2048CustomPublicKey[] = {
0xBD, 0x54, 0x73, 0xB7, 0xEF, 0x26, 0x13, 0xBA, 0x04, 0xE1, 0x19, 0x26, 0x4A, 0x1D, 0xF0, 0xB3,
0x80, 0x86, 0x94, 0x18, 0xFB, 0xBA, 0x11, 0xE4, 0x7F, 0x00, 0xA9, 0x3C, 0x5B, 0x27, 0xE1, 0x33,
0x55, 0x74, 0xB4, 0x68, 0x61, 0x86, 0x35, 0xEE, 0x34, 0x18, 0x59, 0x3B, 0x5C, 0x39, 0x83, 0xCC,
@ -84,7 +85,7 @@ static const u8 g_rsa2048CustomAcidPublicKey[] = {
static void rsaCalculateMgf1AndXor(void *data, size_t data_size, const void *h_src, size_t h_src_size);
bool rsa2048GenerateSha256BasedCustomAcidSignature(void *dst, const void *src, size_t size)
bool rsa2048GenerateSha256BasedPssSignature(void *dst, const void *src, size_t size)
{
if (!dst || !src || !size)
{
@ -121,7 +122,7 @@ bool rsa2048GenerateSha256BasedCustomAcidSignature(void *dst, const void *src, s
}
/* Parse private key. */
ret = mbedtls_pk_parse_key(&pk, (u8*)g_rsa2048CustomAcidPrivateKey, strlen(g_rsa2048CustomAcidPrivateKey) + 1, NULL, 0);
ret = mbedtls_pk_parse_key(&pk, (const u8*)g_rsa2048CustomPrivateKey, strlen(g_rsa2048CustomPrivateKey) + 1, NULL, 0);
if (ret != 0)
{
LOGFILE("mbedtls_pk_parse_key failed! (%d).", ret);
@ -151,9 +152,9 @@ end:
return success;
}
const u8 *rsa2048GetCustomAcidPublicKey(void)
const u8 *rsa2048GetCustomPublicKey(void)
{
return g_rsa2048CustomAcidPublicKey;
return g_rsa2048CustomPublicKey;
}
bool rsa2048OaepDecryptAndVerify(void *dst, size_t dst_size, const void *signature, const void *modulus, const void *exponent, size_t exponent_size, const void *label_hash, size_t *out_size)

View file

@ -27,12 +27,14 @@
#define RSA2048_SIG_SIZE 0x100
/// Generates a SHA-256 based RSA-2048 signature, suitable to replace the ACID signature in NCA headers.
bool rsa2048GenerateSha256BasedCustomAcidSignature(void *dst, const void *src, size_t size);
/// Generates a RSA-2048-PSS with SHA-256 signature using a custom RSA-2048 private key.
/// Suitable to replace the ACID signature in a Program NCA header.
/// Destination buffer size should be at least RSA2048_SIG_SIZE.
bool rsa2048GenerateSha256BasedPssSignature(void *dst, const void *src, size_t size);
/// Returns the custom ACID public key that can be used to verify the signature generated by rsa2048GenerateSha256BasedCustomAcidSignature().
/// Suitable to replace the ACID public key in main.npdm files.
const u8 *rsa2048GetCustomAcidPublicKey(void);
/// Returns a pointer to the RSA-2048 public key that can be used to verify signatures generated by rsa2048GenerateSha256BasedPssSignature().
/// Suitable to replace the ACID public key in a NPDM.
const u8 *rsa2048GetCustomPublicKey(void);
/// Performs RSA-2048-OAEP decryption and verification. Used to decrypt the titlekey block from tickets with personalized crypto.
bool rsa2048OaepDecryptAndVerify(void *dst, size_t dst_size, const void *signature, const void *modulus, const void *exponent, size_t exponent_size, const void *label_hash, size_t *out_size);

View file

@ -1358,7 +1358,7 @@ static bool titleRetrieveContentMetaKeysFromDatabase(u8 storage_id)
/* Fill information. */
cur_title_info->storage_id = storage_id;
memcpy(&(cur_title_info->meta_key), &(meta_keys[i]), sizeof(NcmContentMetaKey));
memcpy(&(cur_title_info->version), &(meta_keys[i].version), sizeof(u32));
cur_title_info->version.value = meta_keys[i].version;
if (cur_title_info->meta_key.type <= NcmContentMetaType_Application) cur_title_info->app_metadata = titleFindApplicationMetadataByTitleId(meta_keys[i].id);

View file

@ -31,15 +31,6 @@
#define TITLE_DELTA_TYPE_VALUE (u64)0xC00
/// Used to display version numbers in dot notation: "{Major}.{Minor}.{Micro}-{MajorRelstep}.{MinorRelstep}".
typedef struct {
u32 TitleVersion_MinorRelstep : 8;
u32 TitleVersion_MajorRelstep : 8;
u32 TitleVersion_Micro : 4;
u32 TitleVersion_Minor : 6;
u32 TitleVersion_Major : 6;
} TitleVersion;
/// Retrieved using ns application records and/or ncm content meta keys.
/// Used by the UI to display title lists.
typedef struct {
@ -53,7 +44,7 @@ typedef struct {
typedef struct _TitleInfo {
u8 storage_id; ///< NcmStorageId.
NcmContentMetaKey meta_key; ///< Used with ncm calls.
TitleVersion version; ///< Holds the same value from meta_key.version.
VersionType1 version; ///< Holds the same value from meta_key.version.
u32 content_count; ///< Content info count.
NcmContentInfo *content_infos; ///< Content info entries from this title.
u64 title_size; ///< Total title size.
@ -230,9 +221,4 @@ NX_INLINE NcmContentInfo *titleGetContentInfoByTypeAndIdOffset(TitleInfo *info,
return NULL;
}
NX_INLINE u32 titleGetVersionInteger(TitleVersion *version)
{
return (version ? *((u32*)version) : 0);
}
#endif /* __TITLE_H__ */

View file

@ -51,6 +51,8 @@ static u8 g_customFirmwareType = UtilsCustomFirmwareType_Unknown;
static AppletHookCookie g_systemOverclockCookie = {0};
static Mutex g_logfileMutex = 0;
static const char *g_logfileTimestampFormat = "%d-%02d-%02d %02d:%02d:%02d -> %s: ";
static const char *g_logfileLineBreak = "\r\n";
static const char *g_sizeSuffixes[] = { "B", "KiB", "MiB", "GiB" };
static const u32 g_sizeSuffixesCount = MAX_ELEMENTS(g_sizeSuffixes);
@ -389,13 +391,13 @@ void utilsWriteMessageToLogFile(const char *func_name, const char *fmt, ...)
time_t now = time(NULL);
struct tm *ts = localtime(&now);
fprintf(logfile, "%d-%02d-%02d %02d:%02d:%02d -> %s: ", ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, func_name);
fprintf(logfile, g_logfileTimestampFormat, ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, func_name);
va_start(args, fmt);
vfprintf(logfile, fmt, args);
va_end(args);
fprintf(logfile, "\r\n");
fprintf(logfile, g_logfileLineBreak);
fclose(logfile);
utilsCommitSdCardFileSystemChanges();
@ -423,7 +425,7 @@ void utilsWriteMessageToLogBuffer(char **dst, size_t *dst_size, const char *func
dst_str_len = 0;
}
timestamp_len = snprintf(NULL, 0, "%d-%02d-%02d %02d:%02d:%02d -> %s: ", ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, func_name);
timestamp_len = snprintf(NULL, 0, g_logfileTimestampFormat, ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, func_name);
if (timestamp_len <= 0) goto end;
formatted_str_len = vsnprintf(NULL, 0, fmt, args);
@ -443,9 +445,9 @@ void utilsWriteMessageToLogBuffer(char **dst, size_t *dst_size, const char *func
*dst_size = required_dst_size;
}
sprintf(*dst + dst_str_len, "%d-%02d-%02d %02d:%02d:%02d -> %s: ", ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, func_name);
sprintf(*dst + dst_str_len, g_logfileTimestampFormat, ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec, func_name);
vsprintf(*dst + dst_str_len + (size_t)timestamp_len, fmt, args);
sprintf(*dst + dst_str_len + (size_t)timestamp_len + (size_t)formatted_str_len, "\r\n");
sprintf(*dst + dst_str_len + (size_t)timestamp_len + (size_t)formatted_str_len, g_logfileLineBreak);
end:
va_end(args);

View file

@ -38,6 +38,8 @@
#include <stdatomic.h>
#include <switch.h>
#include "common.h"
#define APP_BASE_PATH "sdmc:/switch/" APP_TITLE "/"
#define MEMBER_SIZE(type, member) sizeof(((type*)NULL)->member)
@ -58,10 +60,6 @@
/// Need to move this to npdm.c/h eventually.
#define NPDM_META_MAGIC 0x4D455441 /* "META". */