1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef _WIN32
#define snprintf _snprintf
#endif
uint32_t read_le32( FILE * source )
{
unsigned char buffer[ 4 ];
fread( buffer, 1, 4, source );
return buffer[ 0 ] + buffer[ 1 ] * 0x100 + buffer[ 2 ] * 0x10000 + buffer[ 3 ] * 0x1000000;
}
int transfer_bytes( FILE * source, FILE * target, size_t count )
{
unsigned char buffer[ 32768 ];
while ( count )
{
size_t to_read = ( count > 32768 ) ? 32768 : count;
if ( fread( buffer, 1, to_read, source ) < to_read ) return -1;
if ( fwrite( buffer, 1, to_read, target ) < to_read ) return -1;
count -= to_read;
}
return 0;
}
int extract_file( const char * filename )
{
int rval = -1;
FILE * input_file = NULL, * output_file = NULL;
uint32_t i, file_count, pointer, size;
uint32_t * pointers = NULL;
char output_filename[512];
input_file = fopen( filename, "rb" );
if ( !input_file ) { fprintf( stderr, "Error opening file: %s\n", filename ); goto cleanup; }
file_count = read_le32( input_file );
pointers = ( uint32_t * ) malloc( ( file_count + 1 ) * sizeof( uint32_t ) );
if ( !pointers ) { fputs( "Out of memory\n", stderr ); goto cleanup; }
for ( i = 0; i <= file_count; ++i ) pointers[ i ] = read_le32( input_file );
for ( i = 0; i < file_count; ++i )
{
snprintf( output_filename, _countof( output_filename ) - 1, "%s_file%u.bin", filename, i );
output_filename[ _countof( output_filename ) - 1 ] = 0;
output_file = fopen( output_filename, "wb" );
if ( !output_file ) { fprintf( stderr, "Error opening output file: %s\n", output_filename ); goto cleanup; }
fseek( input_file, pointers[ i ], SEEK_SET );
if ( transfer_bytes( input_file, output_file, pointers[ i + 1 ] - pointers[ i ] ) < 0 ) { fputs( "Error writing to output file\n", stderr ); goto cleanup; }
fclose( output_file );
output_file = NULL;
}
rval = 0;
cleanup:
if ( output_file != NULL ) fclose( output_file );
if ( pointers != NULL ) free( pointers );
if ( input_file != NULL ) fclose( input_file );
return rval;
}
int main( int argc, const char * const * argv )
{
int i;
for ( i = 1; i < argc; ++i )
{
fprintf( stderr, "Processing %s...\n", argv[ i ] );
if ( extract_file( argv[ i ] ) < 0 ) break;
}
return 0;
}
|