diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.ncb b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.ncb index 54ac40a..220890f 100644 Binary files a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.ncb and b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.ncb differ diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.suo b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.suo index c19bc14..49e764c 100644 Binary files a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.suo and b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker.suo differ diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/Debug/BuildLog.htm b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/Debug/BuildLog.htm index 6f066d2..02b73c9 100644 Binary files a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/Debug/BuildLog.htm and b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/Debug/BuildLog.htm differ diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/MasterEditorTWLChecker.cpp b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/MasterEditorTWLChecker.cpp index ba2a278..07cd87a 100644 --- a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/MasterEditorTWLChecker.cpp +++ b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/MasterEditorTWLChecker.cpp @@ -5,21 +5,62 @@ using namespace System; +// ------------------------------------------------------------------ +// context +// ------------------------------------------------------------------ +ref class RCContext +{ +public: + property System::Boolean isVerbose; +public: + RCContext() + { + this->isVerbose = false; + } +}; +System::Int32 parseOption( array ^args, RCContext ^context ); + +// ------------------------------------------------------------------ +// main +// ------------------------------------------------------------------ + int main(array ^args) { + RCContext ^context = gcnew RCContext(); + int argc = parseOption( args, context ); + try { - setDebugPrint( true ); + if( context->isVerbose ) + { + setDebugPrint( true ); + } + if( argc <= 0 ) + { + throw (gcnew System::Exception("Argc is 0.")); + } + else if( argc == 1 ) + { + System::String ^sheet = args[0]; + DebugPrint( "Sheet file : " + sheet ); - //FilenameItem ^fItem = gcnew FilenameItem; - //fItem->parseFilename( args[0] ); - //SheetItem ^sItem = gcnew SheetItem; - //sItem->readSheet( args[0] ); - //checkSheet( fItem, sItem ); + FilenameItem ^fItem = gcnew FilenameItem; + fItem->parseFilename( sheet ); + SheetItem ^sItem = gcnew SheetItem; + sItem->readSheet( sheet ); + checkSheet( fItem, sItem ); + } + else + { + System::String ^original = args[0]; + System::String ^target = args[1]; + DebugPrint( "Original file : " + original ); + DebugPrint( "Target file : " + target ); - FilenameItem ^fItem = gcnew FilenameItem; - fItem->parseFilename( args[0] ); - checkRom( fItem, args[0] ); + FilenameItem ^fItem = gcnew FilenameItem; + fItem->parseFilename( target ); + checkRom( fItem, original, target ); + } } catch( System::Exception ^ex ) { @@ -29,3 +70,36 @@ int main(array ^args) Console::WriteLine( "OK" ); return 0; } + +// ------------------------------------------------------------------ +// getopt +// ------------------------------------------------------------------ + +// @ret オプションを除いたときのargc +System::Int32 parseOption( array ^args, RCContext ^context ) +{ + System::Collections::Generic::List ^indexList + = gcnew System::Collections::Generic::List; + + int numopt = 0; + int i; + for( i=0; i < args->Length; i++ ) + { + if( args[i]->StartsWith( "-v" ) ) + { + context->isVerbose = true; + numopt++; + } + else if( !args[i]->StartsWith( "-" ) ) // オプションでない引数のindexを記録 + { + indexList->Add(i); + } + } + i=0; + for each( System::Int32 index in indexList ) // オプションでない引数を前につめていく + { + args[i] = args[index]; + i++; + } + return (args->Length - numopt); +} diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.cpp b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.cpp index 5ad8ddb..b69fa33 100644 --- a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.cpp +++ b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.cpp @@ -58,6 +58,11 @@ System::Void FilenameItem::parseFilename( System::String ^filepath ) System::String ^filename = System::IO::Path::GetFileNameWithoutExtension(filepath); cli::array ^list = filename->Split( '_' ); + if( list->Length < 4 ) + { + throw (gcnew System::Exception("Illegal filename format. REGION_OGN_AGE_LANG.[SRL/XML]")); + return; + } this->region = System::String::Copy(list[0]); this->ogn = System::String::Copy(list[1]); this->rating = System::String::Copy(list[2]); @@ -70,6 +75,24 @@ System::Void FilenameItem::parseFilename( System::String ^filepath ) DebugPrint( "{0,-10} {1,-20}", "Rating", this->rating ); DebugPrint( "{0,-10} {1,-20}", "Language",this->lang ); DebugPrint( "--------------------------------------------------------" ); + + // ファイル名の検査 + if( this->getRegionBitmap() == 0 ) + { + throw (gcnew System::Exception("Illegal filename format. (Region.) REGION_OGN_RATING_LANG.[SRL/XML]")); + return; + } + if( this->getOgnNumber() < -1 ) + { + throw (gcnew System::Exception("Illegal filename format. (Ogn.) REGION_OGN_RATING_LANG.[SRL/XML]")); + return; + } + if( this->getRatingValue() == 0 ) + { + throw (gcnew System::Exception("Illegal filename format. (Rating.) REGION_OGN_RATING_LANG.[SRL/XML]")); + return; + } + return; } @@ -125,7 +148,7 @@ u32 FilenameItem::getRegionBitmap() int FilenameItem::getOgnNumber() { - int num = -1; + int num = -2; if( this->ogn == "CERO" ) { num = OS_TWL_PCTL_OGN_CERO; @@ -158,6 +181,10 @@ int FilenameItem::getOgnNumber() //{ // num = OS_TWL_PCTL_OGN_GRB; //} + else if( this->ogn == "UN" ) + { + num = -1; + } return num; } diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.h b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.h index 435afe2..2ee3c61 100644 --- a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.h +++ b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check.h @@ -40,7 +40,7 @@ public: }; // ROMヘッダの値と真値(ファイル名)を比較 -System::Void checkRom( FilenameItem ^fItem, System::String ^srlpath ); +System::Void checkRom( FilenameItem ^fItem, System::String ^orgSrl, System::String ^targetSrl ); // 提出確認書の文字列と真値を比較 System::Void checkSheet( FilenameItem ^fItem, SheetItem ^sItem ); diff --git a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check_rom.cpp b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check_rom.cpp index e3efc8d..c363ca5 100644 --- a/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check_rom.cpp +++ b/build/tools/MasterEditor/MasterEditorTWLChecker/MasterEditorTWLChecker/check_rom.cpp @@ -12,20 +12,22 @@ #include System::Void checkRomHeaderSign( ROM_Header *prh ); - +System::Void verifyArea( FILE *fp1, FILE *fp2, const int offset, const int size ); // ------------------------------------------------------------------- // 出力SRLのチェック // ------------------------------------------------------------------- -System::Void checkRom( FilenameItem ^fItem, System::String ^srlpath ) +System::Void checkRom( FilenameItem ^fItem, System::String ^orgSrl, System::String ^targetSrl ) { - const char *chpath = - (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( srlpath ).ToPointer(); + const char *chorg = + (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( orgSrl ).ToPointer(); + const char *chtarget = + (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( targetSrl ).ToPointer(); // ROMヘッダの読み込み ROM_Header rh; FILE *fp = NULL; - if( fopen_s( &fp, chpath, "rb" ) != NULL ) + if( fopen_s( &fp, chtarget, "rb" ) != NULL ) { throw (gcnew System::Exception("Fail to Open SRL File.")); return; @@ -73,9 +75,7 @@ System::Void checkRom( FilenameItem ^fItem, System::String ^srlpath ) u8 rating = fItem->getRatingValue(); if( rh.s.parental_control_rating_info[ ogn ] != rating ) { - throw (gcnew System::Exception("Mismatch Rating Ogn " + ogn.ToString() + ". " - + "filename = " + rating.ToString("2X") - + "srl = " + rh.s.parental_control_rating_info[ ogn ].ToString("2X") + ".")); + throw (gcnew System::Exception("Mismatch Rating Ogn " + ogn.ToString() + ".")); return; } @@ -106,6 +106,38 @@ System::Void checkRom( FilenameItem ^fItem, System::String ^srlpath ) } } DebugPrint( "--------------------------------------------------------" ); + + // 全領域ベリファイ + FILE *fp1 = NULL; + if( fopen_s( &fp1, chorg, "rb" ) != NULL ) + { + throw (gcnew System::Exception("Fail to Open SRL File.")); + return; + } + FILE *fp2 = NULL; + if( fopen_s( &fp2, chtarget, "rb" ) != NULL ) + { + throw (gcnew System::Exception("Fail to Open SRL File.")); + return; + } + // ファイルサイズをまずチェック + fseek(fp1, 0, SEEK_END); + u32 filesize1 = ftell( fp1 ); + fseek(fp2, 0, SEEK_END); + u32 filesize2 = ftell( fp2 ); + DebugPrint( "{0,-10} {1,-20} {2,-20}", nullptr, "Original File", "Target File" ); + DebugPrint( "{0,-10} {1,-20:X08} {2,-20:X08}", "Filesize", filesize1, filesize2 ); + DebugPrint( "--------------------------------------------------------" ); + if( filesize1 != filesize2 ) + { + throw (gcnew System::Exception("Incorrect filesize")); + return; + } + // マスタエディタで書き換えられていない領域をチェック + verifyArea( fp1, fp2, 0, 0x1b0 ); + verifyArea( fp1, fp2, 0x1b4, 0x2f0 - 0x1b4 ); + verifyArea( fp1, fp2, 0x300, filesize1 - 0x300 ); + DebugPrint( "--------------------------------------------------------" ); } // ------------------------------------------------------------------- @@ -168,3 +200,50 @@ System::Void checkRomHeaderSign( ROM_Header *prh ) } return; } + +// ------------------------------------------------------------------- +// 書き換えた箇所以外の全領域をベリファイしたいので +// 指定領域をベリファイする関数をつくる +// ------------------------------------------------------------------- +#define VERIFY_AREA_BUFSIZE (10*1024*1024) +System::Void verifyArea( FILE *fp1, FILE *fp2, const int offset, const int size ) +{ + if( !fp1 || !fp2 ) + { + throw (gcnew System::Exception("File pointer is NULL.")); + return; + } + + DebugPrint( "{0,-10} {1:X08} - {2:X08}", "Verify", offset, offset+size-1 ); + + cli::array ^mbuf1 = gcnew cli::array(VERIFY_AREA_BUFSIZE); // 解放の必要なし + pin_ptr buf1 = &mbuf1[0]; + cli::array ^mbuf2 = gcnew cli::array(VERIFY_AREA_BUFSIZE); + pin_ptr buf2 = &mbuf2[0]; + + fseek( fp1, offset, SEEK_SET ); + fseek( fp2, offset, SEEK_SET ); + + // バッファよりも大きい場合は細切れにリードしてベリファイする + int rest = size; + while( rest > 0 ) + { + int len = (rest > VERIFY_AREA_BUFSIZE)?(VERIFY_AREA_BUFSIZE):(rest); + if( fread(buf1, 1, len, fp1) != len ) + { + throw (gcnew System::Exception("In Verify, fail to fread")); + return; + } + if( fread(buf2, 1, len, fp2) != len ) + { + throw (gcnew System::Exception("In Verify, fail to fread")); + return; + } + if( memcmp(buf1, buf2, len) != 0 ) + { + throw (gcnew System::Exception("In Verify, incorrect area.")); + } + rest = rest - len; + } + return; +}