diff --git a/build/buildtools/commondefs b/build/buildtools/commondefs index f8ea3c53..9bfa8118 100644 --- a/build/buildtools/commondefs +++ b/build/buildtools/commondefs @@ -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 diff --git a/build/libraries_sysmenu/dht/common/src/dht.c b/build/libraries_sysmenu/dht/common/src/dht.c index b968fe2f..6da8cd33 100644 --- a/build/libraries_sysmenu/dht/common/src/dht.c +++ b/build/libraries_sysmenu/dht/common/src/dht.c @@ -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; +} + diff --git a/build/libraries_sysmenu/sysmenu/ARM9/Makefile b/build/libraries_sysmenu/sysmenu/ARM9/Makefile index a0c019ee..e51b3d6e 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/Makefile +++ b/build/libraries_sysmenu/sysmenu/ARM9/Makefile @@ -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) diff --git a/build/libraries_sysmenu/sysmenu/ARM9/src/title.c b/build/libraries_sysmenu/sysmenu/ARM9/src/title.c index 3676ee5c..b319ae54 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/src/title.c +++ b/build/libraries_sysmenu/sysmenu/ARM9/src/title.c @@ -29,60 +29,60 @@ #define MEASURE_MAKELIST_TIME 0 -#define CARD_BANNER_INDEX ( LAUNCHER_TITLE_LIST_NUM - 1 ) +#define CARD_BANNER_INDEX ( LAUNCHER_TITLE_LIST_NUM - 1 ) -#define LAUNCHER_KEY_INDEX 0 // ファームから送られてくる鍵のうちLauncherキーのインデックス -#define SYSTEM_APP_KEY_INDEX 1 // ファームから送られてくるSYSTEMアプリキーのインデックス -#define SECURE_APP_KEY_INDEX 2 // ファームから送られてくるSECUREアプリキーのインデックス -#define USER_APP_KEY_INDEX 3 // ファームから送られてくるUSERアプリキーのインデックス +#define LAUNCHER_KEY_INDEX 0 // ファームから送られてくる鍵のうちLauncherキーのインデックス +#define SYSTEM_APP_KEY_INDEX 1 // ファームから送られてくるSYSTEMアプリキーのインデックス +#define SECURE_APP_KEY_INDEX 2 // ファームから送られてくるSECUREアプリキーのインデックス +#define USER_APP_KEY_INDEX 3 // ファームから送られてくるUSERアプリキーのインデックス -#define ROM_HEADER_HASH_OFFSET (0x0) // 署名からROMヘッダハッシュを取り出すためのオフセット +#define ROM_HEADER_HASH_OFFSET (0x0) // 署名からROMヘッダハッシュを取り出すためのオフセット -#define SIGN_HEAP_ADDR 0x023c0000 // 署名計算のためのヒープ領域開始アドレス -#define SIGN_HEAP_SIZE 0x1000 // 署名計算のためのヒープサイズ -#define ARM9_ENCRYPT_DEF_SIZE 0x800 // ARM9FLXの先頭暗号化部分のサイズ +#define SIGN_HEAP_ADDR 0x023c0000 // 署名計算のためのヒープ領域開始アドレス +#define SIGN_HEAP_SIZE 0x1000 // 署名計算のためのヒープサイズ +#define ARM9_ENCRYPT_DEF_SIZE 0x800 // ARM9FLXの先頭暗号化部分のサイズ -#define DIGEST_HASH_BLOCK_SIZE_SHA1 (512/8) -#define TWL_ROM_HEADER_HASH_CALC_DATA_LEN 0xe00 // ROMヘッダのハッシュ計算する部分の長さTWL版 -#define NTR_ROM_HEADER_HASH_CALC_DATA_LEN 0x160 // ROMヘッダのハッシュ計算する部分の長さDS版 +#define DIGEST_HASH_BLOCK_SIZE_SHA1 (512/8) +#define TWL_ROM_HEADER_HASH_CALC_DATA_LEN 0xe00 // ROMヘッダのハッシュ計算する部分の長さTWL版 +#define NTR_ROM_HEADER_HASH_CALC_DATA_LEN 0x160 // ROMヘッダのハッシュ計算する部分の長さDS版 #define AUTH_KEY_BUFFER_LEN 128 -#define MB_AUTH_SIGN_SIZE (128) /* digital sign size */ +#define MB_AUTH_SIGN_SIZE (128) /* digital sign size */ -#define THREAD_PRIO_FS_WRAM 3 -#define WRAM_SIZE_FOR_FS MI_WRAM_SIZE_96KB +#define THREAD_PRIO_FS_WRAM 3 +#define WRAM_SIZE_FOR_FS MI_WRAM_SIZE_96KB #ifdef USE_HYENA_COMPONENT -#define WRAM_SLOT_FOR_FS 5 +#define WRAM_SLOT_FOR_FS 5 #else -#define WRAM_SLOT_FOR_FS 0 +#define WRAM_SLOT_FOR_FS 0 #endif #include -#define DS_HASH_TABLE_SIZE (256*1024) +#define DS_HASH_TABLE_SIZE (512*1024) -#define SYSM_TITLE_MESSAGE_ARRAY_MAX 1 +#define SYSM_TITLE_MESSAGE_ARRAY_MAX 1 -#define SIZE_16KB ( 16 * 1024 ) +#define SIZE_16KB ( 16 * 1024 ) -typedef struct MbAuthCode +typedef struct MbAuthCode { - char magic_code[2]; // マジックナンバー - u16 version; // バージョン - u8 sign[MB_AUTH_SIGN_SIZE]; // 署名 - u32 serial_number; // シリアル番号 -} MbAuthCode; // 16byte + char magic_code[2]; // マジックナンバー + u16 version; // バージョン + u8 sign[MB_AUTH_SIGN_SIZE]; // 署名 + u32 serial_number; // シリアル番号 +} MbAuthCode; // 16byte typedef struct CalcHMACSHA1CallbackArg { - SVCHMACSHA1Context ctx; - u32 hash_length; + SVCHMACSHA1Context ctx; + u32 hash_length; } CalcHMACSHA1CallbackArg; typedef struct CalcSHA1CallbackArg { - SVCSHA1Context ctx; - u32 hash_length; + SVCSHA1Context ctx; + u32 hash_length; } CalcSHA1CallbackArg; // extern data----------------------------------------------------------------- @@ -101,18 +101,18 @@ static void SYSMi_CpuClearFast( void *dest, u32 size ); // global variable------------------------------------------------------------- // static variable------------------------------------------------------------- -static OSThread s_thread; -static OSThread s_auth_thread; -static TWLBannerFile s_card_bannerBuf; +static OSThread s_thread; +static OSThread s_auth_thread; +static TWLBannerFile s_card_bannerBuf; static MbAuthCode s_authcode; -static BOOL s_loadstart = FALSE; +static BOOL s_loadstart = FALSE; -static BOOL s_loadPaused = FALSE; +static BOOL s_loadPaused = FALSE; -static OSMessageQueue s_msgQ; -static OSMessage s_msgArray[SYSM_TITLE_MESSAGE_ARRAY_MAX]; +static OSMessageQueue s_msgQ; +static OSMessage s_msgArray[SYSM_TITLE_MESSAGE_ARRAY_MAX]; static int s_listLength = 0; @@ -120,21 +120,29 @@ static u8 *s_calc_hash = NULL; static BOOL s_b_dev = FALSE; static BOOL s_result_phase1 = FALSE; -static DHTFile *dht = NULL; -static const u8* hash0 = NULL; -static const u8* hash1 = NULL; +static struct +{ + void* buffer; + DHTFile* dht; // in buffer + DHTFileEx* dhtex; // in buffer + DHTFileAdHoc* dhtah; // in buffer + const u8* hash1; + const u8* hash2; + const u8* hash3; +} +s_dht; // const data------------------------------------------------------------------ static const OSBootType s_launcherToOSBootType[ LAUNCHER_BOOTTYPE_MAX ] = { - OS_BOOTTYPE_ILLEGAL, // ILLEGAL - OS_BOOTTYPE_ROM, // ROM - OS_BOOTTYPE_NAND, // TEMP - OS_BOOTTYPE_NAND, // NAND - OS_BOOTTYPE_MEMORY, // MEMORY + OS_BOOTTYPE_ILLEGAL, // ILLEGAL + OS_BOOTTYPE_ROM, // ROM + OS_BOOTTYPE_NAND, // TEMP + OS_BOOTTYPE_NAND, // NAND + OS_BOOTTYPE_MEMORY, // MEMORY }; // HMAC_SHA1用鍵 -static const u8 s_digestDefaultKey[ DIGEST_HASH_BLOCK_SIZE_SHA1 ] = +static const u8 s_digestDefaultKey[ DIGEST_HASH_BLOCK_SIZE_SHA1 ] = { 0x21, 0x06, 0xc0, 0xde, 0xba, 0x98, 0xce, 0x3f, @@ -218,42 +226,166 @@ static BOOL GetDatabaseFilepath(char *path) return TRUE; } -static void PrepareDHTDatabase(void) +// open and read every database (フェーズ4があるので常に実行すること) +static BOOL PrepareDHTDatabase(void) { char path[256]; - if ( GetDatabaseFilepath( path ) ) + int length; + FSFile file; + + if ( s_dht.buffer ) { - FSFile file; - if ( FS_OpenFileEx(&file, path, FS_FILEMODE_R) ) - { -#if 0 // 1 if using attach_dummyromheader - if ( FS_SeekFile(&file, sizeof(ROM_Header), FS_SEEK_SET) ) -#endif - { - dht = SYSM_Alloc( DS_HASH_TABLE_SIZE ); - if( dht != NULL ) - { - if( DHT_PrepareDatabase(dht, &file) ) - { - DC_FlushRange(dht, DHT_GetDatabaseLength(dht)); - FS_CloseFile(&file); - return; - } - } - } - FS_CloseFile(&file); - } + return TRUE; // already done !? } - - MI_CpuClear8(dht, sizeof(DHTHeader)); - dht = NULL; + + if ( !GetDatabaseFilepath( path ) ) + { + OS_TPrintf("PrepareDHTDatabase failed: DHT file is not found.\n"); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): DHT file is not found.\n" ); + } + return FALSE; // database was not found + } + if ( !FS_OpenFileEx(&file, path, FS_FILEMODE_R) ) + { + OS_TPrintf("PrepareDHTDatabase failed: DHT file cannot open.\n"); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): DHT file cannot open.\n" ); + } + return FALSE; // cannot open the file + } + length = (int)FS_GetFileLength(&file); + if ( length > DS_HASH_TABLE_SIZE ) + { + OS_TPrintf("PrepareDHTDatabase failed: DHT file size (%d) is too large.\n", length ); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): DHT file size (%d) is too large.\n", length ); + } + FS_CloseFile(&file); + return FALSE; // too large + } + +#if 0 // 1 if using attach_dummyromheader + if ( FS_SeekFile(&file, sizeof(ROM_Header), FS_SEEK_SET) ) + { + OS_TPrintf("PrepareDHTDatabase failed: DHT file size (%d) is too small.\n", length ); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): DHT file size (%d) is too small.\n", length ); + } + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + FS_CloseFile(&file); + return FALSE; + } +#endif + + s_dht.buffer = SYSM_Alloc( (u32)length ); + if ( !s_dht.buffer ) + { + OS_TPrintf("PrepareDHTDatabase failed: cannot allocate %d bytes for buffer.\n", length ); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot allocate %d bytes for buffer.\n", length ); + } + FS_CloseFile(&file); + return FALSE; // cannot allocate the memory + } + // 基本データベース + s_dht.dht = s_dht.buffer; + if ( sizeof(DHTHeader) != FS_ReadFile(&file, &s_dht.dht->header, sizeof(DHTHeader)) ) + { + OS_TPrintf("PrepareDHTDatabase failed: cannot read DHTHeader for phase 1/2.\n" ); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot read DHTHeader for phase 1/2.\n" ); + } + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + FS_CloseFile(&file); + return FALSE; // cannot read the file + } + length = (int)DHT_GetDatabaseLength(s_dht.dht) - (int)sizeof(DHTHeader); + if ( length < 0 || length != FS_ReadFile(&file, &s_dht.dht->database, length) ) + { + OS_TPrintf("PrepareDHTDatabase failed: cannot read DHTDatabase for phase 1/2.\n" ); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot read DHTDatabase for phase 1/2.\n" ); + } + s_dht.dht = NULL; + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + FS_CloseFile(&file); + return FALSE; // cannot read the file + } + // 拡張データベース + s_dht.dhtex = (void*)((u32)s_dht.buffer + DHT_GetDatabaseLength(s_dht.dht)); + if ( sizeof(DHTHeader) != FS_ReadFile(&file, &s_dht.dhtex->header, sizeof(DHTHeader)) ) + { + s_dht.dhtex = NULL; + OS_TPrintf("PrepareDHTDatabase failed: cannot read DHTHeader for phase 3.\n" ); + FS_CloseFile(&file); +#ifndef SYSM_IGNORE_DHT_EX_NOT_FOUND + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot read DHTHeader for phase 3.\n" ); + } + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + return FALSE; // cannot read the file +#else + return TRUE; +#endif + } + length = (int)DHT_GetDatabaseExLength(s_dht.dhtex) - (int)sizeof(DHTHeader); + if ( length < 0 || length != FS_ReadFile(&file, &s_dht.dhtex->database, length) ) + { + s_dht.dhtex = NULL; + OS_TPrintf("PrepareDHTDatabase failed: cannot read DHTDatabaseEx for phase 3.\n" ); + FS_CloseFile(&file); +#ifndef SYSM_IGNORE_DHT_EX_NOT_FOUND + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot read DHTDatabaseEx for phase 3.\n" ); + } + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + return FALSE; // cannot read the file +#else + return TRUE; +#endif + } + // 個別対応データベース + s_dht.dhtah = (void*)((u32)s_dht.buffer + DHT_GetDatabaseExLength(s_dht.dhtex)); + if ( sizeof(DHTHeader) != FS_ReadFile(&file, &s_dht.dhtah->header, sizeof(DHTHeader)) ) + { + s_dht.dhtah = NULL; + OS_TPrintf("PrepareDHTDatabase failed: cannot read DHTHeader for phase 4.\n" ); + FS_CloseFile(&file); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot read DHTHeader for phase 4.\n" ); + } + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + return FALSE; // phase 3が読めてphase4が読めないことはあり得ない + } + length = (int)DHT_GetDatabaseAdHocLength(s_dht.dhtah) - (int)sizeof(DHTHeader); + if ( length < 0 || length != FS_ReadFile(&file, &s_dht.dhtah->database, length) ) + { + s_dht.dhtah = NULL; + OS_TPrintf("PrepareDHTDatabase failed: cannot read DHTDatabaseAdHoc for phase 4.\n" ); + FS_CloseFile(&file); + if(!s_b_dev) { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): cannot read DHTDatabaseAdHoc for phase 4.\n" ); + } + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + return FALSE; // phase 3が読めてphase4が読めないことはあり得ない + } + FS_CloseFile(&file); + return TRUE; } static BOOL WrapperFunc_ReadCardData(void* dest, s32 offset, s32 length, void* arg) { #pragma unused(arg) - HOTSW_ReadCardData( (void *)offset, dest, (u32)length); - return TRUE; + HOTSW_ReadCardData( (void *)offset, dest, (u32)length); + return TRUE; } @@ -272,7 +404,7 @@ static BOOL WrapperFunc_ReadCardData(void* dest, s32 offset, s32 length, void* a // SharedArea Access ver. static inline u16 SCFG_GetBondingOption(void) { - return (u16)(*(u8*)(HW_SYS_CONF_BUF+HWi_WSYS08_OFFSET) & HWi_WSYS08_OP_OPT_MASK); + return (u16)(*(u8*)(HW_SYS_CONF_BUF+HWi_WSYS08_OFFSET) & HWi_WSYS08_OP_OPT_MASK); } @@ -287,122 +419,122 @@ static inline u16 SCFG_GetBondingOption(void) // カードタイトルの取得 TitleProperty *SYSM_GetCardTitleList( BOOL *changed ) { - TitleProperty *pTitleList_Card = AMN_getTitlePropertyList(); - if(changed) *changed = FALSE; - - if(s_loadstart) - { - // ロード開始していたら、もうヘッダやタイトル情報は変更しない - return pTitleList_Card; - } - - if( SYSMi_GetWork()->flags.hotsw.isCardStateChanged ) { - u16 id = (u16)OS_GetLockID(); - const ROM_Header_Short *pROMH_bak = (ROM_Header_Short *)SYSM_CARD_ROM_HEADER_BAK; - - MI_CpuClear32( pTitleList_Card, sizeof(TitleProperty) ); - - (void)OS_LockByWord( id, &SYSMi_GetWork()->lockCardRsc, NULL ); // ARM7と排他制御する - - // ROMヘッダバッファのコピー - if( SYSM_IsExistCard() ) { - if( ( pROMH_bak->platform_code & PLATFORM_CODE_FLAG_TWL ) && !UTL_CheckAppRegion( pROMH_bak->card_region_bitmap ) ) { - // TWLアプリでカードリージョンが本体と一致しないものは、カードを認識しない。 - OS_TPrintf( "Region Check NG : %llx\n", pROMH_bak->titleID ); - MI_CpuClearFast( (void *)SYSM_APP_ROM_HEADER_BUF, SYSM_APP_ROM_HEADER_SIZE ); // ROMヘッダのクリア - MI_CpuClearFast( &s_card_bannerBuf, sizeof(TWLBannerFile) ); // バナーデータのクリア - }else { - // ROMヘッダのリード - (void)SYSMi_CopyCardRomHeader(); - // バナーデータのリード - (void)SYSMi_CopyCardBanner(); - - pTitleList_Card->pBanner = &s_card_bannerBuf; - AMN_stepBannerAnime(0, TRUE); // バナーカウンタセットしなおし - pTitleList_Card->flags.isValid = TRUE; - pTitleList_Card->flags.isAppLoadCompleted = FALSE; - pTitleList_Card->flags.isAppRelocate = TRUE; - MI_CpuCopy8( SYSM_GetCardRomHeader(), AMN_getRomHeaderList(), sizeof(ROM_Header_Short) ); - } - }else { - MI_CpuClearFast( (void *)SYSM_APP_ROM_HEADER_BUF, SYSM_APP_ROM_HEADER_SIZE ); // ROMヘッダのクリア - MI_CpuClearFast( &s_card_bannerBuf, sizeof(TWLBannerFile) ); // バナーデータのクリア - } - - SYSMi_GetWork()->flags.hotsw.isCardStateChanged = FALSE; // カード情報更新フラグを落とす - (void)OS_UnlockByWord( id, &SYSMi_GetWork()->lockCardRsc, NULL ); // ARM7と排他制御する - OS_ReleaseLockID( id ); - - // タイトル情報フラグのセット - pTitleList_Card->flags.bootType = LAUNCHER_BOOTTYPE_ROM; - - if( SYSM_GetCardRomHeader()->platform_code & PLATFORM_CODE_FLAG_TWL ) { - // TWLアプリの時は、TitleIDをそのままセット - pTitleList_Card->titleID = *(u64 *)( &SYSM_GetCardRomHeader()->titleID_Lo ); - }else { - // NTRアプリの時は、TitleIDがないので、GameCodeをいじって擬似的にTitleIDとする。 - pTitleList_Card->titleID = (u64)( ( SYSM_GetCardRomHeader()->game_code[ 3 ] << 0 ) | - ( SYSM_GetCardRomHeader()->game_code[ 2 ] << 8 ) | - ( SYSM_GetCardRomHeader()->game_code[ 1 ] << 16 ) | - ( SYSM_GetCardRomHeader()->game_code[ 0 ] << 24 ) ); - } - if(changed) *changed = TRUE; - } - - return pTitleList_Card; + TitleProperty *pTitleList_Card = AMN_getTitlePropertyList(); + if(changed) *changed = FALSE; + + if(s_loadstart) + { + // ロード開始していたら、もうヘッダやタイトル情報は変更しない + return pTitleList_Card; + } + + if( SYSMi_GetWork()->flags.hotsw.isCardStateChanged ) { + u16 id = (u16)OS_GetLockID(); + const ROM_Header_Short *pROMH_bak = (ROM_Header_Short *)SYSM_CARD_ROM_HEADER_BAK; + + MI_CpuClear32( pTitleList_Card, sizeof(TitleProperty) ); + + (void)OS_LockByWord( id, &SYSMi_GetWork()->lockCardRsc, NULL ); // ARM7と排他制御する + + // ROMヘッダバッファのコピー + if( SYSM_IsExistCard() ) { + if( ( pROMH_bak->platform_code & PLATFORM_CODE_FLAG_TWL ) && !UTL_CheckAppRegion( pROMH_bak->card_region_bitmap ) ) { + // TWLアプリでカードリージョンが本体と一致しないものは、カードを認識しない。 + OS_TPrintf( "Region Check NG : %llx\n", pROMH_bak->titleID ); + MI_CpuClearFast( (void *)SYSM_APP_ROM_HEADER_BUF, SYSM_APP_ROM_HEADER_SIZE ); // ROMヘッダのクリア + MI_CpuClearFast( &s_card_bannerBuf, sizeof(TWLBannerFile) ); // バナーデータのクリア + }else { + // ROMヘッダのリード + (void)SYSMi_CopyCardRomHeader(); + // バナーデータのリード + (void)SYSMi_CopyCardBanner(); + + pTitleList_Card->pBanner = &s_card_bannerBuf; + AMN_stepBannerAnime(0, TRUE); // バナーカウンタセットしなおし + pTitleList_Card->flags.isValid = TRUE; + pTitleList_Card->flags.isAppLoadCompleted = FALSE; + pTitleList_Card->flags.isAppRelocate = TRUE; + MI_CpuCopy8( SYSM_GetCardRomHeader(), AMN_getRomHeaderList(), sizeof(ROM_Header_Short) ); + } + }else { + MI_CpuClearFast( (void *)SYSM_APP_ROM_HEADER_BUF, SYSM_APP_ROM_HEADER_SIZE ); // ROMヘッダのクリア + MI_CpuClearFast( &s_card_bannerBuf, sizeof(TWLBannerFile) ); // バナーデータのクリア + } + + SYSMi_GetWork()->flags.hotsw.isCardStateChanged = FALSE; // カード情報更新フラグを落とす + (void)OS_UnlockByWord( id, &SYSMi_GetWork()->lockCardRsc, NULL ); // ARM7と排他制御する + OS_ReleaseLockID( id ); + + // タイトル情報フラグのセット + pTitleList_Card->flags.bootType = LAUNCHER_BOOTTYPE_ROM; + + if( SYSM_GetCardRomHeader()->platform_code & PLATFORM_CODE_FLAG_TWL ) { + // TWLアプリの時は、TitleIDをそのままセット + pTitleList_Card->titleID = *(u64 *)( &SYSM_GetCardRomHeader()->titleID_Lo ); + }else { + // NTRアプリの時は、TitleIDがないので、GameCodeをいじって擬似的にTitleIDとする。 + pTitleList_Card->titleID = (u64)( ( SYSM_GetCardRomHeader()->game_code[ 3 ] << 0 ) | + ( SYSM_GetCardRomHeader()->game_code[ 2 ] << 8 ) | + ( SYSM_GetCardRomHeader()->game_code[ 1 ] << 16 ) | + ( SYSM_GetCardRomHeader()->game_code[ 0 ] << 24 ) ); + } + if(changed) *changed = TRUE; + } + + return pTitleList_Card; } // カードROMヘッダのARM7バッファからARM9バッファへのコピー BOOL SYSMi_CopyCardRomHeader( void ) { - BOOL retval = FALSE; + BOOL retval = FALSE; - if( SYSM_IsExistCard() ) { - // ROMヘッダのリード - DC_InvalidateRange( (void *)SYSM_CARD_ROM_HEADER_BAK, SYSM_APP_ROM_HEADER_SIZE ); // キャッシュケア - MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BAK, (void *)SYSM_APP_ROM_HEADER_BUF, SYSM_APP_ROM_HEADER_SIZE ); // ROMヘッダコピー + if( SYSM_IsExistCard() ) { + // ROMヘッダのリード + DC_InvalidateRange( (void *)SYSM_CARD_ROM_HEADER_BAK, SYSM_APP_ROM_HEADER_SIZE ); // キャッシュケア + MI_CpuCopyFast( (void *)SYSM_CARD_ROM_HEADER_BAK, (void *)SYSM_APP_ROM_HEADER_BUF, SYSM_APP_ROM_HEADER_SIZE ); // ROMヘッダコピー - retval = TRUE; - } + retval = TRUE; + } - return retval; + return retval; } // カードバナーのARM7バッファからARM9バッファへのコピー BOOL SYSMi_CopyCardBanner( void ) { - BOOL retval = FALSE; + BOOL retval = FALSE; - if( SYSM_IsExistCard() ) { - // バナーデータのコピー - TWLBannerFile *pBanner = &s_card_bannerBuf; - if( SYSMi_GetWork()->flags.hotsw.isValidCardBanner ) { - DC_InvalidateRange( (void *)SYSM_CARD_BANNER_BUF, 0x3000 ); - MI_CpuCopyFast( (void *)SYSM_CARD_BANNER_BUF, pBanner, sizeof(TWLBannerFile) ); - } - retval = AMN_checkBannerFile( pBanner ); - - if( !retval ) { - MI_CpuClearFast( pBanner, sizeof(TWLBannerFile) ); - } - } + if( SYSM_IsExistCard() ) { + // バナーデータのコピー + TWLBannerFile *pBanner = &s_card_bannerBuf; + if( SYSMi_GetWork()->flags.hotsw.isValidCardBanner ) { + DC_InvalidateRange( (void *)SYSM_CARD_BANNER_BUF, 0x3000 ); + MI_CpuCopyFast( (void *)SYSM_CARD_BANNER_BUF, pBanner, sizeof(TWLBannerFile) ); + } + retval = AMN_checkBannerFile( pBanner ); - return retval; + if( !retval ) { + MI_CpuClearFast( pBanner, sizeof(TWLBannerFile) ); + } + } + + return retval; } void SYSM_InitTitleList( void ) { - AMN_init( SYSM_Alloc, SYSM_Free ); + AMN_init( SYSM_Alloc, SYSM_Free ); } // SYSM_InitTitleListを事前に呼ぶ必要あり void SYSM_MakeNandTitleListMakerInfo( void ) { - AMN_restartWithReadNandTitleHeaderShort(); - while (!AMN_isNandTitleListReady()) { - OS_Sleep(1); - } + AMN_restartWithReadNandTitleHeaderShort(); + while (!AMN_isNandTitleListReady()) { + OS_Sleep(1); + } } // ローンチ対象となるNANDタイトルリストの取得 @@ -410,33 +542,33 @@ void SYSM_MakeNandTitleListMakerInfo( void ) // return:Titleリストのポインタ TitleProperty *SYSM_GetNandTitleList( void ) { - // filter_flag : ALL, ALL_APP, SYS_APP, USER_APP, Data only, 等の条件を指定してタイトルリストを取得する。 - AMN_restartWithReadNandTitle(); - while (!AMN_isNandTitleListReady()) { - OS_Sleep(1); - } - return AMN_getTitlePropertyList(); + // filter_flag : ALL, ALL_APP, SYS_APP, USER_APP, Data only, 等の条件を指定してタイトルリストを取得する。 + AMN_restartWithReadNandTitle(); + while (!AMN_isNandTitleListReady()) { + OS_Sleep(1); + } + return AMN_getTitlePropertyList(); } // SYSM_InitTitleListを事前に呼ぶ必要あり void SYSM_MakeNandTitleListMakerInfoAsync( void ) { - AMN_restartWithReadNandTitleHeaderShort(); + AMN_restartWithReadNandTitleHeaderShort(); } void SYSM_MakeNandTitleListAsync( void ) { - AMN_restartWithReadNandTitle(); + AMN_restartWithReadNandTitle(); } BOOL SYSM_isNandTitleListReady( void ) { - return AMN_isNandTitleListReady(); + return AMN_isNandTitleListReady(); } TitleProperty *SYSM_GetTitlePropertyList( void ) { - return AMN_getTitlePropertyList(); + return AMN_getTitlePropertyList(); } // ============================================================================ @@ -449,142 +581,142 @@ TitleProperty *SYSM_GetTitlePropertyList( void ) static void CallbackSub_DecryptAES(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot) { - OSIntrMode enabled = OS_DisableInterrupts();// WRAM切り替え途中で割り込み発生→別スレッドでWRAM切り替え→死亡の可能性があるので暫定対応 - MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM9, MI_WRAM_ARM7 );// Wramを7にスイッチ - SYSM_StartDecryptAESRegion_W( addr, orig_addr, len ); // AES領域デクリプト - MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM7, MI_WRAM_ARM9 );// Wramが7にスイッチしてしまっているので戻す - OS_RestoreInterrupts(enabled);// 割り込み許可 + OSIntrMode enabled = OS_DisableInterrupts();// WRAM切り替え途中で割り込み発生→別スレッドでWRAM切り替え→死亡の可能性があるので暫定対応 + MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM9, MI_WRAM_ARM7 );// Wramを7にスイッチ + SYSM_StartDecryptAESRegion_W( addr, orig_addr, len ); // AES領域デクリプト + MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM7, MI_WRAM_ARM9 );// Wramが7にスイッチしてしまっているので戻す + OS_RestoreInterrupts(enabled);// 割り込み許可 } static void SYSMi_CalcHMACSHA1Callback(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot, void* arg) { - CalcHMACSHA1CallbackArg *cba = (CalcHMACSHA1CallbackArg *)arg; - u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); - CallbackSub_DecryptAES( addr, orig_addr, len, wram, slot ); - if( calc_len == 0 ) return; - cba->hash_length -= calc_len; - SVC_HMACSHA1Update( &cba->ctx, addr, calc_len ); + CalcHMACSHA1CallbackArg *cba = (CalcHMACSHA1CallbackArg *)arg; + u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); + CallbackSub_DecryptAES( addr, orig_addr, len, wram, slot ); + if( calc_len == 0 ) return; + cba->hash_length -= calc_len; + SVC_HMACSHA1Update( &cba->ctx, addr, calc_len ); } static void SYSMi_CalcSHA1Callback(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot, void* arg) { - CalcSHA1CallbackArg *cba = (CalcSHA1CallbackArg *)arg; - u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); - CallbackSub_DecryptAES( addr, orig_addr, len, wram, slot ); - if( calc_len == 0 ) return; - cba->hash_length -= calc_len; - SVC_SHA1Update( &cba->ctx, addr, calc_len ); + CalcSHA1CallbackArg *cba = (CalcSHA1CallbackArg *)arg; + u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); + CallbackSub_DecryptAES( addr, orig_addr, len, wram, slot ); + if( calc_len == 0 ) return; + cba->hash_length -= calc_len; + SVC_SHA1Update( &cba->ctx, addr, calc_len ); } static void SYSMi_DHTPhase1Callback(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot, void* arg) { - CalcHMACSHA1CallbackArg *cba = (CalcHMACSHA1CallbackArg *)arg; - u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); - CallbackSub_DecryptAES( addr, orig_addr, len, wram, slot ); - if( calc_len == 0 ) return; - cba->hash_length -= calc_len; - DHT_CheckHashPhase1Update( &cba->ctx, addr, (s32)calc_len ); + CalcHMACSHA1CallbackArg *cba = (CalcHMACSHA1CallbackArg *)arg; + u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); + CallbackSub_DecryptAES( addr, orig_addr, len, wram, slot ); + if( calc_len == 0 ) return; + cba->hash_length -= calc_len; + DHT_CheckHashPhase1Update( &cba->ctx, addr, (s32)calc_len ); } static void SYSMi_FinalizeHotSWAsync( TitleProperty *pBootTitle, ROM_Header *head ) { - HotSwCardState card_state; + HotSwCardState card_state; ROM_Header* rh = (void*)SYSM_APP_ROM_HEADER_BUF; - DC_StoreRange( head, sizeof(ROM_Header) ); + DC_StoreRange( head, sizeof(ROM_Header) ); - switch( pBootTitle->flags.bootType ) - { - case LAUNCHER_BOOTTYPE_NAND: - case LAUNCHER_BOOTTYPE_TEMP: - // ROMヘッダのアクセスコントロール情報をもとにカード状態を制御するのは "NAND/TMPブートのTWL-LTD" アプリのみ - if ( ( head->s.platform_code & PLATFORM_CODE_TWL_LIMITED ) == PLATFORM_CODE_TWL_LIMITED ) - { - if(rh->s.access_control.game_card_nitro_mode){ - card_state = HOTSW_CARD_STATE_GAME_MODE; - } + switch( pBootTitle->flags.bootType ) + { + case LAUNCHER_BOOTTYPE_NAND: + case LAUNCHER_BOOTTYPE_TEMP: + // ROMヘッダのアクセスコントロール情報をもとにカード状態を制御するのは "NAND/TMPブートのTWL-LTD" アプリのみ + if ( ( head->s.platform_code & PLATFORM_CODE_TWL_LIMITED ) == PLATFORM_CODE_TWL_LIMITED ) + { + if(rh->s.access_control.game_card_nitro_mode){ + card_state = HOTSW_CARD_STATE_GAME_MODE; + } else if(rh->s.access_control.game_card_on){ - card_state = HOTSW_CARD_STATE_NORMAL_MODE; - }else - { - card_state = HOTSW_CARD_STATE_POWER_OFF; - } - } - // それ以外は強制的にNTR互換Game領域にアクセス可能な状態となる(DSダウンロードプレイも含む) - else - { - card_state = HOTSW_CARD_STATE_GAME_MODE; - } - break; - case LAUNCHER_BOOTTYPE_ROM: - default: - card_state = HOTSW_CARD_STATE_KEEP; - break; - } + card_state = HOTSW_CARD_STATE_NORMAL_MODE; + }else + { + card_state = HOTSW_CARD_STATE_POWER_OFF; + } + } + // それ以外は強制的にNTR互換Game領域にアクセス可能な状態となる(DSダウンロードプレイも含む) + else + { + card_state = HOTSW_CARD_STATE_GAME_MODE; + } + break; + case LAUNCHER_BOOTTYPE_ROM: + default: + card_state = HOTSW_CARD_STATE_KEEP; + break; + } - HOTSW_FinalizeHotSWAsync( card_state ); + HOTSW_FinalizeHotSWAsync( card_state ); } static void SYSMi_LoadTitleThreadFunc( TitleProperty *pBootTitle ) { - enum - { - region_header = 0, - region_arm9_ntr, - region_arm7_ntr, - region_arm9_twl, - region_arm7_twl, - region_max - }; - // DSダウンロードプレイおよびpictochat等のNTR拡張NANDアプリの時は、ROMヘッダを退避する - // が、NTR-ROMヘッダは旧無線パッチとデバッガパッチを当てる必要があるため、再配置はrebootライブラリで行う。 - - // ロード + enum + { + region_header = 0, + region_arm9_ntr, + region_arm7_ntr, + region_arm9_twl, + region_arm7_twl, + region_max + }; + // DSダウンロードプレイおよびpictochat等のNTR拡張NANDアプリの時は、ROMヘッダを退避する + // が、NTR-ROMヘッダは旧無線パッチとデバッガパッチを当てる必要があるため、再配置はrebootライブラリで行う。 + + // ロード char path[256]; FSFile file[1]; BOOL bSuccess; BOOL isTwlApp = TRUE; BOOL isCardApp = FALSE; - - switch( pBootTitle->flags.bootType ) - { - case LAUNCHER_BOOTTYPE_NAND: - // NAND - NAM_GetTitleBootContentPathFast(path, pBootTitle->titleID); - break; - case LAUNCHER_BOOTTYPE_ROM: - // CARD - isCardApp = TRUE; - break; - case LAUNCHER_BOOTTYPE_TEMP: - // tmpフォルダ - STD_TSNPrintf( path, 256, OS_TMP_APP_PATH, pBootTitle->titleID ); - break; - default: - // unknown - UTL_SetFatalError(FATAL_ERROR_LOAD_UNKNOWN_BOOTTYPE); - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "TitleID : %016llx \n", pBootTitle->titleID ); - ERRORLOG_Printf( "flags.isValid : %d\n", pBootTitle->flags.isValid ); - ERRORLOG_Printf( "flags.bootType : %d\n", pBootTitle->flags.bootType ); - ERRORLOG_Printf( "isAppLoadCompl : %d\n", pBootTitle->flags.isAppLoadCompleted ); - return; - } - if(!isCardApp) - { - FS_InitFile( file ); - bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R); + switch( pBootTitle->flags.bootType ) + { + case LAUNCHER_BOOTTYPE_NAND: + // NAND + NAM_GetTitleBootContentPathFast(path, pBootTitle->titleID); + break; + case LAUNCHER_BOOTTYPE_ROM: + // CARD + isCardApp = TRUE; + break; + case LAUNCHER_BOOTTYPE_TEMP: + // tmpフォルダ + STD_TSNPrintf( path, 256, OS_TMP_APP_PATH, pBootTitle->titleID ); + break; + default: + // unknown + UTL_SetFatalError(FATAL_ERROR_LOAD_UNKNOWN_BOOTTYPE); + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "TitleID : %016llx \n", pBootTitle->titleID ); + ERRORLOG_Printf( "flags.isValid : %d\n", pBootTitle->flags.isValid ); + ERRORLOG_Printf( "flags.bootType : %d\n", pBootTitle->flags.bootType ); + ERRORLOG_Printf( "isAppLoadCompl : %d\n", pBootTitle->flags.isAppLoadCompleted ); + return; + } + + if(!isCardApp) + { + FS_InitFile( file ); + bSuccess = FS_OpenFileEx(file, path, FS_FILEMODE_R); }else { - bSuccess = TRUE; - } + bSuccess = TRUE; + } if( ! bSuccess ) { OS_TPrintf("RebootSystem failed: cant open file\n"); - UTL_SetFatalError(FATAL_ERROR_LOAD_OPENFILE_FAILED); - goto ERROR; + UTL_SetFatalError(FATAL_ERROR_LOAD_OPENFILE_FAILED); + goto ERROR; } { @@ -597,63 +729,63 @@ OS_TPrintf("RebootSystem failed: cant open file\n"); ROM_Header *head = (ROM_Header *)header; CalcHMACSHA1CallbackArg dht_arg; - // WRAM利用Read関数の準備、 - // 使用するコンポーネントに応じて、WRAMのスロットを解放しておく - // hyena : WRAM_C slot 5-7 - // jackal : WRAM_C slot 0-2 - FS_InitWramTransfer( THREAD_PRIO_FS_WRAM ); - MI_FreeWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM7 ); - MI_FreeWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM9 ); - MI_FreeWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_DSP ); - MI_CancelWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM7 ); - MI_CancelWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM9 ); - MI_CancelWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_DSP ); - - // ハッシュ格納用バッファ(ヒープから取っているけど変更するかも) - s_calc_hash = SYSM_Alloc( region_max * SVC_SHA1_DIGEST_SIZE ); - if(!s_calc_hash) - { + // WRAM利用Read関数の準備、 + // 使用するコンポーネントに応じて、WRAMのスロットを解放しておく + // hyena : WRAM_C slot 5-7 + // jackal : WRAM_C slot 0-2 + FS_InitWramTransfer( THREAD_PRIO_FS_WRAM ); + MI_FreeWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM7 ); + MI_FreeWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM9 ); + MI_FreeWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_DSP ); + MI_CancelWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM7 ); + MI_CancelWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_ARM9 ); + MI_CancelWramSlot_C( WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, MI_WRAM_DSP ); + + // ハッシュ格納用バッファ(ヒープから取っているけど変更するかも) + s_calc_hash = SYSM_Alloc( region_max * SVC_SHA1_DIGEST_SIZE ); + if(!s_calc_hash) + { OS_TPrintf("RebootSystem failed: Alloc Failed.\n"); - UTL_SetFatalError(FATAL_ERROR_LOAD_MEMALLOC_FAILED); - goto ERROR; - } + UTL_SetFatalError(FATAL_ERROR_LOAD_MEMALLOC_FAILED); + goto ERROR; + } // まずROMヘッダを読み込む if(!isCardApp) { - bSuccess = FS_SeekFile(file, 0x00000000, FS_SEEK_SET); - }else - { - bSuccess = TRUE; - } + bSuccess = FS_SeekFile(file, 0x00000000, FS_SEEK_SET); + }else + { + bSuccess = TRUE; + } if( ! bSuccess ) { OS_TPrintf("RebootSystem failed: cant seek file(0)\n"); - UTL_SetFatalError(FATAL_ERROR_LOAD_SEEKFILE_FAILED); - goto ERROR; + UTL_SetFatalError(FATAL_ERROR_LOAD_SEEKFILE_FAILED); + goto ERROR; } - //ヘッダ読み込みと同時に各種ハッシュ計算……できない(NTRかTWLか判別できないため)ので読み込みのみ - { + //ヘッダ読み込みと同時に各種ハッシュ計算……できない(NTRかTWLか判別できないため)ので読み込みのみ + { BOOL result; u32 len = MATH_ROUNDUP( (s32)sizeof(header), SYSM_ALIGNMENT_LOAD_MODULE ); if(!isCardApp) - { - result = FS_ReadFileViaWram(file, (void *)header, (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, NULL, NULL ); - }else - { - result = HOTSW_ReadCardViaWram((void*) 0, (void*)header, (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, NULL, NULL ); - } - if ( !result ) - { + { + result = FS_ReadFileViaWram(file, (void *)header, (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, NULL, NULL ); + }else + { + result = HOTSW_ReadCardViaWram((void*) 0, (void*)header, (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, NULL, NULL ); + } + if ( !result ) + { OS_TPrintf("RebootSystem failed: cant read file(%d, %d)\n", 0, len); - UTL_SetFatalError(FATAL_ERROR_LOAD_READHEADER_FAILED); - goto ERROR; - } - } + UTL_SetFatalError(FATAL_ERROR_LOAD_READHEADER_FAILED); + goto ERROR; + } + } if( head->s.nintendo_logo_crc16 != 0xCF56 ) { @@ -667,301 +799,301 @@ OS_TPrintf("%02X ", header[i * 0x10 + j]); OS_TPrintf("\n"); } OS_TPrintf("RebootSystem failed: logo CRC error\n"); - UTL_SetFatalError(FATAL_ERROR_LOAD_LOGOCRC_ERROR); - goto ERROR; + UTL_SetFatalError(FATAL_ERROR_LOAD_LOGOCRC_ERROR); + goto ERROR; } - + if( !(head->s.platform_code & PLATFORM_CODE_FLAG_TWL) ) { - //NTR専用ROM or NTR TWL両方非対応のアプリ - isTwlApp = FALSE; - if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_TEMP) - { - // NTR-DLアプリの場合はDLアプリ署名データを取得しておく - u32 valid_size = ( head->s.rom_valid_size ? head->s.rom_valid_size : 0x01000000 ); + //NTR専用ROM or NTR TWL両方非対応のアプリ + isTwlApp = FALSE; + if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_TEMP) + { + // NTR-DLアプリの場合はDLアプリ署名データを取得しておく + u32 valid_size = ( head->s.rom_valid_size ? head->s.rom_valid_size : 0x01000000 ); - bSuccess = FS_SeekFile(file, (s32)valid_size, FS_SEEK_SET); + bSuccess = FS_SeekFile(file, (s32)valid_size, FS_SEEK_SET); - if( ! bSuccess ) - { + if( ! bSuccess ) + { OS_TPrintf("RebootSystem failed: cant seek file(0)\n"); - UTL_SetFatalError(FATAL_ERROR_LOAD_SEEKFILE_FAILED); - goto ERROR; - } - readLen = FS_ReadFile(file, &s_authcode, (s32)sizeof(s_authcode)); - if( readLen != (s32)sizeof(s_authcode) ) - { + UTL_SetFatalError(FATAL_ERROR_LOAD_SEEKFILE_FAILED); + goto ERROR; + } + readLen = FS_ReadFile(file, &s_authcode, (s32)sizeof(s_authcode)); + if( readLen != (s32)sizeof(s_authcode) ) + { OS_TPrintf("RebootSystem failed: cant read file(%p, %d, %d, %d)\n", &s_authcode, 0, sizeof(s_authcode), readLen); - UTL_SetFatalError(FATAL_ERROR_LOAD_READDLSIGN_FAILED); - goto ERROR; - } - } - } - - // ヘッダのハッシュ計算 - SVC_CalcSHA1( s_calc_hash, header, (u32)( ( isTwlApp || ( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND ) || head->s.exFlags.enable_nitro_whitelist_signature ) ? - TWL_ROM_HEADER_HASH_CALC_DATA_LEN : NTR_ROM_HEADER_HASH_CALC_DATA_LEN )); - - //この時点でヘッダの正当性検証 - // ※ROMヘッダ認証 - if( !SYSMi_AuthenticateHeader( pBootTitle, head ) ) - { - UTL_SetFatalError(FATAL_ERROR_LOAD_AUTH_HEADER_FAILED); - goto ERROR; - } - - // 正当性の検証されたヘッダを、本来のヘッダバッファへコピー - MI_CpuCopy8( head, (void*)SYSM_APP_ROM_HEADER_BUF, HW_TWL_ROM_HEADER_BUF_SIZE ); - - // NTRカードアプリはDHTのPhase1のための計算が必要 - if( !isTwlApp && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) - { - DHT_CheckHashPhase1Init(&dht_arg.ctx, &head->s); - } - - // ヘッダ読み込み完了直後の処理 - // ヘッダ読み込み完了フラグを立てる - SYSM_SetHeaderLoadCompleted(TRUE); - - // HOTSW終了処理有効化 - SYSMi_FinalizeHotSWAsync( pBootTitle, (void*)SYSM_APP_ROM_HEADER_BUF ); - + UTL_SetFatalError(FATAL_ERROR_LOAD_READDLSIGN_FAILED); + goto ERROR; + } + } + } + + // ヘッダのハッシュ計算 + SVC_CalcSHA1( s_calc_hash, header, (u32)( ( isTwlApp || ( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND ) || head->s.exFlags.enable_nitro_whitelist_signature ) ? + TWL_ROM_HEADER_HASH_CALC_DATA_LEN : NTR_ROM_HEADER_HASH_CALC_DATA_LEN )); + + //この時点でヘッダの正当性検証 + // ※ROMヘッダ認証 + if( !SYSMi_AuthenticateHeader( pBootTitle, head ) ) + { + UTL_SetFatalError(FATAL_ERROR_LOAD_AUTH_HEADER_FAILED); + goto ERROR; + } + + // 正当性の検証されたヘッダを、本来のヘッダバッファへコピー + MI_CpuCopy8( head, (void*)SYSM_APP_ROM_HEADER_BUF, HW_TWL_ROM_HEADER_BUF_SIZE ); + + // NTRカードアプリはDHTのPhase1のための計算が必要 + if( !isTwlApp && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) + { + DHT_CheckHashPhase1Init(&dht_arg.ctx, &head->s); + } + + // ヘッダ読み込み完了直後の処理 + // ヘッダ読み込み完了フラグを立てる + SYSM_SetHeaderLoadCompleted(TRUE); + + // HOTSW終了処理有効化 + SYSMi_FinalizeHotSWAsync( pBootTitle, (void*)SYSM_APP_ROM_HEADER_BUF ); + // 各領域を読み込む source [region_arm9_ntr] = head->s.main_rom_offset; length [region_arm9_ntr] = head->s.main_size; destaddr[region_arm9_ntr] = (u32)head->s.main_ram_address; - + source [region_arm7_ntr] = head->s.sub_rom_offset; length [region_arm7_ntr] = head->s.sub_size; destaddr[region_arm7_ntr] = (u32)head->s.sub_ram_address; - - if( isTwlApp ) - { - source [region_arm9_twl] = head->s.main_ltd_rom_offset; - length [region_arm9_twl] = head->s.main_ltd_size; - destaddr[region_arm9_twl] = (u32)head->s.main_ltd_ram_address; - - source [region_arm7_twl] = head->s.sub_ltd_rom_offset; - length [region_arm7_twl] = head->s.sub_ltd_size; - destaddr[region_arm7_twl] = (u32)head->s.sub_ltd_ram_address; + + if( isTwlApp ) + { + source [region_arm9_twl] = head->s.main_ltd_rom_offset; + length [region_arm9_twl] = head->s.main_ltd_size; + destaddr[region_arm9_twl] = (u32)head->s.main_ltd_ram_address; + + source [region_arm7_twl] = head->s.sub_ltd_rom_offset; + length [region_arm7_twl] = head->s.sub_ltd_size; + destaddr[region_arm7_twl] = (u32)head->s.sub_ltd_ram_address; } - + // 領域読み込み先のチェック及び再配置情報データの作成 // ゲームカードの再配置情報が書き込まれているので、nandアプリロード前に一旦クリア MI_CpuClearFast(SYSMi_GetWork()->romRelocateInfo, sizeof(Relocate_Info) * RELOCATE_INFO_NUM); - for( i=0; i= ARM9_LTD_STATIC ) continue;// nitroでは読み込まない領域 - if ( !SYSM_CheckLoadRegionAndSetRelocateInfo( (RomSegmentName)i, &(destaddr[i+region_arm9_ntr]), length[i+region_arm9_ntr], - &(SYSMi_GetWork()->romRelocateInfo[i]), isTwlApp ) ) - { - OS_TPrintf("RebootSystem failed: ROM Load Region error\n"); - UTL_SetFatalError(FATAL_ERROR_LOAD_RELOCATEINFO_FAILED); - goto ERROR; - } - } - - // AES初期化(ヘッダと再配置情報がそろってから) - (void)SYSM_InitDecryptAESRegion_W( (ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF ); + for( i=0; i= ARM9_LTD_STATIC ) continue;// nitroでは読み込まない領域 + if ( !SYSM_CheckLoadRegionAndSetRelocateInfo( (RomSegmentName)i, &(destaddr[i+region_arm9_ntr]), length[i+region_arm9_ntr], + &(SYSMi_GetWork()->romRelocateInfo[i]), isTwlApp ) ) + { + OS_TPrintf("RebootSystem failed: ROM Load Region error\n"); + UTL_SetFatalError(FATAL_ERROR_LOAD_RELOCATEINFO_FAILED); + goto ERROR; + } + } + + // AES初期化(ヘッダと再配置情報がそろってから) + (void)SYSM_InitDecryptAESRegion_W( (ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF ); for (i = region_arm9_ntr; i < region_max; ++i) { - BOOL result; - + BOOL result; + u32 len = MATH_ROUNDUP( length[i], SYSM_ALIGNMENT_LOAD_MODULE );// AESおよびDMA転送サイズの仕様で、ロードサイズは32バイトアライメントに補正 - + if ( !isTwlApp && i >= region_arm9_twl ) continue;// nitroでは読み込まない領域 - if(!isCardApp) - { - bSuccess = FS_SeekFile(file, (s32)source[i], FS_SEEK_SET); + if(!isCardApp) + { + bSuccess = FS_SeekFile(file, (s32)source[i], FS_SEEK_SET); }else { - bSuccess = TRUE; - } + bSuccess = TRUE; + } if( ! bSuccess ) { OS_TPrintf("RebootSystem failed: cant seek file(%d)\n", source[i]); - UTL_SetFatalError(FATAL_ERROR_LOAD_SEEKFILE_FAILED); - goto ERROR; + UTL_SetFatalError(FATAL_ERROR_LOAD_SEEKFILE_FAILED); + goto ERROR; } OS_TPrintf("RebootSystem : Load VIA WRAM %d.\n", i); // ここでロード処理と同時にハッシュ計算とAES処理もやってしまう // 別スレッドで同じWRAM使おうとすると多分コケるので注意 - + // コールバック関数に与える引数を初期化してRead if( !isTwlApp && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_TEMP ) { - // NTRダウンロードアプリのモジュール - CalcSHA1CallbackArg arg; - SVC_SHA1Init( &arg.ctx ); - arg.hash_length = (u32)length[i]; - if(!isCardApp) - { - result = FS_ReadFileViaWram(file, (void *)destaddr[i], (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcSHA1Callback, &arg ); - }else - { - result = HOTSW_ReadCardViaWram((void *)source[i], (void *)destaddr[i], (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcSHA1Callback, &arg ); - } - SVC_SHA1GetHash( &arg.ctx, &s_calc_hash[i * SVC_SHA1_DIGEST_SIZE] ); - }else if( !isTwlApp && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) - { - // NTRカードアプリはDHTのPhase1のための計算が必要 - // DHTチェックphase1用のハッシュを計算(DHT_CheckHashPhase1Update 関数)し、結果まで出しておく - dht_arg.hash_length = (u32)length[i]; - result = HOTSW_ReadCardViaWram((void *)source[i], (void *)destaddr[i], (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_DHTPhase1Callback, &dht_arg ); - }else - { - // それ以外 - CalcHMACSHA1CallbackArg arg; - SVC_HMACSHA1Init( &arg.ctx, (void *)s_digestDefaultKey, DIGEST_HASH_BLOCK_SIZE_SHA1 ); - arg.hash_length = length[i]; - if(!isCardApp) - { - result = FS_ReadFileViaWram(file, (void *)destaddr[i], (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcHMACSHA1Callback, &arg ); - }else - { - result = HOTSW_ReadCardViaWram((void *)source[i], (void *)destaddr[i], (s32)len, MI_WRAM_C, - WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcHMACSHA1Callback, &arg ); - //speed test code - /* - HOTSW_ReadCardData((void *)source[i], (void *)destaddr[i], (u32)len); - SVC_HMACSHA1Update( &arg.ctx, (void *)destaddr[i], length[i] ); - */ - } - SVC_HMACSHA1GetHash( &arg.ctx, &s_calc_hash[i * SVC_SHA1_DIGEST_SIZE] ); - } - if ( !result ) - { + // NTRダウンロードアプリのモジュール + CalcSHA1CallbackArg arg; + SVC_SHA1Init( &arg.ctx ); + arg.hash_length = (u32)length[i]; + if(!isCardApp) + { + result = FS_ReadFileViaWram(file, (void *)destaddr[i], (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcSHA1Callback, &arg ); + }else + { + result = HOTSW_ReadCardViaWram((void *)source[i], (void *)destaddr[i], (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcSHA1Callback, &arg ); + } + SVC_SHA1GetHash( &arg.ctx, &s_calc_hash[i * SVC_SHA1_DIGEST_SIZE] ); + }else if( !isTwlApp && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) + { + // NTRカードアプリはDHTのPhase1のための計算が必要 + // DHTチェックphase1用のハッシュを計算(DHT_CheckHashPhase1Update 関数)し、結果まで出しておく + dht_arg.hash_length = (u32)length[i]; + result = HOTSW_ReadCardViaWram((void *)source[i], (void *)destaddr[i], (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_DHTPhase1Callback, &dht_arg ); + }else + { + // それ以外 + CalcHMACSHA1CallbackArg arg; + SVC_HMACSHA1Init( &arg.ctx, (void *)s_digestDefaultKey, DIGEST_HASH_BLOCK_SIZE_SHA1 ); + arg.hash_length = length[i]; + if(!isCardApp) + { + result = FS_ReadFileViaWram(file, (void *)destaddr[i], (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcHMACSHA1Callback, &arg ); + }else + { + result = HOTSW_ReadCardViaWram((void *)source[i], (void *)destaddr[i], (s32)len, MI_WRAM_C, + WRAM_SLOT_FOR_FS, WRAM_SIZE_FOR_FS, SYSMi_CalcHMACSHA1Callback, &arg ); + //speed test code + /* + HOTSW_ReadCardData((void *)source[i], (void *)destaddr[i], (u32)len); + SVC_HMACSHA1Update( &arg.ctx, (void *)destaddr[i], length[i] ); + */ + } + SVC_HMACSHA1GetHash( &arg.ctx, &s_calc_hash[i * SVC_SHA1_DIGEST_SIZE] ); + } + if ( !result ) + { OS_TPrintf("RebootSystem failed: cant read file(%d, %d)\n", source[i], len); - UTL_SetFatalError(FATAL_ERROR_LOAD_READMODULE_FAILED); - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "LOAD_READMODULE_FAILED (sub info): region %d read failed.\n", i ); - goto ERROR; - } + UTL_SetFatalError(FATAL_ERROR_LOAD_READMODULE_FAILED); + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "LOAD_READMODULE_FAILED (sub info): region %d read failed.\n", i ); + goto ERROR; + } } - + // NTRカードアプリはDHTのPhase1最終計算を行う if( !isTwlApp && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) { - SVC_HMACSHA1GetHash(&dht_arg.ctx, &s_calc_hash[1 * SVC_SHA1_DIGEST_SIZE]); - } + SVC_HMACSHA1GetHash(&dht_arg.ctx, &s_calc_hash[1 * SVC_SHA1_DIGEST_SIZE]); + } - if(!isCardApp) - { - (void)FS_CloseFile(file); + if(!isCardApp) + { + (void)FS_CloseFile(file); } } - + // モジュール最終ロード先領域のうち、現在空いている場所をクリア // [TODO:]とりあえずベタ書き。余裕があればスレッド化する。 SYSMi_ClearRomLoadSegment( (ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF ); - - SYSM_SetLoadSucceeded(TRUE); - - // ここでスタック壊れていないかチェック - if( OS_STACK_NO_ERROR != OS_GetStackStatus( &s_thread ) ) - { - OS_TPrintf("RebootSystem warning: stack was broken!\n"); - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "SYSMi_LoadTitleThreadFunc: stack was broken! %d\n", OS_GetStackStatus( &s_thread ) ); - } - - return; - + + SYSM_SetLoadSucceeded(TRUE); + + // ここでスタック壊れていないかチェック + if( OS_STACK_NO_ERROR != OS_GetStackStatus( &s_thread ) ) + { + OS_TPrintf("RebootSystem warning: stack was broken!\n"); + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "SYSMi_LoadTitleThreadFunc: stack was broken! %d\n", OS_GetStackStatus( &s_thread ) ); + } + + return; + ERROR: - if(!isCardApp) - { + if(!isCardApp) + { (void)FS_CloseFile(file); } - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "SYSMi_LoadTitleThreadFunc: some error has occurred.\n"); + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "SYSMi_LoadTitleThreadFunc: some error has occurred.\n"); } // モジュール最終ロード先領域のうち、現在空いている場所をクリア #define CLEAR_LIST_LENGTH (8 + 1 + RELOCATE_INFO_NUM * 2) static void SYSMi_ClearRomLoadSegment( ROM_Header_Short *rhs ) { - int l; - u32 twl_clear_list[CLEAR_LIST_LENGTH] = { - SYSM_TWL_ARM9_LOAD_MMEM, SYSM_TWL_ARM9_LOAD_MMEM_END, - SYSM_TWL_ARM7_LOAD_MMEM, SYSM_TWL_ARM7_LOAD_MMEM_END, - SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END, - SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END, - NULL, - }; - u32 nitro_clear_list[CLEAR_LIST_LENGTH] = { - SYSM_NTR_ARM9_LOAD_MMEM, SYSM_NTR_ARM9_LOAD_MMEM_END, - SYSM_NTR_ARM7_LOAD_MMEM, SYSM_NTR_ARM7_LOAD_MMEM_END, - SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END, - SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END, - NULL, - }; - u32 *clear_list; - u32 length[RELOCATE_INFO_NUM]; - u32 dataExistAddr[RELOCATE_INFO_NUM]; - + int l; + u32 twl_clear_list[CLEAR_LIST_LENGTH] = { + SYSM_TWL_ARM9_LOAD_MMEM, SYSM_TWL_ARM9_LOAD_MMEM_END, + SYSM_TWL_ARM7_LOAD_MMEM, SYSM_TWL_ARM7_LOAD_MMEM_END, + SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END, + SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END, + NULL, + }; + u32 nitro_clear_list[CLEAR_LIST_LENGTH] = { + SYSM_NTR_ARM9_LOAD_MMEM, SYSM_NTR_ARM9_LOAD_MMEM_END, + SYSM_NTR_ARM7_LOAD_MMEM, SYSM_NTR_ARM7_LOAD_MMEM_END, + SYSM_TWL_ARM9_LTD_LOAD_MMEM, SYSM_TWL_ARM9_LTD_LOAD_MMEM_END, + SYSM_TWL_ARM7_LTD_LOAD_MMEM, SYSM_TWL_ARM7_LTD_LOAD_MMEM_END, + NULL, + }; + u32 *clear_list; + u32 length[RELOCATE_INFO_NUM]; + u32 dataExistAddr[RELOCATE_INFO_NUM]; + length [0] = rhs->main_size; dataExistAddr[0] = (u32)rhs->main_ram_address; - + length [1] = rhs->sub_size; dataExistAddr[1] = (u32)rhs->sub_ram_address; - - if( !(rhs->platform_code & PLATFORM_CODE_FLAG_TWL) ) - { - clear_list = nitro_clear_list; - } - else - { - clear_list = twl_clear_list; + + if( !(rhs->platform_code & PLATFORM_CODE_FLAG_TWL) ) + { + clear_list = nitro_clear_list; + } + else + { + clear_list = twl_clear_list; length [2] = rhs->main_ltd_size; dataExistAddr[2] = (u32)rhs->main_ltd_ram_address; length [3] = rhs->sub_ltd_size; dataExistAddr[3] = (u32)rhs->sub_ltd_ram_address; - } + } - for( l=0; lplatform_code & PLATFORM_CODE_FLAG_TWL) && l==2 ) - { - break; - } - // 再配置情報があればそちらの情報を取得 - if( SYSMi_GetWork()->romRelocateInfo[l].src != NULL ) - { - length[l] = SYSMi_GetWork()->romRelocateInfo[l].length; - dataExistAddr[l] = SYSMi_GetWork()->romRelocateInfo[l].src; - } - - // 領域の切り取り - SYSMi_CutAwayRegionList( clear_list, dataExistAddr[l], dataExistAddr[l] + length[l] ); - } - - // リストに従って消す - for( l=0; lplatform_code & PLATFORM_CODE_FLAG_TWL) && l==2 ) + { + break; + } + // 再配置情報があればそちらの情報を取得 + if( SYSMi_GetWork()->romRelocateInfo[l].src != NULL ) + { + length[l] = SYSMi_GetWork()->romRelocateInfo[l].length; + dataExistAddr[l] = SYSMi_GetWork()->romRelocateInfo[l].src; + } + + // 領域の切り取り + SYSMi_CutAwayRegionList( clear_list, dataExistAddr[l], dataExistAddr[l] + length[l] ); + } + + // リストに従って消す + for( l=0; ltitleID & TITLE_ID_DATA_ONLY_FLAG_MASK ) - { - OS_TPrintf("SYSM_StartLoadTitle failed: This App has Data_Only flag.\n"); - return; - } - - // 最後、カード抜き挿しが発生してからSYSM_GetCardTitleListが呼ばれていない状態 - // (画面表示やリストに変更が通知されていない)だったらFATAL - // ただし、カード起動のときのみ - if( SYSMi_GetWork()->flags.hotsw.isCardStateChanged && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) - { - UTL_SetFatalError(FATAL_ERROR_EJECT_CARD_AFTER_LOAD_START); - } - - s_loadstart = TRUE; - s_loadTimes++; // ロード回数のチェック用、二回目以降は非対応の実装なので - - // このあとCardRomヘッダバッファにROMヘッダを上書きで読み込むので - // この時点でHotSWが止まっていないと、さらにカードのROMヘッダ - // を上書きしてしまう可能性がある + static u64 stack[ STACK_SIZE / sizeof(u64) ]; - // アプリ未ロード状態なら、ロード開始 - if( !pBootTitle->flags.isAppLoadCompleted ) { - SYSM_SetLoadFinished(FALSE); - SYSM_SetLoadSucceeded(FALSE); - OS_InitThread(); - OS_CreateThread( &s_thread, (void (*)(void *))SYSMi_LoadTitleThreadFunc, (void*)pBootTitle, stack+STACK_SIZE/sizeof(u64), STACK_SIZE,THREAD_PRIO ); - OS_WakeupThreadDirect( &s_thread ); + HOTSW_InvalidHotSWAsync(); + // 値が変化するまでスリープして待つ。 + while( HOTSW_isEnableHotSW() != FALSE ) { + OS_Sleep( 2 ); + } - }else { - // アプリロード済み - SYSM_SetLoadSucceeded(TRUE); - SYSM_SetLoadFinished(TRUE); - } - - if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) { - SYSM_SetCardBoot(TRUE); - }else if(pBootTitle->flags.isAppLoadCompleted) - { - // カードブートでなく、ロード済みの場合は今のところ何もしない - } + // DataOnlyなアプリはロードも起動もしない + if( pBootTitle->titleID & TITLE_ID_DATA_ONLY_FLAG_MASK ) + { + OS_TPrintf("SYSM_StartLoadTitle failed: This App has Data_Only flag.\n"); + return; + } + + // 最後、カード抜き挿しが発生してからSYSM_GetCardTitleListが呼ばれていない状態 + // (画面表示やリストに変更が通知されていない)だったらFATAL + // ただし、カード起動のときのみ + if( SYSMi_GetWork()->flags.hotsw.isCardStateChanged && pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) + { + UTL_SetFatalError(FATAL_ERROR_EJECT_CARD_AFTER_LOAD_START); + } + + s_loadstart = TRUE; + s_loadTimes++; // ロード回数のチェック用、二回目以降は非対応の実装なので + + // このあとCardRomヘッダバッファにROMヘッダを上書きで読み込むので + // この時点でHotSWが止まっていないと、さらにカードのROMヘッダ + // を上書きしてしまう可能性がある + + // アプリ未ロード状態なら、ロード開始 + if( !pBootTitle->flags.isAppLoadCompleted ) { + SYSM_SetLoadFinished(FALSE); + SYSM_SetLoadSucceeded(FALSE); + OS_InitThread(); + OS_CreateThread( &s_thread, (void (*)(void *))SYSMi_LoadTitleThreadFunc, (void*)pBootTitle, stack+STACK_SIZE/sizeof(u64), STACK_SIZE,THREAD_PRIO ); + OS_WakeupThreadDirect( &s_thread ); + + }else { + // アプリロード済み + SYSM_SetLoadSucceeded(TRUE); + SYSM_SetLoadFinished(TRUE); + } + + if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) { + SYSM_SetCardBoot(TRUE); + }else if(pBootTitle->flags.isAppLoadCompleted) + { + // カードブートでなく、ロード済みの場合は今のところ何もしない + } } // アプリロード済みかどうかをチェック BOOL SYSM_IsLoadTitleFinished( void ) { - // ロード済みの時は、常にTRUE - if( !SYSMi_GetWork()->flags.arm9.isLoadFinished ) { - // ロードスレッドの完了をチェック。 - SYSM_SetLoadFinished(OS_IsThreadTerminated( &s_thread )); - } - return SYSMi_GetWork()->flags.arm9.isLoadFinished ? TRUE : FALSE; + // ロード済みの時は、常にTRUE + if( !SYSMi_GetWork()->flags.arm9.isLoadFinished ) { + // ロードスレッドの完了をチェック。 + SYSM_SetLoadFinished(OS_IsThreadTerminated( &s_thread )); + } + return SYSMi_GetWork()->flags.arm9.isLoadFinished ? TRUE : FALSE; } @@ -1047,67 +1179,67 @@ BOOL SYSM_IsLoadTitleFinished( void ) // 署名つきアプリ(≠DSダウンロードアプリ署名)共通のヘッダ認証処理 static BOOL SYSMi_AuthenticateHeaderWithSign( TitleProperty *pBootTitle, ROM_Header *head ) { - // 署名処理 - const u8 *key; - u32 hi; - u8 keynum; - SignatureData sigbuf; - SVCSignHeapContext con; - char *gamecode = (char *)&(pBootTitle->titleID); - OSTick start,prev; - start = OS_GetTick(); - - prev = OS_GetTick(); - hi = head->s.titleID_Hi; - // Launcherは専用の鍵を使う - if( ( 0 == STD_CompareNString( &gamecode[1], "ANH", 3 ) ) + // 署名処理 + const u8 *key; + u32 hi; + u8 keynum; + SignatureData sigbuf; + SVCSignHeapContext con; + char *gamecode = (char *)&(pBootTitle->titleID); + OSTick start,prev; + start = OS_GetTick(); + + prev = OS_GetTick(); + hi = head->s.titleID_Hi; + // Launcherは専用の鍵を使う + if( ( 0 == STD_CompareNString( &gamecode[1], "ANH", 3 ) ) #ifdef DEV_UIG_LAUNCHER - || ( ( 0 == STD_CompareNString( &gamecode[1], "AN4", 3 ) ) && ( SCFG_GetBondingOption() != 0 ) ) + || ( ( 0 == STD_CompareNString( &gamecode[1], "AN4", 3 ) ) && ( SCFG_GetBondingOption() != 0 ) ) #endif - ) - { - keynum = LAUNCHER_KEY_INDEX; - }else - { - // keynum = 1:SystemApp 2:SecureApp 3:UserApp - keynum = (u8)( (hi & TITLE_ID_HI_SECURE_FLAG_MASK) ? SECURE_APP_KEY_INDEX - : ( (hi & TITLE_ID_HI_APP_TYPE_MASK) ? SYSTEM_APP_KEY_INDEX : USER_APP_KEY_INDEX ) - ); - } - - // アプリ種別とボンディングオプションによって使う鍵を分ける + ) + { + keynum = LAUNCHER_KEY_INDEX; + }else + { + // keynum = 1:SystemApp 2:SecureApp 3:UserApp + keynum = (u8)( (hi & TITLE_ID_HI_SECURE_FLAG_MASK) ? SECURE_APP_KEY_INDEX + : ( (hi & TITLE_ID_HI_APP_TYPE_MASK) ? SYSTEM_APP_KEY_INDEX : USER_APP_KEY_INDEX ) + ); + } + + // アプリ種別とボンディングオプションによって使う鍵を分ける //#define LNC_PDTKEY_DBG #ifdef LNC_PDTKEY_DBG - { - // 注:デバグ用コード。 - // 開発用TSボードで開発版ROMおよび製品版ROMの署名チェックとAESデクリプトをデバグするためのコード - if( head->s.developer_encrypt_old || head->s.exFlags.developer_encrypt ) - { - // 開発版鍵取得 - key = g_devPubKey[keynum]; - }else - { - // 製品版鍵取得 - key = ((OSFromFirm9Buf *)HW_FIRM_FROM_FIRM_BUF)->rsa_pubkey[keynum]; - } - // デバッガが有効でTLF読み込みならば、ハッシュチェックスルーフラグを立てる - if( SYSM_IsRunOnDebugger() && SYSMi_GetWork()->romEmuInfo.isTlfRom ) - { - s_b_dev = TRUE; - } - } + { + // 注:デバグ用コード。 + // 開発用TSボードで開発版ROMおよび製品版ROMの署名チェックとAESデクリプトをデバグするためのコード + if( head->s.developer_encrypt_old || head->s.exFlags.developer_encrypt ) + { + // 開発版鍵取得 + key = g_devPubKey[keynum]; + }else + { + // 製品版鍵取得 + key = ((OSFromFirm9Buf *)HW_FIRM_FROM_FIRM_BUF)->rsa_pubkey[keynum]; + } + // デバッガが有効でTLF読み込みならば、ハッシュチェックスルーフラグを立てる + if( SYSM_IsRunOnDebugger() && SYSMi_GetWork()->romEmuInfo.isTlfRom ) + { + s_b_dev = TRUE; + } + } #else if( SCFG_GetBondingOption() == 0 ) { - // 製品版鍵取得 - key = ((OSFromFirm9Buf *)HW_FIRM_FROM_FIRM_BUF)->rsa_pubkey[keynum]; + // 製品版鍵取得 + key = ((OSFromFirm9Buf *)HW_FIRM_FROM_FIRM_BUF)->rsa_pubkey[keynum]; }else { - // 開発版 - key = g_devPubKey[keynum]; - // デバッガが有効でTLF読み込みならば、ハッシュチェックスルーフラグを立てる - if( SYSM_IsRunOnDebugger() && SYSMi_GetWork()->romEmuInfo.isTlfRom ) - { - s_b_dev = TRUE; - } + // 開発版 + key = g_devPubKey[keynum]; + // デバッガが有効でTLF読み込みならば、ハッシュチェックスルーフラグを立てる + if( SYSM_IsRunOnDebugger() && SYSMi_GetWork()->romEmuInfo.isTlfRom ) + { + s_b_dev = TRUE; + } } #endif // 署名を鍵で復号 @@ -1115,605 +1247,716 @@ static BOOL SYSMi_AuthenticateHeaderWithSign( TitleProperty *pBootTitle, ROM_Hea SVC_InitSignHeap( &con, (void *)SIGN_HEAP_ADDR, SIGN_HEAP_SIZE );// ヒープの初期化 if( !SVC_DecryptSign( &con, sigbuf.digest, head->signature, key )) { - OS_TPrintf("Authenticate_Header failed: Sign decryption failed.\n"); - if(!s_b_dev) { - UTL_SetFatalError(FATAL_ERROR_SIGN_DECRYPTION_FAILED); - return FALSE; - } - } - if(s_calc_hash) - { - // 署名のハッシュ値とヘッダのハッシュ値を比較 - if(!SVC_CompareSHA1(sigbuf.digest, (const void *)&s_calc_hash[0])) - { - OS_TPrintf("Authenticate_Header failed: Sign compare failed.\n"); - if(!s_b_dev) { - UTL_SetFatalError(FATAL_ERROR_SIGN_COMPARE_FAILED); - return FALSE; - } - }else - { - OS_TPrintf("Authenticate_Header : Sign check succeed. %dms.\n", OS_TicksToMilliSeconds(OS_GetTick() - prev)); - } - }else - { - OS_TPrintf("Authenticate_Header failed: Header Hash calc failed.\n"); - if(!s_b_dev) { - UTL_SetFatalError(FATAL_ERROR_HEADER_HASH_CALC_FAILED); - return FALSE; - } - } - OS_TPrintf("Authenticate_Header : total %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - start) ); - - return TRUE; + OS_TPrintf("Authenticate_Header failed: Sign decryption failed.\n"); + if(!s_b_dev) { + UTL_SetFatalError(FATAL_ERROR_SIGN_DECRYPTION_FAILED); + return FALSE; + } + } + if(s_calc_hash) + { + // 署名のハッシュ値とヘッダのハッシュ値を比較 + if(!SVC_CompareSHA1(sigbuf.digest, (const void *)&s_calc_hash[0])) + { + OS_TPrintf("Authenticate_Header failed: Sign compare failed.\n"); + if(!s_b_dev) { + UTL_SetFatalError(FATAL_ERROR_SIGN_COMPARE_FAILED); + return FALSE; + } + }else + { + OS_TPrintf("Authenticate_Header : Sign check succeed. %dms.\n", OS_TicksToMilliSeconds(OS_GetTick() - prev)); + } + }else + { + OS_TPrintf("Authenticate_Header failed: Header Hash calc failed.\n"); + if(!s_b_dev) { + UTL_SetFatalError(FATAL_ERROR_HEADER_HASH_CALC_FAILED); + return FALSE; + } + } + OS_TPrintf("Authenticate_Header : total %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - start) ); + + return TRUE; } // TWLアプリ、NTR拡張NANDアプリ 共通のヘッダ認証処理 static BOOL SYSMi_AuthenticateTWLHeader( TitleProperty *pBootTitle, ROM_Header *head ) { - // pBootTitle->titleIDとROMヘッダのtitleIDの一致確認をする。 - // ホワイトリストマスタリングされたNTRアプリでも行う場合はSYSMi_AuthenticateTWLHeaderへ移動 - if( pBootTitle->titleID != head->s.titleID ) - { - //TWL対応ROMで、ヘッダのtitleIDが起動指定されたIDと違う - OS_TPrintf( "Authenticate_Header failed: header TitleID error\n" ); - OS_TPrintf( "Authenticate_Header failed: selectedTitleID=%.16llx\n", pBootTitle->titleID ); - OS_TPrintf( "Authenticate_Header failed: headerTitleID=%.16llx\n", head->s.titleID ); - UTL_SetFatalError(FATAL_ERROR_TITLEID_COMPARE_FAILED); - return FALSE; - }else - { - OS_TPrintf( "Authenticate_Header : header TitleID check succeed.\n" ); - } - - if( head->s.enable_signature || ( SYSM_IsRunOnDebugger() && SYSMi_GetWork()->romEmuInfo.isTlfRom)) - { - return SYSMi_AuthenticateHeaderWithSign( pBootTitle, head ); - }else - { - // 署名有効フラグが立っていない 且つ デバッガが有効でTLFを読み込んでいるのでなければFAILED - OS_TPrintf("Authenticate_Header failed: Sign check flag is OFF!\n"); - UTL_SetFatalError(FATAL_ERROR_VALID_SIGN_FLAG_OFF); - return FALSE; - } + // pBootTitle->titleIDとROMヘッダのtitleIDの一致確認をする。 + // ホワイトリストマスタリングされたNTRアプリでも行う場合はSYSMi_AuthenticateTWLHeaderへ移動 + if( pBootTitle->titleID != head->s.titleID ) + { + //TWL対応ROMで、ヘッダのtitleIDが起動指定されたIDと違う + OS_TPrintf( "Authenticate_Header failed: header TitleID error\n" ); + OS_TPrintf( "Authenticate_Header failed: selectedTitleID=%.16llx\n", pBootTitle->titleID ); + OS_TPrintf( "Authenticate_Header failed: headerTitleID=%.16llx\n", head->s.titleID ); + UTL_SetFatalError(FATAL_ERROR_TITLEID_COMPARE_FAILED); + return FALSE; + }else + { + OS_TPrintf( "Authenticate_Header : header TitleID check succeed.\n" ); + } + + if( head->s.enable_signature || ( SYSM_IsRunOnDebugger() && SYSMi_GetWork()->romEmuInfo.isTlfRom)) + { + return SYSMi_AuthenticateHeaderWithSign( pBootTitle, head ); + }else + { + // 署名有効フラグが立っていない 且つ デバッガが有効でTLFを読み込んでいるのでなければFAILED + OS_TPrintf("Authenticate_Header failed: Sign check flag is OFF!\n"); + UTL_SetFatalError(FATAL_ERROR_VALID_SIGN_FLAG_OFF); + return FALSE; + } } static s32 s_nam_error = NAM_OK; s32 SYSMi_getCheckTitleLaunchRightsResult( void ) { - return s_nam_error; + return s_nam_error; } // TWLアプリ、NTR拡張NANDアプリ 共通の認証 static BOOL SYSMi_AuthenticateTWLTitle( TitleProperty *pBootTitle ) { - ROM_Header *head; - OSTick start,prev; - start = OS_GetTick(); - - head = ( ROM_Header *)SYSM_APP_ROM_HEADER_BUF; - - // NANDアプリの場合、NAM_CheckTitleLaunchRights()を呼んでチェック - if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND ) - { - s32 result = NAM_CheckTitleLaunchRights( pBootTitle->titleID ); - if( NAM_OK != result) - { - s_nam_error = result; - OS_TPrintf("Authenticate failed: NAM_CheckTitleLaunchRights failed. %d \n",result); - UTL_SetFatalError(FATAL_ERROR_CHECK_TITLE_LAUNCH_RIGHTS_FAILED); - return FALSE; - }else - { - OS_TPrintf("Authenticate : NAM_CheckTitleLaunchRights succeed. %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - start) ); - } - } + ROM_Header *head; + OSTick start,prev; + start = OS_GetTick(); - // デバッガ動作以外の時はNANDアプリはNAND、カードアプリはカードからのみブート許可 - if ( ! SYSM_IsRunOnDebugger() ) - { - if ( ( (pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND || - pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_TEMP) && !(head->s.titleID_Hi & TITLE_ID_HI_MEDIA_MASK) ) || - (pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM && (head->s.titleID_Hi & TITLE_ID_HI_MEDIA_MASK) ) ) - { - UTL_SetFatalError(FATAL_ERROR_MEDIA_CHECK_FAILED); - return FALSE; - } - } + head = ( ROM_Header *)SYSM_APP_ROM_HEADER_BUF; - // ハッシュ比較 + // NANDアプリの場合、NAM_CheckTitleLaunchRights()を呼んでチェック + if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND ) { - int l; - u32 *module_addr[RELOCATE_INFO_NUM]; - u32 module_size[RELOCATE_INFO_NUM]; - u8 *hash_addr[RELOCATE_INFO_NUM]; - int module_num; - char *gamecode = (char *)&(pBootTitle->titleID); - - // それぞれARM9,7のFLXおよびLTDについてハッシュを計算してヘッダに格納されているハッシュと比較 - module_addr[ARM9_STATIC] = head->s.main_ram_address; - module_addr[ARM7_STATIC] = head->s.sub_ram_address; - module_size[ARM9_STATIC] = head->s.main_size; - module_size[ARM7_STATIC] = head->s.sub_size; - hash_addr[ARM9_STATIC] = &(head->s.main_static_digest[0]); - hash_addr[ARM7_STATIC] = &(head->s.sub_static_digest[0]); - module_num = 2; - - // NITROアプリの拡張では使わない領域 - if( head->s.platform_code != 0 ) - { - module_addr[ARM9_LTD_STATIC] = head->s.main_ltd_ram_address; - module_addr[ARM7_LTD_STATIC] = head->s.sub_ltd_ram_address; - module_size[ARM9_LTD_STATIC] = head->s.main_ltd_size; - module_size[ARM7_LTD_STATIC] = head->s.sub_ltd_size; - hash_addr[ARM9_LTD_STATIC] = &(head->s.main_ltd_static_digest[0]); - hash_addr[ARM7_LTD_STATIC] = &(head->s.sub_ltd_static_digest[0]); - module_num = RELOCATE_INFO_NUM; - } - - for( l=0; ltitleID ); + if( NAM_OK != result) + { + s_nam_error = result; + OS_TPrintf("Authenticate failed: NAM_CheckTitleLaunchRights failed. %d \n",result); + UTL_SetFatalError(FATAL_ERROR_CHECK_TITLE_LAUNCH_RIGHTS_FAILED); + return FALSE; + }else + { + OS_TPrintf("Authenticate : NAM_CheckTitleLaunchRights succeed. %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - start) ); + } + } - return TRUE; + // デバッガ動作以外の時はNANDアプリはNAND、カードアプリはカードからのみブート許可 + if ( ! SYSM_IsRunOnDebugger() ) + { + if ( ( (pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND || + pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_TEMP) && !(head->s.titleID_Hi & TITLE_ID_HI_MEDIA_MASK) ) || + (pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM && (head->s.titleID_Hi & TITLE_ID_HI_MEDIA_MASK) ) ) + { + UTL_SetFatalError(FATAL_ERROR_MEDIA_CHECK_FAILED); + return FALSE; + } + } + + // ハッシュ比較 + { + int l; + u32 *module_addr[RELOCATE_INFO_NUM]; + u32 module_size[RELOCATE_INFO_NUM]; + u8 *hash_addr[RELOCATE_INFO_NUM]; + int module_num; + char *gamecode = (char *)&(pBootTitle->titleID); + + // それぞれARM9,7のFLXおよびLTDについてハッシュを計算してヘッダに格納されているハッシュと比較 + module_addr[ARM9_STATIC] = head->s.main_ram_address; + module_addr[ARM7_STATIC] = head->s.sub_ram_address; + module_size[ARM9_STATIC] = head->s.main_size; + module_size[ARM7_STATIC] = head->s.sub_size; + hash_addr[ARM9_STATIC] = &(head->s.main_static_digest[0]); + hash_addr[ARM7_STATIC] = &(head->s.sub_static_digest[0]); + module_num = 2; + + // NITROアプリの拡張では使わない領域 + if( head->s.platform_code != 0 ) + { + module_addr[ARM9_LTD_STATIC] = head->s.main_ltd_ram_address; + module_addr[ARM7_LTD_STATIC] = head->s.sub_ltd_ram_address; + module_size[ARM9_LTD_STATIC] = head->s.main_ltd_size; + module_size[ARM7_LTD_STATIC] = head->s.sub_ltd_size; + hash_addr[ARM9_LTD_STATIC] = &(head->s.main_ltd_static_digest[0]); + hash_addr[ARM7_LTD_STATIC] = &(head->s.sub_ltd_static_digest[0]); + module_num = RELOCATE_INFO_NUM; + } + + for( l=0; ltitleIDとROMヘッダのゲームコードの一致確認をする。 - ntr_fake_titleID = (u64)( ( head->s.game_code[ 3 ] << 0 ) | - ( head->s.game_code[ 2 ] << 8 ) | - ( head->s.game_code[ 1 ] << 16 ) | - ( head->s.game_code[ 0 ] << 24 ) ); - if( pBootTitle->titleID != ntr_fake_titleID ) - { - // ヘッダから作成した擬似titleIDが起動指定されたタイトルに格納されている擬似IDと違う - OS_TPrintf( "SYSMi_AuthenticateNTRCardAppHeader failed: header TitleID error\n" ); - OS_TPrintf( "SYSMi_AuthenticateNTRCardAppHeader failed: selectedTitleID=%.16llx\n", pBootTitle->titleID ); - OS_TPrintf( "SYSMi_AuthenticateNTRCardAppHeader failed: headerTitleID=%.16llx\n", ntr_fake_titleID ); - UTL_SetFatalError(FATAL_ERROR_TITLEID_COMPARE_FAILED_NTR); - return FALSE; - }else - { - OS_TPrintf( "Authenticate_Header : header TitleID check succeed.\n" ); - } - - if( head->s.exFlags.enable_nitro_whitelist_signature ) - { - // マスタリング済みNTRカードアプリの署名チェック(実はTWLアプリと同じ) - ret = SYSMi_AuthenticateHeaderWithSign( pBootTitle, head ); - if( ret == TRUE ) - { - hash0 = head->s.nitro_whitelist_phase1_digest; - hash1 = head->s.nitro_whitelist_phase2_diegst; - } - }else - { - // ホワイトリスト検索 - const DHTDatabase* db; - PrepareDHTDatabase();// 60msくらいなので、ここでやってしまってOKとする。 - if(!dht) - { - OS_TPrintf(" Search DHT : database init Failed.\n"); - if(!s_b_dev) - { - UTL_SetFatalError(FATAL_ERROR_WHITELIST_INITDB_FAILED); - ret = FALSE; - } - }else - { - OS_TPrintf("Searching DHT for %.4s(%02X)...", head->s.game_code, head->s.rom_version); - db = DHT_GetDatabase(dht, &head->s); - if ( !db ) - { - OS_TPrintf(" Search DHT : Failed.\n"); - if(!s_b_dev) - { - UTL_SetFatalError(FATAL_ERROR_WHITELIST_NOTFOUND); - ret = FALSE; - } - }else - { - hash0 = db->hash[0]; - hash1 = db->hash[1]; - ret = TRUE; - } - } - } - - return ret; + // pBootTitle->titleIDとROMヘッダのゲームコードの一致確認をする。 + ntr_fake_titleID = (u64)( ( head->s.game_code[ 3 ] << 0 ) | + ( head->s.game_code[ 2 ] << 8 ) | + ( head->s.game_code[ 1 ] << 16 ) | + ( head->s.game_code[ 0 ] << 24 ) ); + if( pBootTitle->titleID != ntr_fake_titleID ) + { + // ヘッダから作成した擬似titleIDが起動指定されたタイトルに格納されている擬似IDと違う + OS_TPrintf( "SYSMi_AuthenticateNTRCardAppHeader failed: header TitleID error\n" ); + OS_TPrintf( "SYSMi_AuthenticateNTRCardAppHeader failed: selectedTitleID=%.16llx\n", pBootTitle->titleID ); + OS_TPrintf( "SYSMi_AuthenticateNTRCardAppHeader failed: headerTitleID=%.16llx\n", ntr_fake_titleID ); + UTL_SetFatalError(FATAL_ERROR_TITLEID_COMPARE_FAILED_NTR); + return FALSE; + }else + { + OS_TPrintf( "Authenticate_Header : header TitleID check succeed.\n" ); + } + + // phase 4があるので常に読み込む + if ( !PrepareDHTDatabase() ) + { + OS_TPrintf(" SYSMi_AuthenticateNTRCardAppHeader failed : database init error.\n"); + if(!s_b_dev) + { + UTL_SetFatalError(FATAL_ERROR_WHITELIST_INITDB_FAILED); + return FALSE; + } + } + // マスタリングの有無 + if( head->s.exFlags.enable_nitro_whitelist_signature ) + { + // マスタリング済みNTRカードアプリの署名チェック(実はTWLアプリと同じ) + ret = SYSMi_AuthenticateHeaderWithSign( pBootTitle, head ); + if( ret == TRUE ) + { + s_dht.hash1 = head->s.nitro_whitelist_phase1_digest; + s_dht.hash2 = head->s.nitro_whitelist_phase2_diegst; + // 新マスタリングの有無 + if( head->s.exFlags.enable_nitro_extra_whitelist ) + { + s_dht.hash3 = head->s.banner_digest; + } + } + }else + { + // ホワイトリスト検索 + const DHTDatabase* db; + if(!s_dht.dht) + { + OS_TPrintf(" Search DHT : database init Failed.\n"); + if(!s_b_dev) + { + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): whitelist for phase 1/2 was not loaded.\n" ); + UTL_SetFatalError(FATAL_ERROR_WHITELIST_INITDB_FAILED); + ret = FALSE; + } + }else + { + OS_TPrintf("Searching DHT for %.4s(%02X)...", head->s.game_code, head->s.rom_version); + db = DHT_GetDatabase(s_dht.dht, &head->s); + if ( !db ) + { + OS_TPrintf(" Search DHT : Failed.\n"); + if(!s_b_dev) + { + ERRORLOG_Printf( "WHITELIST_NOTFOUND (sub info): no entry for phase 1/2.\n" ); + UTL_SetFatalError(FATAL_ERROR_WHITELIST_NOTFOUND); + ret = FALSE; + } + }else + { + s_dht.hash1 = db->hash[0]; + s_dht.hash2 = db->hash[1]; + ret = TRUE; + } + } + } + // ROMヘッダにバナーハッシュがない (マスタリング自体とは別枠) + if( !s_dht.hash3 ) + { + // 拡張ホワイトリスト検索 + const DHTDatabaseEx* db; + if(!s_dht.dhtex) + { + OS_TPrintf(" Search DHT Ex: database init Failed.\n"); + if(!s_b_dev) + { +#ifndef SYSM_IGNORE_DHT_EX_NOT_FOUND + ERRORLOG_Printf( "WHITELIST_INITDB_FAILED (sub info): whitelist for phase 3 was not loaded.\n" ); + UTL_SetFatalError(FATAL_ERROR_WHITELIST_INITDB_FAILED); + ret = FALSE; +#endif + } + }else + { + OS_TPrintf("Searching DHT Ex for %.4s(%02X)...", head->s.game_code, head->s.rom_version); + db = DHT_GetDatabaseEx(s_dht.dhtex, &head->s); + if ( !db ) + { + OS_TPrintf(" Search DHT Ex: Failed.\n"); + if(!s_b_dev) + { + ERRORLOG_Printf( "WHITELIST_NOTFOUND (sub info): no entry for phase 3.\n" ); + UTL_SetFatalError(FATAL_ERROR_WHITELIST_NOTFOUND); + ret = FALSE; + } + }else + { + s_dht.hash3 = db->banner_hash; + ret = TRUE; + } + } + } + return ret; } // NTR版カードアプリの認証 static BOOL SYSMi_AuthenticateNTRCardTitle( TitleProperty *pBootTitle) { #pragma unused(pBootTitle) - DHTPhase2Work* p2work = NULL; - ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; + DHTPhase2Work* p2work = NULL; + ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; - // phase1最終検証 - if(s_calc_hash) - { - // アプリをロードする時に計算したハッシュを検証 - if( !hash0 || !SVC_CompareSHA1( (const void *)hash0, (const void *)&s_calc_hash[1 * SVC_SHA1_DIGEST_SIZE] ) ) - { - OS_TPrintf("DHT Phase1 failed: hash check failed.\n"); - if(!s_b_dev) { - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "DHT_PAHSE1_FAILED (sub info): hash0Addr-%08x\n", hash0 ); - if(hash0) - { - ERRORLOG_Printf( "DHT_PAHSE1_FAILED (sub info): hash0 - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", - hash0[0], hash0[1], hash0[2], hash0[3], hash0[4], hash0[5], hash0[6], hash0[7], hash0[8], hash0[9], - hash0[10], hash0[11], hash0[12], hash0[13], hash0[14], hash0[15], hash0[16], hash0[17], hash0[18], hash0[19]); - ERRORLOG_Printf( "DHT_PAHSE1_FAILED (sub info): calc_hash - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", - s_calc_hash[0], s_calc_hash[1], s_calc_hash[2], s_calc_hash[3], s_calc_hash[4], - s_calc_hash[5], s_calc_hash[6], s_calc_hash[7], s_calc_hash[8], s_calc_hash[9], - s_calc_hash[10], s_calc_hash[11], s_calc_hash[12], s_calc_hash[13], s_calc_hash[14], - s_calc_hash[15], s_calc_hash[16], s_calc_hash[17], s_calc_hash[18], s_calc_hash[19]); - } - UTL_SetFatalError(FATAL_ERROR_DHT_PHASE1_FAILED); - return FALSE; - } - }else - { - OS_TPrintf("DHT Phase1 : hash check succeed..\n"); - } - }else - { - OS_TPrintf("DHT Phase1 failed: hash calc failed.\n"); - if(!s_b_dev) { - UTL_SetFatalError(FATAL_ERROR_DHT_PHASE1_CALC_FAILED); - return FALSE; - } - } - - // DHTチェックphase2 - OS_TPrintf("DHT Phase2..."); - p2work = SYSM_Alloc( sizeof(DHTPhase2Work) ); - if ( !p2work || !hash1 || !DHT_CheckHashPhase2(hash1, hs, p2work, WrapperFunc_ReadCardData, NULL) ) - { - OS_TPrintf(" DHT Phase2 : Failed.\n"); - if(!s_b_dev){ - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "DHT_PAHSE2_FAILED (sub info): p2workAddr-%08x hash1Addr-%08x\n", p2work, hash1 ); - if( p2work ) SYSM_Free(p2work); - UTL_SetFatalError(FATAL_ERROR_DHT_PHASE2_FAILED); - return FALSE; - } - } - if( p2work ) SYSM_Free(p2work); + // DHTチェックphase1 + if(s_calc_hash) + { + // アプリをロードする時に計算したハッシュを検証 + if( !s_dht.hash1 || !SVC_CompareSHA1( (const void *)s_dht.hash1, (const void *)&s_calc_hash[1 * SVC_SHA1_DIGEST_SIZE] ) ) + { + OS_TPrintf("DHT Phase1 failed: hash check failed.\n"); + if(!s_b_dev) { + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "DHT_PAHSE1_FAILED (sub info): hash1Addr-%08x\n", s_dht.hash1 ); + if(s_dht.hash1) + { + ERRORLOG_Printf( "DHT_PAHSE1_FAILED (sub info): hash1 - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + s_dht.hash1[0], s_dht.hash1[1], s_dht.hash1[2], s_dht.hash1[3], s_dht.hash1[4], + s_dht.hash1[5], s_dht.hash1[6], s_dht.hash1[7], s_dht.hash1[8], s_dht.hash1[9], + s_dht.hash1[10], s_dht.hash1[11], s_dht.hash1[12], s_dht.hash1[13], s_dht.hash1[14], + s_dht.hash1[15], s_dht.hash1[16], s_dht.hash1[17], s_dht.hash1[18], s_dht.hash1[19]); + ERRORLOG_Printf( "DHT_PAHSE1_FAILED (sub info): calc_hash - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + s_calc_hash[0], s_calc_hash[1], s_calc_hash[2], s_calc_hash[3], s_calc_hash[4], + s_calc_hash[5], s_calc_hash[6], s_calc_hash[7], s_calc_hash[8], s_calc_hash[9], + s_calc_hash[10], s_calc_hash[11], s_calc_hash[12], s_calc_hash[13], s_calc_hash[14], + s_calc_hash[15], s_calc_hash[16], s_calc_hash[17], s_calc_hash[18], s_calc_hash[19]); + } + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE1_FAILED); + return FALSE; + } + }else + { + OS_TPrintf("DHT Phase1 : hash check succeed..\n"); + } + }else + { + OS_TPrintf("DHT Phase1 failed: hash calc failed.\n"); + if(!s_b_dev) { + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE1_CALC_FAILED); + return FALSE; + } + } - return TRUE; + // DHTチェックphase2 + OS_TPrintf("DHT Phase2..."); + p2work = SYSM_Alloc( sizeof(DHTPhase2Work) ); + if ( !p2work ) + { + OS_TPrintf(" Cannot allocate DHT work area.\n"); + if (!s_b_dev){ + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "DHT_PAHSE2_FAILED (sub info): p2workAddr-%08x hash2Addr-%08x\n", p2work, s_dht.hash2 ); + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE2_FAILED); + return FALSE; + } + return TRUE; + } + if ( !s_dht.hash2 || !DHT_CheckHashPhase2(s_dht.hash2, hs, p2work, WrapperFunc_ReadCardData, NULL) ) + { + OS_TPrintf(" DHT Phase2 : Failed.\n"); + if(!s_b_dev){ + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "DHT_PAHSE2_FAILED (sub info): p2workAddr-%08x hash2Addr-%08x\n", p2work, s_dht.hash2 ); + SYSM_Free(p2work); + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE2_FAILED); + return FALSE; + } + } + + // DHTチェックphase3 (バナーチェック) + OS_TPrintf("DHT Phase3..."); + if ( !s_dht.hash3 || !DHT_CheckHashPhase3(s_dht.hash3, (NTRBannerFile*)&s_card_bannerBuf) ) + { + OS_TPrintf(" DHT Phase3 : Failed.\n"); + if(!s_b_dev){ + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "DHT_PAHSE3_FAILED (sub info): hash3Addr-%08x\n", s_dht.hash3 ); +#ifndef SYSM_IGNORE_DHT_EX_NOT_FOUND +#ifndef SYSM_IGNORE_DHT_PHASE_3 + SYSM_Free(p2work); + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE3_FAILED); + return FALSE; +#endif +#endif + } + } + + // DHTチェックphase4 (個別チェック) + OS_TPrintf("DHT Phase4..."); + if ( !s_dht.dhtah ) + { + OS_TPrintf(" DHT Phase4 : No database.\n"); + if(!s_b_dev){ + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "DHT_PAHSE4_FAILED (sub info): no database\n" ); +#ifndef SYSM_IGNORE_DHT_EX_NOT_FOUND + SYSM_Free(p2work); + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE4_FAILED); + return FALSE; +#endif + } + } + else if ( !DHT_CheckHashPhase4(s_dht.dhtah, hs, (DHTPhase4Work*)p2work, WrapperFunc_ReadCardData, NULL) ) + { + OS_TPrintf(" DHT Phase4 : Failed.\n"); + if(!s_b_dev){ + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "DHT_PAHSE4_FAILED (sub info): p2workAddr-%08x\n", p2work ); + SYSM_Free(p2work); + UTL_SetFatalError(FATAL_ERROR_DHT_PHASE4_FAILED); + return FALSE; + } + } + + SYSM_Free(p2work); + + return TRUE; } // ヘッダ認証 static BOOL SYSMi_AuthenticateHeader( TitleProperty *pBootTitle, ROM_Header *head ) { - ROM_Header_Short *hs = ( ROM_Header_Short *)head; - if( hs->platform_code & PLATFORM_CODE_FLAG_TWL ) - { - // TWLアプリ - // 認証処理 - switch( pBootTitle->flags.bootType ) - { - case LAUNCHER_BOOTTYPE_NAND: - OS_TPrintf( "Authenticate_Header :TWL_NAND start.\n" ); - return SYSMi_AuthenticateTWLHeader( pBootTitle, head ); - case LAUNCHER_BOOTTYPE_ROM: - OS_TPrintf( "Authenticate_Header :TWL_ROM start.\n" ); - return SYSMi_AuthenticateTWLHeader( pBootTitle, head ); - case LAUNCHER_BOOTTYPE_TEMP: - OS_TPrintf( "Authenticate_Header :TWL_TEMP start.\n" ); - if (!hs->permit_landing_tmp_jump) - { - OS_TPrintf("Authenticate failed: TMP flag error.\n"); - UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); - return FALSE; - } - return SYSMi_AuthenticateTWLHeader( pBootTitle, head ); - default: - UTL_SetFatalError(FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN); - return FALSE; - } - } - else - { - if( hs->platform_code & PLATFORM_CODE_FLAG_NOT_NTR ) - { - // TWLでもNTRでもない不正なアプリ - OS_TPrintf( "Authenticate_Header failed :NOT NTR NOT TWL.\n" ); - UTL_SetFatalError(FATAL_ERROR_PLATFORM_UNKNOWN); - return FALSE; - } - // NTRアプリ - switch( pBootTitle->flags.bootType ) - { - case LAUNCHER_BOOTTYPE_NAND: - OS_TPrintf( "Authenticate_Header :NTR_NAND start.\n" ); - return SYSMi_AuthenticateNTRNandAppHeader( pBootTitle, head ); - case LAUNCHER_BOOTTYPE_TEMP: - OS_TPrintf( "Authenticate_Header :NTR_TEMP start.\n" ); - if (!hs->permit_landing_tmp_jump) - { - OS_TPrintf("Authenticate_Header failed : TMP flag error.\n"); - UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); - return FALSE; - } - return SYSMi_AuthenticateNTRDownloadAppHeader( pBootTitle, head ); - case LAUNCHER_BOOTTYPE_ROM: - OS_TPrintf( "Authenticate_Header :NTR_ROM start.\n" ); - return SYSMi_AuthenticateNTRCardAppHeader( pBootTitle, head ); - default: - UTL_SetFatalError(FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN); - return FALSE; - } - } + ROM_Header_Short *hs = ( ROM_Header_Short *)head; + if( hs->platform_code & PLATFORM_CODE_FLAG_TWL ) + { + // TWLアプリ + // 認証処理 + switch( pBootTitle->flags.bootType ) + { + case LAUNCHER_BOOTTYPE_NAND: + OS_TPrintf( "Authenticate_Header :TWL_NAND start.\n" ); + return SYSMi_AuthenticateTWLHeader( pBootTitle, head ); + case LAUNCHER_BOOTTYPE_ROM: + OS_TPrintf( "Authenticate_Header :TWL_ROM start.\n" ); + return SYSMi_AuthenticateTWLHeader( pBootTitle, head ); + case LAUNCHER_BOOTTYPE_TEMP: + OS_TPrintf( "Authenticate_Header :TWL_TEMP start.\n" ); + if (!hs->permit_landing_tmp_jump) + { + OS_TPrintf("Authenticate failed: TMP flag error.\n"); + UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); + return FALSE; + } + return SYSMi_AuthenticateTWLHeader( pBootTitle, head ); + default: + UTL_SetFatalError(FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN); + return FALSE; + } + } + else + { + if( hs->platform_code & PLATFORM_CODE_FLAG_NOT_NTR ) + { + // TWLでもNTRでもない不正なアプリ + OS_TPrintf( "Authenticate_Header failed :NOT NTR NOT TWL.\n" ); + UTL_SetFatalError(FATAL_ERROR_PLATFORM_UNKNOWN); + return FALSE; + } + // NTRアプリ + switch( pBootTitle->flags.bootType ) + { + case LAUNCHER_BOOTTYPE_NAND: + OS_TPrintf( "Authenticate_Header :NTR_NAND start.\n" ); + return SYSMi_AuthenticateNTRNandAppHeader( pBootTitle, head ); + case LAUNCHER_BOOTTYPE_TEMP: + OS_TPrintf( "Authenticate_Header :NTR_TEMP start.\n" ); + if (!hs->permit_landing_tmp_jump) + { + OS_TPrintf("Authenticate_Header failed : TMP flag error.\n"); + UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); + return FALSE; + } + return SYSMi_AuthenticateNTRDownloadAppHeader( pBootTitle, head ); + case LAUNCHER_BOOTTYPE_ROM: + OS_TPrintf( "Authenticate_Header :NTR_ROM start.\n" ); + return SYSMi_AuthenticateNTRCardAppHeader( pBootTitle, head ); + default: + UTL_SetFatalError(FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN); + return FALSE; + } + } } // 認証 static BOOL SYSMi_AuthenticateTitleCore( TitleProperty *pBootTitle) { - ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; - if( hs->platform_code & PLATFORM_CODE_FLAG_TWL ) - { - // TWLアプリ - // 認証処理 - switch( pBootTitle->flags.bootType ) - { - case LAUNCHER_BOOTTYPE_NAND: - OS_TPrintf( "Authenticate :TWL_NAND start.\n" ); - return SYSMi_AuthenticateTWLTitle( pBootTitle ); - case LAUNCHER_BOOTTYPE_ROM: - OS_TPrintf( "Authenticate :TWL_ROM start.\n" ); - return SYSMi_AuthenticateTWLTitle( pBootTitle ); - case LAUNCHER_BOOTTYPE_TEMP: - OS_TPrintf( "Authenticate :TWL_TEMP start.\n" ); - if (!hs->permit_landing_tmp_jump) - { - OS_TPrintf("Authenticate failed: TMP flag error.\n"); - UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); - return FALSE; - } - return SYSMi_AuthenticateTWLTitle( pBootTitle ); - default: - UTL_SetFatalError(FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN); - return FALSE; - } - } - else - { - if( hs->platform_code & PLATFORM_CODE_FLAG_NOT_NTR ) - { - // TWLでもNTRでもない不正なアプリ - OS_TPrintf( "Authenticate :NOT NTR NOT TWL.\n" ); - UTL_SetFatalError(FATAL_ERROR_PLATFORM_UNKNOWN); - return FALSE; - } - // NTRアプリ - switch( pBootTitle->flags.bootType ) - { - case LAUNCHER_BOOTTYPE_NAND: - OS_TPrintf( "Authenticate :NTR_NAND start.\n" ); - return SYSMi_AuthenticateNTRNandTitle( pBootTitle ); - case LAUNCHER_BOOTTYPE_TEMP: - OS_TPrintf( "Authenticate :NTR_TEMP start.\n" ); - if (!hs->permit_landing_tmp_jump) - { - OS_TPrintf("Authenticate failed: TMP flag error.\n"); - UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); - return FALSE; - } - return SYSMi_AuthenticateNTRDownloadTitle( pBootTitle ); - case LAUNCHER_BOOTTYPE_ROM: - OS_TPrintf( "Authenticate :NTR_ROM start.\n" ); - return SYSMi_AuthenticateNTRCardTitle( pBootTitle ); - default: - UTL_SetFatalError(FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN); - return FALSE; - } - } + ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; + if( hs->platform_code & PLATFORM_CODE_FLAG_TWL ) + { + // TWLアプリ + // 認証処理 + switch( pBootTitle->flags.bootType ) + { + case LAUNCHER_BOOTTYPE_NAND: + OS_TPrintf( "Authenticate :TWL_NAND start.\n" ); + return SYSMi_AuthenticateTWLTitle( pBootTitle ); + case LAUNCHER_BOOTTYPE_ROM: + OS_TPrintf( "Authenticate :TWL_ROM start.\n" ); + return SYSMi_AuthenticateTWLTitle( pBootTitle ); + case LAUNCHER_BOOTTYPE_TEMP: + OS_TPrintf( "Authenticate :TWL_TEMP start.\n" ); + if (!hs->permit_landing_tmp_jump) + { + OS_TPrintf("Authenticate failed: TMP flag error.\n"); + UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); + return FALSE; + } + return SYSMi_AuthenticateTWLTitle( pBootTitle ); + default: + UTL_SetFatalError(FATAL_ERROR_TWL_BOOTTYPE_UNKNOWN); + return FALSE; + } + } + else + { + if( hs->platform_code & PLATFORM_CODE_FLAG_NOT_NTR ) + { + // TWLでもNTRでもない不正なアプリ + OS_TPrintf( "Authenticate :NOT NTR NOT TWL.\n" ); + UTL_SetFatalError(FATAL_ERROR_PLATFORM_UNKNOWN); + return FALSE; + } + // NTRアプリ + switch( pBootTitle->flags.bootType ) + { + case LAUNCHER_BOOTTYPE_NAND: + OS_TPrintf( "Authenticate :NTR_NAND start.\n" ); + return SYSMi_AuthenticateNTRNandTitle( pBootTitle ); + case LAUNCHER_BOOTTYPE_TEMP: + OS_TPrintf( "Authenticate :NTR_TEMP start.\n" ); + if (!hs->permit_landing_tmp_jump) + { + OS_TPrintf("Authenticate failed: TMP flag error.\n"); + UTL_SetFatalError(FATAL_ERROR_LANDING_TMP_JUMP_FLAG_OFF); + return FALSE; + } + return SYSMi_AuthenticateNTRDownloadTitle( pBootTitle ); + case LAUNCHER_BOOTTYPE_ROM: + OS_TPrintf( "Authenticate :NTR_ROM start.\n" ); + return SYSMi_AuthenticateNTRCardTitle( pBootTitle ); + default: + UTL_SetFatalError(FATAL_ERROR_NTR_BOOTTYPE_UNKNOWN); + return FALSE; + } + } } // 認証処理のスレッド static void SYSMi_AuthenticateTitleThreadFunc( TitleProperty *pBootTitle ) { - - // ロード開始してませんよ - if( !s_loadstart ) - { - UTL_SetFatalError(FATAL_ERROR_LOAD_NEVER_STARTED); - return; - } - - // ロード中 - if( !SYSM_IsLoadTitleFinished() ) { - UTL_SetFatalError(FATAL_ERROR_LOAD_UNFINISHED); - return; - } - // ロード成功? - if( SYSMi_GetWork()->flags.arm9.isLoadSucceeded == FALSE ) - { - UTL_SetFatalError(FATAL_ERROR_TITLE_LOAD_FAILED); - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "SYSMi_AuthenticateTitleThreadFunc: loaded %d times.\n", s_loadTimes ); - return; - } - // パラメータチェック - if( !SYSMi_CheckTitlePointer( pBootTitle ) ) { - UTL_SetFatalError(FATAL_ERROR_TITLE_POINTER_ERROR); - return; - } - // エントリアドレスの正当性をチェック - if( !SYSMi_CheckEntryAddress() ) { - UTL_SetFatalError(FATAL_ERROR_ENTRY_ADDRESS_ERROR); - return; - } - - // BOOTTYPE_MEMORYでNTRモードのFSありでブートすると、旧NitroSDKでビルドされたアプリの場合、 - // ROMアーカイブにカードが割り当てられて、FSで関係ないカードにアクセスにいってしまうので、それを防止する。 - if( ( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_MEMORY ) && - ( ( (( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF)->platform_code ) == 0 ) && - ( ( (( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF)->fat_size ) > 0 ) - ) { - UTL_SetFatalError(FATAL_ERROR_TITLE_BOOTTYPE_ERROR); - return; - } - - // 認証 - (void)SYSMi_AuthenticateTitleCore( pBootTitle ); - - // ここでスタック壊れていないかチェック - if( OS_STACK_NO_ERROR != OS_GetStackStatus( &s_auth_thread ) ) - { - OS_TPrintf("RebootSystem warning: stack was broken!\n"); - // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 - ERRORLOG_Printf( "SYSMi_AuthenticateTitleThreadFunc: stack was broken! %d\n", OS_GetStackStatus( &s_auth_thread ) ); - } + + // ロード開始してませんよ + if( !s_loadstart ) + { + UTL_SetFatalError(FATAL_ERROR_LOAD_NEVER_STARTED); + return; + } + + // ロード中 + if( !SYSM_IsLoadTitleFinished() ) { + UTL_SetFatalError(FATAL_ERROR_LOAD_UNFINISHED); + return; + } + // ロード成功? + if( SYSMi_GetWork()->flags.arm9.isLoadSucceeded == FALSE ) + { + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "SYSMi_AuthenticateTitleThreadFunc: loaded %d times.\n", s_loadTimes ); + UTL_SetFatalError(FATAL_ERROR_TITLE_LOAD_FAILED); + return; + } + // パラメータチェック + if( !SYSMi_CheckTitlePointer( pBootTitle ) ) { + UTL_SetFatalError(FATAL_ERROR_TITLE_POINTER_ERROR); + return; + } + // エントリアドレスの正当性をチェック + if( !SYSMi_CheckEntryAddress() ) { + UTL_SetFatalError(FATAL_ERROR_ENTRY_ADDRESS_ERROR); + return; + } + + // BOOTTYPE_MEMORYでNTRモードのFSありでブートすると、旧NitroSDKでビルドされたアプリの場合、 + // ROMアーカイブにカードが割り当てられて、FSで関係ないカードにアクセスにいってしまうので、それを防止する。 + if( ( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_MEMORY ) && + ( ( (( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF)->platform_code ) == 0 ) && + ( ( (( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF)->fat_size ) > 0 ) + ) { + UTL_SetFatalError(FATAL_ERROR_TITLE_BOOTTYPE_ERROR); + return; + } + + // 認証 + (void)SYSMi_AuthenticateTitleCore( pBootTitle ); + + // ここでスタック壊れていないかチェック + if( OS_STACK_NO_ERROR != OS_GetStackStatus( &s_auth_thread ) ) + { + OS_TPrintf("RebootSystem warning: stack was broken!\n"); + // デバグ用。ERRORLOG_Init()がすでに呼ばれている事前提 + ERRORLOG_Printf( "SYSMi_AuthenticateTitleThreadFunc: stack was broken! %d\n", OS_GetStackStatus( &s_auth_thread ) ); + } } @@ -1721,372 +1964,372 @@ static void SYSMi_AuthenticateTitleThreadFunc( TitleProperty *pBootTitle ) #define AUTH_STACK_SIZE 0x1400 void SYSM_StartAuthenticateTitle( TitleProperty *pBootTitle ) { - static u64 stack[ AUTH_STACK_SIZE / sizeof(u64) ]; - OS_InitThread(); - OS_CreateThread( &s_auth_thread, (void (*)(void *))SYSMi_AuthenticateTitleThreadFunc, (void*)pBootTitle, stack+AUTH_STACK_SIZE/sizeof(u64), AUTH_STACK_SIZE,THREAD_PRIO ); - OS_WakeupThreadDirect( &s_auth_thread ); - + static u64 stack[ AUTH_STACK_SIZE / sizeof(u64) ]; + OS_InitThread(); + OS_CreateThread( &s_auth_thread, (void (*)(void *))SYSMi_AuthenticateTitleThreadFunc, (void*)pBootTitle, stack+AUTH_STACK_SIZE/sizeof(u64), AUTH_STACK_SIZE,THREAD_PRIO ); + OS_WakeupThreadDirect( &s_auth_thread ); + // ROMヘッダのNintendoロゴ 正当性チェック if( !UTL_CheckNintendoLogoData((ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF) ){ - UTL_SetFatalError( FATAL_ERROR_NINTENDO_LOGO_CHECK_FAILED ); + UTL_SetFatalError( FATAL_ERROR_NINTENDO_LOGO_CHECK_FAILED ); } } // 検証済み? BOOL SYSM_IsAuthenticateTitleFinished( void ) { - return OS_IsThreadTerminated( &s_auth_thread ); + return OS_IsThreadTerminated( &s_auth_thread ); } // アプリ起動に必要なセーブファイルやSharedファイルのリカバリ static char *s_strResult[] = { - "Target file exists and file size matched.", - "File size didn't match. Changing size succeeded.", - "Target file didn't exist. Creating file and setting size succeeded.", - "ERROR: File Recovery Failed." + "Target file exists and file size matched.", + "File size didn't match. Changing size succeeded.", + "Target file didn't exist. Creating file and setting size succeeded.", + "ERROR: File Recovery Failed." }; static void SYSMi_FileRecovery( TitleProperty *pBootTitle ) { - ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; - char path[2][ FS_ENTRY_LONGNAME_MAX ]; - UTL_RecoveryStatus stat; - - // TWL非対応のときは不要なのでreturn - if ( !(hs->platform_code & PLATFORM_CODE_FLAG_TWL) ) - { - return; - } - - // NANDアプリのときだけ - if ( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND ) - { - // get savedata_path - s32 result = NAM_GetTitleSaveFilePath( path[ 0 ], path[ 1 ], hs->titleID ); - - // pub_save - if( result == NAM_OK && hs->public_save_data_size != 0 ) - { - stat = UTL_RecoveryFile( path[0], hs->public_save_data_size ); - OS_TPrintf("pub_save recovery result : %s \n", s_strResult[stat]); - } - - // prv_save - if( result == NAM_OK && hs->private_save_data_size != 0 ) - { - stat = UTL_RecoveryFile( path[1], hs->private_save_data_size ); - OS_TPrintf("prv_save recovery result : %s \n", s_strResult[stat]); - } - - // sub_banner - if( hs->exFlags.availableSubBannerFile && NAM_GetTitleBannerFilePath( path[0], hs->titleID ) == NAM_OK ) - { - stat = UTL_RecoveryFile( path[0], SIZE_16KB ); - OS_TPrintf("sub_banner recovery result : %s \n", s_strResult[stat]); - } - } - - // shared2 (size+1) * 16kb - if( hs->shared2_file0_size != 0 ) - { - stat = UTL_RecoveryFile( "nand:/shared2/0000", (u32)( hs->shared2_file0_size + 1 ) * SIZE_16KB ); - OS_TPrintf("shared2_0 recovery result : %s \n", s_strResult[stat]); - } - if( hs->shared2_file1_size != 0 ) - { - stat = UTL_RecoveryFile( "nand:/shared2/0001", (u32)( hs->shared2_file1_size + 1 ) * SIZE_16KB ); - OS_TPrintf("shared2_1 recovery result : %s \n", s_strResult[stat]); - } - if( hs->shared2_file2_size != 0 ) - { - stat = UTL_RecoveryFile( "nand:/shared2/0002", (u32)( hs->shared2_file2_size + 1 ) * SIZE_16KB ); - OS_TPrintf("shared2_2 recovery result : %s \n", s_strResult[stat]); - } - if( hs->shared2_file3_size != 0 ) - { - stat = UTL_RecoveryFile( "nand:/shared2/0003", (u32)( hs->shared2_file3_size + 1 ) * SIZE_16KB ); - OS_TPrintf("shared2_3 recovery result : %s \n", s_strResult[stat]); - } - if( hs->shared2_file4_size != 0 ) - { - stat = UTL_RecoveryFile( "nand:/shared2/0004", (u32)( hs->shared2_file4_size + 1 ) * SIZE_16KB ); - OS_TPrintf("shared2_4 recovery result : %s \n", s_strResult[stat]); - } - if( hs->shared2_file5_size != 0 ) - { - stat = UTL_RecoveryFile( "nand:/shared2/0005", (u32)( hs->shared2_file5_size + 1 ) * SIZE_16KB ); - OS_TPrintf("shared2_5 recovery result : %s \n", s_strResult[stat]); - } + ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; + char path[2][ FS_ENTRY_LONGNAME_MAX ]; + UTL_RecoveryStatus stat; + + // TWL非対応のときは不要なのでreturn + if ( !(hs->platform_code & PLATFORM_CODE_FLAG_TWL) ) + { + return; + } + + // NANDアプリのときだけ + if ( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_NAND ) + { + // get savedata_path + s32 result = NAM_GetTitleSaveFilePath( path[ 0 ], path[ 1 ], hs->titleID ); + + // pub_save + if( result == NAM_OK && hs->public_save_data_size != 0 ) + { + stat = UTL_RecoveryFile( path[0], hs->public_save_data_size ); + OS_TPrintf("pub_save recovery result : %s \n", s_strResult[stat]); + } + + // prv_save + if( result == NAM_OK && hs->private_save_data_size != 0 ) + { + stat = UTL_RecoveryFile( path[1], hs->private_save_data_size ); + OS_TPrintf("prv_save recovery result : %s \n", s_strResult[stat]); + } + + // sub_banner + if( hs->exFlags.availableSubBannerFile && NAM_GetTitleBannerFilePath( path[0], hs->titleID ) == NAM_OK ) + { + stat = UTL_RecoveryFile( path[0], SIZE_16KB ); + OS_TPrintf("sub_banner recovery result : %s \n", s_strResult[stat]); + } + } + + // shared2 (size+1) * 16kb + if( hs->shared2_file0_size != 0 ) + { + stat = UTL_RecoveryFile( "nand:/shared2/0000", (u32)( hs->shared2_file0_size + 1 ) * SIZE_16KB ); + OS_TPrintf("shared2_0 recovery result : %s \n", s_strResult[stat]); + } + if( hs->shared2_file1_size != 0 ) + { + stat = UTL_RecoveryFile( "nand:/shared2/0001", (u32)( hs->shared2_file1_size + 1 ) * SIZE_16KB ); + OS_TPrintf("shared2_1 recovery result : %s \n", s_strResult[stat]); + } + if( hs->shared2_file2_size != 0 ) + { + stat = UTL_RecoveryFile( "nand:/shared2/0002", (u32)( hs->shared2_file2_size + 1 ) * SIZE_16KB ); + OS_TPrintf("shared2_2 recovery result : %s \n", s_strResult[stat]); + } + if( hs->shared2_file3_size != 0 ) + { + stat = UTL_RecoveryFile( "nand:/shared2/0003", (u32)( hs->shared2_file3_size + 1 ) * SIZE_16KB ); + OS_TPrintf("shared2_3 recovery result : %s \n", s_strResult[stat]); + } + if( hs->shared2_file4_size != 0 ) + { + stat = UTL_RecoveryFile( "nand:/shared2/0004", (u32)( hs->shared2_file4_size + 1 ) * SIZE_16KB ); + OS_TPrintf("shared2_4 recovery result : %s \n", s_strResult[stat]); + } + if( hs->shared2_file5_size != 0 ) + { + stat = UTL_RecoveryFile( "nand:/shared2/0005", (u32)( hs->shared2_file5_size + 1 ) * SIZE_16KB ); + OS_TPrintf("shared2_5 recovery result : %s \n", s_strResult[stat]); + } } // ロード済みの指定タイトルの認証とブートを行う // SYSM_GetNandTitleListまたはSYSM_GetNandTitleListMakerInfoのどちらかをSYSM_TryToBootTitle前に呼ぶ必要あり void SYSM_TryToBootTitle( TitleProperty *pBootTitle ) { - // [TODO:] この内部の処理で失敗した場合にそのままブートしてしまって大丈夫か? - - if(s_calc_hash) - { - // ハッシュ値保存領域解放 - SYSM_Free( s_calc_hash ); - s_calc_hash = NULL; - } - - if(dht) - { - // dht用バッファが確保されていたら解放 - SYSM_Free( dht ); - dht = NULL; - } - - // ダイレクトブート時など、まだSystemMenuVersionのデータがセットされていない場合は、ここでセットする。 - if( *(u8 *)HW_SYSM_VER_INFO_CONTENT_LAST_INITIAL_CODE == 0 ) { - SYSM_SetSystemMenuVersionControlData(); - } - - // デバッガ接続中以外の時のみTWL設定データにブートするタイトルのTitleIDとplatformCodeを保存。 + // [TODO:] この内部の処理で失敗した場合にそのままブートしてしまって大丈夫か? + + if(s_calc_hash) + { + // ハッシュ値保存領域解放 + SYSM_Free( s_calc_hash ); + s_calc_hash = NULL; + } + + if(s_dht.buffer) + { + // DHT用バッファが確保されていたら解放 + SYSM_Free( s_dht.buffer ); + s_dht.buffer = NULL; + } + + // ダイレクトブート時など、まだSystemMenuVersionのデータがセットされていない場合は、ここでセットする。 + if( *(u8 *)HW_SYSM_VER_INFO_CONTENT_LAST_INITIAL_CODE == 0 ) { + SYSM_SetSystemMenuVersionControlData(); + } + + // デバッガ接続中以外の時のみTWL設定データにブートするタイトルのTitleIDとplatformCodeを保存。 if( !SYSM_IsRunOnDebugger() || // スタンドアロン (OSi_DetectDebugger() & OS_CONSOLE_TWLDEBUGGER) ) // デバッグ時 { - u8 *pBuffer = SYSM_Alloc( LCFG_WRITE_TEMP ); - if( pBuffer != NULL ) { - LCFG_TSD_SetLastTimeBootSoftPlatform( (u8)SYSM_GetAppRomHeader()->platform_code ); - (void)LCFG_WriteTWLSettings( (u8 (*)[ LCFG_WRITE_TEMP ] )pBuffer ); - SYSM_Free( pBuffer ); - } - } - - // マウント情報の登録 - SYSMi_GetWork2()->bootTitleProperty = *pBootTitle; - SYSMi_SetBootSRLPathToWork2( pBootTitle ); - - // ブート種別仮セット - SYSMi_GetWork()->appBootType = s_launcherToOSBootType[ pBootTitle->flags.bootType ]; - + u8 *pBuffer = SYSM_Alloc( LCFG_WRITE_TEMP ); + if( pBuffer != NULL ) { + LCFG_TSD_SetLastTimeBootSoftPlatform( (u8)SYSM_GetAppRomHeader()->platform_code ); + (void)LCFG_WriteTWLSettings( (u8 (*)[ LCFG_WRITE_TEMP ] )pBuffer ); + SYSM_Free( pBuffer ); + } + } + + // マウント情報の登録 + SYSMi_GetWork2()->bootTitleProperty = *pBootTitle; + SYSMi_SetBootSRLPathToWork2( pBootTitle ); + + // ブート種別仮セット + SYSMi_GetWork()->appBootType = s_launcherToOSBootType[ pBootTitle->flags.bootType ]; + #if 0 - // ブート時ファイルリカバリ処理 - SYSMi_FileRecovery( pBootTitle ); + // ブート時ファイルリカバリ処理 + SYSMi_FileRecovery( pBootTitle ); #endif - // タイトルIDリストの作成 - SYSMi_makeTitleIdList(); - - // バンブラパッチ - SYSMi_applyPatchToBandBrothers(); - - BOOT_Ready(); // never return. - + // タイトルIDリストの作成 + SYSMi_makeTitleIdList(); + + // バンブラパッチ + SYSMi_applyPatchToBandBrothers(); + + BOOT_Ready(); // never return. + } // バンブラパッチを当てる関数 static void SYSMi_applyPatchToBandBrothers( void ) { - ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; + ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; - if( ( 0 == STD_CompareNString( hs->game_code , "AXBJ", 4 ) ) && ( hs->rom_version == 0 ) ) - { - u32 len = 0; - u32 llen; - FSFile src; - void *dest; + if( ( 0 == STD_CompareNString( hs->game_code , "AXBJ", 4 ) ) && ( hs->rom_version == 0 ) ) + { + u32 len = 0; + u32 llen; + FSFile src; + void *dest; - // データ読み込み + パッチ - FS_InitFile( &src ); - if ( !FS_OpenFileEx( &src, "rom:/data/bandbrothers_arm7flx_patch.sbin", FS_FILEMODE_R ) ) return; - len = FS_GetFileLength( &src ); - - // ヘッダ情報のうち、ARM7FLXのサイズを改変する - hs->sub_size = len; - - if( SYSMi_GetWork()->romRelocateInfo[ARM7_STATIC].src != NULL ) - { - // ARM7FLXが再配置の場合 - dest = (void *)SYSMi_GetWork()->romRelocateInfo[ARM7_STATIC].src; - SYSMi_GetWork()->romRelocateInfo[ARM7_STATIC].length = len; - OS_TPrintf("bandbrothers patch : relocate info changed! \n"); - }else - { - // 再配置なし - dest = hs->sub_ram_address; - } + // データ読み込み + パッチ + FS_InitFile( &src ); + if ( !FS_OpenFileEx( &src, "rom:/data/bandbrothers_arm7flx_patch.sbin", FS_FILEMODE_R ) ) return; + len = FS_GetFileLength( &src ); - for(llen = 0; llen < len; ) - { - int rd; - rd = FS_ReadFile( &src, dest, (s32)len ); - if(rd == -1) - { - FS_CloseFile( &src ); - return; - } - dest = (void *)((u32)dest + rd); - llen += rd; - } - if ( !FS_CloseFile( &src ) ) return; - if (len != llen) return; - - OS_TPrintf("bandbrothers patch : apply succeeded! \n"); - } - - return; + // ヘッダ情報のうち、ARM7FLXのサイズを改変する + hs->sub_size = len; + + if( SYSMi_GetWork()->romRelocateInfo[ARM7_STATIC].src != NULL ) + { + // ARM7FLXが再配置の場合 + dest = (void *)SYSMi_GetWork()->romRelocateInfo[ARM7_STATIC].src; + SYSMi_GetWork()->romRelocateInfo[ARM7_STATIC].length = len; + OS_TPrintf("bandbrothers patch : relocate info changed! \n"); + }else + { + // 再配置なし + dest = hs->sub_ram_address; + } + + for(llen = 0; llen < len; ) + { + int rd; + rd = FS_ReadFile( &src, dest, (s32)len ); + if(rd == -1) + { + FS_CloseFile( &src ); + return; + } + dest = (void *)((u32)dest + rd); + llen += rd; + } + if ( !FS_CloseFile( &src ) ) return; + if (len != llen) return; + + OS_TPrintf("bandbrothers patch : apply succeeded! \n"); + } + + return; } // タイトルIDリストの作成 static void SYSMi_makeTitleIdList( void ) { - OSTitleIDList *list = ( OSTitleIDList * )HW_OS_TITLE_ID_LIST; - ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; - int l; - u8 count = 0; - int max = AMN_getRomHeaderListLength(); - OSTick start; - - // 時間計測総合 - start = OS_GetTick(); - - // とりあえずゼロクリア - MI_CpuClear8( (void *)HW_OS_TITLE_ID_LIST, HW_OS_TITLE_ID_LIST_SIZE ); + OSTitleIDList *list = ( OSTitleIDList * )HW_OS_TITLE_ID_LIST; + ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; + int l; + u8 count = 0; + int max = AMN_getRomHeaderListLength(); + OSTick start; - // これから起動するアプリがTWLアプリでない - if( !hs->platform_code ) - { - return; - } + // 時間計測総合 + start = OS_GetTick(); - for(l=0;ltitleID; - - for(m=0;mmaker_code[m] != pe_hs->maker_code[m]) - { - same_maker_code = FALSE; - } - } - - // 無効なTitleIDはスキップ - if( id == NULL ) - { - continue; - } - - gamecode = (char *)&(id); - - // ランチャーはリストに入れない - if( ( 0 == STD_CompareNString( &gamecode[1], "ANH", 3 ) ) + // これから起動するアプリがTWLアプリでない + if( !hs->platform_code ) + { + return; + } + + for(l=0;ltitleID; + + for(m=0;mmaker_code[m] != pe_hs->maker_code[m]) + { + same_maker_code = FALSE; + } + } + + // 無効なTitleIDはスキップ + if( id == NULL ) + { + continue; + } + + gamecode = (char *)&(id); + + // ランチャーはリストに入れない + if( ( 0 == STD_CompareNString( &gamecode[1], "ANH", 3 ) ) #ifdef DEV_UIG_LAUNCHER - || ( ( 0 == STD_CompareNString( &gamecode[1], "AN4", 3 ) ) && ( SCFG_GetBondingOption() != 0 ) ) + || ( ( 0 == STD_CompareNString( &gamecode[1], "AN4", 3 ) ) && ( SCFG_GetBondingOption() != 0 ) ) #endif - ) - { - continue; - } - - if( same_maker_code ) - { - // リストに追加 - list->TitleID[count] = id; - // sameMakerFlagをON - list->sameMakerFlag[count/8] |= (u8)(0x1 << (count%8)); - } - - // ジャンプ可能フラグON or ブートアプリ自身 or ジャンプ元アプリ ならばジャンプ可能 - if( pe_hs->permit_landing_normal_jump || hs->titleID == id || - ( SYSMi_GetWork()->flags.arm7.isValidLauncherParam && SYSM_GetLauncherParamBody()->v1.bootTitleID && ( SYSM_GetLauncherParamBody()->v1.prevTitleID == id ) ) - ) - { - // リストに追加してジャンプ可能フラグON - list->TitleID[count] = id; - list->appJumpFlag[count/8] |= (u8)(0x1 << (count%8)); - } - - // ブートアプリがセキュアアプリの場合 - if( hs->titleID & TITLE_ID_SECURE_FLAG_MASK ) - { - // Prv,Pubそれぞれセーブデータがあるか見て、存在すればフラグON - if(pe_hs->public_save_data_size != 0) - { - list->publicFlag[count/8] |= (u8)(0x1 << (count%8)); - } - if(pe_hs->private_save_data_size != 0) - { - list->privateFlag[count/8] |= (u8)(0x1 << (count%8)); - } - // リストに強制追加 - list->TitleID[count] = id; - }else - { - // セキュアアプリでない && メーカーコードが同じ - if( !(id & TITLE_ID_SECURE_FLAG_MASK) && same_maker_code ) - { - // Prv,Pubそれぞれセーブデータがあるか見て、存在すればフラグON - if(pe_hs->public_save_data_size != 0) - { - list->publicFlag[count/8] |= (u8)(0x1 << (count%8)); - // リストに追加 - list->TitleID[count] = id; - } - if(pe_hs->private_save_data_size != 0) - { - list->privateFlag[count/8] |= (u8)(0x1 << (count%8)); - // リストに追加 - list->TitleID[count] = id; - } - } - } - - // ここまでのうちに、list->TitleID[count]が編集されていたらcountインクリメント - if( list->TitleID[count] != NULL ) - { - count++; - } - } - list->num = count; - // end時間計測総合 - OS_TPrintf("SYSMi_makeTitleIdList : total %dms\n",OS_TicksToMilliSeconds(OS_GetTick() - start)); + ) + { + continue; + } + + if( same_maker_code ) + { + // リストに追加 + list->TitleID[count] = id; + // sameMakerFlagをON + list->sameMakerFlag[count/8] |= (u8)(0x1 << (count%8)); + } + + // ジャンプ可能フラグON or ブートアプリ自身 or ジャンプ元アプリ ならばジャンプ可能 + if( pe_hs->permit_landing_normal_jump || hs->titleID == id || + ( SYSMi_GetWork()->flags.arm7.isValidLauncherParam && SYSM_GetLauncherParamBody()->v1.bootTitleID && ( SYSM_GetLauncherParamBody()->v1.prevTitleID == id ) ) + ) + { + // リストに追加してジャンプ可能フラグON + list->TitleID[count] = id; + list->appJumpFlag[count/8] |= (u8)(0x1 << (count%8)); + } + + // ブートアプリがセキュアアプリの場合 + if( hs->titleID & TITLE_ID_SECURE_FLAG_MASK ) + { + // Prv,Pubそれぞれセーブデータがあるか見て、存在すればフラグON + if(pe_hs->public_save_data_size != 0) + { + list->publicFlag[count/8] |= (u8)(0x1 << (count%8)); + } + if(pe_hs->private_save_data_size != 0) + { + list->privateFlag[count/8] |= (u8)(0x1 << (count%8)); + } + // リストに強制追加 + list->TitleID[count] = id; + }else + { + // セキュアアプリでない && メーカーコードが同じ + if( !(id & TITLE_ID_SECURE_FLAG_MASK) && same_maker_code ) + { + // Prv,Pubそれぞれセーブデータがあるか見て、存在すればフラグON + if(pe_hs->public_save_data_size != 0) + { + list->publicFlag[count/8] |= (u8)(0x1 << (count%8)); + // リストに追加 + list->TitleID[count] = id; + } + if(pe_hs->private_save_data_size != 0) + { + list->privateFlag[count/8] |= (u8)(0x1 << (count%8)); + // リストに追加 + list->TitleID[count] = id; + } + } + } + + // ここまでのうちに、list->TitleID[count]が編集されていたらcountインクリメント + if( list->TitleID[count] != NULL ) + { + count++; + } + } + list->num = count; + // end時間計測総合 + OS_TPrintf("SYSMi_makeTitleIdList : total %dms\n",OS_TicksToMilliSeconds(OS_GetTick() - start)); } // システムメニューバージョン情報制御データのセット void SYSM_SetSystemMenuVersionControlData( void ) { - int l; - int max = AMN_getRomHeaderListLength(); - - for(l=0;ltitleID; - - gamecode = (char *)&(id); - // バージョン情報の特殊処理 - if( ( 0 == STD_CompareNString( &gamecode[1], "LNH", 3 ) ) ) - { - char path[ FS_ENTRY_LONGNAME_MAX ]; - char *p; - NAM_GetTitleBootContentPathFast(path, id); - p = STD_SearchString( path, ".app" ); - if( p == NULL) - { - // 失敗 - continue; - } - MI_CpuCopy8( p-8, (void *)HW_SYSM_VER_INFO_CONTENT_ID, 8 ); - ((char *)HW_SYSM_VER_INFO_CONTENT_ID )[8] = '\0'; - ((char *)HW_SYSM_VER_INFO_CONTENT_ID )[9] = gamecode[0]; - } - } + for(l=0;ltitleID; + + gamecode = (char *)&(id); + // バージョン情報の特殊処理 + if( ( 0 == STD_CompareNString( &gamecode[1], "LNH", 3 ) ) ) + { + char path[ FS_ENTRY_LONGNAME_MAX ]; + char *p; + NAM_GetTitleBootContentPathFast(path, id); + p = STD_SearchString( path, ".app" ); + if( p == NULL) + { + // 失敗 + continue; + } + MI_CpuCopy8( p-8, (void *)HW_SYSM_VER_INFO_CONTENT_ID, 8 ); + ((char *)HW_SYSM_VER_INFO_CONTENT_ID )[8] = '\0'; + ((char *)HW_SYSM_VER_INFO_CONTENT_ID )[9] = gamecode[0]; + } + } } @@ -2094,46 +2337,46 @@ void SYSM_SetSystemMenuVersionControlData( void ) static BOOL SYSMi_CheckTitlePointer( TitleProperty *pBootTitle ) { #pragma unused( pBootTitle ) - - return TRUE; + + return TRUE; } #if 0 void CheckDigest( void ) { - int i; - for( i = 0; i < 4; i++ ) { - if( SYSMi_GetWork()->reloc_info[ i ].src ) { - - }else { - } - } + int i; + for( i = 0; i < 4; i++ ) { + if( SYSMi_GetWork()->reloc_info[ i ].src ) { + + }else { + } + } } #endif // 単純リスト要素削除 static void SYSMi_DeleteElementFromList( u32 *list, u32 index ) { - int l; - for( l=(int)index; list[l]!=NULL; l++ ) - { - list[l] = list[l+1]; - } + int l; + for( l=(int)index; list[l]!=NULL; l++ ) + { + list[l] = list[l+1]; + } } // 単純リスト要素追加 static void SYSMi_InsertElementToList( u32 *list, u32 index, u32 value ) { - int l = (int)index; - while(list[l]!=NULL) - { - l++; - } - list[l+1] = NULL; - for( ; index= start ) - { - break; - } - } - for( m=l; regionlist[m]!=NULL; m++ ) - { - if( regionlist[m] > end ) - { - break; - } - } - // この時点でregionlist[l]およびregionlist[m]は、start <= regionlist[l], end < regionlist[m]で、且つ最も小さな値 - - if( m % 2 == 1 ) - { - SYSMi_InsertElementToList( regionlist, (u32)m, end ); - // endをリストに追加した場合、mは追加した要素を指すように - } - if( l % 2 == 1 ) - { - SYSMi_InsertElementToList( regionlist, (u32)l, start ); - m++; - // startをリストに追加した場合、mは1増える - l++; - // startをリストに追加した場合、lは追加した要素の次の要素を指すように - } - - // regionlist[l]からregionlist[m-1]までの要素を消す - for( n=l; l= start ) + { + break; + } + } + for( m=l; regionlist[m]!=NULL; m++ ) + { + if( regionlist[m] > end ) + { + break; + } + } + // この時点でregionlist[l]およびregionlist[m]は、start <= regionlist[l], end < regionlist[m]で、且つ最も小さな値 + + if( m % 2 == 1 ) + { + SYSMi_InsertElementToList( regionlist, (u32)m, end ); + // endをリストに追加した場合、mは追加した要素を指すように + } + if( l % 2 == 1 ) + { + SYSMi_InsertElementToList( regionlist, (u32)l, start ); + m++; + // startをリストに追加した場合、mは1増える + l++; + // startをリストに追加した場合、lは追加した要素の次の要素を指すように + } + + // regionlist[l]からregionlist[m-1]までの要素を消す + for( n=l; l $@ +$(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 \ diff --git a/build/systemMenu_RED/DSHashTable/commondefs.DSHashTable b/build/systemMenu_RED/DSHashTable/commondefs.DSHashTable index 8bab299b..4685b71e 100644 --- a/build/systemMenu_RED/DSHashTable/commondefs.DSHashTable +++ b/build/systemMenu_RED/DSHashTable/commondefs.DSHashTable @@ -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 diff --git a/build/systemMenu_RED/Launcher/ARM9/src/main.c b/build/systemMenu_RED/Launcher/ARM9/src/main.c index e1124701..76a0e06a 100644 --- a/build/systemMenu_RED/Launcher/ARM9/src/main.c +++ b/build/systemMenu_RED/Launcher/ARM9/src/main.c @@ -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; iflags.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 ); + } + } } diff --git a/docs/繝。繝「繝ェ繝槭ャ繝誉NAND繝輔ぃ繝シ繝.vsd b/docs/繝。繝「繝ェ繝槭ャ繝誉NAND繝輔ぃ繝シ繝.vsd index 3ac08045..16f17ef2 100644 Binary files a/docs/繝。繝「繝ェ繝槭ャ繝誉NAND繝輔ぃ繝シ繝.vsd and b/docs/繝。繝「繝ェ繝槭ャ繝誉NAND繝輔ぃ繝シ繝.vsd differ diff --git a/include/sysmenu/dht/dht.h b/include/sysmenu/dht/dht.h index 492421dc..9f14f7b9 100644 --- a/include/sysmenu/dht/dht.h +++ b/include/sysmenu/dht/dht.h @@ -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 #include #include +#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" */ diff --git a/include/sysmenu/dht/dht_format.h b/include/sysmenu/dht/dht_format.h index b41f957b..655c843b 100644 --- a/include/sysmenu/dht/dht_format.h +++ b/include/sysmenu/dht/dht_format.h @@ -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 +#include #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, \ +} /* ユーティリティ - 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" */ diff --git a/include/sysmenu/util.h b/include/sysmenu/util.h index 1db41990..97144994 100644 --- a/include/sysmenu/util.h +++ b/include/sysmenu/util.h @@ -15,8 +15,8 @@ $Author$ *---------------------------------------------------------------------------*/ -#ifndef __SYSM_UTIL_H__ -#define __SYSM_UTIL_H__ +#ifndef __SYSM_UTIL_H__ +#define __SYSM_UTIL_H__ #include #include @@ -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ホワイトリスト認証失敗(フェーズ1) - FATAL_ERROR_DHT_PHASE2_FAILED = 29, // アプリのNTRホワイトリスト認証失敗(フェーズ2) - 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ホワイトリスト認証失敗(フェーズ1) + FATAL_ERROR_DHT_PHASE2_FAILED = 29, // アプリのNTRホワイトリスト認証失敗(フェーズ2) + 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ホワイトリスト認証失敗(フェーズ3) + FATAL_ERROR_DHT_PHASE4_FAILED = 52, // アプリのNTRホワイトリスト認証失敗(フェーズ4) - 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 ); // マスターキー  (10進5桁)算出(※内部でRTC_GetDateを使用します。) +extern u32 UTL_CalcPCTLInquiryCode( void ); // 問い合わせコード(10進8桁)算出 +extern u32 UTL_CalcPCTLMasterKey( void ); // マスターキー  (10進5桁)算出(※内部で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; }