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