SystemUpdater

TAD をインポートする前に NandInitializer と同様の順序でソートするよう変更

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2757 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yoshida_teruhisa 2009-02-27 08:22:17 +00:00
parent 720f33a37d
commit 3c38336557
7 changed files with 436 additions and 15 deletions

View File

@ -85,7 +85,8 @@ SRCS = main.c \
process_mcu.c \
process_wireless_setting.c \
hwi.c \
debugger_hw_reset_control.c
debugger_hw_reset_control.c \
sort_title.c
LINCLUDES = ../../NandInitializerRed/common/include \
../../NandInitializerRed/ARM9.TWL/include \

View File

@ -21,7 +21,7 @@
#============================================================================
# SystemMenuファイルの置かれているフォルダを指定(相対もしくは絶対)
UPDATER_HOST_ROOT_DIR = s:/v1_2
UPDATER_HOST_ROOT_DIR = ./v1_2
# COMPILE SWITCH for build SystemUpdaterTRUEにすると、ダミーdev.kpを生成しないようになります。
FOR_LOTCHECK ?= FALSE
@ -79,7 +79,8 @@ SRCS = main.c \
process_nandfirm.c \
process_namut_format.c \
process_delete_other_region_sysmenu.c \
fade.c
fade.c \
sort_title.c
LINCLUDES = include \
../common/include \

View File

@ -73,7 +73,7 @@ extern BOOL ProcessFormat(void);
extern BOOL ProcessHwinfo(void);
extern void ProcessLog(void);
extern void ProcessFinish(BOOL result);
extern BOOL ProcessImport(void);
extern BOOL ProcessImport( void *(*alloc)(unsigned long), void (*free)(void *) );
extern BOOL ProcessWriteFont(void);
extern BOOL ProcessWriteCert(void);
extern BOOL ProcessWriteDummy(void);

View File

@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - SystemUpdaterRegionSelect
File: sort_title.h
Copyright 2008 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$
*---------------------------------------------------------------------------*/
/*
TitleID TitleSortSet
TitleSortSet SortTitle
使
#define FILE_NUM_MAX 256 // 手抜き
#define QSORT_BUF_SIZE ((8+1) * 8) // サイズは(log2(num)+1) * 8 bytes
char sFilePath[FILE_NUM_MAX][FS_ENTRY_LONGNAME_MAX];
TitleSortSet sTitleSortSet[FILE_NUM_MAX];
FSDirectoryEntryInfo info[1];
NAMTadInfo tadInfo;
char qsortBuf[QSORT_BUF_SIZE];
while ()
{
// info にファイル情報読み込み~
// tadInfo に tad 情報取得~
STD_CopyString( sFilePath[ counter ], info->longname );
sTitleSortSet[ counter ].titleID = tadInfo.titleInfo.titleId;
sTitleSortSet[ counter ].index = counter;
counter++;
}
SortTitle( sTitleSortSet, counter, qsortBuf );
// ソート完了
// 例えば、ソートされた順に要素を表示する場合は次のようにする。
for( i=0; i<counter; i++){
OS_Printf("%d : %s", i, sFilePath[ sTitleSortSet[ i ].index ]);
}
*/
#ifndef TWL_SORT_TITLE_H_
#define TWL_SORT_TITLE_H_
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
#include <twl.h>
/*===========================================================================*/
typedef struct {
OSTitleId titleID;
u32 index;
} TitleSortSet;
// TitleSortSet の配列をある法則にしたがってソートします。
// 内部で MATH_QSort を使用しているので、MATH_QSortStackSize() 関数で取得できる
// サイズの作業バッファを buf に与える必要があります。
// このサイズは (log2(num)+1) * 8 byte となっています。
// 作業バッファを渡さない場合には、スタックからこのサイズの作業領域が確保されます。
//
// info ソートする TitleSortSet 配列の先頭アドレス
// num ソートする配列の要素数
// buf 作業バッファ
void SortTitle( TitleSortSet *info, u32 num, void *buf );
/*===========================================================================*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* TWL_SORT_TITLE_H_ */
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/

View File

@ -189,7 +189,7 @@ TwlMain()
result &= ProcessWriteDummy();
// TADのインポート開始
result &= ProcessImport();
result &= ProcessImport( OS_AllocFromMain, OS_FreeToMain );
// 選択リージョン以外のSystemMenuの消去を行う
result &= ProcessDeleteOtherResionSysmenu();

View File

@ -28,6 +28,7 @@
#include "graphics.h"
#include "kami_global.h"
#include "font.h"
#include "sort_title.h"
/*---------------------------------------------------------------------------*
@ -39,6 +40,9 @@
#define THREAD_STACK_SIZE (16*1024)
#define DIR_NUM 3
#define FULLPATH_LEN ( FS_ENTRY_LONGNAME_MAX+6 )
static const char* sDirectoryNameRegion[] =
{
"japan",
@ -55,6 +59,11 @@ static const char* sDirectoryNameConsole[] =
"" // UNKNOWN
};
typedef struct {
u8 dirNameIndex;
char fileName[FS_ENTRY_LONGNAME_MAX];
} ImportFileInfo;
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
@ -74,6 +83,10 @@ static void Destructor(void* arg);
void ProgressDraw(f32 ratio);
BOOL ImportDirectoryTad(char* directory);
static u32 CountTadInDir( char (*dir_path)[FULLPATH_LEN], u32 dir_num );
static BOOL MakeList( char (*dir)[FULLPATH_LEN], u32 dir_max, ImportFileInfo *info, TitleSortSet *sortset );
static BOOL ImportTadFromList( char (*dir)[FULLPATH_LEN], ImportFileInfo *info, TitleSortSet *sortset, u32 import_max );
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
@ -87,13 +100,17 @@ BOOL ImportDirectoryTad(char* directory);
Returns:
*---------------------------------------------------------------------------*/
BOOL ProcessImport(void)
BOOL ProcessImport( void *(*alloc)(unsigned long), void (*free)(void *) )
{
const s32 MAX_RETRY_COUNT = 2;
BOOL result = TRUE;
char directory[FS_ENTRY_LONGNAME_MAX+6];
char directory[DIR_NUM][FULLPATH_LEN];
s32 i=0;
s32 j=0;
u32 fileCount = 0;
ImportFileInfo *importFileInfoList = NULL;
TitleSortSet *titleSortSetList = NULL;
void *sortBuf = NULL;
OS_WaitVBlankIntr();
NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 30, 256, 100);
@ -112,14 +129,30 @@ BOOL ProcessImport(void)
OS_WaitVBlankIntr();
}
STD_TSNPrintf(directory, sizeof(directory), "rom:/data/%s/%s/", sDirectoryNameConsole[GetConsole()], sDirectoryNameRegion[gRegion]);
result &= ImportDirectoryTad(directory);
STD_TSNPrintf(directory[0], sizeof(directory[0]), "rom:/data/%s/%s/", sDirectoryNameConsole[GetConsole()], sDirectoryNameRegion[gRegion]);
STD_TSNPrintf(directory[1], sizeof(directory[1]), "rom:/data/common/%s/", sDirectoryNameRegion[gRegion]);
STD_TSNPrintf(directory[2], sizeof(directory[2]), "rom:/data/common/");
// ディレクトリ内の TAD ファイル数をカウントする
fileCount = CountTadInDir(directory, DIR_NUM);
STD_TSNPrintf(directory, sizeof(directory), "rom:/data/common/%s/", sDirectoryNameRegion[gRegion]);
result &= ImportDirectoryTad(directory);
STD_TSNPrintf(directory, sizeof(directory), "rom:/data/common/");
result &= ImportDirectoryTad(directory);
// ファイル名+ディレクトリインデックス配列、TitleSortInfo 配列を確保
importFileInfoList = alloc( sizeof(ImportFileInfo) * fileCount );
titleSortSetList = alloc( sizeof(TitleSortSet) * fileCount );
// 情報を読み込む
result &= MakeList( directory, DIR_NUM, importFileInfoList, titleSortSetList);
// TitleSortInfoをソート
sortBuf = alloc( MATH_QSortStackSize( fileCount ) );
SortTitle( titleSortSetList, fileCount, sortBuf );
// インポート
result &= ImportTadFromList( directory, importFileInfoList, titleSortSetList, fileCount );
// もはや必要ないリストの解放
free( importFileInfoList );
free( titleSortSetList );
while (!FadeOutTick())
{
@ -129,6 +162,199 @@ BOOL ProcessImport(void)
return result;
}
/*---------------------------------------------------------------------------*
Name: CountTadInDir
Description: TAD
Arguments: dir_list,dir_max
Returns: u32
*---------------------------------------------------------------------------*/
static u32 CountTadInDir( char (*dir_list)[FULLPATH_LEN], u32 dir_max )
{
int l;
u32 count = 0;
for( l=0; l<dir_max; l++ )
{
char *dirName = dir_list[ l ];
FSFile dir;
FSDirectoryEntryInfo info[1];
FS_InitFile(&dir);
if (!FS_OpenDirectory(&dir, dirName, FS_FILEMODE_R))
{
// 空ディレクトリはMakerom時に削除されるようなのでここでは飛ばす
continue;
}
while (FS_ReadDirectory(&dir, info))
{
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0)
{
char* pExtension;
// 拡張子のチェック
pExtension = STD_SearchCharReverse( info->longname, '.');
if (pExtension)
{
if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") )
{
count++;
}
}
}
}
FS_CloseDirectory( &dir );
}
return count;
}
/*---------------------------------------------------------------------------*
Name: MakeList
Description: ImportTadFromList
Arguments: dir_list, dir_max, info, sortset
Returns: BOOL
*---------------------------------------------------------------------------*/
static BOOL MakeList( char (*dir_list)[FULLPATH_LEN], u32 dir_max, ImportFileInfo *info, TitleSortSet *sortset )
{
int l;
u32 count = 0;
BOOL result = TRUE;
for( l=0; l<dir_max; l++ )
{
char *dirName = dir_list[ l ];
FSFile dir;
FSDirectoryEntryInfo fsinfo[1];
FS_InitFile(&dir);
if (!FS_OpenDirectory(&dir, dirName, FS_FILEMODE_R))
{
// 空ディレクトリはMakerom時に削除されるようなのでここでは飛ばす
continue;
}
while (FS_ReadDirectory(&dir, fsinfo))
{
if ((fsinfo->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0)
{
char* pExtension;
// 拡張子のチェック
pExtension = STD_SearchCharReverse( fsinfo->longname, '.');
if (pExtension)
{
if (!STD_CompareString( pExtension, ".tad") || !STD_CompareString( pExtension, ".TAD") )
{
NAMTadInfo tadInfo;
char fullPath[FULLPATH_LEN];
// フルパス作成
STD_TSNPrintf(fullPath, sizeof(fullPath), "%s/%s", dirName, fsinfo->longname);
// TAD情報取得
// tadファイルの情報取得
if (NAM_ReadTadInfo(&tadInfo, fullPath) != NAM_OK)
{
// 失敗したらエラーを表示して次のファイルへ、結果はFalse
kamiFontPrintfConsole(CONSOLE_RED, "Error NAM_ReadTadInfo()\n");
kamiFontPrintfConsole(CONSOLE_RED, "file : %s\n",fsinfo->longname);
result = FALSE;
continue;
}
// ImportFileInfo と TitleSortSet に情報を転載
info[count].dirNameIndex = (u8)l;
STD_TSNPrintf(info[count].fileName, FS_ENTRY_LONGNAME_MAX, fsinfo->longname);
sortset[count].index = count;
sortset[count].titleID = tadInfo.titleInfo.titleId;
count++;
}
}
}
}
}
return result;
}
/*---------------------------------------------------------------------------*
Name: ImportTadFromList
Description: MakeList TAD
Arguments: dir_list, info, sortset, import_max
Returns: BOOL
*---------------------------------------------------------------------------*/
static BOOL ImportTadFromList( char (*dir_list)[FULLPATH_LEN], ImportFileInfo *info, TitleSortSet *sortset, u32 import_max )
{
int l;
int j;
BOOL result = TRUE;
s32 listNo=0;
for( l=0; l<import_max; l++ )
{
char *longName = info[ sortset[ l ].index ].fileName;
char *dirName = dir_list[ info[ sortset[ l ].index ].dirNameIndex ];
char fullPath[FULLPATH_LEN];
char string1[256];
u16 string2[256];
const s32 MAX_RETRY_COUNT = 2;
s32 nam_result;
char *tlo = (char *)( &sortset[ l ].titleID );
// フルパス作成
STD_TSNPrintf(fullPath, sizeof(fullPath), "%s/%s", dirName, longName);
// インポート
STD_TSPrintf(string1, "List %d ", ++listNo);
MI_CpuClear8(string2, sizeof(string2));
STD_ConvertStringSjisToUnicode(string2, NULL, string1, NULL, NULL);
NNS_G2dCharCanvasClearArea(&gCanvas, TXT_COLOR_WHITE, 0, 60, 256, 20);
NNS_G2dTextCanvasDrawText(&gTextCanvas, 40, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)L"Now Import..");
NNS_G2dTextCanvasDrawText(&gTextCanvas, 135, 60,
TXT_COLOR_WHITE_BASE, TXT_DRAWTEXT_FLAG_DEFAULT, (const char*)string2);
// MAX_RETRY_COUNTまでリトライする
for (j=0; j<MAX_RETRY_COUNT; j++)
{
nam_result = kamiImportTad(fullPath, j);
if (nam_result == NAM_OK)
{
break;
}
else
{
kamiFontPrintfConsole(CONSOLE_GREEN, "Import %d Retry!\n", listNo);
}
}
if ( nam_result == NAM_OK)
{
// kamiFontPrintfConsole(FONT_COLOR_GREEN, "List : %d(%c%c%c%c) Import Success.\n", listNo, tlo[3], tlo[2], tlo[1], tlo[0] );
kamiFontPrintfConsole(FONT_COLOR_GREEN, "List : %d Import Success.\n", listNo );
}
else
{
// kamiFontPrintfConsole(FONT_COLOR_RED, "Error: %d(%c%c%c%c) : RetCode = %d\n", listNo, tlo[3], tlo[2], tlo[1], tlo[0], nam_result );
kamiFontPrintfConsole(FONT_COLOR_RED, "Error: %d : RetCode = %d\n", listNo, nam_result );
result = FALSE;
}
kamiFontLoadScreenData();
}
return result;
}
/*---------------------------------------------------------------------------*
Name: ImportDirectoryTad
@ -144,7 +370,7 @@ BOOL ImportDirectoryTad(char* directory)
FSDirectoryEntryInfo info[1];
const s32 MAX_RETRY_COUNT = 2;
BOOL result = TRUE;
char full_path[FS_ENTRY_LONGNAME_MAX+6];
char full_path[FULLPATH_LEN];
static s32 listNo=0;
s32 j=0;
@ -157,6 +383,10 @@ BOOL ImportDirectoryTad(char* directory)
}
// tadファイルを検索してインポート
// [TODO:]先にfull_pathのリストを作って、NAM_ReadTadInfoで取れるTitleID_loの値でソートしてから
// 順番にインポートするように変更する。
// この関数を分けるイメージで、各フォルダの名称リストを先に作成する
//
while (FS_ReadDirectory(&dir, info))
{
s32 nam_result;

View File

@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - SystemUpdaterRegionSelect
File: sort_title.c
Copyright 2008 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 "sort_title.h"
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
// ソート用 Compare 関数
static s32 TitleCompareFunc(void *elem1, void *elem2)
{
TitleSortSet *ipp1 = (TitleSortSet *)elem1;
TitleSortSet *ipp2 = (TitleSortSet *)elem2;
u32 titleID_lo1 = (u32)(0xffffffff & ipp1->titleID);
u32 titleID_lo2 = (u32)(0xffffffff & ipp2->titleID);
BOOL isSystem1 = (u32)( 0x1 & ( ipp1->titleID >> 32 ) ) ? TRUE : FALSE;
BOOL isSystem2 = (u32)( 0x1 & ( ipp2->titleID >> 32 ) ) ? TRUE : FALSE;
BOOL isH1 = ( (u8)( 0xff & ( titleID_lo1 >> 24 ) ) == 'H' ) ? TRUE : FALSE;
BOOL isH2 = ( (u8)( 0xff & ( titleID_lo2 >> 24 ) ) == 'H' ) ? TRUE : FALSE;
if( isSystem1 && !isSystem2 )
{
// 要素1が System であり、要素2が System でない場合、要素1が前 (-1)
return -1;
}else if( !isSystem1 && isSystem2 )
{
// 要素1が System でなく、要素2が System である場合、要素1が後 (1)
return 1;
}else if( isH1 && !isH2 )
{
// 要素1が "H***" であり、要素2が "H***" でない場合、要素1が前 (-1)
return -1;
}else if( !isH1 && isH2 )
{
// 要素1が "H***" でなく、要素2が "H***" である場合、要素1が後 (1)
return 1;
}else
{
// その他の場合、titleID_loの小さいほうが前
return ( titleID_lo1 > titleID_lo2 ) ?
1 :
( (titleID_lo1 < titleID_lo2) ? -1 : 0 );
}
}
// TitleSortSet の配列をある法則にしたがってソートします。
// 内部で MATH_QSort を使用しているので、MATH_QSortStackSize() 関数で取得できる
// サイズの作業バッファを buf に与える必要があります。
// このサイズは (log2(num)+1) * 8 byte となっています。
// 作業バッファを渡さない場合には、スタックからこのサイズの作業領域が確保されます。
//
// info ソートする TitleSortSet 配列の先頭アドレス
// num ソートする配列の要素数
// buf 作業バッファ
void SortTitle( TitleSortSet *info, u32 num, void *buf )
{
MATH_QSort( info, num, sizeof(TitleSortSet), TitleCompareFunc, buf );
}