mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2025-02-19 23:15:37 +00:00
Implemented BFTTF font loading and decoding.
Some people may call me a madman but I don't want to see any more nxdumptool screenshots with a Disney-like font. *war flashbacks*
This commit is contained in:
parent
44965430b3
commit
e6bb15d608
11 changed files with 321 additions and 21 deletions
|
@ -247,7 +247,6 @@ int main(int argc, char *argv[])
|
||||||
char nca_id_str[0x21] = {0};
|
char nca_id_str[0x21] = {0};
|
||||||
|
|
||||||
NcaContext *nca_ctx = NULL;
|
NcaContext *nca_ctx = NULL;
|
||||||
Ticket tik = {0};
|
|
||||||
|
|
||||||
app_metadata = titleGetApplicationMetadataEntries(true, &app_count);
|
app_metadata = titleGetApplicationMetadataEntries(true, &app_count);
|
||||||
if (!app_metadata || !app_count)
|
if (!app_metadata || !app_count)
|
||||||
|
@ -357,7 +356,7 @@ int main(int argc, char *argv[])
|
||||||
} else
|
} else
|
||||||
if (menu == 2)
|
if (menu == 2)
|
||||||
{
|
{
|
||||||
if (!ncaInitializeContext(nca_ctx, cur_title_info->storage_id, 0, &(cur_title_info->content_infos[nca_idx]), &tik))
|
if (!ncaInitializeContext(nca_ctx, cur_title_info->storage_id, 0, &(cur_title_info->content_infos[nca_idx]), NULL))
|
||||||
{
|
{
|
||||||
consolePrint("nca initialize ctx failed\n");
|
consolePrint("nca initialize ctx failed\n");
|
||||||
error = true;
|
error = true;
|
||||||
|
|
|
@ -329,7 +329,6 @@ int main(int argc, char *argv[])
|
||||||
u8 *buf = NULL;
|
u8 *buf = NULL;
|
||||||
|
|
||||||
NcaContext *base_nca_ctx = NULL, *update_nca_ctx = NULL;
|
NcaContext *base_nca_ctx = NULL, *update_nca_ctx = NULL;
|
||||||
Ticket base_tik = {0}, update_tik = {0};
|
|
||||||
|
|
||||||
RomFileSystemContext romfs_ctx = {0};
|
RomFileSystemContext romfs_ctx = {0};
|
||||||
BktrContext bktr_ctx = {0};
|
BktrContext bktr_ctx = {0};
|
||||||
|
@ -486,7 +485,7 @@ int main(int argc, char *argv[])
|
||||||
consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id + program_id_offset);
|
consolePrint("selected title:\n%s (%016lX)\n\n", app_metadata[selected_idx]->lang_entry.name, app_metadata[selected_idx]->title_id + program_id_offset);
|
||||||
|
|
||||||
if (!ncaInitializeContext(base_nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
|
if (!ncaInitializeContext(base_nca_ctx, user_app_data.app_info->storage_id, (user_app_data.app_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
|
||||||
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Program, program_id_offset), &base_tik))
|
titleGetContentInfoByTypeAndIdOffset(user_app_data.app_info, NcmContentType_Program, program_id_offset), NULL))
|
||||||
{
|
{
|
||||||
consolePrint("nca initialize base ctx failed\n");
|
consolePrint("nca initialize base ctx failed\n");
|
||||||
goto out2;
|
goto out2;
|
||||||
|
@ -495,7 +494,7 @@ int main(int argc, char *argv[])
|
||||||
if (user_app_data.patch_info)
|
if (user_app_data.patch_info)
|
||||||
{
|
{
|
||||||
if (!ncaInitializeContext(update_nca_ctx, user_app_data.patch_info->storage_id, (user_app_data.patch_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
|
if (!ncaInitializeContext(update_nca_ctx, user_app_data.patch_info->storage_id, (user_app_data.patch_info->storage_id == NcmStorageId_GameCard ? GameCardHashFileSystemPartitionType_Secure : 0), \
|
||||||
titleGetContentInfoByTypeAndIdOffset(user_app_data.patch_info, NcmContentType_Program, program_id_offset), &update_tik))
|
titleGetContentInfoByTypeAndIdOffset(user_app_data.patch_info, NcmContentType_Program, program_id_offset), NULL))
|
||||||
{
|
{
|
||||||
consolePrint("nca initialize update ctx failed\n");
|
consolePrint("nca initialize update ctx failed\n");
|
||||||
goto out2;
|
goto out2;
|
||||||
|
|
230
source/bfttf.c
Normal file
230
source/bfttf.c
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
* bfttf.c
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018, simontime.
|
||||||
|
* Copyright (c) 2020, DarkMatterCore <pabloacurielz@gmail.com>.
|
||||||
|
*
|
||||||
|
* This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
|
||||||
|
*
|
||||||
|
* nxdumptool is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* nxdumptool is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "bfttf.h"
|
||||||
|
#include "romfs.h"
|
||||||
|
#include "title.h"
|
||||||
|
|
||||||
|
/* Type definitions. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 title_id; ///< System title ID.
|
||||||
|
char path[64]; ///< Path to BFTTF file inside the RomFS section from the system title.
|
||||||
|
u32 size;
|
||||||
|
u8 *data;
|
||||||
|
} BfttfFontInfo;
|
||||||
|
|
||||||
|
/* Global variables. */
|
||||||
|
|
||||||
|
static Mutex g_bfttfMutex = 0;
|
||||||
|
static bool g_bfttfInterfaceInit = false;
|
||||||
|
|
||||||
|
static BfttfFontInfo g_fontInfo[] = {
|
||||||
|
{ 0x0100000000000811, "/nintendo_udsg-r_std_003.bfttf", 0, NULL }, /* FontStandard. */
|
||||||
|
{ 0x0100000000000810, "/nintendo_ext_003.bfttf", 0, NULL }, /* FontNintendoExtension (1).*/
|
||||||
|
{ 0x0100000000000810, "/nintendo_ext2_003.bfttf", 0, NULL }, /* FontNintendoExtension (2).*/
|
||||||
|
{ 0x0100000000000812, "/nintendo_udsg-r_ko_003.bfttf", 0, NULL }, /* FontKorean. */
|
||||||
|
{ 0x0100000000000814, "/nintendo_udsg-r_org_zh-cn_003.bfttf", 0, NULL }, /* FontChineseSimplified (1). */
|
||||||
|
{ 0x0100000000000814, "/nintendo_udsg-r_ext_zh-cn_003.bfttf", 0, NULL }, /* FontChineseSimplified (2). */
|
||||||
|
{ 0x0100000000000813, "/nintendo_udjxh-db_zh-tw_003.bfttf", 0, NULL } /* FontChineseTraditional. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u32 g_fontInfoCount = MAX_ELEMENTS(g_fontInfo);
|
||||||
|
|
||||||
|
static const u32 g_bfttfKey = 0x06186249;
|
||||||
|
|
||||||
|
/* Function prototypes. */
|
||||||
|
|
||||||
|
static bool bfttfDecodeFont(BfttfFontInfo *font_info);
|
||||||
|
|
||||||
|
bool bfttfInitialize(void)
|
||||||
|
{
|
||||||
|
mutexLock(&g_bfttfMutex);
|
||||||
|
|
||||||
|
u32 count = 0;
|
||||||
|
NcaContext *nca_ctx = NULL;
|
||||||
|
TitleInfo *title_info = NULL;
|
||||||
|
u64 prev_title_id = 0;
|
||||||
|
|
||||||
|
RomFileSystemContext romfs_ctx = {0};
|
||||||
|
RomFileSystemFileEntry *romfs_file_entry = NULL;
|
||||||
|
|
||||||
|
bool ret = g_bfttfInterfaceInit;
|
||||||
|
if (ret) goto end;
|
||||||
|
|
||||||
|
/* Allocate memory for a temporary NCA context. */
|
||||||
|
nca_ctx = calloc(1, sizeof(NcaContext));
|
||||||
|
if (!nca_ctx)
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to allocate memory for temporary NCA context!");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve BFTTF data. */
|
||||||
|
for(u32 i = 0; i < g_fontInfoCount; i++)
|
||||||
|
{
|
||||||
|
BfttfFontInfo *font_info = &(g_fontInfo[i]);
|
||||||
|
|
||||||
|
/* Check if the title ID for the current font container matches the one from the previous font container. */
|
||||||
|
/* We won't have to reinitialize both NCA and RomFS contexts if that's the case. */
|
||||||
|
if (font_info->title_id != prev_title_id)
|
||||||
|
{
|
||||||
|
/* Get title info. */
|
||||||
|
if (!(title_info = titleGetInfoFromStorageByTitleId(NcmStorageId_BuiltInSystem, font_info->title_id)))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to get title info for %016lX!", font_info->title_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize NCA context. */
|
||||||
|
if (!ncaInitializeContext(nca_ctx, NcmStorageId_BuiltInSystem, 0, titleGetContentInfoByTypeAndIdOffset(title_info, NcmContentType_Data, 0), NULL))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to initialize Data NCA context for %016lX!", font_info->title_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize RomFS context. */
|
||||||
|
if (!romfsInitializeContext(&romfs_ctx, &(nca_ctx->fs_ctx[0])))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to initialize RomFS context for Data NCA from %016lX!", font_info->title_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update previous title ID. */
|
||||||
|
prev_title_id = font_info->title_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get RomFS file entry. */
|
||||||
|
if (!(romfs_file_entry = romfsGetFileEntryByPath(&romfs_ctx, font_info->path)))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to retrieve RomFS file entry in %016lX!", font_info->title_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check file size. */
|
||||||
|
if (!romfs_file_entry->size)
|
||||||
|
{
|
||||||
|
LOGFILE("Invalid file size for \"%s\" in %016lX!", font_info->path, font_info->title_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for BFTTF data. */
|
||||||
|
if (!(font_info->data = malloc(romfs_file_entry->size)))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to allocate 0x%lX bytes for \"%s\" in %016lX!", romfs_file_entry->size, font_info->path, font_info->title_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read BFTFF data. */
|
||||||
|
if (!romfsReadFileEntryData(&romfs_ctx, romfs_file_entry, font_info->data, romfs_file_entry->size, 0))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to read 0x%lX bytes long \"%s\" in %016lX!", romfs_file_entry->size, font_info->path, font_info->title_id);
|
||||||
|
free(font_info->data);
|
||||||
|
font_info->data = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update BFTTF size. */
|
||||||
|
font_info->size = (u32)romfs_file_entry->size;
|
||||||
|
|
||||||
|
/* Decode BFTTF data. */
|
||||||
|
if (!bfttfDecodeFont(font_info))
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to decode 0x%lX bytes long \"%s\" in %016lX!", romfs_file_entry->size, font_info->path, font_info->title_id);
|
||||||
|
free(font_info->data);
|
||||||
|
font_info->data = NULL;
|
||||||
|
font_info->size = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase retrieved BFTTF count. */
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = g_bfttfInterfaceInit = (count > 0);
|
||||||
|
if (!ret) LOGFILE("No BFTTF fonts retrieved!");
|
||||||
|
|
||||||
|
end:
|
||||||
|
romfsFreeContext(&romfs_ctx);
|
||||||
|
|
||||||
|
if (nca_ctx) free(nca_ctx);
|
||||||
|
|
||||||
|
mutexUnlock(&g_bfttfMutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bfttfExit(void)
|
||||||
|
{
|
||||||
|
mutexLock(&g_bfttfMutex);
|
||||||
|
|
||||||
|
/* Free BFTTF data. */
|
||||||
|
for(u32 i = 0; i < g_fontInfoCount; i++)
|
||||||
|
{
|
||||||
|
BfttfFontInfo *font_info = &(g_fontInfo[i]);
|
||||||
|
font_info->size = 0;
|
||||||
|
if (font_info->data) free(font_info->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bfttfInterfaceInit = false;
|
||||||
|
|
||||||
|
mutexUnlock(&g_bfttfMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bfttfGetFontByType(BfttfFontData *font_data, u8 font_type)
|
||||||
|
{
|
||||||
|
if (!font_data || font_type >= BfttfFontType_Total)
|
||||||
|
{
|
||||||
|
LOGFILE("Invalid parameters!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BfttfFontInfo *font_info = &(g_fontInfo[font_type]);
|
||||||
|
if (font_info->size <= 8 || !font_info->data)
|
||||||
|
{
|
||||||
|
LOGFILE("BFTTF font data unavailable for type 0x%02X!", font_type);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_data->type = font_type;
|
||||||
|
font_data->size = (font_info->size - 8);
|
||||||
|
font_data->ptr = (font_info->data + 8);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bfttfDecodeFont(BfttfFontInfo *font_info)
|
||||||
|
{
|
||||||
|
if (!font_info || font_info->size <= 8 || !IS_ALIGNED(font_info->size, 4) || !font_info->data)
|
||||||
|
{
|
||||||
|
LOGFILE("Invalid parameters!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(u32 i = 8; i < (font_info->size - 8); i += 4)
|
||||||
|
{
|
||||||
|
u32 *ptr = (u32*)(font_info->data + i);
|
||||||
|
*ptr = (*ptr ^ g_bfttfKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
55
source/bfttf.h
Normal file
55
source/bfttf.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* bftff.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018, simontime.
|
||||||
|
* 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 __BFTTF_H__
|
||||||
|
#define __BFTTF_H__
|
||||||
|
|
||||||
|
/// Loosely based on PlSharedFontType.
|
||||||
|
typedef enum {
|
||||||
|
BfttfFontType_Standard = 0, ///< Japan, US and Europe
|
||||||
|
BfttfFontType_NintendoExt1 = 1, ///< Nintendo Extended (1). This font only has the special Nintendo-specific characters, which aren't available with the other fonts.
|
||||||
|
BfttfFontType_NintendoExt2 = 2, ///< Nintendo Extended (2). This font only has the special Nintendo-specific characters, which aren't available with the other fonts.
|
||||||
|
BfttfFontType_Korean = 3, ///< Korean (Hangul).
|
||||||
|
BfttfFontType_ChineseSimplified = 4, ///< Chinese Simplified.
|
||||||
|
BfttfFontType_ExtChineseSimplified = 5, ///< Extended Chinese Simplified.
|
||||||
|
BfttfFontType_ChineseTraditional = 6, ///< Chinese Traditional.
|
||||||
|
BfttfFontType_Total = 7 ///< Total fonts supported by this enum.
|
||||||
|
} BfttfFontType;
|
||||||
|
|
||||||
|
/// Loosely based on PlFontData.
|
||||||
|
typedef struct {
|
||||||
|
u8 type; ///< BfttfFontType.
|
||||||
|
u32 size; ///< Decoded BFTFF font size.
|
||||||
|
u8 *ptr; ///< Pointer to font data.
|
||||||
|
} BfttfFontData;
|
||||||
|
|
||||||
|
/// Initializes the BFTTF interface.
|
||||||
|
bool bfttfInitialize(void);
|
||||||
|
|
||||||
|
/// Closes the BFTTF interface.
|
||||||
|
void bfttfExit(void);
|
||||||
|
|
||||||
|
/// Returns a specific BFTTF font using the provided BfttfFontType.
|
||||||
|
bool bfttfGetFontByType(BfttfFontData *font, u8 font_type);
|
||||||
|
|
||||||
|
#endif /* __BFTTF_H__ */
|
|
@ -50,6 +50,9 @@ bool bktrInitializeContext(BktrContext *out, NcaFsSectionContext *base_nca_fs_ct
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free output context beforehand. */
|
||||||
|
bktrFreeContext(out);
|
||||||
|
|
||||||
/* Update missing base NCA RomFS status. */
|
/* Update missing base NCA RomFS status. */
|
||||||
out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs || base_nca_fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx);
|
out->missing_base_romfs = (!base_nca_fs_ctx->enabled || base_nca_fs_ctx->section_type != NcaFsSectionType_RomFs || base_nca_fs_ctx->encryption_type == NcaEncryptionType_AesCtrEx);
|
||||||
|
|
||||||
|
|
16
source/nca.c
16
source/nca.c
|
@ -88,7 +88,7 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
||||||
NcmContentStorage *ncm_storage = NULL;
|
NcmContentStorage *ncm_storage = NULL;
|
||||||
|
|
||||||
if (!out || (storage_id != NcmStorageId_GameCard && !(ncm_storage = titleGetNcmStorageByStorageId(storage_id))) || \
|
if (!out || (storage_id != NcmStorageId_GameCard && !(ncm_storage = titleGetNcmStorageByStorageId(storage_id))) || \
|
||||||
(storage_id == NcmStorageId_GameCard && hfs_partition_type >= GameCardHashFileSystemPartitionType_Count) || !content_info || content_info->content_type > NcmContentType_DeltaFragment || !tik)
|
(storage_id == NcmStorageId_GameCard && hfs_partition_type >= GameCardHashFileSystemPartitionType_Count) || !content_info || content_info->content_type > NcmContentType_DeltaFragment)
|
||||||
{
|
{
|
||||||
LOGFILE("Invalid parameters!");
|
LOGFILE("Invalid parameters!");
|
||||||
return false;
|
return false;
|
||||||
|
@ -138,12 +138,15 @@ bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type,
|
||||||
|
|
||||||
if (out->rights_id_available)
|
if (out->rights_id_available)
|
||||||
{
|
{
|
||||||
|
Ticket tmp_tik = {0};
|
||||||
|
Ticket *usable_tik = (tik ? tik : &tmp_tik);
|
||||||
|
|
||||||
/* Retrieve ticket. */
|
/* Retrieve ticket. */
|
||||||
/* This will return true if it has already been retrieved. */
|
/* This will return true if it has already been retrieved. */
|
||||||
if (tikRetrieveTicketByRightsId(tik, &(out->header.rights_id), out->storage_id == NcmStorageId_GameCard))
|
if (tikRetrieveTicketByRightsId(usable_tik, &(out->header.rights_id), out->storage_id == NcmStorageId_GameCard))
|
||||||
{
|
{
|
||||||
/* Copy decrypted titlekey. */
|
/* Copy decrypted titlekey. */
|
||||||
memcpy(out->titlekey, tik->dec_titlekey, 0x10);
|
memcpy(out->titlekey, usable_tik->dec_titlekey, 0x10);
|
||||||
out->titlekey_retrieved = true;
|
out->titlekey_retrieved = true;
|
||||||
} else {
|
} else {
|
||||||
LOGFILE("Error retrieving ticket for NCA \"%s\"!", out->content_id_str);
|
LOGFILE("Error retrieving ticket for NCA \"%s\"!", out->content_id_str);
|
||||||
|
@ -953,7 +956,12 @@ static bool ncaGenerateHashDataPatch(NcaFsSectionContext *ctx, const void *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear output patch. */
|
/* Clear output patch. */
|
||||||
memset(out, 0, !is_integrity_patch ? sizeof(NcaHierarchicalSha256Patch) : sizeof(NcaHierarchicalIntegrityPatch));
|
if (!is_integrity_patch)
|
||||||
|
{
|
||||||
|
ncaFreeHierarchicalSha256Patch(hierarchical_sha256_patch);
|
||||||
|
} else {
|
||||||
|
ncaFreeHierarchicalIntegrityPatch(hierarchical_integrity_patch);
|
||||||
|
}
|
||||||
|
|
||||||
/* Process each layer. */
|
/* Process each layer. */
|
||||||
for(u32 i = layer_count; i > 0; i--)
|
for(u32 i = layer_count; i > 0; i--)
|
||||||
|
|
|
@ -351,7 +351,9 @@ void ncaFreeCryptoBuffer(void);
|
||||||
|
|
||||||
/// Initializes a NCA context.
|
/// Initializes a NCA context.
|
||||||
/// If 'storage_id' == NcmStorageId_GameCard, the 'hfs_partition_type' argument must be a valid GameCardHashFileSystemPartitionType value.
|
/// If 'storage_id' == NcmStorageId_GameCard, the 'hfs_partition_type' argument must be a valid GameCardHashFileSystemPartitionType value.
|
||||||
/// If the NCA holds a populated Rights ID field, and if the Ticket element pointed to by 'tik' hasn't been filled, ticket data will be retrieved.
|
/// If the NCA holds a populated Rights ID field, ticket data will need to be retrieved.
|
||||||
|
/// If the 'tik' argument points to a valid Ticket element, it will either be updated (if it's empty) or be used to read ticket data that has already been retrieved.
|
||||||
|
/// If the 'tik' argument is NULL, the function will just retrieve the necessary ticket data on its own.
|
||||||
/// If ticket data can't be retrieved, the context will still be initialized, but anything that involves working with encrypted NCA FS section blocks won't be possible (e.g. ncaReadFsSection()).
|
/// If ticket data can't be retrieved, the context will still be initialized, but anything that involves working with encrypted NCA FS section blocks won't be possible (e.g. ncaReadFsSection()).
|
||||||
bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, const NcmContentInfo *content_info, Ticket *tik);
|
bool ncaInitializeContext(NcaContext *out, u8 storage_id, u8 hfs_partition_type, const NcmContentInfo *content_info, Ticket *tik);
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ bool pfsInitializeContext(PartitionFileSystemContext *out, NcaFsSectionContext *
|
||||||
u32 hash_region_count = 0;
|
u32 hash_region_count = 0;
|
||||||
NcaRegion *hash_region = NULL;
|
NcaRegion *hash_region = NULL;
|
||||||
|
|
||||||
/* Clear output Partition FS context. */
|
/* Free output context beforehand. */
|
||||||
memset(out, 0, sizeof(PartitionFileSystemContext));
|
pfsFreeContext(out);
|
||||||
|
|
||||||
/* Fill context. */
|
/* Fill context. */
|
||||||
out->nca_fs_ctx = nca_fs_ctx;
|
out->nca_fs_ctx = nca_fs_ctx;
|
||||||
|
|
|
@ -43,8 +43,8 @@ bool romfsInitializeContext(RomFileSystemContext *out, NcaFsSectionContext *nca_
|
||||||
NcaRegion *hash_region = NULL;
|
NcaRegion *hash_region = NULL;
|
||||||
NcaHierarchicalIntegrityVerificationLevelInformation *level_information = NULL;
|
NcaHierarchicalIntegrityVerificationLevelInformation *level_information = NULL;
|
||||||
|
|
||||||
/* Clear output RomFS context. */
|
/* Free output context beforehand. */
|
||||||
memset(out, 0, sizeof(RomFileSystemContext));
|
romfsFreeContext(out);
|
||||||
|
|
||||||
/* Fill context. */
|
/* Fill context. */
|
||||||
out->nca_fs_ctx = nca_fs_ctx;
|
out->nca_fs_ctx = nca_fs_ctx;
|
||||||
|
|
|
@ -41,7 +41,6 @@ typedef struct {
|
||||||
|
|
||||||
static Result smHasService(bool *out_has_service, SmServiceName name);
|
static Result smHasService(bool *out_has_service, SmServiceName name);
|
||||||
|
|
||||||
static Result servicesPlUserInitialize(void);
|
|
||||||
static Result servicesNifmUserInitialize(void);
|
static Result servicesNifmUserInitialize(void);
|
||||||
static bool servicesClkGetServiceType(void *arg);
|
static bool servicesClkGetServiceType(void *arg);
|
||||||
static bool servicesSplCryptoCheckAvailability(void *arg);
|
static bool servicesSplCryptoCheckAvailability(void *arg);
|
||||||
|
@ -56,7 +55,6 @@ static ServiceInfo g_serviceInfo[] = {
|
||||||
{ false, "spl:", NULL, &splInitialize, &splExit },
|
{ false, "spl:", NULL, &splInitialize, &splExit },
|
||||||
{ false, "spl:mig", &servicesSplCryptoCheckAvailability, &splCryptoInitialize, &splCryptoExit }, /* Checks if spl:mig is really available (e.g. avoid calling splInitialize twice). */
|
{ false, "spl:mig", &servicesSplCryptoCheckAvailability, &splCryptoInitialize, &splCryptoExit }, /* Checks if spl:mig is really available (e.g. avoid calling splInitialize twice). */
|
||||||
{ false, "pm:dmnt", NULL, &pmdmntInitialize, &pmdmntExit },
|
{ false, "pm:dmnt", NULL, &pmdmntInitialize, &pmdmntExit },
|
||||||
{ false, "pl:u", NULL, &servicesPlUserInitialize, &plExit },
|
|
||||||
{ false, "psm", NULL, &psmInitialize, &psmExit },
|
{ false, "psm", NULL, &psmInitialize, &psmExit },
|
||||||
{ false, "nifm:u", NULL, &servicesNifmUserInitialize, &nifmExit },
|
{ false, "nifm:u", NULL, &servicesNifmUserInitialize, &nifmExit },
|
||||||
{ false, "clk", &servicesClkGetServiceType, NULL, NULL }, /* Placeholder for pcv / clkrst. */
|
{ false, "clk", &servicesClkGetServiceType, NULL, NULL }, /* Placeholder for pcv / clkrst. */
|
||||||
|
@ -219,11 +217,6 @@ static Result smHasService(bool *out_has_service, SmServiceName name)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result servicesPlUserInitialize(void)
|
|
||||||
{
|
|
||||||
return plInitialize(PlServiceType_User);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result servicesNifmUserInitialize(void)
|
static Result servicesNifmUserInitialize(void)
|
||||||
{
|
{
|
||||||
return nifmInitialize(NifmServiceType_User);
|
return nifmInitialize(NifmServiceType_User);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "nca.h"
|
#include "nca.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "title.h"
|
#include "title.h"
|
||||||
|
#include "bfttf.h"
|
||||||
#include "fatfs/ff.h"
|
#include "fatfs/ff.h"
|
||||||
|
|
||||||
#define LOGFILE_PATH "./" APP_TITLE ".log"
|
#define LOGFILE_PATH "./" APP_TITLE ".log"
|
||||||
|
@ -125,6 +126,13 @@ bool utilsInitializeResources(void)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize BFTTF interface. */
|
||||||
|
if (!bfttfInitialize())
|
||||||
|
{
|
||||||
|
LOGFILE("Failed to initialize BFTTF interface!");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
/* Retrieve pointer to the SD card FsFileSystem element. */
|
/* Retrieve pointer to the SD card FsFileSystem element. */
|
||||||
if (!(g_sdCardFileSystem = fsdevGetDeviceFileSystem("sdmc:")))
|
if (!(g_sdCardFileSystem = fsdevGetDeviceFileSystem("sdmc:")))
|
||||||
{
|
{
|
||||||
|
@ -186,6 +194,9 @@ void utilsCloseResources(void)
|
||||||
/* Unmount eMMC BIS System partition. */
|
/* Unmount eMMC BIS System partition. */
|
||||||
utilsUnmountEmmcBisSystemPartitionStorage();
|
utilsUnmountEmmcBisSystemPartitionStorage();
|
||||||
|
|
||||||
|
/* Deinitialize BFTTF interface. */
|
||||||
|
bfttfExit();
|
||||||
|
|
||||||
/* Deinitialize title interface. */
|
/* Deinitialize title interface. */
|
||||||
titleExit();
|
titleExit();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue