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.

407 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. dpmi32.c
  5. Abstract:
  6. This function contains common code such as the dpmi dispatcher,
  7. and handling for the initialization of the dos extender.
  8. Author:
  9. Dave Hastings (daveh) 24-Nov-1992
  10. Revision History:
  11. Neil Sandlin (neilsa) 31-Jul-1995 - Updates for the 486 emulator
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "softpc.h"
  16. #include <intapi.h>
  17. //
  18. // DPMI dispatch table
  19. //
  20. VOID (*DpmiDispatchTable[MAX_DPMI_BOP_FUNC])(VOID) = {
  21. DpmiInitDosxRM, // 0
  22. DpmiInitDosx, // 1
  23. DpmiInitLDT, // 2
  24. DpmiGetFastBopEntry, // 3
  25. DpmiInitIDT, // 4
  26. DpmiInitExceptionHandlers, // 5
  27. DpmiInitApp, // 6
  28. DpmiTerminateApp, // 7
  29. DpmiDpmiInUse, // 8
  30. DpmiDpmiNoLongerInUse, // 9
  31. switch_to_protected_mode, // 10 (DPMISwitchToProtectedMode)
  32. switch_to_real_mode, // 11 (DPMISwitchToRealMode)
  33. DpmiSetAltRegs, // 12
  34. DpmiIntHandlerIret16, // 13
  35. DpmiIntHandlerIret32, // 14
  36. DpmiFaultHandlerIret16, // 15
  37. DpmiFaultHandlerIret32, // 16
  38. DpmiUnhandledExceptionHandler, // 17
  39. DpmiRMCallBackCall, // 18
  40. DpmiReflectIntrToPM, // 19
  41. DpmiReflectIntrToV86, // 20
  42. DpmiInitPmStackInfo, // 21
  43. DpmiVcdPmSvcCall32, // 22
  44. DpmiSetDescriptorEntry, // 23
  45. DpmiResetLDTUserBase, // 24
  46. DpmiXlatInt21Call, // 25
  47. DpmiInt31Entry, // 26
  48. DpmiInt31Call, // 27
  49. DpmiHungAppIretAndExit // 28
  50. };
  51. VOID
  52. DpmiDispatch(
  53. VOID
  54. )
  55. /*++
  56. Routine Description:
  57. This function dispatches to the appropriate subfunction
  58. Arguments:
  59. None
  60. Return Value:
  61. None.
  62. --*/
  63. {
  64. DECLARE_LocalVdmContext;
  65. ULONG Index;
  66. static USHORT NestLevel = 0;
  67. Index = *(PUCHAR)VdmMapFlat(getCS(), getIP(), getMODE());
  68. setIP((getIP() + 1)); // take care of subfn.
  69. DBGTRACE(VDMTR_TYPE_DPMI | DPMI_DISPATCH_ENTRY, NestLevel++, Index);
  70. if (Index >= MAX_DPMI_BOP_FUNC) {
  71. //BUGBUG IMHO, we should fatal exit here
  72. #if DBG
  73. DbgPrint("NtVdm: Invalid DPMI BOP %lx\n", Index);
  74. #endif
  75. return;
  76. }
  77. (*DpmiDispatchTable[Index])();
  78. DBGTRACE(VDMTR_TYPE_DPMI | DPMI_DISPATCH_EXIT, --NestLevel, Index);
  79. }
  80. VOID
  81. DpmiIllegalFunction(
  82. VOID
  83. )
  84. /*++
  85. Routine Description:
  86. This routine ignores any Dpmi bops that are not implemented on a
  87. particular platform. It is called through the DpmiDispatchTable
  88. by #define'ing individual entries to this function.
  89. See dpmidata.h and dpmidatr.h.
  90. Arguments:
  91. None.
  92. Return Value:
  93. None.
  94. --*/
  95. {
  96. DECLARE_LocalVdmContext;
  97. char szFormat[] = "NtVdm: Invalid DPMI BOP from CS:IP %4.4x:%4.4x (%s mode), could be i386 dosx.exe.\n";
  98. char szMsg[sizeof(szFormat)+64];
  99. wsprintf(
  100. szMsg,
  101. szFormat,
  102. (int)getCS(),
  103. (int)getIP(),
  104. (getMSW() & MSW_PE) ? "prot" : "real"
  105. );
  106. OutputDebugString(szMsg);
  107. }
  108. VOID
  109. DpmiInitDosxRM(
  110. VOID
  111. )
  112. /*++
  113. Routine Description:
  114. This routine handles the RM initialization bop for the dos extender.
  115. It get the addresses of the structures that the dos extender and
  116. 32 bit code share.
  117. Arguments:
  118. None
  119. Return Value:
  120. None.
  121. --*/
  122. {
  123. DECLARE_LocalVdmContext;
  124. PDOSX_RM_INIT_INFO pdi;
  125. ASSERT(!(getMSW() & MSW_PE));
  126. pdi = (PDOSX_RM_INIT_INFO) VdmMapFlat(getDS(), getSI(), VDM_V86);
  127. DosxStackFrameSize = pdi->StackFrameSize;
  128. RmBopFe = pdi->RmBopFe;
  129. PmBopFe = pdi->PmBopFe;
  130. DosxStackSegment = pdi->StackSegment;
  131. DosxRmCodeSegment = pdi->RmCodeSegment;
  132. DosxRmCodeSelector = pdi->RmCodeSelector;
  133. DosxFaultHandlerIret = pdi->pFaultHandlerIret;
  134. DosxFaultHandlerIretd = pdi->pFaultHandlerIretd;
  135. DosxIntHandlerIret = pdi->pIntHandlerIret;
  136. DosxIntHandlerIretd = pdi->pIntHandlerIretd;
  137. DosxIret = pdi->pIret;
  138. DosxIretd = pdi->pIretd;
  139. DosxRMReflector = pdi->RMReflector;
  140. RMCallBackBopOffset = pdi->RMCallBackBopOffset;
  141. RMCallBackBopSeg = pdi->RMCallBackBopSeg;
  142. PMReflectorSeg = pdi->PMReflectorSeg;
  143. DosxRmSaveRestoreState= pdi->RmSaveRestoreState;
  144. DosxPmSaveRestoreState= pdi->PmSaveRestoreState;
  145. DosxRmRawModeSwitch = pdi->RmRawModeSwitch;
  146. DosxPmRawModeSwitch = pdi->PmRawModeSwitch;
  147. DosxVcdPmSvcCall = pdi->VcdPmSvcCall;
  148. DosxMsDosApi = pdi->MsDosApi;
  149. DosxXmsControl = pdi->XmsControl;
  150. DosxHungAppExit = pdi->HungAppExit;
  151. //
  152. // Load the temporary LDT info (updated in DpmiInitLDT())
  153. //
  154. Ldt = VdmMapFlat(pdi->InitialLDTSeg, 0, VDM_V86);
  155. LdtMaxSel = pdi->InitialLDTSize;
  156. #ifdef _X86_
  157. //
  158. // On x86 platforms, return the fast bop address
  159. //
  160. GetFastBopEntryAddress(&((PVDM_TIB)NtCurrentTeb()->Vdm)->VdmContext);
  161. #endif
  162. }
  163. VOID
  164. DpmiInitDosx(
  165. VOID
  166. )
  167. /*++
  168. Routine Description:
  169. This routine handles the PM initialization bop for the dos extender.
  170. It get the addresses of the structures that the dos extender and
  171. 32 bit code share.
  172. Note: These values are initialized here since they are FLAT pointers,
  173. and are thus not easily computed at the time of InitDosxRM.
  174. Arguments:
  175. None
  176. Return Value:
  177. None.
  178. --*/
  179. {
  180. DECLARE_LocalVdmContext;
  181. PDOSX_INIT_INFO pdi;
  182. ASSERT((getMSW() & MSW_PE));
  183. pdi = (PDOSX_INIT_INFO) VdmMapFlat(getDS(), getSI(), VDM_PM);
  184. SmallXlatBuffer = Sim32GetVDMPointer(pdi->pSmallXlatBuffer, 4, TRUE);
  185. LargeXlatBuffer = Sim32GetVDMPointer(pdi->pLargeXlatBuffer, 4, TRUE);
  186. DosxDtaBuffer = Sim32GetVDMPointer(pdi->pDtaBuffer, 4, TRUE);
  187. DosxStackFramePointer = (PWORD16)((PULONG)Sim32GetVDMPointer(
  188. pdi->pStackFramePointer, 4, TRUE));
  189. }
  190. VOID
  191. DpmiInitApp(
  192. VOID
  193. )
  194. /*++
  195. Routine Description:
  196. This routine handles any necessary 32 bit initialization for extended
  197. applications.
  198. Arguments:
  199. None.
  200. Return Value:
  201. None.
  202. Notes:
  203. This function contains a number of 386 specific things.
  204. Since we are likely to expand the 32 bit portions of DPMI in the
  205. future, this makes more sense than duplicating the common portions
  206. another file.
  207. --*/
  208. {
  209. DECLARE_LocalVdmContext;
  210. PWORD16 Data;
  211. Data = (PWORD16) VdmMapFlat(getSS(), getSP(), VDM_PM);
  212. // Only 1 bit defined in dpmi
  213. CurrentAppFlags = getAX() & DPMI_32BIT;
  214. #ifdef _X86_
  215. ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.Flags = CurrentAppFlags;
  216. if (CurrentAppFlags & DPMI_32BIT) {
  217. *pNtVDMState |= VDM_32BIT_APP;
  218. }
  219. #endif
  220. DpmiInitRegisterSize();
  221. CurrentDta = Sim32GetVDMPointer(
  222. *(PDWORD16)(Data),
  223. 1,
  224. TRUE
  225. );
  226. CurrentDosDta = (PUCHAR) NULL;
  227. CurrentDtaOffset = *Data;
  228. CurrentDtaSelector = *(Data + 1);
  229. CurrentPSPSelector = *(Data + 2);
  230. }
  231. VOID
  232. DpmiTerminateApp(
  233. VOID
  234. )
  235. /*++
  236. Routine Description:
  237. This routine handles any necessary 32 bit destruction for extended
  238. applications.
  239. Arguments:
  240. None.
  241. Return Value:
  242. None.
  243. Notes:
  244. --*/
  245. {
  246. DpmiFreeAppXmem();
  247. CurrentPSPSelector = 0; // indicate no running app
  248. }
  249. VOID
  250. DpmiEnableIntHooks(
  251. VOID
  252. )
  253. /*++
  254. Routine Description:
  255. This routine is called very early on in NTVDM initialization. It
  256. gives the dpmi code a chance to do some startup stuff before any
  257. client code has run.
  258. This is not called via bop.
  259. Arguments:
  260. None
  261. Return Value:
  262. None.
  263. --*/
  264. {
  265. #ifndef _X86_
  266. IntelBase = (ULONG) VdmMapFlat(0, 0, VDM_V86);
  267. VdmInstallHardwareIntHandler(DpmiHwIntHandler);
  268. VdmInstallSoftwareIntHandler(DpmiSwIntHandler);
  269. VdmInstallFaultHandler(DpmiFaultHandler);
  270. #endif // _X86_
  271. }
  272. #ifdef DBCS
  273. VOID
  274. DpmiSwitchToDosxStack(
  275. VOID
  276. )
  277. {
  278. DECLARE_LocalVdmContext;
  279. SWITCH_TO_DOSX_RMSTACK();
  280. }
  281. VOID
  282. DpmiSwitchFromDosxStack(
  283. VOID
  284. )
  285. {
  286. DECLARE_LocalVdmContext;
  287. SWITCH_FROM_DOSX_RMSTACK();
  288. }
  289. #endif