예제 #1
0
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;
}
예제 #2
0
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;
    }

}