ホワイトリスト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 #FIRM_USE_PRODUCT_KEYS = TRUE
#SYSM_BUILD_FOR_DEBUGGER = TRUE #SYSM_BUILD_FOR_DEBUGGER = TRUE
SYSM_DEV_WHITELIST_CHECK_SKIP ?= TRUE SYSM_DEV_WHITELIST_CHECK_SKIP ?= TRUE
#SYSM_IGNORE_DHT_PHASE_3 = TRUE
SYSM_IGNORE_DHT_EX_NOT_FOUND ?= TRUE
ifeq ($(TARGET_FIRM),SYSTEMMENU) ifeq ($(TARGET_FIRM),SYSTEMMENU)
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs.sysmenu include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs.sysmenu

View File

@ -49,7 +49,8 @@ static const u8 g_pubkey_DER[ 0xa2 ] = {
0x00, 0x01 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 DHTReadFunc imageReadFunc;
static void* imageBuffer; static void* imageBuffer;
@ -114,6 +115,25 @@ u32 DHT_GetDatabaseLength(const DHTFile* pDHT)
} }
return sizeof(DHTHeader) + pDHT->header.nums * sizeof(DHTDatabase); 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) static BOOL DHT_CheckDatabase(const DHTFile* pDHT)
{ {
SVCSignHeapContext pool; SVCSignHeapContext pool;
@ -216,6 +236,219 @@ const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short*
#endif #endif
return db; 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) (1)
@ -468,3 +701,141 @@ void DHT_CheckHashPhase2ExUpdate(SVCHMACSHA1Context* ctx, const void* ptr, s32 l
SVC_HMACSHA1Update(ctx, ptr, (u32)length); 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) ifeq ($(SYSM_DEV_WHITELIST_CHECK_SKIP),TRUE)
MACRO_FLAGS += -DDEV_WHITELIST_CHECK_SKIP 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 endif
INSTALL_TARGETS = $(TARGETS) 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 include ./commondefs.DSHashTable
MY_DATA = $(DS_HASH_TABLE_DATA) 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_APPEND = revision.bin
MY_DATA2 = data.bin MY_DATA2 = data.bin
@ -49,8 +51,8 @@ do-build : $(MY_TAD)
$(MY_TAD): $(MY_DATA2) $(MY_TAD): $(MY_DATA2)
$(MAKETAD) $(call empath,$<) $(DS_HASH_TABLE_MAKETAD_OPTION) -o $@ $(MAKETAD) $(call empath,$<) $(DS_HASH_TABLE_MAKETAD_OPTION) -o $@
$(MY_DATA2): $(MY_DATA) $(MY_APPEND) $(MY_DATA2): $(MY_DATA) $(MY_DATA_EX) $(MY_DATA_ADHOC) $(MY_APPEND)
cat $(MY_DATA) $(MY_APPEND) > $@ cat $(MY_DATA) $(MY_DATA_EX) $(MY_DATA_ADHOC) $(MY_APPEND) > $@
$(MY_APPEND):: $(MY_APPEND)::
@if test -e $(SYSMENU_ROOT)/.svn; then \ @if test -e $(SYSMENU_ROOT)/.svn; then \

View File

@ -17,8 +17,12 @@
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
DS_HASH_TABLE_TITLE_NAME := DSHashTable 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_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_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 := HNHA
DS_HASH_TABLE_TITLE_ID_HI := 0003000F 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)'")') 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_MINOR_VERSION := $(shell expr $(DS_HASH_TABLE_VERSION) % 256)
DS_HASH_TABLE_MAJOR_VERSION := 0 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) \ 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 -v $(DS_HASH_TABLE_MINOR_VERSION) -p

View File

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

View File

@ -2,7 +2,7 @@
Project: TwlIPL - DHT Project: TwlIPL - DHT
File: dht.h File: dht.h
Copyright 2008 Nintendo. All rights reserved. Copyright 2008,2009 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo proprietary information of Nintendo of America Inc. and/or Nintendo
@ -17,13 +17,28 @@
#ifndef SYSMENU_DHT_H_ #ifndef SYSMENU_DHT_H_
#define 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/types.h>
#include <twl/os/common/format_rom.h> #include <twl/os/common/format_rom.h>
#include <sysmenu/dht/dht_format.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_PAGE_SIZE 512
#define DHT_FAT_CACHE_SIZE (DHT_FAT_PAGE_SIZE * 2) #define DHT_FAT_CACHE_SIZE (DHT_FAT_PAGE_SIZE * 2)
#define DHT_PHASE3_MAX DHT_OVERLAY_MAX
/* /*
DHT_CheckHashPhase2で必要なワークメモリ DHT_CheckHashPhase2で必要なワークメモリ
*/ */
@ -34,6 +49,17 @@ typedef struct DHTPhase2Work
} }
DHTPhase2Work; DHTPhase2Work;
/*
DHT_CheckHashPhase4で必要なワークメモリ
(DHTPhase4Work <= DHTPhase2Workが必ず成り立つ)
*/
typedef struct DHTPhase4Work
{
u32 buffer[DHT_PHASE3_MAX/sizeof(u32)];
}
DHTPhase4Work;
/* /*
DHT_CheckHashPhase2Exで必要なワークメモリ DHT_CheckHashPhase2Exで必要なワークメモリ
*/ */
@ -48,7 +74,7 @@ extern "C" {
#endif #endif
/* /*
DHT_CheckHashPhase2/DHT_CheckHashPhase2Exで使用するRead関数 DHT_CheckHashPhase2/DHT_CheckHashPhase2Ex/DHT_CheckHashPhase4で使用するRead関数
dest dest
offset ROMオフセット offset ROMオフセット
length length
@ -59,7 +85,7 @@ extern "C" {
typedef BOOL (*DHTReadFunc)(void* dest, s32 offset, s32 length, void* arg); typedef BOOL (*DHTReadFunc)(void* dest, s32 offset, s32 length, void* arg);
/* /*
DHT_CheckHashPhase2Exで使用するRead関数 DHT_CheckHashPhase2Ex/DHT_CheckHashPhase4Exで使用するRead関数
DHT_CheckHashPhase2ExUpdateを呼び出すこと() DHT_CheckHashPhase2ExUpdateを呼び出すこと()
ctx 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); typedef BOOL (*DHTReadFuncEx)(SVCHMACSHA1Context* ctx, s32 offset, s32 length, void* arg);
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Name: DHT_PrepareDatabase Name: DHT_GetDatabaseLength
Description: Description:
@ -81,12 +107,34 @@ typedef BOOL (*DHTReadFuncEx)(SVCHMACSHA1Context* ctx, s32 offset, s32 length
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
u32 DHT_GetDatabaseLength(const DHTFile* pDHT); 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 Name: DHT_PrepareDatabase
Description: FS関数を利用して全データベースを読み込みと検証を行う Description: FS関数を利用してデータベースを読み込みと検証を行う
Arguments: pDHT Arguments: pDHT
fp fp
DHTHeaderの先頭までシーク済みである必要がある DHTHeaderの先頭までシーク済みである必要がある
@ -94,18 +142,56 @@ u32 DHT_GetDatabaseLength(const DHTFile* pDHT);
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
BOOL DHT_PrepareDatabase(DHTFile* pDHT, FSFile* fp); 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 Name: DHT_GetDatabase
Description: ROMヘッダに対応するデータベースを検索する Description: ROMヘッダに対応するデータベースを検索する
Arguments: pDHT Arguments: pDHT
pROMHeader ROMヘッダ格納先 pROMHeader ROMヘッダ格納先
Returns: Returns: NULL
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short* pROMHeader); 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 Name: DHT_CheckHashPhase1Init
@ -178,7 +264,6 @@ BOOL DHT_CheckHashPhase2(const u8* hash, const ROM_Header_Short* pROMHeader, DHT
Name: DHT_CheckHashPhase2Ex Name: DHT_CheckHashPhase2Ex
Description: Description:
(Read APIを登録できるべき)
Arguments: hash (db->hash[1]) Arguments: hash (db->hash[1])
pROMHeader ROMヘッダ格納先 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); 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から呼び出すこと() DHTReadFuncExから呼び出すこと()
: Phase4でも流用している
Arguments: ctx SVCHMACSHA1コンテキスト Arguments: ctx SVCHMACSHA1コンテキスト
ptr ptr
@ -205,6 +291,51 @@ BOOL DHT_CheckHashPhase2Ex(const u8* hash, const ROM_Header_Short* pROMHeader, D
Returns: None Returns: None
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
void DHT_CheckHashPhase2ExUpdate(SVCHMACSHA1Context* ctx, const void* ptr, s32 length); 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 #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@ -21,7 +21,12 @@
#define DHT_DS_HEADER_SIZE 0x160 #define DHT_DS_HEADER_SIZE 0x160
#define DHT_OVERLAY_MAX (512*1024) #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/types.h>
#include <twl/os/common/banner.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -35,6 +40,8 @@ typedef struct DHTHeader
} }
DHTHeader; DHTHeader;
#define DHTHeaderEx DHTHeader
typedef struct DHTDatabase typedef struct DHTDatabase
{ {
u8 game_code[4]; u8 game_code[4];
@ -44,6 +51,33 @@ typedef struct DHTDatabase
} }
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 typedef struct DHTFile
{ {
DHTHeader header; DHTHeader header;
@ -51,6 +85,20 @@ typedef struct DHTFile
} }
DHTFile; DHTFile;
typedef struct DHTFileEx
{
DHTHeader header;
DHTDatabaseEx database[];
}
DHTFileEx;
typedef struct DHTFileAdHoc
{
DHTHeader header;
DHTDatabaseAdHoc database[];
}
DHTFileAdHoc;
#define DHT_HMAC_KEY { \ #define DHT_HMAC_KEY { \
0x61, 0xbd, 0xdd, 0x72, 0x7e, 0x72, 0xbe, 0xde, 0xad, 0x3a, 0xdf, 0x7f, 0x3d, 0x2d, 0xf7, 0xa5, \ 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, \ 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 \ 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 ƒ<EFBFBD>[ƒeƒBƒŠƒeƒB
hp: hp:
*/ */
#define DHT_GET_SIGN_TARGET_ADDR(hp) (&((DHTHeader*)hp)->nums) #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_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_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 #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

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