Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Integration of varioous improvements:
-xbox360 iso format
-xbox360 XGD3 iso format
-option switch to discard xbox360 system updates
-progress status of each files during the extraction

Warn fixes
  • Loading branch information
twillecomme committed Jan 11, 2014
1 parent 2ef1bc0 commit 1766b46
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 39 deletions.
22 changes: 22 additions & 0 deletions README.TXT
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
extract-xiso v2.7.1

integration of somsky's and Aiyyo's improvements
minor fixes

extract-xiso v2.7.0

Added XGD3 support (somsky)

extract-xiso v2.6.2

Fix extraction bug (Aiyyo)

extract-xiso v2.6.1

Fix -l (list files in iso) bug (My mistake).(Aiyyo)

extract-xiso v2.6

Added new command line switch (-s -> skip $SystemUpdate folder). (Aiyyo)
Try to create destination directory and display progressbar during the extraction. (Aiyyo)

extract-xiso v2.5

Added a few patches from sourceforge, fixed some bugs.
Expand Down
132 changes: 94 additions & 38 deletions extract-xiso.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@
Added in security patch from Chris Bainbridge. Thanks.
Fixed a few minor bugs.
01.18.10 aiyyo: XBox 360 iso extraction supported.
10.04.10 aiyyo: Added new command line switch (-s skip $SystemUpdate folder).
Display file progress in percent.
Try to create destination directory.
10.11.10 aiyyo: Fix -l bug (empty list).
05.02.11 aiyyo: Remove security patch.
09.30.11 somski: Added XGD3 support
01.11.14 twillecomme: Intégration of aiyyo's and somski's work.
Minor warn fixes.
enjoy!
in
Expand Down Expand Up @@ -274,7 +289,7 @@


#if defined( __DARWIN__ )
#define exiso_target "mac os x"
#define exiso_target "macos-x"

#define PATH_CHAR '/'
#define PATH_CHAR_STR "/"
Expand Down Expand Up @@ -319,7 +334,7 @@
#elif defined( __OPENBSD__ )
#define exiso_target "openbsd"
#elif defined( _WIN32 )
#define exiso_target "windows"
#define exiso_target "win32"

#define PATH_CHAR '\\'
#define PATH_CHAR_STR "\\"
Expand Down Expand Up @@ -397,8 +412,8 @@
#endif


#define exiso_version "2.6 (02.14.06)"
#define VERSION_LENGTH 14
#define exiso_version "2.7.1 (01.11.14)"
#define VERSION_LENGTH 16

#define banner "extract-xiso v" exiso_version " for " exiso_target " - written by in <[email protected]>\n"

Expand Down Expand Up @@ -443,6 +458,7 @@
-p <password> Ftp password (defaults to \"xbox\")\n\
-q Run quiet (suppress all non-error output).\n\
-Q Run silent (suppress all output).\n\
-s Skip $SystemUpdate folder.\n\
-u <user name> Ftp user name (defaults to \"xbox\")\n\
-v Print version information and exit.\n\
", banner, argv[ 0 ], argv[ 0 ] );
Expand Down Expand Up @@ -481,6 +497,7 @@
media enable patching (not recommended).\n\
-q Run quiet (suppress all non-error output).\n\
-Q Run silent (suppress all output).\n\
-s Skip $SystemUpdate folder.\n\
-v Print version information and exit.\n\
", banner, argv[ 0 ], argv[ 0 ] );
#endif
Expand Down Expand Up @@ -510,6 +527,8 @@
#endif


#define GLOBAL_LSEEK_OFFSET 0xFD90000ul
#define XGD3_LSEEK_OFFSET 0x2080000ul

#define n_sectors( size ) ( ( size ) / XISO_SECTOR_SIZE + ( ( size ) % XISO_SECTOR_SIZE ? 1 : 0 ) )

Expand Down Expand Up @@ -566,9 +585,9 @@
#define DEBUG_DUMP_DIRECTORY "/Volumes/c/xbox/iso/exiso"

#if ! defined( NO_FTP )
#define GETOPT_STRING BURN_OPTION_CHAR "c:d:Df:hlmp:qQru:vx"
#define GETOPT_STRING BURN_OPTION_CHAR "c:d:Df:hlmp:qQrsu:vx"
#else
#define GETOPT_STRING BURN_OPTION_CHAR "c:d:Dhlmp:qQrvx"
#define GETOPT_STRING BURN_OPTION_CHAR "c:d:Dhlmp:qQrsvx"
#endif


Expand Down Expand Up @@ -659,7 +678,7 @@ char *boyer_moore_search( char *in_text, long in_text_len );
int boyer_moore_init( char *in_pattern, long in_pat_len, long in_alphabet_size );

int free_dir_node_avl( void *in_dir_node_avl, void *, long );
int extract_file( int in_xiso, dir_node *in_file, modes in_mode );
int extract_file( int in_xiso, dir_node *in_file, modes in_mode, char *path );
int open_ftp_connection( char *in_host, char *in_user, char *in_password, FTP **out_ftp );
int decode_xiso( char *in_xiso, char *in_path, modes in_mode, char **out_iso_path, bool in_ll_compat );
int verify_xiso( int in_xiso, int32_t *out_root_dir_sector, int32_t *out_root_dir_size, char *in_iso_name );
Expand Down Expand Up @@ -699,6 +718,10 @@ static xoff_t s_total_bytes_all_isos = 0;
static int s_total_files_all_isos = 0;
static bool s_warned = 0;

static bool s_remove_systemupdate = false;
static char *s_systemupdate = "$SystemUpdate";

static xoff_t s_xbox_disc_lseek = 0;

#if BURN_ENABLED
#if defined( __DARWIN__ )
Expand Down Expand Up @@ -808,6 +831,10 @@ int main( int argc, char **argv ) {
rewrite = true;
} break;

case 's': {
s_remove_systemupdate = true;
} break;

case 'u': {
if ( user && free_user ) free( user );
if ( ( user = strdup( optarg ) ) == nil ) mem_err();
Expand Down Expand Up @@ -960,7 +987,7 @@ int main( int argc, char **argv ) {
}
}

if ( ! err && ! burn ) exiso_log( "\n%u files in %s total %llu bytes\n", s_total_files, rewrite ? new_iso_path : argv[ i ], s_total_bytes );
if ( ! err && ! burn ) exiso_log( "\n%u files in %s total %lld bytes\n", s_total_files, rewrite ? new_iso_path : argv[ i ], (long long int) s_total_bytes );

if ( new_iso_path ) {
if ( ! err ) exiso_log( "\n%s successfully rewritten%s%s\n", argv[ i ], path ? " as " : ".", path ? new_iso_path : "" );
Expand All @@ -972,7 +999,7 @@ int main( int argc, char **argv ) {
if ( err == err_iso_no_files ) err = 0;
}

if ( ! err && isos > 1 && ! burn ) exiso_log( "\n%u files in %u xiso's total %llu bytes\n", s_total_files_all_isos, isos, s_total_bytes_all_isos );
if ( ! err && isos > 1 && ! burn ) exiso_log( "\n%u files in %u xiso's total %lld bytes\n", s_total_files_all_isos, isos, (long long int) s_total_bytes_all_isos );
if ( s_warned ) exiso_log( "\nWARNING: Warning(s) were issued during execution--review stderr!\n" );

if ( s_ftp ) FtpBye( s_ftp );
Expand Down Expand Up @@ -1031,8 +1058,21 @@ int verify_xiso( int in_xiso, int32_t *out_root_dir_sector, int32_t *out_root_di

if ( lseek( in_xiso, (xoff_t) XISO_HEADER_OFFSET, SEEK_SET ) == -1 ) seek_err();
if ( ! err && read( in_xiso, buffer, XISO_HEADER_DATA_LENGTH ) != XISO_HEADER_DATA_LENGTH ) read_err();
if ( ! err && memcmp( buffer, XISO_HEADER_DATA, XISO_HEADER_DATA_LENGTH ) ) misc_err( "%s does not appear to be a valid xbox iso image\n", in_iso_name, 0, 0 );

if ( ! err && memcmp( buffer, XISO_HEADER_DATA, XISO_HEADER_DATA_LENGTH ) )
{
if ( lseek( in_xiso, (xoff_t) XISO_HEADER_OFFSET + GLOBAL_LSEEK_OFFSET, SEEK_SET ) == -1 ) seek_err();
if ( ! err && read( in_xiso, buffer, XISO_HEADER_DATA_LENGTH ) != XISO_HEADER_DATA_LENGTH ) read_err();
if ( ! err && memcmp( buffer, XISO_HEADER_DATA, XISO_HEADER_DATA_LENGTH ) ) {

if ( lseek( in_xiso, (xoff_t) XISO_HEADER_OFFSET + XGD3_LSEEK_OFFSET, SEEK_SET ) == -1 ) seek_err();
if ( ! err && read( in_xiso, buffer, XISO_HEADER_DATA_LENGTH ) != XISO_HEADER_DATA_LENGTH ) read_err();
if ( ! err && memcmp( buffer, XISO_HEADER_DATA, XISO_HEADER_DATA_LENGTH ) ) misc_err( "%s does not appear to be a valid xbox iso image\n", in_iso_name, 0, 0 )
else s_xbox_disc_lseek = XGD3_LSEEK_OFFSET;
}
else s_xbox_disc_lseek = GLOBAL_LSEEK_OFFSET;
}
else s_xbox_disc_lseek = 0;

// read root directory information
if ( ! err && read( in_xiso, out_root_dir_sector, XISO_SECTOR_OFFSET_SIZE ) != XISO_SECTOR_OFFSET_SIZE ) read_err();
if ( ! err && read( in_xiso, out_root_dir_size, XISO_DIRTABLE_SIZE ) != XISO_DIRTABLE_SIZE ) read_err();
Expand Down Expand Up @@ -1208,7 +1248,7 @@ int create_xiso( char *in_root_directory, char *in_output_directory, dir_node_av

if ( ! in_root ) {
if ( err ) { exiso_log( "\ncould not create %s%s\n", iso_name ? iso_name : "xiso", iso_name && ! in_name ? ".iso" : "" ); }
else exiso_log( "\nsucessfully created %s%s (%u files totalling %llu bytes added)\n", iso_name ? iso_name : "xiso", iso_name && ! in_name ? ".iso" : "", s_total_files, s_total_bytes );
else exiso_log( "\nsucessfully created %s%s (%u files totalling %lld bytes added)\n", iso_name ? iso_name : "xiso", iso_name && ! in_name ? ".iso" : "", s_total_files, (long long int) s_total_bytes );
}

if ( root.subdirectory != EMPTY_SUBDIRECTORY ) avl_traverse_depth_first( root.subdirectory, free_dir_node_avl, nil, k_postfix, 0 );
Expand Down Expand Up @@ -1236,7 +1276,7 @@ int decode_xiso( char *in_xiso, char *in_path, modes in_mode, char **out_iso_pat
bool repair = false;
int32_t root_dir_sect, root_dir_size;
int xiso, err = 0, len, path_len = 0, add_slash = 0;
char *buf, *cwd = nil, *name = nil, *short_name = nil, *iso_name;
char *buf, *cwd = nil, *name = nil, *short_name = nil, *iso_name, *folder = nil;

if ( ( xiso = open( in_xiso, READFLAGS, 0 ) ) == -1 ) open_err( in_xiso );

Expand Down Expand Up @@ -1264,6 +1304,7 @@ int decode_xiso( char *in_xiso, char *in_path, modes in_mode, char **out_iso_pat

if ( ! err && in_mode == k_extract && in_path ) {
if ( ( cwd = getcwd( nil, 0 ) ) == nil ) mem_err();
if ( ! err && mkdir( in_path, 0755 ) );
if ( ! err && chdir( in_path ) == -1 ) chdir_err( in_path );
}

Expand Down Expand Up @@ -1297,9 +1338,11 @@ int decode_xiso( char *in_xiso, char *in_path, modes in_mode, char **out_iso_pat
sprintf( buf, "%s%s%s%c", in_path ? in_path : "", add_slash && ( ! in_path || in_mode == k_upload ) ? PATH_CHAR_STR : "", in_mode != k_list && ( ! in_path || in_mode == k_upload ) ? iso_name : "", PATH_CHAR );

if ( in_mode == k_rewrite ) {
if ( ! err && lseek( xiso, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE, SEEK_SET ) == -1 ) seek_err();
if ( ! err ) err = traverse_xiso( xiso, nil, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE, buf, k_generate_avl, &root, in_ll_compat );
if ( ! err ) err = create_xiso( iso_name, in_path, root, xiso, out_iso_path, nil, nil );

if ( ! err && lseek( xiso, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1 ) seek_err();
if ( ! err ) err = traverse_xiso( xiso, nil, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE + s_xbox_disc_lseek, buf, k_generate_avl, &root, in_ll_compat );
if ( ! err ) err = create_xiso( iso_name, in_path, root, xiso, out_iso_path, nil, nil );

} else if ( in_mode == k_burn ) {
#if BURN_ENABLED
#if __DARWIN__
Expand All @@ -1321,8 +1364,8 @@ int decode_xiso( char *in_xiso, char *in_path, modes in_mode, char **out_iso_pat
}
#endif
} else {
if ( ! err && lseek( xiso, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE, SEEK_SET ) == -1 ) seek_err();
if ( ! err ) err = traverse_xiso( xiso, nil, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE, buf, in_mode, nil, in_ll_compat );
if ( ! err && lseek( xiso, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1) seek_err();
if ( ! err ) err = traverse_xiso( xiso, nil, (xoff_t) root_dir_sect * XISO_SECTOR_SIZE + s_xbox_disc_lseek, buf, in_mode, nil, in_ll_compat );
}

free( buf );
Expand Down Expand Up @@ -1448,11 +1491,13 @@ int traverse_xiso( int in_xiso, dir_node *in_dir_node, xoff_t in_dir_start, char

if ( ! err ) {
sprintf( path, "%s%s%c", in_path, dir->filename, PATH_CHAR );
if ( dir->start_sector && lseek( in_xiso, (xoff_t) dir->start_sector * XISO_SECTOR_SIZE, SEEK_SET ) == -1 ) seek_err();
if ( dir->start_sector && lseek( in_xiso, (xoff_t) dir->start_sector * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1 ) seek_err();
}
} else path = nil;

if ( ! err ) {
if ( !s_remove_systemupdate || !strstr( dir->filename, s_systemupdate ) )
{
if ( in_mode == k_extract ) {
if ( ( err = mkdir( dir->filename, 0755 ) ) ) mkdir_err( dir->filename );
if ( ! err && dir->start_sector && ( err = chdir( dir->filename ) ) ) chdir_err( dir->filename );
Expand All @@ -1462,34 +1507,40 @@ int traverse_xiso( int in_xiso, dir_node *in_dir_node, xoff_t in_dir_start, char
}
if ( ! err && in_mode != k_list && in_mode != k_generate_avl ) exiso_log( "creating %s (0 bytes) [OK]\n", path );
}
}

if ( ! err && dir->start_sector ) {
memcpy( &subdir, dir, sizeof(dir_node) );

subdir.parent = nil;
if ( ! err && dir->file_size > 0 ) err = traverse_xiso( in_xiso, &subdir, (xoff_t) dir->start_sector * XISO_SECTOR_SIZE + s_xbox_disc_lseek, path, in_mode, in_mode == k_generate_avl ? &dir->avl_node->subdirectory : nil, in_ll_compat );

if ( ! err ) err = traverse_xiso( in_xiso, &subdir, (xoff_t) dir->start_sector * XISO_SECTOR_SIZE, path, in_mode, in_mode == k_generate_avl ? &dir->avl_node->subdirectory : nil, in_ll_compat );
if ( !s_remove_systemupdate || !strstr( dir->filename, s_systemupdate ) )
{

if ( ! err && in_mode == k_extract && ( err = chdir( ".." ) ) ) chdir_err( ".." );
if ( ! err && in_mode == k_upload && FtpChdir( s_ftp, ".." ) < 0 ) rchdir_err( ".." );
}
}

if ( path ) free( path );
} else if ( in_mode != k_generate_avl ) {
if ( ! err ) {
exiso_log( "%s%s%s (%u bytes)%s", in_mode == k_extract ? "extracting " : in_mode == k_upload ? "uploading " : "", in_path, dir->filename, dir->file_size , in_mode == k_extract || in_mode == k_upload ? " " : "" ); flush();
if ( !s_remove_systemupdate || !strstr( in_path, s_systemupdate ) )
{

if ( in_mode == k_extract || in_mode == k_upload ) {
err = extract_file( in_xiso, dir, in_mode );
if ( ! err ) exiso_log( "[OK]\n" );
err = extract_file( in_xiso, dir, in_mode, in_path );
} else {
exiso_log( "%s%s%s (%lu bytes)%s", in_mode == k_extract ? "extracting " : in_mode == k_upload ? "uploading " : "", in_path, dir->filename, dir->file_size , in_mode == k_extract || in_mode == k_upload ? " " : "" ); flush();
exiso_log( "\n" );
}

++s_total_files;
++s_total_files_all_isos;
s_total_bytes += dir->file_size;
s_total_bytes_all_isos += dir->file_size;
}
}
}
}
Expand Down Expand Up @@ -1775,25 +1826,19 @@ char *boyer_moore_search( char *in_text, long in_text_len ) {
#endif


int extract_file( int in_xiso, dir_node *in_file, modes in_mode ) {
int extract_file( int in_xiso, dir_node *in_file, modes in_mode , char* path) {
char c;
int err = 0;
bool ftp_open = false, warn = false;
unsigned long i, size;
unsigned long i, size, totalsize = 0, totalpercent = 0;
int out;

// in 02.14.06: force filename to contain only ASCII characters
for ( i = 0; ( c = in_file->filename[ i ] ); ++i ) {
if ( c & 0x80 ) {
#if FORCE_ASCII
in_file->filename[ i ] = '?';
#endif
warn = true;
s_warned = true;
if ( s_remove_systemupdate && strstr( path, s_systemupdate ) )
{
if ( ! err && lseek( in_xiso, (xoff_t) in_file->start_sector * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1 ) seek_err();
}
}

if ( warn ) log_err( __FILE__, __LINE__, "WARNING: file \"%s\" contains non-ASCII character(s) [each instance has been mapped to a literal '?' character].\n", in_file->filename );
else
{

if ( in_mode == k_extract ) {
if ( ( out = open( in_file->filename, WRITEFLAGS, 0644 ) ) == -1 ) open_err( in_file->filename );
Expand All @@ -1802,9 +1847,11 @@ int extract_file( int in_xiso, dir_node *in_file, modes in_mode ) {
else ftp_open = true;
} else err = 1;

if ( ! err && lseek( in_xiso, (xoff_t) in_file->start_sector * XISO_SECTOR_SIZE, SEEK_SET ) == -1 ) seek_err();
if ( ! err && lseek( in_xiso, (xoff_t) in_file->start_sector * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1 ) seek_err();

if ( ! err ) {
if ( in_file->file_size == 0 )
exiso_log( "%s%s%s (0 bytes) [100%%]%s\r", in_mode == k_extract ? "extracting " : in_mode == k_upload ? "uploading " : "", path, in_file->filename, in_mode == k_extract || in_mode == k_upload ? " " : "" );
if ( in_mode == k_extract ) {
for ( i = 0, size = min( in_file->file_size, READWRITE_BUFFER_SIZE );
i < in_file->file_size && read( in_xiso, s_copy_buffer, size ) == (int) size;
Expand All @@ -1814,6 +1861,9 @@ int extract_file( int in_xiso, dir_node *in_file, modes in_mode ) {
write_err();
break;
}
totalsize += size;
totalpercent = ( totalsize * 100.0 ) / in_file->file_size;
exiso_log( "%s%s%s (%lu bytes) [%lu%%]%s\r", in_mode == k_extract ? "extracting " : in_mode == k_upload ? "uploading " : "", path, in_file->filename, in_file->file_size , totalpercent, in_mode == k_extract || in_mode == k_upload ? " " : "" );
}

close( out );
Expand All @@ -1826,11 +1876,17 @@ int extract_file( int in_xiso, dir_node *in_file, modes in_mode ) {
rwrite_err();
break;
}
totalsize += size;
totalpercent = ( totalsize * 100.0 ) / in_file->file_size;
exiso_log( "%s%s%s (%lu bytes) [%lu%%]%s\r", in_mode == k_extract ? "extracting " : in_mode == k_upload ? "uploading " : "", path, in_file->filename, in_file->file_size , totalpercent, in_mode == k_extract || in_mode == k_upload ? " " : "" );
}
}
}

if ( ftp_open ) FtpClose( s_ftp );
}

if ( ! err ) exiso_log( "\n" );

return err;
}
Expand Down Expand Up @@ -1929,7 +1985,7 @@ int write_file( dir_node_avl *in_avl, write_tree_context *in_context, int in_dep
}

if ( ! err ) {
exiso_log( "adding %s%s (%u bytes) ", in_context->path, in_avl->filename, in_avl->file_size ); flush();
exiso_log( "adding %s%s (%lu bytes) ", in_context->path, in_avl->filename, in_avl->file_size ); flush();

if ( s_media_enable && ( i = (int) strlen( in_avl->filename ) ) >= 4 && in_avl->filename[ i - 4 ] == '.' && ( in_avl->filename[ i - 3 ] | 0x20 ) == 'x' && ( in_avl->filename[ i - 2 ] | 0x20 ) == 'b' && ( in_avl->filename[ i - 1 ] | 0x20 ) == 'e' ) {
for ( bytes = in_avl->file_size, i = 0; ! err && bytes; ) {
Expand Down
2 changes: 1 addition & 1 deletion libftp-5.0.1.modified.by.in/FtpDebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ FtpHash(FTP *ftp, unsigned long chars)

if (chars==0) return ftp->counter=0;
ftp->counter+=chars;
fprintf(stderr,"%10u bytes transfered\r",ftp->counter);
fprintf(stderr,"%10lu bytes transfered\r",ftp->counter);
fflush(stderr);
return ftp->counter;
}
Expand Down
File renamed without changes.

0 comments on commit 1766b46

Please sign in to comment.