home *** CD-ROM | disk | FTP | other *** search
- /*
- * wininit.c
- *
- * Initialization for running WATTCP as a Windows DLL.
- */
- #ifdef WINDOWS
-
- #include <dos.h>
- #include <windows.h>
- #include "wattcp.h"
- #include "errors.h"
- #include "dpmi.h"
-
- extern struct pkt_struct far *pktstruct; /* PCPKT.C */
- extern DWORD far *interrupts; /* PCPKT.C */
- extern unsigned long far *realclock; /* PCTCP.C */
-
- extern struct pkt_struct far *pktstruct_raddr; /* PCPKT.C */
- extern void far (*_pktentry_raddr)(); /* PCPKT.C */
- extern void (*do_intr)(); /* PCPKT.C */
-
- /* Values returned by DPMI mapping functions */
- static void far (*MkCallbackRet)();
- static DWORD DosAllocRet;
- static RMODE_CALL rmode_call;
-
- /*
- * Windows-aware yield function, called when the library is
- * busy-waiting for something to happen.
- */
- void
- win_yield(void)
- {
- MSG msg;
-
- while(PeekMessage((LPMSG)&msg, 0, 0, 0, PM_REMOVE)) {
- if(msg.message == WM_PAINT)
- /* PeekMessage() leaves WM_PAINT's in the queue */
- GetMessage((LPMSG)&msg, 0, 0, 0);
- TranslateMessage((LPMSG)&msg);
- DispatchMessage((LPMSG)&msg);
- }
- }
-
- /*
- * Upcall routine for use in Windows. The packet driver's call to
- * pktentry_raddr in real-mode will cause DPMI to enter protected
- * mode, disable interrupts and call WinCallback(), which then calls
- * this function and returns to real-mode.
- */
- RMODE_CALL far *
- WinPktEntry(RMODE_CALL far *rc, unsigned short far *rmstack)
- {
- register int i;
-
- /* Find and set the program's DS - rc supposedly points into it. */
- _asm {
- push di
- les di, rc
- mov di, es
- mov ds, di
- pop di
- }
-
- /* First fix up the real-mode return address and stack */
- rc->ip = *rmstack++;
- rc->cs = *rmstack;
- rc->sp += 4;
-
- if((rc->eax & 0xff) == 0) {
- /* Assume failure */
- rc->es = rc->edi = 0;
- /* If the packet isn't too big, find a free buffer */
- if((unsigned short)rc->ecx <= BUFSIZE) {
- for(i = 0; i < MAXBUFS; i++) {
- if(pktstruct->buf[i][0] == 0) {
- rc->edi = FP_OFF(&pktstruct_raddr->buf[i][2]);
- rc->es = FP_SEG(&pktstruct_raddr->buf[i][2]);
- break;
- }
- }
- }
- }
- else {
- /* Mark a buffer ready to use */
- if(rc->esi != 0)
- *((byte far *)pktstruct+(unsigned short)rc->esi-2) = 1;
- }
-
- return rc;
- }
-
- /*
- * Callback function for protected mode Windows.
- */
- void
- WinCallback(void)
- {
- _asm {
- push ds /* DS:SI-> real-mode stack */
- push si
- push es /* ES:DI-> RMODE_CALL struct */
- push di
- call WinPktEntry
- mov di, ax /* return RMODE_CALL ptr to DPMI */
- mov es, dx
- mov sp, bp
- pop bp
- iret
- }
- }
-
-
- int
- WinInit(void)
- {
- extern void pmode_intr();
-
- /* Install a Windows-aware system yield function */
- sock_yield((tcp_Socket *)0, win_yield);
-
- /* If not running standard or enhanced, nothing more to do */
- if(!(GetWinFlags() & WF_PMODE))
- return(SUCCESS);
-
- /* Use the dpmi intr() substitute. */
- do_intr = pmode_intr;
-
- /* Map in low memory and fix pointers to it. */
- interrupts = (DWORD far *)map_real((void far *)0, 0x400L);
- realclock = (unsigned long far *)map_real((void far *)0x46c, 4L);
- if(!interrupts || !realclock) {
- sock_exit();
- return(ER_MAP);
- }
-
- /* Get a real-mode address for the upcall routine accessed by */
- /* the packet driver. */
- MkCallbackRet = dpmi_make_callback((void far (*)())WinCallback,&rmode_call);
- if(!MkCallbackRet) {
- sock_exit();
- return(ER_CALLBACK);
- }
- _pktentry_raddr = MkCallbackRet;
-
- /* Get a real-mode address for the data accessed by the packet */
- /* driver and lock it down. If it isn't in DOS memory, move it */
- /* there first. */
- /*
- if(!(pktstruct_raddr = (void far *)ProtToReal(pktstruct)))
- */
- {
- struct pkt_struct far *temp;
- DosAllocRet = GlobalDosAlloc((DWORD)((sizeof(*pktstruct)+15)&~15));
- if(!DosAllocRet) {
- sock_exit();
- return(ER_DOSALLOC);
- }
- /* The high word of DosAllocRet is the rmode segment. The */
- /* low word is the protected-mode selector. Build them */
- /* into full adresses. */
- pktstruct_raddr = (void far *)(DosAllocRet & 0xffff0000L);
- temp = (struct pkt_struct far *)(DosAllocRet << 16);
-
- /* Parts of the static struct are initialized, so copy */
- /* the contents into the new area. Then point to it. */
- *temp = *pktstruct;
- pktstruct = temp;
- }
- return(SUCCESS);
- }
-
- void
- WinExit(void)
- {
- return;
- if(MkCallbackRet)
- dpmi_free_callback(MkCallbackRet);
- if(DosAllocRet)
- GlobalDosFree(DosAllocRet);
- MkCallbackRet = NULL;
- DosAllocRet = 0;
- }
-
- #endif
-