Index: trunk/src/kernel32/exceptions.cpp
===================================================================
--- trunk/src/kernel32/exceptions.cpp	(revision 1223)
+++ trunk/src/kernel32/exceptions.cpp	(revision 1224)
@@ -1,3 +1,3 @@
-/* $Id: exceptions.cpp,v 1.22 1999-10-09 13:33:23 sandervl Exp $ */
+/* $Id: exceptions.cpp,v 1.23 1999-10-09 15:03:10 sandervl Exp $ */
 
 /*
@@ -64,4 +64,5 @@
 #include "mmap.h"
 #include <wprocess.h>
+#include "oslibexcept.h"
 
 //Global Process Unhandled exception filter
@@ -130,7 +131,5 @@
                                DWORD es,  DWORD fs,   DWORD gs,  DWORD ss)
 {
-  PWINEXCEPTION_FRAME   pframe, dispatch, nested_frame;
   WINEXCEPTION_RECORD   record;
-  WINEXCEPTION_RECORD   newrec;
   WINEXCEPTION_POINTERS ExceptionInfo;
   WINCONTEXT            context;
@@ -175,6 +174,34 @@
   }
 
+  rc = RtlDispatchException(&record, &context);
+
+  // and finally, the unhandled exception filter
+  if(rc == ExceptionContinueSearch && UnhandledExceptionFilter != NULL)
+  {
+    ExceptionInfo.ExceptionRecord = &record;
+    ExceptionInfo.ContextRecord   = &context;
+
+    rc = UnhandledExceptionFilter(&ExceptionInfo);
+  }
+
+  // terminate the process
+  if(rc != ExceptionContinueExecution ||
+     record.ExceptionFlags & EH_NONCONTINUABLE)
+  {
+    dprintf(("KERNEL32: RaiseException terminating process.\n"));
+    DosExit(EXIT_PROCESS, 0);
+  }
+
+  return;
+}
+//******************************************************************************
+//******************************************************************************
+DWORD RtlDispatchException(WINEXCEPTION_RECORD *pRecord, WINCONTEXT *pContext)
+{
+  PWINEXCEPTION_FRAME   pframe, dispatch, nested_frame;
+  int                   rc;
+
   // get chain of exception frames
-  rc     = ExceptionContinueSearch;
+  rc  = ExceptionContinueSearch;
 
   nested_frame = NULL;
@@ -193,12 +220,12 @@
             (int)pframe & 3)
         {
-            record.ExceptionFlags |= EH_STACK_INVALID;
+            pRecord->ExceptionFlags |= EH_STACK_INVALID;
             break;
         }
 
-    	rc = pframe->Handler(&record,
+    	rc = pframe->Handler(pRecord,
                              pframe,
-                             &context,
-                             &dispatch);
+                             pContext,
+                             dispatch);
 
         if (pframe == nested_frame)
@@ -206,5 +233,5 @@
             /* no longer nested */
             nested_frame = NULL;
-            record.ExceptionFlags &= ~EH_NESTED_CALL;
+            pRecord->ExceptionFlags &= ~EH_NESTED_CALL;
         }
 
@@ -214,6 +241,5 @@
         {
         case ExceptionContinueExecution:
-            if (!(record.ExceptionFlags & EH_NONCONTINUABLE)) return;
-	    DosExit(EXIT_PROCESS, 0);
+            if (!(pRecord->ExceptionFlags & EH_NONCONTINUABLE)) return rc;
             break;
         case ExceptionContinueSearch:
@@ -221,8 +247,7 @@
         case ExceptionNestedException:
             if (nested_frame < dispatch) nested_frame = dispatch;
-            record.ExceptionFlags |= EH_NESTED_CALL;
+            pRecord->ExceptionFlags |= EH_NESTED_CALL;
             break;
         default:
-	    DosExit(EXIT_PROCESS, 0);
             break;
         }
@@ -230,25 +255,6 @@
         pframe = pframe->Prev;
   }
-
-  // and finally, the unhandled exception filter
-  if(rc == ExceptionContinueSearch && UnhandledExceptionFilter != NULL)
-  {
-    ExceptionInfo.ExceptionRecord = &record;
-    ExceptionInfo.ContextRecord   = &context;
-
-    rc = UnhandledExceptionFilter(&ExceptionInfo);
-  }
-
-  // terminate the process
-  if(rc != ExceptionContinueExecution)
-  {
-    dprintf(("KERNEL32: RaiseException terminating process.\n"));
-    DosExit(EXIT_PROCESS, 0);
-  }
-
-  return;
-}
-
-
+  return rc;
+}
 /*****************************************************************************
  * Name      : int _Pascal OS2RtlUnwind
@@ -934,5 +940,4 @@
                                    PVOID                        p)
 {
-  //  pERegRec->prev_structure = 0;
   dprintfException(pERepRec, pERegRec, pCtxRec, p);
 
@@ -948,10 +953,16 @@
   case XCPT_FLOAT_UNDERFLOW:
   	dprintf(("KERNEL32: OS2ExceptionHandler: FPU exception, fix and continue\n"));
-        pCtxRec->ctx_env[0] |= 0x1F;
-        pCtxRec->ctx_stack[0].losig = 0;
-        pCtxRec->ctx_stack[0].hisig = 0;
-        pCtxRec->ctx_stack[0].signexp = 0;
-
-      	return (XCPT_CONTINUE_EXECUTION);
+	if(fIsOS2Image == FALSE)  //Only for real win32 apps
+	{
+		if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == FALSE) 
+		{
+		        pCtxRec->ctx_env[0] |= 0x1F;
+		        pCtxRec->ctx_stack[0].losig = 0;
+		        pCtxRec->ctx_stack[0].hisig = 0;
+		        pCtxRec->ctx_stack[0].signexp = 0;
+		}
+	      	return (XCPT_CONTINUE_EXECUTION);
+	}
+      	else	return (XCPT_CONTINUE_SEARCH);
 
   case XCPT_PROCESS_TERMINATE:
@@ -1008,4 +1019,11 @@
   case XCPT_IN_PAGE_ERROR:
 CrashAndBurn:
+	if(fIsOS2Image == FALSE)  //Only for real win32 apps
+	{
+		if(OSLibDispatchException(pERepRec, pERegRec, pCtxRec, p) == TRUE) 
+		{
+		      	return (XCPT_CONTINUE_EXECUTION);
+		}
+	}
     	dprintf(("KERNEL32: OS2ExceptionHandler: Continue and kill\n"));
     	pCtxRec->ctx_RegEip = (ULONG)KillWin32Process;
Index: trunk/src/kernel32/makefile
===================================================================
--- trunk/src/kernel32/makefile	(revision 1223)
+++ trunk/src/kernel32/makefile	(revision 1224)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.42 1999-09-18 17:47:10 sandervl Exp $
+# $Id: makefile,v 1.43 1999-10-09 15:03:10 sandervl Exp $
 
 #
@@ -34,5 +34,5 @@
 pefile.OBJ winimgres.OBJ wintls.obj async.OBJ fileio.obj \
 atom.obj disk.obj directory.obj cvtbitmap.obj hmmmap.obj \
-cvtmenu.obj cvtaccel.obj cvticon.obj cvticongrp.obj \
+cvtmenu.obj cvtaccel.obj cvticon.obj cvticongrp.obj oslibexcept.obj \
 cvtcursor.obj cvtcursorgrp.obj stubs.obj interlock.obj toolhelp.obj
 
@@ -142,4 +142,5 @@
 exceptions.OBJ: \
     .\exceptions.cpp \
+    oslibexcept.h \
     mmap.h \
     $(PDWIN32_INCLUDE)\exceptions.h \
@@ -149,4 +150,9 @@
     .\message.cpp \
     $(PDWIN32_INCLUDE)\unicode.h
+
+oslibexcept.obj: \
+    oslibexcept.cpp \
+    $(PDWIN32_INCLUDE)\exceptions.h \
+    oslibexcept.h 
 
 devio.OBJ: \
Index: trunk/src/kernel32/oslibexcept.cpp
===================================================================
--- trunk/src/kernel32/oslibexcept.cpp	(revision 1224)
+++ trunk/src/kernel32/oslibexcept.cpp	(revision 1224)
@@ -0,0 +1,264 @@
+/* $Id: oslibexcept.cpp,v 1.1 1999-10-09 15:03:23 sandervl Exp $ */
+/*
+ * Exception handler util. procedures
+ *
+ * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ */
+#define INCL_BASE
+#define INCL_DOSEXCEPTIONS
+#define INCL_DOSMEMMGR
+#define INCL_DOSPROCESS
+#include <os2wrap.h>                     //Odin32 OS/2 api wrappers
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <win32type.h>
+#include <misc.h>
+#include "oslibexcept.h"
+#include <exceptions.h>
+
+//******************************************************************************
+//Dispatches OS/2 exception to win32 handler
+//Returns: TRUE, win32 exception handler returned continue execution
+//         FALSE, otherwise
+//******************************************************************************
+BOOL OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 
+                            PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 
+                            PCONTEXTRECORD pContextRec, PVOID p)
+{
+ WINEXCEPTION_RECORD winreportrec;
+ WINCONTEXT          wincontextrec;
+ ULONG               rc;
+
+  memset(&winreportrec, 0, sizeof(winreportrec));
+  memcpy(&winreportrec, pReportRec, sizeof(*pReportRec));
+
+  switch(pReportRec->ExceptionNum) {
+  case XCPT_FLOAT_DENORMAL_OPERAND:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND;
+	break;
+  case XCPT_FLOAT_DIVIDE_BY_ZERO:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
+	break;
+  case XCPT_FLOAT_INEXACT_RESULT:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
+	break;
+  case XCPT_FLOAT_INVALID_OPERATION:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+	break;
+  case XCPT_FLOAT_OVERFLOW:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
+	break;
+  case XCPT_FLOAT_STACK_CHECK:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_STACK_CHECK;
+	break;
+  case XCPT_FLOAT_UNDERFLOW:
+	winreportrec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
+	break;
+  case XCPT_INTEGER_DIVIDE_BY_ZERO:
+	winreportrec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
+	break;
+  case XCPT_INTEGER_OVERFLOW:
+	winreportrec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
+	break;
+  case XCPT_PRIVILEGED_INSTRUCTION:
+	winreportrec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
+	break;
+  case XCPT_BREAKPOINT:
+	winreportrec.ExceptionCode = EXCEPTION_BREAKPOINT;
+	break;
+  case XCPT_SINGLE_STEP:
+	winreportrec.ExceptionCode = EXCEPTION_SINGLE_STEP;
+	break;
+  case XCPT_ARRAY_BOUNDS_EXCEEDED:
+	winreportrec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
+	break;
+  case XCPT_DATATYPE_MISALIGNMENT:
+	winreportrec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
+	break;
+  case XCPT_ILLEGAL_INSTRUCTION:
+	winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+	break;
+  case XCPT_INVALID_LOCK_SEQUENCE:
+	winreportrec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+	break;
+  case XCPT_GUARD_PAGE_VIOLATION:
+	winreportrec.ExceptionCode = EXCEPTION_GUARD_PAGE;
+	break;
+  case XCPT_UNABLE_TO_GROW_STACK:
+	winreportrec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
+	break;
+  case XCPT_IN_PAGE_ERROR:
+	winreportrec.ExceptionCode = EXCEPTION_IN_PAGE_ERROR;
+	break;
+  case XCPT_ACCESS_VIOLATION:
+	winreportrec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+	break;
+  default: //no other exceptions should be dispatched to win32 apps
+	return FALSE;
+  }
+  //TODO:
+  //According to the Wine folks the flags are the same in OS/2 and win32
+  //Let's assume for now the rest is identical as well
+
+  //copy context record info
+  memset(&wincontextrec, 0, sizeof(wincontextrec));
+  if(pContextRec->ContextFlags & CONTEXT_CONTROL) {
+	wincontextrec.ContextFlags |= WINCONTEXT_CONTROL;
+	wincontextrec.Ebp     = pContextRec->ctx_RegEbp;
+	wincontextrec.Eip     = pContextRec->ctx_RegEip;
+	wincontextrec.SegCs   = pContextRec->ctx_SegCs;
+	wincontextrec.EFlags  = pContextRec->ctx_EFlags;
+	wincontextrec.Esp     = pContextRec->ctx_RegEsp;
+	wincontextrec.SegSs   = pContextRec->ctx_SegSs;
+  }
+  if(pContextRec->ContextFlags & CONTEXT_INTEGER) {
+	wincontextrec.ContextFlags |= WINCONTEXT_INTEGER;
+	wincontextrec.Edi     = pContextRec->ctx_RegEdi;
+	wincontextrec.Esi     = pContextRec->ctx_RegEsi;
+	wincontextrec.Ebx     = pContextRec->ctx_RegEbx;
+	wincontextrec.Edx     = pContextRec->ctx_RegEdx;
+	wincontextrec.Ecx     = pContextRec->ctx_RegEcx;
+	wincontextrec.Eax     = pContextRec->ctx_RegEax;
+  }
+  if(pContextRec->ContextFlags & CONTEXT_SEGMENTS) {
+	wincontextrec.ContextFlags |= WINCONTEXT_SEGMENTS;
+	wincontextrec.SegGs   = pContextRec->ctx_SegGs;
+	wincontextrec.SegFs   = pContextRec->ctx_SegFs;
+	wincontextrec.SegEs   = pContextRec->ctx_SegEs;
+	wincontextrec.SegDs   = pContextRec->ctx_SegDs;
+  }
+  if(pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) {
+	wincontextrec.ContextFlags |= WINCONTEXT_FLOATING_POINT;
+	//TODO: First 7 dwords the same?
+	memcpy(&wincontextrec.FloatSave, pContextRec->ctx_env, sizeof(pContextRec->ctx_env));
+	memcpy(&wincontextrec.FloatSave.RegisterArea, pContextRec->ctx_stack, sizeof(pContextRec->ctx_stack));
+  }
+  //It doesn't seem correct if we dispatch real exceptions to win32 apps
+  //Some just call RtlUnwind and continue as if they were processing an
+  //exception thrown by C++ code. (instead of real OS exception)
+#if 0
+  switch(pReportRec->ExceptionNum) {
+  case XCPT_FLOAT_DENORMAL_OPERAND:
+  case XCPT_FLOAT_DIVIDE_BY_ZERO:
+  case XCPT_FLOAT_INEXACT_RESULT:
+  case XCPT_FLOAT_INVALID_OPERATION:
+  case XCPT_FLOAT_OVERFLOW:
+  case XCPT_FLOAT_STACK_CHECK:
+  case XCPT_FLOAT_UNDERFLOW:
+	rc = RtlDispatchException(&winreportrec, &wincontextrec);
+	break;
+
+  case XCPT_ACCESS_VIOLATION:
+	rc = RtlDispatchException(&winreportrec, &wincontextrec);
+	break;
+
+  case XCPT_INTEGER_DIVIDE_BY_ZERO:
+  case XCPT_INTEGER_OVERFLOW:
+  case XCPT_PRIVILEGED_INSTRUCTION:
+  case XCPT_BREAKPOINT:
+  case XCPT_SINGLE_STEP:
+  case XCPT_ARRAY_BOUNDS_EXCEEDED:
+  case XCPT_DATATYPE_MISALIGNMENT:
+  case XCPT_ILLEGAL_INSTRUCTION:
+  case XCPT_INVALID_LOCK_SEQUENCE:
+  case XCPT_GUARD_PAGE_VIOLATION:
+  case XCPT_UNABLE_TO_GROW_STACK:
+  case XCPT_IN_PAGE_ERROR:
+	return FALSE; //let's no dispatch those for now
+  }
+
+  if(rc == ExceptionContinueExecution) {
+  	dprintf(("Win32 exception handler returned ExceptionContinueExecution"));
+  	if(wincontextrec.ContextFlags & WINCONTEXT_CONTROL) {
+		pContextRec->ctx_RegEbp = wincontextrec.Ebp;
+		pContextRec->ctx_RegEip = wincontextrec.Eip;
+		pContextRec->ctx_SegCs  = wincontextrec.SegCs;
+		pContextRec->ctx_EFlags = wincontextrec.EFlags;
+		pContextRec->ctx_RegEsp = wincontextrec.Esp;
+		pContextRec->ctx_SegSs  = wincontextrec.SegSs;
+  	}
+	if(wincontextrec.ContextFlags & WINCONTEXT_INTEGER) {
+		pContextRec->ctx_RegEdi = wincontextrec.Edi;
+		pContextRec->ctx_RegEsi = wincontextrec.Esi;
+		pContextRec->ctx_RegEbx = wincontextrec.Ebx;
+		pContextRec->ctx_RegEdx = wincontextrec.Edx;
+		pContextRec->ctx_RegEcx = wincontextrec.Ecx;
+		pContextRec->ctx_RegEax = wincontextrec.Eax;
+	}
+#if 0
+	//This is not a good idea
+	if(wincontextrec.ContextFlags & WINCONTEXT_SEGMENTS) {
+		pContextRec->ctx_SegGs = wincontextrec.SegGs;
+		pContextRec->ctx_SegFs = wincontextrec.SegFs;
+		pContextRec->ctx_SegEs = wincontextrec.SegEs;
+		pContextRec->ctx_SegDs = wincontextrec.SegDs;
+	}
+#endif
+	if(wincontextrec.ContextFlags & WINCONTEXT_FLOATING_POINT) {
+		//TODO: First 7 dwords the same?
+		memcpy(pContextRec->ctx_env, &wincontextrec.FloatSave, sizeof(pContextRec->ctx_env));
+		memcpy(pContextRec->ctx_stack, &wincontextrec.FloatSave.RegisterArea, sizeof(pContextRec->ctx_stack));
+	}
+  	if (pContextRec->ContextFlags & CONTEXT_CONTROL)         /* check flags */
+    		dprintf(("   SS:ESP=%04x:%08x EFLAGS=%08x\n"
+		             "   CS:EIP=%04x:%08x EBP   =%08x\n",
+		             pContextRec->ctx_SegSs,
+		             pContextRec->ctx_RegEsp,
+		             pContextRec->ctx_EFlags,
+		             pContextRec->ctx_SegCs,
+		             pContextRec->ctx_RegEip,
+		             pContextRec->ctx_RegEbp));
+
+	if (pContextRec->ContextFlags & CONTEXT_INTEGER)         /* check flags */
+		    dprintf(("   EAX=%08x EBX=%08x ESI=%08x\n"
+		             "   ECX=%08x EDX=%08x EDI=%08x\n",
+		             pContextRec->ctx_RegEax,
+		             pContextRec->ctx_RegEbx,
+		             pContextRec->ctx_RegEsi,
+		             pContextRec->ctx_RegEcx,
+		             pContextRec->ctx_RegEdx,
+		             pContextRec->ctx_RegEdi));
+		
+	if (pContextRec->ContextFlags & CONTEXT_SEGMENTS)        /* check flags */
+		    dprintf(("   DS=%04x     ES=%08x"
+		             "   FS=%04x     GS=%04x\n",
+		              pContextRec->ctx_SegDs,
+		              pContextRec->ctx_SegEs,
+		              pContextRec->ctx_SegFs,
+		              pContextRec->ctx_SegGs));
+
+	if (pContextRec->ContextFlags & CONTEXT_FLOATING_POINT)  /* check flags */
+	{
+	    ULONG ulCounter;                 /* temporary local counter for fp stack */
+
+		dprintf(("   Env[0]=%08x Env[1]=%08x Env[2]=%08x Env[3]=%08x\n",
+		             pContextRec->ctx_env[0],
+		             pContextRec->ctx_env[1],
+		             pContextRec->ctx_env[2],
+		             pContextRec->ctx_env[3]));
+		
+		dprintf(("   Env[4]=%08x Env[5]=%08x Env[6]=%08x\n",
+			     pContextRec->ctx_env[4],
+			     pContextRec->ctx_env[5],
+		             pContextRec->ctx_env[6]));
+
+    		for (ulCounter = 0;
+		     ulCounter < 8; /* see TOOLKIT\INCLUDE\BSEEXPT.H, _CONTEXT structure */
+		     ulCounter ++)
+		      dprintf(("   FP-Stack[%u] losig=%08x hisig=%08x signexp=%04x\n",
+		               ulCounter,
+		               pContextRec->ctx_stack[0].losig,
+		               pContextRec->ctx_stack[0].hisig,
+		               pContextRec->ctx_stack[0].signexp));
+	}
+	
+	return TRUE;
+  }
+  dprintf(("Win32 exception handler returned %x", rc));
+#endif
+  return FALSE;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/kernel32/oslibexcept.h
===================================================================
--- trunk/src/kernel32/oslibexcept.h	(revision 1224)
+++ trunk/src/kernel32/oslibexcept.h	(revision 1224)
@@ -0,0 +1,20 @@
+/* $Id: oslibexcept.h,v 1.1 1999-10-09 15:03:24 sandervl Exp $ */
+/*
+ * Exception handler util. procedures
+ *
+ * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ */
+#ifndef __OSLIBEXCEPT_H__
+#define __OSLIBEXCEPT_H__
+
+//******************************************************************************
+//Dispatches OS/2 exception to win32 handler
+//Returns: TRUE, win32 exception handler returned continue execution
+//         FALSE, otherwise
+//******************************************************************************
+BOOL OSLibDispatchException(PEXCEPTIONREPORTRECORD pReportRec, 
+                            PEXCEPTIONREGISTRATIONRECORD pRegistrationRec, 
+                            PCONTEXTRECORD pContextRec, PVOID p);
+
+#endif
