[NTOS]
[reactos.git] / reactos / ntoskrnl / ke / i386 / v86vdm.c
index 2d1ff01..503f413 100644 (file)
@@ -70,23 +70,23 @@ KiVdmOpcodePUSHF(IN PKTRAP_FRAME TrapFrame,
     
     /* 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 */
@@ -103,20 +103,22 @@ KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame,
     /* 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;
@@ -137,7 +139,7 @@ KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame,
     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);
@@ -311,6 +313,7 @@ KiVdmOpcodeIRET(IN PKTRAP_FRAME TrapFrame,
     else
     {
         /* FIXME: Check for VDM interrupts */
+       DPRINT("FIXME: Check for VDM interrupts\n");
     }
     
     /* We're done */
@@ -659,37 +662,87 @@ Ke386CallBios(IN ULONG Int,
 }
 
 /*
- * @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;
 }