TwlIPL/build/libraries_sysmenu/settings/ARM9/src/TWLStoreFile.c
yosiokat 698853c42d ・NTR設定データのAPI仕様を変更。一時バッファ用引数を必要としない形に変更。
・NTR設定データのTWLリージョンによる言語コードの取り回しの実装。
・言語コード処理.xlsのドキュメント追加。
・メモリマップ.vsd更新。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@355 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2007-12-12 13:00:55 +00:00

258 lines
7.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: TwlIPL
File: TWLHWInfo.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 <twl.h>
#include <sysmenu/settings/common/TWLStoreFile.h>
// define data----------------------------------------------------------
// function's prototype-------------------------------------------------
// static variables-----------------------------------------------------
// global variables-----------------------------------------------------
// const data-----------------------------------------------------------
// function's description-----------------------------------------------
// TSFファイルの読み出し
TSFReadResult TSF_ReadFile( char *pPath, void *pDstBody, const TSFParam *pParam, u8 *pSaveCount )
{
TSFHeader header;
TSFReadResult retval;
FSFile file;
FS_InitFile( &file );
// ヘッダ用バッファのクリア
MI_CpuClear8( &header, sizeof(TSFHeader) );
// ボディ用バッファのクリア
if( pParam->pClearFunc ) {
// クリア用関数ありの時は、バージョン下位互換の場合を考慮して、デフォルト値をセットしておく
pParam->pClearFunc( pDstBody );
}else {
// そうでない場合は、リードバッファをクリア
MI_CpuClear8( pDstBody, pParam->dataLength );
}
// ファイルオープン
if( !FS_OpenFileEx( &file, pPath, FS_FILEMODE_R ) ) {
OS_TPrintf( "Read : file open error. %s\n", pPath );
retval = TSF_READ_RESULT_ERROR_FILE_EXIST;
goto END2;
}
// ファイル長チェック
if( FS_GetFileLength( &file ) != pParam->fileLength ) {
OS_TPrintf( "Read : file length error. : %s length = %d\n", pPath, FS_GetFileLength( &file ) );
retval = TSF_READ_RESULT_ERROR_FILE_LENGTH;
goto END;
}
// ヘッダリード
if( FS_ReadFile( &file, &header, sizeof(TSFHeader) ) < sizeof(TSFHeader) ) {
OS_TPrintf( "Read : file read error. %s\n", pPath );
retval = TSF_READ_RESULT_ERROR_DATA;
goto END;
}
// ヘッダチェック
if( header.bodyLength > pParam->dataLength ) {
OS_TPrintf( "Read : file header error. %s\n", pPath );
retval = TSF_READ_RESULT_ERROR_DATA;
goto END;
}
// ボディリード
if( FS_ReadFile( &file, pDstBody, (long)header.bodyLength ) < pParam->dataLength ) {
OS_TPrintf( "Read : file read error. %s\n", pPath );
retval = TSF_READ_RESULT_ERROR_DATA;
goto END;
}
// データのダイジェストチェック
if( pParam->pCheckDigestFunc &&
!pParam->pCheckDigestFunc( pDstBody, header.bodyLength, header.digest.dst ) ) {
OS_TPrintf( "Read : file digest error. %s\n", pPath );
retval = TSF_READ_RESULT_ERROR_DATA;
goto END;
}
// データの値チェック
if( pParam->pCheckValueFunc &&
!pParam->pCheckValueFunc( pDstBody ) ) {
OS_TPrintf( "Read : file data value error. %s\n", pPath );
retval = TSF_READ_RESULT_ERROR_DATA;
goto END;
}
// バージョン互換チェック
if( pParam->conpatibleVerList ) {
const u8 *pVersion = pParam->conpatibleVerList;
while( *pVersion++ != TSF_VERSION_TERMINATOR ) {
if( *pVersion == header.version ) {
break; // 互換あり
}
}
if( *pVersion == TSF_VERSION_TERMINATOR ) {
retval = TSF_READ_RESULT_ERROR_DATA;
goto END;
}
}
if( pSaveCount ) {
*pSaveCount = header.saveCount;
}
retval = TSF_READ_RESULT_SUCCEEDED;
END:
// ファイルクローズ
FS_CloseFile( &file );
END2:
if( retval != TSF_READ_RESULT_SUCCEEDED ) {
// ボディ用バッファのクリア
if( pParam->pClearFunc ) {
// クリア用関数ありの時は、バージョン下位互換の場合を考慮して、デフォルト値をセットしておく
pParam->pClearFunc( pDstBody );
}else {
// そうでない場合は、リードバッファをクリア
MI_CpuClear8( pDstBody, pParam->dataLength );
}
}
return retval;
}
// TWLファイルのライト
BOOL TSF_WriteFile( char *pPath, TSFHeader *pHeader, const void *pSrcBody, u8 *pSaveCount )
{
BOOL retval = FALSE;
FSFile file;
FS_InitFile( &file );
if( pSaveCount ) {
*pSaveCount = (u8)( ( *pSaveCount + 1 ) & SAVE_COUNT_MASK );
pHeader->saveCount = *pSaveCount;
}else {
pHeader->saveCount = 0;
}
OS_TPrintf( "Write > %s : %d\n", pPath, pHeader->saveCount );
// ファイルオープン
if( !FS_OpenFileEx( &file, pPath, FS_FILEMODE_R | FS_FILEMODE_W ) ) { // R|Wモードで開くと、既存ファイルを残したまま更新。
OS_TPrintf( "Write : file open error. %s\n", pPath );
return FALSE;
}
// ライト
if( FS_WriteFile( &file, pHeader, sizeof(TSFHeader) ) < sizeof(TSFHeader) ) {
OS_TPrintf( "Write : file header write error. %s\n", pPath );
goto END;
}
if( FS_WriteFile( &file, pSrcBody, (long)pHeader->bodyLength ) < pHeader->bodyLength ) {
OS_TPrintf( "Write : file body write error. %s\n", pPath );
goto END;
}
retval = TRUE;
END:
// ファイルクローズ
FS_CloseFile( &file );
return retval;
}
// TWLファイルのリカバリ
BOOL TSF_RecoveryFile( TSFReadResult err, char *pPath, u32 fileLength )
{
#define INITIAL_DATA_PATTERN 0xffffffff
#define READ_SIZE 1024
u32 buffer[ READ_SIZE / sizeof(u32) ];
u32 length;
BOOL retval = FALSE;
BOOL isWrite = FALSE;
FSFile file;
FS_InitFile( &file );
if( err == TSF_READ_RESULT_SUCCEEDED ) {
return TRUE;
}
// ファイル生成
if( err == TSF_READ_RESULT_ERROR_FILE_EXIST ) {
if( !FS_CreateFile( pPath, FS_PERMIT_R | FS_PERMIT_W ) ) {
OS_TPrintf( "Recovery: create file error. %s\n", pPath );
goto END2;
}
}
// ファイルオープン
if( !FS_OpenFileEx( &file, pPath, FS_FILEMODE_R | FS_FILEMODE_W ) ) {
OS_TPrintf( "Recovery : file open error. %s\n", pPath );
goto END2;
}
// ファイル長変更
if( ( err == TSF_READ_RESULT_ERROR_FILE_EXIST ) ||
( err == TSF_READ_RESULT_ERROR_FILE_LENGTH ) ) {
if( FS_SetFileLength( &file, fileLength ) != FS_RESULT_SUCCESS ) {
OS_TPrintf( "Recovery : set file length error. %s\n", pPath );
goto END;
}
}
// データベリファイ
MI_CpuFillFast( buffer, INITIAL_DATA_PATTERN, sizeof(buffer) );
length = fileLength;
while( length ) {
int i;
u32 rdSize = ( length > READ_SIZE ) ? READ_SIZE : length;
FS_ReadFile( &file, buffer, (s32)rdSize );
for( i = 0; i < rdSize / sizeof(u32); i++ ) {
if( buffer[ i ] != INITIAL_DATA_PATTERN ) {
isWrite = TRUE;
goto NEXT;
}
}
length -= rdSize;
}
NEXT:
// ベリファイエラーの場合は、ファイル内データ初期化0xff埋め
if( isWrite ) {
FS_SeekFile( &file, 0, FS_SEEK_SET );
length = fileLength;
while( length ) {
u32 wrSize = ( length > READ_SIZE ) ? READ_SIZE : length;
if( FS_WriteFile( &file, buffer, (s32)wrSize ) < wrSize ) {
OS_TPrintf( "Recovery : write error. %s\n", pPath );
goto END;
}
length -= wrSize;
}
}
retval = TRUE;
END:
// ファイルクローズ
FS_CloseFile( &file );
END2:
return retval;
}