Commit in reactos on MAIN
lib/ntdll/rtl/i386/except.s+2911.4 -> 1.5
                  /exception.c+4461.8 -> 1.9
ntoskrnl/rtl/i386/except.s+2911.3 -> 1.4
+1028
3 modified files
re-added files that hyperion accidently deleted from HEAD

reactos/lib/ntdll/rtl/i386
except.s 1.4 -> 1.5
diff -N except.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ except.s	25 Jun 2004 16:39:41 -0000	1.5
@@ -0,0 +1,291 @@
+/* $Id: except.s,v 1.5 2004/06/25 16:39:41 weiden Exp $
+ *
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS kernel
+ * PURPOSE:           User-mode exception support for IA-32
+ * FILE:              lib/ntdll/rtl/i386/except.s
+ * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES:             This file is shared with ntoskrnl/rtl/i386/except.s.
+ *                    Please keep them in sync.
+ */
+
+#define EXCEPTION_UNWINDING		0x02
+
+#define EREC_FLAGS				0x04
+
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch    1
+#define ExceptionNestedException   2
+#define ExceptionCollidedUnwind    3
+
+.globl _RtlpExecuteHandlerForException
+.globl _RtlpExecuteHandlerForUnwind
+
+#define CONTEXT_FLAGS	0x00
+#define CONTEXT_SEGGS	0x8C
+#define CONTEXT_SEGFS	0x90
+#define CONTEXT_SEGES	0x94
+#define CONTEXT_SEGDS	0x98
+#define CONTEXT_EDI		0x9C
+#define CONTEXT_ESI		0xA0
+#define CONTEXT_EBX		0xA4
+#define CONTEXT_EDX		0xA8
+#define CONTEXT_ECX		0xAC
+#define CONTEXT_EAX		0xB0
+#define CONTEXT_EBP		0xB4
+#define CONTEXT_EIP		0xB8
+#define CONTEXT_SEGCS	0xBC
+#define CONTEXT_EFLAGS	0xC0
+#define CONTEXT_ESP		0xC4
+#define CONTEXT_SEGSS	0xC8
+
+
+#define RCC_CONTEXT		0x08
+
+// EAX = value to print
+_do_debug:
+	pushal
+	pushl	%eax
+	call	_AsmDebug@4
+	popal
+	ret
+
+#ifndef __NTOSKRNL__
+
+//
+// VOID
+// RtlpCaptureContext(PCONTEXT pContext);
+//
+// Parameters:
+//   [ESP+08h] - PCONTEXT_X86 pContext
+// Registers:
+//   None
+// Returns:
+//   Nothing
+// Notes:
+//   Grabs the current CPU context.
+.globl _RtlpCaptureContext
+_RtlpCaptureContext:
+	pushl   %ebp
+    movl	%esp, %ebp
+	movl	RCC_CONTEXT(%ebp), %edx		// EDX = Address of context structure
+
+	cld
+	pushf
+	pop		%eax
+	movl	%eax, CONTEXT_EFLAGS(%edx)
+	xorl	%eax, %eax
+	movl	%eax, CONTEXT_EAX(%edx)
+	movl	%eax, CONTEXT_EBX(%edx)
+	movl	%eax, CONTEXT_ECX(%edx)
+	movl	%eax, CONTEXT_EDX(%edx)
+	movl	%eax, CONTEXT_ESI(%edx)
+	movl	%eax, CONTEXT_EDI(%edx)
+	movl	%cs, %eax
+	movl	%eax, CONTEXT_SEGCS(%edx)
+	movl	%ds, %eax
+	movl	%eax, CONTEXT_SEGDS(%edx)
+	movl	%es, %eax
+	movl	%eax, CONTEXT_SEGES(%edx)
+	movl	%fs, %eax
+	movl	%eax, CONTEXT_SEGFS(%edx)
+	movl	%gs, %eax
+	movl	%eax, CONTEXT_SEGGS(%edx)
+	movl	%ss, %eax
+	movl	%eax, CONTEXT_SEGSS(%edx)
+
+	//
+	// STACK LAYOUT: - (ESP to put in context structure)
+	//               - RETURN ADDRESS OF CALLER OF CALLER
+	//               - EBP OF CALLER OF CALLER
+	//                 ...
+	//               - RETURN ADDRESS OF CALLER
+	//               - EBP OF CALLER
+	//                 ...
+	//
+
+	// Get return address of the caller of the caller of this function
+	movl	%ebp, %ebx
+	//movl	4(%ebx), %eax			// EAX = return address of caller
+	movl	(%ebx), %ebx			// EBX = EBP of caller
+
+	movl	4(%ebx), %eax			// EAX = return address of caller of caller
+	movl	(%ebx), %ebx			// EBX = EBP of caller of caller
+
+	movl	%eax, CONTEXT_EIP(%edx)	// EIP = return address of caller of caller
+	movl	%ebx, CONTEXT_EBP(%edx)	// EBP = EBP of caller of caller
+	addl	$8, %ebx
+	movl	%ebx, CONTEXT_ESP(%edx)	// ESP = EBP of caller of caller + 8
+
+    movl	%ebp, %esp
+    popl	%ebp
+    ret
+
+#endif /* !__NTOSKRNL__ */
+
+#define REH_ERECORD		0x08
+#define REH_RFRAME		0x0C
+#define REH_CONTEXT		0x10
+#define REH_DCONTEXT	0x14
+#define REH_EROUTINE	0x18
+
+// Parameters:
+//   None
+// Registers:
+//   [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
+//   [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [EBP+10h] - PVOID Context
+//   [EBP+14h] - PVOID DispatcherContext
+//   [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
+//   EDX       - Address of protecting exception handler
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//   Setup the protecting exception handler and call the exception
+//   handler in the right context.
+_RtlpExecuteHandler:
+	pushl    %ebp
+    movl     %esp, %ebp
+    pushl    REH_RFRAME(%ebp)
+
+    pushl    %edx
+    pushl    %fs:0x0
+    movl     %esp, %fs:0x0
+
+    // Prepare to call the exception handler
+    pushl    REH_DCONTEXT(%ebp)
+    pushl    REH_CONTEXT(%ebp)
+    pushl    REH_RFRAME(%ebp)
+    pushl    REH_ERECORD(%ebp)
+
+    // Now call the exception handler
+    movl     REH_EROUTINE(%ebp), %eax
+    call    *%eax
+
+	cmpl	$-1, %fs:0x0
+	jne		.reh_stack_looks_ok
+
+	// This should not happen
+	pushl	0
+	pushl	0
+	pushl	0
+	pushl	0
+	call	_RtlAssert@16
+
+.reh_loop:
+	jmp	.reh_loop
+
+.reh_stack_looks_ok:
+    movl     %fs:0x0, %esp
+
+    // Return to the 'front-end' for this function
+    popl     %fs:0x0
+    movl     %ebp, %esp
+    popl     %ebp
+    ret
+
+
+#define REP_ERECORD     0x04
+#define REP_RFRAME      0x08
+#define REP_CONTEXT     0x0C
+#define REP_DCONTEXT    0x10
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//    This exception handler protects the exception handling
+//    mechanism by detecting nested exceptions.
+_RtlpExceptionProtector:
+    movl     $ExceptionContinueSearch, %eax
+    movl     REP_ERECORD(%esp), %ecx
+    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
+    jnz      .rep_end
+
+    // Unwinding is not taking place, so return ExceptionNestedException
+
+    // Set DispatcherContext field to the exception registration for the
+    // exception handler that executed when a nested exception occurred
+    movl     REP_DCONTEXT(%esp), %ecx
+    movl     REP_RFRAME(%esp), %eax
+    movl     %eax, (%ecx)
+    movl     $ExceptionNestedException, %eax
+
+.rep_end:
+    ret
+
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//   Front-end
+_RtlpExecuteHandlerForException:
+    movl     $_RtlpExceptionProtector, %edx
+    jmp      _RtlpExecuteHandler
+
+
+#define RUP_ERECORD     0x04
+#define RUP_RFRAME      0x08
+#define RUP_CONTEXT     0x0C
+#define RUP_DCONTEXT    0x10
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//    This exception handler protects the exception handling
+//    mechanism by detecting collided unwinds.
+_RtlpUnwindProtector:
+    movl     $ExceptionContinueSearch, %eax
+    movl     %ecx, RUP_ERECORD(%esp)
+    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
+    jz       .rup_end
+
+    // Unwinding is taking place, so return ExceptionCollidedUnwind
+
+    movl     RUP_RFRAME(%esp), %ecx
+    movl     RUP_DCONTEXT(%esp), %edx
+
+    // Set DispatcherContext field to the exception registration for the
+    // exception handler that executed when a collision occurred
+    movl     RUP_RFRAME(%ecx), %eax
+    movl     %eax, (%edx)
+    movl     $ExceptionCollidedUnwind, %eax
+
+.rup_end:
+    ret
+
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+_RtlpExecuteHandlerForUnwind:
+    movl     $_RtlpUnwindProtector, %edx
+    jmp      _RtlpExecuteHandler

reactos/lib/ntdll/rtl/i386
exception.c 1.8 -> 1.9
diff -N exception.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ exception.c	25 Jun 2004 16:39:41 -0000	1.9
@@ -0,0 +1,446 @@
+/* $Id: exception.c,v 1.9 2004/06/25 16:39:41 weiden Exp $
+ *
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS kernel
+ * PURPOSE:           User-mode exception support for IA-32
+ * FILE:              lib/ntdll/rtl/i386/exception.c
+ * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <windows.h>
+#include <string.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+/* Implemented in except.s */
+
+VOID
+RtlpCaptureContext(PCONTEXT pContext);
+
+/* Macros that will help streamline the SEH implementations for
+   kernel mode and user mode */
+
+#define SehpGetStackLimits(StackBase, StackLimit) \
+{ \
+	(*(StackBase)) = NtCurrentTeb()->Tib->StackBase; \
+	(*(StackLimit)) = NtCurrentTeb()->Tib->StackLimit; \
+}
+
+#define SehpGetExceptionList() \
+	(PEXCEPTION_REGISTRATION)(NtCurrentTeb()->Tib.ExceptionList)
+
+#define SehpSetExceptionList(NewExceptionList) \
+	NtCurrentTeb()->Tib.ExceptionList = (PVOID)(NewExceptionList)
+
+#define SehpCaptureContext(Context) \
+{ \
+	RtlpCaptureContext(Context); \
+}
+
+#define SehpContinue(Context, TestAlert) \
+	NtContinue(Context, TestAlert)
+
+/*** Code below this line is shared with ntoskrnl/rtl/i386/exception.c - please keep in sync ***/
+
+VOID STDCALL
+AsmDebug(ULONG Value)
+{
+  DbgPrint("Value 0x%.08x\n", Value);
+}
+
+
+/* Declare a few prototypes for the functions in except.s */
+
+EXCEPTION_DISPOSITION
+RtlpExecuteHandlerForException(
+  PEXCEPTION_RECORD ExceptionRecord,
+  PEXCEPTION_REGISTRATION RegistrationFrame,
+  PCONTEXT Context,
+  PVOID DispatcherContext,
+  PEXCEPTION_HANDLER ExceptionHandler);
+
+EXCEPTION_DISPOSITION
+RtlpExecuteHandlerForUnwind(
+  PEXCEPTION_RECORD ExceptionRecord,
+  PEXCEPTION_REGISTRATION RegistrationFrame,
+  PCONTEXT Context,
+  PVOID DispatcherContext,
+  PEXCEPTION_HANDLER ExceptionHandler);
+
+
+#ifndef NDEBUG
+
+VOID RtlpDumpExceptionRegistrations(VOID)
+{
+  PEXCEPTION_REGISTRATION Current;
+
+  DbgPrint("Dumping exception registrations:\n");
+
+  Current = SehpGetExceptionList();
+
+  if ((ULONG_PTR)Current != -1)
+  {
+    while ((ULONG_PTR)Current != -1)
+    {
+      DbgPrint("   (0x%08X)   HANDLER (0x%08X)\n", Current, Current->handler);
+      Current = Current->prev;
+    }
+    DbgPrint("   End-Of-List\n");
+  } else {
+    DbgPrint("   No exception registrations exists.\n");
+  }
+}
+
+#endif /* NDEBUG */
+
+ULONG
+RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
+	IN PCONTEXT  Context)
+{
+  PEXCEPTION_REGISTRATION RegistrationFrame;
+  DWORD DispatcherContext;
+  DWORD ReturnValue;
+
+  DPRINT("RtlpDispatchException()\n");
+
+#ifndef NDEBUG
+  RtlpDumpExceptionRegistrations();
+#endif /* NDEBUG */
+
+  RegistrationFrame = SehpGetExceptionList();
+ 
+  DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame);
+
+  while ((ULONG_PTR)RegistrationFrame != -1)
+  {
+    EXCEPTION_RECORD ExceptionRecord2;
+    DWORD Temp = 0;
+    //PVOID RegistrationFrameEnd = (PVOID)RegistrationFrame + 8;
+
+    // Make sure the registration frame is located within the stack
+
+    DPRINT("Error checking\n");
+#if 0
+    if (Teb->Tib.StackBase > RegistrationFrameEnd)
+    {
+      DPRINT("Teb->Tib.StackBase (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
+        Teb->Tib.StackBase, RegistrationFrameEnd);
+      ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
+      return ExceptionContinueExecution;
+    }
+    // FIXME: Stack top, correct?
+    if (Teb->Tib.StackLimit < RegistrationFrameEnd)
+    {
+      DPRINT("Teb->Tib.StackLimit (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
+        Teb->Tib.StackLimit, RegistrationFrameEnd);
+      ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
+      return ExceptionContinueExecution;
+    }
+ 
+    // Make sure stack is DWORD aligned
+    if ((ULONG_PTR)RegistrationFrame & 3)
+    {
+      DPRINT("RegistrationFrameEnd (0x%.08x) is not DWORD aligned.\n",
+        RegistrationFrameEnd);
+      ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
+      return ExceptionContinueExecution;
+    }
+#endif
+
+#if 0
+    /* FIXME: */
+    if (someFlag)
+      RtlpLogLastExceptionDisposition( hLog, retValue );
+#endif
+
+    DPRINT("Calling handler at 0x%X\n", RegistrationFrame->handler);
+    DPRINT("ExceptionRecord 0x%X\n", ExceptionRecord);
+    DPRINT("RegistrationFrame 0x%X\n", RegistrationFrame);
+    DPRINT("Context 0x%X\n", Context);
+    DPRINT("&DispatcherContext 0x%X\n", &DispatcherContext);
+
+    ReturnValue = RtlpExecuteHandlerForException(
+      ExceptionRecord,
+      RegistrationFrame,
+      Context,
+      &DispatcherContext,
+      RegistrationFrame->handler);
+#ifdef DEBUG
+    DPRINT("Exception handler said 0x%X\n", ReturnValue);
+	DPRINT("RegistrationFrame == 0x%.08x\n", RegistrationFrame);
+	{
+		PULONG sp = (PULONG)((PVOID)RegistrationFrame - 0x08);
+		DPRINT("StandardESP == 0x%.08x\n", sp[0]);
+		DPRINT("Exception Pointers == 0x%.08x\n", sp[1]);
+		DPRINT("PrevFrame == 0x%.08x\n", sp[2]);
+		DPRINT("Handler == 0x%.08x\n", sp[3]);
+		DPRINT("ScopeTable == 0x%.08x\n", sp[4]);
+		DPRINT("TryLevel == 0x%.08x\n", sp[5]);
+		DPRINT("EBP == 0x%.08x\n", sp[6]);
+	}
+#endif
+    if (RegistrationFrame == NULL)
+    {
+      ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL;  // Turn off flag
+    }
+
+    if (ReturnValue == ExceptionContinueExecution)
+    {
+      DPRINT("ReturnValue == ExceptionContinueExecution\n");
+      if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
+      {
+        DPRINT("(ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == TRUE\n");
+
+        ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+        ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
+        ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+        ExceptionRecord2.NumberParameters = 0;
+        RtlRaiseException(&ExceptionRecord2);
+      }
+      else
+      {
+        /* Copy the (possibly changed) context back to the trap frame and return */
+        SehpContinue(Context, FALSE);
+        return ExceptionContinueExecution;
+      }
+    }
+    else if (ReturnValue == ExceptionContinueSearch)
+    {
+      DPRINT("ReturnValue == ExceptionContinueSearch\n");
+
+      /* Nothing to do here */
+    }
+    else if (ReturnValue == ExceptionNestedException)
+    {
+      DPRINT("ReturnValue == ExceptionNestedException\n");
+
+      ExceptionRecord->ExceptionFlags |= EXCEPTION_EXIT_UNWIND;
+      if (DispatcherContext > Temp)
+	  {
+          Temp = DispatcherContext;
+	  }
+    }
+    else /* if (ReturnValue == ExceptionCollidedUnwind) */
+    {
+      DPRINT("ReturnValue == ExceptionCollidedUnwind or unknown\n");
+
+      ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+      ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
+      ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+      ExceptionRecord2.NumberParameters = 0;
+      RtlRaiseException(&ExceptionRecord2);
+    }
+
+    RegistrationFrame = RegistrationFrame->prev;  // Go to previous frame
+  }
+ 
+  /* No exception handler will handle this exception */
+
+  DPRINT("RtlpDispatchException(): Return ExceptionContinueExecution\n");
+
+  return ExceptionContinueExecution;  
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+RtlRaiseStatus(NTSTATUS Status)
+{
+  EXCEPTION_RECORD ExceptionRecord;
+
+  DPRINT("RtlRaiseStatus(Status 0x%.08x)\n", Status);
+
+  ExceptionRecord.ExceptionCode    = Status;
+  ExceptionRecord.ExceptionRecord  = NULL;
+  ExceptionRecord.NumberParameters = 0;
+  ExceptionRecord.ExceptionFlags   = EXCEPTION_NONCONTINUABLE;
+  RtlRaiseException (& ExceptionRecord);
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
+  PVOID ReturnAddress,
+  PEXCEPTION_RECORD ExceptionRecord,
+  DWORD EaxValue)
+{
+  PEXCEPTION_REGISTRATION ERHead;
+  PEXCEPTION_RECORD pExceptRec;
+  EXCEPTION_RECORD TempER;    
+  CONTEXT Context;
+
+  DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame);
+
+#ifndef NDEBUG
+  RtlpDumpExceptionRegistrations();
+#endif /* NDEBUG */
+
+  ERHead = SehpGetExceptionList();
+ 
+  DPRINT("ERHead is 0x%X\n", ERHead);
+
+  if (ExceptionRecord == NULL) // The normal case
+  {
+	DPRINT("ExceptionRecord == NULL (normal)\n");
+
+    pExceptRec = &TempER;
+    pExceptRec->ExceptionFlags = 0;
+    pExceptRec->ExceptionCode = STATUS_UNWIND;
+    pExceptRec->ExceptionRecord = NULL;
+    pExceptRec->ExceptionAddress = ReturnAddress;
+    pExceptRec->ExceptionInformation[0] = 0;
+  }
+  else
+  {
+    pExceptRec = ExceptionRecord;
+  }
+
+  if (RegistrationFrame)
+    pExceptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
+  else
+    pExceptRec->ExceptionFlags |= (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND);
+
+#ifndef NDEBUG
+  DPRINT("ExceptionFlags == 0x%x:\n", pExceptRec->ExceptionFlags);
+  if (pExceptRec->ExceptionFlags & EXCEPTION_UNWINDING)
+  {
+	  DPRINT("  * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING);
+  }
+  if (pExceptRec->ExceptionFlags & EXCEPTION_EXIT_UNWIND)
+  {
+	  DPRINT("  * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND);
+  }
+#endif /* NDEBUG */
+
+  Context.ContextFlags =
+    (CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
+
+  SehpCaptureContext(&Context);
+
+  DPRINT("Context.Eip = 0x%.08x\n", Context.Eip);
+  DPRINT("Context.Ebp = 0x%.08x\n", Context.Ebp);
+  DPRINT("Context.Esp = 0x%.08x\n", Context.Esp);
+
+  Context.Esp += 0x10;
+  Context.Eax = EaxValue;
+ 
+  // Begin traversing the list of EXCEPTION_REGISTRATION
+  while ((ULONG_PTR)ERHead != -1)
+  {
+    EXCEPTION_RECORD er2;
+ 
+    DPRINT("ERHead 0x%X\n", ERHead);
+
+    if (ERHead == RegistrationFrame)
+    {
+      DPRINT("Continueing execution\n");
+      SehpContinue(&Context, FALSE);
+      return;
+    }
+    else
+    {
+      // If there's an exception frame, but it's lower on the stack
+      // than the head of the exception list, something's wrong!
+      if (RegistrationFrame && (RegistrationFrame <= ERHead))
+      {
+        DPRINT("The exception frame is bad\n");
+
+        // Generate an exception to bail out
+        er2.ExceptionRecord = pExceptRec;
+        er2.NumberParameters = 0;
+        er2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
+        er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;    
+ 
+        RtlRaiseException(&er2);
+      }
+    }
+ 
+#if 0
+    Stack = ERHead + sizeof(EXCEPTION_REGISTRATION);
+    if ( (Teb->Tib.StackBase <= (PVOID)ERHead )      // Make sure that ERHead
+      && (Teb->Tib.->StackLimit >= (PVOID)Stack )      // is in range, and a multiple
+      && (0 == ((ULONG_PTR)ERHead & 3)) )         // of 4 (i.e., sane)
+    {
+#else
+    if (1) {
+#endif
+      PEXCEPTION_REGISTRATION NewERHead;
+      PEXCEPTION_REGISTRATION pCurrExceptReg;
+      EXCEPTION_DISPOSITION ReturnValue;
+  
+      DPRINT("Executing handler at 0x%X for unwind\n", ERHead->handler);
+
+      ReturnValue = RtlpExecuteHandlerForUnwind(
+        pExceptRec,
+        ERHead,
+        &Context,
+        &NewERHead,
+        ERHead->handler);
+ 
+      DPRINT("Handler at 0x%X returned 0x%X\n", ERHead->handler, ReturnValue);
+
+      if (ReturnValue != ExceptionContinueSearch)
+      {
+        if (ReturnValue != ExceptionCollidedUnwind)
+        {
+          DPRINT("Bad return value\n");
+
+          er2.ExceptionRecord = pExceptRec;
+          er2.NumberParameters = 0;
+          er2.ExceptionCode = STATUS_INVALID_DISPOSITION;
+          er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;    
+ 
+          RtlRaiseException(&er2);
+        }
+        else
+        {
+          ERHead = NewERHead;
+        }
+      }
+ 
+      pCurrExceptReg = ERHead;
+      ERHead = ERHead->prev;
+
+      DPRINT("New ERHead is 0x%X\n", ERHead);
+
+      DPRINT("Setting exception registration at 0x%X as current\n",
+        RegistrationFrame->prev);
+
+      // Unlink the exception handler
+      SehpSetExceptionList(RegistrationFrame->prev);
+    }
+    else // The stack looks goofy! Raise an exception to bail out
+    {
+      DPRINT("Bad stack\n");
+
+      er2.ExceptionRecord = pExceptRec;
+      er2.NumberParameters = 0;
+      er2.ExceptionCode = STATUS_BAD_STACK;
+      er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;    
+ 
+      RtlRaiseException(&er2);
+    }
+  }
+ 
+  // If we get here, we reached the end of the EXCEPTION_REGISTRATION list.
+  // This shouldn't happen normally.
+
+  DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n",
+    RegistrationFrame);
+
+  if ((ULONG_PTR)RegistrationFrame == -1)
+    SehpContinue(&Context, FALSE);
+  else
+    NtRaiseException(pExceptRec, &Context, 0);
+}
+
+/* EOF */

reactos/ntoskrnl/rtl/i386
except.s 1.3 -> 1.4
diff -N except.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ except.s	25 Jun 2004 16:39:41 -0000	1.4
@@ -0,0 +1,291 @@
+/* $Id: except.s,v 1.4 2004/06/25 16:39:41 weiden Exp $
+ *
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS kernel
+ * PURPOSE:           Kernel-mode exception support for IA-32
+ * FILE:              ntoskrnl/rtl/i386/except.s
+ * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES:             This file is shared with lib/ntdll/rtl/i386/except.s.
+ *                    Please keep them in sync.
+ */
+
+#define EXCEPTION_UNWINDING		0x02
+
+#define EREC_FLAGS				0x04
+
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch    1
+#define ExceptionNestedException   2
+#define ExceptionCollidedUnwind    3
+
+.globl _RtlpExecuteHandlerForException
+.globl _RtlpExecuteHandlerForUnwind
+
+#define CONTEXT_FLAGS	0x00
+#define CONTEXT_SEGGS	0x8C
+#define CONTEXT_SEGFS	0x90
+#define CONTEXT_SEGES	0x94
+#define CONTEXT_SEGDS	0x98
+#define CONTEXT_EDI		0x9C
+#define CONTEXT_ESI		0xA0
+#define CONTEXT_EBX		0xA4
+#define CONTEXT_EDX		0xA8
+#define CONTEXT_ECX		0xAC
+#define CONTEXT_EAX		0xB0
+#define CONTEXT_EBP		0xB4
+#define CONTEXT_EIP		0xB8
+#define CONTEXT_SEGCS	0xBC
+#define CONTEXT_EFLAGS	0xC0
+#define CONTEXT_ESP		0xC4
+#define CONTEXT_SEGSS	0xC8
+
+
+#define RCC_CONTEXT		0x08
+
+// EAX = value to print
+_do_debug:
+	pushal
+	pushl	%eax
+	call	_AsmDebug@4
+	popal
+	ret
+
+#ifndef __NTOSKRNL__
+
+//
+// VOID
+// RtlpCaptureContext(PCONTEXT pContext);
+//
+// Parameters:
+//   [ESP+08h] - PCONTEXT_X86 pContext
+// Registers:
+//   None
+// Returns:
+//   Nothing
+// Notes:
+//   Grabs the current CPU context.
+.globl _RtlpCaptureContext
+_RtlpCaptureContext:
+	pushl   %ebp
+    movl	%esp, %ebp
+	movl	RCC_CONTEXT(%ebp), %edx		// EDX = Address of context structure
+
+	cld
+	pushf
+	pop		%eax
+	movl	%eax, CONTEXT_EFLAGS(%edx)
+	xorl	%eax, %eax
+	movl	%eax, CONTEXT_EAX(%edx)
+	movl	%eax, CONTEXT_EBX(%edx)
+	movl	%eax, CONTEXT_ECX(%edx)
+	movl	%eax, CONTEXT_EDX(%edx)
+	movl	%eax, CONTEXT_ESI(%edx)
+	movl	%eax, CONTEXT_EDI(%edx)
+	movl	%cs, %eax
+	movl	%eax, CONTEXT_SEGCS(%edx)
+	movl	%ds, %eax
+	movl	%eax, CONTEXT_SEGDS(%edx)
+	movl	%es, %eax
+	movl	%eax, CONTEXT_SEGES(%edx)
+	movl	%fs, %eax
+	movl	%eax, CONTEXT_SEGFS(%edx)
+	movl	%gs, %eax
+	movl	%eax, CONTEXT_SEGGS(%edx)
+	movl	%ss, %eax
+	movl	%eax, CONTEXT_SEGSS(%edx)
+
+	//
+	// STACK LAYOUT: - (ESP to put in context structure)
+	//               - RETURN ADDRESS OF CALLER OF CALLER
+	//               - EBP OF CALLER OF CALLER
+	//                 ...
+	//               - RETURN ADDRESS OF CALLER
+	//               - EBP OF CALLER
+	//                 ...
+	//
+
+	// Get return address of the caller of the caller of this function
+	movl	%ebp, %ebx
+	//movl	4(%ebx), %eax			// EAX = return address of caller
+	movl	(%ebx), %ebx			// EBX = EBP of caller
+
+	movl	4(%ebx), %eax			// EAX = return address of caller of caller
+	movl	(%ebx), %ebx			// EBX = EBP of caller of caller
+
+	movl	%eax, CONTEXT_EIP(%edx)	// EIP = return address of caller of caller
+	movl	%ebx, CONTEXT_EBP(%edx)	// EBP = EBP of caller of caller
+	addl	$8, %ebx
+	movl	%ebx, CONTEXT_ESP(%edx)	// ESP = EBP of caller of caller + 8
+
+    movl	%ebp, %esp
+    popl	%ebp
+    ret
+
+#endif /* !__NTOSKRNL__ */
+
+#define REH_ERECORD		0x08
+#define REH_RFRAME		0x0C
+#define REH_CONTEXT		0x10
+#define REH_DCONTEXT	0x14
+#define REH_EROUTINE	0x18
+
+// Parameters:
+//   None
+// Registers:
+//   [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
+//   [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [EBP+10h] - PVOID Context
+//   [EBP+14h] - PVOID DispatcherContext
+//   [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
+//   EDX       - Address of protecting exception handler
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//   Setup the protecting exception handler and call the exception
+//   handler in the right context.
+_RtlpExecuteHandler:
+	pushl    %ebp
+    movl     %esp, %ebp
+    pushl    REH_RFRAME(%ebp)
+
+    pushl    %edx
+    pushl    %fs:0x0
+    movl     %esp, %fs:0x0
+
+    // Prepare to call the exception handler
+    pushl    REH_DCONTEXT(%ebp)
+    pushl    REH_CONTEXT(%ebp)
+    pushl    REH_RFRAME(%ebp)
+    pushl    REH_ERECORD(%ebp)
+
+    // Now call the exception handler
+    movl     REH_EROUTINE(%ebp), %eax
+    call    *%eax
+
+	cmpl	$-1, %fs:0x0
+	jne		.reh_stack_looks_ok
+
+	// This should not happen
+	pushl	0
+	pushl	0
+	pushl	0
+	pushl	0
+	call	_RtlAssert@16
+
+.reh_loop:
+	jmp	.reh_loop
+	
+.reh_stack_looks_ok:
+    movl     %fs:0x0, %esp
+
+    // Return to the 'front-end' for this function
+    popl     %fs:0x0
+    movl     %ebp, %esp
+    popl     %ebp
+    ret
+
+
+#define REP_ERECORD     0x04
+#define REP_RFRAME      0x08
+#define REP_CONTEXT     0x0C
+#define REP_DCONTEXT    0x10
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//    This exception handler protects the exception handling
+//    mechanism by detecting nested exceptions.
+_RtlpExceptionProtector:
+    movl     $ExceptionContinueSearch, %eax
+    movl     REP_ERECORD(%esp), %ecx
+    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
+    jnz      .rep_end
+
+    // Unwinding is not taking place, so return ExceptionNestedException
+
+    // Set DispatcherContext field to the exception registration for the
+    // exception handler that executed when a nested exception occurred
+    movl     REP_DCONTEXT(%esp), %ecx
+    movl     REP_RFRAME(%esp), %eax
+    movl     %eax, (%ecx)
+    movl     $ExceptionNestedException, %eax
+
+.rep_end:
+    ret
+
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//   Front-end
+_RtlpExecuteHandlerForException:
+    movl     $_RtlpExceptionProtector, %edx
+    jmp      _RtlpExecuteHandler
+
+
+#define RUP_ERECORD     0x04
+#define RUP_RFRAME      0x08
+#define RUP_CONTEXT     0x0C
+#define RUP_DCONTEXT    0x10
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+// Notes:
+//    This exception handler protects the exception handling
+//    mechanism by detecting collided unwinds.
+_RtlpUnwindProtector:
+    movl     $ExceptionContinueSearch, %eax
+    movl     %ecx, RUP_ERECORD(%esp)
+    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
+    jz       .rup_end
+
+    // Unwinding is taking place, so return ExceptionCollidedUnwind
+
+    movl     RUP_RFRAME(%esp), %ecx
+    movl     RUP_DCONTEXT(%esp), %edx
+
+    // Set DispatcherContext field to the exception registration for the
+    // exception handler that executed when a collision occurred
+    movl     RUP_RFRAME(%ecx), %eax
+    movl     %eax, (%edx)
+    movl     $ExceptionCollidedUnwind, %eax
+
+.rup_end:
+    ret
+
+
+// Parameters:
+//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
+//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
+//   [ESP+0Ch] - PCONTEXT Context
+//   [ESP+10h] - PVOID DispatcherContext
+//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
+// Registers:
+//   None
+// Returns:
+//   EXCEPTION_DISPOSITION
+_RtlpExecuteHandlerForUnwind:
+    movl     $_RtlpUnwindProtector, %edx
+    jmp      _RtlpExecuteHandler
CVSspam 0.2.8