bool z3ResEx::extractItem( FILEINDEX_ENTRY &info, unsigned char method, const char *strMrf, const char *strName ) { TFileStream mrf( strMrf ); if( !( mrf.isOpen() ) ) { setMessage( "ERROR: Unable to open file (%s)", strMrf ); return false; } // Format the output filename std::string fname( fsRename( strMrf, strName ) ); // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } vector<unsigned char> buf( info.zsize ); // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( &buf[0], info.zsize ); mrf.Close(); // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( &buf[0], info.zsize ); buf.clear(); printf ( ( m_doExtraction ? "Saving %s.. " : "Checking %s.. " ), fname.substr( fname.rfind('/') +1 ).c_str() ); // Create path only when extraction is flagged if( m_doExtraction ) fsCreatePath( fname ); switch( method ) { // Compressed, most files case FILEINDEX_ENTRY_COMPRESSED : { fsXor( fdata, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); puts(" ..done!"); } // fsRle will display any errors fdata_raw.Close(); break; } // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( fdata, fdata_dec, m_fileindexKey, m_fileindexKeyLength ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( fdata_dec, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); printf(" ..done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } // Large files, some FSB (GunZ 2) case FILEINDEX_ENTRY_UNCOMPRESSED : { if( m_doExtraction ) fdata.SaveToFile( fname.c_str() ); puts(" ..done!"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", method); return false; } } fdata.Close(); return true; }
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); } }
bool extractItem( FILEINDEX_ENTRY &info, unsigned char method, char *strMrf, char *strName ) { TFileStream mrf( strMrf ); if( !( mrf.isOpen() ) ) { printf("ERROR: Could not open file (%s)\n", strMrf ); return false; } // Format the output filename std::string fname( fsRename( strMrf, strName ) ); #ifdef VERBOSE printf("Using filename: %s\n", fname.c_str()); #endif // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } unsigned char *buf( new unsigned char[ info.zsize ] ); #ifdef VERBOSE printf("Allocated %u bytes\n", info.zsize); #endif // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( buf, info.zsize ); mrf.Close(); #ifdef VERBOSE printf("Read %u bytes at %u\n", info.zsize, info.offset ); #endif // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( buf, info.zsize ); delete buf; printf ( ( user_opt_allow_extraction ? "Saving %s.. " : "Checking %s.. " ), fname.substr( fname.rfind('/') +1 ).c_str() ); // Create path only when extraction is flagged if( user_opt_allow_extraction ) fsCreatePath( fname ); switch( method ) { // Compressed, most files case FILEINDEX_ENTRY_COMPRESSED : { fsXor( info, fdata ); #ifdef VERBOSE printf("Complete XOR routine\n"); #endif TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { #ifdef VERBOSE printf("Completed RLE routine\n"); #endif if( user_opt_allow_extraction ) fdata_raw.SaveToFile( fname.c_str() ); printf("done!\n"); } // fsRle will display any errors fdata_raw.Close(); break; } // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( z3CurrentKey, fdata, fdata_dec ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( info, fdata_dec ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( user_opt_allow_extraction ) fdata_raw.SaveToFile( fname.c_str() ); printf("done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } // Large files, some FSB (GunZ 2) case FILEINDEX_ENTRY_UNCOMPRESSED : { if( user_opt_allow_extraction ) fdata.SaveToFile( fname.c_str() ); printf("done!\n"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", method); return false; } } fdata.Close(); return true; }
bool z3ResEx::extractItem2( FILEINDEX_ENTRY2 &info, const string &strMrf, char *strName ) { TFileStream mrf( strMrf.c_str() ); if( !( mrf.isOpen() ) ) { setMessage( "ERROR: Unable to open file (%s)", strMrf.c_str() ); return false; } // Format the output filename std::string fname( fsRename( strMrf.c_str(), strName ) ); // UNFORCED EXTRACTION // If file already exists, ignore it if( TFileSize( fname.c_str() ) == info.size ) { mrf.Close(); return true; } unsigned char *buf( new unsigned char[ info.zsize ] ); // Load MRF data into buffer mrf.Seek( info.offset, bufo_start ); mrf.Read( buf, info.zsize ); mrf.Close(); // Copy into TStream TMemoryStream fdata; fdata.LoadFromBuffer( buf, info.zsize ); delete buf; printf( "Saving %s.. ", fname.substr( fname.rfind('/') +1 ).c_str() ); fsCreatePath( fname ); switch( info.type ) { case FILEINDEXITEM_COMPRESSED : { fsXor( fdata, info.xorkey ); TMemoryStream fdata_raw; if( fsRle( fdata, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); puts(" ..done!"); } // fsRle will display any errors fdata_raw.Close(); break; } /* // Encrypted and compressed, some system data (GunZ 2) case FILEINDEX_ENTRY_COMPRESSED2 : { TMemoryStream fdata_dec; z3Decrypt( fdata, fdata_dec, m_fileindexKey, m_fileindexKeyLength ); fdata.Close(); // Now same as FILEINDEX_ENTRY_COMPRESSED fsXor( info, fdata_dec ); TMemoryStream fdata_raw; if( fsRle( fdata_dec, fdata_raw ) ) { if( m_doExtraction ) fdata_raw.SaveToFile( fname.c_str() ); printf(" ..done!\n"); } // fsRle will display any errors fdata_dec.Close(); fdata_raw.Close(); break; } */ case FILEINDEXITEM_UNCOMPRESSED : { fdata.SaveToFile( fname.c_str() ); puts(" ..done!"); break; } default: { fdata.Close(); printf("ERROR: Unknown compression type (%02X)\n", info.type); return false; } } fdata.Close(); return true; }