void z3ResEx::parseMsf( TMemoryStream &msf ) { switch( m_fileindexVer ) { case 0 : { unsigned char method( 0 ); FILEINDEX_ENTRY info; unsigned char *strMRFN( nullptr ); unsigned char *strName( nullptr ); unsigned int items( 0 ), errors( 0 ); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackStringEx( msf, strMRFN, info.lenMRFN ); unpackStringEx( msf, strName, info.lenName ); if( m_listContents ) { printf( "%s (%u bytes)\n", strName, info.size ); } else { if( !( extractItem( info, method, (char *)strMRFN, (char *)strName ) ) ) ++errors; } ++items; delete strMRFN; delete strName; } printf( "Processed %u items (%u issues)\n\n", items, errors ); break; } case 1 : { parseMsfMethod2( msf ); break; } } }
void z3ResEx::parseMsf( TMemoryStream &msf ) { switch( m_fileindexVer ) { case 0 : { unsigned char method( 0 ); FILEINDEX_ENTRY info; vector<unsigned char> strMRFN(MAX_STRING_SIZE); vector<unsigned char> strName(MAX_STRING_SIZE); unsigned int items( 0 ), errors( 0 ); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackStringEx(msf, strMRFN, info.lenMRFN); unpackStringEx(msf, strName, info.lenName); if( m_listContents ) { printf( "%s (%u bytes)\n", &strName[0], info.size ); } else { if( !( extractItem( info, method, reinterpret_cast<const char*>(&strMRFN[0]), reinterpret_cast<const char*>(&strName[0]) ) ) ) ++errors; } ++items; } printf( "Processed %u items (%u issues)\n\n", items, errors ); break; } case 1 : { parseMsfMethod2( msf ); break; } } }
void z3ResEx::parseMsfMethod2( TMemoryStream &msf ) { unsigned short strLen( 0 ); unsigned short mrfIndexLen( 0 ); // Folders are now in a table at the top of the file msf.Read( &mrfIndexLen, sizeof( unsigned short ) ); if (mrfIndexLen == 0) { // There are no folders in the filesystem return; } // List of filenames vector<string> vecMsf(mrfIndexLen); vector<unsigned char> strBuffer(MAX_STRING_SIZE); // MRF filenames are now packed in a list for( unsigned short i( 0 ); i != mrfIndexLen; ++i ) { strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); // Required to rename files //vecMsf[i].first.assign( (char *)strBuffer ); // Cached file opening (and a pointer so we can call the constructor) //vecMsf[i].second = new TFileStream( strBuffer ); vecMsf[i] = string(strBuffer.begin(), strBuffer.end()); } // Files are now listed (similar to before) FILEINDEX_ENTRY2 fiItem; unsigned int items( 0 ), errors( 0 ); //msf.SaveToFile("debugFilesys.dat"); bool bMatchesCriteria = true; string tmpFilename; while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { msf.Read( &fiItem, sizeof( FILEINDEX_ENTRY2 ) ); strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); if( !m_folderCriteria.empty() ) { tmpFilename = string(strBuffer.begin(), strBuffer.end()); std::transform(tmpFilename.begin(), tmpFilename.end(), tmpFilename.begin(), ::toupper); bMatchesCriteria = !( tmpFilename.find( m_folderCriteria ) == string::npos ); } if( bMatchesCriteria ) { if( m_listContents ) { printf( "%s (%u bytes)\n", &strBuffer[0], fiItem.size ); } else { if( !( extractItem2( fiItem, vecMsf[ fiItem.mrfIndex ], reinterpret_cast<const char*>(&strBuffer[0]) ) ) ) ++errors; } } ++items; } vecMsf.clear(); printf( "Processed %u items (%u issues)\n\n", items, errors ); }
void extractionMain( TMemoryStream &msf ) { const unsigned int MAX_ERRORS( 50 ); unsigned int items( 0 ); FILEINDEX_ENTRY info; unsigned char method; char *strMRFN( nullptr ), *strName( nullptr ); #define unpackString(buf,len) \ { \ buf = new char[ len +1 ]; \ msf.Read( buf, len ); \ buf[ len ] = 0; \ } #ifdef SAVE_MSF_FILEINDEX msf.SaveToFile("z3debug_fileindex.msf"); #endif // Are we just listing files? if( user_opt_list_files ) { std::string fname; printf("Listing filesystem contents\n\n"); while( msf.Position() < msf.Size() ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackString( strMRFN, info.lenMRFN ); unpackString( strName, info.lenName ); fname = fsRename( strMRFN, strName ); printf("%s\n", fname.c_str()); ++items; delete strMRFN; delete strName; } fname.clear(); printf("\nLocated %u files\n", items); } else // Run the main extraction loop { unsigned int errors( 0 ); printf("Extracting filesystem contents\n\n"); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { method = msf.ReadByte(); msf.Read( &info, sizeof( FILEINDEX_ENTRY ) ); unpackString( strMRFN, info.lenMRFN ); unpackString( strName, info.lenName ); if( !( extractItem( info, method, strMRFN, strName ) ) ) ++errors; ++items; delete strMRFN; delete strName; } if( errors >= MAX_ERRORS ) printf("ERROR: Extraction stopped as there were too many errors\n"); else printf("\nExtracted %u files (%u problems)\n", items, errors); } }
void z3ResEx::parseMsfMethod2( TMemoryStream &msf ) { unsigned short strLen( 0 ); unsigned char *strBuffer( nullptr ); unsigned short mrfIndexLen( 0 ); // Folders are now in a table at the top of the file msf.Read( &mrfIndexLen, sizeof( unsigned short ) ); // List of filenames //typedef std::pair<string, TFileStream* > mrfItem; typedef vector<string > mrfItemList; mrfItemList vecMsf; vecMsf.resize( mrfIndexLen ); // MRF filenames are now packed in a list for( unsigned short i( 0 ); i != mrfIndexLen; ++i ) { strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); // Required to rename files //vecMsf[i].first.assign( (char *)strBuffer ); // Cached file opening (and a pointer so we can call the constructor) //vecMsf[i].second = new TFileStream( strBuffer ); vecMsf[i].assign( (char *)strBuffer ); delete strBuffer; } // Files are now listed (similar to before) FILEINDEX_ENTRY2 fiItem; unsigned int items( 0 ), errors( 0 ); //msf.SaveToFile("debugFilesys.dat"); while( ( msf.Position() < msf.Size() ) && ( errors < MAX_ERRORS ) ) { msf.Read( &fiItem, sizeof( FILEINDEX_ENTRY2 ) ); strLen = msf.ReadUShort(); unpackStringEx( msf, strBuffer, strLen ); if( m_listContents ) { printf( "%s (%u bytes)\n", strBuffer, fiItem.size ); } else { if( !( extractItem2( fiItem, vecMsf[ fiItem.mrfIndex ], (char *)strBuffer ) ) ) ++errors; } delete strBuffer; ++items; } vecMsf.clear(); printf( "Processed %u items (%u issues)\n\n", items, errors ); }