Leaked source code of windows server 2003
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.

412 lines
9.1 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. #if 0 // This probably is for private debugging only
  81. VOID
  82. DpmiIllegalFunction(
  83. VOID
  84. )
  85. /*++
  86. Routine Description:
  87. This routine ignores any Dpmi bops that are not implemented on a
  88. particular platform. It is called through the DpmiDispatchTable
  89. by #define'ing individual entries to this function.
  90. See dpmidata.h and dpmidatr.h.
  91. Arguments:
  92. None.
  93. Return Value:
  94. None.
  95. --*/
  96. {
  97. DECLARE_LocalVdmContext;
  98. char szFormat[] = "NtVdm: Invalid DPMI BOP from CS:IP %4.4x:%4.4x (%s mode), could be i386 dosx.exe.\n";
  99. char szMsg[sizeof(szFormat)+64];
  100. wsprintf(
  101. szMsg,
  102. szFormat,
  103. (int)getCS(),
  104. (int)getIP(),
  105. (getMSW() & MSW_PE) ? "prot" : "real"
  106. );
  107. OutputDebugString(szMsg);
  108. }
  109. #endif
  110. VOID
  111. DpmiInitDosxRM(
  112. VOID
  113. )
  114. /*++
  115. Routine Description:
  116. This routine handles the RM initialization bop for the dos extender.
  117. It get the addresses of the structures that the dos extender and
  118. 32 bit code share.
  119. Arguments:
  120. None
  121. Return Value:
  122. None.
  123. --*/
  124. {
  125. DECLARE_LocalVdmContext;
  126. PDOSX_RM_INIT_INFO pdi;
  127. ASSERT(!(getMSW() & MSW_PE));
  128. pdi = (PDOSX_RM_INIT_INFO) VdmMapFlat(getDS(), getSI(), VDM_V86);
  129. DosxStackFrameSize = pdi->StackFrameSize;
  130. RmBopFe = pdi->RmBopFe;
  131. PmBopFe = pdi->PmBopFe;
  132. DosxStackSegment = pdi->StackSegment;
  133. DosxRmCodeSegment = pdi->RmCodeSegment;
  134. DosxRmCodeSelector = pdi->RmCodeSelector;
  135. DosxFaultHandlerIret = pdi->pFaultHandlerIret;
  136. DosxFaultHandlerIretd = pdi->pFaultHandlerIretd;
  137. DosxIntHandlerIret = pdi->pIntHandlerIret;
  138. DosxIntHandlerIretd = pdi->pIntHandlerIretd;
  139. DosxIret = pdi->pIret;
  140. DosxIretd = pdi->pIretd;
  141. DosxRMReflector = pdi->RMReflector;
  142. RMCallBackBopOffset = pdi->RMCallBackBopOffset;
  143. RMCallBackBopSeg = pdi->RMCallBackBopSeg;
  144. PMReflectorSeg = pdi->PMReflectorSeg;
  145. DosxRmSaveRestoreState= pdi->RmSaveRestoreState;
  146. DosxPmSaveRestoreState= pdi->PmSaveRestoreState;
  147. DosxRmRawModeSwitch = pdi->RmRawModeSwitch;
  148. DosxPmRawModeSwitch = pdi->PmRawModeSwitch;
  149. DosxVcdPmSvcCall = pdi->VcdPmSvcCall;
  150. DosxMsDosApi = pdi->MsDosApi;
  151. DosxXmsControl = pdi->XmsControl;
  152. DosxHungAppExit = pdi->HungAppExit;
  153. //
  154. // Load the temporary LDT info (updated in DpmiInitLDT())
  155. //
  156. Ldt = VdmMapFlat(pdi->InitialLDTSeg, 0, VDM_V86);
  157. LdtMaxSel = pdi->InitialLDTSize;
  158. #ifdef _X86_
  159. //
  160. // On x86 platforms, return the fast bop address
  161. //
  162. GetFastBopEntryAddress(&((PVDM_TIB)NtCurrentTeb()->Vdm)->VdmContext);
  163. #endif
  164. }
  165. VOID
  166. DpmiInitDosx(
  167. VOID
  168. )
  169. /*++
  170. Routine Description:
  171. This routine handles the PM initialization bop for the dos extender.
  172. It get the addresses of the structures that the dos extender and
  173. 32 bit code share.
  174. Note: These values are initialized here since they are FLAT pointers,
  175. and are thus not easily computed at the time of InitDosxRM.
  176. Arguments:
  177. None
  178. Return Value:
  179. None.
  180. --*/
  181. {
  182. DECLARE_LocalVdmContext;
  183. PDOSX_INIT_INFO pdi;
  184. ASSERT((getMSW() & MSW_PE));
  185. pdi = (PDOSX_INIT_INFO) VdmMapFlat(getDS(), getSI(), VDM_PM);
  186. SmallXlatBuffer = Sim32GetVDMPointer(pdi->pSmallXlatBuffer, 4, TRUE);
  187. LargeXlatBuffer = Sim32GetVDMPointer(pdi->pLargeXlatBuffer, 4, TRUE);
  188. DosxDtaBuffer = Sim32GetVDMPointer(pdi->pDtaBuffer, 4, TRUE);
  189. DosxStackFramePointer = (PWORD16)((PULONG)Sim32GetVDMPointer(
  190. pdi->pStackFramePointer, 4, TRUE));
  191. }
  192. VOID
  193. DpmiInitApp(
  194. VOID
  195. )
  196. /*++
  197. Routine Description:
  198. This routine handles any necessary 32 bit initialization for extended
  199. applications.
  200. Arguments:
  201. None.
  202. Return Value:
  203. None.
  204. Notes:
  205. This function contains a number of 386 specific things.
  206. Since we are likely to expand the 32 bit portions of DPMI in the
  207. future, this makes more sense than duplicating the common portions
  208. another file.
  209. --*/
  210. {
  211. DECLARE_LocalVdmContext;
  212. PWORD16 Data;
  213. Data = (PWORD16) VdmMapFlat(getSS(), getSP(), VDM_PM);
  214. // Only 1 bit defined in dpmi
  215. CurrentAppFlags = getAX() & DPMI_32BIT;
  216. #ifdef _X86_
  217. ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.Flags = CurrentAppFlags;
  218. if (CurrentAppFlags & DPMI_32BIT) {
  219. *pNtVDMState |= VDM_32BIT_APP;
  220. }
  221. #endif
  222. DpmiInitRegisterSize();
  223. CurrentDta = Sim32GetVDMPointer(
  224. *(PDWORD16)(Data),
  225. 1,
  226. TRUE
  227. );
  228. CurrentDosDta = (PUCHAR) NULL;
  229. CurrentDtaOffset = *Data;
  230. CurrentDtaSelector = *(Data + 1);
  231. CurrentPSPSelector = *(Data + 2);
  232. CurrentPSPXmem = 0;
  233. }
  234. VOID
  235. DpmiTerminateApp(
  236. VOID
  237. )
  238. /*++
  239. Routine Description:
  240. This routine handles any necessary 32 bit destruction for extended
  241. applications.
  242. Arguments:
  243. None.
  244. Return Value:
  245. None.
  246. Notes:
  247. --*/
  248. {
  249. DECLARE_LocalVdmContext;
  250. DpmiFreeAppXmem(getDX());
  251. CurrentPSPXmem = 0; // DpmiFreeAppXmem should also zero it
  252. CurrentPSPSelector = getCX(); // indicate no running app
  253. }
  254. VOID
  255. DpmiEnableIntHooks(
  256. VOID
  257. )
  258. /*++
  259. Routine Description:
  260. This routine is called very early on in NTVDM initialization. It
  261. gives the dpmi code a chance to do some startup stuff before any
  262. client code has run.
  263. This is not called via bop.
  264. Arguments:
  265. None
  266. Return Value:
  267. None.
  268. --*/
  269. {
  270. #ifndef _X86_
  271. IntelBase = (ULONG) VdmMapFlat(0, 0, VDM_V86);
  272. VdmInstallHardwareIntHandler(DpmiHwIntHandler);
  273. VdmInstallSoftwareIntHandler(DpmiSwIntHandler);
  274. VdmInstallFaultHandler(DpmiFaultHandler);
  275. #endif // _X86_
  276. }
  277. #ifdef DBCS
  278. VOID
  279. DpmiSwitchToDosxStack(
  280. VOID
  281. )
  282. {
  283. DECLARE_LocalVdmContext;
  284. SWITCH_TO_DOSX_RMSTACK();
  285. }
  286. VOID
  287. DpmiSwitchFromDosxStack(
  288. VOID
  289. )
  290. {
  291. DECLARE_LocalVdmContext;
  292. SWITCH_FROM_DOSX_RMSTACK();
  293. }
  294. #endif