mirror of
https://github.com/rvtr/TwlToolsRED.git
synced 2025-10-31 06:41:18 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@521 7061adef-622a-194b-ae81-725974e89856
607 lines
17 KiB
C
607 lines
17 KiB
C
/********************************************************************/
|
||
/* main.c */
|
||
/* SaveDataCleaner */
|
||
/* */
|
||
/* Copyright (C) 2003-2006 NINTENDO Co.,Ltd. */
|
||
/********************************************************************/
|
||
/*
|
||
ƒ<>ƒCƒ“
|
||
*/
|
||
|
||
#include <twl.h>
|
||
#include <twl/aes.h>
|
||
#include <twl/na.h>
|
||
#include <twl/na/ARM9/init.h>
|
||
#include <twl/sea.h>
|
||
#include <twl/nam.h>
|
||
#include "myChar.h"
|
||
#include "myFunc.h"
|
||
|
||
|
||
// define data-----------------------------------------------------------------
|
||
#define MY_DEBUG 0
|
||
|
||
#define ROUND_UP(value, alignment) \
|
||
(((u32)(value) + (alignment-1)) & ~(alignment-1))
|
||
|
||
#define STREAMING_BUFFER_SIZE (128 * 1024)
|
||
#define TITLEID_HI_USER_NAND 0x0003000400000000LL
|
||
#define TARGET_INITIALCODE_SPEC_FILE "SaveDataCleaner.spec"
|
||
|
||
// extern data-----------------------------------------------------------------
|
||
|
||
// function's prototype--------------------------------------------------------
|
||
static void INTR_VBlank( void );
|
||
static void InitHeap( void );
|
||
BOOL SearchTitle( OSTitleId titleID, BOOL *pIsPrivSave, BOOL *pIsPubSave );
|
||
BOOL CleanupSaveDataDrive( const char *pDriveName , OSTitleId titleID );
|
||
BOOL CreateFileWithLength( char *path, u32 length );
|
||
BOOL DeleteDirectoryRecursively( const char *path );
|
||
BOOL FillFileRandom( const char* path );
|
||
BOOL DumpFile( const char* pPath );
|
||
BOOL ReadTargetFileFromSD( const char *pFilename, char **ppDst, u32 *pFileSize );
|
||
|
||
// global variables------------------------------------------------------------
|
||
u8 targetGameCode[ 5 ] = { 'K', 'E', 'N', 'J', 0x00 };
|
||
|
||
// static variables------------------------------------------------------------
|
||
static u8 sStreamBuffer[ STREAMING_BUFFER_SIZE ] ATTRIBUTE_ALIGN(32);
|
||
static FSFATFSArchiveWork sOtherTitleWork ATTRIBUTE_ALIGN(32);
|
||
|
||
// const data------------------------------------------------------------------
|
||
|
||
|
||
// ============================================================================
|
||
// function's description
|
||
// ============================================================================
|
||
void TwlMain(void)
|
||
{
|
||
BOOL isFound = FALSE;
|
||
BOOL isPrivSave = FALSE;
|
||
BOOL isPubSave = FALSE;
|
||
BOOL isFailed = FALSE;
|
||
BOOL isAutoExe = TRUE;
|
||
u16 pad_old = 0;
|
||
u16 pad = 0;
|
||
u16 trg = 0;
|
||
OSTitleId titleID;
|
||
|
||
(void)OS_EnableIrq();
|
||
(void)OS_EnableInterrupts();
|
||
|
||
OS_Init();
|
||
SEA_Init();
|
||
FS_Init( 3 );
|
||
// AES_Init();
|
||
|
||
InitHeap();
|
||
InitDispMain();
|
||
InitDispSub ();
|
||
|
||
NAM_Init( OS_AllocFromMain, OS_FreeToMain );
|
||
|
||
// Vƒuƒ‰ƒ“ƒNŠ„‚è<E2809A>ž‚Ý‹–‰Â----------------------------
|
||
(void)OS_SetIrqFunction( OS_IE_V_BLANK, INTR_VBlank );
|
||
(void)OS_EnableIrqMask ( OS_IE_V_BLANK );
|
||
(void)GX_VBlankIntr( TRUE );
|
||
|
||
//---- •\ަŠJŽn
|
||
GX_DispOn();
|
||
GXS_DispOn();
|
||
|
||
PrintStringS( 1, 0, YELLOW, "SaveData Clearner" );
|
||
|
||
// SDƒJ<C692>[ƒh<C692>ã‚ÌSPECƒtƒ@ƒCƒ‹‚©‚ç<E2809A>Aƒ^<5E>[ƒQƒbƒg‚ÌGameCode‚ð“Ç‚Ý<E2809A>ž‚Ý
|
||
#if USE_SDCARD
|
||
{
|
||
u32 size;
|
||
char *pSrc = TARGET_INITIALCODE_SPEC_FILE;
|
||
char *pSDFileBuffer;
|
||
if( !ReadTargetFileFromSD( pSrc, &pSDFileBuffer, &size ) ) {
|
||
PrintStringS( 1, 6, RED, "SD card specfile read failed." );
|
||
PrintStringS( 1, 8, WHITE, "Please set" );
|
||
PrintStringS( 1, 10, WHITE, " \"%s\"", TARGET_INITIALCODE_SPEC_FILE );
|
||
SVC_WaitVBlankIntr();
|
||
OS_Terminate();
|
||
}
|
||
if( !STD_TSScanf( pSDFileBuffer, "%4s", targetGameCode ) ||
|
||
STD_StrLen( (const char *)targetGameCode ) != 4 ) {
|
||
PrintStringS( 1, 6, RED, "SD card specfile format failed." );
|
||
PrintStringS( 1, 8, WHITE, "Please set InitialCode." );
|
||
SVC_WaitVBlankIntr();
|
||
OS_Terminate();
|
||
}
|
||
OS_TPrintf( "%s\n", targetGameCode );
|
||
OS_Free( pSDFileBuffer );
|
||
}
|
||
#endif
|
||
|
||
// targetGameCode ‚©‚ç titleID ‚ð<E2809A>ì<EFBFBD>¬
|
||
{
|
||
int i;
|
||
u8 *pDst = (u8 *)&titleID;
|
||
titleID = TITLEID_HI_USER_NAND;
|
||
for( i = 0; i < 4; i++ ) {
|
||
*pDst++ = targetGameCode[ 3 -i ];
|
||
}
|
||
}
|
||
|
||
// ƒZ<C692>[ƒuƒf<C692>[ƒ^ƒT<C692>[ƒ`
|
||
isFound = SearchTitle( titleID, &isPrivSave, &isPubSave );
|
||
PrintStringS( 1, 6, WHITE, "InitialCode : %s", targetGameCode );
|
||
if( isFound ) {
|
||
PrintStringS( 1, 8, GREEN, "application found.", targetGameCode );
|
||
PrintStringS( 1, 10, WHITE, "Press [A] to Cleanup START." );
|
||
PrintStringS( 1, 11, WHITE, "Press [B] to STOP." );
|
||
}else {
|
||
PrintStringS( 1, 8, YELLOW, "application not found.", targetGameCode );
|
||
*(u16 *)0x05000006 = myPalette[ YELLOW ][ 1 ];
|
||
}
|
||
SVC_WaitVBlankIntr();
|
||
|
||
// ƒ<>ƒCƒ“ƒ‹<C692>[ƒv----------------------------
|
||
trg = PAD_Read(); // ƒpƒbƒhƒf<C692>[ƒ^“ǂݎæ‚è
|
||
while( isFound ){
|
||
// ƒpƒbƒhƒf<C692>[ƒ^“ǂݎæ‚è
|
||
pad_old = pad;
|
||
pad = PAD_Read();
|
||
trg = (u16)( pad ^ pad_old );
|
||
|
||
if( ( trg & ( PAD_BUTTON_A | PAD_BUTTON_B ) ) || isAutoExe ) {
|
||
ClearRectangleS( 1, 10, 31, 1 );
|
||
ClearRectangleS( 1, 11, 31, 1 );
|
||
}
|
||
if( ( trg & PAD_BUTTON_A ) || isAutoExe ) {
|
||
// ƒZ<C692>[ƒuƒf<C692>[ƒ^ƒNƒŠƒAŽÀ<C5BD>s
|
||
// PrivateƒZ<C692>[ƒuƒf<C692>[ƒ^
|
||
PrintStringS( 1, 10, WHITE, "Private Save:" );
|
||
if( isPrivSave ) {
|
||
PrintStringS( 14, 10, YELLOW, "cleanup executing..." );
|
||
if( CleanupSaveDataDrive( "otherPrv", titleID ) ) {
|
||
PrintStringS( 14, 10, GREEN, "cleanup succeedded. " );
|
||
}else {
|
||
PrintStringS( 14, 10, RED, "cleanup failed. " );
|
||
isFailed = TRUE;
|
||
}
|
||
}else {
|
||
PrintStringS( 14, 10, YELLOW, "not existed." );
|
||
}
|
||
|
||
// PublicƒZ<C692>[ƒuƒf<C692>[ƒ^
|
||
PrintStringS( 1, 11, WHITE, "Public Save:" );
|
||
if( isPubSave ) {
|
||
PrintStringS( 14, 11, YELLOW, "cleanup executing." );
|
||
if( CleanupSaveDataDrive( "otherPub", titleID ) ) {
|
||
PrintStringS( 14, 11, GREEN, "cleanup succeedded. " );
|
||
}else {
|
||
PrintStringS( 14, 11, RED, "cleanup failed. " );
|
||
isFailed = TRUE;
|
||
}
|
||
}else {
|
||
PrintStringS( 14, 11, YELLOW, "not existed." );
|
||
}
|
||
|
||
PrintStringS( 1, 12, WHITE, "Application :" );
|
||
PrintStringS( 14, 12, YELLOW, "cleanup executing." );
|
||
if( NAM_DeleteTitle( titleID ) == NAM_OK ) {
|
||
PrintStringS( 14, 12, GREEN, "cleanup succeedded. " );
|
||
}else {
|
||
PrintStringS( 14, 12, RED, "cleanup failed. " );
|
||
isFailed = TRUE;
|
||
}
|
||
if( isFailed ) {
|
||
*(u16 *)0x05000006 = myPalette[ RED ][ 1 ];
|
||
}else {
|
||
*(u16 *)0x05000006 = myPalette[ LIGHTGREEN ][ 1 ];
|
||
}
|
||
break;
|
||
}else if( trg & PAD_BUTTON_B ) {
|
||
// ƒZ<C692>[ƒuƒf<C692>[ƒ^ƒNƒŠƒAƒLƒƒƒ“ƒZƒ‹<C692>B
|
||
PrintStringS( 1, 10, YELLOW, "Cancel SaveData cleanup." );
|
||
break;
|
||
}
|
||
SVC_WaitVBlankIntr(); // Vƒuƒ‰ƒ“ƒNŠ„<C5A0>ž<EFBFBD>I—¹‘Ò‚¿
|
||
}
|
||
|
||
SVC_WaitVBlankIntr();
|
||
OS_Terminate();
|
||
}
|
||
|
||
// Vƒuƒ‰ƒ“ƒNŠ„‚è<E2809A>ž‚Ý
|
||
static void INTR_VBlank(void)
|
||
{
|
||
//---- BG-VRAM‚Ì<E2809A>X<EFBFBD>V
|
||
DC_FlushRange( bg0BakM, sizeof(bg0BakM) );
|
||
MI_CpuCopyFast ( bg0BakM, (void*)( HW_BG_VRAM + BG0_SCREEN_BASE ), sizeof(bg0BakM) );
|
||
DC_FlushRange( bg0BakS, sizeof(bg0BakS) );
|
||
MI_CpuCopyFast ( bg0BakS, (void*)( HW_DB_BG_VRAM + BG0_SCREEN_BASE ), sizeof(bg0BakS) );
|
||
//---- Š„‚è<E2809A>ž‚݃`ƒFƒbƒNƒtƒ‰ƒO
|
||
OS_SetIrqCheckFlag( OS_IE_V_BLANK );
|
||
}
|
||
|
||
|
||
// ƒq<C692>[ƒv<C692>‰Šú‰»
|
||
static void InitHeap( void )
|
||
{
|
||
void* tempLo;
|
||
OSHeapHandle hh;
|
||
|
||
// ƒ<>ƒCƒ“ƒ<E2809C>ƒ‚ƒŠ<C692>ã‚̃AƒŠ<C692>[ƒi‚Ƀq<C692>[ƒv‚ð‚ЂƂÂ<E2809A>ì<EFBFBD>¬
|
||
tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
|
||
OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
|
||
hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
|
||
if (hh < 0) {
|
||
// ƒq<C692>[ƒv<C692>ì<EFBFBD>¬‚ÉŽ¸”s‚µ‚½<E2809A>ê<EFBFBD>‡‚͈Ù<CB86>í<EFBFBD>I—¹
|
||
OS_Panic("ARM9: Fail to create heap...\n");
|
||
}
|
||
(void)OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
ŠÖ<C5A0>”’è‹`
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
// Žw’èƒ^ƒCƒgƒ‹‚ª‘¶<E28098>Ý‚·‚é‚©Šm”F‚µ<E2809A>A‘¶<E28098>Ý‚·‚é‚È‚ç<E2809A>AsameMakerFlag ‚ð‹<E280B9>§ƒZƒbƒg‚µ<E2809A>APrivateƒZ<C692>[ƒuƒf<C692>[ƒ^<5E>APublicƒZ<C692>[ƒuƒf<C692>[ƒ^‚Ì‘¶<E28098>Ý—L–³‚ð•Ô‚·<E2809A>B
|
||
BOOL SearchTitle( OSTitleId titleID, BOOL *pIsPrivSave, BOOL *pIsPubSave )
|
||
{
|
||
int i;
|
||
int index, shift;
|
||
|
||
OSTitleIDList *pList = (OSTitleIDList *)HW_OS_TITLE_ID_LIST;
|
||
for ( i = 0; i < pList->num; i++ ) {
|
||
if( pList->TitleID[ i ] == titleID ) {
|
||
break;
|
||
}
|
||
}
|
||
if( i == pList->num ) {
|
||
*pIsPrivSave = FALSE;
|
||
*pIsPubSave = FALSE;
|
||
return FALSE;
|
||
}
|
||
index = i >> 3;
|
||
shift = i % 8;
|
||
pList->sameMakerFlag[ index ] |= 0x01 << shift;
|
||
// pList->privateFlag[ index ] |= 0x01 << shift; // ƒ†<C692>[ƒU<C692>[ƒAƒvƒŠ‚È‚ç<E2809A>AprivateFlag‚à–â‘è‚È‚¢‚Í‚¸<E2809A>B
|
||
*pIsPrivSave = ( pList->privateFlag[ index ] & ( 0x01 << shift ) ) ? TRUE : FALSE;
|
||
*pIsPubSave = ( pList->publicFlag [ index ] & ( 0x01 << shift ) ) ? TRUE : FALSE;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Žw’肳‚ꂽƒZ<C692>[ƒuƒf<C692>[ƒ^ƒhƒ‰ƒCƒu‚̃Z<C692>[ƒuƒf<C692>[ƒ^<5E>Á‹Ž
|
||
BOOL CleanupSaveDataDrive( const char *pDriveName , OSTitleId titleID ) // otherPrv, otherPub
|
||
{
|
||
#define TEMP_FILE "temp.bin"
|
||
BOOL result = TRUE;
|
||
FSArchiveResource rsc, rsc2;
|
||
char path[ FS_ENTRY_LONGNAME_MAX ];
|
||
|
||
if( pDriveName == NULL ) {
|
||
OS_TPrintf( "drive name invalid.\n" );
|
||
return FALSE;
|
||
}
|
||
|
||
// PrivateƒZ<C692>[ƒuƒf<C692>[ƒ^‚ðƒ}ƒEƒ“ƒg
|
||
if( FSi_MountSpecialArchive( titleID, pDriveName, &sOtherTitleWork) != FS_RESULT_SUCCESS ) {
|
||
return FALSE;
|
||
}
|
||
|
||
// PrivateƒZ<C692>[ƒuƒf<C692>[ƒ^ƒhƒ‰ƒCƒu<C692>ã‚Ì‘Sƒf<C692>[ƒ^<5E>í<EFBFBD>œ
|
||
STD_TSPrintf( path, "%s:/", pDriveName );
|
||
if( !DeleteDirectoryRecursively( path ) ) {
|
||
OS_TPrintf( "%s delete recursively failed.\n", path );
|
||
result = FALSE;
|
||
goto END;
|
||
}
|
||
|
||
// ƒhƒ‰ƒCƒu‚̋󂫗̈æ‚ðŽæ“¾
|
||
if( !FS_GetArchiveResource( path, &rsc ) ) {
|
||
OS_TPrintf( "FS_GetArchiveResource(%s) failed : code = %08x\n", path, FS_GetArchiveResultCode( &rsc ) );
|
||
result = FALSE;
|
||
goto END;
|
||
}
|
||
|
||
// ‹ó‚«—̈悪32bit‚ð’´‚¦‚Ä‚¢‚½<E2809A>ê<EFBFBD>‡‚̓Gƒ‰<C692>[
|
||
if( rsc.availableSize > 0x0000000100000000LL ) {
|
||
OS_TPrintf( "%s : availableSize over 32bit.\n", pDriveName );
|
||
result = FALSE;
|
||
goto END;
|
||
}
|
||
|
||
STD_TSPrintf( path, "%s:/%s", pDriveName, TEMP_FILE );
|
||
|
||
#if MY_DEBUG
|
||
(void)CreateFileWithLength( path, (u32)rsc.availableSize );
|
||
(void)DumpFile( path );
|
||
(void)FS_DeleteFile( path );
|
||
#endif
|
||
|
||
// ƒhƒ‰ƒCƒu‚̋󂫃TƒCƒYMAX‚Å<E2809A>ATEMPƒtƒ@ƒCƒ‹<C692>¶<EFBFBD>¬
|
||
if( !CreateFileWithLength( path, (u32)rsc.availableSize ) ) {
|
||
OS_TPrintf( "CreateFileWithLength(%s, %08x) failed.\n", path, (u32)rsc.availableSize );
|
||
result = FALSE;
|
||
goto END;
|
||
}
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒ‰ƒ“ƒ_ƒ€ƒtƒBƒ‹
|
||
if( !FillFileRandom( path ) ) {
|
||
OS_TPrintf( "FillFileRandom(%s) failed.\n", path );
|
||
result = FALSE;
|
||
}
|
||
|
||
// ƒtƒ@ƒCƒ‹<C692>í<EFBFBD>œ
|
||
if( !FS_DeleteFile( path ) ) {
|
||
OS_TPrintf( "FS_DeleteFile(%s) failed.\n", path );
|
||
result = FALSE;
|
||
}
|
||
|
||
// <20>Ä“xƒhƒ‰ƒCƒu‚̋󂫗̈æ‚ðŽæ“¾
|
||
if( !FS_GetArchiveResource( path, &rsc2 ) ) {
|
||
OS_TPrintf( "FS_GetArchiveResource(%s) failed : code = %08x\n", path, FS_GetArchiveResultCode( &rsc2 ) );
|
||
result = FALSE;
|
||
}
|
||
|
||
#if MY_DEBUG
|
||
(void)CreateFileWithLength( path, (u32)rsc.availableSize );
|
||
(void)DumpFile( path );
|
||
(void)FS_DeleteFile( path );
|
||
#endif
|
||
|
||
// ‹ó‚«ƒTƒCƒY‚ª“¯‚¶‚©ƒ`ƒFƒbƒN
|
||
OS_TPrintf( "Before available size : %016llx\n", rsc.availableSize );
|
||
OS_TPrintf( "After available size : %016llx\n", rsc2.availableSize );
|
||
if( rsc.availableSize != rsc2.availableSize ) {
|
||
OS_TPrintf( "available size error.\n" );
|
||
result = FALSE;
|
||
}
|
||
|
||
END:
|
||
// ƒZ<C692>[ƒuƒf<C692>[ƒ^‚̃}ƒEƒ“ƒg‰ð<E280B0>œ
|
||
(void)FSi_MountSpecialArchive(0, NULL, &sOtherTitleWork);
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
// Žw’èƒpƒXˆÈ‰º‚̃fƒBƒŒƒNƒgƒŠ‚ð<E2809A>Á‹Ž
|
||
BOOL DeleteDirectoryRecursively( const char *pPath )
|
||
{
|
||
FSFile dir;
|
||
FSDirectoryEntryInfo entryInfo;
|
||
BOOL ret = TRUE;
|
||
char path[ FS_ENTRY_LONGNAME_MAX ];
|
||
|
||
FS_InitFile( &dir );
|
||
|
||
// ˆø<CB86>”‚ÅŽw’肳‚ꂽƒfƒBƒŒƒNƒgƒŠ‚ðŠJ‚
|
||
if ( !FS_OpenDirectory( &dir, pPath, FS_FILEMODE_R ) ) {
|
||
OS_TWarning( "Fail! FS_OpenDirectory(%s) in %s\n", pPath, __func__ );
|
||
return FALSE;
|
||
}
|
||
|
||
// ƒfƒBƒŒƒNƒgƒŠ‚Ì’†<E28099>g‚ð“Ç‚Þ
|
||
while ( FS_ReadDirectory( &dir, &entryInfo ) )
|
||
{
|
||
if ( STD_CompareString( entryInfo.longname, "." ) == 0 ||
|
||
STD_CompareString( entryInfo.longname, ".." ) == 0 ) {
|
||
continue;
|
||
}
|
||
|
||
STD_CopyLString( path, pPath, FS_ENTRY_LONGNAME_MAX );
|
||
STD_ConcatenateLString( path, "/", FS_ENTRY_LONGNAME_MAX );
|
||
STD_ConcatenateLString( path, entryInfo.longname, FS_ENTRY_LONGNAME_MAX );
|
||
|
||
// ƒfƒBƒŒƒNƒgƒŠ
|
||
if (entryInfo.attributes & FS_ATTRIBUTE_IS_DIRECTORY) {
|
||
if (!FS_DeleteDirectoryAuto(path)) {
|
||
ret = FALSE;
|
||
OS_TWarning( "Fail! FS_DeleteDirectoryAuto(%s) in %s\n", path, __func__ );
|
||
}
|
||
}else {
|
||
// ƒtƒ@ƒCƒ‹
|
||
if ( !FS_DeleteFileAuto( path ) ) {
|
||
ret = FALSE;
|
||
OS_TWarning( "Fail! FS_DeleteFileAuto(%s) in %s\n", path, __func__ );
|
||
}
|
||
}
|
||
}
|
||
|
||
// ƒfƒBƒŒƒNƒgƒŠ‚ð•‚¶‚é
|
||
FS_CloseDirectory( &dir );
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
// Žw’èƒtƒ@ƒCƒ‹‚ðŽw’èƒTƒCƒY‚Å<E2809A>ì<EFBFBD>¬
|
||
BOOL CreateFileWithLength( char *path, u32 length )
|
||
{
|
||
FSFile file;
|
||
BOOL result = TRUE;
|
||
|
||
// PrivateƒZ<C692>[ƒuƒf<C692>[ƒ^ƒhƒ‰ƒCƒu<C692>ã‚ÉTEMPƒtƒ@ƒCƒ‹<C692>ì<EFBFBD>¬
|
||
if ( !FS_CreateFile( path, FS_PERMIT_R | FS_PERMIT_RW ) )
|
||
{
|
||
OS_TPrintf( "FS_CreateFile(%s) failed.\n", path );
|
||
return FALSE;
|
||
}
|
||
|
||
// TEMPƒtƒ@ƒCƒ‹ƒI<C692>[ƒvƒ“
|
||
FS_InitFile(&file);
|
||
if ( !FS_OpenFileEx( &file, path, FS_FILEMODE_W ) )
|
||
{
|
||
OS_TPrintf( "FS_OpenFile(%s) failed.\n", path );
|
||
result = FALSE;
|
||
goto END;
|
||
}
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒTƒCƒY‚ðƒZƒbƒg
|
||
if ( FS_SetFileLength( &file, length ) != FS_RESULT_SUCCESS )
|
||
{
|
||
OS_TPrintf( "FS_SetFileLength(%s) failed.\n", path );
|
||
result = FALSE;
|
||
}
|
||
|
||
END:
|
||
// ƒtƒ@ƒCƒ‹ƒNƒ<4E><C692>[ƒY
|
||
(void)FS_CloseFile( &file );
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
// Žw’èƒtƒ@ƒCƒ‹‚ðƒ‰ƒ“ƒ_ƒ€ƒf<C692>[ƒ^‚ŃtƒBƒ‹
|
||
BOOL FillFileRandom( const char* pPath )
|
||
{
|
||
u64 seed;
|
||
MATHRandContext32 rndctx;
|
||
u32 *pBuffer = (u32 *)sStreamBuffer;
|
||
s32 result = TRUE;
|
||
FSFile f;
|
||
|
||
// —<><E28094>”‚ÌSEED<45>Ý’è
|
||
if( AES_Rand( &seed, sizeof(seed) ) != AES_RESULT_SUCCESS ) {
|
||
return FALSE;
|
||
}
|
||
MATH_InitRand32( &rndctx, seed );
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒtƒBƒ‹
|
||
FS_InitFile( &f );
|
||
if( !FS_OpenFileEx( &f, pPath, FS_FILEMODE_RWL ) ) {
|
||
return FALSE;
|
||
}else {
|
||
u32 fileSize;
|
||
u32 current;
|
||
|
||
fileSize = FS_GetFileLength(&f);
|
||
|
||
for( current = 0; current < fileSize; current += STREAMING_BUFFER_SIZE ) {
|
||
const u32 nextSize = MATH_MIN( STREAMING_BUFFER_SIZE, fileSize - current);
|
||
const u32 nextU32 = MATH_DIVUP( nextSize, sizeof(u32) );
|
||
u32 i;
|
||
s32 writtenSize;
|
||
u32* p = pBuffer;
|
||
|
||
for( i = 0; i < nextU32; ++i ) {
|
||
*p++ = MATH_Rand32( &rndctx, 0 );
|
||
}
|
||
|
||
writtenSize = FS_WriteFile( &f, pBuffer, (s32)nextSize );
|
||
|
||
if( writtenSize != (s32)nextSize ) {
|
||
result = FALSE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
(void)FS_CloseFile( &f );
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
// Žw’èƒtƒ@ƒCƒ‹‚ðƒXƒgƒŠ<C692>[ƒ€ƒoƒbƒtƒ@‚ɓǂݎ̂Ä
|
||
BOOL DumpFile( const char* pPath )
|
||
{
|
||
u32 *pBuffer = (u32 *)sStreamBuffer;
|
||
s32 result = TRUE;
|
||
FSFile f;
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒtƒBƒ‹
|
||
FS_InitFile( &f );
|
||
if( !FS_OpenFileEx( &f, pPath, FS_FILEMODE_R ) ) {
|
||
return FALSE;
|
||
}else {
|
||
u32 fileSize;
|
||
u32 current;
|
||
|
||
fileSize = FS_GetFileLength(&f);
|
||
|
||
for( current = 0; current < fileSize; current += STREAMING_BUFFER_SIZE ) {
|
||
const u32 nextSize = MATH_MIN( STREAMING_BUFFER_SIZE, fileSize - current);
|
||
const u32 nextU32 = MATH_DIVUP( nextSize, sizeof(u32) );
|
||
s32 readSize;
|
||
|
||
readSize = FS_ReadFile( &f, pBuffer, (s32)nextSize );
|
||
|
||
if( readSize != (s32)nextSize ) {
|
||
result = FALSE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
(void)FS_CloseFile( &f );
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
// SDƒJ<C692>[ƒh‚̃‹<C692>[ƒgƒfƒBƒŒƒNƒgƒŠ<C692>ã‚ÌŽw’èƒtƒ@ƒCƒ‹‚ðƒoƒbƒtƒ@‚ɓǂÝ<E2809A>ž‚Ý
|
||
BOOL ReadTargetFileFromSD( const char *pFilename, char **ppDst, u32 *pFileSize )
|
||
{
|
||
FSFile dir, file;
|
||
BOOL open_is_ok;
|
||
BOOL read_is_ok;
|
||
u32 allocSize;
|
||
BOOL result = TRUE;
|
||
char fullPath[FS_ENTRY_LONGNAME_MAX+6];
|
||
|
||
// ƒoƒbƒtƒ@‚̃NƒŠƒA
|
||
MI_CpuClear8( fullPath, sizeof(fullPath) );
|
||
|
||
// SDƒJ<C692>[ƒh‚̃‹<C692>[ƒgƒfƒBƒŒƒNƒgƒŠ‚ðŒŸ<C592>õ
|
||
FS_InitFile(&dir);
|
||
if ( !FS_OpenDirectory(&dir, "sdmc:/", FS_FILEMODE_R) )
|
||
{
|
||
OS_TPrintf("Error FS_OpenDirectory(sdmc:/)");
|
||
}
|
||
else
|
||
{
|
||
FSDirectoryEntryInfo info[1];
|
||
// ƒ‹<C692>[ƒgƒfƒBƒŒƒNƒgƒŠ<C692>ã‚Ń^<5E>[ƒQƒbƒgƒtƒ@ƒCƒ‹‚ð’T‚·
|
||
while (FS_ReadDirectory(&dir, info))
|
||
{
|
||
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) == 0 )
|
||
{
|
||
if (!STD_CompareNString(info->longname, pFilename, STD_GetStringLength( pFilename ) ) )
|
||
{
|
||
STD_CopyString( fullPath, "sdmc:/" );
|
||
STD_ConcatenateString( fullPath, pFilename );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
(void)FS_CloseDirectory(&dir);
|
||
}
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒI<C692>[ƒvƒ“
|
||
FS_InitFile(&file);
|
||
open_is_ok = FS_OpenFile(&file, fullPath);
|
||
if (!open_is_ok)
|
||
{
|
||
OS_TPrintf( "FS_OpenFile(\"%s\") ... ERROR!\n", fullPath);
|
||
return FALSE;
|
||
}
|
||
|
||
// ƒtƒ@ƒCƒ‹ƒŠ<C692>[ƒh
|
||
*pFileSize = FS_GetFileLength(&file) ;
|
||
allocSize = ROUND_UP(*pFileSize, 32) ;
|
||
*ppDst = OS_Alloc( allocSize );
|
||
SDK_NULL_ASSERT(*ppDst);
|
||
DC_InvalidateRange(*ppDst, allocSize);
|
||
read_is_ok = FS_ReadFile( &file, *ppDst, (s32)*pFileSize );
|
||
FS_CloseFile(&file);
|
||
if (!read_is_ok)
|
||
{
|
||
OS_TPrintf( "FS_ReadFile(\"%s\") ... ERROR!\n", fullPath);
|
||
OS_Free(*ppDst);
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|