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.

1024 lines
23 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. dpmi32.h
  5. Abstract:
  6. This is the private include file for the 32 bit dpmi and protected mode
  7. support
  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. Neil Sandlin (neilsa) 15-Sep-1996 - Merged dpmi32p.h, dpmidata.h
  13. --*/
  14. #define FAST_VDM_REGISTERS
  15. //
  16. // DPMI structures and definitions
  17. //
  18. #define I31VERSION 90 // Int 31 services major/minor version #'s
  19. #define I31FLAGS 0x000D // 386 extender, pMode NetBIOS
  20. #define idCpuType 3 // LATER: conceivably, we could return the real proc type
  21. #define I31MasterPIC 0x08 // Master PIC Interrupts start at 08h
  22. #define I31SlavePIC 0x70 // Slave PIC Interrupts start at 70h
  23. #define MAX_APP_XMEM 0x2000000 // 32 MB = max DPMI mem + max XMS from pif
  24. #pragma pack(1)
  25. typedef struct _DPMIMEMINFO {
  26. DWORD LargestFree;
  27. DWORD MaxUnlocked;
  28. DWORD MaxLocked;
  29. DWORD AddressSpaceSize;
  30. DWORD UnlockedPages;
  31. DWORD FreePages;
  32. DWORD PhysicalPages;
  33. DWORD FreeAddressSpace;
  34. DWORD PageFileSize;
  35. } DPMIMEMINFO, *PDPMIMEMINFO;
  36. #pragma pack()
  37. #pragma pack(1)
  38. typedef struct _DPMI_RMCALLSTRUCT {
  39. DWORD Edi;
  40. DWORD Esi;
  41. DWORD Ebp;
  42. DWORD Reserved;
  43. DWORD Ebx;
  44. DWORD Edx;
  45. DWORD Ecx;
  46. DWORD Eax;
  47. WORD Flags;
  48. WORD Es;
  49. WORD Ds;
  50. WORD Fs;
  51. WORD Gs;
  52. WORD Ip;
  53. WORD Cs;
  54. WORD Sp;
  55. WORD Ss;
  56. } DPMI_RMCALLSTRUCT, *PDPMI_RMCALLSTRUCT;
  57. #pragma pack()
  58. //
  59. // dpmi32 init structure
  60. //
  61. #pragma pack(1)
  62. typedef struct _DOSX_RM_INIT_INFO {
  63. USHORT StackSegment;
  64. USHORT StackFrameSize;
  65. ULONG RmBopFe;
  66. ULONG PmBopFe;
  67. USHORT RmCodeSegment;
  68. USHORT RmCodeSelector;
  69. ULONG pFaultHandlerIret;
  70. ULONG pFaultHandlerIretd;
  71. ULONG pIntHandlerIret;
  72. ULONG pIntHandlerIretd;
  73. ULONG pIret;
  74. ULONG pIretd;
  75. USHORT RMCallBackBopOffset;
  76. USHORT RMCallBackBopSeg;
  77. ULONG RMReflector;
  78. USHORT PMReflectorSeg;
  79. USHORT InitialLDTSeg;
  80. USHORT InitialLDTSize;
  81. ULONG RmSaveRestoreState;
  82. ULONG PmSaveRestoreState;
  83. ULONG RmRawModeSwitch;
  84. ULONG PmRawModeSwitch;
  85. ULONG VcdPmSvcCall;
  86. ULONG MsDosApi;
  87. ULONG XmsControl;
  88. ULONG HungAppExit;
  89. } DOSX_RM_INIT_INFO;
  90. typedef DOSX_RM_INIT_INFO UNALIGNED* PDOSX_RM_INIT_INFO;
  91. typedef struct _DOSX_INIT_INFO {
  92. ULONG pSmallXlatBuffer;
  93. ULONG pLargeXlatBuffer;
  94. ULONG pStackFramePointer;
  95. ULONG pDtaBuffer;
  96. } DOSX_INIT_INFO;
  97. typedef DOSX_INIT_INFO UNALIGNED* PDOSX_INIT_INFO;
  98. #pragma pack()
  99. #define SWITCH_TO_DOSX_RMSTACK() { \
  100. setSS(DosxStackSegment); \
  101. setSP(*DosxStackFramePointer); \
  102. *DosxStackFramePointer -= DosxStackFrameSize; \
  103. }
  104. #define SWITCH_FROM_DOSX_RMSTACK() { \
  105. *DosxStackFramePointer += DosxStackFrameSize; \
  106. }
  107. //
  108. // Defines to allow us to use a common dispatch table without having
  109. // to add a bunch of stub functions
  110. //
  111. extern VDM_INTERRUPTHANDLER DpmiInterruptHandlers[256];
  112. extern VDM_FAULTHANDLER DpmiFaultHandlers[32];
  113. #ifdef _X86_
  114. #ifdef FAST_VDM_REGISTERS
  115. #define LockedPMStackSel (_LocalVdmTib->DpmiInfo.SsSelector)
  116. #define LockedPMStackCount (_LocalVdmTib->DpmiInfo.LockCount)
  117. #define PMLockOrigEIP (_LocalVdmTib->DpmiInfo.SaveEip)
  118. #define PMLockOrigESP (_LocalVdmTib->DpmiInfo.SaveEsp)
  119. #define PMLockOrigSS (_LocalVdmTib->DpmiInfo.SaveSsSelector)
  120. #define DosxFaultHandlerIret (_LocalVdmTib->DpmiInfo.DosxFaultIret)
  121. #define DosxFaultHandlerIretd (_LocalVdmTib->DpmiInfo.DosxFaultIretD)
  122. #define DosxIntHandlerIret (_LocalVdmTib->DpmiInfo.DosxIntIret)
  123. #define DosxIntHandlerIretd (_LocalVdmTib->DpmiInfo.DosxIntIretD)
  124. #define DosxRMReflector (_LocalVdmTib->DpmiInfo.DosxRmReflector)
  125. #else //FAST_VDM_REGISTERS
  126. // Temporary only. Doing this so I can switch back to the old way in case ...
  127. #define LockedPMStackSel ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.SsSelector
  128. #define LockedPMStackCount ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.LockCount
  129. #define PMLockOrigEIP ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.SaveEip
  130. #define PMLockOrigESP ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.SaveEsp
  131. #define PMLockOrigSS ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.SaveSsSelector
  132. #define DosxFaultHandlerIret ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.DosxFaultIret
  133. #define DosxFaultHandlerIretd ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.DosxFaultIretD
  134. #define DosxIntHandlerIret ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.DosxIntIret
  135. #define DosxIntHandlerIretd ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.DosxIntIretD
  136. #define DosxRMReflector ((PVDM_TIB)NtCurrentTeb()->Vdm)->DpmiInfo.DosxRmReflector
  137. #endif //FAST_VDM_REGISTERS
  138. #else // _X86_
  139. extern USHORT LockedPMStackSel;
  140. extern ULONG LockedPMStackCount;
  141. extern ULONG PMLockOrigEIP;
  142. extern ULONG PMLockOrigSS;
  143. extern ULONG PMLockOrigESP;
  144. extern ULONG DosxFaultHandlerIret;
  145. extern ULONG DosxFaultHandlerIretd;
  146. extern ULONG DosxIntHandlerIret;
  147. extern ULONG DosxIntHandlerIretd;
  148. extern ULONG DosxRMReflector;
  149. //
  150. // Ldt entry definition
  151. //
  152. // This appears in nti386.h, and winnt.h. The definitions in
  153. // winnt.h are not included if the nt include files are included.
  154. // The simple solution, since this structure will never change
  155. // is to put the definition here.
  156. //
  157. typedef struct _LDT_ENTRY {
  158. WORD LimitLow;
  159. WORD BaseLow;
  160. union {
  161. struct {
  162. BYTE BaseMid;
  163. BYTE Flags1; // Declare as bytes to avoid alignment
  164. BYTE Flags2; // Problems.
  165. BYTE BaseHi;
  166. } Bytes;
  167. struct {
  168. DWORD BaseMid : 8;
  169. DWORD Type : 5;
  170. DWORD Dpl : 2;
  171. DWORD Pres : 1;
  172. DWORD LimitHi : 4;
  173. DWORD Sys : 1;
  174. DWORD Reserved_0 : 1;
  175. DWORD Default_Big : 1;
  176. DWORD Granularity : 1;
  177. DWORD BaseHi : 8;
  178. } Bits;
  179. } HighWord;
  180. } LDT_ENTRY, *PLDT_ENTRY;
  181. //
  182. // Data items
  183. //
  184. extern VOID force_yoda(VOID);
  185. extern VOID DisableEmulatorIretHooks(VOID);
  186. extern VOID EnableEmulatorIretHooks(VOID);
  187. #endif
  188. typedef struct _IDT_ENTRY {
  189. WORD OffsetLow;
  190. WORD Selector;
  191. BYTE Reserved;
  192. union {
  193. struct {
  194. BYTE Flags;
  195. } Bytes;
  196. struct {
  197. BYTE Type : 5;
  198. BYTE Dpl : 2;
  199. BYTE Pres : 1;
  200. } Bits;
  201. } u;
  202. WORD OffsetHi;
  203. } IDT_ENTRY, *PIDT_ENTRY;
  204. #define GET_SELECTOR_BASE(Sel) ( (ULONG) ( \
  205. Ldt[Sel>>3].BaseLow | \
  206. Ldt[Sel>>3].HighWord.Bytes.BaseMid << 16 | \
  207. Ldt[Sel>>3].HighWord.Bytes.BaseHi << 24 \
  208. ))
  209. #define GET_SELECTOR_LIMIT(Sel) ( (ULONG) ( \
  210. ((Ldt[Sel>>3].HighWord.Bits.LimitHi << 16 | Ldt[Sel>>3].LimitLow) \
  211. << (12 * Ldt[Sel>>3].HighWord.Bits.Granularity)) + \
  212. Ldt[Sel>>3].HighWord.Bits.Granularity * 0xFFF \
  213. ))
  214. #if DBG
  215. #define GET_SHADOW_SELECTOR_LIMIT(Selector, Limit) \
  216. Limit = SelectorLimit[Selector>>3]
  217. #else
  218. #ifdef _X86_
  219. #define GET_SHADOW_SELECTOR_LIMIT(Selector, Limit) _asm \
  220. { \
  221. _asm xor eax, eax \
  222. _asm xor ecx, ecx \
  223. _asm mov ax, Selector \
  224. _asm or eax, 7 \
  225. _asm lsl ecx, eax \
  226. _asm mov [Limit], ecx \
  227. }
  228. #else
  229. #define GET_SHADOW_SELECTOR_LIMIT(Selector, Limit) \
  230. Limit = GET_SELECTOR_LIMIT(Selector)
  231. #endif
  232. #endif
  233. #define SET_SELECTOR_LIMIT(Sel, Limit) { \
  234. USHORT i = Sel>>3; \
  235. if (!Ldt[i].HighWord.Bits.Granularity) { \
  236. Ldt[i].LimitLow = (USHORT)(Limit & 0x0000FFFF); \
  237. Ldt[i].HighWord.Bits.LimitHi = \
  238. (Limit & 0x000f0000) >> 16; \
  239. } else { \
  240. Ldt[i].LimitLow = (USHORT)((Limit >> 12) & 0xFFFF); \
  241. Ldt[i].HighWord.Bits.LimitHi = \
  242. ((Limit >> 12) & 0x000f0000) >> 16; \
  243. } \
  244. }
  245. #define SET_SELECTOR_ACCESS(Sel, Access) { \
  246. Ldt[Sel>>3].HighWord.Bytes.Flags1 = LOBYTE(Access); \
  247. Ldt[Sel>>3].HighWord.Bytes.Flags2 = (HIBYTE(Access) & 0xd0) + \
  248. (Ldt[Sel>>3].HighWord.Bytes.Flags2 & 0x0f); \
  249. }
  250. #define IS_SELECTOR_FREE(Sel) ((Ldt[Sel>>3].HighWord.Bytes.Flags1 == 0) && \
  251. (Ldt[Sel>>3].HighWord.Bytes.BaseHi == 0x80))
  252. #define IS_SELECTOR_READABLE(Sel) ( \
  253. ((Ldt[Sel>>3].HighWord.Bytes.Flags1 & \
  254. (AB_DPL3|AB_PRESENT|AB_DATA)) == \
  255. (AB_DPL3|AB_PRESENT|AB_DATA)) \
  256. )
  257. #ifdef _X86_
  258. #define FLUSH_SELECTOR_CACHE(SelStart, SelCount) TRUE
  259. #else
  260. #define FLUSH_SELECTOR_CACHE(SelStart, SelCount) FlushSelectorCache(SelStart, SelCount)
  261. #endif
  262. //
  263. // These values define the range of the reserved DPMI selectors, given
  264. // out by Int31, func 000d.
  265. //
  266. #define SEL_DPMI_FIRST 0
  267. #define SEL_DPMI_LAST 0x78
  268. // Whenever we allocate a descriptor, the access rights byte is set
  269. // to 0Fh. This marks it as a '386 task gate, which is not legal to
  270. // have in the GDT. We need to stick something in this byte, because
  271. // having the access rights byte be 0 means that it is free, which is
  272. // no longer the case.
  273. #define MARK_SELECTOR_ALLOCATED(Sel) { \
  274. Ldt[Sel>>3].HighWord.Bytes.Flags1 = 0xf; \
  275. Ldt[Sel>>3].HighWord.Bytes.BaseHi = 0; \
  276. }
  277. #define MARK_SELECTOR_FREE(Sel) { \
  278. Ldt[Sel>>3].HighWord.Bytes.Flags1 = 0; \
  279. Ldt[Sel>>3].HighWord.Bytes.BaseHi = 0x80; \
  280. }
  281. #define NEXT_FREE_SEL(Sel) (Ldt[Sel>>3].LimitLow)
  282. #define ALLOCATE_SELECTOR() AllocateSelectors(1, FALSE)
  283. #define ALLOCATE_SELECTORS(Count) AllocateSelectors(Count, FALSE)
  284. #define ALLOCATE_WOW_SELECTORS(Count) AllocateSelectors(Count, TRUE)
  285. #define SEGMENT_IS_BIG(sel) ((sel<LdtMaxSel) && (Ldt[(sel & ~0x7)/sizeof(LDT_ENTRY)].HighWord.Bits.Default_Big))
  286. #define SEGMENT_IS_PRESENT(sel) ((sel<LdtMaxSel) && (Ldt[(sel & ~0x7)/sizeof(LDT_ENTRY)].HighWord.Bits.Pres))
  287. // This checks for S, Data, W
  288. #define SEGMENT_IS_WRITABLE(sel) ((sel<LdtMaxSel) && ( (Ldt[(sel & ~0x7)/sizeof(LDT_ENTRY)].HighWord.Bits.Type & 0x1a) == 0x12))
  289. #define SEL_INDEX_MASK ~7
  290. // Ldt, ring 3 bits
  291. #define SEL_LDT3 7
  292. //
  293. // Descriptor Access Byte constants
  294. //
  295. #define AB_ACCESSED 0x01 //segment has been accessed
  296. #define AB_WRITE 0x02 //writable data
  297. #define AB_DATA 0x10 //data segment
  298. #define AB_CODE 0x18 //code segment
  299. #define AB_DPL3 0x60 //ring 3 DPL
  300. #define AB_PRESENT 0x80 //segment present bit
  301. #define AB_TRAPGATE 0x07 //trap gate descriptor
  302. #define AB_INTRGATE 0x0e //80386 interrupt gate descriptor
  303. #define STD_DATA AB_PRESENT+AB_DPL3+AB_DATA+AB_WRITE
  304. #define STD_TRAP AB_PRESENT+AB_DPL3+AB_TRAPGATE
  305. #define STD_INTR AB_PRESENT+AB_DPL3+AB_INTRGATE
  306. //
  307. // Internal Constants
  308. //
  309. #define MAX_V86_ADDRESS 64 * 1024 + 1024 * 1024
  310. #define ONE_MB 1024 * 1024
  311. // bugbug
  312. #define SMALL_XLAT_BUFFER_SIZE 128
  313. // bugbug
  314. #define LARGE_XLAT_BUFFER_SIZE 8192
  315. #define DPMI_32BIT 0x1
  316. #define Frame32 ((BOOL)CurrentAppFlags)
  317. #define LockedPMStackOffset 0x1000
  318. //
  319. // Internal types
  320. //
  321. typedef ULONG (*GETREGISTERFUNCTION)(VOID);
  322. typedef VOID (*SETREGISTERFUNCTION)(ULONG);
  323. #define SAVE_CLIENT_REGS(Regs) {\
  324. Regs.Eax = getEAX(); \
  325. Regs.Ebx = getEBX(); \
  326. Regs.Ecx = getECX(); \
  327. Regs.Edx = getEDX(); \
  328. Regs.Edi = getEDI(); \
  329. Regs.Esi = getESI(); \
  330. Regs.Ebp = getEBP(); \
  331. Regs.Eip = getEIP(); \
  332. Regs.Esp = getESP(); \
  333. Regs.Eflags = getEFLAGS(); \
  334. Regs.Cs = getCS(); \
  335. Regs.Ds = getDS(); \
  336. Regs.Es = getES(); \
  337. Regs.Fs = getFS(); \
  338. Regs.Gs = getGS(); \
  339. Regs.Ss = getSS(); \
  340. }
  341. #define SET_CLIENT_REGS(Regs) { \
  342. setEAX(Regs.Eax); \
  343. setEBX(Regs.Ebx); \
  344. setECX(Regs.Ecx); \
  345. setEDX(Regs.Edx); \
  346. setEDI(Regs.Edi); \
  347. setESI(Regs.Esi); \
  348. setEBP(Regs.Ebp); \
  349. setEIP(Regs.Eip); \
  350. setESP(Regs.Esp); \
  351. setEFLAGS(Regs.Eflags); \
  352. setCS(Regs.Cs); \
  353. setDS(Regs.Ds); \
  354. setES(Regs.Es); \
  355. setFS(Regs.Fs); \
  356. setGS(Regs.Gs); \
  357. setSS(Regs.Ss); \
  358. }
  359. typedef struct _CLIENT_REGS {
  360. ULONG Eax;
  361. ULONG Ebx;
  362. ULONG Ecx;
  363. ULONG Edx;
  364. ULONG Edi;
  365. ULONG Esi;
  366. ULONG Ebp;
  367. ULONG Eip;
  368. ULONG Esp;
  369. ULONG Eflags;
  370. USHORT Cs;
  371. USHORT Ss;
  372. USHORT Es;
  373. USHORT Ds;
  374. USHORT Fs;
  375. USHORT Gs;
  376. } CLIENT_REGS, *PCLIENT_REGS;
  377. //
  378. // Memory management definitions
  379. //
  380. #define DELETE_BLOCK(BLK) \
  381. (BLK->Prev)->Next = BLK->Next;\
  382. (BLK->Next)->Prev = BLK->Prev;\
  383. if (CurrentPSPSelector != 0 && BLK->Owner != 0) CurrentPSPXmem -= BLK->Length
  384. #define INSERT_BLOCK(BLK, HEAD) \
  385. BLK->Next = HEAD.Next; \
  386. BLK->Prev= HEAD.Next->Prev;\
  387. (HEAD.Next)->Prev = BLK; \
  388. HEAD.Next = BLK; \
  389. if (CurrentPSPSelector != 0 && BLK->Owner != 0) CurrentPSPXmem += BLK->Length
  390. #define RESIZE_BLOCK(BLK, ADDR, SIZE) \
  391. if (CurrentPSPSelector != 0 && BLK->Owner != 0) { \
  392. CurrentPSPXmem -= BLK->Length; \
  393. CurrentPSPXmem += SIZE; \
  394. } \
  395. BLK->Address = (PVOID)ADDR; \
  396. BLK->Length = SIZE
  397. //
  398. // Visible structure for save state stuff
  399. //
  400. typedef struct _VSavedState {
  401. UCHAR Misc[28];
  402. } VSAVEDSTATE, PVSAVEDSTATE;
  403. //
  404. // Descriptor mapping (for dib.drv)
  405. //
  406. #ifndef _X86_
  407. ULONG
  408. GetDescriptorMapping(
  409. USHORT Sel,
  410. ULONG LdtBase
  411. );
  412. typedef struct _DESC_MAPPING {
  413. USHORT Sel;
  414. USHORT SelCount;
  415. ULONG LdtBase;
  416. ULONG FlatBase;
  417. struct _DESC_MAPPING* pNext;
  418. } DESC_MAPPING, *PDESC_MAPPING;
  419. #endif
  420. //
  421. // Dpmi32 data
  422. //
  423. //SLT: these two should be per-thread
  424. extern ULONG LastLockedPMStackSS;
  425. extern ULONG LastLockedPMStackESP;
  426. extern PUCHAR SmallXlatBuffer;
  427. extern PUCHAR LargeXlatBuffer;
  428. extern BOOL SmallBufferInUse;
  429. extern USHORT LargeBufferInUseCount;
  430. extern USHORT DosxStackSegment;
  431. extern USHORT DosxRmCodeSegment;
  432. extern USHORT DosxRmCodeSelector;
  433. extern PWORD16 DosxStackFramePointer;
  434. extern USHORT DosxStackFrameSize;
  435. extern USHORT CurrentAppFlags;
  436. extern ULONG RmBopFe;
  437. extern ULONG PmBopFe;
  438. extern USHORT RMCallBackBopSeg;
  439. extern USHORT RMCallBackBopOffset;
  440. extern USHORT PMReflectorSeg;
  441. extern PUCHAR DosxDtaBuffer;
  442. extern ULONG IntelBase;
  443. extern PLDT_ENTRY Ldt;
  444. extern USHORT LdtSel;
  445. extern USHORT LdtMaxSel;
  446. extern USHORT LdtUserSel;
  447. extern PIDT_ENTRY Idt;
  448. extern USHORT WOWAllocSeg;
  449. extern USHORT WOWAllocFunc;
  450. extern USHORT WOWFreeSeg;
  451. extern USHORT WOWFreeFunc;
  452. //
  453. // Information about the current DTA
  454. //
  455. // N.B. The selector:offset, and flat pointer following MAY point to
  456. // different linear addresses. This will be the case if the
  457. // dta selector is in high memory
  458. extern PUCHAR CurrentDta;
  459. extern PUCHAR CurrentPmDtaAddress;
  460. extern PUCHAR CurrentDosDta;
  461. extern USHORT CurrentDtaSelector;
  462. extern USHORT CurrentDtaOffset;
  463. #if DBG
  464. extern ULONG SelectorLimit[LDT_SIZE];
  465. #endif
  466. //
  467. // Register manipulation functions (for register that might be 16 or 32 bits)
  468. //
  469. extern GETREGISTERFUNCTION GetCXRegister;
  470. extern GETREGISTERFUNCTION GetDXRegister;
  471. extern GETREGISTERFUNCTION GetDIRegister;
  472. extern GETREGISTERFUNCTION GetSIRegister;
  473. extern GETREGISTERFUNCTION GetBXRegister;
  474. extern GETREGISTERFUNCTION GetAXRegister;
  475. extern GETREGISTERFUNCTION GetSPRegister;
  476. extern SETREGISTERFUNCTION SetCXRegister;
  477. extern SETREGISTERFUNCTION SetDXRegister;
  478. extern SETREGISTERFUNCTION SetDIRegister;
  479. extern SETREGISTERFUNCTION SetSIRegister;
  480. extern SETREGISTERFUNCTION SetBXRegister;
  481. extern SETREGISTERFUNCTION SetAXRegister;
  482. extern SETREGISTERFUNCTION SetSPRegister;
  483. extern USHORT CurrentPSPSelector;
  484. extern ULONG CurrentPSPXmem;
  485. extern ULONG FlatAddress[LDT_SIZE];
  486. extern ULONG DosxIret;
  487. extern ULONG DosxIretd;
  488. extern ULONG DosxRmSaveRestoreState;
  489. extern ULONG DosxPmSaveRestoreState;
  490. extern ULONG DosxRmRawModeSwitch;
  491. extern ULONG DosxPmRawModeSwitch;
  492. extern ULONG DosxVcdPmSvcCall;
  493. extern ULONG DosxMsDosApi;
  494. extern ULONG DosxXmsControl;
  495. extern ULONG DosxHungAppExit;
  496. //
  497. // Monitor functions
  498. //
  499. VOID
  500. GetFastBopEntryAddress(
  501. PCONTEXT VdmContext
  502. );
  503. //
  504. // Dispatched functions (via bop)
  505. //
  506. VOID DpmiInitDosxRM(VOID);
  507. VOID DpmiInitDosx(VOID);
  508. VOID DpmiInitLDT(VOID);
  509. VOID DpmiGetFastBopEntry(VOID);
  510. VOID DpmiInitIDT(VOID);
  511. VOID DpmiInitExceptionHandlers(VOID);
  512. VOID DpmiInitPmStackInfo(VOID);
  513. VOID DpmiInitApp(VOID);
  514. VOID DpmiTerminateApp(VOID);
  515. VOID DpmiDpmiInUse(VOID);
  516. VOID DpmiDpmiNoLongerInUse(VOID);
  517. VOID switch_to_protected_mode(VOID);
  518. VOID switch_to_real_mode(VOID);
  519. VOID DpmiSetAltRegs(VOID);
  520. VOID DpmiVcdPmSvcCall32(VOID);
  521. VOID DpmiFreeAppXmem(USHORT);
  522. VOID DpmiFreeAllXmem(VOID);
  523. VOID DpmiIntHandlerIret16(VOID);
  524. VOID DpmiIntHandlerIret32(VOID);
  525. VOID DpmiFaultHandlerIret16(VOID);
  526. VOID DpmiFaultHandlerIret32(VOID);
  527. VOID DpmiUnhandledExceptionHandler(VOID);
  528. VOID DpmiRMCallBackCall(VOID);
  529. VOID DpmiReflectIntrToPM(VOID);
  530. VOID DpmiReflectIntrToV86(VOID);
  531. VOID DpmiSetDescriptorEntry(VOID);
  532. VOID DpmiAllocateSelectors(VOID);
  533. VOID DpmiFreeSelector(VOID);
  534. VOID DpmiResetLDTUserBase(VOID);
  535. VOID DpmiXlatInt21Call(VOID);
  536. VOID DpmiInt31Entry(VOID);
  537. VOID DpmiInt31Call(VOID);
  538. VOID DpmiHungAppIretAndExit(VOID);
  539. //
  540. // Internal functions
  541. //
  542. VOID
  543. BeginUseLockedPMStack(
  544. VOID
  545. );
  546. BOOL
  547. EndUseLockedPMStack(
  548. VOID
  549. );
  550. BOOL
  551. BuildStackFrame(
  552. ULONG StackUnits,
  553. PUCHAR *pVdmStackPointer,
  554. ULONG *pNewSP
  555. );
  556. VOID
  557. EmulateV86Int(
  558. UCHAR InterruptNumber
  559. );
  560. typedef enum {
  561. RESTORE_FLAGS,
  562. PASS_FLAGS,
  563. PASS_CARRY_FLAG,
  564. PASS_CARRY_FLAG_16
  565. } IRET_BEHAVIOR;
  566. VOID
  567. SimulateIret(
  568. IRET_BEHAVIOR fdsp
  569. );
  570. VOID
  571. SimulateFarCall(
  572. USHORT Seg,
  573. ULONG Offset
  574. );
  575. VOID
  576. SimulateCallWithIretFrame(
  577. USHORT Seg,
  578. ULONG Offset
  579. );
  580. BOOL
  581. DpmiSwIntHandler(
  582. ULONG IntNumber
  583. );
  584. BOOL
  585. DpmiHwIntHandler(
  586. ULONG IntNumber
  587. );
  588. BOOL
  589. DpmiFaultHandler(
  590. ULONG IntNumber,
  591. ULONG ErrorCode
  592. );
  593. BOOL
  594. SetProtectedModeInterrupt(
  595. USHORT IntNumber,
  596. USHORT Sel,
  597. ULONG Offset,
  598. USHORT Flags
  599. );
  600. BOOL
  601. SetFaultHandler(
  602. USHORT IntNumber,
  603. USHORT Sel,
  604. ULONG Offset
  605. );
  606. BOOL
  607. DispatchPMInt(
  608. UCHAR InterruptNumber
  609. );
  610. VOID
  611. DpmiRMCall(
  612. UCHAR mode
  613. );
  614. VOID
  615. DpmiAllocateRMCallBack(
  616. VOID
  617. );
  618. VOID
  619. DpmiFreeRMCallBack(
  620. VOID
  621. );
  622. BOOL
  623. PMInt2fHandler(
  624. VOID
  625. );
  626. VOID
  627. GetVxDApiHandler(
  628. USHORT VxdId
  629. );
  630. BOOL
  631. DpmiSetDebugRegisters(
  632. PULONG RegisterPointer
  633. );
  634. BOOL
  635. DpmiGetDebugRegisters(
  636. PULONG RegisterPointer
  637. );
  638. //
  639. // Descriptor managagment
  640. //
  641. #ifdef _X86_
  642. BOOL
  643. DpmiSetX86Descriptor(
  644. USHORT SelStart,
  645. USHORT SelCount
  646. );
  647. #else
  648. VOID
  649. FlushSelectorCache(
  650. USHORT SelStart,
  651. USHORT SelCount
  652. );
  653. #endif
  654. VOID
  655. SetShadowDescriptorEntries(
  656. USHORT SelStart,
  657. USHORT SelCount
  658. );
  659. VOID
  660. SetDescriptorBase(
  661. USHORT Sel,
  662. ULONG Base
  663. );
  664. VOID
  665. SetDescriptor(
  666. USHORT Sel,
  667. ULONG Base,
  668. ULONG Limit,
  669. USHORT Access
  670. );
  671. USHORT
  672. AllocateSelectors(
  673. USHORT Count,
  674. BOOL bWow
  675. );
  676. BOOL
  677. FreeSelector(
  678. USHORT Sel
  679. );
  680. USHORT
  681. FindSelector(
  682. ULONG Base,
  683. UCHAR Access
  684. );
  685. BOOL
  686. RemoveFreeSelector(
  687. USHORT Sel
  688. );
  689. USHORT
  690. SegmentToSelector(
  691. USHORT Segment,
  692. USHORT Access
  693. );
  694. VOID
  695. SetDescriptorArray(
  696. USHORT Sel,
  697. ULONG Base,
  698. ULONG MemSize
  699. );
  700. //
  701. // Memory management
  702. //
  703. NTSTATUS
  704. DpmiAllocateVirtualMemory(
  705. PVOID *Address,
  706. PULONG Size
  707. );
  708. NTSTATUS
  709. DpmiFreeVirtualMemory(
  710. PVOID *Address,
  711. PULONG Size
  712. );
  713. NTSTATUS
  714. DpmiReallocateVirtualMemory(
  715. PVOID OldAddress,
  716. ULONG OldSize,
  717. PVOID *NewAddress,
  718. PULONG NewSize
  719. );
  720. VOID
  721. DpmiGetMemoryInfo(
  722. VOID
  723. );
  724. PMEM_DPMI
  725. DpmiAllocateXmem(
  726. ULONG Size
  727. );
  728. BOOL
  729. DpmiFreeXmem(
  730. PMEM_DPMI XmemBlock
  731. );
  732. BOOL
  733. DpmiIsXmemHandle(
  734. PMEM_DPMI XmemBlock
  735. );
  736. BOOL
  737. DpmiReallocateXmem(
  738. PMEM_DPMI XmemBlock,
  739. ULONG Size
  740. );
  741. PMEM_DPMI
  742. DpmiFindXmem(
  743. USHORT Sel
  744. );
  745. ULONG
  746. DpmiCalculateAppXmem(
  747. VOID
  748. );
  749. VOID
  750. DpmiAllocateDosMem(
  751. VOID
  752. );
  753. VOID
  754. DpmiFreeDosMem(
  755. VOID
  756. );
  757. VOID
  758. DpmiSizeDosMem(
  759. VOID
  760. );
  761. //
  762. // Utility functions
  763. //
  764. VOID
  765. DpmiInitRegisterSize(
  766. VOID
  767. );
  768. VOID
  769. DpmiSwitchToProtectedMode(
  770. VOID
  771. );
  772. VOID
  773. DpmiSwitchToRealMode(
  774. VOID
  775. );
  776. VOID
  777. DpmiPushRmInt(
  778. USHORT InterruptNumber
  779. );
  780. VOID
  781. DpmiSaveSegmentsAndStack(
  782. PVOID ContextPointer
  783. );
  784. PVOID
  785. DpmiRestoreSegmentsAndStack(
  786. VOID
  787. );
  788. //
  789. // Int21 translation
  790. //
  791. VOID
  792. SetVector(
  793. VOID
  794. );
  795. VOID
  796. GetVector(
  797. VOID
  798. );
  799. PUCHAR
  800. DpmiMapAndCopyBuffer(
  801. PUCHAR Buffer,
  802. USHORT BufferLength
  803. );
  804. VOID
  805. DpmiUnmapAndCopyBuffer(
  806. PUCHAR Destination,
  807. PUCHAR Source,
  808. USHORT BufferLength
  809. );
  810. USHORT
  811. DpmiCalcFcbLength(
  812. PUCHAR FcbPointer
  813. );
  814. PUCHAR
  815. DpmiMapString(
  816. USHORT StringSeg,
  817. ULONG StringOff,
  818. PWORD16 Length
  819. );
  820. PUCHAR
  821. DpmiAllocateBuffer(
  822. USHORT Length
  823. );
  824. #define DpmiUnmapString DpmiFreeBuffer
  825. #define DpmiUnmapBuffer DpmiFreeBuffer
  826. VOID
  827. DpmiFreeBuffer(
  828. PUCHAR Buffer,
  829. USHORT Length
  830. );
  831. VOID
  832. DpmiFreeAllBuffers(
  833. VOID
  834. );
  835. #ifdef DBCS
  836. VOID
  837. DpmiSwitchToDosxStack(
  838. VOID
  839. );
  840. VOID
  841. DpmiSwitchFromDosxStack(
  842. VOID
  843. );
  844. #endif //DBCS