/*---------------------------------------------------------------------------* Project: TwlIPL - NAMUT File: namut.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$ *---------------------------------------------------------------------------*/ // Nand Application Management UTility ライブラリ、略してNAMUTライブラリです。 // レイヤー的にはNAMと重なりますのでNAMに吸収しても良いと思います。 #include #include #include #include #include /*---------------------------------------------------------------------------* 定数定義 *---------------------------------------------------------------------------*/ // クリーンアップ実行時に // 指定ディレクトリ以下は全て消去されます。 // 指定ディレクトリ自体は残ります static const char* sDeleteDirectoryList[] = { "nand:/tmp" }; // クリーンアップ実行時に // 指定ファイルは0xffでFillされます。 static const char* sFillFileList[] = { "nand:/shared1/TWLCFG0.dat", "nand:/shared1/TWLCFG1.dat" }; // クリーンアップで消去しないタイトルを // TitleProperty (TitleID Hiの下位16bit)のビットで指定します。 // どれか1つでもビットが立っていれば消去の対象から外します。 #define PROTECT_TITLE_PROPERTY (TITLE_ID_HI_APP_TYPE_MASK) #define DIRECTORY_DEPTH_MAX 16 // ディレクトリの深さの最大(NANDの正規構成としては最大6) #define TITLE_PATH "nand:/title" #define TICKET_PATH "nand:/ticket" #define IMPORT_PATH "nand:/import" #define TITLE_ID_HI_SIZE 8 #define TITLE_LIST_MAX 256 #define CLEAR_DATA_SIZE 256 static const u8 sClearData[CLEAR_DATA_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /*---------------------------------------------------------------------------* 内部変数定義 *---------------------------------------------------------------------------*/ static FSDirectoryEntryInfo sEntryInfo; static NAMTitleId sTitleIdArray[TITLE_LIST_MAX]; /*---------------------------------------------------------------------------* 内部関数宣言 *---------------------------------------------------------------------------*/ static BOOL NAMUTi_DeleteNonprotectedTitle(void); static BOOL NAMUTi_DeleteNonprotectedTitleEntity(const char* path); static BOOL NAMUTi_ClearSavedataAll(BOOL fill); static BOOL NAMUTi_ClearSavedata(const char* path, BOOL fill); static BOOL NAMUTi_DeleteNandDirectory(const char *path); static BOOL NAMUTi_FillFile(const char* path); static void NAMUTi_DrawNandTree(s32 depth, const char *path); static void PrintDirectory(s32 depth, const char* path); static void PrintFile(s32 depth, const char* path); /*---------------------------------------------------------------------------* Name: NAMUT_Format Description: NANDのクリーンアップ (システム系の必要なファイルのみを残し他を消去します) Arguments: None Returns: None *---------------------------------------------------------------------------*/ BOOL NAMUT_Format(void) { int i; BOOL ret = TRUE; // プロテクトされていないタイトルの削除を行います ret &= NAMUTi_DeleteNonprotectedTitle(); // プロテクトタイトルのセーブデータをフォーマットします ret &= NAMUTi_ClearSavedataAll(TRUE); // 指定ファイルを0xffでクリアします for (i=0; i 0) { ret &= NAMUTi_ClearSavedata(savePublicPath, fill); } // privateSaveSizeが0以上なら0xFFクリア&フォーマット if (namTitleInfo.privateSaveSize > 0) { ret &= NAMUTi_ClearSavedata(savePrivatePath, fill); } } else { ret = FALSE; } } else { ret = FALSE; } } return ret; } /*---------------------------------------------------------------------------* Name: NAMUTi_ClearSavedata Description: 指定したセーブデータファイルに対して FFクリア&フォーマットを行います。 Arguments: fill : FFクリアを行うならTRUEを指定します Returns: None *---------------------------------------------------------------------------*/ static BOOL NAMUTi_ClearSavedata(const char* path, BOOL fill) { char drive[2] = { 'Z', '\0' }; FSFile file; BOOL ret = FALSE; // ファイル構造体初期化 FS_InitFile(&file); // セーブファイルオープン if (!FS_OpenFileEx(&file, path, (FS_FILEMODE_R|FS_FILEMODE_W))) { return FALSE; } // セーブファイルを0xFFでクリア if (fill) { u32 filesize = FS_GetFileLength(&file); for (; filesize > CLEAR_DATA_SIZE; filesize -= CLEAR_DATA_SIZE) { FS_WriteFile(&file, sClearData, CLEAR_DATA_SIZE); } FS_WriteFile(&file, sClearData, (s32)filesize); } // セーブファイルに対してマウント for (drive[0]='Z'; drive[0]>='A'; drive[0]--) { if (FATFS_MountDrive(drive, FATFS_MEDIA_TYPE_SUBNAND, (FATFSFileHandle)file.userdata)) { break; } } // マウント成功ならフォーマットする if (drive[0] >= 'A') { char drive_colon[3]; drive_colon[0] = drive[0]; drive_colon[1] = ':'; drive_colon[2] = '\0'; // メディアフォーマット if (FATFSi_FormatMedia(drive_colon)) { // ドライブフォーマット if (FATFS_FormatDrive(drive_colon)) { ret = TRUE; } } // アンマウント FATFS_UnmountDrive(drive); } // ファイルクローズ FS_CloseFile(&file); return ret; } /*---------------------------------------------------------------------------* Name: NAMUTi_FillFile Description: 指定したファイルを0xFFで埋めます。 Arguments: path Returns: None *---------------------------------------------------------------------------*/ static BOOL NAMUTi_FillFile(const char* path) { FSFile file; // ファイル構造体初期化 FS_InitFile(&file); // ファイルオープン if (FS_OpenFileEx(&file, path, (FS_FILEMODE_R|FS_FILEMODE_W))) { // ファイルを0xFFでクリア u32 filesize = FS_GetFileLength(&file); for (; filesize > CLEAR_DATA_SIZE; filesize -= CLEAR_DATA_SIZE) { FS_WriteFile(&file, sClearData, CLEAR_DATA_SIZE); } FS_WriteFile(&file, sClearData, (s32)filesize); FS_CloseFile(&file); } else { return FALSE; } return TRUE; } /*---------------------------------------------------------------------------* Name: NAMUT_DrawNandTree Description: NANDのツリー情報をプリント出力します Arguments: ... Returns: None. *---------------------------------------------------------------------------*/ void NAMUT_DrawNandTree(void) { NAMUTi_DrawNandTree(0, "nand:/"); } /*---------------------------------------------------------------------------* Name: NAMUTi_DrawNandTree Description: 指定パスのツリー情報をプリント出力します(再帰関数) Arguments: ... Returns: None. *---------------------------------------------------------------------------*/ static void NAMUTi_DrawNandTree(s32 depth, const char *path) { FSFile dir; PrintDirectory(depth, path); // 深さ制限 if (depth > DIRECTORY_DEPTH_MAX) { OS_TPrintf("Fail! Depth is too deep.\n"); return; } FS_InitFile(&dir); // 引数で指定されたディレクトリを開く if (!FS_OpenDirectory(&dir, path, (FS_FILEMODE_R|FS_FILEMODE_W))) { OS_TPrintf("%d Fail! FS_OpenDirectory(%s)\n", __LINE__, path); return; } // カレントディレクトリを設定する if (!FS_SetCurrentDirectory(path)) { OS_TPrintf("Fail! FS_SetCurrentDirectory(%s)\n", path); FS_CloseDirectory(&dir); return; } // ディレクトリの中身を読む while (FS_ReadDirectory(&dir, &sEntryInfo)) { if (STD_CompareString(sEntryInfo.longname, ".") == 0 || STD_CompareString(sEntryInfo.longname, "..") == 0) { continue; } // ディレクトリであれば再帰呼び出し if (!(sEntryInfo.attributes & FS_ATTRIBUTE_IS_DIRECTORY)) { // PrintFile(depth, sEntryInfo.longname); } else { NAMUTi_DrawNandTree(depth + 1, sEntryInfo.longname); } } // カレントディレクトリを元に戻します if (!FS_SetCurrentDirectory("..")) { OS_TPrintf("Fail! FS_SetCurrentDirectory(..)\n"); } FS_CloseDirectory(&dir); } /*---------------------------------------------------------------------------* Name: PrintDirectory Description: ツリー情報をプリント出力します(ディレクトリ用) Arguments: ... Returns: None. *---------------------------------------------------------------------------*/ static void PrintDirectory(s32 depth, const char* path) { int i; for (i=0; i