THANK YOU ALBERTO!!! This is just what I have been looking for with StarTeam, which now gets further! Since your patch seems to have wrapped, I took the liberty of patching it in by hand and resubmitting it. Here goes: LICENSE: LGPL CHANGELOG: * dlls/msvcrt: main.c, cppexcept.c: Alberto Massari <alby@exln.com> - allow MSVC C++ apps to reraise exceptions without infinite recursion in the exception handlers. -- gmt "The purpose of government is to rein in the rights of the people" --President Bill Clinton, MTV interview, 1993
diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/msvcrt/cppexcept.c ./dlls/msvcrt/cppexcept.c --- ../wine.test/dlls/msvcrt/cppexcept.c 2002-10-03 20:26:18.000000000 -0500 +++ ./dlls/msvcrt/cppexcept.c 2002-10-28 08:24:10.000000000 -0600 @@ -172,6 +172,10 @@ { int i; + if(type==NULL) + return; + + DPRINTF( "exception type:\n" ); DPRINTF( "flags %x destr %p handler %p type info %p\n", type->flags, type->destructor, type->custom_handler, type->type_info_table ); @@ -236,6 +240,10 @@ { UINT i; + if(exc_type==NULL || exc_type->type_info_table==NULL) + return NULL; + + for (i = 0; i < exc_type->type_info_table->count; i++) { cxx_type_info *type = exc_type->type_info_table->info[i]; @@ -300,13 +308,13 @@ MSVCRT_terminate(); } handler = descr->unwind_table[trylevel].handler; + trylevel = descr->unwind_table[trylevel].prev; if (handler) { TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n", handler, trylevel, last_level, &frame->ebp ); call_ebp_func( handler, &frame->ebp ); } - trylevel = descr->unwind_table[trylevel].prev; } frame->trylevel = last_level; } @@ -383,9 +391,10 @@ if (!descr->tryblock_count) return ExceptionContinueSearch; exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; + if (rec->ExceptionCode != CXX_EXCEPTION) goto normal_handler; if (rec->ExceptionInformation[0] != CXX_FRAME_MAGIC) goto normal_handler; - if (exc_type->custom_handler) + if (exc_type!=NULL && exc_type->custom_handler) return exc_type->custom_handler( rec, frame, exc_context, dispatch, descr, 0, 0, 0 ); normal_handler: @@ -422,6 +431,8 @@ #endif /* __i386__ */ +extern DWORD LastExceptionObj_tls_index, LastExceptionType_tls_index; + /********************************************************************* * _CxxThrowException (MSVCRT.@) */ @@ -429,6 +440,17 @@ { DWORD args[3]; + if(object==NULL && type==NULL) + { + object=TlsGetValue(LastExceptionObj_tls_index); + type=(cxx_exception_type*)TlsGetValue(LastExceptionType_tls_index); + } + else + { + TlsSetValue(LastExceptionObj_tls_index,object); + TlsSetValue(LastExceptionType_tls_index,type); + } + args[0] = CXX_FRAME_MAGIC; args[1] = (DWORD)object; args[2] = (DWORD)type; diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/msvcrt/main.c ./dlls/msvcrt/main.c --- ../wine.test/dlls/msvcrt/main.c 2002-10-25 00:03:04.000000000 -0500 +++ ./dlls/msvcrt/main.c 2002-10-28 08:26:47.000000000 -0600 @@ -29,6 +29,10 @@ /* Index to TLS */ DWORD MSVCRT_tls_index; +/* TLS for re-throwing exceptions */ +DWORD LastExceptionObj_tls_index; +DWORD LastExceptionType_tls_index; + static inline BOOL msvcrt_init_tls(void); static inline BOOL msvcrt_free_tls(void); const char* msvcrt_get_reason(DWORD reason) WINE_UNUSED; @@ -91,6 +95,21 @@ ERR("TlsAlloc() failed!\n"); return FALSE; } + + LastExceptionObj_tls_index=TlsAlloc(); + if (LastExceptionObj_tls_index == TLS_OUT_OF_INDEXES) + { + ERR("TlsAlloc() failed!\n"); + return FALSE; + } + + LastExceptionType_tls_index=TlsAlloc(); + if(LastExceptionType_tls_index == TLS_OUT_OF_INDEXES) + { + ERR("TlsAlloc() failed!\n"); + return FALSE; + } + return TRUE; } @@ -101,6 +120,16 @@ ERR("TlsFree() failed!\n"); return FALSE; } + if (!TlsFree(LastExceptionObj_tls_index)) + { + ERR("TlsFree() failed!\n"); + return FALSE; + } + if (!TlsFree(LastExceptionType_tls_index)) + { + ERR("TlsFree() failed!\n"); + return FALSE; + } return TRUE; }