home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / WNWATTCP.ZIP / SRC / WININIT.C < prev   
Encoding:
C/C++ Source or Header  |  1991-09-25  |  4.6 KB  |  186 lines

  1. /*
  2. *       wininit.c
  3. *
  4. *       Initialization for running WATTCP as a Windows DLL.
  5. */
  6. #ifdef WINDOWS
  7.  
  8. #include <dos.h>
  9. #include <windows.h>
  10. #include "wattcp.h"
  11. #include "errors.h"
  12. #include "dpmi.h"
  13.  
  14. extern struct pkt_struct far    *pktstruct;   /* PCPKT.C */
  15. extern DWORD far        *interrupts;    /* PCPKT.C */
  16. extern unsigned long far    *realclock;   /* PCTCP.C */
  17.  
  18. extern struct pkt_struct far    *pktstruct_raddr;       /* PCPKT.C */
  19. extern void far            (*_pktentry_raddr)();   /* PCPKT.C */
  20. extern void            (*do_intr)();        /* PCPKT.C */
  21.  
  22. /* Values returned by DPMI mapping functions */
  23. static void far   (*MkCallbackRet)();
  24. static DWORD    DosAllocRet;
  25. static RMODE_CALL rmode_call;
  26.  
  27. /*
  28. * Windows-aware yield function, called when the library is
  29. * busy-waiting for something to happen.
  30. */
  31. void
  32. win_yield(void)
  33. {
  34.   MSG msg;
  35.  
  36.   while(PeekMessage((LPMSG)&msg, 0, 0, 0, PM_REMOVE)) {
  37.     if(msg.message == WM_PAINT)
  38.       /* PeekMessage() leaves WM_PAINT's in the queue */
  39.       GetMessage((LPMSG)&msg, 0, 0, 0);
  40.     TranslateMessage((LPMSG)&msg);
  41.     DispatchMessage((LPMSG)&msg);
  42.   }
  43. }
  44.  
  45. /*
  46. * Upcall routine for use in Windows.   The packet driver's call to
  47. * pktentry_raddr in real-mode will cause DPMI to enter protected
  48. * mode, disable interrupts and call WinCallback(), which then calls
  49. * this function and returns to real-mode.
  50. */
  51. RMODE_CALL far *
  52. WinPktEntry(RMODE_CALL far *rc, unsigned short far *rmstack)
  53. {
  54.   register int i;
  55.  
  56.   /* Find and set the program's DS - rc supposedly points into it. */
  57.   _asm {
  58.     push  di
  59.     les di, rc
  60.     mov di, es
  61.     mov ds, di
  62.     pop di
  63.   }
  64.  
  65.   /* First fix up the real-mode return address and stack */
  66.   rc->ip = *rmstack++;
  67.   rc->cs = *rmstack;
  68.   rc->sp += 4;
  69.  
  70.   if((rc->eax & 0xff) == 0) {
  71.     /* Assume failure */
  72.     rc->es = rc->edi = 0;
  73.     /* If the packet isn't too big, find a free buffer */
  74.     if((unsigned short)rc->ecx <= BUFSIZE) {
  75.       for(i = 0; i < MAXBUFS; i++) {
  76.           if(pktstruct->buf[i][0] == 0) {
  77.         rc->edi = FP_OFF(&pktstruct_raddr->buf[i][2]);
  78.         rc->es = FP_SEG(&pktstruct_raddr->buf[i][2]);
  79.         break;
  80.           }
  81.       }
  82.     }
  83.   }
  84.   else {
  85.     /* Mark a buffer ready to use */
  86.     if(rc->esi != 0)
  87.       *((byte far *)pktstruct+(unsigned short)rc->esi-2) = 1;
  88.   }
  89.  
  90.   return rc;
  91. }
  92.  
  93. /*
  94. * Callback function for protected mode Windows.
  95. */
  96. void
  97. WinCallback(void)
  98. {
  99.   _asm {
  100.     push  ds    /* DS:SI-> real-mode stack */
  101.     push  si
  102.     push  es    /* ES:DI-> RMODE_CALL struct */
  103.     push  di
  104.     call  WinPktEntry
  105.     mov di, ax    /* return RMODE_CALL ptr to DPMI */
  106.     mov es, dx
  107.     mov sp, bp
  108.     pop bp
  109.     iret
  110.   }
  111. }
  112.  
  113.  
  114. int
  115. WinInit(void)
  116. {
  117.   extern void pmode_intr();
  118.  
  119.   /* Install a Windows-aware system yield function */
  120.   sock_yield((tcp_Socket *)0, win_yield);
  121.  
  122.   /* If not running standard or enhanced, nothing more to do */
  123.   if(!(GetWinFlags() & WF_PMODE))
  124.     return(SUCCESS);
  125.  
  126.   /* Use the dpmi intr() substitute. */
  127.   do_intr = pmode_intr;
  128.  
  129.   /* Map in low memory and fix pointers to it. */
  130.   interrupts = (DWORD far *)map_real((void far *)0, 0x400L);
  131.   realclock = (unsigned long far *)map_real((void far *)0x46c, 4L);
  132.   if(!interrupts || !realclock) {
  133.      sock_exit();
  134.      return(ER_MAP);
  135.   }
  136.  
  137.   /* Get a real-mode address for the upcall routine accessed by */
  138.   /* the packet driver. */
  139.   MkCallbackRet = dpmi_make_callback((void far (*)())WinCallback,&rmode_call);
  140.   if(!MkCallbackRet) {
  141.      sock_exit();
  142.      return(ER_CALLBACK);
  143.   }
  144.   _pktentry_raddr = MkCallbackRet;
  145.  
  146.   /* Get a real-mode address for the data accessed by the packet */
  147.   /* driver and lock it down.  If it isn't in DOS memory, move it */
  148.   /* there first. */
  149. /*
  150.   if(!(pktstruct_raddr = (void far *)ProtToReal(pktstruct)))
  151. */
  152.   {
  153.     struct pkt_struct far *temp;
  154.     DosAllocRet = GlobalDosAlloc((DWORD)((sizeof(*pktstruct)+15)&~15));
  155.     if(!DosAllocRet) {
  156.        sock_exit();
  157.        return(ER_DOSALLOC);
  158.     }
  159.     /* The high word of DosAllocRet is the rmode segment.  The */
  160.     /* low word is the protected-mode selector.  Build them */
  161.     /* into full adresses. */
  162.     pktstruct_raddr = (void far *)(DosAllocRet & 0xffff0000L);
  163.     temp = (struct pkt_struct far *)(DosAllocRet << 16);
  164.  
  165.     /* Parts of the static struct are initialized, so copy */
  166.     /* the contents into the new area.  Then point to it. */
  167.     *temp = *pktstruct;
  168.     pktstruct = temp;
  169.   }
  170.   return(SUCCESS);
  171. }
  172.  
  173. void
  174. WinExit(void)
  175. {
  176. return;
  177.   if(MkCallbackRet)
  178.     dpmi_free_callback(MkCallbackRet);
  179.   if(DosAllocRet)
  180.     GlobalDosFree(DosAllocRet);
  181.   MkCallbackRet = NULL;
  182.   DosAllocRet = 0;
  183. }
  184.  
  185. #endif 
  186.