[ros-diffs] [fireball] 30363: - Winesync cppexcept.c. This fixes try/catch C++ exception handling in various apps (like MFC based apps).

fireball at svn.reactos.org fireball at svn.reactos.org
Sun Nov 11 21:40:22 CET 2007


Author: fireball
Date: Sun Nov 11 23:40:21 2007
New Revision: 30363

URL: http://svn.reactos.org/svn/reactos?rev=30363&view=rev
Log:
- Winesync cppexcept.c. This fixes try/catch C++ exception handling in various apps (like MFC based apps).

Modified:
    trunk/reactos/lib/sdk/crt/except/cppexcept.c
    trunk/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h
    trunk/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h
    trunk/reactos/media/doc/README.WINE

Modified: trunk/reactos/lib/sdk/crt/except/cppexcept.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/except/cppexcept.c?rev=30363&r1=30362&r2=30363&view=diff
==============================================================================
--- trunk/reactos/lib/sdk/crt/except/cppexcept.c (original)
+++ trunk/reactos/lib/sdk/crt/except/cppexcept.c Sun Nov 11 23:40:21 2007
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  * NOTES
  * A good reference is the article "How a C++ compiler implements
@@ -39,44 +39,59 @@
 
 #include <internal/wine/cppexcept.h>
 
+#ifdef __i386__  /* CxxFrameHandler is not supported on non-i386 */
+
 WINE_DEFAULT_DEBUG_CHANNEL(seh);
 
-#ifdef __i386__  /* CxxFrameHandler is not supported on non-i386 */
-
-static DWORD cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
-                                PCONTEXT exc_context, EXCEPTION_REGISTRATION_RECORD** dispatch,
-                                cxx_function_descr *descr, EXCEPTION_REGISTRATION_RECORD* nested_frame,
-                                int nested_trylevel );
+DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
+                               PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
+                               const cxx_function_descr *descr,
+                               EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel );
 
 /* call a function with a given ebp */
-__inline static void *call_ebp_func( void *func, void *ebp )
+static inline void *call_ebp_func( void *func, void *ebp )
 {
     void *ret;
-    __asm__ __volatile__ ("pushl %%ebp; movl %2,%%ebp; call *%%eax; popl %%ebp" \
-                          : "=a" (ret) : "0" (func), "g" (ebp) : "ecx", "edx", "memory" );
+    int dummy;
+    __asm__ __volatile__ ("pushl %%ebx\n\t"
+                          "pushl %%ebp\n\t"
+                          "movl %4,%%ebp\n\t"
+                          "call *%%eax\n\t"
+                          "popl %%ebp\n\t"
+                          "popl %%ebx"
+                          : "=a" (ret), "=S" (dummy), "=D" (dummy)
+                          : "0" (func), "1" (ebp) : "ecx", "edx", "memory" );
     return ret;
 }
 
 /* call a copy constructor */
-__inline static void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
+static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
 {
     TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
     if (has_vbase)
         /* in that case copy ctor takes an extra bool indicating whether to copy the base class */
         __asm__ __volatile__("pushl $1; pushl %2; call *%0"
-                             : : "r" (func), "c" (this), "g" (src) : "eax", "edx", "memory" );
+                             : : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" );
     else
         __asm__ __volatile__("pushl %2; call *%0"
-                             : : "r" (func), "c" (this), "g" (src) : "eax", "edx", "memory" );
+                             : : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" );
 }
 
 /* call the destructor of the exception object */
-__inline static void call_dtor( void *func, void *object )
+static inline void call_dtor( void *func, void *object )
 {
     __asm__ __volatile__("call *%0" : : "r" (func), "c" (object) : "eax", "edx", "memory" );
 }
 
-static void dump_type( const cxx_type_info *type )
+/* continue execution to the specified address after exception is caught */
+static inline void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr )
+{
+    __asm__ __volatile__("movl -4(%0),%%esp; leal 12(%0),%%ebp; jmp *%1"
+                         : : "r" (frame), "a" (addr) );
+    for (;;) ; /* unreached */
+}
+
+static inline void dump_type( const cxx_type_info *type )
 {
     TRACE( "flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n",
              type->flags, type->type_info, dbgstr_type_info(type->type_info),
@@ -88,49 +103,47 @@
 {
     UINT i;
 
-    DPRINTF( "exception type:\n" );
-    DPRINTF( "flags %x destr %p handler %p type info %p\n",
+    TRACE( "flags %x destr %p handler %p type info %p\n",
              type->flags, type->destructor, type->custom_handler, type->type_info_table );
     for (i = 0; i < type->type_info_table->count; i++)
     {
-        DPRINTF( "    %d: ", i );
+        TRACE( "    %d: ", i );
         dump_type( type->type_info_table->info[i] );
     }
 }
 
-static void dump_function_descr( const cxx_function_descr *descr, const cxx_exception_type *info )
+static void dump_function_descr( const cxx_function_descr *descr )
 {
     UINT i;
     int j;
 
-    DPRINTF( "function descr:\n" );
-    DPRINTF( "magic %x\n", descr->magic );
-    DPRINTF( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count );
+    TRACE( "magic %x\n", descr->magic );
+    TRACE( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count );
     for (i = 0; i < descr->unwind_count; i++)
     {
-        DPRINTF( "    %d: prev %d func %p\n", i,
+        TRACE( "    %d: prev %d func %p\n", i,
                  descr->unwind_table[i].prev, descr->unwind_table[i].handler );
     }
-    DPRINTF( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
+    TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
     for (i = 0; i < descr->tryblock_count; i++)
     {
-        DPRINTF( "    %d: start %d end %d catchlevel %d catch %p %d\n", i,
+        TRACE( "    %d: start %d end %d catchlevel %d catch %p %d\n", i,
                  descr->tryblock[i].start_level, descr->tryblock[i].end_level,
                  descr->tryblock[i].catch_level, descr->tryblock[i].catchblock,
                  descr->tryblock[i].catchblock_count );
         for (j = 0; j < descr->tryblock[i].catchblock_count; j++)
         {
-            catchblock_info *ptr = &descr->tryblock[i].catchblock[j];
-            DPRINTF( "        %d: flags %x offset %d handler %p type %p",
-                     j, ptr->flags, ptr->offset, ptr->handler, ptr->type_info );
-            if (ptr->type_info) DPRINTF( " (%p %s)", ptr->type_info->name, ptr->type_info->mangled );
-            DPRINTF( "\n" );
+            const catchblock_info *ptr = &descr->tryblock[i].catchblock[j];
+            TRACE( "        %d: flags %x offset %d handler %p type %p %s\n",
+                     j, ptr->flags, ptr->offset, ptr->handler,
+                     ptr->type_info, dbgstr_type_info( ptr->type_info ) );
         }
     }
 }
 
 /* check if the exception type is caught by a given catch block, and return the type that matched */
-static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, catchblock_info *catchblock )
+static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type,
+                                              const catchblock_info *catchblock )
 {
     UINT i;
 
@@ -156,7 +169,7 @@
 
 /* copy the exception object where the catch block wants it */
 static void copy_exception( void *object, cxx_exception_frame *frame,
-                            catchblock_info *catchblock, const cxx_type_info *type )
+                            const catchblock_info *catchblock, const cxx_type_info *type )
 {
     void **dest_ptr;
 
@@ -185,14 +198,14 @@
 }
 
 /* unwind the local function up to a given trylevel */
-static void cxx_local_unwind( cxx_exception_frame* frame, cxx_function_descr *descr, int last_level)
+static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
 {
     void (*handler)();
     int trylevel = frame->trylevel;
 
     while (trylevel != last_level)
     {
-        if (trylevel < 0 || trylevel >= (int)descr->unwind_count)
+        if (trylevel < 0 || trylevel >= descr->unwind_count)
         {
             ERR( "invalid trylevel %d\n", trylevel );
             MSVCRT_terminate();
@@ -215,8 +228,9 @@
     EXCEPTION_REGISTRATION_RECORD frame;     /* standard exception frame */
     EXCEPTION_RECORD             *prev_rec;  /* previous record to restore in thread data */
     cxx_exception_frame          *cxx_frame; /* frame of parent exception */
-    cxx_function_descr           *descr;     /* descriptor of parent exception */
+    const cxx_function_descr     *descr;     /* descriptor of parent exception */
     int                           trylevel;  /* current try level */
+    EXCEPTION_RECORD             *rec;       /* rec associated with frame */
 };
 
 /* handler for exceptions happening while calling a catch function */
@@ -230,20 +244,41 @@
         msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec;
         return ExceptionContinueSearch;
     }
-    else
-    {
-        TRACE( "got nested exception in catch function\n" );
-        return cxx_frame_handler( rec, nested_frame->cxx_frame, context,
-                                  NULL, nested_frame->descr, &nested_frame->frame,
-                                  nested_frame->trylevel );
-    }
+
+    TRACE( "got nested exception in catch function\n" );
+
+    if(rec->ExceptionCode == CXX_EXCEPTION)
+    {
+        PEXCEPTION_RECORD prev_rec = nested_frame->rec;
+        if(rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
+        {
+            /* exception was rethrown */
+            rec->ExceptionInformation[1] = prev_rec->ExceptionInformation[1];
+            rec->ExceptionInformation[2] = prev_rec->ExceptionInformation[2];
+            TRACE("detect rethrow: re-propagate: obj: %lx, type: %lx\n",
+                    rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
+        }
+        else {
+            /* new exception in exception handler, destroy old */
+            void *object = (void*)prev_rec->ExceptionInformation[1];
+            cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2];
+            TRACE("detect threw new exception in catch block - destroy old(obj: %p type: %p)\n",
+                    object, info);
+            if(info && info->destructor)
+                call_dtor( info->destructor, object );
+        }
+    }
+
+    return cxx_frame_handler( rec, nested_frame->cxx_frame, context,
+                              NULL, nested_frame->descr, &nested_frame->frame,
+                              nested_frame->trylevel );
 }
 
 /* find and call the appropriate catch block for an exception */
 /* returns the address to continue execution to after the catch block was called */
-__inline static void *call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame,
-                                      cxx_function_descr *descr, int nested_trylevel,
-                                      cxx_exception_type *info )
+static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame,
+                                     const cxx_function_descr *descr, int nested_trylevel,
+                                     cxx_exception_type *info )
 {
     UINT i;
     int j;
@@ -251,10 +286,11 @@
     struct catch_func_nested_frame nested_frame;
     int trylevel = frame->trylevel;
     MSVCRT_thread_data *thread_data = msvcrt_get_thread_data();
+    DWORD save_esp = ((DWORD*)frame)[-1];
 
     for (i = 0; i < descr->tryblock_count; i++)
     {
-        tryblock_info *tryblock = &descr->tryblock[i];
+        const tryblock_info *tryblock = &descr->tryblock[i];
 
         if (trylevel < tryblock->start_level) continue;
         if (trylevel > tryblock->end_level) continue;
@@ -262,14 +298,24 @@
         /* got a try block */
         for (j = 0; j < tryblock->catchblock_count; j++)
         {
-            catchblock_info *catchblock = &tryblock->catchblock[j];
-            const cxx_type_info *type = find_caught_type( info, catchblock );
-            if (!type) continue;
-
-            TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j );
-
-            /* copy the exception to its destination on the stack */
-            copy_exception( object, frame, catchblock, type );
+            const catchblock_info *catchblock = &tryblock->catchblock[j];
+            if(info)
+            {
+                const cxx_type_info *type = find_caught_type( info, catchblock );
+                if (!type) continue;
+
+                TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j );
+
+                /* copy the exception to its destination on the stack */
+                copy_exception( object, frame, catchblock, type );
+            }
+            else
+            {
+                /* no CXX_EXCEPTION only proceed with a catch(...) block*/
+                if(catchblock->type_info)
+                    continue;
+                TRACE("found catch(...) block\n");
+            }
 
             /* unwind the stack */
             RtlUnwind( frame, 0, rec, 0 );
@@ -277,17 +323,17 @@
             frame->trylevel = tryblock->end_level + 1;
 
             /* call the catch block */
-            TRACE( "calling catch block %p for type %p addr %p ebp %p\n",
-                   catchblock, type, catchblock->handler, &frame->ebp );
+            TRACE( "calling catch block %p addr %p ebp %p\n",
+                   catchblock, catchblock->handler, &frame->ebp );
 
             /* setup an exception block for nested exceptions */
 
-            //nested_frame.frame.Handler = catch_function_nested_handler;
             nested_frame.frame.Handler = (PEXCEPTION_HANDLER)catch_function_nested_handler;
             nested_frame.prev_rec  = thread_data->exc_record;
             nested_frame.cxx_frame = frame;
             nested_frame.descr     = descr;
             nested_frame.trylevel  = nested_trylevel + 1;
+            nested_frame.rec = rec;
 
             __wine_push_frame( &nested_frame.frame );
             thread_data->exc_record = rec;
@@ -295,12 +341,13 @@
             thread_data->exc_record = nested_frame.prev_rec;
             __wine_pop_frame( &nested_frame.frame );
 
-            if (info->destructor) call_dtor( info->destructor, object );
+            ((DWORD*)frame)[-1] = save_esp;
+            if (info && info->destructor) call_dtor( info->destructor, object );
             TRACE( "done, continuing at %p\n", addr );
-            return addr;
-        }
-    }
-    return NULL;
+
+            continue_after_catch( frame, addr );
+        }
+    }
 }
 
 
@@ -309,14 +356,13 @@
  *
  * Implementation of __CxxFrameHandler.
  */
-static DWORD cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
-                                PCONTEXT exc_context, EXCEPTION_REGISTRATION_RECORD** dispatch,
-                                cxx_function_descr *descr, EXCEPTION_REGISTRATION_RECORD* nested_frame,
-                                int nested_trylevel )
+DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
+                               PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
+                               const cxx_function_descr *descr,
+                               EXCEPTION_REGISTRATION_RECORD* nested_frame,
+                               int nested_trylevel )
 {
     cxx_exception_type *exc_type;
-    void *next_ip;
-    PEXCEPTION_RECORD orig_rec = rec;
 
     if (descr->magic != CXX_FRAME_MAGIC)
     {
@@ -330,71 +376,88 @@
     }
     if (!descr->tryblock_count) return ExceptionContinueSearch;
 
-    exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
-    if (rec->ExceptionCode == CXX_EXCEPTION &&
-        rec->ExceptionInformation[0] > CXX_FRAME_MAGIC &&
-        exc_type->custom_handler)
-    {
-        return exc_type->custom_handler( rec, frame, exc_context, dispatch,
+    if(rec->ExceptionCode == CXX_EXCEPTION)
+    {
+        exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
+
+        if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC &&
+                exc_type->custom_handler)
+        {
+            return exc_type->custom_handler( rec, frame, context, dispatch,
                                          descr, nested_trylevel, nested_frame, 0 );
-    }
-
-    if (!exc_type)  /* nested exception, fetch info from original exception */
-    {
-        rec = msvcrt_get_thread_data()->exc_record;
-        exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
-    }
-
-    if (TRACE_ON(seh))
-    {
-        TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",
-              rec, frame, frame->trylevel, descr, nested_frame );
-        dump_exception_type( exc_type );
-        dump_function_descr( descr, exc_type );
-    }
-
-    next_ip = call_catch_block( rec, frame, descr, frame->trylevel, exc_type );
-
-    if (!next_ip) return ExceptionContinueSearch;
-    orig_rec->ExceptionFlags &= ~EH_NONCONTINUABLE;
-    exc_context->Eip = (DWORD)next_ip;
-    exc_context->Ebp = (DWORD)&frame->ebp;
-    exc_context->Esp = ((DWORD*)frame)[-1];
-    return ExceptionContinueExecution;
+        }
+
+        if (TRACE_ON(seh))
+        {
+            TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",
+                  rec, frame, frame->trylevel, descr, nested_frame );
+            dump_exception_type( exc_type );
+            dump_function_descr( descr );
+        }
+    }
+    else
+    {
+        exc_type = NULL;
+        TRACE("handling C exception code %x  rec %p frame %p trylevel %d descr %p nested_frame %p\n",
+              rec->ExceptionCode,  rec, frame, frame->trylevel, descr, nested_frame );
+    }
+
+    call_catch_block( rec, frame, descr, frame->trylevel, exc_type );
+    return ExceptionContinueSearch;
 }
 
 
 /*********************************************************************
  *		__CxxFrameHandler (MSVCRT.@)
  */
-DWORD __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
-                              PCONTEXT exc_context, EXCEPTION_REGISTRATION_RECORD** dispatch )
-{
-    cxx_function_descr *descr;
-
-    __asm__ __volatile__("mov %%eax, %0\n" : "=m"(descr));
-    return cxx_frame_handler(rec, (cxx_exception_frame *)frame,
-                             exc_context, dispatch, descr, NULL, 0 );
-}
+extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
+                                      PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch );
+__ASM_GLOBAL_FUNC( __CxxFrameHandler,
+                   "pushl $0\n\t"        /* nested_trylevel */
+                   "pushl $0\n\t"        /* nested_frame */
+                   "pushl %eax\n\t"      /* descr */
+                   "pushl 28(%esp)\n\t"  /* dispatch */
+                   "pushl 28(%esp)\n\t"  /* context */
+                   "pushl 28(%esp)\n\t"  /* frame */
+                   "pushl 28(%esp)\n\t"  /* rec */
+                   "call " __ASM_NAME("cxx_frame_handler") "\n\t"
+                   "add $28,%esp\n\t"
+                   "ret" )
+
+
+/*********************************************************************
+ *		__CxxLongjmpUnwind (MSVCRT.@)
+ *
+ * Callback meant to be used as UnwindFunc for setjmp/longjmp.
+ */
+void __stdcall __CxxLongjmpUnwind( const struct MSVCRT___JUMP_BUFFER *buf )
+{
+    cxx_exception_frame *frame = (cxx_exception_frame *)buf->Registration;
+    const cxx_function_descr *descr = (const cxx_function_descr *)buf->UnwindData[0];
+
+    TRACE( "unwinding frame %p descr %p trylevel %ld\n", frame, descr, buf->TryLevel );
+    cxx_local_unwind( frame, descr, buf->TryLevel );
+}
+
 #endif  /* __i386__ */
 
 /*********************************************************************
  *		_CxxThrowException (MSVCRT.@)
  */
-void _CxxThrowException( void *object, const cxx_exception_type *type )
-{
-    DWORD args[3];
+void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type )
+{
+    ULONG_PTR args[3];
 
     args[0] = CXX_FRAME_MAGIC;
-    args[1] = (DWORD)object;
-    args[2] = (DWORD)type;
+    args[1] = (ULONG_PTR)object;
+    args[2] = (ULONG_PTR)type;
     RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
 }
 
 /*********************************************************************
  *		__CxxDetectRethrow (MSVCRT.@)
  */
-BOOL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
+BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
 {
   PEXCEPTION_RECORD rec;
 
@@ -417,7 +480,7 @@
 /*********************************************************************
  *		__CxxQueryExceptionSize (MSVCRT.@)
  */
-unsigned int __CxxQueryExceptionSize(void)
+unsigned int CDECL __CxxQueryExceptionSize(void)
 {
   return sizeof(cxx_exception_type);
 }

Modified: trunk/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h?rev=30363&r1=30362&r2=30363&view=diff
==============================================================================
--- trunk/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h (original)
+++ trunk/reactos/lib/sdk/crt/include/internal/wine/cppexcept.h Sun Nov 11 23:40:21 2007
@@ -121,7 +121,7 @@
 
 typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, cxx_exception_frame*,
                                          PCONTEXT, EXCEPTION_REGISTRATION_RECORD**,
-                                         cxx_function_descr*, int nested_trylevel,
+                                         const cxx_function_descr*, int nested_trylevel,
                                          EXCEPTION_REGISTRATION_RECORD *nested_frame, DWORD unknown3 );
 
 /* type information for an exception object */
@@ -133,7 +133,7 @@
     const cxx_type_info_table *type_info_table;  /* list of types for this exception object */
 } cxx_exception_type;
 
-void _CxxThrowException(void*,const cxx_exception_type*);
+void _CxxThrowException(exception*,const cxx_exception_type*);
 
 static inline const char *dbgstr_type_info( const type_info *info )
 {

Modified: trunk/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h?rev=30363&r1=30362&r2=30363&view=diff
==============================================================================
--- trunk/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h (original)
+++ trunk/reactos/lib/sdk/crt/include/internal/wine/msvcrt.h Sun Nov 11 23:40:21 2007
@@ -166,6 +166,23 @@
 #define _RT_CRNL        252
 #define _RT_BANNER      255
 
+#ifdef __i386__
+struct MSVCRT___JUMP_BUFFER {
+    unsigned long Ebp;
+    unsigned long Ebx;
+    unsigned long Edi;
+    unsigned long Esi;
+    unsigned long Esp;
+    unsigned long Eip;
+    unsigned long Registration;
+    unsigned long TryLevel;
+    /* Start of new struct members */
+    unsigned long Cookie;
+    unsigned long UnwindFunc;
+    unsigned long UnwindData[6];
+};
+#endif /* __i386__ */
+
 typedef void* (*malloc_func_t)(size_t);
 typedef void  (*free_func_t)(void*);
 #define MSVCRT_malloc malloc

Modified: trunk/reactos/media/doc/README.WINE
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=30363&r1=30362&r2=30363&view=diff
==============================================================================
--- trunk/reactos/media/doc/README.WINE (original)
+++ trunk/reactos/media/doc/README.WINE Sun Nov 11 23:40:21 2007
@@ -119,8 +119,8 @@
 
 msvcrt -
   reactos/dll/win32/msvcrt/wine/*.c             # Out of sync
-  reactos/lib/sdk/crt/except                    # Synced at XXXXXXXX
   reactos/lib/sdk/crt/cpp.c                     # Synced at 20071111
+  reactos/lib/sdk/crt/cppexcept.c               # Synced at 20071111
   reactos/lib/sdk/crt/wine                      # Synced at XXXXXXXX
 
 User32 -




More information about the Ros-diffs mailing list