Index: include/excpt.h
===================================================================
--- include/excpt.h	(revision 21636)
+++ include/excpt.h	(working copy)
@@ -41,6 +41,134 @@
 
 #if defined(__GNUC__)
 
+#if 1
+
+struct ___seh_REGISTRATIONRECORD;
+typedef int (_System *__seh_PEXCEPTIONHANDLER)(void * /*PEXCEPTIONREPORTRECORD*/,
+                                               struct ___seh_REGISTRATIONRECORD *,
+                                               void * /*PCONTEXTRECORD*/,
+                                               void * /*PDISPATCHERCONTEXT*/);
+
+#pragma pack(1)
+
+typedef struct ___seh_REGISTRATIONRECORD
+{
+    /* + 0 */ struct ___seh_REGISTRATIONRECORD *pPrev;
+    /* + 4 */ __seh_PEXCEPTIONHANDLER pHandler;
+    /* + 8 */ void *pFilterCallback;
+    /* +12 */ void *pHandlerCallback;
+    /* +16 */ void *pHandlerContext;
+    /* +20 */ int filterResult;
+    /* +24 */ DWORD EBX;
+    /* +28 */ DWORD ESI;
+    /* +32 */ DWORD EDI;
+    /* +36 */ DWORD EBP;
+    /* +40 */ DWORD ESP;
+    /* +44 */ EXCEPTION_POINTERS Pointers;
+    /* +52 */ int state;
+}
+__seh_REGISTRATIONRECORD;
+
+#pragma pack()
+
+extern int _System __seh_handler(void * /*PEXCEPTIONREPORTRECORD*/,
+                                 struct ___seh_REGISTRATIONRECORD *,
+                                 void * /*CONTEXTRECORD*/,
+                                 void * /*DISPATCHERCONTEXT*/);
+
+#define _exception_code() (__seh_frame.Pointers.ExceptionRecord->ExceptionCode)
+#define _exception_info() ((void *)&__seh_frame.Pointers)
+
+#define exception_code _exception_code
+#define exception_info (PEXCEPTION_POINTERS)_exception_info
+
+#define GetExceptionCode _exception_code
+#define GetExceptionInformation (PEXCEPTION_POINTERS)_exception_info
+
+#define __try \
+    volatile __seh_REGISTRATIONRECORD __seh_frame;                             \
+    __seh_frame.pHandler = __seh_handler;                                      \
+    __seh_frame.Pointers.ExceptionRecord = NULL;                               \
+    __seh_frame.Pointers.ContextRecord = NULL;                                 \
+    __seh_frame.state = 0;                                                     \
+    /* install OS/2 exception handler (note: EDX is in clobber too since it may\
+     * carry any value when we jump back to pFilterCallback from the handler */\
+    __asm__ ("leal %0, %%ecx; "                                                \
+                                                                               \
+             "movl %%fs:0, %%eax; "                                            \
+             "movl %%eax, 0(%%ecx); "                                          \
+             "movl $0f, 8(%%ecx); "                                            \
+                                                                               \
+             "movl %%ebx, 24(%%ecx); "                                         \
+             "movl %%esi, 28(%%ecx); "                                         \
+             "movl %%edi, 32(%%ecx); "                                         \
+             "movl %%ebp, 36(%%ecx); "                                         \
+             "movl %%esp, 40(%%ecx); "                                         \
+                                                                               \
+             "movl %%ecx, %%fs:0; "                                            \
+                                                                               \
+             "\n0: /* pFilterCallback */ \n"                                   \
+                                                                               \
+             : : "m" (__seh_frame)                                             \
+             : "%eax", "%ecx", "%edx");                                        \
+    for (; __seh_frame.state <= 3; ++__seh_frame.state)                        \
+        if (__seh_frame.state == 0)                                            \
+        {                                                                      \
+            {
+
+#define __except(filter_expr) \
+            }                                                                  \
+            /* cause the next state to be 3 */                                 \
+            __seh_frame.state = 2;                                             \
+        }                                                                      \
+        else if (__seh_frame.state == 1) {                                     \
+            /* execption caught, call filter expression */                     \
+            __seh_frame.filterResult = (filter_expr);                          \
+            __asm__("leal %0, %%ebx; jmp *%1"                                  \
+                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
+                    : "%ebx");                                                 \
+        }                                                                      \
+        else if (__seh_frame.state == 3)                                       \
+            /* remove exception handler */                                     \
+            __asm__ ("leal %0, %%ecx; "                                        \
+                                                                               \
+                     "movl 0(%%ecx), %%eax; "                                  \
+                     "movl %%eax, %%fs:0; "                                    \
+                                                                               \
+                     : : "m"(__seh_frame)                                      \
+                     : "%eax", "%ecx");                                        \
+        else /* __seh_frame.state == 2 -> execute except block */
+
+#define __finally \
+            }                                                                  \
+            /* cause the next state to be 2 */                                 \
+            __seh_frame.state = 1;                                             \
+        }                                                                      \
+        else if (__seh_frame.state == 1) {                                     \
+            /* execption caught, handle and proceed to the filally block */    \
+            __seh_frame.filterResult = EXCEPTION_EXECUTE_HANDLER;              \
+            __asm__("leal %0, %%ebx; jmp *%1"                                  \
+                    : : "m"(__seh_frame), "m"(__seh_frame.pHandlerCallback)    \
+                    : "%ebx");                                                 \
+        }                                                                      \
+        else if (__seh_frame.state == 3)                                       \
+            /* remove exception handler */                                     \
+            __asm__ ("leal %0, %%ecx; "                                        \
+                                                                               \
+                     "movl 0(%%ecx), %%eax; "                                  \
+                     "movl %%eax, %%fs:0; "                                    \
+                                                                               \
+                     : : "m"(__seh_frame)                                      \
+                     : "%eax", "%ecx");                                        \
+        else /* __seh_frame.state == 2 -> execute finally block */
+
+#define __leave \
+            /* cause the next state to be 2 */                                 \
+            __seh_frame.state = 1;                                             \
+            continue;
+
+#else
+
 struct ___seh_EXCEPTION_FRAME;
 typedef int (*__seh_PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,
                                         struct ___seh_EXCEPTION_FRAME *,
@@ -200,6 +328,8 @@
             __seh_frame.state = 1;                                             \
             continue;
 
+#endif
+
 #else /* defined(__GNUC__) */
 
 #warning "Structured exception handling is not supported for this compiler!"
Index: src/kernel32/exceptions.cpp
===================================================================
--- src/kernel32/exceptions.cpp	(revision 21631)
+++ src/kernel32/exceptions.cpp	(working copy)
@@ -117,6 +117,7 @@
                              PEXCEPTIONREGISTRATIONRECORD pERegRec,
                              PCONTEXTRECORD pCtxRec, PVOID p, PSZ szTrapDump);
 
+#if 0
 extern "C"
 int __cdecl __seh_handler(PWINEXCEPTION_RECORD pRec,
                           PWINEXCEPTION_FRAME pFrame,
@@ -124,6 +125,7 @@
 
 extern "C"
 PWINEXCEPTION_FRAME __cdecl __seh_get_prev_frame(PWINEXCEPTION_FRAME pFrame);
+#endif
 
 #ifdef DEBUG
 static void PrintWin32ExceptionChain(PWINEXCEPTION_FRAME pframe);
@@ -361,7 +363,11 @@
     // walk the exception chain
     while( (pFrame != NULL) && ((ULONG)((ULONG)pFrame & 0xFFFFF000) != 0xFFFFF000) )
     {
+#if 0
         pPrevFrame = __seh_get_prev_frame(pFrame);
+#else
+        pPrevFrame = pFrame->Prev;
+#endif
 
         dprintf(("KERNEL32: RtlDispatchException - pframe=%08X, pframe->Prev=%08X",
                  pFrame, pPrevFrame));
@@ -510,7 +516,11 @@
 
   while (((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) && (frame != pEndFrame))
   {
+#if 0
         prevFrame = __seh_get_prev_frame(frame);
+#else
+        prevFrame = frame->Prev;
+#endif
 
         /* Check frame address */
         if (pEndFrame && (frame > pEndFrame))
@@ -563,9 +573,15 @@
         dprintf(("KERNEL32: RtlUnwind (before)- frame=%08X, frame->Prev=%08X", frame, prevFrame));
         SetExceptionChain((DWORD)prevFrame);
         frame = prevFrame;
+#if 0
         dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame,
                  ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ?
                  __seh_get_prev_frame(frame) : (void*)0xFFFFFFFF));
+#else
+        dprintf(("KERNEL32: RtlUnwind (after) - frame=%08X, frame->Prev=%08X", frame,
+                 ((ULONG)((ULONG)frame & 0xFFFFF000) != 0xFFFFF000) ?
+                 frame->Prev : (void*)0xFFFFFFFF));
+#endif
   }
 
   dprintf(("KERNEL32: RtlUnwind returning.\n"));
@@ -1345,6 +1361,7 @@
     }
 continueFail:
 
+#if 0
     /*
      * vladest: OK, try to implement write AUTOCOMMIT
      * last chance after MMAP commit is failed
@@ -1382,7 +1399,7 @@
         else
             goto CrashAndBurn;
     }
-
+#endif
 
 ////#define DEBUGSTACK
 #ifdef DEBUGSTACK
@@ -1840,11 +1857,17 @@
     dprintf(("Win32 exception chain:"));
     while ((pFrame != NULL) && ((ULONG)pFrame != 0xFFFFFFFF))
     {
+#if 0
         PWINEXCEPTION_FRAME pPrevFrame = __seh_get_prev_frame(pFrame);
         dprintf(("  Record at %08X, Prev at %08X, handler at %08X%s",
                  pFrame, pPrevFrame, pFrame->Handler,
                  pFrame->Handler == (PEXCEPTION_HANDLER)__seh_handler ?
                  " (SEH)" : ""));
+#else
+        PWINEXCEPTION_FRAME pPrevFrame = pFrame->Prev;
+        dprintf(("  Record at %08X, Prev at %08X, handler at %08X",
+                 pFrame, pPrevFrame, pFrame->Handler));
+#endif
         if (pFrame == pPrevFrame)
         {
             dprintf(("Chain corrupted! Record at %08X pointing to itself!",
Index: src/kernel32/KERNEL32.DEF
===================================================================
--- src/kernel32/KERNEL32.DEF	(revision 21631)
+++ src/kernel32/KERNEL32.DEF	(working copy)
@@ -1352,6 +1352,8 @@
     EncodePointer              = _EncodePointer@4                 @3530 NONAME
     RtlUniform                 = _RtlUniform@4                    @3531 NONAME
     
-    ___seh_handler                                                @3600 NONAME
+;    ___seh_handler                                                @3600 NONAME
+;    _EnableSEH@0                                                  @3601 NONAME
+    __seh_handler                                                 @3600 NONAME
     _EnableSEH@0                                                  @3601 NONAME
     
\ No newline at end of file
Index: src/kernel32/kernel32dbg.def
===================================================================
--- src/kernel32/kernel32dbg.def	(revision 21631)
+++ src/kernel32/kernel32dbg.def	(working copy)
@@ -1351,5 +1351,7 @@
     EncodePointer              = _EncodePointer@4                 @3530 NONAME
     RtlUniform                 = _RtlUniform@4                    @3531 NONAME
     
-    ___seh_handler                                                @3600 NONAME
+;    ___seh_handler                                                @3600 NONAME
+;    _EnableSEH@0                                                  @3601 NONAME
+    __seh_handler                                                 @3600 NONAME
     _EnableSEH@0                                                  @3601 NONAME
Index: src/kernel32/oslibexcept.cpp
===================================================================
--- src/kernel32/oslibexcept.cpp	(revision 21631)
+++ src/kernel32/oslibexcept.cpp	(working copy)
@@ -22,6 +22,137 @@
 #define DBG_LOCALLOG    DBG_oslibexcept
 #include "dbglocal.h"
 
+BOOL APIENTRY OSLibExeptionRecordsToWin32(PEXCEPTIONREPORTRECORD pReportRec,
+                                          PCONTEXTRECORD pContextRec,
+                                          WINEXCEPTION_RECORD *pWinReportRec,
+                                          WINCONTEXT *pWinContextRec,
+                                          ULONG FSReg)
+{
+    // Note: FSReg contains a FS value for Win32 apps and a non-zero value is
+    // used as a flag to indicate Win32 app mode
+
+    memset(pWinReportRec, 0, sizeof(*pWinReportRec));
+    memcpy(pWinReportRec, pReportRec, sizeof(*pReportRec));
+
+    switch(pReportRec->ExceptionNum) {
+    case XCPT_FLOAT_DENORMAL_OPERAND:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_DENORMAL_OPERAND;
+          break;
+    case XCPT_FLOAT_DIVIDE_BY_ZERO:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
+          break;
+    case XCPT_FLOAT_INEXACT_RESULT:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
+          break;
+    case XCPT_FLOAT_INVALID_OPERATION:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
+          break;
+    case XCPT_FLOAT_OVERFLOW:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_OVERFLOW;
+          break;
+    case XCPT_FLOAT_STACK_CHECK:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_STACK_CHECK;
+          break;
+    case XCPT_FLOAT_UNDERFLOW:
+          pWinReportRec->ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
+          break;
+    case XCPT_INTEGER_DIVIDE_BY_ZERO:
+          pWinReportRec->ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
+          break;
+    case XCPT_INTEGER_OVERFLOW:
+          pWinReportRec->ExceptionCode = EXCEPTION_INT_OVERFLOW;
+          break;
+    case XCPT_PRIVILEGED_INSTRUCTION:
+          pWinReportRec->ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
+          break;
+    case XCPT_BREAKPOINT:
+          pWinReportRec->ExceptionCode = EXCEPTION_BREAKPOINT;
+          break;
+    case XCPT_SINGLE_STEP:
+          pWinReportRec->ExceptionCode = EXCEPTION_SINGLE_STEP;
+          break;
+    case XCPT_ARRAY_BOUNDS_EXCEEDED:
+          pWinReportRec->ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
+          break;
+    case XCPT_DATATYPE_MISALIGNMENT:
+          pWinReportRec->ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
+          break;
+    case XCPT_ILLEGAL_INSTRUCTION:
+          pWinReportRec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+          break;
+    case XCPT_INVALID_LOCK_SEQUENCE:
+          pWinReportRec->ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+          break;
+    case XCPT_GUARD_PAGE_VIOLATION:
+          pWinReportRec->ExceptionCode = EXCEPTION_GUARD_PAGE;
+          break;
+    case XCPT_UNABLE_TO_GROW_STACK:
+          pWinReportRec->ExceptionCode = EXCEPTION_STACK_OVERFLOW;
+          break;
+    case XCPT_IN_PAGE_ERROR:
+          pWinReportRec->ExceptionCode = EXCEPTION_IN_PAGE_ERROR;
+          break;
+    case XCPT_ACCESS_VIOLATION:
+          pWinReportRec->ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
+          break;
+    default:
+          if (FSReg) {
+              //no other exceptions should be dispatched to win32 apps
+              return FALSE;
+          }
+          //TODO: convert other exception codes
+          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(pWinContextRec, 0, sizeof(pWinContextRec));
+    if(pContextRec->ContextFlags & CONTEXT_CONTROL) {
+          pWinContextRec->ContextFlags |= WINCONTEXT_CONTROL;
+          pWinContextRec->Ebp     = pContextRec->ctx_RegEbp;
+          pWinContextRec->Eip     = pContextRec->ctx_RegEip;
+          pWinContextRec->SegCs   = pContextRec->ctx_SegCs;
+          pWinContextRec->EFlags  = pContextRec->ctx_EFlags;
+          pWinContextRec->Esp     = pContextRec->ctx_RegEsp;
+          pWinContextRec->SegSs   = pContextRec->ctx_SegSs;
+    }
+    if(pContextRec->ContextFlags & CONTEXT_INTEGER) {
+          pWinContextRec->ContextFlags |= WINCONTEXT_INTEGER;
+          pWinContextRec->Edi     = pContextRec->ctx_RegEdi;
+          pWinContextRec->Esi     = pContextRec->ctx_RegEsi;
+          pWinContextRec->Ebx     = pContextRec->ctx_RegEbx;
+          pWinContextRec->Edx     = pContextRec->ctx_RegEdx;
+          pWinContextRec->Ecx     = pContextRec->ctx_RegEcx;
+          pWinContextRec->Eax     = pContextRec->ctx_RegEax;
+    }
+
+    if(pContextRec->ContextFlags & CONTEXT_SEGMENTS) {
+          pWinContextRec->ContextFlags |= WINCONTEXT_SEGMENTS;
+          pWinContextRec->SegGs   = pContextRec->ctx_SegGs;
+          // Use the overriden FS value (necessary for Win32 apps where FS
+          // is not 0x150B)
+          if (FSReg) {
+            pWinContextRec->SegFs   = FSReg;
+          } else {
+            pWinContextRec->SegFs   = pContextRec->ctx_SegFs;
+          }
+          pWinContextRec->SegEs   = pContextRec->ctx_SegEs;
+          pWinContextRec->SegDs   = pContextRec->ctx_SegDs;
+    }
+    if(pContextRec->ContextFlags & CONTEXT_FLOATING_POINT) {
+          pWinContextRec->ContextFlags |= WINCONTEXT_FLOATING_POINT;
+          //TODO: First 7 dwords the same?
+          memcpy(&pWinContextRec->FloatSave, pContextRec->ctx_env,
+                 sizeof(pContextRec->ctx_env));
+          memcpy(&pWinContextRec->FloatSave.RegisterArea, pContextRec->ctx_stack,
+                 sizeof(pContextRec->ctx_stack));
+    }
+
+    return TRUE;
+}
+
 //******************************************************************************
 //Dispatches OS/2 exception to win32 handler
 //Returns: TRUE, win32 exception handler returned continue execution
@@ -35,115 +166,13 @@
  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;
-  }
-
   TEB *winteb = GetThreadTEB();
 
-  if(pContextRec->ContextFlags & CONTEXT_SEGMENTS) {
-        wincontextrec.ContextFlags |= WINCONTEXT_SEGMENTS;
-        wincontextrec.SegGs   = pContextRec->ctx_SegGs;
-//   This resets FS to 0x150B - we DON'T want that!!
-//      wincontextrec.SegFs   = pContextRec->ctx_SegFs;
-        wincontextrec.SegFs   = winteb->teb_sel;
-        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));
-  }
+  if(!OSLibExeptionRecordsToWin32(pReportRec, pContextRec,
+                                  &winreportrec, &wincontextrec,
+                                  winteb->teb_sel))
+    return FALSE;
+
   //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)
Index: src/kernel32/seh/sehutil.s
===================================================================
--- src/kernel32/seh/sehutil.s	(revision 21633)
+++ src/kernel32/seh/sehutil.s	(working copy)
@@ -6,6 +6,265 @@
  * Copyright 2010 Dmitriy Kuminov
  */
 
+#if 1
+
+.global __seh_handler
+
+/*
+ * extern "C"
+ * int _System __seh_handler(PEXCEPTIONREPORTRECORD pRec,
+ *                           struct ___seh_REGISTRATIONRECORD *pFrame,
+ *                           PCONTEXTRECORD pContext,
+ *                           PDISPATCHERCONTEXT pVoid)
+ *
+ * OS/2 structured exception handler that implements the MSVC __try/__except
+ * functionality for GCC.
+ *
+ * NOTE: This is a heavily platform specific stuff. The code depends on the
+ * struct ___seh_EXCEPTION_FRAME and WINEXCEPTION_RECORD / WINCONTEXT layout so
+ * be very careful and keep both in sync!
+ *
+ * _System is much like __cdecl: EAX/ECX/EDX are not preserved, result in
+ * EAX/EDX, caller cleans up the stack.
+ */
+
+__seh_handler:
+
+/*
+    movl 4(%esp), %eax
+    cmpl $0x80000001, 0(%eax)
+    je 0f
+    jmp 1f
+0:
+    xorl %eax, %eax
+    ret
+1:
+*/
+    jmp __seh_handler_Begin
+
+
+    /* if we are the top exception handler, we need to call the Odin exception
+     * handler first in order to let it handle some critical exceptions (e.g.
+     * XCPT_GUARD_PAGE_VIOLATION used to commit new stack pages as it grows) */
+
+
+    movl %fs:0, %eax
+0:
+    cmpl $__seh_handler, 4(%eax)    /* Is it a SEH handler? */
+    je 1f                           /* Yes */
+    movl 0(%eax), %eax              /* pFrame = pFrame->pPrev */
+    jmp 0b
+1:
+    cmpl 8(%esp), %eax              /* Is it our frame? */
+    jne __seh_handler_Begin         /* No */
+
+    /* We're the top SEH handler in the chain, call the Odin handler */
+0:
+    movl 0(%eax), %eax              /* pFrame = pFrame->pPrev */
+    cmpl $-1, %eax                  /* End of chain? */
+    je __seh_handler_Begin
+    cmpl $__seh_handler, 4(%eax)    /* Is it a SEH handler? */
+    je 0b                           /* Yes, skip */
+
+    push 16(%esp)
+    push 16(%esp)
+    push %eax
+    push 16(%esp)
+    call *4(%eax)                   /* pFrame->Handler */
+    movl %eax, %ecx
+    movl 4(%esp), %eax              /* Get the current pFrame back */
+    addl $16, %esp
+    cmpl $0, %ecx                   /* XCPT_CONTINUE_SEARCH? */
+    je 0b                           /* Yes, hand over to the prev handler */
+    ret                             /* No (assume XCPT_CONTINUE_EXECUTION) */
+
+
+
+
+__seh_handler_Begin:
+
+    pushl %ebp
+    movl %esp, %ebp
+
+    /*
+     * 8(%ebp)  - pRec
+     * 12(%ebp) - pFrame
+     * 16(%ebp) - pContext
+     * 20(%ebp) - pVoid
+     */
+
+    /* preserve used registers */
+    pushl %ebx
+    pushl %edi
+    pushl %esi
+
+    /* skip EH_UNWINDING calls (for compatibility with MSVC) */
+    movl 8(%ebp), %ebx
+    movl 4(%ebx), %eax /* pRec->fHandlerFlags */
+    testl $0x2, %eax /* EH_UNWINDING? */
+    movl $0, %eax /* XCPT_CONTINUE_SEARCH */
+    jne ___seh_handler_Return
+
+    /* save handler's context */
+    pushl %ebp
+    pushl $0   /* reserve space for length, must be saved right before ESP! */
+    pushl %esp /* ESP must be saved last! */
+
+    movl 12(%ebp), %ebx
+    movl $0f, 12(%ebx) /* pFrame->pHandlerCallback */
+
+    /* get the size of the handler's stack */
+    movl 40(%ebx), %ecx /* pFrame->ESP */
+    subl %esp, %ecx
+    jle ___seh_handler_Error /* Invalid stack! */
+    movl %ecx, 4(%esp) /* save length */
+
+    /* check that EXCEPTION_RECORD and CONTEXT are on our stack
+     * and save their offsets in pFrame */
+    movl 8(%ebp), %eax
+    subl %esp, %eax
+    jl ___seh_handler_Error /* Invalid stack! */
+    cmpl %ecx, %eax
+    jg ___seh_handler_Error /* Invalid stack! */
+
+    movl 16(%ebp), %eax
+    subl %esp, %eax
+    jl ___seh_handler_Error /* Invalid stack! */
+    cmpl %ecx, %eax
+    jg ___seh_handler_Error /* Invalid stack! */
+
+    /* allocate space on heap for the handler's stack and Win32 exception
+     * records */
+    movl %ecx, %eax /* stack length */
+    addl $284, %eax /* WINEXCEPTION_RECORD (80 b) + WINCONTEXT (204 b) */
+    subl $4, %esp
+    movl %eax, 0(%esp)
+    call odin_malloc /* _Optlink, rtl, EAX/EDX/ECX-in, caller cleans stack */
+    addl $4, %esp
+    testl %eax, %eax
+    je ___seh_handler_Error /* No memory! */
+
+    /* save the handler's stack on heap */
+    movl 4(%esp), %ecx
+    movl %eax, %edi
+    movl %edi, 16(%ebx) /* pFrame->pHandlerContext */
+    movl %esp, %esi
+    rep movsb
+
+    /* set Pointers to WINEXCEPTION_RECORD and WINCONTEXT */
+    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
+    addl 4(%esp), %eax  /* stack length */
+    movl %eax, 44(%ebx) /* pFrame->Pointers.ExceptionRecord */
+    addl $80, %eax
+    movl %eax, 48(%ebx) /* pFrame->Pointers.ContextRecord */
+
+    /* convert OS/2 exception records to Win32 exception records */
+    pushl $0        /* FSReg, unused */
+    pushl 48(%ebx)  /* WINCONTEXT */
+    pushl 44(%ebx)  /* WINEXCEPTION_RECORD */
+    pushl 16(%ebp)  /* PCONTEXTRECORD */
+    pushl 8(%ebp)   /* PEXCEPTIONREPORTRECORD */
+    call OSLibExeptionRecordsToWin32 /* _syscall, rtl, caller cleans stack */
+    addl $20, %esp
+    cmpl $0, %eax
+    jne ___seh_handler_RestoreTryCatchContext
+
+    /* free heap block */
+    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
+    subl $4, %esp
+    movl %eax, 0(%esp)
+    call odin_free /* _Optlink, rtl, EAX/EDX/ECX-in, caller cleans stack */
+    addl $4, %esp
+    jmp ___seh_handler_Error /* OSLibExeptionRecordsToWin32 failed */
+
+___seh_handler_RestoreTryCatchContext:
+
+    /* restore __try/__catch context */
+    movl 12(%ebp), %eax
+    movl 24(%eax), %ebx /* pFrame->EBX... */
+    movl 28(%eax), %esi
+    movl 32(%eax), %edi
+    movl 36(%eax), %ebp
+    movl 40(%eax), %esp
+
+    /* jump to the filter callback */
+    movl $1, 52(%eax) /* pFrame->state */
+    jmp *8(%eax) /* pFrame->pFilterCallback */
+
+0:
+    /* restore handler's context (we assume that the callback puts the address
+     * of pFrame back to EBX!) */
+    movl 16(%ebx), %esi /* pFrame->pHandlerContext */
+    movl 0(%esi), %esp  /* restore saved ESP */
+    movl 4(%esi), %ecx  /* saved stack length */
+    subl $4, %esp /* correct ESP to compensate for PUSH ESP logic */
+    movl %esp, %edi
+    rep movsb
+
+    popl %esp
+    addl $4, %esp
+    popl %ebp
+
+    /* free heap block */
+    movl 16(%ebx), %eax /* pFrame->pHandlerContext */
+    subl $4, %esp
+    movl %eax, 0(%esp)
+    call odin_free /* _Optlink, rtl, EAX/EDX/ECX-in, caller cleans stack */
+    addl $4, %esp
+
+    /* analyze filter result */
+    movl 20(%ebx), %eax /* pFrame->filterResult */
+    cmpl $1, %eax /* EXCEPTION_EXECUTE_HANDLER? */
+    je ___seh_handler_Unwind
+    cmpl $-1, %eax /* EXCEPTION_CONTINUE_EXECUTION? */
+    jne 1f
+    movl $0, 52(%ebx) /* pFrame->state */
+    movl $-1, %eax /* XCPT_CONTINUE_EXECUTION */
+    jmp ___seh_handler_Return
+1:
+    /* assume EXCEPTION_CONTINUE_SEARCH (0) */
+    movl $0, %eax /* XCPT_CONTINUE_SEARCH */
+    jmp ___seh_handler_Return
+
+___seh_handler_Unwind:
+
+    /* unwind OS/2 exception chain up to ours */
+    pushl $0        /* PEXCEPTIONREPORTRECORD */
+    pushl $1f       /* PVOID pTargetIP */
+    pushl 12(%ebp)  /* PEXCEPTIONREGISTRATIONRECORD */
+    call _DosUnwindException /* _syscall, rtl, but stack is not restored! */
+1:
+
+    /* restore __try/__except context */
+    movl 12(%ebp), %eax
+    movl 24(%eax), %ebx
+    movl 28(%eax), %esi
+    movl 32(%eax), %edi
+    movl 36(%eax), %ebp
+    movl 40(%eax), %esp
+
+    /* jump to __except */
+    movl $2, 52(%eax) /* pFrame->state */
+    jmp *8(%eax) /* pFrame->pFilterCallback */
+
+___seh_handler_Error:
+
+    addl $8, %esp
+    popl %ebp
+
+    movl $0, %eax /* XCPT_CONTINUE_SEARCH */
+
+___seh_handler_Return:
+
+    popl %esi
+    popl %edi
+    popl %ebx
+
+    popl %ebp
+    ret
+
+#else
+
 .global ___seh_handler
 .global ___seh_get_prev_frame
 
@@ -308,3 +567,4 @@
     movl 0(%eax), %eax /* pFrame->Prev */
     ret
 
+#endif
