SHARE
TWEET

Fezunpack.cpp

a guest May 11th, 2014 307 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <assert.h>
  3.  
  4. #include <Windows.h>
  5.  
  6. // make a directory
  7. static bool makedir( char *path )
  8. {
  9.     assert( path != nullptr );
  10.    
  11.     for ( int i=0; path[i] != '\0'; i++ )
  12.     {
  13.         char ch = path[i];
  14.         if ( ch == '\\' )
  15.         {
  16.             // try to create the new directory
  17.             path[i] = '\0';
  18.             BOOL res = CreateDirectoryA( path, nullptr );
  19.             path[i] = '\\';
  20.  
  21.             // check if we have failed
  22.             if ( res == FALSE )
  23.                 if ( GetLastError() != ERROR_ALREADY_EXISTS )
  24.                     return false;
  25.         }
  26.     }
  27.     return true;
  28. }
  29.  
  30. // pak file chunk container
  31. struct cPakFileChunk
  32. {
  33.     char  name[ 256 ];
  34.     char *bytes;
  35.     int   size;
  36.  
  37.     cPakFileChunk( void )
  38.         : bytes( nullptr )
  39.         , size ( 0 )
  40.     {}
  41.  
  42.     void free( void )
  43.     {
  44.         name[0] = '\0';
  45.         if ( bytes != nullptr )
  46.             delete [] bytes;
  47.         bytes = nullptr;
  48.         size = 0;
  49.     }
  50.  
  51.     bool dump( void )
  52.     {
  53.         assert( bytes != nullptr && size > 0 );
  54.         // make directory structure
  55.         if (! makedir( name ) )
  56.             return false;
  57.         // open a file for writing
  58.         FILE *f = nullptr;
  59.         if ( fopen_s( &f, name, "wb" ) != 0 )
  60.             return false;
  61.         if ( f == nullptr )
  62.             return false;
  63.         // write out bytes to file
  64.         bool res = ( fwrite( bytes, 1, size, f ) == size );
  65.         // close the file
  66.         fclose( f );
  67.         f = nullptr;
  68.         // return the status
  69.         return res;
  70.     }
  71.  
  72. };
  73.  
  74. // file parser
  75. class cFile
  76. {
  77. private:
  78.  
  79.     FILE *file;
  80.  
  81. public:
  82.  
  83.     cFile( void )
  84.         : file( nullptr )
  85.     {}
  86.  
  87.     ~cFile()
  88.     { close(); }
  89.  
  90.     bool open( const char *path )
  91.     {
  92.         if ( fopen_s( &file, path, "rb" ) != 0 )
  93.             return false;
  94.         return file != nullptr;
  95.     };
  96.  
  97.     void close( void )
  98.     {
  99.         if ( file == nullptr )
  100.             return;
  101.         fclose( file );
  102.         file = nullptr;
  103.     }
  104.  
  105.     bool readString( char *dst, int nSize )
  106.     {
  107.         assert( file != nullptr );
  108.         unsigned char length = 0;
  109.         // read string length
  110.         if ( fread_s( &length, 1, 1, 1, file ) != 1 )
  111.             return false;
  112.         // check for enough space
  113.         if ( (length+1) >= nSize )
  114.             return false;
  115.         // read string into memory
  116.         if ( fread_s( dst, nSize, 1, length, file ) != length )
  117.             return false;
  118.         // add null terminator
  119.         dst[ length ] = '\0';
  120.         // validate string
  121.         for ( int i=0; i<length; i++ )
  122.         {
  123.             char ch = dst[i];
  124.             if ( ch >= 'a' && ch <= 'z' )   continue;
  125.             if ( ch >= 'A' && ch <= 'Z' )   continue;
  126.             if ( ch >= '0' && ch <= '9' )   continue;
  127.             if ( ch == '.'  )               continue;
  128.             if ( ch == '_'  )               continue;
  129.             if ( ch == '\\' )               continue;
  130.             if ( ch == ' '  )               continue;
  131.             return false;
  132.         }
  133.         return true;
  134.     }
  135.  
  136.     bool readInt( int &out )
  137.     {
  138.         assert( file != nullptr );
  139.         int outsz = sizeof( out );
  140.         if ( fread_s( &out, outsz, outsz, 1, file ) != 1 )
  141.             return false;
  142.         return true;
  143.     }
  144.  
  145.     bool readPakFile( cPakFileChunk &out )
  146.     {
  147.         if (! readString( out.name, sizeof( out.name ) ) )
  148.             return false;
  149.         if (! readInt( out.size ) )
  150.             return false;
  151.         if ( out.size <= 0 )
  152.             return false;
  153.         // alloc space for data
  154.         out.bytes = new char[ out.size ];
  155.         assert( out.bytes != nullptr );
  156.         // read all of the data
  157.         if ( fread_s( out.bytes, out.size, 1, out.size, file ) != out.size )
  158.         {
  159.             delete [] out.bytes;
  160.             out.bytes = nullptr;
  161.             return false;
  162.         }
  163.         return true;
  164.     }
  165.  
  166. };
  167.  
  168. const char *dumpPakFile( const char *path )
  169. {
  170.  
  171.     // open the pack file
  172.     cFile file;
  173.     if (! file.open( path ) )
  174.         return "unable to open pak file";
  175.  
  176.     // read the number of files in this pak file
  177.     int nFiles = 0;
  178.     if (! file.readInt( nFiles ) )
  179.         return "unable to read file count";
  180.  
  181.     // dump pack files one by one
  182.     cPakFileChunk chunk;
  183.     for ( int i=0; i<nFiles; i++ )
  184.     {
  185.         if (! file.readPakFile( chunk ) )
  186.             return "error reading pak file";
  187.  
  188.         printf( "file: %s, size: %dbytes\n", chunk.name, chunk.size );
  189.  
  190.         if (! chunk.dump( ) )
  191.             return "cant dump file to disk";
  192.  
  193.         chunk.free( );
  194.     }
  195.  
  196.     return nullptr;
  197. }
  198.  
  199. int main( int argc, char **args )
  200. {
  201.     //
  202.     printf( "Fez Unpacker\nAidan Dodds 05/2014\nthe8bitPimp.wordpress.com\n\n" );
  203.  
  204.     // check for pak file as argument
  205.     if ( argc <= 1 )
  206.     {
  207.         printf( "args: fezunpack.exe $pakFilePath\n" );
  208.         printf( "or just drag a pak file onto this .exe\n" );
  209.         getchar( );
  210.         return -1;
  211.     }
  212.  
  213.     const char *error = dumpPakFile( args[1] );
  214.     if ( error != nullptr )
  215.         printf( "error: %s\n", error );
  216.  
  217.     printf( "press any key to close...\n" );
  218.     getchar( );
  219.  
  220.     return 0;
  221. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top