exe2bin.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 485 行 · 第 1/2 页
C
485 行
}
}
return( header );
}
// allocate a relocation-table for the exe-file stream making use of the
// passed header. populate the table using the local endianess. the caller
// owns the returned memory.
reloc_table *get_reltab( FILE *stream, dos_exe_header *header )
{
unsigned_16 rel_num;
reloc_offset rel_off;
reloc_table *reltab;
int i;
rel_num = header->num_relocs;
reltab = malloc( sizeof( reloc_table ) + rel_num * sizeof( unsigned_32 ) );
if( reltab ) {
reltab->num = rel_num;
if( fseek( stream, header->reloc_offset, SEEK_SET ) ) {
free( reltab );
reltab = NULL;
} else {
for( i = 0; i < rel_num; i++ ) {
if( !fread( &rel_off, sizeof( reloc_offset ), 1, stream ) ) {
free( reltab );
reltab = NULL;
break;
} else {
reltab->reloc[i] = (GET_LE_16( rel_off.segment ) << 4)
+ GET_LE_16( rel_off.offset );
}
}
}
}
return( reltab );
}
// parse the command-line and initialize/populate the argument-structure arg.
int parse_cmdline( arguments *arg, int argc, char *argv[] )
{
char tmp_path[ _MAX_PATH2 ];
char *drive;
char *dir;
char *fname;
char *ext;
int i;
arg->opt.be_ext = 0;
arg->opt.be_quiet = 0;
arg->opt.disp_h = 0;
arg->opt.disp_r = 0;
arg->opt.have_l = 0;
// process the passed options
i = 1;
while( (i < argc) && ((*argv[i] == '-') || (*argv[i] == '/')) ) {
switch( argv[i][1] ) {
case 'q':
arg->opt.be_quiet = 1;
break;
case 'h':
arg->opt.disp_h = 1;
break;
case 'r':
arg->opt.disp_r = 1;
break;
case 'l':
if( argv[i][2] != '=' ) {
return( ERR_USAGE );
}
arg->opt.lseg = (unsigned_16)strtol( argv[i] + 3, NULL, 0 );
arg->opt.have_l = 1;
break;
case 'x':
arg->opt.be_ext = 1;
break;
default :
return( ERR_USAGE );
}
i++;
}
// process file-name(s)
if( i < argc ) {
_splitpath2( argv[i], tmp_path, &drive, &dir, &fname, &ext );
if( *ext == '\0' ) {
strcpy( ext, "exe" );
}
_makepath( arg->iname, drive, dir, fname, ext );
i++;
if( i < argc ) {
strncpy( arg->oname, argv[i], _MAX_PATH );
}
else {
strcpy( ext, "bin" );
_makepath( arg->oname, drive, dir, fname, ext );
}
}
else {
return( ERR_USAGE );
}
return( ERR_NONE );
}
int main( int argc, char *argv[] )
{
arguments arg;
dos_exe_header *header;
reloc_table *reltab;
unsigned_32 bin_size;
unsigned_32 tot_skip;
int result;
result = parse_cmdline( &arg, argc, argv );
if( !arg.opt.be_quiet ) {
puts( banner1w( "EXE to Binary Converter", _EXE2BIN_VERSION_ ) );
puts( banner2( "2001" ) );
puts( banner3 );
puts( banner3a );
}
if( result ) {
puts( "Usage: exe2bin [options] exe_file[.exe] [bin_file]\n"
"Options: -q suppress informational messages\n"
" -h display exe-header\n"
" -r display relocations\n"
" -l=<seg> relocate exe_file to segment <seg>\n"
" -x extended behaviour, e.g. files > 64KB" );
return( EXIT_FAILURE );
}
if( (arg.ifile = fopen( arg.iname, "rb" )) == NULL ) {
printf( "Error opening %s for reading.\n", arg.iname );
return( EXIT_FAILURE );
}
if( !(header = get_header( arg.ifile )) || (header->signature != DOS_SIGNATURE) ) {
printf( "Error. %s has no valid exe-header.\n", arg.iname );
return( EXIT_FAILURE );
}
if( !(reltab = get_reltab( arg.ifile, header )) ) {
printf( "Error allocating/reading reloc-table.\n" );
free( header );
return( EXIT_FAILURE );
}
reltab->lseg = arg.opt.lseg;
if( arg.opt.disp_h ) {
printf( "Header of %s (all numbers in hex)\n", arg.iname );
disp_header( header );
}
if( arg.opt.disp_r ) {
disp_reltab( reltab );
}
if( reltab->num && !arg.opt.have_l ) {
printf( "Error. Option \"-l=<seg>\" mandatory (there are "
"relocations).\n" );
free( header );
free( reltab );
return( EXIT_FAILURE );
}
tot_skip = header->hdr_size << 4;
bin_size = header->mod_size + ( (header->file_size - 1) << 9) - tot_skip;
bin_size += header->mod_size ? 0: 512;
// if we do not operate in extended mode check the various restrictions
// of the original exe2bin. For com-files skip another 0x100 bytes.
if( !arg.opt.be_ext ) {
result = ERR_NONE;
if( bin_size > 0x10000 ) {
printf( "Error: Binary part exceeds 64 KBytes.\n" );
result = ERR_RESTRIC;
}
if( header->SS_offset || header->SP ) {
printf( "Error: Stack segment defined.\n" );
result = ERR_RESTRIC;
}
if( header->CS_offset || (header->IP != 0x0000 && header->IP != 0x0100) ) {
printf( "Error: CS:IP neither 0x0000:0x0000 nor 0x0000:0x0100.\n" );
result = ERR_RESTRIC;
}
if( header->IP == 0x0100 && reltab->num != 0 ) {
printf( "Error: com-file must not have relocations.\n" );
result = ERR_RESTRIC;
}
if( result != ERR_NONE ) {
free( header );
free( reltab );
return( EXIT_FAILURE );
}
if( header->IP == 0x0100 ) {
tot_skip += 0x100;
bin_size -= 0x100;
}
}
if( (arg.ofile = fopen( arg.oname, "wb" )) == NULL ) {
printf( "Error opening %s for writing.\n", arg.oname );
free( header );
free( reltab );
return( EXIT_FAILURE );
}
if( (result = copy_bindata( arg.ifile, arg.ofile, bin_size, tot_skip,
reltab )) ) {
switch( result ) {
case ERR_ALLOC:
printf( "Error allocating file I/O buffer.\n" );
break;
case ERR_READ:
printf( "Error reading while copying data.\n" );
break;
case ERR_WRITE:
printf( "Error writing while copying data.\n" );
break;
}
free( header );
free( reltab );
fclose( arg.ofile );
remove( arg.oname );
return( EXIT_FAILURE );
}
free( header );
free( reltab );
return( EXIT_SUCCESS );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?