ReactOS 0.4.16-dev-979-g79f281e
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 /* 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}
272
276 IN ULONG Flags)
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}
352
356 IN ULONG Flags)
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}
370
374 IN ULONG Flags)
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}
388
389/* MASTER OPCODE HANDLER ******************************************************/
390
394 IN ULONG Flags)
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}
451
452/* PREFIX HANDLER *************************************************************/
453
457 IN ULONG Flags)
458{
459 /* Increase instruction size */
460 Flags++;
461
462 /* Handle the next opcode */
463 return KiVdmHandleOpcode(TrapFrame, Flags);
464}
465
466/* TRAP HANDLER ***************************************************************/
467
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}
479
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}
518
519VOID
521KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned)
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}
592
593VOID
594NTAPI
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}
620
621/* PUBLIC FUNCTIONS ***********************************************************/
622
623/*
624 * @implemented
625 */
627NTAPI
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}
717
718/*
719 * @implemented
720 */
722NTAPI
724 IN ULONG MapNumber)
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}
744
745/*
746 * @implemented
747 */
749NTAPI
751 IN PKIO_ACCESS_MAP IopmBuffer)
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}
770
771/*
772 * @implemented
773 */
775NTAPI
777 IN PKIO_ACCESS_MAP IopmBuffer)
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}
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:1688
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:352
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:350
#define EFLAGS_NESTED_TASK
Definition: ketypes.h:194
#define EFLAGS_USER_SANITIZE
Definition: ketypes.h:202
#define EFLAGS_V86_MASK
Definition: ketypes.h:197
#define IOPM_OFFSET
Definition: ketypes.h:351
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1182
#define EFLAGS_VIP
Definition: ketypes.h:200
#define EFLAGS_VIF
Definition: ketypes.h:199
#define RPL_MASK
Definition: ketypes.h:119
#define EFLAGS_ALIGN_CHECK
Definition: ketypes.h:198
#define EFLAGS_IOPL
Definition: ketypes.h:193
#define FIXED_NTVDMSTATE_LINEAR_PC_AT
Definition: asm.h:647
#define NPX_FRAME_LENGTH
Definition: asm.h:247
#define UserMode
Definition: asm.h:39
#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:224
#define PFX_FLAG_FS
Definition: ke.h:191
BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:313
#define PFX_FLAG_ADDR32
Definition: ke.h:194
#define PFX_FLAG_REP
Definition: ke.h:197
#define KiVdmClearVdmEFlags(x)
Definition: ke.h:222
#define KiVdmSetVdmEFlags(x)
Definition: ke.h:221
#define PFX_FLAG_GS
Definition: ke.h:192
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
#define KiCallVdmHandler(x)
Definition: ke.h:223
#define KiVdmUnhandledOpcode(x)
Definition: ke.h:225
#define PFX_FLAG_SS
Definition: ke.h:189
#define PFX_FLAG_ES
Definition: ke.h:187
FORCEINLINE VOID KiSetTebBase(PKPCR Pcr, PNT_TIB TebAddress)
Definition: ke.h:428
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:741
#define PFX_FLAG_OPER32
Definition: ke.h:193
#define PFX_FLAG_REPNE
Definition: ke.h:196
#define PFX_FLAG_DS
Definition: ke.h:190
struct _KV8086_STACK_FRAME * PKV8086_STACK_FRAME
VOID FASTCALL Ki386BiosCallReturnAddress(IN PKTRAP_FRAME TrapFrame)
#define PFX_FLAG_LOCK
Definition: ke.h:195
#define PFX_FLAG_CS
Definition: ke.h:188
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:659
UINT64 SetMember
Definition: ketypes.h:671
USHORT IopmOffset
Definition: ketypes.h:2096
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
Definition: ketypes.h:850
KIIO_ACCESS_MAP IoMaps[IOPM_COUNT]
Definition: ketypes.h:884
USHORT IoMapBase
Definition: ketypes.h:883
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
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
#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:750
PVOID Ki386IopmSaveArea
Definition: v86vdm.c:23
BOOLEAN FASTCALL KiVdmHandleOpcode(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:393
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:456
BOOLEAN FASTCALL Ki386HandleOpcodeV86(IN PKTRAP_FRAME TrapFrame)
Definition: v86vdm.c:470
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:595
BOOLEAN NTAPI Ke386IoSetAccessProcess(IN PKPROCESS Process, IN ULONG MapNumber)
Definition: v86vdm.c:723
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:776
ULONG KeI386EFlagsOrMaskV86
Definition: v86vdm.c:22
VOID FASTCALL KiEnterV86Mode(IN ULONG_PTR StackFrameUnaligned)
Definition: v86vdm.c:521
#define KiVdmGetPrefixFlags(x)
Definition: v86vdm.c:17
BOOLEAN FASTCALL KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:275
#define KiVdmGetInstructionSize(x)
Definition: v86vdm.c:16
NTSTATUS NTAPI Ke386CallBios(IN ULONG Int, OUT PCONTEXT Context)
Definition: v86vdm.c:628
ULONG_PTR FASTCALL KiExitV86Mode(IN PKTRAP_FRAME TrapFrame)
Definition: v86vdm.c:482
BOOLEAN FASTCALL KiVdmOpcodeCLI(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:355
const PULONG KiNtVdmState
Definition: v86vdm.c:25
BOOLEAN FASTCALL KiVdmOpcodeSTI(IN PKTRAP_FRAME TrapFrame, IN ULONG Flags)
Definition: v86vdm.c:373
_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