diff --git a/build/libraries/fs/ARM9/Makefile b/build/libraries/fs/ARM9/Makefile index 96a929ef..69ad1688 100644 --- a/build/libraries/fs/ARM9/Makefile +++ b/build/libraries/fs/ARM9/Makefile @@ -24,7 +24,7 @@ SUBMAKES = LINCLUDES = $(ES_ROOT)/twl/include -SRCS = fs_firm.c +SRCS = fs_firm.c fs_es.c TARGET_LIB = libfs$(FIRM_LIBSUFFIX).a diff --git a/build/libraries/fs/ARM9/src/fs_es.c b/build/libraries/fs/ARM9/src/fs_es.c new file mode 100644 index 00000000..2cb99a6e --- /dev/null +++ b/build/libraries/fs/ARM9/src/fs_es.c @@ -0,0 +1,155 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - libraries - fs + File: fs_es.c + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ +#include +#include + +#define PATH_FORMAT_TMD "nand:/title/%08x/%08x/content/title.tmd" +#define PATH_FORMAT_CONTENT "nand:/title/%08x/%08x/content/%08x.app" + +/*---------------------------------------------------------------------------* + Name: LoadTMD + + Description: 対象のタイトルの TMD ファイルをメモリに読み込みます。 + 処理が正常に行われた場合に得られるバッファへのポインタは + 不要になったら NAMi_Free で解放する必要があります。 + + Arguments: titleId: 対象のタイトルの TitleID。 + + Returns: 処理が正常に行われたなら TRUEを返します。 + そうでなければ FALSE を返します。 + *---------------------------------------------------------------------------*/ +static BOOL LoadTMD(ESTitleMeta* pTmd, u64 titleId) +{ + char path[64]; + FSFile f; + BOOL bSuccess; + u32 fileSize; + s32 readSize; + s32 readResult; + + // TMD のパスを生成 + STD_TSPrintf(path, PATH_FORMAT_TMD, (u32)(titleId >> 32), (u32)titleId); + + FS_InitFile(&f); + bSuccess = FS_OpenFileEx(&f, path, FS_FILEMODE_R); + + if( ! bSuccess ) + { + // ファイルが開けなかった + return FALSE; + } + + fileSize = FS_GetFileLength(&f); + + // ファイルサイズをチェック 1 + // 固定部分サイズ <= fileSize <= 固定部分サイズ + 可変長部分最大サイズ + if( (fileSize < sizeof(IOSCSigRsa2048) + sizeof(ESTitleMetaHeader)) + || (sizeof(ESTitleMeta) < fileSize) ) + { + // ファイルサイズが異常 + FS_CloseFile(&f); + return FALSE; + } + + readSize = (s32)fileSize; + readResult = FS_ReadFile(&f, pTmd, readSize); + FS_CloseFile(&f); + + if( readResult != readSize ) + { + // ファイルからの読み込みに失敗 + return FALSE; + } + + // ファイルサイズをチェック 2 + // 可変長部分を正しく考慮 + if( fileSize != sizeof(IOSCSigRsa2048) + + sizeof(ESTitleMetaHeader) + + sizeof(ESContentMeta) * MI_SwapEndian16(pTmd->head.numContents) ) + { + // ファイルサイズが異常 + return FALSE; + } + + // タイトル ID の一致をチェック + if( titleId != MI_SwapEndian64(pTmd->head.titleId) ) + { + // タイトル ID が一致しない + return FALSE; + } + + return TRUE; +} +/*---------------------------------------------------------------------------* + Name: FS_GetTitleBootContentPathFast + + Description: NAND にインストールされているアプリの実行ファイルのパスを + 取得します。 + 取得する情報の正当性を検証しないため高速ですが、 + 情報が改竄されている可能性があることに注意しなければなりません。 + + Arguments: buf: パスを格納するバッファへのポインタ。 + FS_ENTRY_LONGNAME_MAX 以上のサイズが必要です。 + titleId: パスを取得するアプリの Title ID。 + + Returns: 正常に処理が行われたなら TRUE を返します。 + *---------------------------------------------------------------------------*/ +BOOL FS_GetTitleBootContentPathFast(char* buf, u64 titleId) +{ + ESTitleMeta tmd; + u32 bootContentId; + int bootContentIndex; + int numContents; + int i; + + SDK_POINTER_ASSERT(buf); + + + + if( !LoadTMD(&tmd, titleId) ) + { + return FALSE; + } + + // 生の TMD は BigEndian + bootContentIndex = MI_SwapEndian16(tmd.head.bootIndex); + numContents = MI_SwapEndian16(tmd.head.numContents); + + // bootContentIndex に一致するコンテンツを探す + for( i = 0; i < numContents; ++i ) + { + const ESContentMeta* pContent = &tmd.contents[i]; + + if( MI_SwapEndian16(pContent->index) == bootContentIndex ) + { + bootContentId = MI_SwapEndian32(pContent->cid); + break; + } + } + + if( i >= numContents ) + { + return FALSE; + } + + // コンテンツのパスを生成 + STD_TSPrintf(buf, PATH_FORMAT_CONTENT, (u32)(titleId >> 32), (u32)titleId, bootContentId); + + return TRUE; +} + + diff --git a/build/libraries/fs/ARM9/src/fs_firm.c b/build/libraries/fs/ARM9/src/fs_firm.c index 20b955c2..6d9eb3cc 100644 --- a/build/libraries/fs/ARM9/src/fs_firm.c +++ b/build/libraries/fs/ARM9/src/fs_firm.c @@ -114,7 +114,7 @@ void FS_DeleteAesKeySeed( void ) BOOL FS_ResolveSrl( u64 titleId ) { if ( ES_ERR_OK != ES_InitLib() || - ES_ERR_OK != ES_GetContentPath(titleId, CONTENT_INDEX_SRL, (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF) || + !FS_GetTitleBootContentPathFast((char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, titleId) || ES_ERR_OK != ES_CloseLib() ) { return FALSE; diff --git a/include/firm/fs.h b/include/firm/fs.h index 3688fdf1..c445fdac 100644 --- a/include/firm/fs.h +++ b/include/firm/fs.h @@ -22,6 +22,7 @@ #include #else #include +#include #endif // SDK_ARM7 diff --git a/include/firm/fs/ARM9/fs_es.h b/include/firm/fs/ARM9/fs_es.h new file mode 100644 index 00000000..baaf63a4 --- /dev/null +++ b/include/firm/fs/ARM9/fs_es.h @@ -0,0 +1,50 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - fs + File: fs_es.h + + Copyright 2007 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_FS_ES_FIRM_H_ +#define FIRM_FS_ES_FIRM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: FS_GetTitleBootContentPathFast + + Description: NAND にインストールされているアプリの実行ファイルのパスを + 取得します。 + 取得する情報の正当性を検証しないため高速ですが、 + 情報が改竄されている可能性があることに注意しなければなりません。 + + Arguments: buf: パスを格納するバッファへのポインタ。 + FS_ENTRY_LONGNAME_MAX 以上のサイズが必要です。 + titleId: パスを取得するアプリの Title ID。 + + Returns: 正常に処理が行われたなら TRUE を返します。 + *---------------------------------------------------------------------------*/ +BOOL FS_GetTitleBootContentPathFast(char* buf, u64 titleId); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +/* FIRM_FS_ES_FIRM_H_ */ +#endif