/* Build flat ESP */
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
- Esp -= 2;
/* Check for OPER32 */
if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
{
/* Save EFlags */
- Esp -= 2;
- *(PULONG)(Esp - 2) = V86EFlags;
+ Esp -= 4;
+ *(PULONG)Esp = V86EFlags;
}
else
{
/* Save EFLags */
+ Esp -= 2;
*(PUSHORT)Esp = (USHORT)V86EFlags;
}
/* Set new ESP and EIP */
- TrapFrame->HardwareEsp = (USHORT)Esp;
+ TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
/* We're done */
/* Build flat ESP */
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
- /* Read EFlags */
- EFlags = *(PULONG)Esp;
- Esp += 4;
-
/* Check for OPER32 */
- if (!(KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32))
+ if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
{
- /* Read correct flags and use correct stack address */
- Esp -= 2;
- EFlags &= 0xFFFF;
+ /* Read EFlags */
+ EFlags = *(PULONG)Esp;
+ Esp += 4;
+ }
+ else
+ {
+ /* Read EFlags */
+ EFlags = *(PUSHORT)Esp;
+ Esp += 2;
}
/* Set new ESP */
- TrapFrame->HardwareEsp = Esp;
+ TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
/* Mask out IOPL from the flags */
EFlags &= ~EFLAGS_IOPL;
V86EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK;
/* Update EFlags in trap frame */
- TrapFrame->EFlags |= V86EFlags;
+ TrapFrame->EFlags = V86EFlags;
/* Check if ESP0 needs to be fixed up */
if (TrapEFlags & EFLAGS_V86_MASK) Ki386AdjustEsp0(TrapFrame);
else
{
/* FIXME: Check for VDM interrupts */
+ DPRINT("FIXME: Check for VDM interrupts\n");
}
/* We're done */
}
/*
- * @unimplemented
+ * @implemented
*/
BOOLEAN
NTAPI
Ke386IoSetAccessProcess(IN PKPROCESS Process,
- IN ULONG Flag)
+ IN ULONG MapNumber)
{
- UNIMPLEMENTED;
- return FALSE;
+ USHORT MapOffset;
+ PKPRCB Prcb;
+ KAFFINITY TargetProcessors;
+
+ if(MapNumber > IOPM_COUNT)
+ return FALSE;
+
+ MapOffset = KiComputeIopmOffset(MapNumber);
+
+ Process->IopmOffset = MapOffset;
+
+ TargetProcessors = Process->ActiveProcessors;
+ Prcb = KeGetCurrentPrcb();
+ if (TargetProcessors & Prcb->SetMember)
+ KeGetPcr()->TSS->IoMapBase = MapOffset;
+
+ return TRUE;
}
/*
- * @unimplemented
+ * @implemented
*/
BOOLEAN
NTAPI
-Ke386SetIoAccessMap(IN ULONG Flag,
- IN PVOID IopmBuffer)
+Ke386SetIoAccessMap(IN ULONG MapNumber,
+ IN PKIO_ACCESS_MAP IopmBuffer)
{
- UNIMPLEMENTED;
- return FALSE;
+ PKPROCESS CurrentProcess;
+ PKPRCB Prcb;
+ PVOID pt;
+
+ if ((MapNumber > IOPM_COUNT) || (MapNumber == IO_ACCESS_MAP_NONE))
+ return FALSE;
+
+ Prcb = KeGetCurrentPrcb();
+
+ // Copy the IOP map and load the map for the current process.
+ pt = &(KeGetPcr()->TSS->IoMaps[MapNumber-1].IoMap);
+ RtlMoveMemory(pt, (PVOID)IopmBuffer, IOPM_SIZE);
+ CurrentProcess = Prcb->CurrentThread->ApcState.Process;
+ KeGetPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset;
+
+ return TRUE;
}
/*
- * @unimplemented
+ * @implemented
*/
BOOLEAN
NTAPI
-Ke386QueryIoAccessMap(IN ULONG Flag,
- IN PVOID IopmBuffer)
+Ke386QueryIoAccessMap(IN ULONG MapNumber,
+ IN PKIO_ACCESS_MAP IopmBuffer)
{
- UNIMPLEMENTED;
- return FALSE;
+ ULONG i;
+ PVOID Map;
+ PUCHAR p;
+
+ if (MapNumber > IOPM_COUNT)
+ return FALSE;
+
+ if (MapNumber == IO_ACCESS_MAP_NONE)
+ {
+ // no access, simply return a map of all 1s
+ p = (PUCHAR)IopmBuffer;
+ for (i = 0; i < IOPM_SIZE; i++) {
+ p[i] = (UCHAR)-1;
+ }
+ }
+ else
+ {
+ // copy the bits
+ Map = (PVOID)&(KeGetPcr()->TSS->IoMaps[MapNumber-1].IoMap);
+ RtlMoveMemory((PVOID)IopmBuffer, Map, IOPM_SIZE);
+ }
+
+ return TRUE;
}