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.

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