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.

3021 lines
62 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Int21Map.c
  5. Abstract:
  6. This module performs int 21 API translation for dpmi
  7. Author:
  8. Dave Hastings (daveh) 23-Nov-1992
  9. Revision History:
  10. Neil Sandlin (neilsa) 31-Jul-1995 - Updates for the 486 emulator
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include "int21map.h"
  15. #include "softpc.h"
  16. #include "xlathlp.h"
  17. //
  18. // Local constants
  19. //
  20. //#define Verbose 1
  21. #define MAX_SUPPORTED_DOS_CALL 0x6d
  22. #define DosxTranslated NULL
  23. typedef VOID (*APIXLATFUNCTION)(VOID);
  24. APIXLATFUNCTION ApiXlatTable[MAX_SUPPORTED_DOS_CALL] = {
  25. DosxTranslated , // 00h - Terminate process
  26. NoTranslation , // 01h - Char input with echo
  27. NoTranslation , // 02h - Character output
  28. NoTranslation , // 03h - Auxiliary input
  29. NoTranslation , // 04h - Auxiliary output
  30. NoTranslation , // 05h - Print character
  31. NoTranslation , // 06h - Direct console I/O
  32. NoTranslation , // 07h - Unfiltered char input
  33. NoTranslation , // 08h - Char input w/o echo
  34. DisplayString , // 09h - Display "$" term string
  35. BufferedKeyboardInput , // 0Ah - Buffered keyboard input
  36. NoTranslation , // 0Bh - Check keyboard status
  37. FlushBuffReadKbd , // 0Ch - Flush buff, Read kbd
  38. NoTranslation , // 0Dh - Disk reset
  39. NoTranslation , // 0Eh - Select disk
  40. NotSupportedFCB , // 0Fh * Open file with FCB
  41. NotSupportedFCB , // 10h * Close file with FCB
  42. FindFileFCB , // 11h - Find First File
  43. FindFileFCB , // 12h - Find Next File
  44. MapFCB , // 13h - Delete File
  45. NotSupportedFCB , // 14h * Sequential Read
  46. NotSupportedFCB , // 15h * Sequential Write
  47. NotSupportedFCB , // 16h * Create File With FCB
  48. RenameFCB , // 17h - Rename File With FCB
  49. NoTranslation , // 18h - UNUSED
  50. NoTranslation , // 19h - Get Current Disk
  51. SetDTA , // 1Ah - Set DTA Address
  52. GetDriveData , // 1Bh - Get Default Drive Data
  53. GetDriveData , // 1Ch - Get Drive Data
  54. NoTranslation , // 1Dh - UNUSED
  55. NoTranslation , // 1Eh - UNUSED
  56. GetDriveData , // 1Fh - Get Drive Parameter Blk
  57. NoTranslation , // 20h - UNUSED
  58. NotSupportedFCB , // 21h * Random Read
  59. NotSupportedFCB , // 22h * Random Write
  60. NotSupportedFCB , // 23h * Get File Size
  61. NotSupportedFCB , // 24h * Set Relative Record
  62. SetVector , // 25h - Set interrupt vector
  63. CreatePSP , // 26h - Create PSP
  64. NotSupportedFCB , // 27h * Random block read
  65. NotSupportedFCB , // 28h * Random block write
  66. ParseFilename , // 29h - Parse filename
  67. GetDate , // 2Ah - Get date
  68. NoTranslation , // 2Bh - Set date
  69. NoTranslation , // 2Ch - Get time
  70. NoTranslation , // 2Dh - Set time
  71. NoTranslation , // 2Eh - Set/Reset verify flag
  72. GetDTA , // 2Fh - Get DTA address
  73. NoTranslation , // 30h - Get DOS version
  74. TSR , // 31h - Terminate and Stay Res
  75. GetDevParamBlock , // 32h - Get device parameter blk
  76. NoTranslation , // 33h - Get/Set Control-C Flag
  77. ReturnESBX , // 34h - Get Address of InDOS
  78. GetVector , // 35h - Get Interrupt Vector
  79. NoTranslation , // 36h - Get Disk Free Space
  80. NoTranslation , // 37h - Char Oper
  81. GetSetCountry , // 38h - Get/Set Current Country
  82. MapASCIIZDSDX , // 39h - Create Directory
  83. MapASCIIZDSDX , // 3Ah - Remove Directory
  84. MapASCIIZDSDX , // 3Bh - Change Current Directory
  85. MapASCIIZDSDX , // 3Ch - Create File with Handle
  86. MapASCIIZDSDX , // 3Dh - Open File with Handle
  87. NoTranslation , // 3Eh - Close File with Handle
  88. ReadWriteFile , // 3Fh - Read File or Device
  89. ReadWriteFile , // 40h - Write File or Device
  90. MapASCIIZDSDX , // 41h - Delete File
  91. NoTranslation , // 42h - Move file pointer
  92. MapASCIIZDSDX , // 43h - Get/Set File Attributes
  93. IOCTL , // 44h - IOCTL
  94. NoTranslation , // 45h - Duplicate File Handle
  95. NoTranslation , // 46h - Force Duplicate Handle
  96. GetCurDir , // 47h - Get Current Directory
  97. AllocateMemoryBlock , // 48h - Allocate Memory Block
  98. FreeMemoryBlock , // 49h - Free Memory Block
  99. ResizeMemoryBlock , // 4Ah - Resize Memory Block
  100. LoadExec , // 4Bh - Load and Exec Program
  101. DosxTranslated , // 4Ch - Terminate with Ret Code
  102. NoTranslation , // 4Dh - Get Ret Code Child Proc
  103. FindFirstFileHandle , // 4Eh - Find First File
  104. FindNextFileHandle , // 4Fh - Find Next File
  105. SetPSP , // 50h - Set PSP Segment
  106. GetPSP , // 51h - Get PSP Segment
  107. ReturnESBX , // 52h - Get List of Lists (invars)
  108. TranslateBPB , // 53h - Translate BPB
  109. NoTranslation , // 54h - Get Verify Flag
  110. CreatePSP , // 55h - Create PSP
  111. RenameFile , // 56h - Rename File
  112. NoTranslation , // 57h - Get/Set Date/Time File
  113. NoTranslation , // 58h - Get/Set Alloc Strategy
  114. NoTranslation , // 59h - Get Extended Error Info
  115. CreateTempFile , // 5Ah - Create Temporary File
  116. MapASCIIZDSDX , // 5Bh - Create New File
  117. NoTranslation , // 5Ch - Lock/Unlock File Region
  118. Func5Dh , // 5Dh - Server DOS call
  119. Func5Eh , // 5Eh - Net Name/Printer Setup
  120. Func5Fh , // 5Fh - Network redir stuff
  121. NotSupportedBad , // 60h - NameTrans
  122. NoTranslation , // 61h - UNUSED
  123. GetPSP , // 62h - Get PSP Address
  124. #ifdef DBCS
  125. ReturnDSSI , // 63h - Get DBCS Vector
  126. #else
  127. NotSupportedBetter , // 63h - Hangool call
  128. #endif
  129. NotSupportedBad , // 64h - Set Prn Flag
  130. GetExtendedCountryInfo , // 65h - Get Extended Country Info
  131. NoTranslation , // 66h - Get/Set Global Code Page
  132. NoTranslation , // 67h - Set Handle Count
  133. NoTranslation , // 68h - Commit File
  134. NoTranslation , // 69h -
  135. NoTranslation , // 6Ah -
  136. NoTranslation , // 6Bh -
  137. MapASCIIZDSSI // 6Ch - Extended open
  138. };
  139. VOID
  140. DpmiXlatInt21Call(
  141. VOID
  142. )
  143. /*++
  144. Routine Description:
  145. This routine dispatches to the appropriate routine to perform the
  146. actual translation of the api
  147. Arguments:
  148. None
  149. Return Value:
  150. None.
  151. --*/
  152. {
  153. DECLARE_LocalVdmContext;
  154. ULONG DosMajorCode;
  155. PUCHAR StackPointer;
  156. //
  157. // Pop ds from stack
  158. //
  159. StackPointer = Sim32GetVDMPointer(
  160. ((ULONG)getSS() << 16),
  161. 1,
  162. TRUE
  163. );
  164. StackPointer += (*GetSPRegister)();
  165. setDS(*(PWORD16)StackPointer);
  166. (*SetSPRegister)((*GetSPRegister)() + 2);
  167. DosMajorCode = getAH();
  168. if (DosMajorCode >= MAX_SUPPORTED_DOS_CALL) {
  169. return;
  170. }
  171. if (ApiXlatTable[DosMajorCode]) {
  172. ULONG Eip, Esp;
  173. USHORT Cs, Ss;
  174. Eip = getEIP();
  175. Esp = getESP();
  176. Cs = getCS();
  177. Ss = getSS();
  178. (*ApiXlatTable[DosMajorCode])();
  179. setEIP(Eip);
  180. setESP(Esp);
  181. setCS(Cs);
  182. setSS(Ss);
  183. SimulateIret(PASS_CARRY_FLAG_16);
  184. }
  185. // put this back in after beta 2.5
  186. DpmiFreeAllBuffers();
  187. }
  188. VOID
  189. NoTranslation(
  190. VOID
  191. )
  192. /*++
  193. Routine Description:
  194. This routine handles int 21 functions which don't need any translation.
  195. It simply executes the int 21 in real/v86 mode
  196. Arguments:
  197. None
  198. Return Value:
  199. None.
  200. --*/
  201. {
  202. DECLARE_LocalVdmContext;
  203. DpmiSwitchToRealMode();
  204. DPMI_EXEC_INT(0x21);
  205. DpmiSwitchToProtectedMode();
  206. }
  207. VOID
  208. DisplayString(
  209. VOID
  210. )
  211. /*++
  212. Routine Description:
  213. This routine translates the int 21 display string function.
  214. N.B. Win 3.1 does this by calling int 21 function 2 repeatedly.
  215. We do it this way because Win 3.1 does. If this function is
  216. frequently used, we should actually buffer the string and
  217. call the dos display string function.
  218. Arguments:
  219. None
  220. Return Value:
  221. None.
  222. --*/
  223. { PUCHAR String;
  224. DECLARE_LocalVdmContext;
  225. USHORT ClientAX, ClientDX;
  226. USHORT ClientDS = getDS();
  227. DpmiSwitchToRealMode();
  228. String = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  229. + (*GetDXRegister)();
  230. //
  231. // Repeatedly call int 21 function 2 to display the characters
  232. //
  233. ClientAX = getAX();
  234. ClientDX = getDX();
  235. setAH(2);
  236. while (*(String) != '$') {
  237. setDL(*(String));
  238. DPMI_EXEC_INT(0x21);
  239. String++;
  240. }
  241. setAX(ClientAX);
  242. setDX(ClientDX);
  243. DpmiSwitchToProtectedMode();
  244. }
  245. VOID
  246. BufferedKeyboardInput(
  247. VOID
  248. )
  249. /*++
  250. Routine Description:
  251. This routine performs the tranlation for the int 21 function Ah
  252. Arguments:
  253. None.
  254. Return Value:
  255. None.
  256. --*/
  257. {
  258. DECLARE_LocalVdmContext;
  259. PUCHAR PmInputBuffer, RmInputBuffer;
  260. USHORT BufferSeg, BufferOff, BufferLen;
  261. USHORT ClientDX;
  262. USHORT ClientDS = getDS();
  263. DpmiSwitchToRealMode();
  264. ClientDX = getDX();
  265. //
  266. // Get a pointer to the PM buffer
  267. //
  268. PmInputBuffer = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  269. + (*GetDXRegister)();
  270. //
  271. // Get the buffer length (there are two bytes in addition to the
  272. // buffer)
  273. //
  274. BufferLen = *PmInputBuffer + 2;
  275. //
  276. // Move the buffer to low memory
  277. //
  278. RmInputBuffer = DpmiMapAndCopyBuffer(PmInputBuffer, BufferLen);
  279. //
  280. // Set up the registers for the int 21 call
  281. //
  282. DPMI_FLAT_TO_SEGMENTED(RmInputBuffer, &BufferSeg, &BufferOff);
  283. setDS(BufferSeg);
  284. setDX(BufferOff);
  285. DPMI_EXEC_INT(0x21);
  286. //
  287. // Copy the data back
  288. //
  289. DpmiUnmapAndCopyBuffer(PmInputBuffer, RmInputBuffer, BufferLen);
  290. setDX(ClientDX);
  291. DpmiSwitchToProtectedMode();
  292. setDS(ClientDS);
  293. }
  294. VOID
  295. FlushBuffReadKbd(
  296. VOID
  297. )
  298. /*++
  299. Routine Description:
  300. This routine performs translation for the flush keyboard routines.
  301. It calls the appropriate xlat routine.
  302. Arguments:
  303. None.
  304. Return Value:
  305. None.
  306. --*/
  307. {
  308. DECLARE_LocalVdmContext;
  309. if (getAL() == 0x0a) {
  310. BufferedKeyboardInput();
  311. } else {
  312. NoTranslation();
  313. }
  314. }
  315. VOID
  316. NotSupportedFCB(
  317. VOID
  318. )
  319. /*++
  320. Routine Description:
  321. This routine does not do any translation. It prints a warning to
  322. the debugger
  323. Arguments:
  324. None.
  325. Return Value:
  326. None.
  327. --*/
  328. {
  329. #if DBG
  330. DECLARE_LocalVdmContext;
  331. DbgPrint(
  332. "WARNING: DOS INT 21 call AH = %x will not be translated.\n", getAH());
  333. DbgPrint(
  334. " Protected mode applications should not be using\n");
  335. DbgPrint(
  336. " this type of FCB call. Convert this application\n");
  337. DbgPrint(
  338. " to use the handle calls.\n"
  339. );
  340. #endif
  341. NoTranslation();
  342. }
  343. VOID
  344. FindFileFCB(
  345. VOID
  346. )
  347. /*++
  348. Routine Description:
  349. This function translates the find first/find next FCB calls.
  350. Arguments:
  351. None.
  352. Return Value:
  353. None.
  354. --*/
  355. {
  356. DECLARE_LocalVdmContext;
  357. PUCHAR FcbAddress, FcbBufferedAddress;
  358. USHORT FcbSegment, FcbOffset;
  359. USHORT ClientDX;
  360. USHORT FcbLength;
  361. USHORT ClientDS = getDS();
  362. DpmiSwitchToRealMode();
  363. SetDTAPointers();
  364. ClientDX = getDX();
  365. FcbAddress = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  366. + (*GetDXRegister)();
  367. //
  368. // Calculate the size of the FCB
  369. //
  370. FcbLength = DpmiCalcFcbLength(FcbAddress);
  371. //
  372. // Buffer the FCB
  373. //
  374. FcbBufferedAddress = DpmiMapAndCopyBuffer(FcbAddress, FcbLength);
  375. //
  376. // Check to see if we need to set the real dta
  377. //
  378. if (CurrentDosDta != CurrentDta)
  379. SetDosDTA();
  380. //
  381. // Make the int 21 call
  382. //
  383. DPMI_FLAT_TO_SEGMENTED(FcbBufferedAddress, &FcbSegment, &FcbOffset);
  384. setDS(FcbSegment);
  385. setDX(FcbOffset);
  386. DPMI_EXEC_INT(0x21);
  387. //
  388. // If the call was successful and the PM dta is in high memory
  389. // copy the dta to high memory
  390. //
  391. if ((getAL() == 0) && (CurrentPmDtaAddress != CurrentDta)) {
  392. MoveMemory(CurrentPmDtaAddress, CurrentDta, FcbLength);
  393. DpmiUnmapAndCopyBuffer(FcbAddress, FcbBufferedAddress, FcbLength);
  394. } else {
  395. DpmiUnmapBuffer(FcbBufferedAddress, FcbLength);
  396. }
  397. setDX(ClientDX);
  398. DpmiSwitchToProtectedMode();
  399. setDS(ClientDS);
  400. }
  401. VOID
  402. MapFCB(
  403. VOID
  404. )
  405. /*++
  406. Routine Description:
  407. This routine translates the delete file fcb int 21 call
  408. Arguments:
  409. None.
  410. Return Value:
  411. None.
  412. --*/
  413. {
  414. DECLARE_LocalVdmContext;
  415. USHORT FcbLength, FcbSegment, FcbOffset;
  416. PUCHAR FcbAddress, FcbBufferedAddress;
  417. USHORT ClientDX;
  418. USHORT ClientDS = getDS();
  419. DpmiSwitchToRealMode();
  420. ClientDX = getDX();
  421. FcbAddress = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  422. + (*GetDXRegister)();
  423. //
  424. // Get the length of the FCB
  425. //
  426. FcbLength = DpmiCalcFcbLength(FcbAddress);
  427. //
  428. // Copy the FCB
  429. //
  430. FcbBufferedAddress = DpmiMapAndCopyBuffer(FcbAddress, FcbLength);
  431. //
  432. // Make the int 21 call
  433. //
  434. DPMI_FLAT_TO_SEGMENTED(FcbBufferedAddress, &FcbSegment, &FcbOffset);
  435. setDS(FcbSegment);
  436. setDX(FcbOffset);
  437. DPMI_EXEC_INT(0x21);
  438. //
  439. // Copy the FCB back
  440. //
  441. DpmiUnmapAndCopyBuffer(FcbAddress, FcbBufferedAddress, FcbLength);
  442. //
  443. // Clean up
  444. //
  445. setDX(ClientDX);
  446. DpmiSwitchToProtectedMode();
  447. setDS(ClientDS);
  448. }
  449. VOID
  450. RenameFCB(
  451. VOID
  452. )
  453. /*++
  454. Routine Description:
  455. This routine translates the rename fcb int 21 function
  456. Arguments:
  457. None.
  458. Return Value:
  459. None.
  460. --*/
  461. {
  462. DECLARE_LocalVdmContext;
  463. USHORT FcbSegment, FcbOffset;
  464. PUCHAR FcbAddress, FcbBufferedAddress;
  465. USHORT ClientDX;
  466. USHORT ClientDS = getDS();
  467. DpmiSwitchToRealMode();
  468. ClientDX = getDX();
  469. FcbAddress = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  470. + (*GetDXRegister)();
  471. //
  472. // Copy the FCB (The fcb for rename is a special format, fixed size)
  473. //
  474. FcbBufferedAddress = DpmiMapAndCopyBuffer(FcbAddress, 0x25);
  475. //
  476. // Make the int 21 call
  477. //
  478. DPMI_FLAT_TO_SEGMENTED(FcbBufferedAddress, &FcbSegment, &FcbOffset);
  479. setDS(FcbSegment);
  480. setDX(FcbOffset);
  481. DPMI_EXEC_INT(0x21);
  482. //
  483. // Copy the FCB back
  484. //
  485. DpmiUnmapAndCopyBuffer(FcbAddress, FcbAddress, 0x25);
  486. //
  487. // Clean up
  488. //
  489. setDX(ClientDX);
  490. DpmiSwitchToProtectedMode();
  491. setDS(ClientDS);
  492. }
  493. VOID
  494. GetDriveData(
  495. VOID
  496. )
  497. /*++
  498. Routine Description:
  499. Translates the drive data int 21 calls
  500. Arguments:
  501. None.
  502. Return Value:
  503. None.
  504. --*/
  505. {
  506. DECLARE_LocalVdmContext;
  507. USHORT Selector;
  508. DpmiSwitchToRealMode();
  509. DPMI_EXEC_INT(0x21);
  510. Selector = getDS();
  511. DpmiSwitchToProtectedMode();
  512. setDS(SegmentToSelector(Selector, STD_DATA));
  513. (*SetBXRegister)((ULONG)getBX());
  514. }
  515. VOID
  516. SetVector(
  517. VOID
  518. )
  519. /*++
  520. Routine Description:
  521. This function translates int 21 function 25
  522. Arguments:
  523. None.
  524. Return Value:
  525. None.
  526. --*/
  527. {
  528. DECLARE_LocalVdmContext;
  529. SetProtectedModeInterrupt(getAL(), getDS(), (*GetDXRegister)(),
  530. (USHORT)(Frame32 ? VDM_INT_32 : VDM_INT_16));
  531. }
  532. VOID
  533. CreatePSP(
  534. VOID
  535. )
  536. /*++
  537. Routine Description:
  538. This routine translates the selector to a segment and reflects the
  539. calls
  540. Arguments:
  541. None.
  542. Return Value:
  543. None.
  544. --*/
  545. {
  546. DECLARE_LocalVdmContext;
  547. ULONG Segment;
  548. USHORT ClientDX;
  549. DpmiSwitchToRealMode();
  550. ClientDX = getDX();
  551. Segment = SELECTOR_TO_INTEL_LINEAR_ADDRESS(ClientDX);
  552. if (Segment > ONE_MB) {
  553. //
  554. // Create PSP doesn't do anything on error
  555. //
  556. } else {
  557. setDX((USHORT) (Segment >> 4));
  558. DPMI_EXEC_INT(0x21);
  559. }
  560. setDX(ClientDX);
  561. DpmiSwitchToProtectedMode();
  562. }
  563. VOID
  564. ParseFilename(
  565. VOID
  566. )
  567. /*++
  568. Routine Description:
  569. This routine translates the int 21 parse filename api
  570. Arguments:
  571. None.
  572. Return Value:
  573. None.
  574. --*/
  575. {
  576. DECLARE_LocalVdmContext;
  577. USHORT ClientSI, ClientDI, FcbLength, StringOff, Seg, Off;
  578. PUCHAR Fcb, BufferedFcb, String, BufferedString;
  579. USHORT ClientDS = getDS();
  580. USHORT ClientES = getES();
  581. DpmiSwitchToRealMode();
  582. ClientSI = getSI();
  583. ClientDI = getDI();
  584. Fcb = Sim32GetVDMPointer(((ULONG)ClientES << 16), 1, TRUE)
  585. + (*GetDIRegister)();
  586. FcbLength = DpmiCalcFcbLength(Fcb);
  587. BufferedFcb = DpmiMapAndCopyBuffer(Fcb, FcbLength);
  588. String = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  589. + (*GetSIRegister)();
  590. BufferedString = DpmiMapAndCopyBuffer(String, 20);
  591. DPMI_FLAT_TO_SEGMENTED(BufferedFcb, &Seg, &Off);
  592. setES(Seg);
  593. setDI(Off);
  594. DPMI_FLAT_TO_SEGMENTED(BufferedString, &Seg, &StringOff);
  595. setDS(Seg);
  596. setSI(StringOff);
  597. DPMI_EXEC_INT(0x21);
  598. DpmiUnmapAndCopyBuffer(Fcb, BufferedFcb, FcbLength);
  599. DpmiUnmapAndCopyBuffer(String, BufferedString, 20);
  600. setDI(ClientDI);
  601. setSI(ClientSI + (getSI() - StringOff));
  602. DpmiSwitchToProtectedMode();
  603. setDS(ClientDS);
  604. setES(ClientES);
  605. }
  606. VOID
  607. GetDTA(
  608. VOID
  609. )
  610. /*++
  611. Routine Description:
  612. This routine returns the current DTA.
  613. Arguments:
  614. None.
  615. Return Value:
  616. None.
  617. --*/
  618. {
  619. DECLARE_LocalVdmContext;
  620. //
  621. // Win31 compatibility:
  622. //
  623. // Some hosebag programs set the DTA to a selector that they later free!
  624. // This test makes sure that this does not cause us to crash.
  625. //
  626. if (!SEGMENT_IS_WRITABLE(CurrentDtaSelector)) {
  627. CurrentDtaSelector = 0;
  628. CurrentDtaOffset = 0;
  629. }
  630. setES(CurrentDtaSelector);
  631. setBX(CurrentDtaOffset);
  632. setCF(0);
  633. }
  634. VOID
  635. SetDTA(
  636. VOID
  637. )
  638. /*++
  639. Routine Description:
  640. This routine sets the PM dta address. If the buffer is usable directly,
  641. CurrentDta is set to the translated address. Otherwise, it is set to
  642. the dosx dta.
  643. N.B. The Set Dta call is not actually reflected to Dos until a function
  644. call is made that actually uses the Dta, e.g. the Find First/Next
  645. functions. This techique was implemented to match what is done in
  646. Win 3.1.
  647. Arguments:
  648. None.
  649. Return Value:
  650. None.
  651. --*/
  652. {
  653. DECLARE_LocalVdmContext;
  654. USHORT ClientDX;
  655. ClientDX = getDX();
  656. CurrentDtaOffset = ClientDX;
  657. CurrentDtaSelector = getDS();
  658. //
  659. // Make sure real DTA is updated later
  660. //
  661. CurrentDosDta = (PUCHAR) NULL;
  662. }
  663. VOID
  664. SetDTAPointers(
  665. VOID
  666. )
  667. /*++
  668. Routine Description:
  669. This routine sets up the flat address values used elsewhere to
  670. reference the current DTA.
  671. N.B. This must be done on every entry to handle function calls because
  672. the PM dta may have been GlobalRealloc'd. This may change the base
  673. address of the PM selector (which invalidates the flat addresses),
  674. but not the selector/offset itself.
  675. Arguments:
  676. None.
  677. Return Value:
  678. None.
  679. --*/
  680. {
  681. PUCHAR NewDta;
  682. NewDta = Sim32GetVDMPointer(
  683. (CurrentDtaSelector << 16),
  684. 1,
  685. TRUE
  686. );
  687. NewDta += CurrentDtaOffset;
  688. CurrentPmDtaAddress = NewDta;
  689. //
  690. // If the new dta is not accessible in v86 mode, use the one
  691. // supplied by Dosx
  692. //
  693. if ((ULONG)(NewDta + 128 - IntelBase) > MAX_V86_ADDRESS) {
  694. NewDta = DosxDtaBuffer;
  695. }
  696. //
  697. // Update Current DTA information
  698. //
  699. CurrentDta = NewDta;
  700. }
  701. VOID
  702. SetDosDTA(
  703. VOID
  704. )
  705. /*++
  706. Routine Description:
  707. This routine is called internally by other functions in this module
  708. to reflect a Set Dta call to Dos.
  709. WARNING: The client must be in REAL mode
  710. Arguments:
  711. None.
  712. Return Value:
  713. None.
  714. --*/
  715. {
  716. DECLARE_LocalVdmContext;
  717. USHORT ClientAX, ClientDX, ClientDS, NewDtaSegment, NewDtaOffset;
  718. ASSERT((getMSW() & MSW_PE) == 0);
  719. ClientAX = getAX();
  720. ClientDX = getDX();
  721. ClientDS = getDS();
  722. DPMI_FLAT_TO_SEGMENTED(CurrentDta, &NewDtaSegment, &NewDtaOffset);
  723. setDS(NewDtaSegment);
  724. setDX(NewDtaOffset);
  725. setAH(0x1a);
  726. DPMI_EXEC_INT(0x21);
  727. setAX(ClientAX);
  728. setDX(ClientDX);
  729. setDS(ClientDS);
  730. CurrentDosDta = CurrentDta;
  731. }
  732. VOID
  733. TSR(
  734. VOID
  735. )
  736. /*++
  737. Routine Description:
  738. This function translates int 21h tsr. Win 3.1 does some
  739. magic here. We didn't before and it worked fine. Maybe
  740. we will later.
  741. Arguments:
  742. None.
  743. Return Value:
  744. None.
  745. --*/
  746. {
  747. NoTranslation();
  748. }
  749. VOID
  750. GetDevParamBlock(
  751. VOID
  752. )
  753. /*++
  754. Routine Description:
  755. This routine translates the Device Parameter Block apis
  756. Arguments:
  757. None.
  758. Return Value:
  759. None.
  760. --*/
  761. {
  762. DECLARE_LocalVdmContext;
  763. USHORT Selector;
  764. DpmiSwitchToRealMode();
  765. DPMI_EXEC_INT(0x21);
  766. Selector = getDS();
  767. DpmiSwitchToProtectedMode();
  768. setDS(SegmentToSelector(Selector, STD_DATA));
  769. (*SetBXRegister)((ULONG)getBX());
  770. }
  771. VOID
  772. ReturnESBX(
  773. VOID
  774. )
  775. /*++
  776. Routine Description:
  777. This function translates api that return information in es:bx
  778. Arguments:
  779. None.
  780. Return Value:
  781. None.
  782. --*/
  783. {
  784. DECLARE_LocalVdmContext;
  785. USHORT Selector;
  786. DpmiSwitchToRealMode();
  787. DPMI_EXEC_INT(0x21);
  788. Selector = getES();
  789. DpmiSwitchToProtectedMode();
  790. (*SetBXRegister)((ULONG)getBX());
  791. setES(SegmentToSelector(Selector, STD_DATA));
  792. }
  793. VOID
  794. GetVector(
  795. VOID
  796. )
  797. /*++
  798. Routine Description:
  799. This function translates int 21 function 35
  800. Arguments:
  801. None.
  802. Return Value:
  803. None.
  804. --*/
  805. {
  806. DECLARE_LocalVdmContext;
  807. PVDM_INTERRUPTHANDLER Handlers = DpmiInterruptHandlers;
  808. USHORT IntNumber = getAL();
  809. setES(Handlers[IntNumber].CsSelector);
  810. (*SetBXRegister)(Handlers[IntNumber].Eip);
  811. }
  812. VOID
  813. GetSetCountry(
  814. VOID
  815. )
  816. /*++
  817. Routine Description:
  818. This function translates int 21 function 38
  819. Arguments:
  820. None.
  821. Return Value:
  822. None.
  823. --*/
  824. {
  825. DECLARE_LocalVdmContext;
  826. if (getDX() == 0xFFFF) {
  827. NoTranslation();
  828. } else {
  829. USHORT ClientDX, Seg, Off;
  830. PUCHAR Country, BufferedCountry;
  831. USHORT ClientDS = getDS();
  832. DpmiSwitchToRealMode();
  833. ClientDX = getDX();
  834. Country = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  835. + (*GetDXRegister)();
  836. BufferedCountry = DpmiMapAndCopyBuffer(Country, 34);
  837. DPMI_FLAT_TO_SEGMENTED(BufferedCountry, &Seg, &Off);
  838. setDS(Seg);
  839. setDX(Off);
  840. DPMI_EXEC_INT(0x21);
  841. DpmiSwitchToProtectedMode();
  842. DpmiUnmapAndCopyBuffer(Country, BufferedCountry, 34);
  843. setDX(ClientDX);
  844. setDS(ClientDS);
  845. }
  846. }
  847. VOID
  848. MapASCIIZDSDX(
  849. VOID
  850. )
  851. /*++
  852. Routine Description:
  853. This routine maps the int 21 functions that pass file names in
  854. ds:dx
  855. Arguments:
  856. None.
  857. Return Value:
  858. None.
  859. --*/
  860. {
  861. DECLARE_LocalVdmContext;
  862. PUCHAR BufferedString;
  863. USHORT ClientDX, StringSeg, StringOff, Length;
  864. USHORT ClientDS = getDS();
  865. BufferedString = DpmiMapString(ClientDS, (GetDXRegister)(), &Length);
  866. if (BufferedString == NULL) {
  867. setCF(1);
  868. setAX(3);
  869. } else {
  870. DpmiSwitchToRealMode();
  871. ClientDX = getDX();
  872. DPMI_FLAT_TO_SEGMENTED(BufferedString, &StringSeg, &StringOff);
  873. setDS(StringSeg);
  874. setDX(StringOff);
  875. DPMI_EXEC_INT(0x21);
  876. DpmiSwitchToProtectedMode();
  877. DpmiUnmapString(BufferedString, Length);
  878. setDX(ClientDX);
  879. setDS(ClientDS);
  880. }
  881. }
  882. VOID
  883. ReadWriteFile(
  884. VOID
  885. )
  886. /*++
  887. Routine Description:
  888. This routine translates the read/write file int 21 calls. Large reads
  889. are broken down into 4k chunks.
  890. Arguments:
  891. None.
  892. Return Value:
  893. None.
  894. --*/
  895. {
  896. DECLARE_LocalVdmContext;
  897. USHORT ClientCX, ClientDX, ClientAX, Function, DataSeg, DataOff, BytesToRead;
  898. ULONG BytesRead, TotalBytesToRead;
  899. PUCHAR ReadWriteData, BufferedData;
  900. USHORT ClientDS = getDS();
  901. DpmiSwitchToRealMode();
  902. ClientCX = getCX();
  903. ClientDX = getDX();
  904. Function = getAH();
  905. ClientAX = getAX();
  906. TotalBytesToRead = (*GetCXRegister)();
  907. BytesRead = 0;
  908. ReadWriteData = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  909. + (*GetDXRegister)();
  910. // while (TotalBytesToRead != BytesRead) {
  911. do {
  912. if ((TotalBytesToRead - BytesRead) > 1024 * 4) {
  913. BytesToRead = 4 * 1024;
  914. } else {
  915. BytesToRead = (USHORT)(TotalBytesToRead - BytesRead);
  916. }
  917. BufferedData = DpmiMapAndCopyBuffer(ReadWriteData, BytesToRead);
  918. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  919. setDS(DataSeg);
  920. setDX(DataOff);
  921. setCX(BytesToRead);
  922. setAX(ClientAX);
  923. DPMI_EXEC_INT(0x21);
  924. if (getCF()) {
  925. DpmiUnmapBuffer(BufferedData, BytesToRead);
  926. break;
  927. }
  928. if (getAX() == 0) {
  929. DpmiUnmapBuffer(BufferedData, BytesToRead);
  930. break;
  931. } else if (getAX() < BytesToRead) {
  932. CopyMemory(ReadWriteData, BufferedData, getAX());
  933. DpmiUnmapBuffer(BufferedData, BytesToRead);
  934. BytesRead += getAX();
  935. break;
  936. } else {
  937. DpmiUnmapAndCopyBuffer(
  938. ReadWriteData,
  939. BufferedData,
  940. BytesToRead
  941. );
  942. }
  943. ReadWriteData += getAX();
  944. BytesRead += getAX();
  945. // }
  946. } while (TotalBytesToRead != BytesRead);
  947. setDX(ClientDX);
  948. setCX(ClientCX);
  949. if (!getCF()) {
  950. (*SetAXRegister)(BytesRead);
  951. }
  952. DpmiSwitchToProtectedMode();
  953. setDS(ClientDS);
  954. }
  955. #define MAX_SUPPORTED_DOS_IOCTL_CALL 0x10
  956. //
  957. // Note: The translations here differ from those in the windows dpmi vxd,
  958. // because we do not have to lock memory, and we don't support block
  959. // device drivers.
  960. //
  961. APIXLATFUNCTION IOCTLXlatTable[MAX_SUPPORTED_DOS_IOCTL_CALL] = {
  962. NoTranslation , // 00 - Get Device Data
  963. NoTranslation , // 01 - Set Device Data
  964. MapDSDXLenCX , // 02 - Receive Ctrl Chr Data
  965. MapDSDXLenCX , // 03 - Send Ctrl Chr Data
  966. MapDSDXLenCX , // 04 - Receive Ctrl Block Data
  967. MapDSDXLenCX , // 05 - Send Ctrl Block Data
  968. NoTranslation , // 06 - Check Input Status
  969. NoTranslation , // 07 - Check Output Status
  970. NoTranslation , // 08 - Check Block Dev Removable
  971. NoTranslation , // 09 - Check Block Dev Remote
  972. NoTranslation , // 0A - Check if Handle Remote
  973. NoTranslation , // 0B - Change sharing retry cnt
  974. IOCTLMap2Bytes , // 0C - MAP DS:DX LENGTH 2!
  975. IOCTLBlockDevs , // 0D - Generic IOCTL to blk dev
  976. NoTranslation , // 0E - Get Logical Drive Map
  977. NoTranslation // 0F - Set Logical Drive Map
  978. };
  979. VOID
  980. IOCTL(
  981. VOID
  982. )
  983. /*++
  984. Routine Description:
  985. This function translates the int 21 ioctl function.
  986. Arguments:
  987. None.
  988. Return Value:
  989. None.
  990. --*/
  991. {
  992. DECLARE_LocalVdmContext;
  993. USHORT IoctlMinor;
  994. IoctlMinor = getAL();
  995. if (IoctlMinor >= MAX_SUPPORTED_DOS_IOCTL_CALL) {
  996. #if DBG
  997. OutputDebugString("DPMI: IOCTL DOS CALL NOT SUPPORTED\n");
  998. #endif
  999. NoTranslation();
  1000. return;
  1001. }
  1002. (*IOCTLXlatTable[IoctlMinor])();
  1003. }
  1004. VOID
  1005. GetCurDir(
  1006. VOID
  1007. )
  1008. /*++
  1009. Routine Description:
  1010. This routine translates the get current directory call
  1011. Arguments:
  1012. None.
  1013. Return Value:
  1014. None.
  1015. --*/
  1016. {
  1017. DECLARE_LocalVdmContext;
  1018. PUCHAR DirInfo, BufferedDirInfo;
  1019. USHORT ClientSI, Seg, Off;
  1020. USHORT ClientDS = getDS();
  1021. DpmiSwitchToRealMode();
  1022. ClientSI = getSI();
  1023. DirInfo = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  1024. + (*GetSIRegister)();
  1025. BufferedDirInfo = DpmiMapAndCopyBuffer(DirInfo, 64);
  1026. DPMI_FLAT_TO_SEGMENTED(BufferedDirInfo, &Seg, &Off);
  1027. setDS(Seg);
  1028. setSI(Off);
  1029. DPMI_EXEC_INT(0x21);
  1030. DpmiSwitchToProtectedMode();
  1031. DpmiUnmapAndCopyBuffer(DirInfo, BufferedDirInfo, 64);
  1032. setSI(ClientSI);
  1033. setDS(ClientDS);
  1034. }
  1035. VOID
  1036. AllocateMemoryBlock(
  1037. VOID
  1038. )
  1039. /*++
  1040. Routine Description:
  1041. This routine translates the AllocateMemory Int 21 api
  1042. Arguments:
  1043. None.
  1044. Return Value:
  1045. None.
  1046. --*/
  1047. {
  1048. DECLARE_LocalVdmContext;
  1049. PMEM_DPMI pMem;
  1050. ULONG MemSize = ((ULONG)getBX()) << 4;
  1051. pMem = DpmiAllocateXmem(MemSize);
  1052. if (pMem) {
  1053. pMem->SelCount = (USHORT) ((MemSize>>16) + 1);
  1054. pMem->Sel = ALLOCATE_SELECTORS(pMem->SelCount);
  1055. if (!pMem->Sel) {
  1056. pMem->SelCount = 0;
  1057. DpmiFreeXmem(pMem);
  1058. pMem = NULL;
  1059. } else {
  1060. SetDescriptorArray(pMem->Sel, (ULONG)pMem->Address, MemSize);
  1061. }
  1062. }
  1063. if (!pMem) {
  1064. setCF(1);
  1065. setAX(8);
  1066. setBX(0);
  1067. } else {
  1068. setCF(0);
  1069. setAX(pMem->Sel);
  1070. }
  1071. }
  1072. VOID
  1073. FreeMemoryBlock(
  1074. VOID
  1075. )
  1076. /*++
  1077. Routine Description:
  1078. This routine translates the ResizeMemory Int 21 api
  1079. Arguments:
  1080. None.
  1081. Return Value:
  1082. None.
  1083. --*/
  1084. {
  1085. DECLARE_LocalVdmContext;
  1086. PMEM_DPMI pMem;
  1087. USHORT Sel = getES();
  1088. if (pMem = DpmiFindXmem(Sel)) {
  1089. while(pMem->SelCount--) {
  1090. FreeSelector(Sel);
  1091. Sel+=8;
  1092. }
  1093. DpmiFreeXmem(pMem);
  1094. setCF(0);
  1095. } else {
  1096. setCF(1);
  1097. setAX(9);
  1098. }
  1099. }
  1100. VOID
  1101. ResizeMemoryBlock(
  1102. VOID
  1103. )
  1104. /*++
  1105. Routine Description:
  1106. This routine translates the ResizeMemory int 21 api
  1107. Arguments:
  1108. None.
  1109. Return Value:
  1110. None.
  1111. --*/
  1112. {
  1113. DECLARE_LocalVdmContext;
  1114. PMEM_DPMI pMem;
  1115. ULONG MemSize = ((ULONG)getBX()) << 4;
  1116. USHORT Sel = getES();
  1117. if (pMem = DpmiFindXmem(Sel)) {
  1118. if (DpmiReallocateXmem(pMem, MemSize)) {
  1119. SetDescriptorArray(pMem->Sel, (ULONG)pMem->Address, MemSize);
  1120. setCF(0);
  1121. } else {
  1122. // not enough memory
  1123. setCF(1);
  1124. setAX(8);
  1125. }
  1126. } else {
  1127. // invalid block
  1128. setCF(1);
  1129. setAX(9);
  1130. }
  1131. }
  1132. VOID
  1133. LoadExec(
  1134. VOID
  1135. )
  1136. /*++
  1137. Routine Description:
  1138. This function translates the int 21 load exec function. Load overlay
  1139. is not supported.
  1140. The child always inherits the environment, and the fcbs in the parameter
  1141. block are ignored. (win 3.1 does this)
  1142. Arguments:
  1143. None.
  1144. Return Value:
  1145. None.
  1146. --*/
  1147. {
  1148. DECLARE_LocalVdmContext;
  1149. PUCHAR CommandTail, BufferedString, Environment;
  1150. USHORT ClientDX, ClientBX, Seg, Off, Length, i, EnvironmentSel;
  1151. USHORT ClientDS = getDS();
  1152. USHORT ClientES = getES();
  1153. DpmiSwitchToRealMode();
  1154. ClientDX = getDX();
  1155. ClientBX = getBX();
  1156. if (getAL() == 3) {
  1157. setCF(1);
  1158. setAX(1);
  1159. } else {
  1160. //
  1161. // Map the command string
  1162. //
  1163. BufferedString = DpmiMapString(ClientDS, (*GetDXRegister)(), &Length);
  1164. if (BufferedString == NULL) {
  1165. setCF(1);
  1166. setAX(3);
  1167. } else {
  1168. //
  1169. // Make sure real DTA is updated later
  1170. //
  1171. CurrentDosDta = (PUCHAR) NULL;
  1172. //
  1173. // Set up the Parameter block
  1174. //
  1175. // We use the large xlat buffer. The parameter block comes
  1176. // first, and we fill in the command tail after
  1177. //
  1178. ZeroMemory(LargeXlatBuffer, 512);
  1179. //
  1180. // The environment segment address is now set
  1181. //
  1182. //
  1183. // Set the command tail address, and copy the command tail (all
  1184. // 128 bytes
  1185. //
  1186. DPMI_FLAT_TO_SEGMENTED((LargeXlatBuffer + 0x10), &Seg, &Off)
  1187. *(PWORD16)(LargeXlatBuffer + 2) = Off;
  1188. *(PWORD16)(LargeXlatBuffer + 4) = Seg;
  1189. //
  1190. // CommandTail = FLAT(es:bx)
  1191. //
  1192. CommandTail = Sim32GetVDMPointer(((ULONG)ClientES << 16), 1, TRUE)
  1193. + (*GetBXRegister)();
  1194. if (CurrentAppFlags & DPMI_32BIT) {
  1195. //
  1196. // CommandTail -> string
  1197. //
  1198. CommandTail = Sim32GetVDMPointer((*(PWORD16)(CommandTail + 4)) << 16, 1, TRUE)
  1199. + *(PDWORD16)(CommandTail);
  1200. } else {
  1201. //
  1202. // CommandTail -> string
  1203. //
  1204. CommandTail = Sim32GetVDMPointer(*(PDWORD16)(CommandTail + 2), 1, TRUE);
  1205. }
  1206. CopyMemory((LargeXlatBuffer + 0x10), CommandTail, 128);
  1207. //
  1208. // Set FCB pointers and put spaces in the file names
  1209. //
  1210. DPMI_FLAT_TO_SEGMENTED((LargeXlatBuffer + 144), &Seg, &Off)
  1211. *(PWORD16)(LargeXlatBuffer + 6) = Off;
  1212. *(PWORD16)(LargeXlatBuffer + 8) = Seg;
  1213. for (i = 0; i < 11; i++) {
  1214. (LargeXlatBuffer + 144 + 1)[i] = ' ';
  1215. }
  1216. DPMI_FLAT_TO_SEGMENTED((LargeXlatBuffer + 188), &Seg, &Off)
  1217. *(PWORD16)(LargeXlatBuffer + 0xA) = Off;
  1218. *(PWORD16)(LargeXlatBuffer + 0xC) = Seg;
  1219. for (i = 0; i < 11; i++) {
  1220. (LargeXlatBuffer + 188 + 1)[i] = ' ';
  1221. }
  1222. //
  1223. // Save the environment selector, and make it a segment
  1224. //
  1225. Environment = Sim32GetVDMPointer(((ULONG)CurrentPSPSelector << 16) | 0x2C, 1, TRUE);
  1226. EnvironmentSel = *(PWORD16)Environment;
  1227. *(PWORD16)Environment =
  1228. (USHORT)(SELECTOR_TO_INTEL_LINEAR_ADDRESS(EnvironmentSel) >> 4);
  1229. //
  1230. // Set up registers for the exec
  1231. //
  1232. DPMI_FLAT_TO_SEGMENTED(BufferedString, &Seg, &Off);
  1233. setDS(Seg);
  1234. setDX(Off);
  1235. DPMI_FLAT_TO_SEGMENTED(LargeXlatBuffer, &Seg, &Off);
  1236. setES(Seg);
  1237. setBX(Off);
  1238. DPMI_EXEC_INT(0x21);
  1239. //
  1240. // Restore the environment selector
  1241. //
  1242. Environment = Sim32GetVDMPointer(((ULONG)CurrentPSPSelector << 16) | 0x2C, 1, TRUE);
  1243. *(PWORD16)Environment = EnvironmentSel;
  1244. //
  1245. // Free translation buffer
  1246. //
  1247. DpmiUnmapString(BufferedString, Length);
  1248. }
  1249. }
  1250. setDX(ClientDX);
  1251. setBX(ClientBX);
  1252. DpmiSwitchToProtectedMode();
  1253. setES(ClientES);
  1254. setDS(ClientDS);
  1255. }
  1256. VOID
  1257. Terminate(
  1258. VOID
  1259. )
  1260. /*++
  1261. Routine Description:
  1262. description-of-function.
  1263. Arguments:
  1264. argument-name - Supplies | Returns description of argument.
  1265. .
  1266. .
  1267. Return Value:
  1268. return-value - Description of conditions needed to return value. - or -
  1269. None.
  1270. --*/
  1271. {
  1272. // bugbug We're currently mapping this one in the dos extender
  1273. }
  1274. VOID
  1275. FindFirstFileHandle(
  1276. VOID
  1277. )
  1278. /*++
  1279. Routine Description:
  1280. This routine translates the find first api.
  1281. Arguments:
  1282. None.
  1283. Return Value:
  1284. None.
  1285. --*/
  1286. {
  1287. DECLARE_LocalVdmContext;
  1288. USHORT ClientDX, Seg, Off, StringLength;
  1289. PUCHAR BufferedString;
  1290. USHORT ClientDS = getDS();
  1291. //
  1292. // map the string
  1293. //
  1294. BufferedString = DpmiMapString(ClientDS, (GetDXRegister)(), &StringLength);
  1295. if (BufferedString == NULL) {
  1296. setCF(1);
  1297. setAX(3);
  1298. } else {
  1299. DpmiSwitchToRealMode();
  1300. SetDTAPointers();
  1301. ClientDX = getDX();
  1302. //
  1303. // Copy the DTA (if necessary)
  1304. //
  1305. if (CurrentDta != CurrentPmDtaAddress) {
  1306. CopyMemory(CurrentDta, CurrentPmDtaAddress, 43);
  1307. }
  1308. //
  1309. // Check to see if we need to set the real dta
  1310. //
  1311. if (CurrentDosDta != CurrentDta)
  1312. SetDosDTA();
  1313. DPMI_FLAT_TO_SEGMENTED(BufferedString, &Seg, &Off);
  1314. setDS(Seg);
  1315. setDX(Off);
  1316. DPMI_EXEC_INT(0x21);
  1317. DpmiSwitchToProtectedMode();
  1318. setDS(ClientDS);
  1319. DpmiUnmapString(BufferedString, StringLength);
  1320. //
  1321. // Copy the DTA back (if necessary)
  1322. //
  1323. if (CurrentDta != CurrentPmDtaAddress) {
  1324. CopyMemory(CurrentPmDtaAddress, CurrentDta, 43);
  1325. }
  1326. setDX(ClientDX);
  1327. }
  1328. }
  1329. VOID
  1330. FindNextFileHandle(
  1331. VOID
  1332. )
  1333. /*++
  1334. Routine Description:
  1335. This routine translates the find next api
  1336. Arguments:
  1337. None.
  1338. Return Value:
  1339. None.
  1340. --*/
  1341. {
  1342. DECLARE_LocalVdmContext;
  1343. DpmiSwitchToRealMode();
  1344. SetDTAPointers();
  1345. //
  1346. // Copy the DTA (if necessary)
  1347. //
  1348. if (CurrentDta != CurrentPmDtaAddress) {
  1349. CopyMemory(CurrentDta, CurrentPmDtaAddress, 43);
  1350. }
  1351. //
  1352. // Check to see if we need to set the real dta
  1353. //
  1354. if (CurrentDosDta != CurrentDta)
  1355. SetDosDTA();
  1356. DPMI_EXEC_INT(0x21);
  1357. DpmiSwitchToProtectedMode();
  1358. //
  1359. // Copy the DTA back (if necessary)
  1360. //
  1361. if (CurrentDta != CurrentPmDtaAddress) {
  1362. CopyMemory(CurrentPmDtaAddress, CurrentDta, 43);
  1363. }
  1364. }
  1365. VOID
  1366. SetPSP(
  1367. VOID
  1368. )
  1369. /*++
  1370. Routine Description:
  1371. This routine translates the set psp api. This is substantially the
  1372. same as CreatePSP, except that this can fail (and return carry). It
  1373. also remembers the PSP selector, so we can return it on request.
  1374. Arguments:
  1375. None.
  1376. Return Value:
  1377. None.
  1378. --*/
  1379. {
  1380. DECLARE_LocalVdmContext;
  1381. ULONG Segment;
  1382. USHORT ClientBX;
  1383. DpmiSwitchToRealMode();
  1384. ClientBX = getBX();
  1385. if (ClientBX == 0) {
  1386. CurrentPSPSelector = ClientBX;
  1387. } else {
  1388. Segment = SELECTOR_TO_INTEL_LINEAR_ADDRESS(ClientBX);
  1389. if (Segment > ONE_MB) {
  1390. setCF(1);
  1391. } else {
  1392. setBX((USHORT) (Segment >> 4));
  1393. DPMI_EXEC_INT(0x21);
  1394. CurrentPSPSelector = ClientBX;
  1395. }
  1396. }
  1397. setBX(ClientBX);
  1398. DpmiSwitchToProtectedMode();
  1399. }
  1400. VOID
  1401. GetPSP(
  1402. VOID
  1403. )
  1404. /*++
  1405. Routine Description:
  1406. This routine returns the current PSP selector
  1407. Arguments:
  1408. None.
  1409. Return Value:
  1410. None.
  1411. --*/
  1412. {
  1413. DECLARE_LocalVdmContext;
  1414. DpmiSwitchToRealMode();
  1415. //
  1416. // Get the current psp segment to see if it changed
  1417. //
  1418. DPMI_EXEC_INT(0x21);
  1419. DpmiSwitchToProtectedMode();
  1420. //
  1421. // If it changed get a new selector for the psp
  1422. //
  1423. if (getBX() !=
  1424. (USHORT)(SELECTOR_TO_INTEL_LINEAR_ADDRESS(CurrentPSPSelector) >> 4)
  1425. ){
  1426. CurrentPSPSelector = SegmentToSelector(getBX(), STD_DATA);
  1427. }
  1428. setBX(CurrentPSPSelector);
  1429. setCF(0);
  1430. }
  1431. VOID
  1432. TranslateBPB(
  1433. VOID
  1434. )
  1435. /*++
  1436. Routine Description:
  1437. This function fails and returns. On NT we do not support this dos
  1438. call.
  1439. Arguments:
  1440. None.
  1441. Return Value:
  1442. None.
  1443. --*/
  1444. {
  1445. DECLARE_LocalVdmContext;
  1446. #if DBG
  1447. OutputDebugString("DPMI: Int 21 function 53 is not supported\n");
  1448. #endif
  1449. setCF(1);
  1450. }
  1451. VOID
  1452. RenameFile(
  1453. VOID
  1454. )
  1455. /*++
  1456. Routine Description:
  1457. This routine translates the rename int 21 api
  1458. Arguments:
  1459. None.
  1460. Return Value:
  1461. None.
  1462. --*/
  1463. {
  1464. DECLARE_LocalVdmContext;
  1465. PUCHAR SourceString, DestinationString;
  1466. USHORT ClientDX, ClientDI, Seg, Off, SourceLength, DestinationLength;
  1467. USHORT ClientDS = getDS();
  1468. USHORT ClientES = getES();
  1469. SourceString = DpmiMapString(ClientDS, (*GetDXRegister)(), &SourceLength);
  1470. if (SourceString == NULL) {
  1471. setCF(1);
  1472. setAX(3);
  1473. } else {
  1474. DestinationString = DpmiMapString(ClientES, (*GetDIRegister)(), &DestinationLength);
  1475. if (DestinationString == NULL) {
  1476. setCF(1);
  1477. setAX(3);
  1478. DpmiUnmapString(SourceString, SourceLength);
  1479. } else {
  1480. DpmiSwitchToRealMode();
  1481. ClientDX = getDX();
  1482. ClientDI = getDI();
  1483. DPMI_FLAT_TO_SEGMENTED(SourceString, &Seg, &Off);
  1484. setDX(Off);
  1485. setDS(Seg);
  1486. DPMI_FLAT_TO_SEGMENTED(DestinationString, &Seg, &Off);
  1487. setDI(Off);
  1488. setES(Seg);
  1489. DPMI_EXEC_INT(0x21);
  1490. setDX(ClientDX);
  1491. setDI(ClientDI);
  1492. DpmiSwitchToProtectedMode();
  1493. setDS(ClientDS);
  1494. setES(ClientES);
  1495. DpmiUnmapString(SourceString, SourceLength);
  1496. DpmiUnmapString(DestinationString, DestinationLength);
  1497. }
  1498. }
  1499. }
  1500. VOID
  1501. CreateTempFile(
  1502. VOID
  1503. )
  1504. /*++
  1505. Routine Description:
  1506. This function maps the int 21 create temp file api
  1507. Arguments:
  1508. None.
  1509. Return Value:
  1510. None.
  1511. --*/
  1512. {
  1513. DECLARE_LocalVdmContext;
  1514. PUCHAR String, BufferedString;
  1515. USHORT ClientDX, Seg, Off, Length;
  1516. USHORT ClientDS = getDS();
  1517. DpmiSwitchToRealMode();
  1518. ClientDX = getDX();
  1519. String = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  1520. + (*GetDXRegister)();
  1521. Length = 0;
  1522. while (String[Length] != '\0') {
  1523. Length++;
  1524. }
  1525. Length += 13;
  1526. BufferedString = DpmiMapAndCopyBuffer(String, Length);
  1527. DPMI_FLAT_TO_SEGMENTED(BufferedString, &Seg, &Off);
  1528. setDS(Seg);
  1529. setDX(Off);
  1530. DPMI_EXEC_INT(0x21);
  1531. DpmiSwitchToProtectedMode();
  1532. DpmiUnmapAndCopyBuffer(String, BufferedString, Length);
  1533. setDX(ClientDX);
  1534. setDS(ClientDS);
  1535. }
  1536. #define MAX_SUPPORTED_DOS_5D_CALL 12
  1537. APIXLATFUNCTION Func5DXlatTable[MAX_SUPPORTED_DOS_5D_CALL] = {
  1538. NotSupportedBad , // 0
  1539. MapDPL , // 1
  1540. NotSupportedBad , // 2
  1541. MapDPL , // 3
  1542. MapDPL , // 4
  1543. NotSupportedBad , // 5
  1544. NotSupportedBad , // 6
  1545. NoTranslation , // 7
  1546. NoTranslation , // 8
  1547. NoTranslation , // 9
  1548. MapDPL , // 10
  1549. NotSupportedBad // 11
  1550. };
  1551. VOID
  1552. Func5Dh(
  1553. VOID
  1554. )
  1555. /*++
  1556. Routine Description:
  1557. This function translates dos call 5d
  1558. Arguments:
  1559. None.
  1560. Return Value:
  1561. None.
  1562. --*/
  1563. {
  1564. DECLARE_LocalVdmContext;
  1565. USHORT Func5DhMinor;
  1566. Func5DhMinor = getAL();
  1567. if (Func5DhMinor >= MAX_SUPPORTED_DOS_5D_CALL) {
  1568. #if DBG
  1569. OutputDebugString("DPMI: DOS FUNCTION 5D UNSUPPORTED\n");
  1570. #endif
  1571. NoTranslation();
  1572. return;
  1573. }
  1574. (*Func5DXlatTable[Func5DhMinor])();
  1575. }
  1576. #define MAX_SUPPORTED_DOS_5E_CALL 4
  1577. APIXLATFUNCTION Func5EXlatTable[MAX_SUPPORTED_DOS_5E_CALL] = {
  1578. GetMachineName,
  1579. MapASCIIZDSDX,
  1580. GetPrinterSetup,
  1581. SetPrinterSetup
  1582. };
  1583. VOID
  1584. Func5Eh(
  1585. VOID
  1586. )
  1587. /*++
  1588. Routine Description:
  1589. description-of-function.
  1590. Arguments:
  1591. argument-name - Supplies | Returns description of argument.
  1592. .
  1593. .
  1594. Return Value:
  1595. return-value - Description of conditions needed to return value. - or -
  1596. None.
  1597. --*/
  1598. {
  1599. DECLARE_LocalVdmContext;
  1600. USHORT Func5EhMinor;
  1601. Func5EhMinor = getAL();
  1602. if (Func5EhMinor >= MAX_SUPPORTED_DOS_5E_CALL) {
  1603. #if DBG
  1604. OutputDebugString("DPMI: DOS FUNCTION 5E UNSUPPORTED\n");
  1605. #endif
  1606. NoTranslation();
  1607. return;
  1608. }
  1609. (*Func5EXlatTable[Func5EhMinor])();
  1610. }
  1611. VOID
  1612. Func5Fh(
  1613. VOID
  1614. )
  1615. /*++
  1616. Routine Description:
  1617. description-of-function.
  1618. Arguments:
  1619. argument-name - Supplies | Returns description of argument.
  1620. .
  1621. .
  1622. Return Value:
  1623. return-value - Description of conditions needed to return value. - or -
  1624. None.
  1625. --*/
  1626. {
  1627. DECLARE_LocalVdmContext;
  1628. USHORT Func5FMinor;
  1629. Func5FMinor = getAL();
  1630. if (Func5FMinor == 4) {
  1631. MapASCIIZDSSI();
  1632. return;
  1633. } else if ((Func5FMinor == 2) || (Func5FMinor == 3) ||
  1634. (Func5FMinor == 5)
  1635. ){
  1636. USHORT ClientSI, ClientDI, DataOff, DataSeg;
  1637. PUCHAR Data16, BufferedData16, Data128, BufferedData128;
  1638. USHORT ClientDS = getDS();
  1639. USHORT ClientES = getES();
  1640. DpmiSwitchToRealMode();
  1641. ClientDI = getDI();
  1642. ClientSI = getSI();
  1643. Data16 = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  1644. + (*GetSIRegister)();
  1645. BufferedData16 = DpmiMapAndCopyBuffer(Data16, 16);
  1646. Data128 = Sim32GetVDMPointer(((ULONG)ClientES << 16), 1, TRUE)
  1647. + (*GetDIRegister)();
  1648. BufferedData128 = DpmiMapAndCopyBuffer(Data128, 128);
  1649. DPMI_FLAT_TO_SEGMENTED(BufferedData16, &DataSeg, &DataOff);
  1650. setDS(DataSeg);
  1651. setSI(DataOff);
  1652. DPMI_FLAT_TO_SEGMENTED(BufferedData128, &DataSeg, &DataOff);
  1653. setES(DataSeg);
  1654. setDI(DataOff);
  1655. DPMI_EXEC_INT(0x21);
  1656. DpmiSwitchToProtectedMode();
  1657. DpmiUnmapAndCopyBuffer(Data16, BufferedData16, 16);
  1658. DpmiUnmapAndCopyBuffer(Data128, BufferedData128, 128);
  1659. setDS(ClientDS);
  1660. setES(ClientES);
  1661. setSI(ClientSI);
  1662. setDI(ClientDI);
  1663. } else {
  1664. #if DBG
  1665. OutputDebugString("DPMI: UNSUPPORTED INT 21 FUNCTION 5F\n");
  1666. #endif
  1667. NoTranslation();
  1668. }
  1669. }
  1670. VOID
  1671. NotSupportedBad(
  1672. VOID
  1673. )
  1674. /*++
  1675. Routine Description:
  1676. description-of-function.
  1677. Arguments:
  1678. argument-name - Supplies | Returns description of argument.
  1679. .
  1680. .
  1681. Return Value:
  1682. return-value - Description of conditions needed to return value. - or -
  1683. None.
  1684. --*/
  1685. {
  1686. #if DBG
  1687. DECLARE_LocalVdmContext;
  1688. DbgPrint("WARNING: DOS INT 21 call AX= %x will not be translated.\n", getAH());
  1689. DbgPrint(" Use of this call is not supported from Prot\n");
  1690. DbgPrint(" mode applications.\n");
  1691. #endif
  1692. NoTranslation();
  1693. }
  1694. VOID
  1695. ReturnDSSI(
  1696. VOID
  1697. )
  1698. /*++
  1699. Routine Description:
  1700. This function translates api that return information in ds:si
  1701. Arguments:
  1702. None.
  1703. Return Value:
  1704. None.
  1705. --*/
  1706. {
  1707. DECLARE_LocalVdmContext;
  1708. USHORT Selector;
  1709. DpmiSwitchToRealMode();
  1710. DPMI_EXEC_INT(0x21);
  1711. Selector = getDS();
  1712. DpmiSwitchToProtectedMode();
  1713. (*SetSIRegister)((ULONG)getSI());
  1714. setDS(SegmentToSelector(Selector, STD_DATA));
  1715. }
  1716. VOID
  1717. NotSupportedBetter(
  1718. VOID
  1719. )
  1720. /*++
  1721. Routine Description:
  1722. description-of-function.
  1723. Arguments:
  1724. argument-name - Supplies | Returns description of argument.
  1725. .
  1726. .
  1727. Return Value:
  1728. return-value - Description of conditions needed to return value. - or -
  1729. None.
  1730. --*/
  1731. {
  1732. #if DBG
  1733. DECLARE_LocalVdmContext;
  1734. DbgPrint("WARNING: DOS INT 21 call AX= %x will not be translated.", getAH());
  1735. DbgPrint(" Use of this call by a Prot Mode app is not");
  1736. DbgPrint(" appropriate. There is a better INT 21 call, or a");
  1737. DbgPrint(" Windows call which should be used instead of this.");
  1738. #endif
  1739. NoTranslation();
  1740. }
  1741. VOID
  1742. GetExtendedCountryInfo(
  1743. VOID
  1744. )
  1745. /*++
  1746. Routine Description:
  1747. This routine translates the get extended country info int 21 api
  1748. Arguments:
  1749. None.
  1750. Return Value:
  1751. None.
  1752. --*/
  1753. {
  1754. DECLARE_LocalVdmContext;
  1755. PUCHAR Country, BufferedCountry;
  1756. USHORT ClientDI, Seg, Off, Length;
  1757. USHORT ClientES = getES();
  1758. DpmiSwitchToRealMode();
  1759. ClientDI = getDI();
  1760. Length = getCX();
  1761. Country = Sim32GetVDMPointer(((ULONG)ClientES << 16), 1, TRUE)
  1762. + (*GetDIRegister)();
  1763. BufferedCountry = DpmiMapAndCopyBuffer(Country, Length);
  1764. DPMI_FLAT_TO_SEGMENTED(BufferedCountry, &Seg, &Off);
  1765. setES(Seg);
  1766. setDI(Off);
  1767. DPMI_EXEC_INT(0x21);
  1768. DpmiSwitchToProtectedMode();
  1769. setES(ClientES);
  1770. DpmiUnmapAndCopyBuffer(Country, BufferedCountry, Length);
  1771. setDI(ClientDI);
  1772. }
  1773. VOID
  1774. MapASCIIZDSSI(
  1775. VOID
  1776. )
  1777. /*++
  1778. Routine Description:
  1779. This function translates the int 21 extended open call
  1780. Arguments:
  1781. None.
  1782. Return Value:
  1783. None.
  1784. --*/
  1785. {
  1786. DECLARE_LocalVdmContext;
  1787. PUCHAR BufferedString;
  1788. USHORT ClientSI, StringSeg, StringOff, Length;
  1789. USHORT ClientDS = getDS();
  1790. BufferedString = DpmiMapString(ClientDS, (*GetSIRegister)(), &Length);
  1791. if (BufferedString == NULL) {
  1792. setCF(1);
  1793. setAX(3);
  1794. } else {
  1795. DpmiSwitchToRealMode();
  1796. ClientSI = getSI();
  1797. DPMI_FLAT_TO_SEGMENTED(BufferedString, &StringSeg, &StringOff);
  1798. setDS(StringSeg);
  1799. setSI(StringOff);
  1800. DPMI_EXEC_INT(0x21);
  1801. DpmiSwitchToProtectedMode();
  1802. DpmiUnmapString(BufferedString, Length);
  1803. setSI(ClientSI);
  1804. setDS(ClientDS);
  1805. }
  1806. }
  1807. VOID
  1808. MapDSDXLenCX(
  1809. VOID
  1810. )
  1811. /*++
  1812. Routine Description:
  1813. This function maps the ioctl calls that pass data in DS:DX, with
  1814. length in cx
  1815. Arguments:
  1816. None.
  1817. Return Value:
  1818. None.
  1819. --*/
  1820. {
  1821. DECLARE_LocalVdmContext;
  1822. USHORT ClientDX, ClientCX, DataSeg, DataOff;
  1823. PUCHAR Data, BufferedData;
  1824. USHORT ClientDS = getDS();
  1825. DpmiSwitchToRealMode();
  1826. ClientDX = getDX();
  1827. ClientCX = getCX();
  1828. Data = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  1829. + (*GetDXRegister)();
  1830. BufferedData = DpmiMapAndCopyBuffer(Data, ClientCX);
  1831. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  1832. setDS(DataSeg);
  1833. setDX(DataOff);
  1834. DPMI_EXEC_INT(0x21);
  1835. DpmiSwitchToProtectedMode();
  1836. DpmiUnmapAndCopyBuffer(Data, BufferedData, ClientCX);
  1837. setDS(ClientDS);
  1838. setDX(ClientDX);
  1839. }
  1840. VOID
  1841. IOCTLMap2Bytes(
  1842. VOID
  1843. )
  1844. /*++
  1845. Routine Description:
  1846. description-of-function.
  1847. Arguments:
  1848. argument-name - Supplies | Returns description of argument.
  1849. .
  1850. .
  1851. Return Value:
  1852. return-value - Description of conditions needed to return value. - or -
  1853. None.
  1854. --*/
  1855. {
  1856. DECLARE_LocalVdmContext;
  1857. USHORT ClientDX, DataSeg, DataOff;
  1858. PUCHAR Data, BufferedData;
  1859. USHORT ClientDS = getDS();
  1860. DpmiSwitchToRealMode();
  1861. ClientDX = getDX();
  1862. Data = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  1863. + (*GetDXRegister)();
  1864. BufferedData = DpmiMapAndCopyBuffer(Data, 2);
  1865. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  1866. setDS(DataSeg);
  1867. setDX(DataOff);
  1868. DPMI_EXEC_INT(0x21);
  1869. DpmiSwitchToProtectedMode();
  1870. DpmiUnmapAndCopyBuffer(Data, BufferedData, 2);
  1871. setDS(ClientDS);
  1872. setDX(ClientDX);
  1873. }
  1874. VOID
  1875. IOCTLBlockDevs(
  1876. VOID
  1877. )
  1878. /*++
  1879. Routine Description:
  1880. This function fails the block device ioctls
  1881. Arguments:
  1882. None.
  1883. Return Value:
  1884. None.
  1885. --*/
  1886. {
  1887. DECLARE_LocalVdmContext;
  1888. USHORT IoctlSubFunction, Seg, Off, ClientDX;
  1889. PUCHAR Data, BufferedData;
  1890. USHORT Length;
  1891. USHORT ClientDS = getDS();
  1892. IoctlSubFunction = getCL();
  1893. if ((IoctlSubFunction < 0x40) || (IoctlSubFunction > 0x42) &&
  1894. (IoctlSubFunction < 0x60) || (IoctlSubFunction > 0x62) &&
  1895. (IoctlSubFunction != 0x68)
  1896. ) {
  1897. #if DBG
  1898. OutputDebugString("DPMI: IOCTL DOS CALL NOT SUPPORTED\n");
  1899. #endif
  1900. NoTranslation();
  1901. return;
  1902. }
  1903. //
  1904. // Read and write track are special (and a pain)
  1905. //
  1906. if ((IoctlSubFunction == 0x41) || (IoctlSubFunction == 0x61)) {
  1907. IoctlReadWriteTrack();
  1908. return;
  1909. }
  1910. DpmiSwitchToRealMode();
  1911. ClientDX = getDX();
  1912. Data = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  1913. + (*GetDXRegister)();
  1914. switch (IoctlSubFunction) {
  1915. case 0x40:
  1916. //
  1917. // Map set device params
  1918. //
  1919. Length = (*(PWORD16)(Data + 0x26));
  1920. Length <<= 2;
  1921. Length += 0x28;
  1922. break;
  1923. case 0x60:
  1924. //
  1925. // Map get device params
  1926. //
  1927. Length = 38;
  1928. break;
  1929. case 0x62:
  1930. //
  1931. // Map format verify
  1932. //
  1933. Length = 5;
  1934. break;
  1935. case 0x68:
  1936. //
  1937. // Map Media sense
  1938. //
  1939. Length = 4;
  1940. break;
  1941. }
  1942. BufferedData = DpmiMapAndCopyBuffer(Data, Length);
  1943. DPMI_FLAT_TO_SEGMENTED(BufferedData, &Seg, &Off);
  1944. setDS(Seg);
  1945. setDX(Off);
  1946. DPMI_EXEC_INT(0x21);
  1947. DpmiSwitchToProtectedMode();
  1948. DpmiUnmapAndCopyBuffer(Data, BufferedData, Length);
  1949. setDS(ClientDS);
  1950. setDX(ClientDX);
  1951. }
  1952. VOID
  1953. IoctlReadWriteTrack(
  1954. VOID
  1955. )
  1956. /*++
  1957. Routine Description:
  1958. This routine maps the read/write track ioctl.
  1959. Arguments:
  1960. None.
  1961. Return Value:
  1962. None.
  1963. --*/
  1964. {
  1965. DECLARE_LocalVdmContext;
  1966. USHORT ClientDX, ClientDS, ClientCX, ClientAX;
  1967. USHORT Seg, Off, NumberOfSectors, BytesPerSector;
  1968. USHORT SectorsRead, SectorsToRead;
  1969. PUCHAR ParameterBlock, BufferedPBlock, Data, BufferedData;
  1970. ClientAX = getAX();
  1971. ClientDX = getDX();
  1972. ClientCX = getCX();
  1973. ClientDS = getDS();
  1974. DpmiSwitchToRealMode();
  1975. //
  1976. // Find out how many bytes/sector
  1977. //
  1978. BufferedData = DpmiAllocateBuffer(0x40);
  1979. DPMI_FLAT_TO_SEGMENTED(BufferedData, &Seg, &Off);
  1980. setDS(Seg);
  1981. setDX(Off);
  1982. setAX(0x440D);
  1983. setCX(0x860);
  1984. DPMI_EXEC_INT(0x21);
  1985. if (getCF()) {
  1986. //
  1987. // Failed, we don't know how much data to buffer,
  1988. // so fail read/write track
  1989. //
  1990. DpmiFreeBuffer(BufferedData, 0x40);
  1991. setDX(ClientDX);
  1992. setCX(ClientCX);
  1993. DpmiSwitchToProtectedMode();
  1994. setDS(ClientDS);
  1995. return;
  1996. }
  1997. //
  1998. // Get the number of bytes/sector
  1999. //
  2000. BytesPerSector = *(PWORD16)(BufferedData + 0x7);
  2001. DpmiFreeBuffer(BufferedData, 0x40);
  2002. setDX(ClientDX);
  2003. //
  2004. // First map the parameter block
  2005. //
  2006. ParameterBlock = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  2007. + (*GetDXRegister)();
  2008. BufferedPBlock = DpmiMapAndCopyBuffer(ParameterBlock, 13);
  2009. //
  2010. // Get the segment and offset of the parameter block
  2011. //
  2012. DPMI_FLAT_TO_SEGMENTED(BufferedPBlock, &Seg, &Off);
  2013. setDS(Seg);
  2014. setDX(Off);
  2015. if (CurrentAppFlags & DPMI_32BIT) {
  2016. Data = Sim32GetVDMPointer(
  2017. (*((PWORD16)(BufferedPBlock + 0xd)) << 16),
  2018. 1,
  2019. TRUE
  2020. );
  2021. Data += *((PDWORD16)(BufferedPBlock + 0x9));
  2022. } else {
  2023. Data = Sim32GetVDMPointer(
  2024. (*((PWORD16)(BufferedPBlock + 0xb)) << 16),
  2025. 1,
  2026. TRUE
  2027. );
  2028. Data += *((PWORD16)(BufferedPBlock + 0x9));
  2029. }
  2030. NumberOfSectors = *((PWORD16)(BufferedPBlock + 7));
  2031. SectorsRead = 0;
  2032. while (NumberOfSectors != SectorsRead) {
  2033. if ((NumberOfSectors - SectorsRead) * BytesPerSector > 1024 * 4) {
  2034. SectorsToRead = 4 * 1024 / BytesPerSector;
  2035. } else {
  2036. SectorsToRead = (USHORT)(NumberOfSectors - SectorsRead);
  2037. }
  2038. BufferedData = DpmiMapAndCopyBuffer(
  2039. Data,
  2040. (USHORT) (SectorsToRead * BytesPerSector)
  2041. );
  2042. DPMI_FLAT_TO_SEGMENTED(BufferedData, &Seg, &Off);
  2043. *((PWORD16)(BufferedPBlock + 9)) = Off;
  2044. *((PWORD16)(BufferedPBlock + 11)) = Seg;
  2045. *((PWORD16)(BufferedPBlock + 7)) = SectorsToRead;
  2046. setAX(ClientAX);
  2047. setCX(ClientCX);
  2048. DPMI_EXEC_INT(0x21);
  2049. if (getCF()) {
  2050. DpmiUnmapBuffer(
  2051. BufferedData,
  2052. (USHORT) (SectorsToRead * BytesPerSector)
  2053. );
  2054. break;
  2055. }
  2056. DpmiUnmapAndCopyBuffer(
  2057. Data,
  2058. BufferedData,
  2059. (USHORT) (SectorsToRead * BytesPerSector)
  2060. );
  2061. Data += SectorsToRead * BytesPerSector;
  2062. *((PWORD16)(BufferedPBlock + 5)) += SectorsToRead;
  2063. SectorsRead += SectorsToRead;
  2064. }
  2065. DpmiUnmapBuffer(BufferedPBlock,13);
  2066. setDX(ClientDX);
  2067. DpmiSwitchToProtectedMode();
  2068. setDS(ClientDS);
  2069. }
  2070. VOID
  2071. MapDPL(
  2072. VOID
  2073. )
  2074. /*++
  2075. Routine Description:
  2076. This routine maps a DPL for the server call
  2077. Arguments:
  2078. None.
  2079. Return Value:
  2080. None.
  2081. --*/
  2082. {
  2083. DECLARE_LocalVdmContext;
  2084. USHORT ClientDX, DataSeg, DataOff;
  2085. PUCHAR Data, BufferedData;
  2086. USHORT ClientDS = getDS();
  2087. DpmiSwitchToRealMode();
  2088. ClientDX = getDX();
  2089. Data = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  2090. + (*GetDXRegister)();
  2091. BufferedData = DpmiMapAndCopyBuffer(Data, 22);
  2092. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  2093. setDS(DataSeg);
  2094. setDX(DataOff);
  2095. DPMI_EXEC_INT(0x21);
  2096. DpmiSwitchToProtectedMode();
  2097. DpmiUnmapAndCopyBuffer(Data, BufferedData, 22);
  2098. setDX(ClientDX);
  2099. setDS(ClientDS);
  2100. }
  2101. VOID
  2102. GetMachineName(
  2103. VOID
  2104. )
  2105. /*++
  2106. Routine Description:
  2107. This routine maps a machine name for int 21 function 5e
  2108. Arguments:
  2109. None.
  2110. Return Value:
  2111. None.
  2112. --*/
  2113. {
  2114. DECLARE_LocalVdmContext;
  2115. USHORT ClientDX, DataSeg, DataOff;
  2116. PUCHAR Data, BufferedData;
  2117. USHORT ClientDS = getDS();
  2118. DpmiSwitchToRealMode();
  2119. ClientDX = getDX();
  2120. Data = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  2121. + (*GetDXRegister)();
  2122. BufferedData = DpmiMapAndCopyBuffer(Data, 16);
  2123. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  2124. setDS(DataSeg);
  2125. setDX(DataOff);
  2126. DPMI_EXEC_INT(0x21);
  2127. DpmiSwitchToProtectedMode();
  2128. DpmiUnmapAndCopyBuffer(Data, BufferedData, 16);
  2129. setDX(ClientDX);
  2130. setDS(ClientDS);
  2131. }
  2132. VOID
  2133. GetPrinterSetup(
  2134. VOID
  2135. )
  2136. /*++
  2137. Routine Description:
  2138. This routine maps printer setup data for int 21 function 5e
  2139. Arguments:
  2140. None.
  2141. Return Value:
  2142. None.
  2143. --*/
  2144. {
  2145. DECLARE_LocalVdmContext;
  2146. USHORT ClientSI, ClientCX, DataSeg, DataOff;
  2147. PUCHAR Data, BufferedData;
  2148. USHORT ClientDS = getDS();
  2149. DpmiSwitchToRealMode();
  2150. ClientSI = getSI();
  2151. ClientCX = getCX();
  2152. Data = Sim32GetVDMPointer(((ULONG)ClientDS << 16), 1, TRUE)
  2153. + (*GetSIRegister)();
  2154. BufferedData = DpmiMapAndCopyBuffer(Data, ClientCX);
  2155. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  2156. setDS(DataSeg);
  2157. setSI(DataOff);
  2158. DPMI_EXEC_INT(0x21);
  2159. DpmiSwitchToProtectedMode();
  2160. DpmiUnmapAndCopyBuffer(Data, BufferedData, ClientCX);
  2161. setSI(ClientSI);
  2162. setDS(ClientDS);
  2163. }
  2164. VOID
  2165. SetPrinterSetup(
  2166. VOID
  2167. )
  2168. /*++
  2169. Routine Description:
  2170. This routine maps printer setup data for int 21 function 5e
  2171. Arguments:
  2172. None.
  2173. Return Value:
  2174. None.
  2175. --*/
  2176. {
  2177. DECLARE_LocalVdmContext;
  2178. USHORT ClientDI, DataSeg, DataOff;
  2179. PUCHAR Data, BufferedData;
  2180. USHORT ClientES = getES();
  2181. DpmiSwitchToRealMode();
  2182. ClientDI = getDI();
  2183. Data = Sim32GetVDMPointer(((ULONG)ClientES << 16), 1, TRUE)
  2184. + (*GetDIRegister)();
  2185. BufferedData = DpmiMapAndCopyBuffer(Data, 64);
  2186. DPMI_FLAT_TO_SEGMENTED(BufferedData, &DataSeg, &DataOff);
  2187. setES(DataSeg);
  2188. setDI(DataOff);
  2189. DPMI_EXEC_INT(0x21);
  2190. DpmiSwitchToProtectedMode();
  2191. setES(ClientES);
  2192. DpmiUnmapAndCopyBuffer(Data, BufferedData, 64);
  2193. setDI(ClientDI);
  2194. }
  2195. VOID
  2196. GetDate(
  2197. VOID
  2198. )
  2199. /*++
  2200. Routine Description:
  2201. This routine maps int21 func 2A GetDate
  2202. Arguments:
  2203. None.
  2204. Return Value:
  2205. Client (DH) - month
  2206. Client (DL) - Day
  2207. Client (CX) - Year
  2208. Client (AL) - WeekDay
  2209. --*/
  2210. {
  2211. DECLARE_LocalVdmContext;
  2212. SYSTEMTIME TimeDate;
  2213. GetLocalTime(&TimeDate);
  2214. setDH((UCHAR)TimeDate.wMonth);
  2215. setDL((UCHAR)TimeDate.wDay);
  2216. setCX(TimeDate.wYear);
  2217. setAL((UCHAR)TimeDate.wDayOfWeek);
  2218. }