diff --git a/build/libraries_sysmenu/sysmenu/ARM9/src/title.c b/build/libraries_sysmenu/sysmenu/ARM9/src/title.c index 7b878778..8ea58a08 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/src/title.c +++ b/build/libraries_sysmenu/sysmenu/ARM9/src/title.c @@ -49,6 +49,8 @@ #include #define DS_HASH_TABLE_SIZE (256*1024) +#define SYSM_TITLE_MESSAGE_ARRAY_MAX 1 + typedef struct MbAuthCode { char magic_code[2]; // マジックナンバー @@ -92,6 +94,12 @@ static MbAuthCode s_authcode; static BOOL s_loadstart = FALSE; +static BOOL s_loadPaused = FALSE; +static BOOL s_loadForcibly = FALSE; + +static OSMessageQueue s_msgQ; +static OSMessage s_msgArray[SYSM_TITLE_MESSAGE_ARRAY_MAX]; + static NAMTitleId *s_pTitleIDList = NULL; static int s_listLength = 0; @@ -1206,18 +1214,32 @@ static AuthResult SYSMi_AuthenticateNTRDownloadTitle( TitleProperty *pBootTitle) return AUTH_RESULT_SUCCEEDED; } +BOOL SYSM_IsLoadTitlePaused(void) +{ + return s_loadPaused; +} + +void SYSM_ResumeLoadingThread( BOOL force ) +{ + if( !s_loadPaused ) + { + return; + } + s_loadPaused = FALSE; + // メッセージ送信 + if(!OS_SendMessage(&s_msgQ, (OSMessage)force, OS_MESSAGE_NOBLOCK)) + { + OS_TPrintf( "SYSM_ResumeLoadingThread:Message send error.\n" ); + } +} + // NTR版カードアプリのヘッダ認証処理 static AuthResult SYSMi_AuthenticateNTRCardAppHeader( TitleProperty *pBootTitle, ROM_Header *head ) { AuthResult ret = AUTH_RESULT_SUCCEEDED; - // ボンディングオプション00でないときは適用しない -#ifdef AUTH_NTR_CARD_PRODUCT_ONLY - if( !SCFG_GetBondingOption() == 0 ) -#else // デバッガに接続してるときは適用しない if( SYSM_IsRunOnDebugger() ) -#endif { return AUTH_RESULT_SUCCEEDED; } @@ -1239,19 +1261,48 @@ static AuthResult SYSMi_AuthenticateNTRCardAppHeader( TitleProperty *pBootTitle, if(!dht) { OS_TPrintf(" Search DHT : database init Failed.\n"); - return AUTH_RESULT_WHITELIST_INITDB_FAILED; - } - OS_TPrintf("Searching DHT for %.4s(%02X)...", head->s.game_code, head->s.rom_version); - db = DHT_GetDatabase(dht, &head->s); - if ( !db ) + ret = AUTH_RESULT_WHITELIST_INITDB_FAILED; + }else { - OS_TPrintf(" Search DHT : Failed.\n"); - return AUTH_RESULT_WHITELIST_NOTFOUND; + 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"); + ret = AUTH_RESULT_WHITELIST_NOTFOUND; + }else + { + hash0 = db->hash[0]; + hash1 = db->hash[1]; + ret = AUTH_RESULT_SUCCEEDED; + } } - hash0 = db->hash[0]; - hash1 = db->hash[1]; - ret = AUTH_RESULT_SUCCEEDED; } + + // ボンディングオプションが0のときは以下の特殊処理をせずにリターン + if( SCFG_GetBondingOption() == 0 ) + { + return ret; + } + + // データロード前認証に失敗した場合にボタン押しで強制ロードするようにする + // 失敗時にメインスレッドにメッセージを送り、ボタン押し待ち + // 押されたらメインスレッドからこちらのスレッドにメッセージを送る + // メッセージ内容次第でロードを続行するか、エラーを返して中止するか選択 + // 続行する場合は強制実行フラグを立てる + if( ret != AUTH_RESULT_SUCCEEDED ) + { + BOOL forcing; + OS_InitMessageQueue(&s_msgQ, s_msgArray, SYSM_TITLE_MESSAGE_ARRAY_MAX); + s_loadPaused = TRUE; + OS_ReceiveMessage(&s_msgQ, (OSMessage*)&forcing, OS_MESSAGE_BLOCK); + if(forcing) + { + ret = AUTH_RESULT_SUCCEEDED; + s_loadForcibly = TRUE; + } + } + return ret; } @@ -1263,13 +1314,14 @@ static AuthResult SYSMi_AuthenticateNTRCardTitle( TitleProperty *pBootTitle) SVCHMACSHA1Context ctx; ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF; - // ボンディングオプション00でないときは適用しない -#ifdef AUTH_NTR_CARD_PRODUCT_ONLY - if( !SCFG_GetBondingOption() == 0 ) -#else // デバッガに接続してるときは適用しない if( SYSM_IsRunOnDebugger() ) -#endif + { + return AUTH_RESULT_SUCCEEDED; + } + + // ロード前認証で強制実行フラグを立てていれば、飛ばす + if( s_loadForcibly ) { return AUTH_RESULT_SUCCEEDED; } diff --git a/build/systemMenu_RED/Launcher/ARM9/src/main.c b/build/systemMenu_RED/Launcher/ARM9/src/main.c index 3959efa0..b3ede4db 100644 --- a/build/systemMenu_RED/Launcher/ARM9/src/main.c +++ b/build/systemMenu_RED/Launcher/ARM9/src/main.c @@ -31,6 +31,9 @@ static void INTR_VBlank( void ); static void deleteTmp(); void SYSM_DeleteTempDirectory( TitleProperty *pBootTitle ); +static BOOL IsCommandSelected(void); +static void PrintPause(void); +static void PrintError(AuthResult res); // global variable------------------------------------------------------------- @@ -102,9 +105,10 @@ void TwlMain( void ) LAUNCHER = 3, LOAD_START = 4, LOADING = 5, - AUTHENTICATE = 6, - BOOT = 7, - STOP = 8 + LOAD_PAUSE = 6, + AUTHENTICATE = 7, + BOOT = 8, + STOP = 9 }; u32 state = LOGODEMO_INIT; TitleProperty *pBootTitle = NULL; @@ -309,6 +313,12 @@ void TwlMain( void ) } break; case LOADING: + // ここでロード前ホワイトリストチェック失敗メッセージをポーリングし、受け取ったらstateをLOAD_PAUSEに + if( SYSM_IsLoadTitlePaused() ) + { + state = LOAD_PAUSE; + PrintPause(); + } if( SYSM_IsLoadTitleFinished() ) { SYSM_StartAuthenticateTitle( pBootTitle ); state = AUTHENTICATE; @@ -323,6 +333,14 @@ void TwlMain( void ) OS_TPrintf( "Load Time : %dms\n", OS_TicksToMilliSeconds( end - start ) ); } break; + case LOAD_PAUSE: + // ロード前ホワイトリストチェック失敗で一時停止中 + // 強制起動するか中止するかの選択がされたらLOADINGに戻る + if( IsCommandSelected() ) + { + state = LOADING; + } + break; case AUTHENTICATE: if( ( direct_boot || ( !direct_boot && LauncherFadeout( s_titleList ) ) ) && #ifndef DISABLE_WLFIRM_LOAD @@ -345,20 +363,8 @@ void TwlMain( void ) state = STOP; // [TODO:]クリアしたほうが良いデータ(鍵など)があれば消す - // デバグ表示 - LauncherInit( s_titleList ); - GX_SetVisiblePlane( GX_PLANEMASK_BG0 ); - NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL ); - G2_ChangeBlendAlpha( 0, 31 ); - PrintfSJIS( 1, 25, TXT_COLOR_RED,"LAUNCHER : ERROR OCCURRED! - %d\n",res ); - PrintfSJIS( 1, 40, TXT_COLOR_RED,"%s",error_msg[res] ); - // 特殊表示 - if(res == AUTH_RESULT_CHECK_TITLE_LAUNCH_RIGHTS_FAILED) - { - PrintfSJIS( 1, 55, TXT_COLOR_RED,"NAM result = %d", SYSMi_getCheckTitleLaunchRightsResult() ); - } - GX_DispOn(); - GXS_DispOn(); + // エラー表示 + PrintError(res); break; } @@ -384,6 +390,63 @@ void TwlMain( void ) } } +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 void PrintPause(void) +{ + LauncherInit( s_titleList ); + 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(AuthResult res) +{ + LauncherInit( s_titleList ); + GX_SetVisiblePlane( GX_PLANEMASK_BG0 ); + NNS_G2dCharCanvasClear( &gCanvas, TXT_COLOR_NULL ); + G2_ChangeBlendAlpha( 0, 31 ); + PrintfSJIS( 1, 25, TXT_COLOR_RED,"LAUNCHER : ERROR OCCURRED! - %d\n",res ); + PrintfSJIS( 1, 40, TXT_COLOR_RED,"%s",error_msg[res] ); + // 特殊表示 + if(res == AUTH_RESULT_CHECK_TITLE_LAUNCH_RIGHTS_FAILED) + { + PrintfSJIS( 1, 55, TXT_COLOR_RED,"NAM result = %d", SYSMi_getCheckTitleLaunchRightsResult() ); + } + GX_DispOn(); + GXS_DispOn(); +} // ============================================================================ // 割り込み処理 diff --git a/include/sysmenu/sysmenu_lib/common/sysmenu_api.h b/include/sysmenu/sysmenu_lib/common/sysmenu_api.h index 70f2b853..db542424 100644 --- a/include/sysmenu/sysmenu_lib/common/sysmenu_api.h +++ b/include/sysmenu/sysmenu_lib/common/sysmenu_api.h @@ -139,6 +139,9 @@ extern void SYSM_LoadNintendoLogo1D( u16 *pLogoData, u16 *pDst, int paletteColor extern s32 SYSMi_getCheckTitleLaunchRightsResult( void ); // CheckTitleLaunchRightsの結果を返す(デバグ用) +extern BOOL SYSM_IsLoadTitlePaused(void); // ローディングスレッドが一時停止しているか? +extern void SYSM_ResumeLoadingThread( BOOL force ); // ローディングスレッドが一時停止していたら再開 + #endif // 状態チェック