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.

1632 lines
38 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Monitor.c
  5. Abstract:
  6. This module is the user mode portion of the x86 monitor
  7. Author:
  8. Dave Hastings (daveh) 16 Mar 1991
  9. Environment:
  10. User mode only
  11. Revision History:
  12. Sudeep Bharati (sudeepb) 31-Dec-1991
  13. Converted all register manipulation interfaces to functions
  14. from macros. This is to make ntvdm an exe as well as a dll,
  15. and these register oriented routines are exported from ntvdm
  16. for WOW32 and other installable VDDs.
  17. Dave Hastings (daveh) 18-Apr-1992
  18. Split into multiple files. Track current monitor thread by
  19. Teb pointer. Register initial thread.
  20. Sudeep Bharati (sudeepb) 22-Sep-1992
  21. Added Page Fault Handling For installable VDD support
  22. --*/
  23. #include "monitorp.h"
  24. #include "dbgsvc.h"
  25. //
  26. // Internal functions
  27. //
  28. VOID
  29. EventVdmIo(
  30. VOID
  31. );
  32. VOID
  33. EventVdmStringIo(
  34. VOID
  35. );
  36. VOID
  37. EventVdmMemAccess(
  38. VOID
  39. );
  40. VOID
  41. EventVdmIntAck(
  42. VOID
  43. );
  44. VOID
  45. EventVdmBop(
  46. VOID
  47. );
  48. VOID
  49. EventVdmError(
  50. VOID
  51. );
  52. VOID
  53. EventVdmIrq13(
  54. VOID
  55. );
  56. VOID
  57. EventVdmHandShakeAck(
  58. VOID
  59. );
  60. VOID
  61. CreateProfile(
  62. VOID
  63. );
  64. VOID
  65. StartProfile(
  66. VOID
  67. );
  68. VOID
  69. StopProfile(
  70. VOID
  71. );
  72. VOID
  73. AnalyzeProfile(
  74. VOID
  75. );
  76. VOID
  77. CheckScreenSwitchRequest(
  78. HANDLE handle
  79. );
  80. // [LATER] how do you prevent a struct from straddling a page boundary?
  81. ULONG IntelBase; // base memory address
  82. ULONG VdmSize; // Size of memory in VDM
  83. ULONG VdmDebugLevel; // used to control debugging
  84. PVOID CurrentMonitorTeb; // thread that is currently executing instructions.
  85. ULONG InitialBreakpoint = FALSE; // if set, breakpoint at end of cpu_init
  86. ULONG InitialVdmTibFlags = INITIAL_VDM_TIB_FLAGS; // VdmTib flags picked up from here
  87. CONTEXT InitialContext; // Initial context for all threads
  88. BOOLEAN DebugContextActive = FALSE;
  89. ULONG VdmFeatureBits = 0; // bit to indicate special features
  90. BOOLEAN MainThreadInMonitor = TRUE;
  91. extern PVOID NTVDMpLockPrefixTable;
  92. extern BOOL HandshakeInProgress;
  93. extern HANDLE hSuspend;
  94. extern HANDLE hResume;
  95. extern HANDLE hMainThreadSuspended;
  96. extern PVOID __safe_se_handler_table[]; /* base of safe handler entry table */
  97. extern BYTE __safe_se_handler_count; /* absolute symbol whose address is
  98. the count of table entries */
  99. IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
  100. sizeof(_load_config_used), // Reserved
  101. 0, // Reserved
  102. 0, // Reserved
  103. 0, // Reserved
  104. 0, // GlobalFlagsClear
  105. 0, // GlobalFlagsSet
  106. 0, // CriticalSectionTimeout (milliseconds)
  107. 0, // DeCommitFreeBlockThreshold
  108. 0, // DeCommitTotalFreeThreshold
  109. (ULONG)&NTVDMpLockPrefixTable, // LockPrefixTable, defined in FASTPM.ASM
  110. 0, 0, 0, 0, 0, 0, 0, // Reserved
  111. 0, // & security_cookie
  112. (ULONG)__safe_se_handler_table,
  113. (ULONG)&__safe_se_handler_count
  114. };
  115. // Bop dispatch table
  116. extern void (*BIOS[])();
  117. //
  118. // Event Dispatch table
  119. //
  120. VOID (*EventDispatch[VdmMaxEvent])(VOID) = {
  121. EventVdmIo,
  122. EventVdmStringIo,
  123. EventVdmMemAccess,
  124. EventVdmIntAck,
  125. EventVdmBop,
  126. EventVdmError,
  127. EventVdmIrq13,
  128. EventVdmHandShakeAck
  129. };
  130. #if DBG
  131. BOOLEAN fBreakInDebugger = FALSE;
  132. #endif
  133. EXPORT
  134. VOID
  135. cpu_init(
  136. )
  137. /*++
  138. Routine Description:
  139. This routine is used to prepare the IEU for instruction simulation.
  140. It will set the Intel registers to thier initial value, and perform
  141. any implementation specific initialization necessary.
  142. Arguments:
  143. Return Value:
  144. None.
  145. --*/
  146. {
  147. NTSTATUS Status;
  148. InitialVdmTibFlags |= RM_BIT_MASK;
  149. //
  150. // Find out if we are running with IOPL. We call the kernel
  151. // rather than checking the registry ourselves, so that we can
  152. // insure that both the kernel and ntvdm.exe agree. If they didn't,
  153. // it would result in unnecssary trapping instructions. Whether or
  154. // not Vdms run with IOPL only changes on reboot
  155. //
  156. Status = NtVdmControl(VdmFeatures, &VdmFeatureBits);
  157. #if DBG
  158. if (!NT_SUCCESS(Status)) {
  159. DbgPrint(
  160. "NTVDM: Could not find out whether to use IOPL, %lx\n",
  161. Status
  162. );
  163. }
  164. #endif
  165. //
  166. // If we have fast v86 mode IF emulation set the bit that tells
  167. // the 16 bit IF macros they know.
  168. //
  169. if (VdmFeatureBits & V86_VIRTUAL_INT_EXTENSIONS) {
  170. InitialVdmTibFlags |= RI_BIT_MASK;
  171. }
  172. *pNtVDMState = InitialVdmTibFlags;
  173. // Switch the npx back to 80 bit mode. Win32 apps start with
  174. // 64-bit precision for compatibility across platforms, but
  175. // DOS and Win16 apps expect 80 bit precision.
  176. //
  177. _asm fninit;
  178. //
  179. // We setup the InitialContext structure with the correct floating
  180. // point and debug register configuration, and cpu_createthread
  181. // uses this context to configure each 16-bit thread's floating
  182. // point and debug registers.
  183. //
  184. InitialContext.ContextFlags = CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS;
  185. Status = NtGetContextThread(
  186. NtCurrentThread(),
  187. &InitialContext
  188. );
  189. if (!NT_SUCCESS(Status)) {
  190. #if DBG
  191. DbgPrint("NtVdm terminating : Could not get float/debug context for\n"
  192. " initial thread, status %lx\n", Status);
  193. DbgBreakPoint();
  194. #endif
  195. TerminateVDM();
  196. }
  197. //
  198. //
  199. // Turn OFF em bit so that dos apps will work correctly.
  200. //
  201. // On machines without 387's the floating point flag will have been
  202. // cleared.
  203. //
  204. InitialContext.ContextFlags = CONTEXT_FLOATING_POINT;
  205. InitialContext.FloatSave.Cr0NpxState &= ~0x6; // CR0_EM | CR0_MP
  206. //
  207. // Do the rest of thread initialization
  208. //
  209. cpu_createthread( NtCurrentThread(), NULL );
  210. InterruptInit();
  211. if (InitialBreakpoint) {
  212. DbgBreakPoint();
  213. }
  214. }
  215. EXPORT
  216. VOID
  217. cpu_terminate(
  218. )
  219. /*++
  220. Routine Description:
  221. Arguments:
  222. Return Value:
  223. --*/
  224. {
  225. InterruptTerminate();
  226. }
  227. EXPORT
  228. VOID
  229. cpu_simulate(
  230. )
  231. /*++
  232. Routine Description:
  233. This routine causes the simulation of intel instructions to start.
  234. Arguments:
  235. Return Value:
  236. None.
  237. --*/
  238. {
  239. NTSTATUS Status;
  240. PVDM_TIB VdmTib;
  241. ULONG oldIntState = VDM_VIRTUAL_INTERRUPTS;
  242. DBGTRACE(VDMTR_TYPE_MONITOR | MONITOR_CPU_SIMULATE, 0, 0);
  243. CurrentMonitorTeb = NtCurrentTeb();
  244. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  245. VdmTib->ContinueExecution = TRUE;
  246. VdmTib->VdmContext.ContextFlags = CONTEXT_FULL;
  247. while (VdmTib->ContinueExecution) {
  248. //ASSERT(CurrentMonitorTeb == NtCurrentTeb());
  249. ASSERT(InterlockedIncrement(&VdmTib->NumTasks) == 0);
  250. if (*pNtVDMState & VDM_INTERRUPT_PENDING) {
  251. DispatchInterrupts();
  252. }
  253. // translate MSW bits into EFLAGS
  254. if ( getMSW() & MSW_PE ) {
  255. if (!VDMForWOW && !getIF() && oldIntState == VDM_VIRTUAL_INTERRUPTS) {
  256. //
  257. // For PM apps, we need to set Cli time stamp if interrupts
  258. // are disabled and the time stamp was not set already.
  259. // This is because apps may use int31 to change interrupt
  260. // state instead of using cli.
  261. //
  262. VDM_PM_CLI_DATA cliData;
  263. cliData.Control = PM_CLI_CONTROL_SET;
  264. NtVdmControl(VdmPMCliControl, &cliData);
  265. }
  266. VdmTib->VdmContext.EFlags &= ~EFLAGS_V86_MASK;
  267. if (HandshakeInProgress) {
  268. CheckScreenSwitchRequest(hMainThreadSuspended);
  269. }
  270. MainThreadInMonitor = FALSE;
  271. Status = FastEnterPm();
  272. } else {
  273. VdmTib->VdmContext.EFlags |= EFLAGS_V86_MASK;
  274. if (HandshakeInProgress) {
  275. CheckScreenSwitchRequest(hMainThreadSuspended);
  276. }
  277. MainThreadInMonitor = FALSE;
  278. Status = NtVdmControl(VdmStartExecution,NULL);
  279. }
  280. MainThreadInMonitor = TRUE;
  281. if (HandshakeInProgress) {
  282. CheckScreenSwitchRequest(hMainThreadSuspended);
  283. }
  284. if (!NT_SUCCESS(Status)) {
  285. #if DBG
  286. DbgPrint("NTVDM: Could not start execution\n");
  287. #endif
  288. return;
  289. }
  290. //
  291. // Refresh VdmTib for the fact that wow32 thread never enters cpu_simulate
  292. // but returns here to handle BOP
  293. // Note, I think this needs only in FREE build.
  294. //
  295. CurrentMonitorTeb = NtCurrentTeb();
  296. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  297. if (!VDMForWOW) {
  298. oldIntState = getIF() ? VDM_VIRTUAL_INTERRUPTS : 0;
  299. }
  300. ASSERT(InterlockedDecrement(&VdmTib->NumTasks) < 0);
  301. #if DBG
  302. if (fBreakInDebugger) {
  303. fBreakInDebugger = 0;
  304. DbgBreakPoint();
  305. }
  306. #endif
  307. // Translate Eflags value
  308. ASSERT ((!((VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK) &&
  309. (getMSW() & MSW_PE))));
  310. if ( VdmTib->VdmContext.EFlags & EFLAGS_V86_MASK ) {
  311. VdmTib->VdmContext.EFlags &= ~EFLAGS_V86_MASK;
  312. }
  313. // bugbug does cs:eip wrap cause some kind of fault?
  314. VdmTib->VdmContext.Eip += VdmTib->EventInfo.InstructionSize;
  315. if (VdmTib->EventInfo.Event >= VdmMaxEvent) {
  316. #if DBG
  317. DbgPrint("NTVDM: Unknown event type\n");
  318. DbgBreakPoint();
  319. #endif
  320. VdmTib->ContinueExecution = FALSE;
  321. continue;
  322. }
  323. (*EventDispatch[VdmTib->EventInfo.Event])();
  324. }
  325. // set this back to true incase we are nested
  326. VdmTib->ContinueExecution = TRUE;
  327. //
  328. // Restore the old Vdm tib info. This is necessary for the for the
  329. // case where the application thread is suspended, and a host simulate is
  330. // performed from another thread
  331. //
  332. DBGTRACE(VDMTR_TYPE_MONITOR | MONITOR_CPU_UNSIMULATE, 0, 0);
  333. }
  334. VOID
  335. host_unsimulate(
  336. )
  337. /*++
  338. Routine Description:
  339. This routine causes execution of instructions in a VDM to stop.
  340. Arguments:
  341. Return Value:
  342. None.
  343. --*/
  344. {
  345. PVDM_TIB VdmTib;
  346. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  347. VdmTib->ContinueExecution = FALSE;
  348. }
  349. VOID
  350. EventVdmIo(
  351. VOID
  352. )
  353. /*++
  354. Routine Description:
  355. This function calls the appropriate io simulation routine.
  356. Arguments:
  357. Return Value:
  358. None.
  359. --*/
  360. {
  361. PVDM_TIB VdmTib;
  362. EnableScreenSwitch(TRUE, hMainThreadSuspended); // only in FULLSCREEN
  363. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  364. if (VdmTib->EventInfo.IoInfo.Size == 1) {
  365. if (VdmTib->EventInfo.IoInfo.Read) {
  366. inb(VdmTib->EventInfo.IoInfo.PortNumber,(half_word *)&(VdmTib->VdmContext.Eax));
  367. } else {
  368. outb(VdmTib->EventInfo.IoInfo.PortNumber,getAL());
  369. }
  370. } else if (VdmTib->EventInfo.IoInfo.Size == 2) {
  371. if (VdmTib->EventInfo.IoInfo.Read) {
  372. inw(VdmTib->EventInfo.IoInfo.PortNumber,(word *)&(VdmTib->VdmContext.Eax));
  373. } else {
  374. outw(VdmTib->EventInfo.IoInfo.PortNumber,getAX());
  375. }
  376. }
  377. #if DBG
  378. else {
  379. DbgPrint(
  380. "NtVdm: Unimplemented IO size %d\n",
  381. VdmTib->EventInfo.IoInfo.Size
  382. );
  383. DbgBreakPoint();
  384. }
  385. #endif
  386. DisableScreenSwitch(hMainThreadSuspended);
  387. }
  388. VOID
  389. EventVdmStringIo(
  390. VOID
  391. )
  392. /*++
  393. Routine Description:
  394. This function calls the appropriate io simulation routine.
  395. Arguments:
  396. Return Value:
  397. None.
  398. --*/
  399. {
  400. PVDMSTRINGIOINFO pvsio;
  401. PUSHORT pIndexRegister;
  402. USHORT Index;
  403. PVDM_TIB VdmTib;
  404. EnableScreenSwitch(TRUE, hMainThreadSuspended);
  405. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  406. // WARNING no 32 bit address support
  407. pvsio = &VdmTib->EventInfo.StringIoInfo;
  408. if (pvsio->Size == 1) {
  409. if (pvsio->Read) {
  410. insb((io_addr)pvsio->PortNumber,
  411. (half_word *)Sim32GetVDMPointer(pvsio->Address, 1, ISPESET),
  412. (word)pvsio->Count
  413. );
  414. pIndexRegister = (PUSHORT)&VdmTib->VdmContext.Edi;
  415. } else {
  416. outsb((io_addr)pvsio->PortNumber,
  417. (half_word *)Sim32GetVDMPointer(pvsio->Address,1,ISPESET),
  418. (word)pvsio->Count
  419. );
  420. pIndexRegister = (PUSHORT)&VdmTib->VdmContext.Esi;
  421. }
  422. } else if (pvsio->Size == 2) {
  423. if (pvsio->Read) {
  424. insw((io_addr)pvsio->PortNumber,
  425. (word *)Sim32GetVDMPointer(pvsio->Address,1,ISPESET),
  426. (word)pvsio->Count
  427. );
  428. pIndexRegister = (PUSHORT)&VdmTib->VdmContext.Edi;
  429. } else {
  430. outsw((io_addr)pvsio->PortNumber,
  431. (word *)Sim32GetVDMPointer(pvsio->Address,1,ISPESET),
  432. (word)pvsio->Count
  433. );
  434. pIndexRegister = (PUSHORT)&VdmTib->VdmContext.Esi;
  435. }
  436. } else {
  437. #if DBG
  438. DbgPrint(
  439. "NtVdm: Unimplemented IO size %d\n",
  440. VdmTib->EventInfo.IoInfo.Size
  441. );
  442. DbgBreakPoint();
  443. #endif
  444. DisableScreenSwitch(hMainThreadSuspended);
  445. return;
  446. }
  447. if (getDF()) {
  448. Index = *pIndexRegister - (USHORT)(pvsio->Count * pvsio->Size);
  449. }
  450. else {
  451. Index = *pIndexRegister + (USHORT)(pvsio->Count * pvsio->Size);
  452. }
  453. *pIndexRegister = Index;
  454. if (pvsio->Rep) {
  455. (USHORT)VdmTib->VdmContext.Ecx = 0;
  456. }
  457. DisableScreenSwitch(hMainThreadSuspended);
  458. }
  459. VOID
  460. EventVdmIntAck(
  461. VOID
  462. )
  463. /*++
  464. Routine Description:
  465. This routine is called each time we have returned to monitor context
  466. to dispatch interrupts. Its function is to check for AutoEoi and call
  467. the ica to do a nonspecific eoi, when the ica adapter is in AEOI mode.
  468. Arguments:
  469. Return Value:
  470. None.
  471. --*/
  472. {
  473. int line;
  474. int adapter;
  475. PVDM_TIB VdmTib;
  476. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  477. if (VdmTib->EventInfo.IntAckInfo) {
  478. if (VdmTib->EventInfo.IntAckInfo & VDMINTACK_SLAVE)
  479. adapter = 1;
  480. else
  481. adapter = 0;
  482. line = -1;
  483. host_ica_lock();
  484. ica_eoi(adapter,
  485. &line,
  486. (int)(VdmTib->EventInfo.IntAckInfo & VDMINTACK_RAEOIMASK)
  487. );
  488. host_ica_unlock();
  489. }
  490. }
  491. VOID
  492. EventVdmBop(
  493. VOID
  494. )
  495. /*++
  496. Routine Description:
  497. This routine dispatches to the appropriate bop handler
  498. Arguments:
  499. Return Value:
  500. None.
  501. --*/
  502. {
  503. PVDM_TIB VdmTib;
  504. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  505. if (VdmTib->EventInfo.BopNumber > MAX_BOP) {
  506. #if DBG
  507. DbgPrint(
  508. "NtVdm: Invalid BOP %lx\n",
  509. VdmTib->EventInfo.BopNumber
  510. );
  511. #endif
  512. VdmTib->ContinueExecution = FALSE;
  513. } else {
  514. DBGTRACE(VDMTR_TYPE_MONITOR | MONITOR_EVENT_BOP,
  515. (USHORT)VdmTib->EventInfo.BopNumber,
  516. (ULONG)(*((UCHAR *)Sim32GetVDMPointer(
  517. (VdmTib->VdmContext.SegCs << 16) | VdmTib->VdmContext.Eip,
  518. 1,
  519. ISPESET)))
  520. );
  521. (*BIOS[VdmTib->EventInfo.BopNumber])();
  522. CurrentMonitorTeb = NtCurrentTeb();
  523. }
  524. }
  525. VOID
  526. EventVdmError(
  527. VOID
  528. )
  529. /*++
  530. Routine Description:
  531. This routine prints a message(debug only), and exits the vdm
  532. Arguments:
  533. Return Value:
  534. None.
  535. --*/
  536. {
  537. PVDM_TIB VdmTib;
  538. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  539. #if DBG
  540. DbgPrint(
  541. "NtVdm: Error code %lx\n",
  542. VdmTib->EventInfo.ErrorStatus
  543. );
  544. DbgBreakPoint();
  545. #endif
  546. TerminateVDM();
  547. VdmTib->ContinueExecution = FALSE;
  548. }
  549. VOID
  550. EventVdmIrq13(
  551. VOID
  552. )
  553. /*++
  554. Routine Description:
  555. This routine simulates an IRQ 13 to the vdm
  556. Arguments:
  557. Return Value:
  558. None.
  559. --*/
  560. {
  561. if (!IRQ13BeingHandled) {
  562. IRQ13BeingHandled = TRUE;
  563. ica_hw_interrupt(
  564. ICA_SLAVE,
  565. 5,
  566. 1
  567. );
  568. }
  569. }
  570. VOID
  571. EventVdmHandShakeAck(
  572. VOID
  573. )
  574. /*++
  575. Routine Description:
  576. This routine does nothing.
  577. Arguments:
  578. Return Value:
  579. None.
  580. --*/
  581. {
  582. }
  583. VOID
  584. EventVdmMemAccess(
  585. VOID
  586. )
  587. /*++
  588. Routine Description:
  589. This routine will call the page fault handler routine which
  590. is common to both x86 and mips.
  591. Arguments:
  592. Return Value:
  593. None.
  594. --*/
  595. {
  596. PVDM_TIB VdmTib;
  597. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  598. // RWMode is 0 if read fault or 1 if write fault.
  599. DispatchPageFault(
  600. VdmTib->EventInfo.FaultInfo.FaultAddr,
  601. VdmTib->EventInfo.FaultInfo.RWMode
  602. );
  603. CurrentMonitorTeb = NtCurrentTeb();
  604. }
  605. // Get and Set routines for intel registers.
  606. ULONG getEAX (VOID) {
  607. PVDM_TIB VdmTib;
  608. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  609. return (VdmTib->VdmContext.Eax);
  610. }
  611. USHORT getAX (VOID) {
  612. PVDM_TIB VdmTib;
  613. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  614. return ((USHORT)(VdmTib->VdmContext.Eax));
  615. }
  616. UCHAR getAL (VOID) {
  617. PVDM_TIB VdmTib;
  618. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  619. return ((BYTE)(VdmTib->VdmContext.Eax));
  620. }
  621. UCHAR getAH (VOID) {
  622. PVDM_TIB VdmTib;
  623. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  624. return ((BYTE)(VdmTib->VdmContext.Eax >> 8));
  625. }
  626. ULONG getEBX (VOID) {
  627. PVDM_TIB VdmTib;
  628. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  629. return (VdmTib->VdmContext.Ebx);
  630. }
  631. USHORT getBX (VOID) {
  632. PVDM_TIB VdmTib;
  633. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  634. return ((USHORT)(VdmTib->VdmContext.Ebx));
  635. }
  636. UCHAR getBL (VOID) {
  637. PVDM_TIB VdmTib;
  638. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  639. return ((BYTE)(VdmTib->VdmContext.Ebx));
  640. }
  641. UCHAR getBH (VOID) {
  642. PVDM_TIB VdmTib;
  643. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  644. return ((BYTE)(VdmTib->VdmContext.Ebx >> 8));
  645. }
  646. ULONG getECX (VOID) {
  647. PVDM_TIB VdmTib;
  648. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  649. return (VdmTib->VdmContext.Ecx);
  650. }
  651. USHORT getCX (VOID) {
  652. PVDM_TIB VdmTib;
  653. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  654. return ((USHORT)(VdmTib->VdmContext.Ecx));
  655. }
  656. UCHAR getCL (VOID) {
  657. PVDM_TIB VdmTib;
  658. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  659. return ((BYTE)(VdmTib->VdmContext.Ecx));
  660. }
  661. UCHAR getCH (VOID) {
  662. PVDM_TIB VdmTib;
  663. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  664. return ((BYTE)(VdmTib->VdmContext.Ecx >> 8));
  665. }
  666. ULONG getEDX (VOID) {
  667. PVDM_TIB VdmTib;
  668. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  669. return (VdmTib->VdmContext.Edx);
  670. }
  671. USHORT getDX (VOID) {
  672. PVDM_TIB VdmTib;
  673. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  674. return ((USHORT)(VdmTib->VdmContext.Edx));
  675. }
  676. UCHAR getDL (VOID) {
  677. PVDM_TIB VdmTib;
  678. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  679. return ((BYTE)(VdmTib->VdmContext.Edx));
  680. }
  681. UCHAR getDH (VOID) {
  682. PVDM_TIB VdmTib;
  683. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  684. return ((BYTE)(VdmTib->VdmContext.Edx >> 8));
  685. }
  686. ULONG getESP (VOID) {
  687. PVDM_TIB VdmTib;
  688. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  689. return (VdmTib->VdmContext.Esp);
  690. }
  691. USHORT getSP (VOID) {
  692. PVDM_TIB VdmTib;
  693. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  694. return ((USHORT)VdmTib->VdmContext.Esp);
  695. }
  696. ULONG getEBP (VOID) {
  697. PVDM_TIB VdmTib;
  698. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  699. return (VdmTib->VdmContext.Ebp);
  700. }
  701. USHORT getBP (VOID) {
  702. PVDM_TIB VdmTib;
  703. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  704. return ((USHORT)VdmTib->VdmContext.Ebp);
  705. }
  706. ULONG getESI (VOID) {
  707. PVDM_TIB VdmTib;
  708. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  709. return (VdmTib->VdmContext.Esi);
  710. }
  711. USHORT getSI (VOID) {
  712. PVDM_TIB VdmTib;
  713. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  714. return ((USHORT)VdmTib->VdmContext.Esi);
  715. }
  716. ULONG getEDI (VOID) {
  717. PVDM_TIB VdmTib;
  718. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  719. return (VdmTib->VdmContext.Edi);
  720. }
  721. USHORT getDI (VOID) {
  722. PVDM_TIB VdmTib;
  723. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  724. return ((USHORT)VdmTib->VdmContext.Edi);
  725. }
  726. ULONG getEIP (VOID) {
  727. PVDM_TIB VdmTib;
  728. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  729. return (VdmTib->VdmContext.Eip);
  730. }
  731. USHORT getIP (VOID) {
  732. PVDM_TIB VdmTib;
  733. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  734. return ((USHORT)VdmTib->VdmContext.Eip);
  735. }
  736. USHORT getCS (VOID) {
  737. PVDM_TIB VdmTib;
  738. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  739. return ((USHORT)VdmTib->VdmContext.SegCs);
  740. }
  741. USHORT getSS (VOID) {
  742. PVDM_TIB VdmTib;
  743. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  744. return ((USHORT)VdmTib->VdmContext.SegSs);
  745. }
  746. USHORT getDS (VOID) {
  747. PVDM_TIB VdmTib;
  748. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  749. return ((USHORT)VdmTib->VdmContext.SegDs);
  750. }
  751. USHORT getES (VOID) {
  752. PVDM_TIB VdmTib;
  753. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  754. return ((USHORT)VdmTib->VdmContext.SegEs);
  755. }
  756. USHORT getFS (VOID) {
  757. PVDM_TIB VdmTib;
  758. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  759. return ((USHORT)VdmTib->VdmContext.SegFs);
  760. }
  761. USHORT getGS (VOID) {
  762. PVDM_TIB VdmTib;
  763. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  764. return ((USHORT)VdmTib->VdmContext.SegGs);
  765. }
  766. ULONG getCF (VOID) {
  767. PVDM_TIB VdmTib;
  768. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  769. return ((VdmTib->VdmContext.EFlags & FLG_CARRY) ? 1 : 0);
  770. }
  771. ULONG getPF (VOID) {
  772. PVDM_TIB VdmTib;
  773. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  774. return ((VdmTib->VdmContext.EFlags & FLG_PARITY) ? 1 : 0);
  775. }
  776. ULONG getAF (VOID) {
  777. PVDM_TIB VdmTib;
  778. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  779. return ((VdmTib->VdmContext.EFlags & FLG_AUXILIARY) ? 1 : 0);
  780. }
  781. ULONG getZF (VOID) {
  782. PVDM_TIB VdmTib;
  783. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  784. return ((VdmTib->VdmContext.EFlags & FLG_ZERO) ? 1 : 0);
  785. }
  786. ULONG getSF (VOID) {
  787. PVDM_TIB VdmTib;
  788. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  789. return ((VdmTib->VdmContext.EFlags & FLG_SIGN) ? 1 : 0);
  790. }
  791. ULONG getTF (VOID) {
  792. PVDM_TIB VdmTib;
  793. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  794. return ((VdmTib->VdmContext.EFlags & FLG_TRAP) ? 1 : 0);
  795. }
  796. ULONG getIF (VOID) {
  797. PVDM_TIB VdmTib;
  798. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  799. return ((VdmTib->VdmContext.EFlags & FLG_INTERRUPT) ? 1 : 0);
  800. }
  801. ULONG getDF (VOID) {
  802. PVDM_TIB VdmTib;
  803. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  804. return ((VdmTib->VdmContext.EFlags & FLG_DIRECTION) ? 1 : 0);
  805. }
  806. ULONG getOF (VOID) {
  807. PVDM_TIB VdmTib;
  808. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  809. return ((VdmTib->VdmContext.EFlags & FLG_OVERFLOW) ? 1 : 0);
  810. }
  811. USHORT getMSW (VOID) {
  812. PVDM_TIB VdmTib;
  813. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  814. return ((USHORT)VdmTib->IntelMSW);
  815. }
  816. USHORT getSTATUS(VOID){
  817. PVDM_TIB VdmTib;
  818. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  819. return (USHORT)VdmTib->VdmContext.EFlags;
  820. }
  821. ULONG getEFLAGS(VOID) {
  822. PVDM_TIB VdmTib;
  823. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  824. return VdmTib->VdmContext.EFlags;
  825. }
  826. USHORT getFLAGS(VOID) {
  827. PVDM_TIB VdmTib;
  828. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  829. return (USHORT)VdmTib->VdmContext.EFlags;
  830. }
  831. VOID setEAX (ULONG val) {
  832. PVDM_TIB VdmTib;
  833. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  834. VdmTib->VdmContext.Eax = val;
  835. }
  836. VOID setAX (USHORT val) {
  837. PVDM_TIB VdmTib;
  838. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  839. VdmTib->VdmContext.Eax = (VdmTib->VdmContext.Eax & 0xFFFF0000) |
  840. ((ULONG)val & 0x0000FFFF);
  841. }
  842. VOID setAH (UCHAR val) {
  843. PVDM_TIB VdmTib;
  844. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  845. VdmTib->VdmContext.Eax = (VdmTib->VdmContext.Eax & 0xFFFF00FF) |
  846. ((ULONG)(val << 8) & 0x0000FF00);
  847. }
  848. VOID setAL (UCHAR val) {
  849. PVDM_TIB VdmTib;
  850. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  851. VdmTib->VdmContext.Eax = (VdmTib->VdmContext.Eax & 0xFFFFFF00) |
  852. ((ULONG)val & 0x000000FF);
  853. }
  854. VOID setEBX (ULONG val) {
  855. PVDM_TIB VdmTib;
  856. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  857. VdmTib->VdmContext.Ebx = val ;
  858. }
  859. VOID setBX (USHORT val) {
  860. PVDM_TIB VdmTib;
  861. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  862. VdmTib->VdmContext.Ebx = (VdmTib->VdmContext.Ebx & 0xFFFF0000) |
  863. ((ULONG)val & 0x0000FFFF);
  864. }
  865. VOID setBH (UCHAR val) {
  866. PVDM_TIB VdmTib;
  867. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  868. VdmTib->VdmContext.Ebx = (VdmTib->VdmContext.Ebx & 0xFFFF00FF) |
  869. ((ULONG)(val << 8) & 0x0000FF00);
  870. }
  871. VOID setBL (UCHAR val) {
  872. PVDM_TIB VdmTib;
  873. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  874. VdmTib->VdmContext.Ebx = (VdmTib->VdmContext.Ebx & 0xFFFFFF00) |
  875. ((ULONG)val & 0x000000FF);
  876. }
  877. VOID setECX (ULONG val) {
  878. PVDM_TIB VdmTib;
  879. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  880. VdmTib->VdmContext.Ecx = val ;
  881. }
  882. VOID setCX (USHORT val) {
  883. PVDM_TIB VdmTib;
  884. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  885. VdmTib->VdmContext.Ecx = (VdmTib->VdmContext.Ecx & 0xFFFF0000) |
  886. ((ULONG)val & 0x0000FFFF);
  887. }
  888. VOID setCH (UCHAR val) {
  889. PVDM_TIB VdmTib;
  890. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  891. VdmTib->VdmContext.Ecx = (VdmTib->VdmContext.Ecx & 0xFFFF00FF) |
  892. ((ULONG)(val << 8) & 0x0000FF00);
  893. }
  894. VOID setCL (UCHAR val) {
  895. PVDM_TIB VdmTib;
  896. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  897. VdmTib->VdmContext.Ecx = (VdmTib->VdmContext.Ecx & 0xFFFFFF00) |
  898. ((ULONG)val & 0x000000FF);
  899. }
  900. VOID setEDX (ULONG val) {
  901. PVDM_TIB VdmTib;
  902. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  903. VdmTib->VdmContext.Edx = val ;
  904. }
  905. VOID setDX (USHORT val) {
  906. PVDM_TIB VdmTib;
  907. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  908. VdmTib->VdmContext.Edx = (VdmTib->VdmContext.Edx & 0xFFFF0000) |
  909. ((ULONG)val & 0x0000FFFF);
  910. }
  911. VOID setDH (UCHAR val) {
  912. PVDM_TIB VdmTib;
  913. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  914. VdmTib->VdmContext.Edx = (VdmTib->VdmContext.Edx & 0xFFFF00FF) |
  915. ((ULONG)(val << 8) & 0x0000FF00);
  916. }
  917. VOID setDL (UCHAR val) {
  918. PVDM_TIB VdmTib;
  919. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  920. VdmTib->VdmContext.Edx = (VdmTib->VdmContext.Edx & 0xFFFFFF00) |
  921. ((ULONG)val & 0x000000FF);
  922. }
  923. VOID setESP (ULONG val) {
  924. PVDM_TIB VdmTib;
  925. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  926. VdmTib->VdmContext.Esp = val ;
  927. }
  928. VOID setSP (USHORT val) {
  929. PVDM_TIB VdmTib;
  930. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  931. VdmTib->VdmContext.Esp = (VdmTib->VdmContext.Esp & 0xFFFF0000) |
  932. ((ULONG)val & 0x0000FFFF);
  933. }
  934. VOID setEBP (ULONG val) {
  935. PVDM_TIB VdmTib;
  936. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  937. VdmTib->VdmContext.Ebp = val;
  938. }
  939. VOID setBP (USHORT val) {
  940. PVDM_TIB VdmTib;
  941. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  942. VdmTib->VdmContext.Ebp = (VdmTib->VdmContext.Ebp & 0xFFFF0000) |
  943. ((ULONG)val & 0x0000FFFF);
  944. }
  945. VOID setESI (ULONG val) {
  946. PVDM_TIB VdmTib;
  947. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  948. VdmTib->VdmContext.Esi = val ;
  949. }
  950. VOID setSI (USHORT val) {
  951. PVDM_TIB VdmTib;
  952. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  953. VdmTib->VdmContext.Esi = (VdmTib->VdmContext.Esi & 0xFFFF0000) |
  954. ((ULONG)val & 0x0000FFFF);
  955. }
  956. VOID setEDI (ULONG val) {
  957. PVDM_TIB VdmTib;
  958. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  959. VdmTib->VdmContext.Edi = val ;
  960. }
  961. VOID setDI (USHORT val) {
  962. PVDM_TIB VdmTib;
  963. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  964. VdmTib->VdmContext.Edi = (VdmTib->VdmContext.Edi & 0xFFFF0000) |
  965. ((ULONG)val & 0x0000FFFF);
  966. }
  967. VOID setEIP (ULONG val) {
  968. PVDM_TIB VdmTib;
  969. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  970. VdmTib->VdmContext.Eip = val ;
  971. }
  972. VOID setIP (USHORT val) {
  973. PVDM_TIB VdmTib;
  974. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  975. VdmTib->VdmContext.Eip = (VdmTib->VdmContext.Eip & 0xFFFF0000) |
  976. ((ULONG)val & 0x0000FFFF);
  977. }
  978. VOID setCS (USHORT val) {
  979. PVDM_TIB VdmTib;
  980. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  981. VdmTib->VdmContext.SegCs = (ULONG) val & 0x0000FFFF ;
  982. }
  983. VOID setSS (USHORT val) {
  984. PVDM_TIB VdmTib;
  985. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  986. VdmTib->VdmContext.SegSs = (ULONG) val & 0x0000FFFF ;
  987. }
  988. VOID setDS (USHORT val) {
  989. PVDM_TIB VdmTib;
  990. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  991. VdmTib->VdmContext.SegDs = (ULONG) val & 0x0000FFFF ;
  992. }
  993. VOID setES (USHORT val) {
  994. PVDM_TIB VdmTib;
  995. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  996. VdmTib->VdmContext.SegEs = (ULONG) val & 0x0000FFFF ;
  997. }
  998. VOID setFS (USHORT val) {
  999. PVDM_TIB VdmTib;
  1000. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1001. VdmTib->VdmContext.SegFs = (ULONG) val & 0x0000FFFF ;
  1002. }
  1003. VOID setGS (USHORT val) {
  1004. PVDM_TIB VdmTib;
  1005. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1006. VdmTib->VdmContext.SegGs = (ULONG) val & 0x0000FFFF ;
  1007. }
  1008. VOID setCF (ULONG val) {
  1009. PVDM_TIB VdmTib;
  1010. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1011. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_CARRY) |
  1012. (((ULONG)val << FLG_CARRY_BIT) & FLG_CARRY);
  1013. }
  1014. VOID setPF (ULONG val) {
  1015. PVDM_TIB VdmTib;
  1016. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1017. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_PARITY) |
  1018. (((ULONG)val << FLG_PARITY_BIT) & FLG_PARITY);
  1019. }
  1020. VOID setAF (ULONG val) {
  1021. PVDM_TIB VdmTib;
  1022. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1023. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_AUXILIARY) |
  1024. (((ULONG)val << FLG_AUXILIARY_BIT) & FLG_AUXILIARY);
  1025. }
  1026. VOID setZF (ULONG val) {
  1027. PVDM_TIB VdmTib;
  1028. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1029. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_ZERO) |
  1030. (((ULONG)val << FLG_ZERO_BIT) & FLG_ZERO);
  1031. }
  1032. VOID setSF (ULONG val) {
  1033. PVDM_TIB VdmTib;
  1034. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1035. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_SIGN) |
  1036. (((ULONG)val << FLG_SIGN_BIT) & FLG_SIGN);
  1037. }
  1038. VOID setIF (ULONG val) {
  1039. PVDM_TIB VdmTib;
  1040. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1041. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_INTERRUPT) |
  1042. (((ULONG)val << FLG_INTERRUPT_BIT) & FLG_INTERRUPT);
  1043. }
  1044. VOID setDF (ULONG val) {
  1045. PVDM_TIB VdmTib;
  1046. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1047. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_DIRECTION) |
  1048. (((ULONG)val << FLG_DIRECTION_BIT) & FLG_DIRECTION);
  1049. }
  1050. VOID setOF (ULONG val) {
  1051. PVDM_TIB VdmTib;
  1052. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1053. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & ~FLG_OVERFLOW) |
  1054. (((ULONG)val << FLG_OVERFLOW_BIT) & FLG_OVERFLOW);
  1055. }
  1056. VOID setMSW (USHORT val) {
  1057. PVDM_TIB VdmTib;
  1058. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1059. VdmTib->IntelMSW = val ;
  1060. }
  1061. VOID setSTATUS(USHORT val) {
  1062. PVDM_TIB VdmTib;
  1063. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1064. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & 0xFFFF0000) | val;
  1065. }
  1066. VOID setEFLAGS(ULONG val) {
  1067. PVDM_TIB VdmTib;
  1068. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1069. VdmTib->VdmContext.EFlags = val;
  1070. }
  1071. VOID setFLAGS(USHORT val) {
  1072. PVDM_TIB VdmTib;
  1073. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1074. VdmTib->VdmContext.EFlags = (VdmTib->VdmContext.EFlags & 0xFFFF0000) | val;
  1075. }
  1076. //
  1077. // The following is a private register function
  1078. //
  1079. ULONG getPE(){
  1080. PVDM_TIB VdmTib;
  1081. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1082. return((VdmTib->IntelMSW & MSW_PE) ? 1 : 0);
  1083. }
  1084. PX86CONTEXT
  1085. getIntelRegistersPointer(
  1086. VOID
  1087. )
  1088. /*++
  1089. Routine Description:
  1090. Return Address on Intel Registers for WOW Fast Access
  1091. Arguments:
  1092. None
  1093. Return Value:
  1094. Pointer to Intel Registers x86 Context Record
  1095. --*/
  1096. {
  1097. PVDM_TIB VdmTib;
  1098. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1099. return &(VdmTib->VdmContext);
  1100. }
  1101. BOOLEAN MonitorInitializePrinterInfo(
  1102. WORD Ports,
  1103. PWORD PortTable,
  1104. PUCHAR State,
  1105. PUCHAR Control,
  1106. PUCHAR Status,
  1107. PUCHAR HostState)
  1108. {
  1109. UCHAR adapter;
  1110. PVDM_TIB VdmTib;
  1111. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1112. ASSERT (Ports == 3);
  1113. ASSERT (Status != NULL);
  1114. // only do this if the structure has not been initialized -- meaning
  1115. // the pointers can be set once.
  1116. if (NULL == VdmTib->PrinterInfo.prt_Status) {
  1117. VdmTib->PrinterInfo.prt_PortAddr[0] = PortTable[0];
  1118. VdmTib->PrinterInfo.prt_PortAddr[1] = PortTable[1];
  1119. VdmTib->PrinterInfo.prt_PortAddr[2] = PortTable[2];
  1120. VdmTib->PrinterInfo.prt_Handle[0] =
  1121. VdmTib->PrinterInfo.prt_Handle[1] =
  1122. VdmTib->PrinterInfo.prt_Handle[2] = NULL;
  1123. // default mode is kernel simulating status port read
  1124. // mode will be changed if
  1125. // (1). A vdd is hooking printer ports.
  1126. // (2). Dongle mode is detected
  1127. VdmTib->PrinterInfo.prt_Mode[0] =
  1128. VdmTib->PrinterInfo.prt_Mode[1] =
  1129. VdmTib->PrinterInfo.prt_Mode[2] = PRT_MODE_SIMULATE_STATUS_PORT;
  1130. // primarily for dongle
  1131. VdmTib->PrinterInfo.prt_BytesInBuffer[0] =
  1132. VdmTib->PrinterInfo.prt_BytesInBuffer[1] =
  1133. VdmTib->PrinterInfo.prt_BytesInBuffer[2] = 0;
  1134. // primarily for simulating printer status read in kernel
  1135. VdmTib->PrinterInfo.prt_State = State;
  1136. VdmTib->PrinterInfo.prt_Control = Control;
  1137. VdmTib->PrinterInfo.prt_Status = Status;
  1138. VdmTib->PrinterInfo.prt_HostState = HostState;
  1139. //
  1140. // Give the kernel printer emulation an opportunity to cache the
  1141. // pointers
  1142. //
  1143. if (!NT_SUCCESS(NtVdmControl(VdmPrinterInitialize,NULL))) {
  1144. return FALSE;
  1145. }
  1146. return TRUE;
  1147. } else {
  1148. return FALSE;
  1149. }
  1150. }
  1151. BOOLEAN MonitorEnablePrinterDirectAccess(WORD adapter, HANDLE handle, BOOLEAN Enable)
  1152. {
  1153. PVDM_TIB VdmTib;
  1154. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1155. ASSERT(VDM_NUMBER_OF_LPT > adapter);
  1156. if (Enable) {
  1157. // if the adapter has been allocated by a third party VDD,
  1158. // can't do direct io.
  1159. if (PRT_MODE_VDD_CONNECTED != VdmTib->PrinterInfo.prt_Mode[adapter]) {
  1160. VdmTib->PrinterInfo.prt_Mode[adapter] = PRT_MODE_DIRECT_IO;
  1161. VdmTib->PrinterInfo.prt_Handle[adapter] = handle;
  1162. // NtVdmControl(VdmPrinterDirectIoOpen, &adapter);
  1163. return TRUE;
  1164. }
  1165. else
  1166. return FALSE;
  1167. }
  1168. else {
  1169. // disabling direct i/o. reset it back to status port simulation
  1170. if (VdmTib->PrinterInfo.prt_Handle[adapter] == handle) {
  1171. NtVdmControl(VdmPrinterDirectIoClose, &adapter);
  1172. VdmTib->PrinterInfo.prt_Mode[adapter] = PRT_MODE_SIMULATE_STATUS_PORT;
  1173. VdmTib->PrinterInfo.prt_Handle[adapter] = NULL;
  1174. VdmTib->PrinterInfo.prt_BytesInBuffer[adapter] = 0;
  1175. return TRUE;
  1176. }
  1177. else
  1178. return FALSE;
  1179. }
  1180. }
  1181. BOOLEAN MonitorVddConnectPrinter(WORD Adapter, HANDLE hVdd, BOOLEAN Connect)
  1182. {
  1183. PVDM_TIB VdmTib;
  1184. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1185. if (VDM_NUMBER_OF_LPT <= Adapter)
  1186. return FALSE;
  1187. if (Connect) {
  1188. VdmTib->PrinterInfo.prt_Mode[Adapter] = PRT_MODE_VDD_CONNECTED;
  1189. VdmTib->PrinterInfo.prt_Handle[Adapter] = hVdd;
  1190. return TRUE;
  1191. }
  1192. else {
  1193. if (hVdd == VdmTib->PrinterInfo.prt_Handle[Adapter]) {
  1194. VdmTib->PrinterInfo.prt_Mode[Adapter] = PRT_MODE_SIMULATE_STATUS_PORT;
  1195. VdmTib->PrinterInfo.prt_Handle[Adapter] = NULL;
  1196. return TRUE;
  1197. }
  1198. else return FALSE;
  1199. }
  1200. }
  1201. BOOLEAN MonitorPrinterWriteData(WORD Adapter, BYTE Value)
  1202. {
  1203. USHORT BytesInBuffer;
  1204. PVDM_TIB VdmTib;
  1205. VdmTib = (PVDM_TIB)NtCurrentTeb()->Vdm;
  1206. ASSERT(VDM_NUMBER_OF_LPT > Adapter);
  1207. BytesInBuffer = VdmTib->PrinterInfo.prt_BytesInBuffer[Adapter];
  1208. VdmTib->PrinterInfo.prt_Buffer[Adapter][BytesInBuffer] = Value;
  1209. VdmTib->PrinterInfo.prt_BytesInBuffer[Adapter]++;
  1210. return TRUE;
  1211. }
  1212. /* CheckScreenSwitchRequest -
  1213. *
  1214. * This function checks if timer thread has asked us to stop such that it
  1215. * can handle the fullscreen and windowed switch.
  1216. * If yes, we will signal that we are stopped and wait for resume event.
  1217. *
  1218. */
  1219. VOID CheckScreenSwitchRequest(HANDLE handle)
  1220. {
  1221. DWORD status;
  1222. //
  1223. // Check if Suspen is requested. If yes, we will signal that we are going to
  1224. // the wait state and wait for the resume event
  1225. // Since 'handle' event is a manual event, it is important that
  1226. // we check-and-wait in a loop such that timer thread will not pick up the
  1227. // 'handle' event between the wait-for-resume and the ResetEvent(handle).
  1228. //
  1229. while (TRUE) {
  1230. status = WaitForSingleObject(hSuspend, 0);
  1231. if (status == 0) {
  1232. SetEvent(handle);
  1233. WaitForSingleObject(hResume, INFINITE);
  1234. ResetEvent(handle);
  1235. } else {
  1236. //
  1237. // Make sure event is reset before leaving this function
  1238. //
  1239. ResetEvent(handle);
  1240. return;
  1241. }
  1242. }
  1243. }