home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
ddjmag
/
ddj8712.arc
/
NARO.ARC
/
LOADEXE.C
< prev
next >
Wrap
Text File
|
1987-12-21
|
13KB
|
135 lines
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <dos.h>
#include "loc.h"
#include "externs.h"
char *warn_str = "Warning: Unable to locate virtual segment %04X\n" ;
char *load_exe_file()
{
char buf[128] ;
int count, i ;
long seek_pos ;
unsigned int module_size, pseg, *reloc_ptr, segment ;
unsigned int read_size, mem_size ;
char *load_addr, *entry, *str ;
EXE_HEADER header;
SEG_DESCRIPTOR *p ;
/*
This function reads in the .EXE file and performs the fixup of any
segment references.
*/
/* Read in the .EXE file header information */
count = read(exe_file, (char *) &header, sizeof(header)) ;
if (count != sizeof(header)) {
perror(__FILE__) ;
exit(1) ;
}
/* Exit if not a valid .EXE file */
if (header.signature != 0x5A4D) {
perror("Not an .EXE file") ;
exit(1) ;
}
/* Seek to the start of the load module */
if (lseek(exe_file, (long) header.header_size * 16, SEEK_SET) == -1L) {
perror(__FILE__) ;
exit(1) ;
}
/* Compute how much memory can be allocated for reads */
mem_size = 32 * 1024 ;
if (mem_size > _memavl())
mem_size = _memavl() ;
/* Allocate the memory */
if ((load_addr = malloc(mem_size)) == NULL) {
perror(__FILE__) ;
exit(1) ;
}
while (1) {
/* Read in a segment of the load module */
read_size = read(exe_file, load_addr, mem_size) ;
if (read_size == 0) {
free(load_addr) ;
break ;
}
/* Write it back out to the temporary file */
count = write(tmp_file, load_addr, read_size) ;
if (count != read_size) {
perror(__FILE__) ;
exit(1) ;
}
}
/* Find the relocation list */
if (lseek(exe_file, (long) header.first_reloc_item, SEEK_SET) == -1L) {
perror(__FILE__) ;
exit(1) ;
}
/* Perform the segment fixups on the temporary file */
for (i = 0; i < header.reloc_items; i++) {
/* Read in a relocation item */
count = read(exe_file, (char *) &reloc_ptr, sizeof(reloc_ptr)) ;
if (count != sizeof(reloc_ptr)) {
perror(__FILE__) ;
exit(1) ;
}
/* Compute the position of the fixup in the temporary file */
seek_pos = (long) FP_SEG(reloc_ptr) ;
seek_pos = seek_pos * 16 + FP_OFF(reloc_ptr) ;
if (lseek(tmp_file, seek_pos, SEEK_SET) == -1L) {
perror(__FILE__) ;
exit(1) ;
}
/* Read in the virtual segment from the fixup */
count = read(tmp_file, (char *) &segment, sizeof(segment)) ;
if (count != sizeof(segment)) {
perror(__FILE__) ;
exit(1) ;
}
/* Perform the location */
if (locate_virtual_segment(segment, &pseg) == ERROR)
fprintf(stderr, warn_str, segment) ;
segment = pseg ;
/* Re-seek back to the fixup */
if (lseek(tmp_file, seek_pos, SEEK_SET) == -1L) {
perror(__FILE__) ;
exit(1) ;
}
/* Write the physical segment number to the fixup */
count = write(tmp_file, (char *) &segment, sizeof(segment)) ;
if (count != sizeof(segment)) {
perror(__FILE__) ;
exit(1) ;
}
}
/* Process the program entry point */
if (locate_virtual_segment(header.code_seg_disp, &pseg) == ERROR)
fprintf(stderr, "Warning: Unable to locate entry point\n") ;
FP_SEG(entry) = pseg ;
FP_OFF(entry) = header.initial_pc ;
return entry ;
}