home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_10 / 2n10008a < prev    next >
Text File  |  1991-07-23  |  6KB  |  158 lines

  1. /****************************************************************************/
  2. /*
  3. /*    FLATLOAD.C -- Linear executable loader for WINMEM32-based programs
  4. /*
  5. /*    Written by Walter Oney
  6. /*
  7. /****************************************************************************/
  8.  
  9. /* Include files */
  10. #include "windows.h"             /* Windows API */
  11. #include "string.h"              /* string functions */
  12. #include "newexe.h"              /* new executable dcls (OS/2 SDK) */
  13. #define FOR_EXEHDR 1             /* (prevent duplicate def'ns) */
  14. #include "exe386.h"              /* linear executable dcls (OS/2 SDK) */
  15. #include "winmem32.h"            /* WINMEM32 API (Win3 SDK) */
  16. #include "flatload.h"            /* FlatLoad API dcls */
  17.  
  18. /* Accessing macros for portions of the loader section: */
  19.  
  20.      typedef struct o32_obj *POBJ;
  21.      typedef struct o32_map *PMAP;
  22.  
  23. #define objtab ((POBJ) ldrsect)
  24. #define objmap ((PMAP)(ldrsect+lxhdr.e32_objmap-lxhdr.e32_objtab))
  25.  
  26. /****************************************************************************/
  27.  
  28. /* FlatLoad loads a linear executable into a nonzero-based USE32 segment. It
  29.    returns "TRUE" if the load was successful. */
  30.  
  31.    BOOL FAR PASCAL FlatLoad
  32.       (LPSTR lpFileName,         /* name of file to load */
  33.       LPSTATE32 lpState)         /* where to put initial state descriptor */
  34.       {                          /* FlatLoad */
  35.  
  36. /* Local variables */
  37.  
  38.       int hFile;                 /* input file handle */
  39.       struct exe_hdr oldhdr;     /* MZ header of main file */
  40.       DWORD e32_base;            /* offset to start of LE header */
  41.       struct e32_exe lxhdr;      /* LE header of target subfile */
  42.       HANDLE hLdrsect;           /* handle of loader section memory */
  43.       LPSTR ldrsect;             /* pointer to basic loader info */
  44.       POBJ op;                   /* current object */
  45.       POBJ olast;                /* last object */
  46.       DWORD dwSize;              /* size of target program */
  47.       DWORD pagemask;            /* page-size mask (e.g., 4095) */
  48.       WORD bigds;                /* target pgm's data segment selector */
  49.  
  50. /* Open the input file and read in the header of the linear executable
  51.    subfile. In the interest of simplicity of exposition, assume that
  52.    everything works. */
  53.  
  54.       hFile = _lopen(lpFileName, READ);
  55.       _lread(hFile, (LPSTR) &oldhdr, sizeof(oldhdr));
  56.       e32_base = oldhdr.e_lfanew;
  57.       _llseek(hFile, e32_base, 0);
  58.       _lread(hFile, (LPSTR) &lxhdr, sizeof(lxhdr));
  59.  
  60. /* Allocate local heap memory for the basic "loader section" info. */
  61.  
  62.       hLdrsect = LocalAlloc(LPTR, (WORD) lxhdr.e32_ldrsize);
  63.       ldrsect = LocalLock(hLdrsect);
  64.       _llseek(hFile, lxhdr.e32_objtab + e32_base, 0);
  65.       _lread(hFile, ldrsect, (WORD) lxhdr.e32_ldrsize);
  66.  
  67. /* Determine how much memory is required for the target 32-bit program
  68.    and create a USE32 segment to hold it. */
  69.  
  70.       op = objtab;
  71.       olast = op + lxhdr.e32_objcnt;
  72.       dwSize = 0L;
  73.       pagemask = lxhdr.e32_pagesize - 1;
  74.       for ( ; op < olast; ++op)
  75.          dwSize += (op->o32_size + pagemask) & ~pagemask;
  76.       Global32Alloc(dwSize, &bigds, dwSize, 0);
  77.  
  78. /* Load the target program */
  79.  
  80.       for (op = objtab; op < olast ; ++op)
  81.          {                       /* for each object */
  82.          PMAP mp = objmap + (op->o32_pagemap - 1);
  83.          PMAP mlast = mp + op->o32_mapsize;
  84.          DWORD pagebase = op->o32_base;
  85.          WORD nBytes = lxhdr.e32_pagesize;
  86.  
  87.          for (; mp < mlast ; ++mp, pagebase += nBytes)
  88.             {                    /* for each page in object */
  89.             WORD nPage = GETPAGEIDX(*mp) - 1;
  90.             DWORD dwPage = (DWORD) nPage * nBytes;
  91.             LPSTR pPage;
  92.  
  93.             Global16PointerAlloc(bigds, pagebase, (LPDWORD) &pPage, nBytes, 0);
  94.             if (nPage == lxhdr.e32_mpages - 1)
  95.                 nBytes = lxhdr.e32_lastpagesize; /* last page in pgm */
  96.             switch (mp->o32_pageflags)
  97.                 {                /* handle this type of page */
  98.             case VALID:
  99.                 _llseek(hFile, lxhdr.e32_datapage + dwPage, 0);
  100.                 _lread(hFile, pPage, nBytes);
  101.                 break;
  102.             case ZEROED:
  103.                 _fmemset(pPage, 0, nBytes);
  104.                 break;
  105.                 }                /* handle this type of page */
  106.             Global16PointerFree(bigds, (DWORD) pPage, 0);
  107.             }                    /* for each page in object */
  108.          }                       /* for each object */
  109.  
  110. /* Fill in the initial state descriptor. */
  111.  
  112.       lpState->ss = bigds;
  113.       lpState->esp = objtab[lxhdr.e32_stackobj-1].o32_base + lxhdr.e32_esp;
  114.       Global32CodeAlias(bigds, &lpState->cs, 0);
  115.       lpState->eip = objtab[lxhdr.e32_startobj-1].o32_base + lxhdr.e32_eip;
  116.  
  117. /* Release working memory and return to caller. */
  118.  
  119.       LocalUnlock(hLdrsect);
  120.       LocalFree(hLdrsect);
  121.       return TRUE;
  122.       }                          /* FlatLoad */
  123.  
  124. /****************************************************************************/
  125.  
  126. /* FlatUnload releases the memory used by a program FlatLoad previously
  127.    loaded. */
  128.  
  129.    VOID FAR PASCAL FlatUnload
  130.       (LPSTATE32 lpState)        /* 32-bit program descriptor */
  131.       {                          /* FlatUnload */
  132.       Global32CodeAliasFree(lpState->ss, lpState->cs, 0);
  133.       Global32Free(lpState->ss, 0);
  134.       }                          /* FlatUnload */
  135.  
  136. /**********************************************************************/
  137.  
  138. /* Dynamic Link Library initialization: */
  139.  
  140.      int FAR PASCAL LibMain
  141.         (HANDLE hInstance,      /* library instance handle */
  142.         WORD wDataSeg,          /* data segment selector */
  143.         WORD wHeapSize,         /* size of local heap */
  144.         LPSTR lpCmdLine)        /* command line */
  145.         {                       /* LibMain */
  146.         return TRUE ;           /* indicate success */
  147.         }                       /* LibMain */
  148.  
  149. /**********************************************************************/
  150.  
  151. /* Library exit procedure (called on whim in Windows 3.0): */
  152.  
  153.      int FAR PASCAL WEP
  154.         (BOOL bSysExit)         /* true if system exit occurring */
  155.         {                       /* WEP */
  156.         return TRUE ;           /* indicate success */
  157.         }                       /* WEP */
  158.