Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Int2f.c
  5. Abstract:
  6. This module provides the int 2f API for dpmi
  7. Author:
  8. Neil Sandlin (neilsa) 23-Nov-1996
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <softpc.h>
  14. #include "xlathlp.h"
  15. //
  16. // Local constants
  17. //
  18. #define MSCDEX_FUNC 0x15
  19. #define WIN386_FUNC 0x16
  20. #define WIN386_IDLE 0x80
  21. #define WIN386_Get_Device_API 0x84
  22. #define WIN386_INT31 0x86
  23. #define WIN386_GETLDT 0x88
  24. #define WIN386_KRNLIDLE 0x89
  25. #define DPMI_MSDOS_EXT 0x8A
  26. #define SEL_LDT 0x137
  27. #define DISPCRIT_FUNC 0x40
  28. #define DISPCRIT_ENTER 0x03
  29. #define DISPCRIT_EXIT 0x04
  30. #define XMS_ID 0x43
  31. #define XMS_INS_CHK 0x00
  32. #define XMS_CTRL_FUNC 0x10
  33. typedef BOOL (WINAPI *PFNMSCDEXVDDDISPATCH)(VOID);
  34. PFNMSCDEXVDDDISPATCH
  35. LoadMscdexAndGetVDDDispatchAddr(
  36. VOID
  37. );
  38. BOOL
  39. PMInt2fHandler(
  40. VOID
  41. )
  42. /*++
  43. Routine Description:
  44. This routine is called at the end of the protect mode PM int chain
  45. for int 2fh. It is provided for compatibility with win31.
  46. Arguments:
  47. Client registers are the arguments to int2f
  48. Return Value:
  49. TRUE if the interrupt was handled, FALSE otherwise
  50. --*/
  51. {
  52. DECLARE_LocalVdmContext;
  53. BOOL bHandled = FALSE;
  54. static char szMSDOS[] = "MS-DOS";
  55. PCHAR VdmData;
  56. static PFNMSCDEXVDDDISPATCH pfnMscdexVDDDispatch = NULL;
  57. switch(getAH()) {
  58. //
  59. // Int2f Func 15xx - MSCDEX
  60. //
  61. case MSCDEX_FUNC:
  62. if (!pfnMscdexVDDDispatch) {
  63. pfnMscdexVDDDispatch = LoadMscdexAndGetVDDDispatchAddr();
  64. }
  65. if (pfnMscdexVDDDispatch) {
  66. bHandled = pfnMscdexVDDDispatch();
  67. }
  68. break;
  69. //
  70. // Int2f Func 16
  71. //
  72. case WIN386_FUNC:
  73. switch(getAL()) {
  74. case WIN386_KRNLIDLE:
  75. case WIN386_IDLE:
  76. bHandled = TRUE;
  77. break;
  78. case WIN386_GETLDT:
  79. if (getBX() == 0xbad) {
  80. setAX(0);
  81. setBX(SEL_LDT);
  82. bHandled = TRUE;
  83. }
  84. break;
  85. case WIN386_INT31:
  86. setAX(0);
  87. bHandled = TRUE;
  88. break;
  89. case WIN386_Get_Device_API:
  90. GetVxDApiHandler(getBX());
  91. bHandled = TRUE;
  92. break;
  93. case DPMI_MSDOS_EXT:
  94. VdmData = VdmMapFlat(getDS(), (*GetSIRegister)(), VDM_PM);
  95. if (!strcmp(VdmData, szMSDOS)) {
  96. setES(HIWORD(DosxMsDosApi));
  97. (*SetDIRegister)((ULONG)LOWORD(DosxMsDosApi));
  98. setAX(0);
  99. bHandled = TRUE;
  100. }
  101. break;
  102. }
  103. break;
  104. //
  105. // Int2f Func 40
  106. //
  107. case DISPCRIT_FUNC:
  108. if ((getAL() == DISPCRIT_ENTER) ||
  109. (getAL() == DISPCRIT_ENTER)) {
  110. bHandled = TRUE;
  111. }
  112. break;
  113. //
  114. // Int2f Func 43
  115. //
  116. case XMS_ID:
  117. if (getAL() == XMS_INS_CHK) {
  118. setAL(0x80);
  119. bHandled = TRUE;
  120. } else if (getAL() == XMS_CTRL_FUNC) {
  121. setES(HIWORD(DosxXmsControl));
  122. setBX(LOWORD(DosxXmsControl));
  123. bHandled = TRUE;
  124. }
  125. break;
  126. }
  127. return bHandled;
  128. }
  129. PFNMSCDEXVDDDISPATCH
  130. LoadMscdexAndGetVDDDispatchAddr(
  131. VOID
  132. )
  133. /*++
  134. Routine Description:
  135. This routine is called when we want the VCDEX VDD to handle
  136. a protected-mode Int2f AH=15, but we don't yet have a
  137. pointer to the VCDEX VDDDispatch entrypoint.
  138. Arguments:
  139. None
  140. Return Value:
  141. Pointer to VCDEX VDDDispatch or NULL if the VDD couldn't
  142. be loaded or the entrypoint couldn't be found.
  143. --*/
  144. {
  145. static const char szVCDEX[] = "VCDEX";
  146. DECLARE_LocalVdmContext;
  147. HANDLE hmodMscdexVdd;
  148. WORD saveAX, saveBX, saveCX;
  149. DWORD saveCF;
  150. //
  151. // The VDD may already have been loaded by the MSCDEX TSR.
  152. //
  153. hmodMscdexVdd = GetModuleHandle(szVCDEX);
  154. if (!hmodMscdexVdd) {
  155. //
  156. // Synthesize an Int2f 1500 to get the VDD loaded.
  157. // This can fail if the user has removed mscdex
  158. // from config.nt.
  159. //
  160. DpmiSwitchToRealMode();
  161. saveAX = getAX();
  162. saveBX = getBX();
  163. saveCX = getCX();
  164. saveCF = getCF();
  165. setAX(0x1500);
  166. setBX(0);
  167. DPMI_EXEC_INT(0x2f);
  168. setCF(saveCF);
  169. setCX(saveCX);
  170. setBX(saveBX);
  171. setAX(saveAX);
  172. DpmiSwitchToProtectedMode();
  173. //
  174. // Try again. If this fails, so will GetProcAddress below
  175. // and we'll pass it down to v86 mode handlers.
  176. //
  177. hmodMscdexVdd = GetModuleHandle(szVCDEX);
  178. }
  179. return (PFNMSCDEXVDDDISPATCH) GetProcAddress(hmodMscdexVdd, "VDDDispatch");
  180. }