ReactOS 0.4.16-dev-292-gbbdcc14
v86vdm.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/ke/i386/v86vdm.c
5 * PURPOSE: V8086 and VDM Trap Emulation
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 * Alex Ionescu (alex.ionescu@reactos.org)
8 */
9
10/* INCLUDES *******************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16#define KiVdmGetInstructionSize(x) ((x) & 0xFF)
17#define KiVdmGetPrefixFlags(x) ((x) & 0xFFFFFF00)
18
19/* GLOBALS ********************************************************************/
20
26
27/* UNHANDLED OPCODES **********************************************************/
28
46
47/* OPCODE HANDLERS ************************************************************/
48
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}
101
105 IN ULONG Flags)
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}
175
179 IN ULONG Flags)
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}
264
268 IN ULONG Flags)
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}
338
342 IN ULONG Flags)
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}
356
360 IN ULONG Flags)
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}
374
375/* MASTER OPCODE HANDLER ******************************************************/
376
380 IN ULONG Flags)
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}
437
438/* PREFIX HANDLER *************************************************************/
439
443 IN ULONG Flags)
444{
445 /* Increase instruction size */
446 Flags++;
447
448 /* Handle the next opcode */
449 return KiVdmHandleOpcode(TrapFrame, Flags);
450}
451
452/* TRAP HANDLER ***************************************************************/
453
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}
465
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}
504
505VOID
507KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned)
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}
578
579VOID
580NTAPI
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}
606
607/* PUBLIC FUNCTIONS ***********************************************************/
608
609/*
610 * @implemented
611 */
613NTAPI
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}
703
704/*
705 * @implemented
706 */
708NTAPI
710 IN ULONG MapNumber)
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}
730
731/*
732 * @implemented
733 */
735NTAPI
737 IN PKIO_ACCESS_MAP IopmBuffer)
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}
756
757/*
758 * @implemented
759 */
761NTAPI
763 IN PKIO_ACCESS_MAP IopmBuffer)
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}
unsigned char BOOLEAN
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
#define EFLAGS_TF
Definition: SystemCall.c:10
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
int Int
Definition: definitions.h:37
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
struct _TEB * PTEB
#define pt(x, y)
Definition: drawing.c:79
#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
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_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
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 KeGetCurrentThread
Definition: hal.h:55
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
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define UserMode
Definition: asm.h:35
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:335
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:333
#define EFLAGS_NESTED_TASK
Definition: ketypes.h:179
#define EFLAGS_USER_SANITIZE
Definition: ketypes.h:187
#define EFLAGS_V86_MASK
Definition: ketypes.h:182
#define IOPM_OFFSET
Definition: ketypes.h:334
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1150
#define EFLAGS_VIP
Definition: ketypes.h:185
#define EFLAGS_VIF
Definition: ketypes.h:184
#define RPL_MASK
Definition: ketypes.h:119
#define EFLAGS_ALIGN_CHECK
Definition: ketypes.h:183
#define EFLAGS_IOPL
Definition: ketypes.h:178
#define FIXED_NTVDMSTATE_LINEAR_PC_AT
Definition: asm.h:647
#define NPX_FRAME_LENGTH
Definition: asm.h:247
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_R3_CODE
Definition: ketypes.h:125
#define IOPM_SIZE
Definition: ketypes.h:228
#define KGDT_TSS
Definition: ketypes.h:127
#define KeGetPcr()
Definition: ketypes.h:81
struct _FX_SAVE_AREA FX_SAVE_AREA
KIO_ACCESS_MAP * PKIO_ACCESS_MAP
Definition: ketypes.h:240
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define IOPM_COUNT
Definition: ketypes.h:227
@ VdmStartExecution
Definition: ketypes.h:472
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define FASTCALL
Definition: nt_native.h:50
#define CONTEXT_FULL
Definition: nt_native.h:1375
#define KeGetTrapFrame(Thread)
Definition: ke.h:208
#define KiCallVdmPrefixHandler(x)
Definition: ke.h:216
#define PFX_FLAG_FS
Definition: ke.h:183
BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:313
#define PFX_FLAG_ADDR32
Definition: ke.h:186
#define PFX_FLAG_REP
Definition: ke.h:189
#define KiVdmClearVdmEFlags(x)
Definition: ke.h:214
#define KiVdmSetVdmEFlags(x)
Definition: ke.h:213
#define PFX_FLAG_GS
Definition: ke.h:184
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
#define KiCallVdmHandler(x)
Definition: ke.h:215
#define KiVdmUnhandledOpcode(x)
Definition: ke.h:217
#define PFX_FLAG_SS
Definition: ke.h:181
#define PFX_FLAG_ES
Definition: ke.h:179
FORCEINLINE VOID KiSetTebBase(PKPCR Pcr, PNT_TIB TebAddress)
Definition: ke.h:420
VOID NTAPI Ki386SetupAndExitToV86Mode(OUT PTEB VdmTeb)
VOID NTAPI Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:280
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:733
#define PFX_FLAG_OPER32
Definition: ke.h:185
#define PFX_FLAG_REPNE
Definition: ke.h:188
#define PFX_FLAG_DS
Definition: ke.h:182
struct _KV8086_STACK_FRAME * PKV8086_STACK_FRAME
VOID FASTCALL Ki386BiosCallReturnAddress(IN PKTRAP_FRAME TrapFrame)
#define PFX_FLAG_LOCK
Definition: ke.h:187
#define PFX_FLAG_CS
Definition: ke.h:180
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)
#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
NTSTATUS NTAPI NtVdmControl(IN ULONG ControlCode, IN PVOID ControlData)
Definition: stubs.c:194
unsigned short USHORT
Definition: pedump.c:61
#define F(x, y, z)
Definition: md5.c:51
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
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: ke.h:294
struct _KTSS * TSS
Definition: ke.h:55
struct _KTHREAD * CurrentThread
Definition: ketypes.h:639
UINT64 SetMember
Definition: ketypes.h:651
USHORT IopmOffset
Definition: ketypes.h:2096
ULONG HardwareSegSs
Definition: ketypes.h:325
ULONG Edi
Definition: ketypes.h:316
ULONG EFlags
Definition: ketypes.h:458
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:421
USHORT SegCs
Definition: ketypes.h:454
USHORT SegEs
Definition: ketypes.h:439
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
USHORT SegFs
Definition: ketypes.h:440
USHORT SegGs
Definition: ketypes.h:441
USHORT SegDs
Definition: ketypes.h:438
ULONG Esi
Definition: ketypes.h:317
Definition: ketypes.h:844
KIIO_ACCESS_MAP IoMaps[IOPM_COUNT]
Definition: ketypes.h:878
USHORT IoMapBase
Definition: ketypes.h:877
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
UCHAR IoMap[8196]
Definition: ketypes.h:978
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
#define KiFillTrapFrameDebug(x)
Definition: trap_x.h:184
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
BOOLEAN NTAPI Ke386SetIoAccessMap(IN ULONG MapNumber, IN PKIO_ACCESS_MAP IopmBuffer)
Definition: v86vdm.c:736
PVOID Ki386IopmSaveArea
Definition: v86vdm.c:23
BOOLEAN FASTCALL KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:379
BOOLEAN FASTCALL KiVdmOpcodePUSHF(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:51
BOOLEAN FASTCALL KiVdmOpcodePrefix(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:442
BOOLEAN FASTCALL Ki386HandleOpcodeV86(IN PKTRAP_FRAME TrapFrame)
Definition: v86vdm.c:456
BOOLEAN FASTCALL KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:104
BOOLEAN KeI386VirtualIntExtensions
Definition: v86vdm.c:24
ULONG KeI386EFlagsAndMaskV86
Definition: v86vdm.c:21
VOID NTAPI Ke386SetIOPL(VOID)
Definition: v86vdm.c:581
BOOLEAN NTAPI Ke386IoSetAccessProcess(IN PKPROCESS Process, IN ULONG MapNumber)
Definition: v86vdm.c:709
BOOLEAN FASTCALL KiVdmOpcodeINTnn(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:178
BOOLEAN NTAPI Ke386QueryIoAccessMap(IN ULONG MapNumber, IN PKIO_ACCESS_MAP IopmBuffer)
Definition: v86vdm.c:762
ULONG KeI386EFlagsOrMaskV86
Definition: v86vdm.c:22
VOID FASTCALL KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned)
Definition: v86vdm.c:507
#define KiVdmGetPrefixFlags(x)
Definition: v86vdm.c:17
BOOLEAN FASTCALL KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:267
#define KiVdmGetInstructionSize(x)
Definition: v86vdm.c:16
NTSTATUS NTAPI Ke386CallBios(IN ULONG Int, OUT PCONTEXT Context)
Definition: v86vdm.c:614
ULONG_PTR FASTCALL KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
Definition: v86vdm.c:468
BOOLEAN FASTCALL KiVdmOpcodeCLI(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:341
const PULONG KiNtVdmState
Definition: v86vdm.c:25
BOOLEAN FASTCALL KiVdmOpcodeSTI(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:359
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char UCHAR
Definition: xmlstorage.h:181