home *** CD-ROM | disk | FTP | other *** search
/ Media Share 13 / mediashare_13.zip / mediashare_13 / ZIPPED / PROGRAM / DDJ9403A.ZIP / UC394.ZIP / RINGO.C < prev    next >
C/C++ Source or Header  |  1993-12-21  |  6KB  |  194 lines

  1. /*********************************************************
  2.   RINGO   -- Installable VxD
  3.   RINGO.C -- startup code
  4.   by Alex Shmidt, November 1993
  5. *********************************************************/
  6.  
  7. /* define CALLGATE_386 to use CALLGATE.386 instead of LDT callgate approach */
  8. //#define CALLGATE_386
  9.  
  10. #include <windows.h>
  11. #include "386.h"
  12. #include "callgate.h"
  13.  
  14. #ifdef CALLGATE_386
  15. GATEPROC GetFirstCallGateVxD (FARPROC,BYTE);
  16. void     DestroyInitGateVxD (WORD);
  17. #endif
  18.  
  19. VOID WINAPI RingoInit(void);
  20. VOID WINAPI SeeYouAtRing0(void);
  21. VOID WINAPI MakeSureOurSegIsInMemory(void);
  22. GATEPROC    GetLdtRing0CallGate (FARPROC,BYTE,WORD);
  23.  
  24. GATEPROC GDT_Gate,LDT_Gate;
  25.  
  26. int FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSeg,
  27.                          WORD cbHeapSize, LPSTR lpszCmdLine )
  28. {
  29.    if (!(GetWinFlags () & WF_ENHANCED))   /*VxDs exist in enhanced mode only*/
  30.       return 0;
  31.  
  32.    /* get the first call gate */
  33. #ifdef CALLGATE_386                 // get the GDT one from CALLGATE.386
  34.    if (!(LDT_Gate = GetFirstCallGateVxD ((FARPROC)RingoInit,sizeof(GPARAM)/4)))
  35. #else
  36.    if (!(LDT_Gate = GetLdtRing0CallGate ((FARPROC)RingoInit,sizeof(GPARAM)/4,0)))
  37. #endif
  38.       return 0;
  39.  
  40.    /*** get the GDT call gate ***/
  41.    GDT_Gate = (GATEPROC)LDT_Gate (INITRINGO,sizeof(GPARAM)/4,(DWORD)SeeYouAtRing0);
  42.  
  43.    if (cbHeapSize)
  44.       UnlockData (0);
  45.    return (1);
  46. }
  47.  
  48. int FAR PASCAL _export WEP (int nParameter)
  49. {
  50.    if (GDT_Gate)
  51.    {
  52. // swap it in case we've been discarded
  53.       MakeSureOurSegIsInMemory ();
  54. // if _GATESEG has been moved, remap our first call gate to the new space
  55. #ifdef CALLGATE_386
  56.       (GDT_Gate)(RemapGate_Svc,SELECTOROF(LDT_Gate),(DWORD)RingoInit);
  57. #else
  58.       GetLdtRing0CallGate ((FARPROC)RingoInit,sizeof(GPARAM)/4,SELECTOROF(LDT_Gate));
  59. #endif
  60.       (LDT_Gate)(EXITRINGO,HIWORD(GDT_Gate),0); // destroy our VxD
  61. // free the first call gate
  62. #ifdef CALLGATE_386
  63.       DestroyInitGateVxD (HIWORD(LDT_Gate));
  64. #else
  65.       FreeSelector (HIWORD(LDT_Gate));
  66. #endif
  67.    }
  68.    return (1);
  69. }
  70.  
  71. /*** allocates a new LDT call gate selector or remaps the old one ***/
  72. char vendor[] = "MS-DOS";
  73. GATEPROC GetLdtRing0CallGate (FARPROC gproc, BYTE params,WORD gatesel)
  74. {
  75. #define VENDOR_SPECIFIC_API 0x168a
  76. WORD ldt_map;
  77. WORD (far * entryp)(void);
  78. LPCALLGATEDESCRPT  CGateDescriptor;
  79. WORD RW_ldt_map;   /* ldt map selector fixes segment read-only problem */
  80. WORD CGateSelector;
  81. DWORD initgate_flat;
  82.  
  83.    _asm {
  84.    mov     si, offset vendor
  85.    mov     ax, VENDOR_SPECIFIC_API
  86.    int     2fh
  87.    or      al, al
  88.    jnz     no_vendor
  89.    mov     word ptr [entryp], di          /* private entry point */
  90.    mov     word ptr [entryp+2], es
  91.    mov     ax, 100h
  92.    }
  93.    ldt_map = entryp();                    /* returns LDT map selector */
  94.    _asm    jnc vendor_ok
  95. no_vendor:
  96.    return  0;
  97.  
  98. vendor_ok:
  99.  
  100.    // When run under SoftICE/W LDT alias returns read_only, give us a good one
  101.    if (!(RW_ldt_map = AllocSelector(SELECTOROF((void FAR *)&GDT_Gate))))
  102.       return 0;
  103.    SetSelectorBase(RW_ldt_map, GetSelectorBase(ldt_map));
  104.    SetSelectorLimit(RW_ldt_map, GetSelectorLimit(ldt_map));
  105.  
  106.    if ((CGateSelector = gatesel) == 0)          // we might already have one
  107.       // Get a selector for the call gate
  108.       if (!(CGateSelector = AllocSelector(0)))  // get a fresh one
  109.       {
  110.          FreeSelector (RW_ldt_map);
  111.          return 0;
  112.       }
  113.  
  114.    // create a pointer to write into the LDT
  115.    CGateDescriptor = MAKELP(RW_ldt_map,CGateSelector & SELECTOR_MASK);
  116.  
  117.    //*************************************
  118.    // build 32-bit ring 3-to-0 call gate *
  119.    //*************************************
  120.    initgate_flat = GetSelectorBase (SELECTOROF(gproc)) + (DWORD)OFFSETOF(gproc);
  121.    CGateDescriptor->Offset_O_15 =  LOWORD (initgate_flat);
  122.    CGateDescriptor->Offset_16_31 = HIWORD (initgate_flat);
  123.    CGateDescriptor->Selector = 0x28;                // ring0 flat code seg
  124.    CGateDescriptor->DWord_Count = params & CALLGATE_DDCOUNT_MASK;
  125.    CGateDescriptor->Access_Rights = GATE32_RING3;   //pres,sys,dpl3,32CallGate
  126.  
  127.    FreeSelector (RW_ldt_map);                       // don't need you any more
  128.    return ((GATEPROC)MAKELP(CGateSelector,0));
  129. }
  130.  
  131. #ifdef CALLGATE_386
  132. char cgate386[] = "CallGate";                      // CALLGATE.386 signature
  133. /* CALLGATE.386 services */
  134. #define CREATE_CALLGATE    0
  135. #define DESTROY_CALLGATE   1
  136. GATEPROC GetFirstCallGateVxD (FARPROC gproc, BYTE params)
  137. {
  138. WORD sel = SELECTOROF(gproc);
  139. WORD off = OFFSETOF(gproc) ;
  140.  
  141.    _asm {
  142.    push  es
  143.    mov   si, offset cgate386
  144.    mov   ax, 168ah
  145.    mov   dx, CREATE_CALLGATE
  146.    mov   es, sel;
  147.    mov   di, off;
  148.    mov   cl, params;
  149.    int   2fh
  150.    pop   es
  151.    }
  152. }
  153.  
  154. void DestroyInitGateVxD (WORD gatesel)
  155. {
  156.    _asm {
  157.    mov   si, offset cgate386
  158.    mov   ax, 168ah
  159.    mov   dx, DESTROY_CALLGATE
  160.    mov   cx, gatesel
  161.    int   2fh
  162.    }
  163. }
  164. #endif
  165.  
  166. /* gets system data structures */
  167. DWORD WINAPI _export GetSys (LPVOID sysstruc)
  168. {
  169.    return (GDT_Gate)(Get386_Svc,0,(DWORD)sysstruc);
  170. }
  171.  
  172. /* alternative to DPMI */
  173. DWORD WINAPI _export MapPhysToLinear (DWORD physaddr, WORD mapsize)
  174. {
  175.    return (GDT_Gate)(PhysToLin_Svc,mapsize,physaddr);
  176. }
  177.  
  178. /* connects out clients with the System_control stream */
  179. void WINAPI _export GateRegisterWindow (HWND hwnd)
  180. {
  181.    (GDT_Gate)(Register_Hwnd_Svc,hwnd,(DWORD)(FARPROC)PostMessage);
  182. }
  183.  
  184. void WINAPI _export GateUnregisterWindow (HWND hwnd)
  185. {
  186.    (GDT_Gate)(Unregister_Hwnd_Svc,0,0);
  187. }
  188.  
  189. /* DOS fun */
  190. void WINAPI _export NoDosBox (WORD stop)
  191. {
  192.    (GDT_Gate)(StopVM_Svc,(stop==7)?stop:0xFFFF,0);
  193. }
  194.