BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame) { PUCHAR Eip; PVDM_TIB VdmTib; /* Check if this is from V86 mode */ if (TrapFrame->EFlags & EFLAGS_V86_MASK) { /* Calculate flat EIP */ Eip = (PUCHAR)((TrapFrame->Eip & 0xFFFF) + ((TrapFrame->SegCs & 0xFFFF) << 4)); /* Check if this is a BOP */ if (*(PUSHORT)Eip == 0xC4C4) { /* Check sure its the DOS Bop */ if (Eip[2] == 0x50) { /* FIXME: No VDM Support */ ASSERT(FALSE); } /* Increase the number of BOP operations */ VdmBopCount++; /* Get the TIB */ VdmTib = NtCurrentTeb()->Vdm; /* Fill out a VDM Event */ VdmTib->EventInfo.InstructionSize = 3; VdmTib->EventInfo.BopNumber = Eip[2]; VdmTib->EventInfo.Event = VdmBop; /* End VDM Execution */ VdmEndExecution(TrapFrame, VdmTib); } else { /* Not a BOP */ return FALSE; } } else { /* FIXME: Shouldn't happen on ROS */ ASSERT(FALSE); } /* Return success */ return TRUE; }
BOOLEAN VdmDispatchPageFault( PKTRAP_FRAME TrapFrame, ULONG Mode, ULONG FaultAddr ) /*++ Routine Description: This routine dispatches a v86 mode page fault to the VDM monitor. It verifies that the fault occurred below 1MB. Arguments: TrapFrame Mode - 0 - if read 1 - if write FaultAddr - faulting address Return Value: True if successfull, False otherwise --*/ { PVDM_TIB VdmTib; NTSTATUS Status = STATUS_SUCCESS; KIRQL OldIrql; PAGED_CODE(); // // Raise Irql to APC level... // KeRaiseIrql(APC_LEVEL, &OldIrql); // // VdmTib is in user mode memory // try { // // Get a pointer to the VdmTib // VdmTib = NtCurrentTeb()->Vdm; if ((TrapFrame->EFlags & EFLAGS_V86_MASK) || (TrapFrame->SegCs != (KGDT_R3_CODE | RPL_MASK))) { // // If the faulting address is above 1MB return failure // if (FaultAddr < 0x100000) { VdmTib->EventInfo.Event = VdmMemAccess; VdmTib->EventInfo.InstructionSize = 0; VdmTib->EventInfo.FaultInfo.FaultAddr = FaultAddr; VdmTib->EventInfo.FaultInfo.RWMode = Mode; VdmEndExecution(TrapFrame, VdmTib); } else { Status = STATUS_ILLEGAL_INSTRUCTION; } } } except(EXCEPTION_EXECUTE_HANDLER) { Status = GetExceptionCode(); } KeLowerIrql(OldIrql); if (!NT_SUCCESS(Status)) { return FALSE; } else { return TRUE; } }