branch update for HEAD-2003050101
[reactos.git] / ntoskrnl / ke / catch.c
index 96c671e..5909394 100644 (file)
@@ -28,6 +28,9 @@
 /* INCLUDES *****************************************************************/
 
 #include <ddk/ntddk.h>
+#ifndef LIBCAPTIVE
+#include <reactos/bugcodes.h>
+#endif /* LIBCAPTIVE */
 #include <roscfg.h>
 #include <internal/ke.h>
 #include <internal/ldr.h>
@@ -51,12 +54,16 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
                    BOOLEAN SearchFrames)
 {
   EXCEPTION_DISPOSITION Value;
+#ifndef LIBCAPTIVE
   CONTEXT TContext;
+#endif /* LIBCAPTIVE */
+  KD_CONTINUE_TYPE Action = kdContinue;
 
   DPRINT("KiDispatchException() called\n");
 
   /* PCR->KeExceptionDispatchCount++; */
 
+#ifndef LIBCAPTIVE
   if (Context == NULL)
     {
       TContext.ContextFlags = CONTEXT_FULL;
@@ -69,6 +76,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
 
       Context = &TContext;
     }
+#endif /* LIBCAPTIVE */
 
 #if 0
   if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) 
@@ -76,69 +84,71 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
       Context->Eip--;
     }
 #endif
-  if (PreviousMode == UserMode)
+      
+#ifndef LIBCAPTIVE
+  if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
     {
-      if (SearchFrames)
+      Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
+    }
+#ifdef KDBG
+  else if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_KDB)
+    {
+      Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
+    }
+#endif /* KDBG */
+#endif /* LIBCAPTIVE */
+  if (Action != kdHandleException)
+    {
+      if (PreviousMode == UserMode)
        {
-         PULONG Stack;
-         ULONG CDest;
-
-         /* FIXME: Give the kernel debugger a chance */
-
-         /* FIXME: Forward exception to user mode debugger */
+#ifdef LIBCAPTIVE
+         KeBugCheck (0);             
+#else /* !LIBCAPTIVE */
+         if (SearchFrames)
+           {
+             PULONG Stack;
+             ULONG CDest;
 
-         /* FIXME: Check user mode stack for enough space */
+             /* FIXME: Forward exception to user mode debugger */
 
+             /* FIXME: Check user mode stack for enough space */
          
-         /*
-          * Let usermode try and handle the exception
-          */
-         Tf->Esp = Tf->Esp - 
-           (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
-         Stack = (PULONG)Tf->Esp;
-         CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
-         /* Return address */
-         Stack[0] = 0;    
-         /* Pointer to EXCEPTION_RECORD structure */
-         Stack[1] = (ULONG)&Stack[3];   
-         /* Pointer to CONTEXT structure */
-         Stack[2] = (ULONG)&Stack[CDest];     
-         memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
-         memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
-
-         Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
-         return;
-       }
+             /*
+              * Let usermode try and handle the exception
+              */
+             Tf->Esp = Tf->Esp - 
+               (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
+             Stack = (PULONG)Tf->Esp;
+             CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
+             /* Return address */
+             Stack[0] = 0;    
+             /* Pointer to EXCEPTION_RECORD structure */
+             Stack[1] = (ULONG)&Stack[3];   
+             /* Pointer to CONTEXT structure */
+             Stack[2] = (ULONG)&Stack[CDest];     
+             memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
+             memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
+
+             Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
+             return;
+           }
       
-      /* FIXME: Forward the exception to the debugger */
+         /* FIXME: Forward the exception to the debugger */
 
-      /* FIXME: Forward the exception to the process exception port */
+         /* FIXME: Forward the exception to the process exception port */
 
-      /* Terminate the offending thread */
-      ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+         /* Terminate the offending thread */
+         DPRINT1("Unhandled UserMode exception, terminating thread\n");
+         ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
 
-      /* If that fails then bugcheck */
-      DbgPrint("Could not terminate thread\n");
-      KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
-    }
-  else
-    {
-      KD_CONTINUE_TYPE Action = kdContinue;
-
-      /* PreviousMode == KernelMode */
-      
-      if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
-       {
-         Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
-       }
-#ifdef KDBG
-      else if (KdDebuggerEnable && KdDebugState & KD_DEBUG_KDB)
-       {
-         Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
+         /* If that fails then bugcheck */
+         DPRINT1("Could not terminate thread\n");
+         KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
+#endif /* LIBCAPTIVE */
        }
-#endif /* KDBG */
-      if (Action != kdHandleException)
+      else
        {
+         /* PreviousMode == KernelMode */
          Value = RtlpDispatchException (ExceptionRecord, Context);
          
          DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
@@ -146,18 +156,29 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
           * If RtlpDispatchException() does not handle the exception then 
           * bugcheck 
           */
-         if (Value != ExceptionContinueExecution)
+         if (Value != ExceptionContinueExecution ||
+             0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
            {
-             KeBugCheck (KMODE_EXCEPTION_NOT_HANDLED);       
+#ifndef LIBCAPTIVE
+              KeBugCheckWithTf(KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf);         
+#else /* !LIBCAPTIVE */
+             KeBugCheck (0);         
+#endif /* LIBCAPTIVE */
            }
        }
-      else
-        {
-          KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
-        }
+    }
+  else
+    {
+#ifndef LIBCAPTIVE
+      KeContextToTrapFrame (Context, KeGetCurrentThread()->TrapFrame);
+#else /* !LIBCAPTIVE */
+      KeBugCheck(0);
+#endif /* LIBCAPTIVE */
     }
 }
 
+#ifndef LIBCAPTIVE
+
 VOID STDCALL
 ExRaiseAccessViolation (VOID)
 {
@@ -185,6 +206,7 @@ ExRaiseStatus (IN NTSTATUS Status)
   RtlRaiseException(&ExceptionRecord);
 }
 
+#endif /* LIBCAPTIVE */
 
 NTSTATUS STDCALL
 NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
@@ -194,7 +216,11 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
   KiDispatchException(ExceptionRecord,
                      Context,
                      PsGetCurrentThread()->Tcb.TrapFrame,
+#ifndef LIBCAPTIVE
                      ExGetPreviousMode(),
+#else /* !LIBCAPTIVE */
+                     KernelMode,
+#endif /* LIBCAPTIVE */
                      SearchFrames);
   return(STATUS_SUCCESS);
 }
@@ -203,7 +229,19 @@ NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
 VOID STDCALL
 RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
 {
+#ifndef LIBCAPTIVE
   ZwRaiseException(ExceptionRecord, NULL, TRUE);
+#else /* !LIBCAPTIVE */
+CONTEXT *LocalContext;
+
+  /* Do not use local variable to benefit from ElectricFence boundary checks */
+  LocalContext=ExAllocatePool(PagedPool,sizeof(LocalContext->ContextFlags));
+  LocalContext->ContextFlags=0;
+
+  NtRaiseException(ExceptionRecord, LocalContext, TRUE);
+
+  ExFreePool(LocalContext);
+#endif /* LIBCAPTIVE */
 }
 
 /* EOF */