[CPPRT]
authorThomas Faber <thomas.faber@reactos.org>
Sat, 28 Feb 2015 21:03:04 +0000 (21:03 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sat, 28 Feb 2015 21:03:04 +0000 (21:03 +0000)
- Implement __CxxFrameHandler3 as a wrapper around __CxxFrameHandler that translates VC8-style function exception descriptions to VC7-style. This is necessary to make C++ exceptions work on Windows Server 2003, because msvcrt!__CxxFrameHandler does not support VC8 descriptors there.
CORE-9290 #resolve

svn path=/trunk/; revision=66503

reactos/lib/sdk/cpprt/CMakeLists.txt
reactos/lib/sdk/cpprt/i386/cpprt.s
reactos/lib/sdk/cpprt/i386/framehandler.c [new file with mode: 0644]

index 4bc1ee5..eb2947d 100644 (file)
@@ -1,12 +1,15 @@
 
 set_cpp(WITH_EXCEPTIONS)
 
+include_directories(${REACTOS_SOURCE_DIR}/lib/sdk/crt/include)
+
 list(APPEND SOURCE
     ehvec.cpp
     typeinfo.cpp)
 
 if(ARCH STREQUAL "i386")
   add_asm_files(cpprt_asm i386/cpprt.s)
+  list(APPEND SOURCE i386/framehandler.c)
 elseif(ARCH STREQUAL "amd64")
   add_asm_files(cpprt_asm amd64/cpprt.s)
 endif()
index 9219ede..da85111 100644 (file)
@@ -7,13 +7,27 @@ EXTERN &orig:&type
 ALIAS <&alias> = <&orig>
 ENDM
 
+EXTERN _CxxHandleV8Frame@20 : PROC
+PUBLIC ___CxxFrameHandler3
+___CxxFrameHandler3:
+    push eax
+    push dword ptr [esp + 20]
+    push dword ptr [esp + 20]
+    push dword ptr [esp + 20]
+    push dword ptr [esp + 20]
+    call _CxxHandleV8Frame@20
+    ret
+
+EXTERN ___CxxFrameHandler : PROC
+PUBLIC _CallCxxFrameHandler
+_CallCxxFrameHandler:
+    mov eax, dword ptr [esp + 20]
+    jmp ___CxxFrameHandler
+
 ; void __stdcall `eh vector constructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *),void (__thiscall*)(void *))
 DEFINE_ALIAS ??_L@YGXPAXIHP6EX0@Z1@Z, ?MSVCRTEX_eh_vector_constructor_iterator@@YGXPAXIHP6EX0@Z1@Z
 
 ; void __stdcall `eh vector destructor iterator'(void *,unsigned int,int,void (__thiscall*)(void *))
 DEFINE_ALIAS ??_M@YGXPAXIHP6EX0@Z@Z, ?MSVCRTEX_eh_vector_destructor_iterator@@YGXPAXIHP6EX0@Z@Z
 
-; These are the same
-DEFINE_ALIAS ___CxxFrameHandler3, ___CxxFrameHandler
-
 END
diff --git a/reactos/lib/sdk/cpprt/i386/framehandler.c b/reactos/lib/sdk/cpprt/i386/framehandler.c
new file mode 100644 (file)
index 0000000..806204f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * PROJECT:         ReactOS C++ runtime library
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         __CxxFrameHandler3 to __CxxFrameHandler wrapper
+ * PROGRAMMER:      Thomas Faber (thomas.faber@reactos.org)
+ */
+
+#define WIN32_NO_STATUS
+#include <windef.h>
+#include <winbase.h>
+#include <ndk/rtltypes.h>
+
+#define WINE_NO_TRACE_MSGS
+#include <wine/debug.h>
+#include <wine/exception.h>
+#include <internal/wine/msvcrt.h>
+#include <internal/wine/cppexcept.h>
+
+extern DWORD CDECL CallCxxFrameHandler(PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD *frame,
+                                       PCONTEXT context, EXCEPTION_REGISTRATION_RECORD **dispatch,
+                                       const cxx_function_descr *descr);
+
+DWORD
+__stdcall
+CxxHandleV8Frame(
+    _In_ PEXCEPTION_RECORD rec,
+    _In_ EXCEPTION_REGISTRATION_RECORD *frame,
+    _In_ PCONTEXT context,
+    _In_ EXCEPTION_REGISTRATION_RECORD **dispatch,
+    _In_ const cxx_function_descr *descr)
+{
+    cxx_function_descr stub_descr;
+
+    if (descr->magic != CXX_FRAME_MAGIC_VC8)
+        return CallCxxFrameHandler(rec, frame, context, dispatch, descr);
+
+    if ((descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
+        (rec->ExceptionCode != CXX_EXCEPTION))
+    {
+        return ExceptionContinueSearch;  /* handle only c++ exceptions */
+    }
+
+    stub_descr = *descr;
+    stub_descr.magic = CXX_FRAME_MAGIC_VC7;
+    return CallCxxFrameHandler(rec, frame, context, dispatch, &stub_descr);
+}