ReactOS 0.4.15-dev-7842-g558ab78
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 614 of file v86vdm.c.

616{
617 PUCHAR Trampoline = (PUCHAR)TRAMPOLINE_BASE;
618 PTEB VdmTeb = (PTEB)TRAMPOLINE_TEB;
620 ULONG ContextSize = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
622 PKTSS Tss = KeGetPcr()->TSS;
623 PKPROCESS Process = Thread->ApcState.Process;
624 PVDM_PROCESS_OBJECTS VdmProcessObjects;
625 USHORT OldOffset, OldBase;
626
627 /* Start with a clean TEB */
628 RtlZeroMemory(VdmTeb, sizeof(TEB));
629
630 /* Write the interrupt and bop */
631 *Trampoline++ = 0xCD;
632 *Trampoline++ = (UCHAR)Int;
633 *(PULONG)Trampoline = TRAMPOLINE_BOP;
634
635 /* Setup the VDM TEB and TIB */
636 VdmTeb->Vdm = (PVOID)TRAMPOLINE_TIB;
637 RtlZeroMemory(VdmTib, sizeof(VDM_TIB));
638 VdmTib->Size = sizeof(VDM_TIB);
639
640 /* Set a blank VDM state */
641 *VdmState = 0;
642
643 /* Copy the context */
645 VdmTib->VdmContext.SegCs = (ULONG_PTR)Trampoline >> 4;
646 VdmTib->VdmContext.SegSs = (ULONG_PTR)Trampoline >> 4;
647 VdmTib->VdmContext.Eip = 0;
648 VdmTib->VdmContext.Esp = 2 * PAGE_SIZE - sizeof(ULONG_PTR);
651
652 /* This can't be a real VDM process */
653 ASSERT(PsGetCurrentProcess()->VdmObjects == NULL);
654
655 /* Allocate VDM structure */
656 VdmProcessObjects = ExAllocatePoolWithTag(NonPagedPool,
657 sizeof(VDM_PROCESS_OBJECTS),
658 TAG_KERNEL);
659 if (!VdmProcessObjects) return STATUS_NO_MEMORY;
660
661 /* Set it up */
662 RtlZeroMemory(VdmProcessObjects, sizeof(VDM_PROCESS_OBJECTS));
663 VdmProcessObjects->VdmTib = VdmTib;
664 PsGetCurrentProcess()->VdmObjects = VdmProcessObjects;
665
666 /* Set the system affinity for the current thread */
668
669 /* Make sure there's space for two IOPMs, then copy & clear the current */
670 ASSERT(((PKIPCR)KeGetPcr())->GDT[KGDT_TSS / 8].LimitLow >=
671 (0x2000 + IOPM_OFFSET - 1));
674
675 /* Save the old offset and base, and set the new ones */
676 OldOffset = Process->IopmOffset;
677 OldBase = Tss->IoMapBase;
678 Process->IopmOffset = (USHORT)IOPM_OFFSET;
680
681 /* Switch stacks and work the magic */
683
684 /* Restore IOPM */
686 Process->IopmOffset = OldOffset;
687 Tss->IoMapBase = OldBase;
688
689 /* Restore affinity */
691
692 /* Restore context */
694 Context->ContextFlags = CONTEXT_FULL;
695
696 /* Free VDM objects */
698 PsGetCurrentProcess()->VdmObjects = NULL;
699
700 /* Return status */
701 return STATUS_SUCCESS;
702}
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_INTERRUPT_MASK
Definition: ketypes.h:187
#define EFLAGS_V86_MASK
Definition: ketypes.h:193
#define IOPM_OFFSET
Definition: ketypes.h:330
#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
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
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:844
KIIO_ACCESS_MAP IoMaps[IOPM_COUNT]
Definition: ketypes.h:878
USHORT IoMapBase
Definition: ketypes.h:877
UCHAR IoMap[8196]
Definition: ketypes.h:976
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 709 of file v86vdm.c.

711{
712 USHORT MapOffset;
713 PKPRCB Prcb;
714 KAFFINITY TargetProcessors;
715
716 if(MapNumber > IOPM_COUNT)
717 return FALSE;
718
719 MapOffset = KiComputeIopmOffset(MapNumber);
720
721 Process->IopmOffset = MapOffset;
722
723 TargetProcessors = Process->ActiveProcessors;
724 Prcb = KeGetCurrentPrcb();
725 if (TargetProcessors & Prcb->SetMember)
726 KeGetPcr()->TSS->IoMapBase = MapOffset;
727
728 return TRUE;
729}
#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:331
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1148
#define IOPM_COUNT
Definition: ketypes.h:227
UINT64 SetMember
Definition: ketypes.h:648

◆ Ke386QueryIoAccessMap()

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

Definition at line 762 of file v86vdm.c.

764{
765 ULONG i;
766 PVOID Map;
767 PUCHAR p;
768
769 if (MapNumber > IOPM_COUNT)
770 return FALSE;
771
772 if (MapNumber == IO_ACCESS_MAP_NONE)
773 {
774 // no access, simply return a map of all 1s
775 p = (PUCHAR)IopmBuffer;
776 for (i = 0; i < IOPM_SIZE; i++) {
777 p[i] = (UCHAR)-1;
778 }
779 }
780 else
781 {
782 // copy the bits
783 Map = (PVOID)&(KeGetPcr()->TSS->IoMaps[MapNumber-1].IoMap);
784 RtlMoveMemory((PVOID)IopmBuffer, Map, IOPM_SIZE);
785 }
786
787 return TRUE;
788}
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:329
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

◆ Ke386SetIoAccessMap()

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

Definition at line 736 of file v86vdm.c.

738{
739 PKPROCESS CurrentProcess;
740 PKPRCB Prcb;
741 PVOID pt;
742
743 if ((MapNumber > IOPM_COUNT) || (MapNumber == IO_ACCESS_MAP_NONE))
744 return FALSE;
745
746 Prcb = KeGetCurrentPrcb();
747
748 // Copy the IOP map and load the map for the current process.
749 pt = &(KeGetPcr()->TSS->IoMaps[MapNumber-1].IoMap);
750 RtlMoveMemory(pt, (PVOID)IopmBuffer, IOPM_SIZE);
751 CurrentProcess = Prcb->CurrentThread->ApcState.Process;
752 KeGetPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset;
753
754 return TRUE;
755}
#define pt(x, y)
Definition: drawing.c:79
struct _KTHREAD * CurrentThread
Definition: ketypes.h:636
USHORT IopmOffset
Definition: ketypes.h:2096

◆ Ke386SetIOPL()

VOID NTAPI Ke386SetIOPL ( VOID  )

Definition at line 581 of file v86vdm.c.

582{
583
585 PKPROCESS Process = Thread->ApcState.Process;
586 PKTRAP_FRAME TrapFrame;
588
589 /* IOPL was enabled for this process/thread */
590 Process->Iopl = TRUE;
591 Thread->Iopl = TRUE;
592
593 /* Get the trap frame on exit */
594 TrapFrame = KeGetTrapFrame(Thread);
595
596 /* Convert to a context */
597 Context.ContextFlags = CONTEXT_CONTROL;
598 KeTrapFrameToContext(TrapFrame, NULL, &Context);
599
600 /* Set the IOPL flag */
601 Context.EFlags |= EFLAGS_IOPL;
602
603 /* Convert back to a trap frame */
605}
#define UserMode
Definition: asm.h:35
#define EFLAGS_IOPL
Definition: ketypes.h:189
#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 456 of file v86vdm.c.

457{
458 /* Clean up */
459 TrapFrame->Eip &= 0xFFFF;
460 TrapFrame->HardwareEsp &= 0xFFFF;
461
462 /* We start with only 1 byte per instruction */
463 return KiVdmHandleOpcode(TrapFrame, 1);
464}
BOOLEAN FASTCALL KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:379

Referenced by KiTrap0DHandler().

◆ KiEnterV86Mode()

VOID FASTCALL KiEnterV86Mode ( IN ULONG_PTR  StackFrameUnaligned)

Definition at line 507 of file v86vdm.c.

508{
510 PKV8086_STACK_FRAME StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
511 PKTRAP_FRAME TrapFrame = &StackFrame->TrapFrame;
512 PKV86_FRAME V86Frame = &StackFrame->V86Frame;
513 PFX_SAVE_AREA NpxFrame = &StackFrame->NpxArea;
514
515 ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
516
517 /* Build fake user-mode trap frame */
518 TrapFrame->SegCs = KGDT_R0_CODE | RPL_MASK;
519 TrapFrame->SegEs = TrapFrame->SegDs = TrapFrame->SegFs = TrapFrame->SegGs = 0;
520 TrapFrame->ErrCode = 0;
521
522 /* Get the current thread's initial stack */
525
526 /* Save TEB addresses */
527 V86Frame->ThreadTeb = Thread->Teb;
528 V86Frame->PcrTeb = KeGetPcr()->NtTib.Self;
529
530 /* Save return EIP */
532
533 /* Save our stack (after the frames) */
534 TrapFrame->Esi = StackFrameUnaligned;
535 TrapFrame->Edi = (ULONG_PTR)_AddressOfReturnAddress() + 4;
536
537 /* Sanitize EFlags and enable interrupts */
538 TrapFrame->EFlags = __readeflags() & 0x60DD7;
539 TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
540
541 /* Fill out the rest of the frame */
542 TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
543 TrapFrame->HardwareEsp = 0x11FFE;
545 TrapFrame->Dr7 = 0;
546
547 /* Set some debug fields if trap debugging is enabled */
548 KiFillTrapFrameDebug(TrapFrame);
549
550 /* Disable interrupts */
551 _disable();
552
553 /* Copy the thread's NPX frame */
554 RtlCopyMemory(NpxFrame, V86Frame->ThreadStack, sizeof(FX_SAVE_AREA));
555
556 /* Clear exception list */
557 KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
558
559 /* Set new ESP0 */
560 KeGetPcr()->TSS->Esp0 = (ULONG_PTR)&TrapFrame->V86Es;
561
562 /* Set new initial stack */
563 Thread->InitialStack = V86Frame;
564
565 /* Set VDM TEB */
566 Thread->Teb = (PTEB)TRAMPOLINE_TEB;
568
569 /* Enable interrupts */
570 _enable();
571
572 /* Start VDM execution */
574
575 /* Exit to V86 mode */
576 KiEoiHelper(TrapFrame);
577}
#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:1674
#define RPL_MASK
Definition: ketypes.h:130
#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:424
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:712
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:454
ULONG ErrCode
Definition: ketypes.h:320
ULONG V86Es
Definition: ketypes.h:326
ULONG HardwareEsp
Definition: ketypes.h:324
UINT64 Dr7
Definition: ketypes.h:417
ULONG Eip
Definition: ketypes.h:321
USHORT SegCs
Definition: ketypes.h:450
USHORT SegEs
Definition: ketypes.h:435
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
USHORT SegFs
Definition: ketypes.h:436
USHORT SegGs
Definition: ketypes.h:437
USHORT SegDs
Definition: ketypes.h:434
ULONG Esi
Definition: ketypes.h:317
KTRAP_FRAME TrapFrame
Definition: ke.h:245
KV86_FRAME V86Frame
Definition: ke.h:247
FX_SAVE_AREA NpxArea
Definition: ke.h:246
PVOID ThreadTeb
Definition: ke.h:236
PVOID PcrTeb
Definition: ke.h:237
PVOID ThreadStack
Definition: ke.h:235
#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 468 of file v86vdm.c.

469{
470 PKPCR Pcr = KeGetPcr();
471 ULONG_PTR StackFrameUnaligned;
472 PKV8086_STACK_FRAME StackFrame;
474 PKV86_FRAME V86Frame;
475 PFX_SAVE_AREA NpxFrame;
476
477 /* Get the stack frame back */
478 StackFrameUnaligned = TrapFrame->Esi;
479 StackFrame = (PKV8086_STACK_FRAME)(ROUND_UP(StackFrameUnaligned - 4, 16) + 4);
480 V86Frame = &StackFrame->V86Frame;
481 NpxFrame = &StackFrame->NpxArea;
482 ASSERT((ULONG_PTR)NpxFrame % 16 == 0);
483
484 /* Copy the FPU frame back */
487
488 /* Set initial stack back */
489 Thread->InitialStack = (PVOID)((ULONG_PTR)V86Frame->ThreadStack + sizeof(FX_SAVE_AREA));
490
491 /* Set ESP0 back in the KTSS */
492 Pcr->TSS->Esp0 = (ULONG_PTR)Thread->InitialStack;
493 Pcr->TSS->Esp0 -= sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, V86Es);
494 Pcr->TSS->Esp0 -= NPX_FRAME_LENGTH;
495
496 /* Restore TEB addresses */
497 Thread->Teb = V86Frame->ThreadTeb;
498 KiSetTebBase(KeGetPcr(), V86Frame->ThreadTeb);
499
500 /* Enable interrupts and return a pointer to the trap frame */
501 _enable();
502 return StackFrameUnaligned;
503}
#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 379 of file v86vdm.c.

381{
382 ULONG Eip;
383
384 /* Get flat EIP of the *current* instruction (not the original EIP) */
385 Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
386 Eip += KiVdmGetInstructionSize(Flags) - 1;
387
388 /* Read the opcode entry */
389 switch (*(PUCHAR)Eip)
390 {
391 case 0xF: return KiCallVdmHandler(F);
392 case 0x26: return KiCallVdmPrefixHandler(PFX_FLAG_ES);
393 case 0x2E: return KiCallVdmPrefixHandler(PFX_FLAG_CS);
394 case 0x36: return KiCallVdmPrefixHandler(PFX_FLAG_SS);
395 case 0x3E: return KiCallVdmPrefixHandler(PFX_FLAG_DS);
396 case 0x64: return KiCallVdmPrefixHandler(PFX_FLAG_FS);
397 case 0x65: return KiCallVdmPrefixHandler(PFX_FLAG_GS);
398 case 0x66: return KiCallVdmPrefixHandler(PFX_FLAG_OPER32);
399 case 0x67: return KiCallVdmPrefixHandler(PFX_FLAG_ADDR32);
400 case 0xF0: return KiCallVdmPrefixHandler(PFX_FLAG_LOCK);
401 case 0xF2: return KiCallVdmPrefixHandler(PFX_FLAG_REPNE);
402 case 0xF3: return KiCallVdmPrefixHandler(PFX_FLAG_REP);
403 case 0x6C: return KiCallVdmHandler(INSB);
404 case 0x6D: return KiCallVdmHandler(INSW);
405 case 0x6E: return KiCallVdmHandler(OUTSB);
406 case 0x6F: return KiCallVdmHandler(OUTSW);
407 case 0x98: return KiCallVdmHandler(NPX);
408 case 0xD8: return KiCallVdmHandler(NPX);
409 case 0xD9: return KiCallVdmHandler(NPX);
410 case 0xDA: return KiCallVdmHandler(NPX);
411 case 0xDB: return KiCallVdmHandler(NPX);
412 case 0xDC: return KiCallVdmHandler(NPX);
413 case 0xDD: return KiCallVdmHandler(NPX);
414 case 0xDE: return KiCallVdmHandler(NPX);
415 case 0xDF: return KiCallVdmHandler(NPX);
416 case 0x9C: return KiCallVdmHandler(PUSHF);
417 case 0x9D: return KiCallVdmHandler(POPF);
418 case 0xCD: return KiCallVdmHandler(INTnn);
419 case 0xCE: return KiCallVdmHandler(INTO);
420 case 0xCF: return KiCallVdmHandler(IRET);
421 case 0xE4: return KiCallVdmHandler(INBimm);
422 case 0xE5: return KiCallVdmHandler(INWimm);
423 case 0xE6: return KiCallVdmHandler(OUTBimm);
424 case 0xE7: return KiCallVdmHandler(OUTWimm);
425 case 0xEC: return KiCallVdmHandler(INB);
426 case 0xED: return KiCallVdmHandler(INW);
427 case 0xEE: return KiCallVdmHandler(OUTB);
428 case 0xEF: return KiCallVdmHandler(OUTW);
429 case 0xF4: return KiCallVdmHandler(HLT);
430 case 0xFA: return KiCallVdmHandler(CLI);
431 case 0xFB: return KiCallVdmHandler(STI);
432 default:
433 DPRINT1("Unhandled instruction: 0x%02x.\n", *(PUCHAR)Eip);
434 return KiCallVdmHandler(INV);
435 }
436}
#define DPRINT1
Definition: precomp.h:8
#define KiCallVdmPrefixHandler(x)
Definition: ke.h:216
#define PFX_FLAG_FS
Definition: ke.h:183
#define PFX_FLAG_ADDR32
Definition: ke.h:186
#define PFX_FLAG_REP
Definition: ke.h:189
#define PFX_FLAG_GS
Definition: ke.h:184
#define KiCallVdmHandler(x)
Definition: ke.h:215
#define PFX_FLAG_SS
Definition: ke.h:181
#define PFX_FLAG_ES
Definition: ke.h:179
#define PFX_FLAG_OPER32
Definition: ke.h:185
#define PFX_FLAG_REPNE
Definition: ke.h:188
#define PFX_FLAG_DS
Definition: ke.h:182
#define PFX_FLAG_LOCK
Definition: ke.h:187
#define PFX_FLAG_CS
Definition: ke.h:180
#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 341 of file v86vdm.c.

343{
344 /* Check for VME support */
346
347 /* Disable interrupts */
349
350 /* Skip instruction */
351 TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
352
353 /* Done */
354 return TRUE;
355}
#define KiVdmClearVdmEFlags(x)
Definition: ke.h:214
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 /* Mask in the relevant V86 EFlags into the trap flags */
197 V86EFlags |= (TrapEFlags & ~EFLAGS_INTERRUPT_MASK);
198
199 /* And mask out the VIF, nested task and TF flag from the trap flags */
200 TrapFrame->EFlags = TrapEFlags &~ (EFLAGS_VIF | EFLAGS_NESTED_TASK | EFLAGS_TF);
201
202 /* Add the IOPL flag to the local trap flags */
203 V86EFlags |= EFLAGS_IOPL;
204
205 /* Build flat ESP */
206 Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
207
208 /* Push EFlags */
209 Esp -= 2;
210 *(PUSHORT)(Esp) = (USHORT)V86EFlags;
211
212 /* Push CS */
213 Esp -= 2;
214 *(PUSHORT)(Esp) = (USHORT)TrapFrame->SegCs;
215
216 /* Push IP */
217 Esp -= 2;
218 *(PUSHORT)(Esp) = (USHORT)TrapFrame->Eip + KiVdmGetInstructionSize(Flags) + 1;
219
220 /* Update ESP */
221 TrapFrame->HardwareEsp = (USHORT)Esp;
222
223 /* Get flat EIP */
224 Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
225
226 /* Now get the *next* EIP address (current is original + the count - 1) */
228
229 /* Now read the interrupt number */
230 Interrupt = *(PUCHAR)Eip;
231
232 /* Read the EIP from its IVT entry */
233 Interrupt = *(PULONG)(Interrupt * 4);
234 TrapFrame->Eip = (USHORT)Interrupt;
235
236 /* Now get the CS segment */
237 Interrupt = (USHORT)(Interrupt >> 16);
238
239 /* Check if the trap was not V8086 trap */
240 if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
241 {
242 /* Was it a kernel CS? */
244 if (TrapFrame->SegCs == KGDT_R0_CODE)
245 {
246 /* Add the RPL mask */
247 TrapFrame->SegCs = Interrupt;
248 }
249 else
250 {
251 /* Set user CS */
252 TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
253 }
254 }
255 else
256 {
257 /* Set IVT CS */
258 TrapFrame->SegCs = Interrupt;
259 }
260
261 /* We're done */
262 return TRUE;
263}
#define EFLAGS_NESTED_TASK
Definition: ketypes.h:190
#define EFLAGS_TF
Definition: ketypes.h:186
#define EFLAGS_VIF
Definition: ketypes.h:195
#define EFLAGS_ALIGN_CHECK
Definition: ketypes.h:194
#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 267 of file v86vdm.c.

269{
270 ULONG Esp, V86EFlags, EFlags, TrapEFlags, Eip;
271
272 /* Build flat ESP */
273 Esp = (TrapFrame->HardwareSegSs << 4) + TrapFrame->HardwareEsp;
274
275 /* Check for OPER32 */
277 {
278 /* Build segmented EIP */
279 TrapFrame->Eip = *(PULONG)Esp;
280 TrapFrame->SegCs = *(PUSHORT)(Esp + 4);
281
282 /* Set new ESP */
283 TrapFrame->HardwareEsp += 12;
284
285 /* Get EFLAGS */
286 EFlags = *(PULONG)(Esp + 8);
287 }
288 else
289 {
290 /* Build segmented EIP */
291 TrapFrame->Eip = *(PUSHORT)Esp;
292 TrapFrame->SegCs = *(PUSHORT)(Esp + 2);
293
294 /* Set new ESP */
295 TrapFrame->HardwareEsp += 6;
296
297 /* Get EFLAGS */
298 EFlags = *(PUSHORT)(Esp + 4);
299 }
300
301 /* Mask out EFlags */
303 V86EFlags = EFlags;
304
305 /* Check for VME support */
307
308 /* Add V86 and Interrupt flag */
310
311 /* Update EFlags in trap frame */
312 TrapEFlags = TrapFrame->EFlags;
313 TrapFrame->EFlags = (TrapFrame->EFlags & EFLAGS_VIP) | EFlags;
314
315 /* Check if ESP0 needs to be fixed up */
316 if (!(TrapEFlags & EFLAGS_V86_MASK)) Ki386AdjustEsp0(TrapFrame);
317
318 /* Update the V8086 EFlags state */
320 KiVdmSetVdmEFlags(V86EFlags);
321
322 /* Build flat EIP and check if this is the BOP instruction */
323 Eip = (TrapFrame->SegCs << 4) + TrapFrame->Eip;
324 if (*(PUSHORT)Eip == 0xC4C4)
325 {
326 /* Dispatch the BOP */
327 VdmDispatchBop(TrapFrame);
328 }
329 else
330 {
331 /* FIXME: Check for VDM interrupts */
332 DPRINT("FIXME: Check for VDM interrupts\n");
333 }
334
335 /* We're done */
336 return TRUE;
337}
if(dx< 0)
Definition: linetemp.h:194
#define EFLAGS_VIP
Definition: ketypes.h:196
BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:313
#define KiVdmSetVdmEFlags(x)
Definition: ke.h:213
VOID NTAPI Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:280
#define DPRINT
Definition: sndvol32.h:71
#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 442 of file v86vdm.c.

444{
445 /* Increase instruction size */
446 Flags++;
447
448 /* Handle the next opcode */
449 return KiVdmHandleOpcode(TrapFrame, Flags);
450}

◆ 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 359 of file v86vdm.c.

361{
362 /* Check for VME support */
364
365 /* Enable interrupts */
367
368 /* Skip instruction */
369 TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
370
371 /* Done */
372 return TRUE;
373}

◆ 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().