home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / devddemo.zip / INIT.C < prev    next >
Text File  |  1991-01-31  |  6KB  |  115 lines

  1. /*****************************************************************************/
  2. /* init_mod(req_pkt)                                                         */
  3. /*                                                                           */
  4. /* Called by Strategy, this function executes the INIT command from OS/2.    */
  5. /*                                                                           */
  6. /* Store devhlp entry point for use later by dev_help                        */
  7. /* Display the information about this DD (version, copywrite, etc)           */
  8. /* Do whatever initialization your particular DD needs                       */
  9. /* Set the endpoints of the default CODE and DATA segments                   */
  10. /* At any of these steps, if an error is detected (some steps don't do any   */
  11. /* error checking because there is none to do), the INIT ends, and the DD    */
  12. /* returns a FAIL error.  In essence, it fails to install.                   */
  13. /*                                                                           */
  14. /* Finally, it sets up a pointer to Global Information Segment.  This has    */
  15. /* the Milliseconds since IPL value and the current PID.  These are useful   */
  16. /* things to know.                                                           */
  17. /*                                                                           */
  18. /* There is a bit of razzle-dazzle in this function.  At the very beginning, */
  19. /* the DevHlp entry point must be stored in a place where the DevHlp caller  */
  20. /* can get to it.  Due to the nature of DevHlp calls, the caller needs to    */
  21. /* have it addressable by CS.  To do this, the entry point must be stored in */
  22. /* the CODE segment.  But, the CODE segment is not writable.  Therefore, an  */
  23. /* alias selector (Data, Writeable) must be created.  Another problem is     */
  24. /* that to do this uses for calls to DevHlp. So, the basic steps are:        */
  25. /* 1. Store the DevHlp entry point in a temporary location in the Data Seg   */
  26. /* 2. Get the physical address of the DevHlp storage location in the Code    */
  27. /*    segment.  This uses the temporary DevHlp caller that uses the DevHlp   */
  28. /*    entry point stored in the DATA segment                                 */
  29. /* 3. Make an LDT based pointer to the physical address gotten in step 2.    */
  30. /*    This two uses the temporary DevHlp caller                              */
  31. /* 4. Store the DevHlp entry point in the address gotten in step 3.  From    */
  32. /*    this point on, we can use the CS based DevHlp caller.                  */
  33. /* 5. Free the LDT selector slot used in steps 2 and 3.                      */
  34. /*                                                                           */
  35. /* The reason for using CS as the segment pointer to the DevHlp entry point  */
  36. /* is that CS is the only segment always available.  Some DevHlp calls use   */
  37. /* DS and others use ES, the SS and CS are the only ones left.  I chose to   */
  38. /* pay the price at INIT time and store the entry in CS, and not always      */
  39. /* pass it in the stack (which, by the way is a perfectly valid way to do    */
  40. /* it).                                                                      */
  41. /*                                                                           */
  42. /*****************************************************************************/
  43.  
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include "demo.h"
  47.  
  48. extern unsigned far   last_c;
  49. extern _32bits  near  devhlp;
  50. extern unsigned far  *dev_hlpCS();
  51. extern unsigned near  last_d;
  52.        boolean  near  initialized = FALSE;
  53.  
  54. unsigned far init_mod( struct init_hdr_in *req_hdr)
  55. {
  56.    _32bits             *temp;
  57.    _32bits              pointer;
  58.    _32bits              tempaddr;
  59.    struct init_hdr_out *req_hdr_out;
  60.  
  61.    /* Store the DevHlp entry point in our DS                             */
  62.    /* This one is used only for the next section, which gets the devhlp  */
  63.    /* entry point stored in the DD's CS.  This lets me have 1 devhlper   */
  64.    /* that does not depend on if DS or ES is holding a pointer.  devhelp */
  65.    /* will use CS to access the devhlp entry                             */
  66.    devhlp = req_hdr->pointer1;
  67.  
  68.    /* Store the DevHlp entry point in our CS */
  69.    /*    Get the phys addr of dev_hlpCS */
  70.    pointer.fptr = (void far *)dev_hlpCS;
  71.    tempaddr = get_phys_addr1(pointer);
  72.  
  73.    /*    Make an LDT selector point to it */
  74.    pointer = phys_to_ldt1(tempaddr,32);
  75.    temp = (_32bits *)pointer.fptr;
  76.  
  77.    /*    Store the devhlp entry point in our CS */
  78.    temp->_segadr.segment = req_hdr->pointer1._segadr.segment;
  79.    temp->_segadr.offset  = req_hdr->pointer1._segadr.offset;
  80.  
  81.    /*    Free the LDT selector slot used */
  82.    pointer.phys = (physaddr)temp;
  83.    free_virt(pointer._segadr.segment);
  84.  
  85.    /* Set the return state to fail, if it passes, we will fix before exit */
  86.    req_hdr_out = (struct init_hdr_out *)req_hdr;
  87.    req_hdr_out->code_end = 0;
  88.    req_hdr_out->data_end = 0;
  89.    req_hdr_out->data1 = 0;
  90.  
  91.    /* Make the message file name */
  92.    make_msg_fname(req_hdr->pointer2);
  93.  
  94.    /* Print the loading commercial */
  95.    prt_msg(1,0);
  96.  
  97.    /* Do your initialisation  */
  98.  
  99.    /* Set up so we can use the timer */
  100.    point_to_global();
  101.  
  102.    /* Set the Code and Data segment sizes in the request header */
  103.    pointer.phys = (physaddr)&last_c;
  104.    req_hdr_out->code_end = pointer._segadr.offset;
  105.    pointer.fptr = (void far *)&last_d;
  106.    req_hdr_out->data_end = pointer._segadr.offset;
  107.  
  108.    /* Lock down the external segments */
  109.    pointer.fptr = (void far *)strategy_c;
  110.    lock(pointer._segadr.segment);
  111.  
  112.    return(DONE);
  113.  
  114. }
  115.