Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <assert.h>
- #include <Windows.h>
- // make a directory
- static bool makedir( char *path )
- {
- assert( path != nullptr );
- for ( int i=0; path[i] != '\0'; i++ )
- {
- char ch = path[i];
- if ( ch == '\\' )
- {
- // try to create the new directory
- path[i] = '\0';
- BOOL res = CreateDirectoryA( path, nullptr );
- path[i] = '\\';
- // check if we have failed
- if ( res == FALSE )
- if ( GetLastError() != ERROR_ALREADY_EXISTS )
- return false;
- }
- }
- return true;
- }
- // pak file chunk container
- struct cPakFileChunk
- {
- char name[ 256 ];
- char *bytes;
- int size;
- cPakFileChunk( void )
- : bytes( nullptr )
- , size ( 0 )
- {}
- void free( void )
- {
- name[0] = '\0';
- if ( bytes != nullptr )
- delete [] bytes;
- bytes = nullptr;
- size = 0;
- }
- bool dump( void )
- {
- assert( bytes != nullptr && size > 0 );
- // make directory structure
- if (! makedir( name ) )
- return false;
- // open a file for writing
- FILE *f = nullptr;
- if ( fopen_s( &f, name, "wb" ) != 0 )
- return false;
- if ( f == nullptr )
- return false;
- // write out bytes to file
- bool res = ( fwrite( bytes, 1, size, f ) == size );
- // close the file
- fclose( f );
- f = nullptr;
- // return the status
- return res;
- }
- };
- // file parser
- class cFile
- {
- private:
- FILE *file;
- public:
- cFile( void )
- : file( nullptr )
- {}
- ~cFile()
- { close(); }
- bool open( const char *path )
- {
- if ( fopen_s( &file, path, "rb" ) != 0 )
- return false;
- return file != nullptr;
- };
- void close( void )
- {
- if ( file == nullptr )
- return;
- fclose( file );
- file = nullptr;
- }
- bool readString( char *dst, int nSize )
- {
- assert( file != nullptr );
- unsigned char length = 0;
- // read string length
- if ( fread_s( &length, 1, 1, 1, file ) != 1 )
- return false;
- // check for enough space
- if ( (length+1) >= nSize )
- return false;
- // read string into memory
- if ( fread_s( dst, nSize, 1, length, file ) != length )
- return false;
- // add null terminator
- dst[ length ] = '\0';
- // validate string
- for ( int i=0; i<length; i++ )
- {
- char ch = dst[i];
- if ( ch >= 'a' && ch <= 'z' ) continue;
- if ( ch >= 'A' && ch <= 'Z' ) continue;
- if ( ch >= '0' && ch <= '9' ) continue;
- if ( ch == '.' ) continue;
- if ( ch == '_' ) continue;
- if ( ch == '\\' ) continue;
- if ( ch == ' ' ) continue;
- return false;
- }
- return true;
- }
- bool readInt( int &out )
- {
- assert( file != nullptr );
- int outsz = sizeof( out );
- if ( fread_s( &out, outsz, outsz, 1, file ) != 1 )
- return false;
- return true;
- }
- bool readPakFile( cPakFileChunk &out )
- {
- if (! readString( out.name, sizeof( out.name ) ) )
- return false;
- if (! readInt( out.size ) )
- return false;
- if ( out.size <= 0 )
- return false;
- // alloc space for data
- out.bytes = new char[ out.size ];
- assert( out.bytes != nullptr );
- // read all of the data
- if ( fread_s( out.bytes, out.size, 1, out.size, file ) != out.size )
- {
- delete [] out.bytes;
- out.bytes = nullptr;
- return false;
- }
- return true;
- }
- };
- const char *dumpPakFile( const char *path )
- {
- // open the pack file
- cFile file;
- if (! file.open( path ) )
- return "unable to open pak file";
- // read the number of files in this pak file
- int nFiles = 0;
- if (! file.readInt( nFiles ) )
- return "unable to read file count";
- // dump pack files one by one
- cPakFileChunk chunk;
- for ( int i=0; i<nFiles; i++ )
- {
- if (! file.readPakFile( chunk ) )
- return "error reading pak file";
- printf( "file: %s, size: %dbytes\n", chunk.name, chunk.size );
- if (! chunk.dump( ) )
- return "cant dump file to disk";
- chunk.free( );
- }
- return nullptr;
- }
- int main( int argc, char **args )
- {
- //
- printf( "Fez Unpacker\nAidan Dodds 05/2014\nthe8bitPimp.wordpress.com\n\n" );
- // check for pak file as argument
- if ( argc <= 1 )
- {
- printf( "args: fezunpack.exe $pakFilePath\n" );
- printf( "or just drag a pak file onto this .exe\n" );
- getchar( );
- return -1;
- }
- const char *error = dumpPakFile( args[1] );
- if ( error != nullptr )
- printf( "error: %s\n", error );
- printf( "press any key to close...\n" );
- getchar( );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement