Exemple #1
0
NTSTATUS
NTAPI
KiContinue(IN PCONTEXT Context,
           IN PKEXCEPTION_FRAME ExceptionFrame,
           IN PKTRAP_FRAME TrapFrame)
{
    NTSTATUS Status = STATUS_SUCCESS;
    KIRQL OldIrql = APC_LEVEL;
    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();

    /* Raise to APC_LEVEL, only if needed */
    if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);

    /* Set up SEH to validate the context */
    _SEH2_TRY
    {
        /* Check the previous mode */
        if (PreviousMode != KernelMode)
        {
            /* Validate from user-mode */
            KiContinuePreviousModeUser(Context,
                                       ExceptionFrame,
                                       TrapFrame);
        }
        else
        {
            /* Convert the context into Exception/Trap Frames */
            KeContextToTrapFrame(Context,
                                 ExceptionFrame,
                                 TrapFrame,
                                 Context->ContextFlags,
                                 KernelMode);
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Save the exception code */
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    /* Lower the IRQL if needed */
    if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);

    /* Return status */
    return Status;
}
Exemple #2
0
NTSTATUS
KiContinueEx (
    IN PCONTEXT ContextRecord,
    IN BOOLEAN TestAlert,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )

/*++

Routine Description:

    This function is called to copy the specified context frame to the
    specified exception and trap frames for the continue system service.

    N.B. If the previous mode is user mode, alerts are being tested, a user
         APC is available to execute, and the specified context record was
         previously placed on the stack by the user APC initialization routine,
         then bypass context record copy to the kernel frames and back again.

Arguments:

    ContextRecord - Supplies a pointer to a context record.

    TestAlert - Supplies a boolean value that determines whether a test alert
       is to be performed.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

Return Value:

    STATUS_ACCESS_VIOLATION is returned if the context record is not readable
        from user mode.

    STATUS_DATATYPE_MISALIGNMENT is returned if the context record is not
        properly aligned.

    STATUS_SUCCESS + 1 is returned if the context frame is copied successfully
        to the specified exception and trap frames.

    STATUS_SUCCESS is returned if the context record copy was bypassed and
        another user APC is ready to be delivered.

--*/

{

    KIRQL OldIrql;
    NTSTATUS Status;
    PKTHREAD Thread;
    ULONG64 UserStack;

    //
    // Synchronize with other context operations.
    //
    // If the current IRQL is less than APC_LEVEL, then raise IRQL to APC level.
    // 

    OldIrql = KeGetCurrentIrql();
    if (OldIrql < APC_LEVEL) {
        KfRaiseIrql(APC_LEVEL);
    }

    //
    // If the previous mode was not kernel mode, then attempt to bypass
    // the copy of the context record. Otherwise, copy context to kernel
    // frames directly.
    // 
      
    Status = STATUS_SUCCESS + 1;
    Thread = KeGetCurrentThread();
    if (Thread->PreviousMode != KernelMode) {
        try {
            if (TestAlert != FALSE) {
                ProbeForWriteSmallStructure(ContextRecord,
                                            sizeof(CONTEXT),
                                            CONTEXT_ALIGN);

                KeTestAlertThread(UserMode);
                UserStack = (ContextRecord->Rsp  - sizeof(MACHINE_FRAME)) & ~STACK_ROUND;
                if (((UserStack - sizeof(CONTEXT)) == (ULONG64)ContextRecord) &&
                    (Thread->ApcState.UserApcPending != FALSE)) {

                    //
                    // Save the context record and exception frame addresses
                    // in the trap frame and deliver the user APC bypassing
                    // the context copy.
                    //

                    TrapFrame->ContextRecord = (ULONG64)ContextRecord;
                    TrapFrame->ExceptionFrame = (ULONG64)ExceptionFrame;
                    KiDeliverApc(UserMode, NULL, TrapFrame);
                    Status = STATUS_SUCCESS;
                    leave;
                }

            } else {
                ProbeForReadSmallStructure(ContextRecord,
                                           sizeof(CONTEXT),
                                           CONTEXT_ALIGN);
            }

            KiContinuePreviousModeUser(ContextRecord,
                                       ExceptionFrame,
                                       TrapFrame);

        } except(EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
        }

    } else {
Exemple #3
0
NTSTATUS
KiContinue (
    IN PCONTEXT ContextRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )

/*++

Routine Description:

    This function is called to copy the specified context frame to the
    specified exception and trap frames for the continue system service.

Arguments:

    ContextRecord - Supplies a pointer to a context record.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

Return Value:

    STATUS_ACCESS_VIOLATION is returned if the context record is not readable
        from user mode.

    STATUS_DATATYPE_MISALIGNMENT is returned if the context record is not
        properly aligned.

    STATUS_SUCCESS is returned if the context frame is copied successfully
        to the specified exception and trap frames.

--*/

{

    KIRQL OldIrql;
    NTSTATUS Status;

    //
    // Synchronize with other context operations.
    //
    // If the current IRQL is less than APC_LEVEL, then raise IRQL to APC level.
    // 

    OldIrql = KeGetCurrentIrql();
    if (OldIrql < APC_LEVEL) {
        KfRaiseIrql(APC_LEVEL);
    }

    //
    // If the previous mode was not kernel mode, then use wrapper function
    // to copy context to kernel frames. Otherwise, copy context to kernel
    // frames directly.
    // 
      
    Status = STATUS_SUCCESS;
    if (KeGetPreviousMode() != KernelMode) {
        try {
            KiContinuePreviousModeUser(ContextRecord,
                                       ExceptionFrame,
                                       TrapFrame);

        } except(EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
        }

    } else {