home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / msj / msjv4_4 / overlays / rdovly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-30  |  3.4 KB  |  104 lines

  1. #include "exehdr.h"
  2.  
  3. /* externally-defined full pathname of executable */
  4.  
  5. #define min(a,b) ((a) < (b)) ? (a) : (b)
  6. #define max(a,b) ((a) < (b)) ? (a) : (b)
  7. #define OPENMODE_RO 0
  8. #define MK_FP(a,b) ((void far *)( ((unsigned long)(a) << 16) | (unsigned)(b) ))
  9.  
  10. extern char executable_name[];
  11. extern int pspaddr;
  12.  
  13. void errputs(char far *s);
  14. long mylseek(int handle, long offset, int type);
  15. int myread(int handle, void far *buf, int len);
  16. int myopen(char far *name, int mode);
  17. int myclose(int handle);
  18.  
  19.  
  20. int read_overlay_section(
  21. void far *ovarea,                   /* buffer into which to read him */
  22. int requested_overlay_number        /* number of overlay to read */
  23. )
  24.  
  25. #define RELOC_BUF_SIZE 32
  26. {
  27.     struct reloc_entry_ reloc_buf[RELOC_BUF_SIZE];
  28.     struct reloc_entry_ *reloc_ptr;
  29.     int reloc_chunk;
  30.     unsigned far *target_ptr;
  31.     struct exehdr_ eh;
  32.     int i;
  33.     long startpos, nextpos, filesize;
  34.     long sectionsize, imagesize;
  35.     int executable_handle;
  36.  
  37.     /* open executable */
  38.     executable_handle = myopen(executable_name,OPENMODE_RO);
  39.  
  40.     /* determine file size */
  41.     filesize = mylseek(executable_handle,0L,2);
  42.  
  43.     /* search from beginning of file */
  44.     mylseek(executable_handle,0L,0);
  45.  
  46.     while (1) {
  47.         /* use mylseek() to avoid calling runtime functions */
  48.         startpos = mylseek(executable_handle,0L,1);
  49.         if (myread(executable_handle,&eh,sizeof(eh)) != sizeof(eh)) {
  50.             errputs("Something's wrong...can't read .EXE header\r\n");
  51.             myclose(executable_handle);
  52.             return(1);
  53.         }
  54.  
  55.         if (eh.M_sig != 'M' || eh.Z_sig != 'Z') {
  56.             errputs("Found non-EXE signature!\r\n");
  57.             myclose(executable_handle);
  58.             return(1);
  59.         }
  60.         if (eh.remain_len == 0)
  61.             sectionsize = (long)eh.page_len * 512;
  62.         else
  63.             sectionsize = (long)(eh.page_len - 1) * 512 + eh.remain_len;
  64.  
  65.         if (eh.overlay_number == requested_overlay_number) {
  66.             /* found ours...load and fix up */
  67.  
  68.             /* move to executable image */
  69.             mylseek(executable_handle, startpos + eh.hsize * 16, 0);
  70.  
  71.             myread(executable_handle, ovarea, (int)(sectionsize - eh.hsize * 16));
  72.  
  73.             /* fix up relocations in the loaded overlay */
  74.  
  75.             mylseek(executable_handle,startpos + (long)eh.first_reloc,0);
  76.             while (eh.num_relocs) {
  77.                 reloc_chunk = min(RELOC_BUF_SIZE,eh.num_relocs);
  78.                 myread(executable_handle,reloc_buf,reloc_chunk * sizeof(struct reloc_entry_));
  79.                 eh.num_relocs -= reloc_chunk;
  80.                 for (i = 0; i < reloc_chunk; i++) {
  81.                     reloc_ptr = reloc_buf + i;
  82.                     target_ptr = MK_FP(pspaddr + 0x10 + reloc_ptr->segment,
  83.                                        reloc_ptr->offset);
  84.                     *target_ptr += pspaddr + 0x10;
  85.                 }
  86.             }
  87.             myclose(executable_handle);
  88.             return 0;
  89.         } else {
  90.             nextpos = startpos + sectionsize;
  91.             /* round up to 512-byte bound */
  92.             nextpos = (nextpos + 511L) & ~511L;
  93.             if (nextpos >= filesize) {
  94.                 myclose(executable_handle);
  95.                 return 1;
  96.             }
  97.             mylseek(executable_handle,nextpos,0);
  98.         }
  99.     }
  100.     myclose(executable_handle);
  101.     return 1;
  102. }
  103.  
  104.