ReactOS 0.4.16-dev-905-gc1b8c4f
v86vdm.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for v86vdm.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define KiVdmGetInstructionSize(x)   ((x) & 0xFF)
 
#define KiVdmGetPrefixFlags(x)   ((x) & 0xFFFFFF00)
 

Functions

 KiVdmUnhandledOpcode (F)
 
 KiVdmUnhandledOpcode (OUTSW)
 
 KiVdmUnhandledOpcode (OUTSB)
 
 KiVdmUnhandledOpcode (INSB)
 
 KiVdmUnhandledOpcode (INSW)
 
 KiVdmUnhandledOpcode (NPX)
 
 KiVdmUnhandledOpcode (INBimm)
 
 KiVdmUnhandledOpcode (INWimm)
 
 KiVdmUnhandledOpcode (OUTBimm)
 
 KiVdmUnhandledOpcode (OUTWimm)
 
 KiVdmUnhandledOpcode (INB)
 
 KiVdmUnhandledOpcode (INW)
 
 KiVdmUnhandledOpcode (OUTB)
 
 KiVdmUnhandledOpcode (OUTW)
 
 KiVdmUnhandledOpcode (HLT)
 
 KiVdmUnhandledOpcode (INTO)
 
 KiVdmUnhandledOpcode (INV)
 
BOOLEAN FASTCALL KiVdmOpcodePUSHF (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmOpcodePOPF (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmOpcodeINTnn (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmOpcodeIRET (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmOpcodeCLI (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmOpcodeSTI (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmHandleOpcode (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL KiVdmOpcodePrefix (IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
 
BOOLEAN FASTCALL Ki386HandleOpcodeV86 (IN PKTRAP_FRAME TrapFrame)
 
ULONG_PTR FASTCALL KiExitV86Mode (IN PKTRAP_FRAME TrapFrame)
 
VOID FASTCALL KiEnterV86Mode (IN ULONG_PTR StackFrameUnaligned)
 
VOID NTAPI Ke386SetIOPL (VOID)
 
NTSTATUS NTAPI Ke386CallBios (IN ULONG Int, OUT PCONTEXT Context)
 
BOOLEAN NTAPI Ke386IoSetAccessProcess (IN PKPROCESS Process, IN ULONG MapNumber)
 
BOOLEAN NTAPI Ke386SetIoAccessMap (IN ULONG MapNumber, IN PKIO_ACCESS_MAP IopmBuffer)
 
BOOLEAN NTAPI Ke386QueryIoAccessMap (IN ULONG MapNumber, IN PKIO_ACCESS_MAP IopmBuffer)
 

Variables

ULONG KeI386EFlagsAndMaskV86 = EFLAGS_USER_SANITIZE
 
ULONG KeI386EFlagsOrMaskV86 = EFLAGS_INTERRUPT_MASK
 
PVOID Ki386IopmSaveArea
 
BOOLEAN KeI386VirtualIntExtensions = FALSE
 
const PULONG KiNtVdmState = (PULONG)FIXED_NTVDMSTATE_LINEAR_PC_AT
 

Macro Definition Documentation

◆ KiVdmGetInstructionSize

#define KiVdmGetInstructionSize (   x)    ((x) & 0xFF)

Definition at line 16 of file v86vdm.c.

◆ KiVdmGetPrefixFlags

#define KiVdmGetPrefixFlags (   x)    ((x) & 0xFFFFFF00)

Definition at line 17 of file v86vdm.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file v86vdm.c.

Function Documentation

◆ Ke386CallBios()

NTSTATUS NTAPI Ke386CallBios ( IN ULONG  Int,
OUT PCONTEXT  Context 
)

Definition at line 628 of file v86vdm.c.

630{
631 PUCHAR Trampoline = (PUCHAR)TRAMPOLINE_BASE;
632 PTEB VdmTeb = (PTEB)TRAMPOLINE_TEB;
634 ULONG ContextSize = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
636 PKTSS Tss = KeGetPcr()->TSS;
637 PKPROCESS Process = Thread->ApcState.Process;
638 PVDM_PROCESS_OBJECTS VdmProcessObjects;
639 USHORT OldOffset, OldBase;
640
641 /* Start with a clean TEB */
642 RtlZeroMemory(VdmTeb, sizeof(TEB));
643
644 /* Write the interrupt and bop */
645 *Trampoline++ = 0xCD;
646 *Trampoline++ = (UCHAR)Int;
647 *(PULONG)Trampoline = TRAMPOLINE_BOP;
648
649 /* Setup the VDM TEB and TIB */
650 VdmTeb->Vdm = (PVOID)TRAMPOLINE_TIB;
651 RtlZeroMemory(VdmTib, sizeof(VDM_TIB));
652 VdmTib->Size = sizeof(VDM_TIB);
653
654 /* Set a blank VDM state */
655 *VdmState = 0;
656
657 /* Copy the context */
659 VdmTib->VdmContext.SegCs = (ULONG_PTR)Trampoline >> 4;
660 VdmTib->VdmContext.SegSs = (ULONG_PTR)Trampoline >> 4;
661 VdmTib->VdmContext.Eip = 0;
662 VdmTib->VdmContext.Esp = 2 * PAGE_SIZE - sizeof(ULONG_PTR);
665
666 /* This can't be a real VDM process */
667 ASSERT(PsGetCurrentProcess()->VdmObjects == NULL);
668
669 /* Allocate VDM structure */
670 VdmProcessObjects = ExAllocatePoolWithTag(NonPagedPool,
671 sizeof(VDM_PROCESS_OBJECTS),
672 TAG_KERNEL);
673 if (!VdmProcessObjects) return STATUS_NO_MEMORY;
674
675 /* Set it up */
676 RtlZeroMemory(VdmProcessObjects, sizeof(VDM_PROCESS_OBJECTS));
677 VdmProcessObjects->VdmTib = VdmTib;
678 PsGetCurrentProcess()->VdmObjects = VdmProcessObjects;
679
680 /* Set the system affinity for the current thread */
682
683 /* Make sure there's space for two IOPMs, then copy & clear the current */
684 ASSERT(((PKIPCR)KeGetPcr())->GDT[KGDT_TSS / 8].LimitLow >=
685 (0x2000 + IOPM_OFFSET - 1));
688
689 /* Save the old offset and base, and set the new ones */
690 OldOffset = Process->IopmOffset;
691 OldBase = Tss->IoMapBase;
692 Process->IopmOffset = (USHORT)IOPM_OFFSET;
694
695 /* Switch stacks and work the magic */
697
698 /* Restore IOPM */
700 Process->IopmOffset = OldOffset;
701 Tss->IoMapBase = OldBase;
702
703 /* Restore affinity */
705
706 /* Restore context */
708 Context->ContextFlags = CONTEXT_FULL;
709
710 /* Free VDM objects */
712 PsGetCurrentProcess()->VdmObjects = NULL;
713
714 /* Return status */
715 return STATUS_SUCCESS;
716}
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
int Int
Definition: definitions.h:37
#define NULL
Definition: types.h:112
struct _TEB * PTEB
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NonPagedPool
Definition: env_spec_w32.h:307
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define KeGetCurrentThread
Definition: hal.h:55
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define EFLAGS_V86_MASK
Definition: ketypes.h:197
#define IOPM_OFFSET
Definition: ketypes.h:351
#define IOPM_SIZE
Definition: ketypes.h:228
#define KGDT_TSS
Definition: ketypes.h:127
#define KeGetPcr()
Definition: ketypes.h:81
#define CONTEXT_FULL
Definition: nt_native.h:1375
VOID NTAPI Ki386SetupAndExitToV86Mode(OUT PTEB VdmTeb)
#define TRAMPOLINE_BASE
Definition: vdm.h:36
#define TRAMPOLINE_TIB
Definition: vdm.h:37
#define TRAMPOLINE_TEB
Definition: vdm.h:38
struct _Vdm_Tib * PVDM_TIB
struct _Vdm_Tib VDM_TIB
#define TRAMPOLINE_BOP
Definition: vdm.h:43
#define VdmState
Definition: vdm.h:48
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG Esp
Definition: nt_native.h:1479
ULONG ContextFlags
Definition: nt_native.h:1426
ULONG SegSs
Definition: nt_native.h:1480
ULONG Eip
Definition: nt_native.h:1476
ULONG SegCs
Definition: nt_native.h:1477
ULONG EFlags
Definition: nt_native.h:1478
Definition: ketypes.h:850
KIIO_ACCESS_MAP IoMaps[IOPM_COUNT]
Definition: ketypes.h:884
USHORT IoMapBase
Definition: ketypes.h:883
UCHAR IoMap[8196]
Definition: ketypes.h:1001
Definition: compat.h:836
PVOID Vdm
Definition: compat.h:881
PVDM_TIB VdmTib
Definition: vdm.h:165
Definition: vdm.h:135
ULONG Size
Definition: vdm.h:136
CONTEXT VdmContext
Definition: vdm.h:140
#define TAG_KERNEL
Definition: tag.h:42
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1107
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1021
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
PVOID Ki386IopmSaveArea
Definition: v86vdm.c:23
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by IntInt10CallBios().

◆ Ke386IoSetAccessProcess()

BOOLEAN NTAPI Ke386IoSetAccessProcess ( IN PKPROCESS  Process,
IN ULONG  MapNumber 
)

Definition at line 723 of file v86vdm.c.

725{
726 USHORT MapOffset;
727 PKPRCB Prcb;
728 KAFFINITY TargetProcessors;
729
730 if(MapNumber > IOPM_COUNT)
731 return FALSE;
732
733 MapOffset = KiComputeIopmOffset(MapNumber);
734
735 Process->IopmOffset = MapOffset;
736
737 TargetProcessors = Process->ActiveProcessors;
738 Prcb = KeGetCurrentPrcb();
739 if (TargetProcessors & Prcb->SetMember)
740 KeGetPcr()->TSS->IoMapBase = MapOffset;
741
742 return TRUE;
743}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:352
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1182
#define IOPM_COUNT
Definition: ketypes.h:227
UINT64 SetMember
Definition: ketypes.h:671

◆ Ke386QueryIoAccessMap()

BOOLEAN NTAPI Ke386QueryIoAccessMap ( IN ULONG  MapNumber,
IN PKIO_ACCESS_MAP  IopmBuffer 
)

Definition at line 776 of file v86vdm.c.

778{
779 ULONG i;
780 PVOID Map;
781 PUCHAR p;
782
783 if (MapNumber > IOPM_COUNT)
784 return FALSE;
785
786 if (MapNumber == IO_ACCESS_MAP_NONE)
787 {
788 // no access, simply return a map of all 1s
789 p = (PUCHAR)IopmBuffer;
790 for (i = 0; i < IOPM_SIZE; i++) {
791 p[i] = (UCHAR)-1;
792 }
793 }
794 else
795 {
796 // copy the bits
797 Map = (PVOID)&(KeGetPcr()->TSS->IoMaps[MapNumber-1].IoMap);
798 RtlMoveMemory((PVOID)IopmBuffer, Map, IOPM_SIZE);
799 }
800
801 return TRUE;
802}
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:350
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

◆ Ke386SetIoAccessMap()

BOOLEAN NTAPI Ke386SetIoAccessMap ( IN ULONG  MapNumber,
IN PKIO_ACCESS_MAP  IopmBuffer 
)

Definition at line 750 of file v86vdm.c.

752{
753 PKPROCESS CurrentProcess;
754 PKPRCB Prcb;
755 PVOID pt;
756
757 if ((MapNumber > IOPM_COUNT) || (MapNumber == IO_ACCESS_MAP_NONE))
758 return FALSE;
759
760 Prcb = KeGetCurrentPrcb();
761
762 // Copy the IOP map and load the map for the current process.
763 pt = &(KeGetPcr()->TSS->IoMaps[MapNumber-1].IoMap);
764 RtlMoveMemory(pt, (PVOID)IopmBuffer, IOPM_SIZE);
765 CurrentProcess = Prcb->CurrentThread->ApcState.Process;
766 KeGetPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset;
767
768 return TRUE;
769}
#define pt(x, y)
Definition: drawing.c:79
struct _KTHREAD * CurrentThread
Definition: ketypes.h:659
USHORT IopmOffset
Definition: ketypes.h:2096

◆ Ke386SetIOPL()

VOID NTAPI Ke386SetIOPL ( VOID  )

Definition at line 595 of file v86vdm.c.

596{
597
599 PKPROCESS Process = Thread->ApcState.Process;
600 PKTRAP_FRAME TrapFrame;
602
603 /* IOPL was enabled for this process/thread */
604 Process->Iopl = TRUE;
605 Thread->Iopl = TRUE;
606
607 /* Get the trap frame on exit */
608 TrapFrame = KeGetTrapFrame(Thread);
609
610 /* Convert to a context */
611 Context.ContextFlags = CONTEXT_CONTROL;
612 KeTrapFrameToContext(TrapFrame, NULL, &Context);
613
614 /* Set the IOPL flag */
615 Context.EFlags |= EFLAGS_IOPL;
616
617 /* Convert back to a trap frame */
619}
#define EFLAGS_IOPL
Definition: ketypes.h:193
#define UserMode
Definition: asm.h:39
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define KeGetTrapFrame(Thread)
Definition: ke.h:208
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)

Referenced by NtSetInformationProcess().

◆ Ki386HandleOpcodeV86()

BOOLEAN FASTCALL Ki386HandleOpcodeV86 ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 470 of file v86vdm.c.

471{
472 /* Clean up */
473 TrapFrame->Eip &= 0xFFFF;
474 TrapFrame->HardwareEsp &= 0xFFFF;
475
476 /* We start with only 1 byte per instruction */
477 return KiVdmHandleOpcode(TrapFrame, 1);
478}
BOOLEAN FASTCALL KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:393

Referenced by KiTrap0DHandler().

◆ KiEnterV86Mode()

VOID FASTCALL KiEnterV86Mode ( IN ULONG_PTR  StackFrameUnaligned)

Definition at line 521 of file v86vdm.c.

522{
524 PKV8086_STACK_FRAME StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
525 PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame;
526 PKV86_FRAME V86Frame = &StackFrame->V86Frame;
527 PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea;
528
529 ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
530
531 /* Build fake user-mode trap frame */
532 TrapFrame->SegCs = KGDT_R0_CODE | RPL_MASK;
533 TrapFrame->SegEs = TrapFrame->SegDs = TrapFrame->SegFs = TrapFrame->SegGs = 0;
534 TrapFrame->ErrCode = 0;
535
536 /* Get the current thread's initial stack */
539
540 /* Save TEB addresses */
541 V86Frame->ThreadTeb = Thread->Teb;
542 V86Frame->PcrTeb = KeGetPcr()->NtTib.Self;
543
544 /* Save return EIP */
546
547 /* Save our stack (after the frames) */
548 TrapFrame->Esi = StackFrameUnaligned;
549 TrapFrame->Edi = (ULONG_PTR)_AddressOfReturnAddress() + 4;
550
551 /* Sanitize EFlags and enable interrupts */
552 TrapFrame->EFlags = __readeflags() & 0x60DD7;
553 TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
554
555 /* Fill out the rest of the frame */
556 TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
557 TrapFrame->HardwareEsp = 0x11FFE;
559 TrapFrame->Dr7 = 0;
560
561 /* Set some debug fields if trap debugging is enabled */
562 KiFillTrapFrameDebug(TrapFrame);
563
564 /* Disable interrupts */
565 _disable();
566
567 /* Copy the thread's NPX frame */
568 RtlCopyMemory(NpxFrame, V86Frame->ThreadStack, sizeof(FX_SAVE_AREA));
569
570 /* Clear exception list */
571 KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
572
573 /* Set new ESP0 */
574 KeGetPcr()->TSS->Esp0 = (ULONG_PTR)&TrapFrame->V86Es;
575
576 /* Set new initial stack */
577 Thread->InitialStack = V86Frame;
578
579 /* Set VDM TEB */
580 Thread->Teb = (PTEB)TRAMPOLINE_TEB;
582
583 /* Enable interrupts */
584 _enable();
585
586 /* Start VDM execution */
588
589 /* Exit to V86 mode */
590 KiEoiHelper(TrapFrame);
591}
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define _AddressOfReturnAddress()
Definition: intrin_ppc.h:40
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1688
#define RPL_MASK
Definition: ketypes.h:119
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_R0_CODE
Definition: ketypes.h:123
@ VdmStartExecution
Definition: ketypes.h:472
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
FORCEINLINE VOID KiSetTebBase(PKPCR Pcr, PNT_TIB TebAddress)
Definition: ke.h:428
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:741
struct _KV8086_STACK_FRAME * PKV8086_STACK_FRAME
VOID FASTCALL Ki386BiosCallReturnAddress(IN PKTRAP_FRAME TrapFrame)
NTSTATUS NTAPI NtVdmControl(IN ULONG ControlCode, IN PVOID ControlData)
Definition: stubs.c:194
ULONG HardwareSegSs
Definition: ketypes.h:325
ULONG Edi
Definition: ketypes.h:316
ULONG EFlags
Definition: ketypes.h:478
ULONG ErrCode
Definition: ketypes.h:320
ULONG V86Es
Definition: ketypes.h:326
ULONG HardwareEsp
Definition: ketypes.h:324
ULONG Eip
Definition: ketypes.h:321
UINT64 Dr7
Definition: ketypes.h:441
USHORT SegCs
Definition: ketypes.h:474
USHORT SegEs
Definition: ketypes.h:459
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
USHORT SegFs
Definition: ketypes.h:460
USHORT SegGs
Definition: ketypes.h:461
USHORT SegDs
Definition: ketypes.h:458
ULONG Esi
Definition: ketypes.h:317
KTRAP_FRAME TrapFrame
Definition: ke.h:253
KV86_FRAME V86Frame
Definition: ke.h:255
FX_SAVE_AREA NpxArea
Definition: ke.h:254
PVOID ThreadTeb
Definition: ke.h:244
PVOID PcrTeb
Definition: ke.h:245
PVOID ThreadStack
Definition: ke.h:243
#define KiFillTrapFrameDebug(x)
Definition: trap_x.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ KiExitV86Mode()

ULONG_PTR FASTCALL KiExitV86Mode ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 482 of file v86vdm.c.

483{
484 PKPCR Pcr = KeGetPcr();
485 ULONG_PTR StackFrameUnaligned;
486 PKV8086_STACK_FRAME StackFrame;
488 PKV86_FRAME V86Frame;
489 PFX_SAVE_AREA NpxFrame;
490
491 /* Get the stack frame back */
492 StackFrameUnaligned = TrapFrame->Esi;
493 StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
494 V86Frame = &StackFrame->V86Frame;
495 NpxFrame = &StackFrame->NpxArea;
496 ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
497
498 /* Copy the FPU frame back */
501
502 /* Set initial stack back */
503 Thread->InitialStack = (PVOID)((ULONG_PTR)V86Frame->ThreadStack + sizeof(FX_SAVE_AREA));
504
505 /* Set ESP0 back in the KTSS */
506 Pcr->TSS->Esp0 = (ULONG_PTR)Thread->InitialStack;
507 Pcr->TSS->Esp0 -= sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, V86Es);
508 Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
509
510 /* Restore TEB addresses */
511 Thread->Teb = V86Frame->ThreadTeb;
512 KiSetTebBase(KeGetPcr(), V86Frame->ThreadTeb);
513
514 /* Enable interrupts and return a pointer to the trap frame */
515 _enable();
516 return StackFrameUnaligned;
517}
#define NPX_FRAME_LENGTH
Definition: asm.h:247
struct _FX_SAVE_AREA FX_SAVE_AREA
Definition: ke.h:294
struct _KTSS * TSS
Definition: ke.h:55

◆ KiVdmHandleOpcode()

BOOLEAN FASTCALL KiVdmHandleOpcode ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 393 of file v86vdm.c.

395{
396 ULONG Eip;
397
398 /* Get flat EIP of the *current* instruction (not the original EIP) */
399 Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
400 Eip += KiVdmGetInstructionSize(Flags) - 1;
401
402 /* Read the opcode entry */
403 switch (*(PUCHAR)Eip)
404 {
405 case 0xF: return KiCallVdmHandler(F);
406 case 0x26: return KiCallVdmPrefixHandler(PFX_FLAG_ES);
407 case 0x2E: return KiCallVdmPrefixHandler(PFX_FLAG_CS);
408 case 0x36: return KiCallVdmPrefixHandler(PFX_FLAG_SS);
409 case 0x3E: return KiCallVdmPrefixHandler(PFX_FLAG_DS);
410 case 0x64: return KiCallVdmPrefixHandler(PFX_FLAG_FS);
411 case 0x65: return KiCallVdmPrefixHandler(PFX_FLAG_GS);
412 case 0x66: return KiCallVdmPrefixHandler(PFX_FLAG_OPER32);
413 case 0x67: return KiCallVdmPrefixHandler(PFX_FLAG_ADDR32);
414 case 0xF0: return KiCallVdmPrefixHandler(PFX_FLAG_LOCK);
415 case 0xF2: return KiCallVdmPrefixHandler(PFX_FLAG_REPNE);
416 case 0xF3: return KiCallVdmPrefixHandler(PFX_FLAG_REP);
417 case 0x6C: return KiCallVdmHandler(INSB);
418 case 0x6D: return KiCallVdmHandler(INSW);
419 case 0x6E: return KiCallVdmHandler(OUTSB);
420 case 0x6F: return KiCallVdmHandler(OUTSW);
421 case 0x98: return KiCallVdmHandler(NPX);
422 case 0xD8: return KiCallVdmHandler(NPX);
423 case 0xD9: return KiCallVdmHandler(NPX);
424 case 0xDA: return KiCallVdmHandler(NPX);
425 case 0xDB: return KiCallVdmHandler(NPX);
426 case 0xDC: return KiCallVdmHandler(NPX);
427 case 0xDD: return KiCallVdmHandler(NPX);
428 case 0xDE: return KiCallVdmHandler(NPX);
429 case 0xDF: return KiCallVdmHandler(NPX);
430 case 0x9C: return KiCallVdmHandler(PUSHF);
431 case 0x9D: return KiCallVdmHandler(POPF);
432 case 0xCD: return KiCallVdmHandler(INTnn);
433 case 0xCE: return KiCallVdmHandler(INTO);
434 case 0xCF: return KiCallVdmHandler(IRET);
435 case 0xE4: return KiCallVdmHandler(INBimm);
436 case 0xE5: return KiCallVdmHandler(INWimm);
437 case 0xE6: return KiCallVdmHandler(OUTBimm);
438 case 0xE7: return KiCallVdmHandler(OUTWimm);
439 case 0xEC: return KiCallVdmHandler(INB);
440 case 0xED: return KiCallVdmHandler(INW);
441 case 0xEE: return KiCallVdmHandler(OUTB);
442 case 0xEF: return KiCallVdmHandler(OUTW);
443 case 0xF4: return KiCallVdmHandler(HLT);
444 case 0xFA: return KiCallVdmHandler(CLI);
445 case 0xFB: return KiCallVdmHandler(STI);
446 default:
447 DPRINT1("Unhandled instruction: 0x%02x.\n", *(PUCHAR)Eip);
448 return KiCallVdmHandler(INV);
449 }
450}
#define DPRINT1
Definition: precomp.h:8
#define KiCallVdmPrefixHandler(x)
Definition: ke.h:224
#define PFX_FLAG_FS
Definition: ke.h:191
#define PFX_FLAG_ADDR32
Definition: ke.h:194
#define PFX_FLAG_REP
Definition: ke.h:197
#define PFX_FLAG_GS
Definition: ke.h:192
#define KiCallVdmHandler(x)
Definition: ke.h:223
#define PFX_FLAG_SS
Definition: ke.h:189
#define PFX_FLAG_ES
Definition: ke.h:187
#define PFX_FLAG_OPER32
Definition: ke.h:193
#define PFX_FLAG_REPNE
Definition: ke.h:196
#define PFX_FLAG_DS
Definition: ke.h:190
#define PFX_FLAG_LOCK
Definition: ke.h:195
#define PFX_FLAG_CS
Definition: ke.h:188
#define F(x, y, z)
Definition: md5.c:51
#define KiVdmGetInstructionSize(x)
Definition: v86vdm.c:16
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by Ki386HandleOpcodeV86(), and KiVdmOpcodePrefix().

◆ KiVdmOpcodeCLI()

BOOLEAN FASTCALL KiVdmOpcodeCLI ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 355 of file v86vdm.c.

357{
358 /* Check for VME support */
360
361 /* Disable interrupts */
363
364 /* Skip instruction */
365 TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
366
367 /* Done */
368 return TRUE;
369}
#define KiVdmClearVdmEFlags(x)
Definition: ke.h:222
BOOLEAN KeI386VirtualIntExtensions
Definition: v86vdm.c:24

◆ KiVdmOpcodeINTnn()

BOOLEAN FASTCALL KiVdmOpcodeINTnn ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 178 of file v86vdm.c.

180{
181 ULONG Esp, V86EFlags, TrapEFlags, Eip, Interrupt;
182
183 /* Read trap frame EFlags */
184 TrapEFlags = TrapFrame->EFlags;
185
186 /* Remove interrupt flag from V8086 EFlags */
187 V86EFlags = *KiNtVdmState;
189
190 /* Keep only alignment and interrupt flag from the V8086 state */
192
193 /* Check for VME support */
195 {
196 /* Set IF based on VIF */
197 V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
198 if (TrapEFlags & EFLAGS_VIF)
199 {
200 V86EFlags |= EFLAGS_INTERRUPT_MASK;
201 }
202 }
203
204 /* Mask in the relevant V86 EFlags into the trap flags */
205 V86EFlags |= (TrapEFlags & ~EFLAGS_INTERRUPT_MASK);
206
207 /* And mask out the VIF, nested task and TF flag from the trap flags */
208 TrapFrame->EFlags = TrapEFlags & ~(EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_TF);
209
210 /* Add the IOPL flag to the local trap flags */
211 V86EFlags |= EFLAGS_IOPL;
212
213 /* Build flat ESP */
214 Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
215
216 /* Push EFlags */
217 Esp -= 2;
218 *(PUSHORT)(Esp) = (USHORT)V86EFlags;
219
220 /* Push CS */
221 Esp -= 2;
222 *(PUSHORT)(Esp) = (USHORT)TrapFrame->SegCs;
223
224 /* Push IP */
225 Esp -= 2;
226 *(PUSHORT)(Esp) = (USHORT)TrapFrame->Eip + KiVdmGetInstructionSize(Flags) + 1;
227
228 /* Update ESP */
229 TrapFrame->HardwareEsp = (USHORT)Esp;
230
231 /* Get flat EIP */
232 Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
233
234 /* Now get the *next* EIP address (current is original + the count - 1) */
236
237 /* Now read the interrupt number */
238 Interrupt = *(PUCHAR)Eip;
239
240 /* Read the EIP from its IVT entry */
241 Interrupt = *(PULONG)(Interrupt * 4);
242 TrapFrame->Eip = (USHORT)Interrupt;
243
244 /* Now get the CS segment */
245 Interrupt = (USHORT)(Interrupt >> 16);
246
247 /* Check if the trap was not V8086 trap */
248 if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
249 {
250 /* Was it a kernel CS? */
252 if (TrapFrame->SegCs == KGDT_R0_CODE)
253 {
254 /* Add the RPL mask */
255 TrapFrame->SegCs = Interrupt;
256 }
257 else
258 {
259 /* Set user CS */
260 TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
261 }
262 }
263 else
264 {
265 /* Set IVT CS */
266 TrapFrame->SegCs = Interrupt;
267 }
268
269 /* We're done */
270 return TRUE;
271}
#define EFLAGS_TF
Definition: SystemCall.c:10
#define EFLAGS_NESTED_TASK
Definition: ketypes.h:194
#define EFLAGS_VIF
Definition: ketypes.h:199
#define EFLAGS_ALIGN_CHECK
Definition: ketypes.h:198
#define KGDT_R3_CODE
Definition: ketypes.h:125
uint16_t * PUSHORT
Definition: typedefs.h:56
const PULONG KiNtVdmState
Definition: v86vdm.c:25
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379

◆ KiVdmOpcodeIRET()

BOOLEAN FASTCALL KiVdmOpcodeIRET ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 275 of file v86vdm.c.

277{
278 ULONG Esp, V86EFlags, EFlags, TrapEFlags, Eip;
279
280 /* Build flat ESP */
281 Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
282
283 /* Check for OPER32 */
285 {
286 /* Build segmented EIP */
287 TrapFrame->Eip = *(PULONG)Esp;
288 TrapFrame->SegCs = *(PUSHORT)(Esp + 4);
289
290 /* Set new ESP */
291 TrapFrame->HardwareEsp += 12;
292
293 /* Get EFLAGS */
294 EFlags = *(PULONG)(Esp + 8);
295 }
296 else
297 {
298 /* Build segmented EIP */
299 TrapFrame->Eip = *(PUSHORT)Esp;
300 TrapFrame->SegCs = *(PUSHORT)(Esp + 2);
301
302 /* Set new ESP */
303 TrapFrame->HardwareEsp += 6;
304
305 /* Get EFLAGS */
306 EFlags = *(PUSHORT)(Esp + 4);
307 }
308
309 /* Mask out EFlags */
311 V86EFlags = EFlags;
312
313 /* Check for VME support */
315 {
316 if (EFlags & EFLAGS_INTERRUPT_MASK)
317 {
318 EFlags |= EFLAGS_VIF;
319 }
320 }
321
322 /* Add V86 and Interrupt flag */
324
325 /* Update EFlags in trap frame */
326 TrapEFlags = TrapFrame->EFlags;
327 TrapFrame->EFlags = (TrapFrame->EFlags & EFLAGS_VIP) | EFlags;
328
329 /* Check if ESP0 needs to be fixed up */
330 if (!(TrapEFlags & EFLAGS_V86_MASK)) Ki386AdjustEsp0(TrapFrame);
331
332 /* Update the V8086 EFlags state */
334 KiVdmSetVdmEFlags(V86EFlags);
335
336 /* Build flat EIP and check if this is the BOP instruction */
337 Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
338 if (*(PUSHORT)Eip == 0xC4C4)
339 {
340 /* Dispatch the BOP */
341 VdmDispatchBop(TrapFrame);
342 }
343 else
344 {
345 /* FIXME: Check for VDM interrupts */
346 DPRINT("FIXME: Check for VDM interrupts\n");
347 }
348
349 /* We're done */
350 return TRUE;
351}
if(dx< 0)
Definition: linetemp.h:194
#define EFLAGS_VIP
Definition: ketypes.h:200
BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:313
#define KiVdmSetVdmEFlags(x)
Definition: ke.h:221
VOID NTAPI Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:280
#define DPRINT
Definition: sndvol32.h:73
#define KiVdmGetPrefixFlags(x)
Definition: v86vdm.c:17

◆ KiVdmOpcodePOPF()

BOOLEAN FASTCALL KiVdmOpcodePOPF ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 104 of file v86vdm.c.

106{
107 ULONG Esp, V86EFlags, EFlags, TrapEFlags;
108
109 /* Build flat ESP */
110 Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
111
112 /* Check for OPER32 */
114 {
115 /* Read EFlags */
116 EFlags = *(PULONG)Esp;
117 Esp += 4;
118 }
119 else
120 {
121 /* Read EFlags */
122 EFlags = *(PUSHORT)Esp;
123 Esp += 2;
124 }
125
126 /* Set new ESP */
127 TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
128
129 /* Mask out IOPL from the flags */
130 EFlags &= ~EFLAGS_IOPL;
131
132 /* Save the V86 flags, but mask out the nested task flag */
133 V86EFlags = EFlags & ~EFLAGS_NESTED_TASK;
134
135 /* Now leave only alignment, nested task and interrupt flag */
137
138 /* Get trap EFlags */
139 TrapEFlags = TrapFrame->EFlags;
140
141 /* Check for VME support */
143 {
144 /* Copy the IF flag into the VIF one */
145 V86EFlags &= ~EFLAGS_VIF;
146 if(V86EFlags & EFLAGS_INTERRUPT_MASK)
147 {
148 V86EFlags |= EFLAGS_VIF;
149 /* Don't set the interrupt flag */
150 V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
151 }
152 }
153
154 /* Add V86 flag */
155 V86EFlags |= EFLAGS_V86_MASK;
156
157 /* Update EFlags in trap frame */
158 TrapFrame->EFlags |= V86EFlags;
159
160 /* Check if ESP0 needs to be fixed up */
161 if (TrapEFlags & EFLAGS_V86_MASK) Ki386AdjustEsp0(TrapFrame);
162
163 /* Update the V8086 EFlags state */
165 KiVdmSetVdmEFlags(EFlags);
166
167 /* FIXME: Check for VDM interrupts */
168
169 /* Update EIP */
170 TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
171
172 /* We're done */
173 return TRUE;
174}

◆ KiVdmOpcodePrefix()

BOOLEAN FASTCALL KiVdmOpcodePrefix ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 456 of file v86vdm.c.

458{
459 /* Increase instruction size */
460 Flags++;
461
462 /* Handle the next opcode */
463 return KiVdmHandleOpcode(TrapFrame, Flags);
464}

◆ KiVdmOpcodePUSHF()

BOOLEAN FASTCALL KiVdmOpcodePUSHF ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 51 of file v86vdm.c.

53{
54 ULONG Esp, V86EFlags, TrapEFlags;
55
56 /* Get current V8086 flags and mask out interrupt flag */
57 V86EFlags = *KiNtVdmState;
58 V86EFlags &= ~EFLAGS_INTERRUPT_MASK;
59
60 /* Get trap frame EFLags */
61 TrapEFlags = TrapFrame->EFlags;
62 /* Check for VME support */
64 {
65 /* Copy the virtual interrupt flag to the interrupt flag */
66 TrapEFlags &= ~EFLAGS_INTERRUPT_MASK;
67 if(TrapEFlags & EFLAGS_VIF)
68 TrapEFlags |= EFLAGS_INTERRUPT_MASK;
69 }
70 /* Leave only align, nested task and interrupt */
72
73 /* Add in those flags if they exist, and add in the IOPL flag */
74 V86EFlags |= TrapEFlags;
75 V86EFlags |= EFLAGS_IOPL;
76
77 /* Build flat ESP */
78 Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
79
80 /* Check for OPER32 */
82 {
83 /* Save EFlags */
84 Esp -= 4;
85 *(PULONG)Esp = V86EFlags;
86 }
87 else
88 {
89 /* Save EFLags */
90 Esp -= 2;
91 *(PUSHORT)Esp = (USHORT)V86EFlags;
92 }
93
94 /* Set new ESP and EIP */
95 TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
96 TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
97
98 /* We're done */
99 return TRUE;
100}

◆ KiVdmOpcodeSTI()

BOOLEAN FASTCALL KiVdmOpcodeSTI ( IN PKTRAP_FRAME  TrapFrame,
IN ULONG  Flags 
)

Definition at line 373 of file v86vdm.c.

375{
376 /* Check for VME support */
378
379 /* Enable interrupts */
381
382 /* Skip instruction */
383 TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
384
385 /* Done */
386 return TRUE;
387}

◆ KiVdmUnhandledOpcode() [1/17]

KiVdmUnhandledOpcode ( F  )

◆ KiVdmUnhandledOpcode() [2/17]

KiVdmUnhandledOpcode ( HLT  )

◆ KiVdmUnhandledOpcode() [3/17]

KiVdmUnhandledOpcode ( INB  )

◆ KiVdmUnhandledOpcode() [4/17]

KiVdmUnhandledOpcode ( INBimm  )

◆ KiVdmUnhandledOpcode() [5/17]

KiVdmUnhandledOpcode ( INSB  )

◆ KiVdmUnhandledOpcode() [6/17]

KiVdmUnhandledOpcode ( INSW  )

◆ KiVdmUnhandledOpcode() [7/17]

KiVdmUnhandledOpcode ( INTO  )

◆ KiVdmUnhandledOpcode() [8/17]

KiVdmUnhandledOpcode ( INV  )

◆ KiVdmUnhandledOpcode() [9/17]

KiVdmUnhandledOpcode ( INW  )

◆ KiVdmUnhandledOpcode() [10/17]

KiVdmUnhandledOpcode ( INWimm  )

◆ KiVdmUnhandledOpcode() [11/17]

KiVdmUnhandledOpcode ( NPX  )

◆ KiVdmUnhandledOpcode() [12/17]

KiVdmUnhandledOpcode ( OUTB  )

◆ KiVdmUnhandledOpcode() [13/17]

KiVdmUnhandledOpcode ( OUTBimm  )

◆ KiVdmUnhandledOpcode() [14/17]

KiVdmUnhandledOpcode ( OUTSB  )

◆ KiVdmUnhandledOpcode() [15/17]

KiVdmUnhandledOpcode ( OUTSW  )

◆ KiVdmUnhandledOpcode() [16/17]

KiVdmUnhandledOpcode ( OUTW  )

◆ KiVdmUnhandledOpcode() [17/17]

KiVdmUnhandledOpcode ( OUTWimm  )

Variable Documentation

◆ KeI386EFlagsAndMaskV86

ULONG KeI386EFlagsAndMaskV86 = EFLAGS_USER_SANITIZE

Definition at line 21 of file v86vdm.c.

Referenced by VdmSwapContext().

◆ KeI386EFlagsOrMaskV86

ULONG KeI386EFlagsOrMaskV86 = EFLAGS_INTERRUPT_MASK

Definition at line 22 of file v86vdm.c.

Referenced by VdmSwapContext().

◆ KeI386VirtualIntExtensions

◆ Ki386IopmSaveArea

PVOID Ki386IopmSaveArea

Definition at line 23 of file v86vdm.c.

Referenced by Ke386CallBios(), and KiInitializeKernel().

◆ KiNtVdmState

Definition at line 25 of file v86vdm.c.

Referenced by KiVdmOpcodeINTnn(), and KiVdmOpcodePUSHF().