ホワイトリストphase3, phase4実装、

仮データベース登録 (2009/03/25時点で本物)
SYSM_IGNORE_DHT_PHASE3はバナーチェックでエラーにしない、
SYSM_IGNORE_DHT_EX_NOT_FOUNDは旧データベースでもエラーにしない、
という意味

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2767 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yutaka 2009-03-25 12:00:30 +00:00
parent 3ac6387837
commit a938401b08
13 changed files with 2764 additions and 1937 deletions

View File

@ -21,6 +21,8 @@ TWL_IPL_COMMONDEFS_ = TRUE
#FIRM_USE_PRODUCT_KEYS = TRUE
#SYSM_BUILD_FOR_DEBUGGER = TRUE
SYSM_DEV_WHITELIST_CHECK_SKIP ?= TRUE
#SYSM_IGNORE_DHT_PHASE_3 = TRUE
SYSM_IGNORE_DHT_EX_NOT_FOUND ?= TRUE
ifeq ($(TARGET_FIRM),SYSTEMMENU)
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs.sysmenu

View File

@ -49,7 +49,8 @@ static const u8 g_pubkey_DER[ 0xa2 ] = {
0x00, 0x01
};
static const u8 hmac_key[] = DHT_HMAC_KEY;
static const u8 hmac_key[] = DHT_HMAC_KEY; // for phase1, phase2
static const u8 hmac_key2[] = DHT_HMAC_KEY2; // for phase3, phase4
static DHTReadFunc imageReadFunc;
static void* imageBuffer;
@ -114,6 +115,25 @@ u32 DHT_GetDatabaseLength(const DHTFile* pDHT)
}
return sizeof(DHTHeader) + pDHT->header.nums * sizeof(DHTDatabase);
}
u32 DHT_GetDatabaseExLength(const DHTFileEx* pDHT)
{
if ( pDHT->header.magic_code != DHT_MAGIC_CODE_EX ) // magic codeチェック
{
OS_TPrintf("Invalid magic code (magic=0x%08X) [EX].\n", pDHT->header.magic_code);
return 0;
}
return sizeof(DHTHeader) + pDHT->header.nums * sizeof(DHTDatabaseEx);
}
u32 DHT_GetDatabaseAdHocLength(const DHTFileAdHoc* pDHT)
{
if ( pDHT->header.magic_code != DHT_MAGIC_CODE_ADHOC ) // magic codeチェック
{
OS_TPrintf("Invalid magic code (magic=0x%08X) [AdHoc].\n", pDHT->header.magic_code);
return 0;
}
return sizeof(DHTHeader) + pDHT->header.nums * sizeof(DHTDatabaseAdHoc);
}
static BOOL DHT_CheckDatabase(const DHTFile* pDHT)
{
SVCSignHeapContext pool;
@ -216,6 +236,219 @@ const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short*
#endif
return db;
}
/*
()
*/
static BOOL DHT_CheckDatabaseEx(const DHTFileEx* pDHT)
{
SVCSignHeapContext pool;
static u8 heap[4*1024]; // avoid stack overflow
u8 md1[20];
u8 md2[20];
s32 result;
// ファイル署名取り出し
SVC_InitSignHeap(&pool, heap, sizeof(heap));
SVC_DecryptSign(&pool, md1, pDHT->header.sign, &g_pubkey_DER[29]);
// ハッシュ計算
SVC_CalcSHA1(md2, DHT_GET_SIGN_TARGET_ADDR(&pDHT->header), DHT_GET_SIGN_TARGET_SIZE_EX(&pDHT->header));
// 検証
result = SVC_CompareSHA1(md1, md2);
if ( !result )
{
OS_TPrintf("\n");
OS_TPrintfEx("SIGN = % 20B [EX]\n", md1);
OS_TPrintfEx("HASH = % 20B [EX]\n", md2);
OS_TPrintf("Signature is not valid. [EX]\n");
return FALSE;
}
return TRUE;
}
BOOL DHT_PrepareDatabaseEx(DHTFileEx* pDHT, FSFile* fp)
{
s32 result;
s32 length;
PROFILE_INIT();
if ( fp )
{
// ヘッダ読み込み
PROFILE_COUNT();
result = FS_ReadFile(fp, &pDHT->header, sizeof(DHTHeader));
if ( result != sizeof(DHTHeader) )
{
OS_TPrintf("Cannot read the DHT header (result=%d). [EX]\n", result);
return FALSE;
}
// 拡張データベース読み込み
PROFILE_COUNT();
length = (s32)DHT_GetDatabaseExLength(pDHT) - (s32)sizeof(DHTHeader); // ヘッダを除く
if ( length < 0 )
{
OS_TPrintf("Invalid DHT header. [EX]\n");
return FALSE;
}
result = FS_ReadFile(fp, pDHT->database, length);
if ( result != length )
{
OS_TPrintf("Cannot read the DHT database (result=%d). [EX]\n", result);
return FALSE;
}
}
else
{
PROFILE_COUNT();
PROFILE_COUNT();
}
// 拡張データベースの検証
PROFILE_COUNT();
result = DHT_CheckDatabaseEx(pDHT);
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to prepare the database. [EX]\n");
OS_TPrintf("%10d msec for reading header. [EX]\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for reading database. [EX]\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for comparing hash. [EX]\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("\nTotal: %10d msec. [EX]\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[0]));
#endif
return result;
}
/*
ROMヘッダに対応する拡張データベースを手に入れる
*/
const DHTDatabaseEx* DHT_GetDatabaseEx(const DHTFileEx* pDHT, const ROM_Header_Short* pROMHeader)
{
u8 data[5];
DHTDatabaseEx* db;
PROFILE_INIT();
// 準備
PROFILE_COUNT();
MI_CpuCopy8( pROMHeader->game_code, data, 4 );
data[4] = pROMHeader->rom_version;
db = (DHTDatabaseEx*)bsearch(data, pDHT->database, pDHT->header.nums, sizeof(DHTDatabaseEx), CompareGameCodeAndVersion);
if ( !db )
{
OS_TPrintf("Cannot find the database. [EX]\n");
}
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("%10d msec for searching database. [EX]\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
#endif
return db;
}
/*
()
*/
static BOOL DHT_CheckDatabaseAdHoc(const DHTFileAdHoc* pDHT)
{
SVCSignHeapContext pool;
static u8 heap[4*1024]; // avoid stack overflow
u8 md1[20];
u8 md2[20];
s32 result;
// ファイル署名取り出し
SVC_InitSignHeap(&pool, heap, sizeof(heap));
SVC_DecryptSign(&pool, md1, pDHT->header.sign, &g_pubkey_DER[29]);
// ハッシュ計算
SVC_CalcSHA1(md2, DHT_GET_SIGN_TARGET_ADDR(&pDHT->header), DHT_GET_SIGN_TARGET_SIZE_EX(&pDHT->header));
// 検証
result = SVC_CompareSHA1(md1, md2);
if ( !result )
{
OS_TPrintf("\n");
OS_TPrintfEx("SIGN = % 20B [AdHoc]\n", md1);
OS_TPrintfEx("HASH = % 20B [AdHoc]\n", md2);
OS_TPrintf("Signature is not valid. [AdHoc]\n");
return FALSE;
}
return TRUE;
}
BOOL DHT_PrepareDatabaseAdHoc(DHTFileAdHoc* pDHT, FSFile* fp)
{
s32 result;
s32 length;
PROFILE_INIT();
if ( fp )
{
// ヘッダ読み込み
PROFILE_COUNT();
result = FS_ReadFile(fp, &pDHT->header, sizeof(DHTHeader));
if ( result != sizeof(DHTHeader) )
{
OS_TPrintf("Cannot read the DHT header (result=%d). [AdHoc]\n", result);
return FALSE;
}
// 拡張データベース読み込み
PROFILE_COUNT();
length = (s32)DHT_GetDatabaseAdHocLength(pDHT) - (s32)sizeof(DHTHeader); // ヘッダを除く
if ( length < 0 )
{
OS_TPrintf("Invalid DHT header. [AdHoc]\n");
return FALSE;
}
result = FS_ReadFile(fp, pDHT->database, length);
if ( result != length )
{
OS_TPrintf("Cannot read the DHT database (result=%d). [AdHoc]\n", result);
return FALSE;
}
}
else
{
PROFILE_COUNT();
PROFILE_COUNT();
}
// 拡張データベースの検証
PROFILE_COUNT();
result = DHT_CheckDatabaseAdHoc(pDHT);
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to prepare the database. [AdHoc]\n");
OS_TPrintf("%10d msec for reading header. [AdHoc]\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for reading database. [AdHoc]\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for comparing hash. [AdHoc]\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("\nTotal: %10d msec. [AdHoc]\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[0]));
#endif
return result;
}
/*
ROMヘッダに対応する拡張データベースを手に入れる
*/
static const DHTDatabaseAdHoc* DHT_GetDatabaseAdHoc(const DHTFileAdHoc* pDHT, const ROM_Header_Short* pROMHeader)
{
u8 data[5];
DHTDatabaseAdHoc* db;
PROFILE_INIT();
// 準備
PROFILE_COUNT();
MI_CpuCopy8( pROMHeader->game_code, data, 4 );
data[4] = pROMHeader->rom_version;
db = (DHTDatabaseAdHoc*)bsearch(data, pDHT->database, pDHT->header.nums, sizeof(DHTDatabaseAdHoc), CompareGameCodeAndVersion);
if ( !db )
{
OS_TPrintf("Cannot find the database. [AdHoc]\n");
}
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("%10d msec for searching database. [AdHoc]\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
#endif
return db;
}
/*
(1)
@ -468,3 +701,141 @@ void DHT_CheckHashPhase2ExUpdate(SVCHMACSHA1Context* ctx, const void* ptr, s32 l
SVC_HMACSHA1Update(ctx, ptr, (u32)length);
}
}
/*
(3)
*/
BOOL DHT_CheckHashPhase3(const u8 *hash, const NTRBannerFile* pBanner)
{
SVCHMACSHA1Context ctx;
u8 md[20];
PROFILE_INIT();
PROFILE_COUNT();
SVC_HMACSHA1Init(&ctx, hmac_key2, sizeof(hmac_key2));
// バナーの読み込み (ヘッダ)
PROFILE_COUNT();
SVC_HMACSHA1Update(&ctx, &pBanner->h, sizeof(BannerHeader));
// バナーの読み込み (ボディ)
if (pBanner->h.version == 0)
{
OS_TPrintf("Invalid banner format.\n");
return FALSE;
}
PROFILE_COUNT();
if ( pBanner->h.version >= 1 )
{
SVC_HMACSHA1Update(&ctx, &pBanner->v1, sizeof(BannerFileV1));
}
PROFILE_COUNT();
if ( pBanner->h.version >= 2 )
{
SVC_HMACSHA1Update(&ctx, &pBanner->v2, sizeof(BannerFileV2));
}
PROFILE_COUNT();
if ( pBanner->h.version >= 3 )
{
SVC_HMACSHA1Update(&ctx, &pBanner->v3, sizeof(BannerFileV3));
}
// 検証
PROFILE_COUNT();
SVC_HMACSHA1GetHash(&ctx, md);
if ( !SVC_CompareSHA1(md, hash) )
{
OS_TPrintf("\n");
OS_TPrintfEx("DB = % 20B\n", hash);
OS_TPrintfEx("HASH = % 20B\n", md);
OS_TPrintf("%s: banner_hash is not valid.\n", __func__);
return FALSE;
}
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to check the hash (phase 3).\n");
OS_TPrintf("%10d msec for preparing hash.\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for scanning header.\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for scanning V1 body.\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("%10d msec for scanning V2 body.\n", (int)OS_TicksToMilliSeconds(profile[4]-profile[3]));
OS_TPrintf("%10d msec for scanning V3 body.\n", (int)OS_TicksToMilliSeconds(profile[5]-profile[4]));
OS_TPrintf("%10d msec for comparing hash.\n", (int)OS_TicksToMilliSeconds(profile[6]-profile[5]));
OS_TPrintf("\nTotal: %10d msec.\n", (int)OS_TicksToMilliSeconds(profile[6]-profile[0]));
#endif
return TRUE;
}
/*
(4)
*/
BOOL DHT_CheckHashPhase4(const DHTFileAdHoc* pDHT, const ROM_Header_Short* pROMHeader, DHTPhase4Work* work, DHTReadFunc func, void* arg)
{
imageBuffer = work->buffer;
imageReadFunc = func;
return DHT_CheckHashPhase4Ex(pDHT, pROMHeader, ImageHMACSHA1Update, arg);
}
BOOL DHT_CheckHashPhase4Ex(const DHTFileAdHoc* pDHT, const ROM_Header_Short* pROMHeader, DHTReadFuncEx funcEx, void* arg)
{
const DHTDatabaseAdHoc* plist;
SVCHMACSHA1Context ctx;
int i;
u8 md[20];
PROFILE_INIT();
if ( !funcEx || !pDHT || !pROMHeader )
{
return FALSE;
}
plist = DHT_GetDatabaseAdHoc(pDHT, pROMHeader);
if ( !plist )
{
return TRUE; // not found in individual list
}
// 準備
PROFILE_COUNT();
SVC_HMACSHA1Init(&ctx, hmac_key2, sizeof(hmac_key2));
for (i = 0; i < DHT_INDIVIDUAL_ENTRY_MAX; i++)
{
if (plist->entry[i].offset == 0)
{
break;
}
if ( !funcEx(&ctx, (s32)plist->entry[i].offset, (s32)plist->entry[i].length, arg) )
{
OS_TPrintf("Cannot read the phase 3 for %.4s(%x).\n", pROMHeader->game_code, pROMHeader->rom_version);
return FALSE;
}
}
// 検証
PROFILE_COUNT();
SVC_HMACSHA1GetHash(&ctx, md);
if ( !SVC_CompareSHA1(md, plist->hash) )
{
OS_TPrintf("\n");
OS_TPrintfEx("DB = % 20B\n", plist->hash);
OS_TPrintfEx("HASH = % 20B\n", md);
OS_TPrintf("%s: phase4list->hash is not valid.\n", __func__);
return FALSE;
}
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to check the hash (phase 3).\n");
OS_TPrintf("%10d msec for preparing hash.\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for scanning regions.\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for comparing hash.\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("\nTotal: %10d msec.\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[0]));
#endif
return TRUE;
}

View File

@ -62,6 +62,16 @@ include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
ifeq ($(SYSM_DEV_WHITELIST_CHECK_SKIP),TRUE)
MACRO_FLAGS += -DDEV_WHITELIST_CHECK_SKIP
else
ifeq ($(SYSM_IGNORE_DHT_PHASE_3),TRUE)
MACRO_FLAGS += -DSYSM_IGNORE_DHT_PHASE_3
endif
ifeq ($(SYSM_IGNORE_DHT_EX_NOT_FOUND),TRUE)
MACRO_FLAGS += -DSYSM_IGNORE_DHT_EX_NOT_FOUND
endif
endif
INSTALL_TARGETS = $(TARGETS)

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -27,6 +27,8 @@ include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
include ./commondefs.DSHashTable
MY_DATA = $(DS_HASH_TABLE_DATA)
MY_DATA_EX = $(DS_HASH_TABLE_EX_DATA)
MY_DATA_ADHOC = $(DS_HASH_TABLE_ADHOC_DATA)
MY_APPEND = revision.bin
MY_DATA2 = data.bin
@ -49,8 +51,8 @@ do-build : $(MY_TAD)
$(MY_TAD): $(MY_DATA2)
$(MAKETAD) $(call empath,$<) $(DS_HASH_TABLE_MAKETAD_OPTION) -o $@
$(MY_DATA2): $(MY_DATA) $(MY_APPEND)
cat $(MY_DATA) $(MY_APPEND) > $@
$(MY_DATA2): $(MY_DATA) $(MY_DATA_EX) $(MY_DATA_ADHOC) $(MY_APPEND)
cat $(MY_DATA) $(MY_DATA_EX) $(MY_DATA_ADHOC) $(MY_APPEND) > $@
$(MY_APPEND)::
@if test -e $(SYSMENU_ROOT)/.svn; then \

View File

@ -17,8 +17,12 @@
#----------------------------------------------------------------------------
DS_HASH_TABLE_TITLE_NAME := DSHashTable
DS_HASH_TABLE_EX_TITLE_NAME := DSHashTableEx
DS_HASH_TABLE_ADHOC_TITLE_NAME:= DSHashTableAdHoc
DS_HASH_TABLE_DATA_DIR := $(SYSMENU_ROOT)/build/systemMenu_RED/DSHashTable
DS_HASH_TABLE_DATA := $(DS_HASH_TABLE_DATA_DIR)/$(DS_HASH_TABLE_TITLE_NAME).bin
DS_HASH_TABLE_EX_DATA := $(DS_HASH_TABLE_DATA_DIR)/$(DS_HASH_TABLE_EX_TITLE_NAME).bin
DS_HASH_TABLE_ADHOC_DATA := $(DS_HASH_TABLE_DATA_DIR)/$(DS_HASH_TABLE_ADHOC_TITLE_NAME).bin
DS_HASH_TABLE_TITLE := HNHA
DS_HASH_TABLE_TITLE_ID_HI := 0003000F
DS_HASH_TABLE_TITLE_ID_LO := $(shell perl -e 'printf "%02X%02X%02X%02X", unpack("C4", "'$(DS_HASH_TABLE_TITLE)'")')
@ -32,7 +36,7 @@ DS_HASH_TABLE_VERSION := $(shell perl -e 'open IN, "$(DS_HASH_TABLE_D
#DS_HASH_TABLE_MINOR_VERSION := $(shell expr $(DS_HASH_TABLE_VERSION) % 256)
DS_HASH_TABLE_MAJOR_VERSION := 0
DS_HASH_TABLE_MINOR_VERSION := 0
DS_HASH_TABLE_MINOR_VERSION := 1
DS_HASH_TABLE_MAKETAD_OPTION := -s -d $(DS_HASH_TABLE_TITLE_ID) $(DS_HASH_TABLE_GROUP_ID) $(DS_HASH_TABLE_MAJOR_VERSION) $(DS_HASH_TABLE_TITLE_NAME) \
-v $(DS_HASH_TABLE_MINOR_VERSION) -p

View File

@ -39,13 +39,13 @@
#define INIT_DEVICES_LIKE_UIG_LAUNCHER
// デバッグ用時間計測スイッチ
#define MEASURE_TIME 1
#define MEASURE_TIME 1
#if ( MEASURE_TIME == 1 )
#define MEASURE_START(tgt) ( tgt = OS_GetTick() )
#define MEASURE_RESULT(tgt,str) OS_TPrintf( str, OS_TicksToMilliSeconds( OS_GetTick() - tgt ) )
#define MEASURE_START(tgt) ( tgt = OS_GetTick() )
#define MEASURE_RESULT(tgt,str) OS_TPrintf( str, OS_TicksToMilliSeconds( OS_GetTick() - tgt ) )
#else
#define MEASURE_START(tgt) ((void) 0)
#define MEASURE_RESULT(tgt,str) ((void) 0)
#define MEASURE_START(tgt) ((void) 0)
#define MEASURE_RESULT(tgt,str) ((void) 0)
#endif
// function's prototype-------------------------------------------------------
@ -71,51 +71,51 @@ static StreamInfo s_strm; // stream info
const char filename[] = "data/fanfare.32.wav";
static const char *fatal_error_msg[FATAL_ERROR_MAX] =
static const char *fatal_error_msg[FATAL_ERROR_MAX] =
{
"UNDEFINED",
"NAND",
"HWINFO_NORMAL",
"HWINFO_SECURE",
"TWLSETTINGS",
"SHARED_FONT",
"WLANFIRM_AUTH",
"WLANFIRM_LOAD",
"TITLE_LOAD_FAILED",
"TITLE_POINTER_ERROR",
"AUTHENTICATE_FAILED",
"ENTRY_ADDRESS_ERROR",
"TITLE_BOOTTYPE_ERROR",
"SIGN_DECRYPTION_FAILED",
"SIGN_COMPARE_FAILED",
"HEADER_HASH_CALC_FAILED",
"TITLEID_COMPARE_FAILED",
"VALID_SIGN_FLAG_OFF",
"CHECK_TITLE_LAUNCH_RIGHTS_FAILED",
"MODULE_HASH_CHECK_FAILED",
"MODULE_HASH_CALC_FAILED",
"MEDIA_CHECK_FAILED",
"DL_MAGICCODE_CHECK_FAILED",
"DL_SIGN_DECRYPTION_FAILED",
"DL_HASH_CALC_FAILED",
"DL_SIGN_COMPARE_FAILED",
"WHITELIST_INITDB_FAILED",
"WHITELIST_NOTFOUND",
"DHT_PHASE1_FAILED",
"DHT_PHASE2_FAILED",
"LANDING_TMP_JUMP_FLAG_OFF",
"TWL_BOOTTYPE_UNKNOWN",
"NTR_BOOTTYPE_UNKNOWN",
"PLATFORM_UNKNOWN",
"LOAD_UNFINISHED",
"LOAD_OPENFILE_FAILED",
"LOAD_MEMALLOC_FAILED",
"LOAD_SEEKFILE_FAILED",
"LOAD_READHEADER_FAILED",
"LOAD_LOGOCRC_ERROR",
"LOAD_READDLSIGN_FAILED",
"LOAD_RELOCATEINFO_FAILED",
"LOAD_READMODULE_FAILED",
"UNDEFINED",
"NAND",
"HWINFO_NORMAL",
"HWINFO_SECURE",
"TWLSETTINGS",
"SHARED_FONT",
"WLANFIRM_AUTH",
"WLANFIRM_LOAD",
"TITLE_LOAD_FAILED",
"TITLE_POINTER_ERROR",
"AUTHENTICATE_FAILED",
"ENTRY_ADDRESS_ERROR",
"TITLE_BOOTTYPE_ERROR",
"SIGN_DECRYPTION_FAILED",
"SIGN_COMPARE_FAILED",
"HEADER_HASH_CALC_FAILED",
"TITLEID_COMPARE_FAILED",
"VALID_SIGN_FLAG_OFF",
"CHECK_TITLE_LAUNCH_RIGHTS_FAILED",
"MODULE_HASH_CHECK_FAILED",
"MODULE_HASH_CALC_FAILED",
"MEDIA_CHECK_FAILED",
"DL_MAGICCODE_CHECK_FAILED",
"DL_SIGN_DECRYPTION_FAILED",
"DL_HASH_CALC_FAILED",
"DL_SIGN_COMPARE_FAILED",
"WHITELIST_INITDB_FAILED",
"WHITELIST_NOTFOUND",
"DHT_PHASE1_FAILED",
"DHT_PHASE2_FAILED",
"LANDING_TMP_JUMP_FLAG_OFF",
"TWL_BOOTTYPE_UNKNOWN",
"NTR_BOOTTYPE_UNKNOWN",
"PLATFORM_UNKNOWN",
"LOAD_UNFINISHED",
"LOAD_OPENFILE_FAILED",
"LOAD_MEMALLOC_FAILED",
"LOAD_SEEKFILE_FAILED",
"LOAD_READHEADER_FAILED",
"LOAD_LOGOCRC_ERROR",
"LOAD_READDLSIGN_FAILED",
"LOAD_RELOCATEINFO_FAILED",
"LOAD_READMODULE_FAILED",
"NINTENDO_LOGO_CHECK_FAILED",
"SYSMENU_VERSION",
"DHT_PHASE1_CALC_FAILED",
@ -123,7 +123,9 @@ static const char *fatal_error_msg[FATAL_ERROR_MAX] =
"LOAD_AUTH_HEADER_FAILED",
"LOAD_NEVER_STARTED",
"EJECT_CARD_AFTER_LOAD_START",
"TITLEID_COMPARE_FAILED_NTR"
"TITLEID_COMPARE_FAILED_NTR",
"DHT_PHASE3_FAILED",
"DHT_PHASE4_FAILED"
};
//#define DEBUG_LAUNCHER_DUMP
@ -147,12 +149,12 @@ static int CreateDspSlotBitmap(int slot_num)
{
int i, bitmap;
bitmap = 0;
for (i=0; i<slot_num; i++)
{
bitmap += (1 << i);
}
return bitmap;
}
@ -180,36 +182,36 @@ void TwlMain( void )
#endif
OSTick start, end = 0;
BOOL direct_boot = FALSE;
BOOL isStartScanWDS = FALSE;
BOOL isStartScanWDS = FALSE;
#ifdef DEBUG_LAUNCHER_DUMP
// you should comment out to clear GX/G2/DMA/TM/PAD register in reboot.c to retreive valid boot time
STD_TSPrintf((char*)0x02FFCFC0, "\nLauncher Boot Time: %lld usec\n", OS_TicksToMicroSeconds(reg_OS_TM3CNT_L * (1024/64)));
#endif
// システムメニュー初期化----------
SYSM_Init( Alloc, Free ); // OS_Initの前でコールする必要あり。
OS_Init();
SYSM_SetArena(); // OS_Initの後でコールする必要あり。
// CRYPTOライブラリ初期化---------- 2008.07.24 ESライブラリがCRYPTOを使用するようになったので、この処理が必要。
CRYPTO_SetAllocator( Alloc, Free );
// ColdStart時は、ロゴデモが終わるまでは、HWリセットボタンによるHotBootフラグセットを抑制する。
// (「健康と安全」画面を必ず表示するため)
if( !SYSM_IsHotStart() ) {
OSi_SetEnableHotBoot( FALSE );
}
// CRYPTOライブラリ初期化---------- 2008.07.24 ESライブラリがCRYPTOを使用するようになったので、この処理が必要。
CRYPTO_SetAllocator( Alloc, Free );
// ColdStart時は、ロゴデモが終わるまでは、HWリセットボタンによるHotBootフラグセットを抑制する。
// (「健康と安全」画面を必ず表示するため)
if( !SYSM_IsHotStart() ) {
OSi_SetEnableHotBoot( FALSE );
}
// OS初期化------------------------
OS_InitTick();
// start 時間計測total
// start 時間計測total
MEASURE_START(allstart);
// start時間計測
MEASURE_START(start);
PM_Init();
(void)OS_EnableIrq();
@ -230,37 +232,37 @@ void TwlMain( void )
RTC_Init();
SND_Init();// sound init
#ifdef USE_WRAM_LOAD
HOTSW_Init();
HOTSW_Init();
#endif
//NAMの初期化
NAM_Init( Alloc, Free );
OS_TPrintf( "SYSM_work size = 0x%x\n", sizeof(SYSM_work) );
// 割り込み許可--------------------
(void)OS_SetIrqFunction(OS_IE_V_BLANK, INTR_VBlank);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)GX_VBlankIntr(TRUE);
// システムの初期化----------------
InitAllocator(); // ※SYSM_Init以外のSYSMライブラリ関数を呼ぶ前に
ERRORLOG_Init( Alloc, Free );
// end時間計測
MEASURE_RESULT( start, "System Init Time 1: %dms\n" );
MEASURE_RESULT( start, "System Init Time 1: %dms\n" );
// start時間計測-b
MEASURE_START(start);
// Alloc, Freeで登録したメモリアロケータを初期化してください。
#ifdef INIT_DEVICES_LIKE_UIG_LAUNCHER
// カメラ初期化
// CAMERA_Init();
// CAMERA_Init();
// end時間計測-b
MEASURE_RESULT( start, "Camera Init: %dms\n" );
MEASURE_RESULT( start, "Camera Init: %dms\n" );
#ifdef USE_HYENA_COMPONENT
// DSP初期化
@ -288,109 +290,109 @@ void TwlMain( void )
// start時間計測-c
MEASURE_START(start);
// 各種パラメータの取得------------
pBootTitle = SYSM_ReadParameters(); // 本体設定データ、HW情報リード
// アプリジャンプ、検査用カード起動、生産工程用ショートカット、デバッガ起動、初回起動シーケンス、TP設定ショートカットの判定
// アプリジャンプ、検査用カード起動、生産工程用ショートカット、デバッガ起動、初回起動シーケンス、TP設定ショートカットの判定
// TPキャリブレーション
UTL_CaribrateTP( LCFG_TSD_GetTPCalibrationPtr() );
UTL_CaribrateTP( LCFG_TSD_GetTPCalibrationPtr() );
if( UTL_IsFatalError() ) {
// FATALエラー処理
PrintError(); // エラー表示
state = STOP;
goto MAIN_LOOP_START; // state を STOP にして強制的にメインループ開始
}
if( !LCFG_TSD_IsFinishedInitialSetting_Launcher() ) {
// ランチャー内での初回起動シーケンス中なら、写真撮影を実行するようにする。
// ※本体設定内での初会起動シーケンス中の場合は、SYSM_ReadParameters 内のチェックで検出されて、本体設定が起動されるようになっています。
// ※本体設定内での初会起動シーケンス中の場合は、SYSM_ReadParameters 内のチェックで検出されて、本体設定が起動されるようになっています。
}
// end時間計測-c
MEASURE_RESULT( start, "SYSM_ReadParameters: %dms\n" );
MEASURE_RESULT( start, "SYSM_ReadParameters: %dms\n" );
// start時間計測4
MEASURE_START(start);
// タイトルリストの準備
SYSM_InitTitleList();
// end時間計測4
MEASURE_RESULT( start, "InitNandTitleList : %dms\n" );
MEASURE_RESULT( start, "InitNandTitleList : %dms\n" );
// start時間計測
MEASURE_START(start);
sp_titleList = SYSM_GetCardTitleList(NULL); // カードアプリリストの取得カードアプリはsp_titleList[0]に格納される)
// end時間計測
MEASURE_RESULT( start, "GetCardTitleList Time : %dms\n" );
MEASURE_RESULT( start, "GetCardTitleList Time : %dms\n" );
// start時間計測3
MEASURE_START(start);
// TMPフォルダのクリーン
SYSM_DeleteTmpDirectory( pBootTitle );
// ダミーのDSメニューラッピング用ファイル作成UIGランチャーが作っているもの
CreateDummyWrapFile();
// TMPフォルダのクリーン
SYSM_DeleteTmpDirectory( pBootTitle );
// ダミーのDSメニューラッピング用ファイル作成UIGランチャーが作っているもの
CreateDummyWrapFile();
// end時間計測3
MEASURE_RESULT( start, "TmpClean : %dms\n" );
MEASURE_RESULT( start, "TmpClean : %dms\n" );
// start時間計測5
MEASURE_START(start);
// 「ダイレクトブートでない」なら
if( !pBootTitle ) {
// NAND & カードアプリリスト取得
if( !SYSM_IsLogoDemoSkip() )
{
SYSM_MakeNandTitleListAsync(); // NANDアプリリストの作成取得はしていないので注意
SYSM_MakeNandTitleListAsync(); // NANDアプリリストの作成取得はしていないので注意
}else
{
sp_titleList = SYSM_GetNandTitleList();
}
sp_titleList = SYSM_GetNandTitleList();
}
}else
{
if( !pBootTitle->flags.isLogoSkip )
{
SYSM_MakeNandTitleListMakerInfoAsync(); // アプリに引き渡すタイトルリスト作成用情報の作成
}else
{
SYSM_MakeNandTitleListMakerInfo();
}
}
if( !pBootTitle->flags.isLogoSkip )
{
SYSM_MakeNandTitleListMakerInfoAsync(); // アプリに引き渡すタイトルリスト作成用情報の作成
}else
{
SYSM_MakeNandTitleListMakerInfo();
}
}
// end時間計測5
MEASURE_RESULT( start, "GetNandTitleList : %dms\n" );
MEASURE_RESULT( start, "GetNandTitleList : %dms\n" );
// start時間計測6
MEASURE_START(start);
// 「ダイレクトブートでない」もしくは
// 「ダイレクトブートだが、ロゴデモ表示」の時、各種リソースのロード------------
#ifndef SYSM_BUILD_FOR_PRODUCTION_TEST
if( !pBootTitle ||
( pBootTitle && !SYSM_IsLogoDemoSkip() ) ) {
u32 timestamp;
if( !LoadSharedFontInit() ) { // 共有フォントのロード
UTL_SetFatalError( FATAL_ERROR_SHARED_FONT );
}
timestamp = OS_GetSharedFontTimestamp();
if( timestamp > 0 ) OS_TPrintf( "SharedFont timestamp : %08x\n", timestamp );
}
u32 timestamp;
if( !LoadSharedFontInit() ) { // 共有フォントのロード
UTL_SetFatalError( FATAL_ERROR_SHARED_FONT );
}
timestamp = OS_GetSharedFontTimestamp();
if( timestamp > 0 ) OS_TPrintf( "SharedFont timestamp : %08x\n", timestamp );
}
#endif // SYSM_BUILD_FOR_PRODUCTION_TEST
// end時間計測6
MEASURE_RESULT( start, "GetSharedFont : %dms\n" );
MEASURE_RESULT( start, "GetSharedFont : %dms\n" );
// 開始ステートの判定--------------
// start時間計測7
MEASURE_START(start);
if( pBootTitle ) {
// ダイレクトブートなら、ロゴ、ランチャーを飛ばしてロード開始
if( pBootTitle->flags.isLogoSkip ) {
@ -422,9 +424,9 @@ void TwlMain( void )
#ifdef SYSM_BUILD_FOR_PRODUCTION_TEST
if( !pBootTitle ||
( pBootTitle && ( pBootTitle->flags.bootType != LAUNCHER_BOOTTYPE_ROM ) )
) {
state = STOP;
}
) {
state = STOP;
}
#endif // SYSM_BUILD_FOR_PRODUCTION_TEST
// チャンネルをロックする
@ -437,20 +439,20 @@ void TwlMain( void )
s_strmThreadStack + THREAD_STACK_SIZE / sizeof(u64),
THREAD_STACK_SIZE, STREAM_THREAD_PRIO);
OS_WakeupThreadDirect(&s_strmThread);
// end時間計測7
MEASURE_RESULT( start, "time 7 (etc...) : %dms\n" );
MEASURE_RESULT( start, "time 7 (etc...) : %dms\n" );
// start時間計測8
MEASURE_START(start);
// 無線ファームウェアを無線モジュールにダウンロードする。
if( FALSE == InstallWlanFirmware( SYSM_IsHotStart() ) ) {
OS_TPrintf( "ERROR: Wireless firmware download failed!\n" );
}
// end時間計測8
MEASURE_RESULT( start, "Load WlanFirm Time : %dms\n" );
MEASURE_RESULT( start, "Load WlanFirm Time : %dms\n" );
if( UTL_IsFatalError() ) {
// FATALエラー処理
@ -459,11 +461,11 @@ void TwlMain( void )
goto MAIN_LOOP_START; // state を STOP にして強制的にメインループ開始
}
// end 時間計測total
MEASURE_RESULT( allstart, "Total Time : %dms\n" );
// end 時間計測total
MEASURE_RESULT( allstart, "Total Time : %dms\n" );
MAIN_LOOP_START:
// メインループ--------------------
while( 1 ) {
OS_WaitIrq(1, OS_IE_V_BLANK); // Vブランク割り込み待ち
@ -487,27 +489,27 @@ MAIN_LOOP_START:
state = LOGODEMO;
break;
case LOGODEMO:
if( IsFinishedLoadSharedFont() && // 通常ブート時は、フォントロード終了をここでチェック
LogoMain() &&
SYSM_isNandTitleListReady() // NANDタイトル取得完了かどうかチェック
) {
// ::::::::::::::::::::::::::::::::::::::::::::::
// SystemMenuバージョンetc.の読み込み
// ::::::::::::::::::::::::::::::::::::::::::::::
// NANDタイトルリスト取得が完了した時点で、その情報をもとにSystemMenuVersionデータにアクセスするための制御情報をセットする。
SYSM_SetSystemMenuVersionControlData();
PrintSystemMenuVersion();
if( !direct_boot ) {
sp_titleList = SYSM_GetTitlePropertyList();// TitlePropertyListの取得
if( IsFinishedLoadSharedFont() && // 通常ブート時は、フォントロード終了をここでチェック
LogoMain() &&
SYSM_isNandTitleListReady() // NANDタイトル取得完了かどうかチェック
) {
// ::::::::::::::::::::::::::::::::::::::::::::::
// SystemMenuバージョンetc.の読み込み
// ::::::::::::::::::::::::::::::::::::::::::::::
// NANDタイトルリスト取得が完了した時点で、その情報をもとにSystemMenuVersionデータにアクセスするための制御情報をセットする。
SYSM_SetSystemMenuVersionControlData();
PrintSystemMenuVersion();
if( !direct_boot ) {
sp_titleList = SYSM_GetTitlePropertyList();// TitlePropertyListの取得
state = LAUNCHER_INIT;
}else {
state = LOAD_START;
}
// ロゴデモが終了した場合は、HotBootフラグ抑制を解除する。
OSi_SetEnableHotBoot( TRUE );
}
// ロゴデモが終了した場合は、HotBootフラグ抑制を解除する。
OSi_SetEnableHotBoot( TRUE );
}
break;
case LAUNCHER_INIT:
LauncherInit( NULL );
@ -520,26 +522,26 @@ MAIN_LOOP_START:
}
break;
case LOAD_START:
if( IsFinishedLoadSharedFont() // ダイレクトブートの時は、フォントロード終了をここでチェック
if( IsFinishedLoadSharedFont() // ダイレクトブートの時は、フォントロード終了をここでチェック
&& PollingInstallWlanFirmware()
#ifndef SYSM_DISABLE_WDS_SCAN // アプリブート前にWDSスキャンは終了しておく必要がある
&& ( WDS_WrapperStopScan() != WDSWRAPPER_ERRCODE_OPERATING )
#ifndef SYSM_DISABLE_WDS_SCAN // アプリブート前にWDSスキャンは終了しておく必要がある
&& ( WDS_WrapperStopScan() != WDSWRAPPER_ERRCODE_OPERATING )
#endif // SYSM_DISABLE_WDS_SCAN
) {
SYSM_StartLoadTitle( pBootTitle );
state = LOADING;
start = OS_GetTick();
// 念のため必ず通るパスでもショートカット起動、HotBootフラグ抑制を解除しておく。
OSi_SetEnableHotBoot( TRUE );
}
) {
SYSM_StartLoadTitle( pBootTitle );
state = LOADING;
start = OS_GetTick();
// 念のため必ず通るパスでもショートカット起動、HotBootフラグ抑制を解除しておく。
OSi_SetEnableHotBoot( TRUE );
}
break;
case LOADING:
// ここでロード前ホワイトリストチェック失敗メッセージをポーリングし、受け取ったらstateをLOAD_PAUSEに
if( SYSM_IsLoadTitlePaused() )
{
state = LOAD_PAUSE;
PrintPause();
}
state = LOAD_PAUSE;
PrintPause();
}
if( SYSM_IsLoadTitleFinished() ) {
SYSM_StartAuthenticateTitle( pBootTitle );
state = AUTHENTICATE;
@ -559,14 +561,14 @@ MAIN_LOOP_START:
// 強制起動するか中止するかの選択がされたらLOADINGに戻る
if( IsCommandSelected() )
{
state = LOADING;
}
state = LOADING;
}
break;
case AUTHENTICATE:
if( ( direct_boot || ( !direct_boot && LauncherFadeout( sp_titleList ) ) ) &&
SYSM_IsAuthenticateTitleFinished()
) {
// メインループ開始から検証終了までの間に起きたFATALの処理
) {
// メインループ開始から検証終了までの間に起きたFATALの処理
if( UTL_IsFatalError() ) {
// FATALエラー処理
// [TODO:]クリアしたほうが良いデータ(鍵など)があれば消す
@ -574,59 +576,59 @@ MAIN_LOOP_START:
state = STOP;
break; // state を STOP にして break し、 Boot させない
}
#ifndef SYSM_DISABLE_WDS_SCAN
// Nintendoスポットブート時は、アプリ間パラメータにビーコン情報をセットする。
if( STD_CompareNString( (char *)&pBootTitle->titleID + 1, "JNH", 3 ) == 0 )
{
(void)WDS_WrapperSetArgumentParam();
}
// Nintendoスポットブート時は、アプリ間パラメータにビーコン情報をセットする。
if( STD_CompareNString( (char *)&pBootTitle->titleID + 1, "JNH", 3 ) == 0 )
{
(void)WDS_WrapperSetArgumentParam();
}
#endif // SYSM_DISABLE_WDS_SCAN
state = BOOT;
}
break;
case BOOT:
state = BOOT;
}
break;
case BOOT:
#ifndef SYSM_DISABLE_WDS_SCAN
// アプリブート前にWDSスキャンは終了しておく必要がある
if( ( WDS_WrapperCleanup() != WDSWRAPPER_ERRCODE_OPERATING ) &&
IsClearnupWDSWrapper() )
// アプリブート前にWDSスキャンは終了しておく必要がある
if( ( WDS_WrapperCleanup() != WDSWRAPPER_ERRCODE_OPERATING ) &&
IsClearnupWDSWrapper() )
#endif // SYSM_DISABLE_WDS_SCAN
{
SYSM_TryToBootTitle( pBootTitle ); // never return.
{
SYSM_TryToBootTitle( pBootTitle ); // never return.
}
break;
case STOP: // 停止
OS_Terminate();
OS_Terminate();
break;
}
// カードアプリリストの取得(スレッドで随時カード挿抜を通知されるものをメインループで取得)
{
BOOL changed;
sp_titleList = SYSM_GetCardTitleList( &changed );
if( changed )
{
OS_TPrintf( "Change CARD status.\n" );
}
}
BOOL changed;
sp_titleList = SYSM_GetCardTitleList( &changed );
if( changed )
{
OS_TPrintf( "Change CARD status.\n" );
}
}
// 無線ファームロードのポーリング
if( PollingInstallWlanFirmware() &&
( GetWlanFirmwareInstallFinalResult() == WLANFIRM_RESULT_SUCCESS ) // ロード成功
) {
// 下記条件を満たすなら、WDSスキャン開始
if( PollingInstallWlanFirmware() &&
( GetWlanFirmwareInstallFinalResult() == WLANFIRM_RESULT_SUCCESS ) // ロード成功
) {
// 下記条件を満たすなら、WDSスキャン開始
#ifndef SYSM_DISABLE_WDS_SCAN
if( !isStartScanWDS && // WDSスキャン開始済みでない
!direct_boot && // ダイレクトブートでない
!LCFG_THW_IsForceDisableWireless() && // 無線強制OFFでない
LCFG_TSD_IsAvailableWireless() // 無線ON
) {
InitializeWDS(); // 初期化と動作開始を兼ねている。(失敗しても止まりはしないので、気にしない)
isStartScanWDS = TRUE;
}
if( !isStartScanWDS && // WDSスキャン開始済みでない
!direct_boot && // ダイレクトブートでない
!LCFG_THW_IsForceDisableWireless() && // 無線強制OFFでない
LCFG_TSD_IsAvailableWireless() // 無線ON
) {
InitializeWDS(); // 初期化と動作開始を兼ねている。(失敗しても止まりはしないので、気にしない)
isStartScanWDS = TRUE;
}
#endif // SYSM_DISABLE_WDS_SCAN
}
}
// コマンドフラッシュ
(void)SND_FlushCommand(SND_COMMAND_NOBLOCK);
@ -637,7 +639,7 @@ MAIN_LOOP_START:
//(蓋開き状態とデバッガ接続中のキャンセルはデフォルトで行う)
if ( PollingInstallWlanFirmware() )
{
UTL_GoSleepMode();
UTL_GoSleepMode();
}
#endif // DISABLE_SLEEP
}
@ -645,123 +647,123 @@ MAIN_LOOP_START:
static BOOL IsCommandSelected(void)
{
static BOOL left = FALSE;
if( !( pad.cont & ( PAD_BUTTON_A | PAD_BUTTON_B ) ) )
{
left = TRUE;
}
if( left && ( pad.trg & PAD_BUTTON_A ) )
{
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
PrintfSJIS( 1, 25, TXT_COLOR_RED,"Resume Loading....\n" );
SYSM_ResumeLoadingThread( TRUE );
left = FALSE;
return TRUE;
}else if( left && ( pad.trg & PAD_BUTTON_B ) )
{
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
PrintfSJIS( 1, 25, TXT_COLOR_RED,"Please Wait....\n" );
SYSM_ResumeLoadingThread( FALSE );
left = FALSE;
return TRUE;
}
return FALSE;
static BOOL left = FALSE;
if( !( pad.cont & ( PAD_BUTTON_A | PAD_BUTTON_B ) ) )
{
left = TRUE;
}
if( left && ( pad.trg & PAD_BUTTON_A ) )
{
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
PrintfSJIS( 1, 25, TXT_COLOR_RED,"Resume Loading....\n" );
SYSM_ResumeLoadingThread( TRUE );
left = FALSE;
return TRUE;
}else if( left && ( pad.trg & PAD_BUTTON_B ) )
{
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
PrintfSJIS( 1, 25, TXT_COLOR_RED,"Please Wait....\n" );
SYSM_ResumeLoadingThread( FALSE );
left = FALSE;
return TRUE;
}
return FALSE;
}
static void PrintPause(void)
{
LauncherInit( NULL );
GX_SetVisiblePlane( GX_PLANEMASK_BG0 );
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
G2_ChangeBlendAlpha( 0, 31 );
PrintfSJIS( 1, 25, TXT_COLOR_RED,"WhiteList Check Failed.\n" );
PrintfSJIS( 1, 40, TXT_COLOR_RED,"Prease Select Command." );
PrintfSJIS( 1, 55, TXT_COLOR_RED,"A : Force to Launch" );
PrintfSJIS( 1, 70, TXT_COLOR_RED," or" );
PrintfSJIS( 1, 85, TXT_COLOR_RED,"B : Stop And Show Error Message" );
GX_DispOn();
GXS_DispOn();
LauncherInit( NULL );
GX_SetVisiblePlane( GX_PLANEMASK_BG0 );
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
G2_ChangeBlendAlpha( 0, 31 );
PrintfSJIS( 1, 25, TXT_COLOR_RED,"WhiteList Check Failed.\n" );
PrintfSJIS( 1, 40, TXT_COLOR_RED,"Prease Select Command." );
PrintfSJIS( 1, 55, TXT_COLOR_RED,"A : Force to Launch" );
PrintfSJIS( 1, 70, TXT_COLOR_RED," or" );
PrintfSJIS( 1, 85, TXT_COLOR_RED,"B : Stop And Show Error Message" );
GX_DispOn();
GXS_DispOn();
}
static void PrintError( void )
{
u64 error_code;
int l;
int count = 0;
LauncherInit( NULL );
GX_SetVisiblePlane( GX_PLANEMASK_BG0 );
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
G2_ChangeBlendAlpha( 0, 31 );
PrintfSJIS( 128, 0, TXT_COLOR_BLUE, "IPL:%s", g_strIPLSvnRevision );
PrintfSJIS( 128, 12, TXT_COLOR_BLUE, "SDK:%s", g_strSDKSvnRevision );
error_code = UTL_GetFatalError();
PrintfSJIS( 2, 25, TXT_COLOR_RED,"ERROR! - 0x%016llx\n", error_code );
ERRORLOG_Write(error_code);
for(l=0;l<64;l++)
{
if( error_code & 0x1 )
{
PrintfSJIS( 2, 50+count*13, TXT_COLOR_RED,"%s\n", fatal_error_msg[l] );
count++;
}
error_code = error_code >> 1;
}
GX_DispOn();
GXS_DispOn();
u64 error_code;
int l;
int count = 0;
LauncherInit( NULL );
GX_SetVisiblePlane( GX_PLANEMASK_BG0 );
NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL );
G2_ChangeBlendAlpha( 0, 31 );
PrintfSJIS( 128, 0, TXT_COLOR_BLUE, "IPL:%s", g_strIPLSvnRevision );
PrintfSJIS( 128, 12, TXT_COLOR_BLUE, "SDK:%s", g_strSDKSvnRevision );
error_code = UTL_GetFatalError();
PrintfSJIS( 2, 25, TXT_COLOR_RED,"ERROR! - 0x%016llx\n", error_code );
ERRORLOG_Write(error_code);
for(l=0;l<64;l++)
{
if( error_code & 0x1 )
{
PrintfSJIS( 2, 50+count*13, TXT_COLOR_RED,"%s\n", fatal_error_msg[l] );
count++;
}
error_code = error_code >> 1;
}
GX_DispOn();
GXS_DispOn();
}
// システムメニューバージョンのプリント
static void PrintSystemMenuVersion( void )
{
u8 *pBuffer = SYSM_Alloc( NA_VERSION_DATA_WORK_SIZE );
if( pBuffer &&
ReadSystemMenuVersionData( pBuffer, NA_VERSION_DATA_WORK_SIZE ) ) {
// リード成功
}else {
// FATALエラー
UTL_SetFatalError( FATAL_ERROR_TWLSETTINGS );
}
SYSM_Free( pBuffer );
// バージョン情報の表示
{
char str_ver[ TWL_SYSMENU_VER_STR_LEN / sizeof(u16) ];
int len = sizeof(str_ver);
MI_CpuClear8( str_ver, sizeof(str_ver) );
OS_TPrintf( "SystemMenuVersionData\n" );
// 文字列
if( STD_ConvertStringUnicodeToSjis( str_ver, &len, GetSystemMenuVersionString(), NULL, NULL ) == STD_RESULT_SUCCESS ) {
OS_TPrintf( " Version(str) : %s\n", str_ver );
}
// 数値
OS_TPrintf( " Version(num) : %d.%d\n", GetSystemMenuMajorVersion(), GetSystemMenuMinorVersion() );
// ユーザー領域MAXサイズの表示
OS_TPrintf( " TotalUserAreadSize : 0x%08x\n", FSi_GetTotalUserAreaSize() );
// EULA URLの表示
OS_TPrintf( " EULA URL : %s\n", GetEULA_URL() );
// NUP HostNameの表示
OS_TPrintf( " NUP HostName : %s\n", GetNUP_HostName() );
// SystemMenuVersion情報のタイムスタンプの取得
OS_TPrintf( " Timestamp : %08x\n", GetSystemMenuVersionTimeStamp() );
}
u8 *pBuffer = SYSM_Alloc( NA_VERSION_DATA_WORK_SIZE );
if( pBuffer &&
ReadSystemMenuVersionData( pBuffer, NA_VERSION_DATA_WORK_SIZE ) ) {
// リード成功
}else {
// FATALエラー
UTL_SetFatalError( FATAL_ERROR_TWLSETTINGS );
}
SYSM_Free( pBuffer );
// バージョン情報の表示
{
char str_ver[ TWL_SYSMENU_VER_STR_LEN / sizeof(u16) ];
int len = sizeof(str_ver);
MI_CpuClear8( str_ver, sizeof(str_ver) );
OS_TPrintf( "SystemMenuVersionData\n" );
// 文字列
if( STD_ConvertStringUnicodeToSjis( str_ver, &len, GetSystemMenuVersionString(), NULL, NULL ) == STD_RESULT_SUCCESS ) {
OS_TPrintf( " Version(str) : %s\n", str_ver );
}
// 数値
OS_TPrintf( " Version(num) : %d.%d\n", GetSystemMenuMajorVersion(), GetSystemMenuMinorVersion() );
// ユーザー領域MAXサイズの表示
OS_TPrintf( " TotalUserAreadSize : 0x%08x\n", FSi_GetTotalUserAreaSize() );
// EULA URLの表示
OS_TPrintf( " EULA URL : %s\n", GetEULA_URL() );
// NUP HostNameの表示
OS_TPrintf( " NUP HostName : %s\n", GetNUP_HostName() );
// SystemMenuVersion情報のタイムスタンプの取得
OS_TPrintf( " Timestamp : %08x\n", GetSystemMenuVersionTimeStamp() );
}
}
// ダミーのDSメニューラッピング用ファイル作成UIGランチャーが作っているもの
static void CreateDummyWrapFile( void )
{
const char *path = "nand:/shared2/launcher/wrap.bin";
if( FS_CreateFileAuto( path, FS_PERMIT_R | FS_PERMIT_W ) ) {
FSFile file;
if( FS_OpenFileEx( &file, path, FS_FILEMODE_RW ) ) {
(void)FS_SetFileLength( &file, 16 * 1024 );
FS_CloseFile( &file );
}
}
const char *path = "nand:/shared2/launcher/wrap.bin";
if( FS_CreateFileAuto( path, FS_PERMIT_R | FS_PERMIT_W ) ) {
FSFile file;
if( FS_OpenFileEx( &file, path, FS_FILEMODE_RW ) ) {
(void)FS_SetFileLength( &file, 16 * 1024 );
FS_CloseFile( &file );
}
}
}

View File

@ -2,7 +2,7 @@
Project: TwlIPL - DHT
File: dht.h
Copyright 2008 Nintendo. All rights reserved.
Copyright 2008,2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
@ -17,13 +17,28 @@
#ifndef SYSMENU_DHT_H_
#define SYSMENU_DHT_H_
/*
Phase
Phase1 DHTDatabase->hash[0] ROM_Header_Short->nitro_whitelist_phase1_digest
Phase2 DHTDatabase->hash[1] ROM_Header_Short->nitro_whitelist_phase2_digest
Phase3 DHTDatabaseEx->banner_hash ROM_Header_Short->banner_digest
Phase4 - -
Phase4のハッシュ値はdht_phase4_list.cに含まれる
*/
#include <twl/types.h>
#include <twl/os/common/format_rom.h>
#include <sysmenu/dht/dht_format.h>
#define nitro_whitelist_phase2_digest nitro_whitelist_phase2_diegst // for spell miss
#define DHT_FAT_PAGE_SIZE 512
#define DHT_FAT_CACHE_SIZE (DHT_FAT_PAGE_SIZE * 2)
#define DHT_PHASE3_MAX DHT_OVERLAY_MAX
/*
DHT_CheckHashPhase2で必要なワークメモリ
*/
@ -34,6 +49,17 @@ typedef struct DHTPhase2Work
}
DHTPhase2Work;
/*
DHT_CheckHashPhase4で必要なワークメモリ
(DHTPhase4Work <= DHTPhase2Workが必ず成り立つ)
*/
typedef struct DHTPhase4Work
{
u32 buffer[DHT_PHASE3_MAX/sizeof(u32)];
}
DHTPhase4Work;
/*
DHT_CheckHashPhase2Exで必要なワークメモリ
*/
@ -48,7 +74,7 @@ extern "C" {
#endif
/*
DHT_CheckHashPhase2/DHT_CheckHashPhase2Exで使用するRead関数
DHT_CheckHashPhase2/DHT_CheckHashPhase2Ex/DHT_CheckHashPhase4で使用するRead関数
dest
offset ROMオフセット
length
@ -59,7 +85,7 @@ extern "C" {
typedef BOOL (*DHTReadFunc)(void* dest, s32 offset, s32 length, void* arg);
/*
DHT_CheckHashPhase2Exで使用するRead関数
DHT_CheckHashPhase2Ex/DHT_CheckHashPhase4Exで使用するRead関数
DHT_CheckHashPhase2ExUpdateを呼び出すこと()
ctx DHT_CheckHashPhase2ExUpdateに渡す引数
@ -71,7 +97,7 @@ typedef BOOL (*DHTReadFunc)(void* dest, s32 offset, s32 length, void* arg);
*/
typedef BOOL (*DHTReadFuncEx)(SVCHMACSHA1Context* ctx, s32 offset, s32 length, void* arg);
/*---------------------------------------------------------------------------*
Name: DHT_PrepareDatabase
Name: DHT_GetDatabaseLength
Description:
@ -81,12 +107,34 @@ typedef BOOL (*DHTReadFuncEx)(SVCHMACSHA1Context* ctx, s32 offset, s32 length
*---------------------------------------------------------------------------*/
u32 DHT_GetDatabaseLength(const DHTFile* pDHT);
/*---------------------------------------------------------------------------*
Name: DHT_GetDatabaseExLength
Description:
Arguments: pDHT
Returns: 0
*---------------------------------------------------------------------------*/
u32 DHT_GetDatabaseExLength(const DHTFileEx* pDHT);
/*---------------------------------------------------------------------------*
Name: DHT_GetDatabaseAdHocLength
Description:
Arguments: pDHT
Returns: 0
*---------------------------------------------------------------------------*/
u32 DHT_GetDatabaseAdHocLength(const DHTFileAdHoc* pDHT);
/*---------------------------------------------------------------------------*
Name: DHT_PrepareDatabase
Description: FS関数を利用して全データベースを読み込みと検証を行う
Description: FS関数を利用してデータベースを読み込みと検証を行う
Arguments: pDHT
Arguments: pDHT
fp
DHTHeaderの先頭までシーク済みである必要がある
@ -94,18 +142,56 @@ u32 DHT_GetDatabaseLength(const DHTFile* pDHT);
*---------------------------------------------------------------------------*/
BOOL DHT_PrepareDatabase(DHTFile* pDHT, FSFile* fp);
/*---------------------------------------------------------------------------*
Name: DHT_PrepareDatabaseEx
Description: FS関数を利用して拡張データベースを読み込みと検証を行う
Arguments: pDHT
fp
DHTHeaderの先頭までシーク済みである必要がある
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_PrepareDatabaseEx(DHTFileEx* pDHT, FSFile* fp);
/*---------------------------------------------------------------------------*
Name: DHT_PrepareDatabaseAdHoc
Description: FS関数を利用して個別対応データベースを読み込みと検証を行う
Arguments: pDHT
fp
DHTHeaderの先頭までシーク済みである必要がある
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_PrepareDatabaseAdHoc(DHTFileAdHoc* pDHT, FSFile* fp);
/*---------------------------------------------------------------------------*
Name: DHT_GetDatabase
Description: ROMヘッダに対応するデータベースを検索する
Arguments: pDHT
Arguments: pDHT
pROMHeader ROMヘッダ格納先
Returns:
Returns: NULL
*---------------------------------------------------------------------------*/
const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short* pROMHeader);
/*---------------------------------------------------------------------------*
Name: DHT_GetDatabaseEx
Description: ROMヘッダに対応する拡張データベースを検索する
Arguments: pDHT
pROMHeader ROMヘッダ格納先
Returns: NULL
*---------------------------------------------------------------------------*/
const DHTDatabaseEx* DHT_GetDatabaseEx(const DHTFileEx* pDHT, const ROM_Header_Short* pROMHeader);
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase1Init
@ -178,7 +264,6 @@ BOOL DHT_CheckHashPhase2(const u8* hash, const ROM_Header_Short* pROMHeader, DHT
Name: DHT_CheckHashPhase2Ex
Description:
(Read APIを登録できるべき)
Arguments: hash (db->hash[1])
pROMHeader ROMヘッダ格納先
@ -193,10 +278,11 @@ BOOL DHT_CheckHashPhase2(const u8* hash, const ROM_Header_Short* pROMHeader, DHT
BOOL DHT_CheckHashPhase2Ex(const u8* hash, const ROM_Header_Short* pROMHeader, DHTPhase2ExWork* work, DHTReadFunc func, DHTReadFuncEx funcEx, void* arg);
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase2ExUpdate
Name: DHT_CheckHashPhase2ExUpdate / DHT_CheckHashPhase4ExUpdate
Description:
Description:
DHTReadFuncExから呼び出すこと()
: Phase4でも流用している
Arguments: ctx SVCHMACSHA1コンテキスト
ptr
@ -205,6 +291,51 @@ BOOL DHT_CheckHashPhase2Ex(const u8* hash, const ROM_Header_Short* pROMHeader, D
Returns: None
*---------------------------------------------------------------------------*/
void DHT_CheckHashPhase2ExUpdate(SVCHMACSHA1Context* ctx, const void* ptr, s32 length);
#define DHT_CheckHashPhase4ExUpdate DHT_CheckHashPhase2ExUpdate
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase3
Description:
(使)
Arguments: hash (dbex->banner_hash)
pBanner
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_CheckHashPhase3(const u8* hash, const NTRBannerFile* pBanner);
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase4
Description:
Arguments: pDHT
pROMHeader ROMヘッダ格納先
work APIで使用するワーク (512KB)
phase2の使い回しでOK
func Read関数
arg Read関数に渡される引数
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_CheckHashPhase4(const DHTFileAdHoc* pDHT, const ROM_Header_Short* pROMHeader, DHTPhase4Work* work, DHTReadFunc func, void* arg);
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase4Ex
Description:
Arguments: pDHT
pROMHeader ROMヘッダ格納先
funcEx
DHT_CheckHashPhase2ExUpdateを呼び出す必要がある
arg Read関数に渡される引数
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_CheckHashPhase4Ex(const DHTFileAdHoc* pDHT, const ROM_Header_Short* pROMHeader, DHTReadFuncEx funcEx, void* arg);
#ifdef __cplusplus
} /* extern "C" */

View File

@ -21,7 +21,12 @@
#define DHT_DS_HEADER_SIZE 0x160
#define DHT_OVERLAY_MAX (512*1024)
#define DHT_MAGIC_CODE_EX (('N' << 0)|('D' << 8)|('H' << 16)|('X' << 24))
#define DHT_MAGIC_CODE_ADHOC (('N' << 0)|('D' << 8)|('H' << 16)|('I' << 24))
#include <twl/types.h>
#include <twl/os/common/banner.h>
#ifdef __cplusplus
extern "C" {
@ -35,6 +40,8 @@ typedef struct DHTHeader
}
DHTHeader;
#define DHTHeaderEx DHTHeader
typedef struct DHTDatabase
{
u8 game_code[4];
@ -44,6 +51,33 @@ typedef struct DHTDatabase
}
DHTDatabase;
typedef struct DHTDatabaseEx
{
u8 game_code[4];
u8 rom_version;
u8 reserved[3]; // for 4B alignment DHTDatabase array
u8 banner_hash[20];
}
DHTDatabaseEx;
/*
ad-hoc対処用
*/
#define DHT_INDIVIDUAL_ENTRY_MAX 8
typedef struct DHTDatabaseAdHoc
{
u8 game_code[4];
u8 rom_version;
u8 reserved[3]; // for 4B alignment DHTDatabase array
struct
{
u32 offset;
u32 length;
} entry[DHT_INDIVIDUAL_ENTRY_MAX];
u8 hash[20];
}
DHTDatabaseAdHoc;
typedef struct DHTFile
{
DHTHeader header;
@ -51,6 +85,20 @@ typedef struct DHTFile
}
DHTFile;
typedef struct DHTFileEx
{
DHTHeader header;
DHTDatabaseEx database[];
}
DHTFileEx;
typedef struct DHTFileAdHoc
{
DHTHeader header;
DHTDatabaseAdHoc database[];
}
DHTFileAdHoc;
#define DHT_HMAC_KEY { \
0x61, 0xbd, 0xdd, 0x72, 0x7e, 0x72, 0xbe, 0xde, 0xad, 0x3a, 0xdf, 0x7f, 0x3d, 0x2d, 0xf7, 0xa5, \
0x16, 0x7e, 0xb4, 0xc9, 0x7c, 0x6c, 0x00, 0x7c, 0x57, 0xbb, 0x94, 0x8a, 0x64, 0xcd, 0x4e, 0x1c, \
@ -58,16 +106,28 @@ DHTFile;
0x7f, 0xd9, 0x7c, 0xe9, 0x92, 0x44, 0x0f, 0xef, 0x6b, 0xb6, 0x12, 0x21, 0x68, 0x88, 0xd8, 0xee \
}
#define DHT_HMAC_KEY2 { \
0x85, 0x29, 0x48, 0xf3, 0xa1, 0xbb, 0x13, 0x30, 0x93, 0x5d, 0xb8, 0xc9, 0xa5, 0x9a, 0xe8, 0x30, \
0xc4, 0xd0, 0x4a, 0xdd, 0xa4, 0x92, 0x81, 0xfd, 0x4f, 0xa1, 0x32, 0xfa, 0x46, 0x05, 0xde, 0x68, \
0x7b, 0xa7, 0xd7, 0x5b, 0xc9, 0x3a, 0xc8, 0x8d, 0xcd, 0x25, 0x3a, 0x17, 0x3c, 0xc2, 0xd6, 0xe0, \
0xd2, 0xe5, 0xb9, 0xfb, 0x49, 0xf9, 0x4d, 0x05, 0x70, 0x10, 0x29, 0x51, 0x7a, 0xc5, 0x89, 0x49, \
}
/*
ƒ<EFBFBD>[ƒeƒBƒŠƒeƒB
hp:
hp:
*/
#define DHT_GET_SIGN_TARGET_ADDR(hp) (&((DHTHeader*)hp)->nums)
#define DHT_GET_SIGN_TARGET_SIZE(hp) (((DHTHeader*)hp)->nums * sizeof(DHTDatabase) + sizeof(u32))
#define DHT_GET_SIGN_TARGET_OFFSET (int)DHT_GET_SIGN_TARGET_ADDR(0)
#define DHT_GET_SIGN_TARGET_ADDR_EX(hp) DHT_GET_SIGN_TARGET_ADDR(hp)
#define DHT_GET_SIGN_TARGET_SIZE_EX(hp) (((DHTHeader*)hp)->nums * sizeof(DHTDatabaseEx) + sizeof(u32))
#define DHT_GET_SIGN_TARGET_OFFSET_EX DHT_GET_SIGN_TARGET_OFFSET
#define DHT_GET_SIGN_TARGET_ADDR_ADHOC(hp) DHT_GET_SIGN_TARGET_ADDR(hp)
#define DHT_GET_SIGN_TARGET_SIZE_ADHOC(hp) (((DHTHeader*)hp)->nums * sizeof(DHTDatabaseAdHoc) + sizeof(u32))
#define DHT_GET_SIGN_TARGET_OFFSET_ADHOC DHT_GET_SIGN_TARGET_OFFSET
#ifdef __cplusplus
} /* extern "C" */

View File

@ -15,8 +15,8 @@
$Author$
*---------------------------------------------------------------------------*/
#ifndef __SYSM_UTIL_H__
#define __SYSM_UTIL_H__
#ifndef __SYSM_UTIL_H__
#define __SYSM_UTIL_H__
#include <twl.h>
#include <twl/os/common/format_rom.h>
@ -26,62 +26,64 @@ extern "C" {
#endif
// define data----------------------------------------------------------
#define BACKLIGHT_BRIGHTNESS_MAX 4
#define BACKLIGHT_BRIGHTNESS_MAX 4
typedef enum FatalErrorCode {
FATAL_ERROR_UNDEFINED = 0,
FATAL_ERROR_NAND = 1, // NANDデバイスのエラー
FATAL_ERROR_HWINFO_NORMAL = 2, // HWーマル情報のリードエラー
FATAL_ERROR_HWINFO_SECURE = 3, // HWセキュア情報のリードエラー
FATAL_ERROR_TWLSETTINGS = 4, // 本体設定データのリードエラー
FATAL_ERROR_SHARED_FONT = 5, // 共有フォントのリードエラー
FATAL_ERROR_WLANFIRM_AUTH = 6, // 無線ファームの認証エラー
FATAL_ERROR_WLANFIRM_LOAD = 7, // 無線ファームのロードエラー
FATAL_ERROR_TITLE_LOAD_FAILED = 8, // アプリケーションのロードエラー
FATAL_ERROR_TITLE_POINTER_ERROR = 9, // ブート要求されたが、アプリが指定されていない
FATAL_ERROR_AUTHENTICATE_FAILED = 10, // アプリ認証失敗
FATAL_ERROR_ENTRY_ADDRESS_ERROR = 11, // アプリの起動アドレスが不正
FATAL_ERROR_TITLE_BOOTTYPE_ERROR = 12, // アプリブートタイプが不正NANDブート、カードブート、MBブート以外の値
FATAL_ERROR_SIGN_DECRYPTION_FAILED = 13, // アプリ署名デクリプト失敗
FATAL_ERROR_SIGN_COMPARE_FAILED = 14, // アプリ署名検証失敗
FATAL_ERROR_HEADER_HASH_CALC_FAILED = 15, // アプリハッシュ計算用メモリ確保失敗
FATAL_ERROR_TITLEID_COMPARE_FAILED = 16, // ブート要求されたTWLアプリと実際にロードしたアプリのTitleIDが不一致
FATAL_ERROR_VALID_SIGN_FLAG_OFF = 17, // アプリROMヘッダの署名有効フラグが立っていない
FATAL_ERROR_CHECK_TITLE_LAUNCH_RIGHTS_FAILED = 18, // アプリ起動認証失敗
FATAL_ERROR_MODULE_HASH_CHECK_FAILED = 19, // アプリハッシュ不一致
FATAL_ERROR_MODULE_HASH_CALC_FAILED = 20, // アプリハッシュ計算用メモリ確保失敗
FATAL_ERROR_MEDIA_CHECK_FAILED = 21, // カードアプリをNAND起動 or NANDアプリをカード起動しようとしたデバッガ起動を除く
FATAL_ERROR_DL_MAGICCODE_CHECK_FAILED = 22, // DSダウンロードプレイアプリ署名のマジックコードが不正TEMPブートアプリブート時
FATAL_ERROR_DL_SIGN_DECRYPTION_FAILED = 23, // DSダウンロードプレイアプリ署名のデクリプト失敗TEMPブートアプリブート時
FATAL_ERROR_DL_HASH_CALC_FAILED = 24, // DSダウンロードプレイアプリハッシュ計算用メモリ確保失敗TEMPブートアプリブート時
FATAL_ERROR_DL_SIGN_COMPARE_FAILED = 25, // DSダウンロードプレイアプリハッシュ不一致TEMPブートアプリブート時
FATAL_ERROR_WHITELIST_INITDB_FAILED = 26, // NTRホワイトリスト自身の認証失敗
FATAL_ERROR_WHITELIST_NOTFOUND = 27, // 起動NTRアプリのイニシャルコードがNTRホワイトリストに見つからなかった
FATAL_ERROR_DHT_PHASE1_FAILED = 28, // アプリのNTRホワイトリスト認証失敗フェーズ
FATAL_ERROR_DHT_PHASE2_FAILED = 29, // アプリのNTRホワイトリスト認証失敗フェーズ
FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF = 30, // TMPブートアプリのROMヘッダにTMPジャンプ許可ビットが立っていない
FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN = 31, // TWLアプリブートタイプ不明
FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN = 32, // NTRアプリブートタイプ不明
FATAL_ERROR_PLATFORM_UNKNOWN = 33, // ROMヘッダのプラットホームコード不明
FATAL_ERROR_LOAD_UNFINISHED = 34, // アプリロードが完了していないのに、認証フェーズに進んだ
FATAL_ERROR_LOAD_OPENFILE_FAILED = 35, // NANDアプリのファイルオープン失敗
FATAL_ERROR_LOAD_MEMALLOC_FAILED = 36, // アプリハッシュ計算用メモリ確保失敗
FATAL_ERROR_LOAD_SEEKFILE_FAILED = 37, // NANDアプリのファイルシーク失敗
FATAL_ERROR_LOAD_READHEADER_FAILED = 38, // アプリROMヘッダロード失敗
FATAL_ERROR_LOAD_LOGOCRC_ERROR = 39, // アプリROMヘッダNintendoロゴCRC不正
FATAL_ERROR_LOAD_READDLSIGN_FAILED = 40, // TMPブートアプリのDSダウンロードプレイ署名リード失敗
FATAL_ERROR_LOAD_RELOCATEINFO_FAILED = 41, // アプリ再配置情報生成失敗
FATAL_ERROR_LOAD_READMODULE_FAILED = 42, // アプリロード失敗
FATAL_ERROR_NINTENDO_LOGO_CHECK_FAILED = 43, // アプリROMヘッダNintendoロゴデータ不正
FATAL_ERROR_SYSMENU_VERSION = 44, //
FATAL_ERROR_DHT_PHASE1_CALC_FAILED = 45, // NTRアプリホワイトリストハッシュ計算用メモリ確保失敗
FATAL_ERROR_LOAD_UNKNOWN_BOOTTYPE = 46, // アプリブートタイプが不正
FATAL_ERROR_LOAD_AUTH_HEADER_FAILED = 47, // アプリROMヘッダ認証失敗
FATAL_ERROR_LOAD_NEVER_STARTED = 48, // ロードが開始されていないのに、認証が開始された
FATAL_ERROR_EJECT_CARD_AFTER_LOAD_START = 49, // カードが抜かれているのに、カードアプリのロードが開始された
FATAL_ERROR_TITLEID_COMPARE_FAILED_NTR = 50, // ブート要求されたNTRアプリと実際にロードしたアプリのTitleIDが不一致
FATAL_ERROR_UNDEFINED = 0,
FATAL_ERROR_NAND = 1, // NANDデバイスのエラー
FATAL_ERROR_HWINFO_NORMAL = 2, // HWーマル情報のリードエラー
FATAL_ERROR_HWINFO_SECURE = 3, // HWセキュア情報のリードエラー
FATAL_ERROR_TWLSETTINGS = 4, // 本体設定データのリードエラー
FATAL_ERROR_SHARED_FONT = 5, // 共有フォントのリードエラー
FATAL_ERROR_WLANFIRM_AUTH = 6, // 無線ファームの認証エラー
FATAL_ERROR_WLANFIRM_LOAD = 7, // 無線ファームのロードエラー
FATAL_ERROR_TITLE_LOAD_FAILED = 8, // アプリケーションのロードエラー
FATAL_ERROR_TITLE_POINTER_ERROR = 9, // ブート要求されたが、アプリが指定されていない
FATAL_ERROR_AUTHENTICATE_FAILED = 10, // アプリ認証失敗
FATAL_ERROR_ENTRY_ADDRESS_ERROR = 11, // アプリの起動アドレスが不正
FATAL_ERROR_TITLE_BOOTTYPE_ERROR = 12, // アプリブートタイプが不正NANDブート、カードブート、MBブート以外の値
FATAL_ERROR_SIGN_DECRYPTION_FAILED = 13, // アプリ署名デクリプト失敗
FATAL_ERROR_SIGN_COMPARE_FAILED = 14, // アプリ署名検証失敗
FATAL_ERROR_HEADER_HASH_CALC_FAILED = 15, // アプリハッシュ計算用メモリ確保失敗
FATAL_ERROR_TITLEID_COMPARE_FAILED = 16, // ブート要求されたTWLアプリと実際にロードしたアプリのTitleIDが不一致
FATAL_ERROR_VALID_SIGN_FLAG_OFF = 17, // アプリROMヘッダの署名有効フラグが立っていない
FATAL_ERROR_CHECK_TITLE_LAUNCH_RIGHTS_FAILED = 18, // アプリ起動認証失敗
FATAL_ERROR_MODULE_HASH_CHECK_FAILED = 19, // アプリハッシュ不一致
FATAL_ERROR_MODULE_HASH_CALC_FAILED = 20, // アプリハッシュ計算用メモリ確保失敗
FATAL_ERROR_MEDIA_CHECK_FAILED = 21, // カードアプリをNAND起動 or NANDアプリをカード起動しようとしたデバッガ起動を除く
FATAL_ERROR_DL_MAGICCODE_CHECK_FAILED = 22, // DSダウンロードプレイアプリ署名のマジックコードが不正TEMPブートアプリブート時
FATAL_ERROR_DL_SIGN_DECRYPTION_FAILED = 23, // DSダウンロードプレイアプリ署名のデクリプト失敗TEMPブートアプリブート時
FATAL_ERROR_DL_HASH_CALC_FAILED = 24, // DSダウンロードプレイアプリハッシュ計算用メモリ確保失敗TEMPブートアプリブート時
FATAL_ERROR_DL_SIGN_COMPARE_FAILED = 25, // DSダウンロードプレイアプリハッシュ不一致TEMPブートアプリブート時
FATAL_ERROR_WHITELIST_INITDB_FAILED = 26, // NTRホワイトリスト自身の認証失敗
FATAL_ERROR_WHITELIST_NOTFOUND = 27, // 起動NTRアプリのイニシャルコードがNTRホワイトリストに見つからなかった
FATAL_ERROR_DHT_PHASE1_FAILED = 28, // アプリのNTRホワイトリスト認証失敗フェーズ
FATAL_ERROR_DHT_PHASE2_FAILED = 29, // アプリのNTRホワイトリスト認証失敗フェーズ
FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF = 30, // TMPブートアプリのROMヘッダにTMPジャンプ許可ビットが立っていない
FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN = 31, // TWLアプリブートタイプ不明
FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN = 32, // NTRアプリブートタイプ不明
FATAL_ERROR_PLATFORM_UNKNOWN = 33, // ROMヘッダのプラットホームコード不明
FATAL_ERROR_LOAD_UNFINISHED = 34, // アプリロードが完了していないのに、認証フェーズに進んだ
FATAL_ERROR_LOAD_OPENFILE_FAILED = 35, // NANDアプリのファイルオープン失敗
FATAL_ERROR_LOAD_MEMALLOC_FAILED = 36, // アプリハッシュ計算用メモリ確保失敗
FATAL_ERROR_LOAD_SEEKFILE_FAILED = 37, // NANDアプリのファイルシーク失敗
FATAL_ERROR_LOAD_READHEADER_FAILED = 38, // アプリROMヘッダロード失敗
FATAL_ERROR_LOAD_LOGOCRC_ERROR = 39, // アプリROMヘッダNintendoロゴCRC不正
FATAL_ERROR_LOAD_READDLSIGN_FAILED = 40, // TMPブートアプリのDSダウンロードプレイ署名リード失敗
FATAL_ERROR_LOAD_RELOCATEINFO_FAILED = 41, // アプリ再配置情報生成失敗
FATAL_ERROR_LOAD_READMODULE_FAILED = 42, // アプリロード失敗
FATAL_ERROR_NINTENDO_LOGO_CHECK_FAILED = 43, // アプリROMヘッダNintendoロゴデータ不正
FATAL_ERROR_SYSMENU_VERSION = 44, //
FATAL_ERROR_DHT_PHASE1_CALC_FAILED = 45, // NTRアプリホワイトリストハッシュ計算用メモリ確保失敗
FATAL_ERROR_LOAD_UNKNOWN_BOOTTYPE = 46, // アプリブートタイプが不正
FATAL_ERROR_LOAD_AUTH_HEADER_FAILED = 47, // アプリROMヘッダ認証失敗
FATAL_ERROR_LOAD_NEVER_STARTED = 48, // ロードが開始されていないのに、認証が開始された
FATAL_ERROR_EJECT_CARD_AFTER_LOAD_START = 49, // カードが抜かれているのに、カードアプリのロードが開始された
FATAL_ERROR_TITLEID_COMPARE_FAILED_NTR = 50, // ブート要求されたNTRアプリと実際にロードしたアプリのTitleIDが不一致
FATAL_ERROR_DHT_PHASE3_FAILED = 51, // アプリのNTRホワイトリスト認証失敗フェーズ
FATAL_ERROR_DHT_PHASE4_FAILED = 52, // アプリのNTRホワイトリスト認証失敗フェーズ
FATAL_ERROR_MAX = 51
FATAL_ERROR_MAX = 53
}FatalErrorCode;
@ -91,26 +93,26 @@ typedef enum FatalErrorCode {
#ifdef SDK_ARM9
// バックライト
extern u32 UTL_SetBacklightBrightness( u8 brightness ); // バックライト輝度セット
extern u32 UTL_GetBacklightBrightness( u8 *pBrightness ); // バックライト輝度ゲット
extern u32 UTL_SetBacklightBrightness( u8 brightness ); // バックライト輝度セット
extern u32 UTL_GetBacklightBrightness( u8 *pBrightness ); // バックライト輝度ゲット
// タッチパネル
extern void UTL_CaribrateTP( const LCFGTWLTPCalibData *pCalib ); // TPキャリブレーション
extern BOOL UTL_IsValidCalibration( u16 x, u16 y, u16 correct_x, u16 correct_y ); // TPキャリブレーション後にタッチしたポイントが正確か
extern void UTL_CaribrateTP( const LCFGTWLTPCalibData *pCalib ); // TPキャリブレーション
extern BOOL UTL_IsValidCalibration( u16 x, u16 y, u16 correct_x, u16 correct_y ); // TPキャリブレーション後にタッチしたポイントが正確か
// スリープ
extern void UTL_GoSleepMode( void );
// RTC関係
extern BOOL UTL_CheckRTCDate( RTCDate *pDate ); // 日付が正常かチェック
extern BOOL UTL_CheckRTCTime( RTCTime *pTime ); // 時刻が正常かチェック
extern s64 UTL_CalcRTCOffset( RTCDate *pNewDate, RTCTime *pNewTime ); // RTCオフセット計算とRTCへの日付時刻チェックを行う
extern u32 UTL_GetDayNum( u32 year, u32 month ); // 指定された年・月の日数を取得する
extern BOOL UTL_IsLeapYear100( u32 year ); // 指定された年がうるう年か調べる
extern BOOL UTL_CheckRTCDate( RTCDate *pDate ); // 日付が正常かチェック
extern BOOL UTL_CheckRTCTime( RTCTime *pTime ); // 時刻が正常かチェック
extern s64 UTL_CalcRTCOffset( RTCDate *pNewDate, RTCTime *pNewTime ); // RTCオフセット計算とRTCへの日付時刻チェックを行う
extern u32 UTL_GetDayNum( u32 year, u32 month ); // 指定された年・月の日数を取得する
extern BOOL UTL_IsLeapYear100( u32 year ); // 指定された年がうるう年か調べる
// ペアレンタルコントロール問い合わせ
extern u32 UTL_CalcPCTLInquiryCode( void ); // 問い合わせコード(10進8桁)算出
extern u32 UTL_CalcPCTLMasterKey( void ); // マスターキー  算出※内部でRTC_GetDateを使用します。
extern u32 UTL_CalcPCTLInquiryCode( void ); // 問い合わせコード(10進8桁)算出
extern u32 UTL_CalcPCTLMasterKey( void ); // マスターキー  算出※内部でRTC_GetDateを使用します。
// アプリROMヘッダの要EULAフラグ取得
extern BOOL UTL_IsROMHeaderEULARequired( void );
@ -121,9 +123,9 @@ extern BOOL UTL_CheckNintendoLogoData( ROM_Header_Short *rh );
#endif
// FATALエラー
extern BOOL UTL_IsFatalError( void ); // FATALエラーか
extern void UTL_SetFatalError( FatalErrorCode error ); // FATALエラーのセット
extern u64 UTL_GetFatalError( void ); // FATALエラー状態の取得FatalErrorCodeをビットに割り当てて格納しています。
extern BOOL UTL_IsFatalError( void ); // FATALエラーか
extern void UTL_SetFatalError( FatalErrorCode error ); // FATALエラーのセット
extern u64 UTL_GetFatalError( void ); // FATALエラー状態の取得FatalErrorCodeをビットに割り当てて格納しています。
// リージョンチェック
@ -131,21 +133,21 @@ static inline BOOL UTL_CheckAppRegion( u32 card_region_bitmap )
{
#ifdef SYSM_BUILD_FOR_DEBUGGER
#pragma unused(card_region_bitmap)
return TRUE;
return TRUE;
#else
return ( card_region_bitmap & ( 0x00000001 << OS_GetRegion() ) ) ? TRUE : FALSE;
return ( card_region_bitmap & ( 0x00000001 << OS_GetRegion() ) ) ? TRUE : FALSE;
#endif
}
// CRCチェック
static inline BOOL UTL_CheckAppCRC16( ROM_Header_Short *pROMH )
{
u16 calc_crc = SVC_GetCRC16( 65535, pROMH, 0x015e );
if( ( calc_crc != pROMH->header_crc16 ) ||
( 0xcf56 != pROMH->nintendo_logo_crc16 ) ){
return FALSE;
}
return TRUE;
u16 calc_crc = SVC_GetCRC16( 65535, pROMH, 0x015e );
if( ( calc_crc != pROMH->header_crc16 ) ||
( 0xcf56 != pROMH->nintendo_logo_crc16 ) ){
return FALSE;
}
return TRUE;
}