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:
parent
e943e84380
commit
1c15a096b5
17 changed files with 306 additions and 320 deletions
|
@ -12,9 +12,9 @@
|
|||
{
|
||||
fprintf(title_infos_txt, "Storage ID: 0x%02X\r\n", g_titleInfo[i].storage_id);
|
||||
fprintf(title_infos_txt, "Title ID: %016lX\r\n", g_titleInfo[i].meta_key.id);
|
||||
fprintf(title_infos_txt, "Version: %u (%u.%u.%u-%u.%u)\r\n", g_titleInfo[i].meta_key.version, g_titleInfo[i].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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
55
source/common.h
Normal 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__ */
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
230
source/nacp.c
230
source/nacp.c
|
@ -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++;
|
||||
}
|
||||
|
|
163
source/nacp.h
163
source/nacp.h
|
@ -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);
|
||||
|
|
13
source/nca.h
13
source/nca.h
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
13
source/rsa.c
13
source/rsa.c
|
@ -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)
|
||||
|
|
12
source/rsa.h
12
source/rsa.h
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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". */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue