home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l350 / 3.ddi / EXAMPLES / LOADER / LOAD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-28  |  7.7 KB  |  274 lines

  1. /************************************************************************/
  2. /*    Copyright (C) 1986-1990 Phar Lap Software, Inc.                  */
  3. /*    Unpublished - rights reserved under the Copyright Laws of the    */
  4. /*    United States.  Use, duplication, or disclosure by the           */
  5. /*    Government is subject to restrictions as set forth in            */
  6. /*    subparagraph (c)(1)(ii) of the Rights in Technical Data and      */
  7. /*    Computer Software clause at 252.227-7013.                        */
  8. /*    Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138   */
  9. /************************************************************************/
  10.  
  11. /* INCLUDES */
  12.  
  13. #include <stdio.h>
  14. #include <dos.h>
  15. #include <pharlap.h>
  16. #include <hw386.h>
  17. #include <pldos32.h>
  18.  
  19. void load_err(UCHAR *namep, int errv, UINT info, UINT dosinfo);
  20. int call_child(LDEXP_BLK *ldblkp, ULONG ndword_params, ...);
  21.  
  22. /*
  23. This example program is run as:
  24.     load <.EXE filename>
  25.  
  26. It loads the specified file, and does a FAR call to its entry point.  The
  27. loaded program terminates by executing a FAR return.
  28.  
  29. NOTE:    If you are loading a program built with a high level language, you
  30.     MUST build the program to be loaded with a modified version of the
  31.     initializer that comes with the compiler.  You have to modify the
  32.     initializer to:
  33.     (1) make sure the program terminates with a FAR RET, instead of
  34.         DOS system call INT 21h func 4Ch, and
  35.     (2) the heap initialization modifies the size of the correct segment
  36.         (i.e., doesn't assume hardwired segments 000Ch and 0014h),
  37.         and calculates the desired segment size correctly (i.e., does
  38.         NOT pull program size values out of the PSP, which applies
  39.         to this program not the loaded program, instead it uses
  40.         size values returned in the load parameter block by the
  41.         load program system call).
  42. */
  43. int main (argc,argv)
  44. int    argc;
  45. char    **argv;
  46. {
  47.     UCHAR *namep;            /* ptr to pgm name string */
  48.     LDEXP_BLK ldblk;        /* Load parameter block */
  49.     CONFIG_INF cbuf;        /* config info */
  50.     BOOL unprivf;            /* T ==> if this pgm runs unprivileged*/
  51.     int errv;            /* Error value */
  52.     UINT vmhandle;            /* 386|VMM handle */
  53.     UINT einfo;            /* Error information */
  54.     UINT doseinfo;            /* DOS error information */
  55.     USHORT code_sel;        /* child's code segment selector */
  56.     USHORT data_sel;        /* child's data segment selector */
  57.  
  58. /*
  59.  * Get program name from command line
  60.  */
  61.     if (argc < 2)
  62.     {
  63.         printf("Usage: load filename");
  64.         return TRUE;
  65.     }
  66.     namep = (UCHAR *) *(argv + 1);
  67.     
  68. /*
  69.  * Get config info so we have CS for this program;  then look at the 
  70.  * RPL bits in CS to see if we are running at privilege level 0 (-PRIV) or
  71.  * unprivileged (-UNPRIV).  All we use this for is checking to see if child 
  72.  * privilege selection is the same as ours.
  73.  */
  74.     _dx_config_inf(&cbuf, (UCHAR *) &cbuf);
  75.     unprivf = (cbuf.c_cs_sel & SEL_RPL) != 0;
  76.  
  77. /*
  78.  * Make DOS-X system call to load the program.  If the child privilege
  79.  * level selection (-PRIV or -UNPRIV) is different from ours, print out 
  80.  * a warning message to that effect.  A program linked with -UNPRIV should
  81.  * normally be capable of running at privilege level 0 (-PRIV), but a 
  82.  * program linked with -PRIV may not run unprivileged if it performs 
  83.  * operations (such as accessing the GDT or IDT directly) that are not
  84.  * possible when running unprivileged.
  85.  */
  86.     errv = _dx_ld_flat(namep, &ldblk, FALSE, &vmhandle, &einfo,&doseinfo);
  87.     if (errv != _DOSE_NONE)
  88.     {
  89.         load_err(namep, errv, einfo, doseinfo);
  90.         return TRUE;
  91.     }
  92.     if (ldblk.flags & LD_UNPRIV)
  93.     {
  94.         if (!unprivf)
  95.             printf("Warning:  loader is running privileged,\n\
  96.           child program %s is linked with -UNPRIV\n", namep);
  97.     }
  98.     else if (unprivf)
  99.         printf("Warning:  loader is running unprivileged,\n\
  100.           child program %s is linked with -PRIV\n", namep);
  101.  
  102. /*
  103.  * Call assembly language routine to load regs and do FAR call to
  104.  * loaded child pgm.  First save child's code and data segment selectors,
  105.  * which we need to free up the child later.
  106.  */
  107.     printf("Calling loaded program: <<%s>>\n", namep);
  108.     fflush(stdout);
  109.     code_sel = ldblk.cs;
  110.     data_sel = ldblk.ds;
  111.     call_child(&ldblk, 0);
  112.  
  113. /*
  114.  * Program terminated, now free up the segments for it in the LDT, and
  115.  * if we have a VMM handle make a system call to release the handle.
  116.  *
  117.  * We have to free both the code & data segment to make the allocated memory
  118.  * get freed;  freeing just one removes the segment aliasing but leaves the
  119.  * other still allocated.
  120.  */
  121.     errv = (int) _dos_freemem(code_sel);
  122.     if (errv != _DOSE_NONE)
  123.         goto FREE_ERR;
  124.     errv = (int) _dos_freemem(data_sel);
  125.     if (errv != _DOSE_NONE)
  126.     {
  127. FREE_ERR:
  128.         printf("Unexpected err freeing segment: %d\n", errv);
  129.         return TRUE;
  130.     }
  131.     if (vmhandle != (UINT) -1)
  132.     {
  133.         errv = _dx_vmm_close(vmhandle);
  134.         if (errv != _DOSE_NONE)
  135.         {
  136.             printf("Unexpected err releasing 386|VMM handle: %d\n",
  137.                                 errv);
  138.             return TRUE;
  139.         }
  140.     }
  141.  
  142. /*
  143.  * Successful terminate
  144.  */
  145.     return FALSE;
  146. }
  147.  
  148. /*    <load_err> - Print error message after load error */
  149.  
  150. void load_err(UCHAR *namep, int errv, UINT info, UINT dosinfo)
  151.  
  152. /*
  153. Description:
  154.     This routine takes the error information returned by the load 
  155.     program system call and prints out an appropriate error message.
  156.  
  157. Calling arguments:
  158.     namep        ptr to file name string
  159.     errv        error code returned by load pgm system call
  160.     info        sub-error code ret'd for file error or memory error
  161.     dosinfo        DOS error code ret'd for DOS file error
  162.  
  163. Returned values:
  164.     - none
  165. */
  166. {
  167.     if (errv == 2)
  168.     {
  169.         printf("File related error loading %s\n", namep);
  170.         switch(info)
  171.         {
  172.         case 1:
  173.             printf("       DOS error opening file\n");
  174.             break;
  175.         case 2:
  176.             printf("       DOS error seeking in file\n");
  177.             break;
  178.         case 3:
  179.             printf("       DOS error reading file\n");
  180.             break;
  181.         case 4:
  182.             printf("       Not flat model EXP or REX file\n");
  183.             break;
  184.         case 5:
  185.             printf("       Invalid file format\n");
  186.             break;
  187.         case 6:
  188.             printf("       Program linked with -OFFSET not \
  189. multiple of 4k\n");
  190.             break;
  191.         case 7:
  192.             printf("       -NOPAGE in effect and program was \
  193. linked with -REALBREAK or -OFFSET\n");
  194.             break;
  195.         default:
  196.             printf("       Unexpected file error code: %d\n",
  197.                                 info);
  198.             break;
  199.         }
  200.         if (info == 1 || info == 2 || info == 3)
  201.         {
  202.             switch(dosinfo)
  203.             {
  204.             case 2:
  205.                 printf("       File not found\n");
  206.                 break;
  207.             case 3:
  208.                 printf("       Path not found\n");
  209.                 break;
  210.             case 4:
  211.                 printf("       Too many open files\n");
  212.                 break;
  213.             case 5:
  214.                 printf("       Access denied\n");
  215.                 break;
  216.             case 6:
  217.                 printf("       Invalid file handle\n");
  218.                 break;
  219.             case 12:
  220.                 printf("       Invalid file access code\n");
  221.                 break;
  222.             default:
  223.                 printf("       Unexpected DOS err code: %d\n",
  224.                                 dosinfo);
  225.                 break;
  226.             }
  227.         }
  228.     }
  229.  
  230.     else if (errv == 8)
  231.     {
  232.         printf("Memory related error loading %s\n", namep);
  233.         switch(info){
  234.             case 1:
  235.                 printf("       Out of physical memory\n");
  236.                 break;
  237.             case 2:
  238.                 printf("       Out of swap space\n");
  239.                 break;
  240.             case 3:
  241.                 printf("       Unable to grow LDT\n");
  242.                 break;
  243.             case 4:
  244.                 printf("       Unable to change extended \
  245. memory allocation mark\n");
  246.                 break;
  247.             case 5:
  248.                 printf("       Maximum virtual size (from \
  249. -MAXPGMMEM switch) exceeded\n");
  250.                 break;
  251.             case 6:
  252.                 printf("       Insuff. conv memory to satisfy \
  253. -REALBREAK switch setting\n");
  254.                 break;
  255.             case 7:
  256.                 printf("       No conv memory available for \
  257. program PSP and environment\n");
  258.                 break;
  259.             default:
  260.                 printf("       Unexpected mem err code: %d\n",
  261.                                 info);
  262.                 break;
  263.         }
  264.     }
  265.  
  266.     else
  267.     {
  268.         printf("Unexpected error code from load pgm: %d\n", errv);
  269.         return;
  270.     }
  271.  
  272.     return;
  273. }
  274.