diff --git a/dll/win32/mshtml/ifacewrap.c b/dll/win32/mshtml/ifacewrap.c
index cc22246a72b..e78464d88b0 100644
--- a/dll/win32/mshtml/ifacewrap.c
+++ b/dll/win32/mshtml/ifacewrap.c
@@ -17,6 +17,7 @@
*/
#include "mshtml_private.h"
+#include
/*
* This object wraps any unrecognized interface overriding its IUnknown methods, allowing
diff --git a/dll/win32/msi/custom.c b/dll/win32/msi/custom.c
index 310a1441738..8680b7214b3 100644
--- a/dll/win32/msi/custom.c
+++ b/dll/win32/msi/custom.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "wine/port.h"
+#include "wine/asm.h"
#define COBJMACROS
diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec
index 576b9800eb0..4e0c07aa950 100644
--- a/dll/win32/msvcrt/msvcrt.spec
+++ b/dll/win32/msvcrt/msvcrt.spec
@@ -1,64 +1,64 @@
# msvcrt.dll - MS VC++ Run Time Library
# **************** x86 C++ functions ****************
-@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_copy_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(class __non_rtti_object const &)
-@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@PBD@Z(ptr) __thiscall_MSVCRT___non_rtti_object_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(char const *)
-@ cdecl -i386 -norelay ??0bad_cast@@AAE@PBQBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor # private: __thiscall bad_cast::bad_cast(char const * const *)
-@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor # public: __thiscall bad_cast::bad_cast(char const * const &)
-@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_copy_ctor # public: __thiscall bad_cast::bad_cast(class bad_cast const &)
-@ cdecl -i386 -norelay ??0bad_cast@@QAE@PBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor_charptr # public: __thiscall bad_cast::bad_cast(char const *)
-@ cdecl -i386 -norelay ??0bad_typeid@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_copy_ctor # public: __thiscall bad_typeid::bad_typeid(class bad_typeid const &)
-@ cdecl -i386 -norelay ??0bad_typeid@@QAE@PBD@Z(ptr) __thiscall_MSVCRT_bad_typeid_ctor # public: __thiscall bad_typeid::bad_typeid(char const *)
-@ cdecl -i386 -norelay ??0exception@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_exception_ctor # public: __thiscall exception::exception(char const * const &)
-@ cdecl -i386 -norelay ??0exception@@QAE@ABQBDH@Z(ptr long) __thiscall_MSVCRT_exception_ctor_noalloc # public: __thiscall exception::exception(char const * const &,int)
-@ cdecl -i386 -norelay ??0exception@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_copy_ctor # public: __thiscall exception::exception(class exception const &)
-@ cdecl -i386 -norelay ??0exception@@QAE@XZ() __thiscall_MSVCRT_exception_default_ctor # public: __thiscall exception::exception(void)
-@ cdecl -i386 -norelay ??1__non_rtti_object@@UAE@XZ() __thiscall_MSVCRT___non_rtti_object_dtor # public: virtual __thiscall __non_rtti_object::~__non_rtti_object(void)
-@ cdecl -i386 -norelay ??1bad_cast@@UAE@XZ() __thiscall_MSVCRT_bad_cast_dtor # public: virtual __thiscall bad_cast::~bad_cast(void)
-@ cdecl -i386 -norelay ??1bad_typeid@@UAE@XZ() __thiscall_MSVCRT_bad_typeid_dtor # public: virtual __thiscall bad_typeid::~bad_typeid(void)
-@ cdecl -i386 -norelay ??1exception@@UAE@XZ() __thiscall_MSVCRT_exception_dtor # public: virtual __thiscall exception::~exception(void)
-@ cdecl -i386 -norelay ??1type_info@@UAE@XZ() __thiscall_MSVCRT_type_info_dtor # public: virtual __thiscall type_info::~type_info(void)
+@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) MSVCRT___non_rtti_object_copy_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(class __non_rtti_object const &)
+@ cdecl -i386 -norelay ??0__non_rtti_object@@QAE@PBD@Z(ptr) MSVCRT___non_rtti_object_ctor # public: __thiscall __non_rtti_object::__non_rtti_object(char const *)
+@ cdecl -i386 -norelay ??0bad_cast@@AAE@PBQBD@Z(ptr) MSVCRT_bad_cast_ctor # private: __thiscall bad_cast::bad_cast(char const * const *)
+@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABQBD@Z(ptr) MSVCRT_bad_cast_ctor # public: __thiscall bad_cast::bad_cast(char const * const &)
+@ cdecl -i386 -norelay ??0bad_cast@@QAE@ABV0@@Z(ptr) MSVCRT_bad_cast_copy_ctor # public: __thiscall bad_cast::bad_cast(class bad_cast const &)
+@ cdecl -i386 -norelay ??0bad_cast@@QAE@PBD@Z(ptr) MSVCRT_bad_cast_ctor_charptr # public: __thiscall bad_cast::bad_cast(char const *)
+@ cdecl -i386 -norelay ??0bad_typeid@@QAE@ABV0@@Z(ptr) MSVCRT_bad_typeid_copy_ctor # public: __thiscall bad_typeid::bad_typeid(class bad_typeid const &)
+@ cdecl -i386 -norelay ??0bad_typeid@@QAE@PBD@Z(ptr) MSVCRT_bad_typeid_ctor # public: __thiscall bad_typeid::bad_typeid(char const *)
+@ cdecl -i386 -norelay ??0exception@@QAE@ABQBD@Z(ptr) MSVCRT_exception_ctor # public: __thiscall exception::exception(char const * const &)
+@ cdecl -i386 -norelay ??0exception@@QAE@ABQBDH@Z(ptr long) MSVCRT_exception_ctor_noalloc # public: __thiscall exception::exception(char const * const &,int)
+@ cdecl -i386 -norelay ??0exception@@QAE@ABV0@@Z(ptr) MSVCRT_exception_copy_ctor # public: __thiscall exception::exception(class exception const &)
+@ cdecl -i386 -norelay ??0exception@@QAE@XZ() MSVCRT_exception_default_ctor # public: __thiscall exception::exception(void)
+@ cdecl -i386 -norelay ??1__non_rtti_object@@UAE@XZ() MSVCRT___non_rtti_object_dtor # public: virtual __thiscall __non_rtti_object::~__non_rtti_object(void)
+@ cdecl -i386 -norelay ??1bad_cast@@UAE@XZ() MSVCRT_bad_cast_dtor # public: virtual __thiscall bad_cast::~bad_cast(void)
+@ cdecl -i386 -norelay ??1bad_typeid@@UAE@XZ() MSVCRT_bad_typeid_dtor # public: virtual __thiscall bad_typeid::~bad_typeid(void)
+@ cdecl -i386 -norelay ??1exception@@UAE@XZ() MSVCRT_exception_dtor # public: virtual __thiscall exception::~exception(void)
+@ cdecl -i386 -norelay ??1type_info@@UAE@XZ() MSVCRT_type_info_dtor # public: virtual __thiscall type_info::~type_info(void)
@ cdecl -i386 ??2@YAPAXI@Z(long) MSVCRT_operator_new # void * __cdecl operator new(unsigned int)
;@ cdecl -i386 ??2@YAPAXIHPBDH@Z(long long str long) MSVCRT_operator_new_dbg # void * __cdecl operator new(unsigned int,int,char const *,int)
@ cdecl -i386 ??3@YAXPAX@Z(ptr) MSVCRT_operator_delete # void __cdecl operator delete(void *)
-@ cdecl -i386 -norelay ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_opequals # public: class __non_rtti_object & __thiscall __non_rtti_object::operator=(class __non_rtti_object const &)
-@ cdecl -i386 -norelay ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_opequals # public: class bad_cast & __thiscall bad_cast::operator=(class bad_cast const &)
-@ cdecl -i386 -norelay ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_opequals # public: class bad_typeid & __thiscall bad_typeid::operator=(class bad_typeid const &)
-@ cdecl -i386 -norelay ??4exception@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_opequals # public: class exception & __thiscall exception::operator=(class exception const &)
-@ cdecl -i386 -norelay ??8type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opequals_equals # public: int __thiscall type_info::operator==(class type_info const &)const
-@ cdecl -i386 -norelay ??9type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opnot_equals # public: int __thiscall type_info::operator!=(class type_info const &)const
+@ cdecl -i386 -norelay ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) MSVCRT___non_rtti_object_opequals # public: class __non_rtti_object & __thiscall __non_rtti_object::operator=(class __non_rtti_object const &)
+@ cdecl -i386 -norelay ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_cast_opequals # public: class bad_cast & __thiscall bad_cast::operator=(class bad_cast const &)
+@ cdecl -i386 -norelay ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_typeid_opequals # public: class bad_typeid & __thiscall bad_typeid::operator=(class bad_typeid const &)
+@ cdecl -i386 -norelay ??4exception@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_exception_opequals # public: class exception & __thiscall exception::operator=(class exception const &)
+@ cdecl -i386 -norelay ??8type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opequals_equals # public: int __thiscall type_info::operator==(class type_info const &)const
+@ cdecl -i386 -norelay ??9type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opnot_equals # public: int __thiscall type_info::operator!=(class type_info const &)const
@ extern -i386 ??_7__non_rtti_object@@6B@ MSVCRT___non_rtti_object_vtable # const __non_rtti_object::`vftable'
@ extern -i386 ??_7bad_cast@@6B@ MSVCRT_bad_cast_vtable # const bad_cast::`vftable'
@ extern -i386 ??_7bad_typeid@@6B@ MSVCRT_bad_typeid_vtable # const bad_typeid::`vftable'
@ extern -i386 ??_7exception@@6B@ MSVCRT_exception_vtable # const exception::`vftable'
-@ cdecl -i386 -norelay ??_E__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_vector_dtor # public: virtual void * __thiscall __non_rtti_object::`vector deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Ebad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_vector_dtor # public: virtual void * __thiscall bad_cast::`vector deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Ebad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_vector_dtor # public: virtual void * __thiscall bad_typeid::`vector deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Eexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_vector_dtor # public: virtual void * __thiscall exception::`vector deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Fbad_cast@@QAEXXZ() __thiscall_MSVCRT_bad_cast_default_ctor # public: void __thiscall bad_cast::`default constructor closure'(void)
-@ cdecl -i386 -norelay ??_Fbad_typeid@@QAEXXZ() __thiscall_MSVCRT_bad_typeid_default_ctor # public: void __thiscall bad_typeid::`default constructor closure'(void)
-@ cdecl -i386 -norelay ??_G__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_scalar_dtor # public: virtual void * __thiscall __non_rtti_object::`scalar deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Gbad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_scalar_dtor # public: virtual void * __thiscall bad_cast::`scalar deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Gbad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_scalar_dtor # public: virtual void * __thiscall bad_typeid::`scalar deleting destructor'(unsigned int)
-@ cdecl -i386 -norelay ??_Gexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_scalar_dtor # public: virtual void * __thiscall exception::`scalar deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_E__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_vector_dtor # public: virtual void * __thiscall __non_rtti_object::`vector deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Ebad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_vector_dtor # public: virtual void * __thiscall bad_cast::`vector deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Ebad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_vector_dtor # public: virtual void * __thiscall bad_typeid::`vector deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Eexception@@UAEPAXI@Z(long) MSVCRT_exception_vector_dtor # public: virtual void * __thiscall exception::`vector deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Fbad_cast@@QAEXXZ() MSVCRT_bad_cast_default_ctor # public: void __thiscall bad_cast::`default constructor closure'(void)
+@ cdecl -i386 -norelay ??_Fbad_typeid@@QAEXXZ() MSVCRT_bad_typeid_default_ctor # public: void __thiscall bad_typeid::`default constructor closure'(void)
+@ cdecl -i386 -norelay ??_G__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_scalar_dtor # public: virtual void * __thiscall __non_rtti_object::`scalar deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Gbad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_scalar_dtor # public: virtual void * __thiscall bad_cast::`scalar deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Gbad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_scalar_dtor # public: virtual void * __thiscall bad_typeid::`scalar deleting destructor'(unsigned int)
+@ cdecl -i386 -norelay ??_Gexception@@UAEPAXI@Z(long) MSVCRT_exception_scalar_dtor # public: virtual void * __thiscall exception::`scalar deleting destructor'(unsigned int)
@ cdecl -i386 ??_U@YAPAXI@Z(long) MSVCRT_operator_new # void * __cdecl operator new[](unsigned int)
;@ cdecl -i386 ??_U@YAPAXIHPBDH@Z(long long str long) MSVCRT_operator_new_dbg # void * __cdecl operator new[](unsigned int,int,char const *,int)
@ cdecl -i386 ??_V@YAXPAX@Z(ptr) MSVCRT_operator_delete # void __cdecl operator delete[](void *)
-@ cdecl -i386 -norelay __uncaught_exception(ptr)
+@ cdecl -i386 -norelay __uncaught_exception(ptr) MSVCRT___uncaught_exception
@ cdecl -i386 -norelay ?_query_new_handler@@YAP6AHI@ZXZ() MSVCRT__query_new_handler # int (__cdecl*__cdecl _query_new_handler(void))(unsigned int)
@ cdecl -i386 ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode # int __cdecl _query_new_mode(void)
@ cdecl -i386 -norelay ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z(ptr) MSVCRT__set_new_handler # int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned int)))(unsigned int)
@ cdecl -i386 ?_set_new_mode@@YAHH@Z(long) MSVCRT__set_new_mode # int __cdecl _set_new_mode(int)
@ cdecl -i386 -norelay ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z(ptr) MSVCRT__set_se_translator # void (__cdecl*__cdecl _set_se_translator(void (__cdecl*)(unsigned int,struct _EXCEPTION_POINTERS *)))(unsigned int,struct _EXCEPTION_POINTERS *)
-@ cdecl -i386 -norelay ?before@type_info@@QBEHABV1@@Z(ptr) __thiscall_MSVCRT_type_info_before # public: int __thiscall type_info::before(class type_info const &)const
-@ cdecl -i386 -norelay ?name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_name # public: char const * __thiscall type_info::name(void)const
-@ cdecl -i386 -norelay ?raw_name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_raw_name # public: char const * __thiscall type_info::raw_name(void)const
+@ cdecl -i386 -norelay ?before@type_info@@QBEHABV1@@Z(ptr) MSVCRT_type_info_before # public: int __thiscall type_info::before(class type_info const &)const
+@ cdecl -i386 -norelay ?name@type_info@@QBEPBDXZ() MSVCRT_type_info_name # public: char const * __thiscall type_info::name(void)const
+@ cdecl -i386 -norelay ?raw_name@type_info@@QBEPBDXZ() MSVCRT_type_info_raw_name # public: char const * __thiscall type_info::raw_name(void)const
@ cdecl -i386 ?set_new_handler@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_new_handler # void (__cdecl*__cdecl set_new_handler(void (__cdecl*)(void)))(void)
@ cdecl -i386 ?set_terminate@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_terminate # void (__cdecl*__cdecl set_terminate(void (__cdecl*)(void)))(void)
@ cdecl -i386 ?set_unexpected@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_unexpected # void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void)
@ cdecl -i386 ?terminate@@YAXXZ() MSVCRT_terminate # void __cdecl terminate(void)
@ cdecl -i386 ?unexpected@@YAXXZ() MSVCRT_unexpected # void __cdecl unexpected(void)
-@ cdecl -i386 -norelay ?what@exception@@UBEPBDXZ() __thiscall_MSVCRT_what_exception # public: virtual char const * __thiscall exception::what(void)const
+@ cdecl -i386 -norelay ?what@exception@@UBEPBDXZ() MSVCRT_what_exception # public: virtual char const * __thiscall exception::what(void)const
# **************** win64 C++ functions ****************
@ cdecl -arch=win64 ??0__non_rtti_object@@QEAA@AEBV0@@Z(ptr) MSVCRT___non_rtti_object_copy_ctor # public: __cdecl __non_rtti_object::__non_rtti_object(class __non_rtti_object const & __ptr64) __ptr64
@@ -94,7 +94,7 @@
@ cdecl -arch=win64 ??_Fbad_typeid@@QEAAXXZ() MSVCRT_bad_typeid_default_ctor # public: void __cdecl bad_typeid::`default constructor closure'(void) __ptr64
@ cdecl -arch=win64 ??_U@YAPEAX_K@Z(long) MSVCRT_operator_new # void * __ptr64 __cdecl operator new[](unsigned __int64)
@ cdecl -arch=win64 ??_V@YAXPEAX@Z(ptr) MSVCRT_operator_delete # void __cdecl operator delete[](void * __ptr64)
-@ cdecl -arch=win64 __uncaught_exception(ptr)
+@ cdecl -arch=win64 __uncaught_exception(ptr) MSVCRT___uncaught_exception
@ cdecl -arch=win64 ?_query_new_handler@@YAP6AH_K@ZXZ() MSVCRT__query_new_handler # int (__cdecl*__cdecl _query_new_handler(void))(unsigned __int64)
@ cdecl -arch=win64 ?_query_new_mode@@YAHXZ() MSVCRT__query_new_mode # int __cdecl _query_new_mode(void)
@ cdecl -arch=win64 ?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z(ptr) MSVCRT__set_new_handler # int (__cdecl*__cdecl _set_new_handler(int (__cdecl*)(unsigned __int64)))(unsigned __int64)
@@ -108,7 +108,7 @@
@ cdecl -arch=win64 ?set_unexpected@@YAP6AXXZP6AXXZ@Z(ptr) MSVCRT_set_unexpected # void (__cdecl*__cdecl set_unexpected(void (__cdecl*)(void)))(void)
@ cdecl -arch=win64 ?terminate@@YAXXZ() MSVCRT_terminate # void __cdecl terminate(void)
@ cdecl -arch=win64 ?unexpected@@YAXXZ() MSVCRT_unexpected # void __cdecl unexpected(void)
-@ cdecl -arch=win64 -stub ?what@exception@@UEBAPEBDXZ() MSVCRT_what_exception # public: virtual char const * __ptr64 __cdecl exception::what(void)const __ptr64
+@ cdecl -arch=win64 ?what@exception@@UEBAPEBDXZ() MSVCRT_what_exception # public: virtual char const * __ptr64 __cdecl exception::what(void)const __ptr64
# **************** ARM C++ functions ****************
@ cdecl -arch=arm ??0__non_rtti_object@@QAA@ABV0@@Z() MSVCRT___non_rtti_object_copy_ctor # public: __cdecl __non_rtti_object::__non_rtti_object(class __non_rtti_object const &)
@@ -204,14 +204,14 @@
# stub __CxxCallUnwindDtor
# stub __CxxCallUnwindVecDtor
@ cdecl __CxxDetectRethrow(ptr)
-# stub __CxxExceptionFilter
+@ cdecl __CxxExceptionFilter()
@ cdecl -arch=i386,x86_64 -norelay __CxxFrameHandler(ptr ptr ptr ptr)
@ cdecl -arch=i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler
@ cdecl -arch=arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr)
@ stdcall -i386 __CxxLongjmpUnwind(ptr)
@ cdecl -i386 __CxxQueryExceptionSize()
-# stub -i386 __CxxRegisterExceptionObject
-# stub -i386 __CxxUnregisterExceptionObject
+@ cdecl -i386 __CxxRegisterExceptionObject()
+@ cdecl -i386 __CxxUnregisterExceptionObject()
@ cdecl -version=0x600+ __DestructExceptionObject(ptr)
@ cdecl __RTCastToVoid(ptr) MSVCRT___RTCastToVoid
@ cdecl __RTDynamicCast(ptr long ptr ptr long) MSVCRT___RTDynamicCast
@@ -329,7 +329,7 @@
@ cdecl _callnewh(long)
@ cdecl _cexit()
@ cdecl _cgets(str)
-# stub _cgetws
+@ cdecl -stub _cgetws(wstr)
@ cdecl _chdir(str)
@ cdecl _chdrive(long)
@ cdecl _chgsign(double)
@@ -347,14 +347,14 @@
@ cdecl -arch=x86_64,arm _copysignf(long long)
@ varargs _cprintf(str)
@ cdecl _cputs(str)
-# stub _cputws
+@ cdecl -stub _cputws(wstr)
@ cdecl _creat(str long)
@ varargs _cscanf(str)
@ cdecl _ctime64(ptr)
@ extern _ctype
@ cdecl _cwait(ptr long long)
@ varargs _cwprintf(wstr)
-# @ varargs _cwscanf(wstr)
+@ varargs -stub _cwscanf(wstr)
@ extern _daylight
@ extern _dstbias
@ cdecl _dup(long)
@@ -431,8 +431,8 @@
@ cdecl _getpid() kernel32.GetCurrentProcessId
@ cdecl _getsystime(ptr)
@ cdecl _getw(ptr)
-# stub _getwch
-# stub _getwche
+@ cdecl -stub _getwch()
+@ cdecl -stub _getwche()
@ cdecl _getws(ptr)
@ cdecl -i386 _global_unwind2(ptr)
@ cdecl _gmtime64(ptr)
diff --git a/dll/win32/msvcrt40/msvcrt40.spec b/dll/win32/msvcrt40/msvcrt40.spec
index fab52fec803..d1efd557b46 100644
--- a/dll/win32/msvcrt40/msvcrt40.spec
+++ b/dll/win32/msvcrt40/msvcrt40.spec
@@ -1,14 +1,14 @@
@ stub ??0Iostream_init@@QAE@AAVios@@H@Z
@ stub ??0Iostream_init@@QAE@XZ
-@ cdecl -i386 ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_copy_ctor
-@ cdecl -i386 ??0__non_rtti_object@@QAE@PBD@Z(ptr) __thiscall_MSVCRT___non_rtti_object_ctor
-@ cdecl -i386 ??0bad_cast@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_bad_cast_ctor
-@ cdecl -i386 ??0bad_cast@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_copy_ctor
-@ cdecl -i386 ??0bad_typeid@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_copy_ctor
-@ cdecl -i386 ??0bad_typeid@@QAE@PBD@Z(ptr) __thiscall_MSVCRT_bad_typeid_ctor
-@ cdecl -i386 ??0exception@@QAE@ABQBD@Z(ptr) __thiscall_MSVCRT_exception_ctor
-@ cdecl -i386 ??0exception@@QAE@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_copy_ctor
-@ cdecl -i386 ??0exception@@QAE@XZ() __thiscall_MSVCRT_exception_default_ctor
+@ cdecl -i386 ??0__non_rtti_object@@QAE@ABV0@@Z(ptr) MSVCRT___non_rtti_object_copy_ctor
+@ cdecl -i386 ??0__non_rtti_object@@QAE@PBD@Z(ptr) MSVCRT___non_rtti_object_ctor
+@ cdecl -i386 ??0bad_cast@@QAE@ABQBD@Z(ptr) MSVCRT_bad_cast_ctor
+@ cdecl -i386 ??0bad_cast@@QAE@ABV0@@Z(ptr) MSVCRT_bad_cast_copy_ctor
+@ cdecl -i386 ??0bad_typeid@@QAE@ABV0@@Z(ptr) MSVCRT_bad_typeid_copy_ctor
+@ cdecl -i386 ??0bad_typeid@@QAE@PBD@Z(ptr) MSVCRT_bad_typeid_ctor
+@ cdecl -i386 ??0exception@@QAE@ABQBD@Z(ptr) MSVCRT_exception_ctor
+@ cdecl -i386 ??0exception@@QAE@ABV0@@Z(ptr) MSVCRT_exception_copy_ctor
+@ cdecl -i386 ??0exception@@QAE@XZ() MSVCRT_exception_default_ctor
@ stub ??0filebuf@@QAE@ABV0@@Z
@ stub ??0filebuf@@QAE@H@Z
@ stub ??0filebuf@@QAE@HPADH@Z
@@ -70,10 +70,10 @@
@ stub ??0strstreambuf@@QAE@PADH0@Z
@ stub ??0strstreambuf@@QAE@XZ
@ stub ??1Iostream_init@@QAE@XZ
-@ cdecl -i386 ??1__non_rtti_object@@UAE@XZ() __thiscall_MSVCRT___non_rtti_object_dtor
-@ cdecl -i386 ??1bad_cast@@UAE@XZ() __thiscall_MSVCRT_bad_cast_dtor
-@ cdecl -i386 ??1bad_typeid@@UAE@XZ() __thiscall_MSVCRT_bad_typeid_dtor
-@ cdecl -i386 ??1exception@@UAE@XZ() __thiscall_MSVCRT_exception_dtor
+@ cdecl -i386 ??1__non_rtti_object@@UAE@XZ() MSVCRT___non_rtti_object_dtor
+@ cdecl -i386 ??1bad_cast@@UAE@XZ() MSVCRT_bad_cast_dtor
+@ cdecl -i386 ??1bad_typeid@@UAE@XZ() MSVCRT_bad_typeid_dtor
+@ cdecl -i386 ??1exception@@UAE@XZ() MSVCRT_exception_dtor
@ stub ??1filebuf@@UAE@XZ
@ stub ??1fstream@@UAE@XZ
@ stub ??1ifstream@@UAE@XZ
@@ -92,16 +92,16 @@
@ stub ??1streambuf@@UAE@XZ
@ stub ??1strstream@@UAE@XZ
@ stub ??1strstreambuf@@UAE@XZ
-@ cdecl -i386 ??1type_info@@UAE@XZ() __thiscall_MSVCRT_type_info_dtor
+@ cdecl -i386 ??1type_info@@UAE@XZ() MSVCRT_type_info_dtor
@ cdecl -arch=win32 ??2@YAPAXI@Z(long) MSVCRT_operator_new
@ cdecl -arch=win64 ??2@YAPEAX_K@Z(double) MSVCRT_operator_new
@ cdecl -arch=win32 ??3@YAXPAX@Z(ptr) MSVCRT_operator_delete
@ cdecl -arch=win64 ??3@YAXPEAX@Z(ptr) MSVCRT_operator_delete
@ stub ??4Iostream_init@@QAEAAV0@ABV0@@Z
-@ cdecl -i386 ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_opequals
-@ cdecl -i386 ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_cast_opequals
-@ cdecl -i386 ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_opequals
-@ cdecl -i386 ??4exception@@QAEAAV0@ABV0@@Z(ptr) __thiscall_MSVCRT_exception_opequals
+@ cdecl -i386 ??4__non_rtti_object@@QAEAAV0@ABV0@@Z(ptr) MSVCRT___non_rtti_object_opequals
+@ cdecl -i386 ??4bad_cast@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_cast_opequals
+@ cdecl -i386 ??4bad_typeid@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_bad_typeid_opequals
+@ cdecl -i386 ??4exception@@QAEAAV0@ABV0@@Z(ptr) MSVCRT_exception_opequals
@ stub ??4filebuf@@QAEAAV0@ABV0@@Z
@ stub ??4fstream@@QAEAAV0@AAV0@@Z
@ stub ??4ifstream@@QAEAAV0@ABV0@@Z
@@ -165,8 +165,8 @@
@ stub ??6ostream@@QAEAAV0@PBE@Z
@ stub ??6ostream@@QAEAAV0@PBX@Z
@ stub ??7ios@@QBEHXZ
-@ cdecl -i386 ??8type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opequals_equals
-@ cdecl -i386 ??9type_info@@QBEHABV0@@Z(ptr) __thiscall_MSVCRT_type_info_opnot_equals
+@ cdecl -i386 ??8type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opequals_equals
+@ cdecl -i386 ??9type_info@@QBEHABV0@@Z(ptr) MSVCRT_type_info_opnot_equals
@ stub ??Bios@@QBEPAXXZ
@ extern -i386 ??_7__non_rtti_object@@6B@ MSVCRT___non_rtti_object_vtable
@ extern -i386 ??_7bad_cast@@6B@ MSVCRT_bad_cast_vtable
@@ -219,10 +219,10 @@
@ stub ??_Dstdiostream@@QAEXXZ
@ stub ??_Dstrstream@@QAEXXZ
@ stub ??_EIostream_init@@QAEPAXI@Z
-@ cdecl -i386 ??_E__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_vector_dtor
-@ cdecl -i386 ??_Ebad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_vector_dtor
-@ cdecl -i386 ??_Ebad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_vector_dtor
-@ cdecl -i386 ??_Eexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_vector_dtor
+@ cdecl -i386 ??_E__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_vector_dtor
+@ cdecl -i386 ??_Ebad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_vector_dtor
+@ cdecl -i386 ??_Ebad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_vector_dtor
+@ cdecl -i386 ??_Eexception@@UAEPAXI@Z(long) MSVCRT_exception_vector_dtor
@ stub ??_Efilebuf@@UAEPAXI@Z
@ stub ??_Efstream@@UAEPAXI@Z
@ stub ??_Eifstream@@UAEPAXI@Z
@@ -242,10 +242,10 @@
@ stub ??_Estrstream@@UAEPAXI@Z
@ stub ??_Estrstreambuf@@UAEPAXI@Z
@ stub ??_GIostream_init@@QAEPAXI@Z
-@ cdecl -i386 ??_G__non_rtti_object@@UAEPAXI@Z(long) __thiscall_MSVCRT___non_rtti_object_scalar_dtor
-@ cdecl -i386 ??_Gbad_cast@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_cast_scalar_dtor
-@ cdecl -i386 ??_Gbad_typeid@@UAEPAXI@Z(long) __thiscall_MSVCRT_bad_typeid_scalar_dtor
-@ cdecl -i386 ??_Gexception@@UAEPAXI@Z(long) __thiscall_MSVCRT_exception_scalar_dtor
+@ cdecl -i386 ??_G__non_rtti_object@@UAEPAXI@Z(long) MSVCRT___non_rtti_object_scalar_dtor
+@ cdecl -i386 ??_Gbad_cast@@UAEPAXI@Z(long) MSVCRT_bad_cast_scalar_dtor
+@ cdecl -i386 ??_Gbad_typeid@@UAEPAXI@Z(long) MSVCRT_bad_typeid_scalar_dtor
+@ cdecl -i386 ??_Gexception@@UAEPAXI@Z(long) MSVCRT_exception_scalar_dtor
@ stub ??_Gfilebuf@@UAEPAXI@Z
@ stub ??_Gfstream@@UAEPAXI@Z
@ stub ??_Gifstream@@UAEPAXI@Z
@@ -278,7 +278,7 @@
@ stub ?bad@ios@@QBEHXZ
@ stub ?base@streambuf@@IBEPADXZ
@ stub ?basefield@ios@@2JB
-@ cdecl -i386 ?before@type_info@@QBEHABV1@@Z(ptr) __thiscall_MSVCRT_type_info_before
+@ cdecl -i386 ?before@type_info@@QBEHABV1@@Z(ptr) MSVCRT_type_info_before
@ stub ?binary@filebuf@@2HB
@ stub ?bitalloc@ios@@SAJXZ
@ stub ?blen@streambuf@@IBEHXZ
@@ -356,7 +356,7 @@
@ stub ?lockc@ios@@KAXXZ
@ stub ?lockptr@ios@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
@ stub ?lockptr@streambuf@@IAEPAU_CRT_CRITICAL_SECTION@@XZ
-@ cdecl -i386 ?name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_name
+@ cdecl -i386 ?name@type_info@@QBEPBDXZ() MSVCRT_type_info_name
@ stub ?oct@@YAAAVios@@AAV1@@Z
@ stub ?open@filebuf@@QAEPAV1@PBDHH@Z
@ stub ?open@fstream@@QAEXPBDHH@Z
@@ -384,7 +384,7 @@
@ stub ?put@ostream@@QAEAAV1@E@Z
@ stub ?putback@istream@@QAEAAV1@D@Z
@ stub ?pword@ios@@QBEAAPAXH@Z
-@ cdecl -i386 ?raw_name@type_info@@QBEPBDXZ() __thiscall_MSVCRT_type_info_raw_name
+@ cdecl -i386 ?raw_name@type_info@@QBEPBDXZ() MSVCRT_type_info_raw_name
@ stub ?rdbuf@fstream@@QBEPAVfilebuf@@XZ
@ stub ?rdbuf@ifstream@@QBEPAVfilebuf@@XZ
@ stub ?rdbuf@ios@@QBEPAVstreambuf@@XZ
@@ -467,7 +467,7 @@
@ stub ?unlockbuf@ios@@QAAXXZ
@ stub ?unlockc@ios@@KAXXZ
@ stub ?unsetf@ios@@QAEJJ@Z
-@ cdecl -i386 ?what@exception@@UBEPBDXZ() __thiscall_MSVCRT_what_exception
+@ cdecl -i386 ?what@exception@@UBEPBDXZ() MSVCRT_what_exception
@ stub ?width@ios@@QAEHH@Z
@ stub ?width@ios@@QBEHXZ
@ stub ?write@ostream@@QAEAAV1@PBCH@Z
diff --git a/sdk/include/reactos/wine/asm.h b/sdk/include/reactos/wine/asm.h
index 41a5de32026..14406b784eb 100644
--- a/sdk/include/reactos/wine/asm.h
+++ b/sdk/include/reactos/wine/asm.h
@@ -99,6 +99,10 @@
/* thiscall support */
+#ifdef _MSC_VER
+#define __thiscall __stdcall
+#endif
+
#if defined(__i386__) && !defined(__MINGW32__)
# ifdef _MSC_VER
diff --git a/sdk/include/reactos/wine/config.h b/sdk/include/reactos/wine/config.h
index 670320898e4..7fd05d526e3 100644
--- a/sdk/include/reactos/wine/config.h
+++ b/sdk/include/reactos/wine/config.h
@@ -1316,43 +1316,6 @@
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
-/* Define to a macro to output a .cfi assembly pseudo-op */
-#define __ASM_CFI(str) str
-
-/* Define to a macro to define an assembly function */
-#ifndef _MSC_VER
-#ifndef NO_UNDERSCORE_PREFIX
-#define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl _" #name suffix "\n\t.def _" #name suffix "; .scl 2; .type 32; .endef\n_" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc");
-#else
-#define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl " #name suffix "\n\t.def " #name suffix "; .scl 2; .type 32; .endef\n" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc");
-#endif
-#else
-#define __ASM_DEFINE_FUNC(name,suffix,code)
-#endif
-
-/* Define to a macro to generate an assembly function directive */
-#define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef"
-
-/* Define to a macro to generate an assembly function with C calling
- convention */
-#define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(name,"",code)
-
-/* Define to a macro to generate an assembly name from a C symbol */
-#ifndef NO_UNDERSCORE_PREFIX
-#define __ASM_NAME(name) "_" name
-#else
-#define __ASM_NAME(name) name
-#endif
-
-/* Define to a macro to generate an stdcall suffix */
-#define __ASM_STDCALL(args) "@" #args
-
-/* Define to a macro to generate an assembly function with stdcall calling
- convention */
-#ifndef _MSC_VER
-#define __ASM_STDCALL_FUNC(name,args,code) __ASM_DEFINE_FUNC(name,__ASM_STDCALL(args),code)
-#endif
-
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
diff --git a/sdk/include/reactos/wine/exception.h b/sdk/include/reactos/wine/exception.h
index b16d502f826..9b29f2e470f 100644
--- a/sdk/include/reactos/wine/exception.h
+++ b/sdk/include/reactos/wine/exception.h
@@ -16,6 +16,8 @@ extern "C" {
#define EH_EXIT_UNWIND 0x04
#define EH_STACK_INVALID 0x08
#define EH_NESTED_CALL 0x10
+#define EH_TARGET_UNWIND 0x20
+#define EH_COLLIDED_UNWIND 0x40
#define EXCEPTION_WINE_STUB 0x80000100
#define EXCEPTION_WINE_ASSERTION 0x80000101
@@ -56,6 +58,7 @@ typedef struct _WINE_EXCEPTION_REGISTRATION_RECORD
#define __TRY _SEH2_TRY
#define __EXCEPT(func) _SEH2_EXCEPT(func(_SEH2_GetExceptionInformation()))
+#define __EXCEPT_CTX(func, ctx) _SEH2_EXCEPT((func)(GetExceptionInformation(), ctx))
#define __EXCEPT_PAGE_FAULT _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_ACCESS_VIOLATION)
#define __EXCEPT_ALL _SEH2_EXCEPT(_SEH_EXECUTE_HANDLER)
#define __ENDTRY _SEH2_END
diff --git a/sdk/lib/crt/crt.cmake b/sdk/lib/crt/crt.cmake
index 144a6000976..91f186013b6 100644
--- a/sdk/lib/crt/crt.cmake
+++ b/sdk/lib/crt/crt.cmake
@@ -20,12 +20,8 @@ list(APPEND CRT_SOURCE
direct/wgetdcwd.c
direct/wmkdir.c
direct/wrmdir.c
- except/cpp.c
- except/cppexcept.c
- except/except.c
except/matherr.c
except/stack.c
- except/xcptfil.c
float/chgsign.c
float/copysign.c
float/fpclass.c
@@ -360,7 +356,11 @@ list(APPEND CRT_SOURCE
wstring/wcsstr.c
wstring/wcstok.c
wstring/wcsupr.c
- wstring/wcsxfrm.c
+ wstring/wcsxfrm.c)
+
+list(APPEND CRT_WINE_SOURCE
+ wine/cpp.c
+ wine/except.c
wine/heap.c
wine/undname.c)
@@ -424,7 +424,6 @@ if(ARCH STREQUAL "i386")
string/i386/wcsrchr_asm.s)
list(APPEND CRT_SOURCE
- except/i386/unwind.c
float/i386/clearfp.c
float/i386/cntrlfp.c
float/i386/fpreset.c
@@ -437,6 +436,8 @@ if(ARCH STREQUAL "i386")
math/i386/cisin.c
math/i386/cisqrt.c
math/i386/ldexp.c)
+ list(APPEND CRT_WINE_SOURCE
+ wine/except_i386.c)
if(MSVC)
list(APPEND CRT_ASM_SOURCE
except/i386/cpp.s)
@@ -477,6 +478,8 @@ elseif(ARCH STREQUAL "amd64")
except/amd64/ehandler.c
float/i386/cntrlfp.c
float/i386/statfp.c)
+ list(APPEND CRT_WINE_SOURCE
+ wine/except_x86_64.c)
if(MSVC)
list(APPEND CRT_ASM_SOURCE
except/amd64/cpp.s)
@@ -491,6 +494,9 @@ elseif(ARCH STREQUAL "arm")
math/arm/__rt_udiv.c
math/arm/__rt_udiv64_worker.c
)
+ list(APPEND CRT_WINE_SOURCE
+ wine/except_arm.c
+ )
list(APPEND CRT_ASM_SOURCE
except/arm/_abnormal_termination.s
except/arm/_except_handler2.s
@@ -584,6 +590,9 @@ if(NOT ARCH STREQUAL "i386")
string/wcsrchr.c)
endif()
+# includes for wine code
+include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
+
set_source_files_properties(${CRT_ASM_SOURCE} PROPERTIES COMPILE_DEFINITIONS "__MINGW_IMPORT=extern;USE_MSVCRT_PREFIX;_MSVCRT_LIB_;_MSVCRT_;_MT;CRTDLL")
add_asm_files(crt_asm ${CRT_ASM_SOURCE})
@@ -593,7 +602,7 @@ if(USE_CLANG_CL)
set_property(SOURCE stdlib/rot.c APPEND_STRING PROPERTY COMPILE_FLAGS " /fallback")
endif()
-add_library(crt ${CRT_SOURCE} ${crt_asm})
+add_library(crt ${CRT_SOURCE} ${CRT_WINE_SOURCE} ${crt_asm})
target_link_libraries(crt chkstk)
add_target_compile_definitions(crt
__MINGW_IMPORT=extern
diff --git a/sdk/lib/crt/except/amd64/ehandler.c b/sdk/lib/crt/except/amd64/ehandler.c
index 3705e4a7ed7..6e28e78e604 100644
--- a/sdk/lib/crt/except/amd64/ehandler.c
+++ b/sdk/lib/crt/except/amd64/ehandler.c
@@ -16,15 +16,7 @@ __C_specific_handler(
return 0;
}
-DWORD
-__CxxFrameHandler(
- PEXCEPTION_RECORD rec,
- EXCEPTION_REGISTRATION_RECORD* ExceptionRegistrationFrame,
- PCONTEXT context,
- EXCEPTION_REGISTRATION_RECORD** _ExceptionRecord)
+void __cdecl _local_unwind(void* frame, void* target)
{
- UNIMPLEMENTED;
- __debugbreak();
- return 0;
+ RtlUnwind(frame, target, NULL, 0);
}
-
diff --git a/sdk/lib/crt/except/amd64/seh.s b/sdk/lib/crt/except/amd64/seh.s
index 06bd671721d..77d0f368e4d 100644
--- a/sdk/lib/crt/except/amd64/seh.s
+++ b/sdk/lib/crt/except/amd64/seh.s
@@ -18,7 +18,6 @@
/* GLOBALS *******************************************************************/
PUBLIC _global_unwind2
-PUBLIC _local_unwind
PUBLIC _local_unwind2
PUBLIC _abnormal_termination
PUBLIC _except_handler2
@@ -42,11 +41,6 @@ FUNC _abnormal_termination
ret
ENDFUNC
-FUNC _local_unwind
- .endprolog
- ret
-ENDFUNC
-
FUNC _local_unwind2
.endprolog
ret
diff --git a/sdk/lib/crt/except/cpp.c b/sdk/lib/crt/except/cpp.c
deleted file mode 100644
index 67fd29674d2..00000000000
--- a/sdk/lib/crt/except/cpp.c
+++ /dev/null
@@ -1,1266 +0,0 @@
-/*
- * msvcrt.dll C++ objects
- *
- * Copyright 2000 Jon Griffiths
- * Copyright 2003, 2004 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include
-
-#include
-#include
-#include
-
-typedef exception bad_cast;
-typedef exception bad_typeid;
-typedef exception __non_rtti_object;
-
-typedef struct _rtti_base_descriptor
-{
- const type_info *type_descriptor;
- int num_base_classes;
- this_ptr_offsets offsets; /* offsets for computing the this pointer */
- unsigned int attributes;
-} rtti_base_descriptor;
-
-typedef struct _rtti_base_array
-{
- const rtti_base_descriptor *bases[3]; /* First element is the class itself */
-} rtti_base_array;
-
-typedef struct _rtti_object_hierarchy
-{
- unsigned int signature;
- unsigned int attributes;
- int array_len; /* Size of the array pointed to by 'base_classes' */
- const rtti_base_array *base_classes;
-} rtti_object_hierarchy;
-
-typedef struct _rtti_object_locator
-{
- unsigned int signature;
- int base_class_offset;
- unsigned int flags;
- const type_info *type_descriptor;
- const rtti_object_hierarchy *type_hierarchy;
-} rtti_object_locator;
-
-#ifdef __i386__ /* thiscall functions are i386-specific */
-
-#define THISCALL(func) __thiscall_ ## func
-#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func)
-
-#ifdef _MSC_VER
-#include
-#else
-#define DEFINE_THISCALL_WRAPPER(func,args) \
- extern void THISCALL(func)(void); \
- __ASM_GLOBAL_FUNC(__thiscall_ ## func, \
- "popl %eax\n\t" \
- "pushl %ecx\n\t" \
- "pushl %eax\n\t" \
- "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
-#endif /* _MSC_VER */
-
-#else /* __i386__ */
-
-#define THISCALL(func) func
-#define THISCALL_NAME(func) __ASM_NAME(#func)
-#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
-
-#endif /* __i386__ */
-
-extern const vtable_ptr MSVCRT_exception_vtable;
-extern const vtable_ptr MSVCRT_bad_typeid_vtable;
-extern const vtable_ptr MSVCRT_bad_cast_vtable;
-extern const vtable_ptr MSVCRT___non_rtti_object_vtable;
-extern const vtable_ptr MSVCRT_type_info_vtable;
-
-/* get the vtable pointer for a C++ object */
-static inline const vtable_ptr *get_vtable( void *obj )
-{
- return *(const vtable_ptr **)obj;
-}
-
-static inline const rtti_object_locator *get_obj_locator( void *cppobj )
-{
- const vtable_ptr *vtable = get_vtable( cppobj );
- return (const rtti_object_locator *)vtable[-1];
-}
-
-static void dump_obj_locator( const rtti_object_locator *ptr )
-{
- int i;
- const rtti_object_hierarchy *h = ptr->type_hierarchy;
-
- TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
- ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
- ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy );
- TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
- h->signature, h->attributes, h->array_len, h->base_classes );
- for (i = 0; i < h->array_len; i++)
- {
- TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
- h->base_classes->bases[i],
- h->base_classes->bases[i]->num_base_classes,
- h->base_classes->bases[i]->offsets.this_offset,
- h->base_classes->bases[i]->offsets.vbase_descr,
- h->base_classes->bases[i]->offsets.vbase_offset,
- h->base_classes->bases[i]->attributes,
- h->base_classes->bases[i]->type_descriptor,
- dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) );
- }
-}
-
-/* Internal common ctor for exception */
-static void EXCEPTION_ctor(exception *_this, const char** name)
-{
- _this->vtable = &MSVCRT_exception_vtable;
- if (*name)
- {
- size_t name_len = strlen(*name) + 1;
- _this->name = MSVCRT_malloc(name_len);
- memcpy(_this->name, *name, name_len);
- _this->do_free = TRUE;
- }
- else
- {
- _this->name = NULL;
- _this->do_free = FALSE;
- }
-}
-
-/******************************************************************
- * ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor,8)
-exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** name)
-{
- TRACE("(%p,%s)\n", _this, *name);
- EXCEPTION_ctor(_this, name);
- return _this;
-}
-
-/******************************************************************
- * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor_noalloc,12)
-exception * __stdcall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc)
-{
- TRACE("(%p,%s)\n", _this, *name);
- _this->vtable = &MSVCRT_exception_vtable;
- _this->name = *name;
- _this->do_free = FALSE;
- return _this;
-}
-
-/******************************************************************
- * ??0exception@@QAE@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor,8)
-exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs)
-{
- TRACE("(%p,%p)\n", _this, rhs);
-
- if (!rhs->do_free)
- {
- _this->vtable = &MSVCRT_exception_vtable;
- _this->name = rhs->name;
- _this->do_free = FALSE;
- }
- else
- EXCEPTION_ctor(_this, (const char**)&rhs->name);
- TRACE("name = %s\n", _this->name);
- return _this;
-}
-
-/******************************************************************
- * ??0exception@@QAE@XZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor,4)
-exception * __stdcall MSVCRT_exception_default_ctor(exception * _this)
-{
- static const char* empty = NULL;
-
- TRACE("(%p)\n", _this);
- EXCEPTION_ctor(_this, &empty);
- return _this;
-}
-
-/******************************************************************
- * ??1exception@@UAE@XZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor,4)
-void __stdcall MSVCRT_exception_dtor(exception * _this)
-{
- TRACE("(%p)\n", _this);
- _this->vtable = &MSVCRT_exception_vtable;
- if (_this->do_free) MSVCRT_free(_this->name);
-}
-
-/******************************************************************
- * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals,8)
-exception * __stdcall MSVCRT_exception_opequals(exception * _this, const exception * rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- if (_this != rhs)
- {
- MSVCRT_exception_dtor(_this);
- MSVCRT_exception_copy_ctor(_this, rhs);
- }
- TRACE("name = %s\n", _this->name);
- return _this;
-}
-
-/******************************************************************
- * ??_Eexception@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor,8)
-void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- if (flags & 2)
- {
- /* we have an array, with the number of elements stored before the first object */
- int i, *ptr = (int *)_this - 1;
-
- for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i);
- MSVCRT_operator_delete(ptr);
- }
- else
- {
- MSVCRT_exception_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- }
- return _this;
-}
-
-/******************************************************************
- * ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor,8)
-void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- MSVCRT_exception_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- return _this;
-}
-
-/******************************************************************
- * ?what@exception@@UBEPBDXZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception,4)
-const char * __stdcall MSVCRT_what_exception(exception * _this)
-{
- TRACE("(%p) returning %s\n", _this, _this->name);
- return _this->name ? _this->name : "Unknown exception";
-}
-
-/******************************************************************
- * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor,8)
-bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- MSVCRT_exception_copy_ctor(_this, rhs);
- _this->vtable = &MSVCRT_bad_typeid_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor,8)
-bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name)
-{
- TRACE("(%p %s)\n", _this, name);
- EXCEPTION_ctor(_this, &name);
- _this->vtable = &MSVCRT_bad_typeid_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_default_ctor,4)
-bad_typeid * __stdcall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this)
-{
- return MSVCRT_bad_typeid_ctor( _this, "bad typeid" );
-}
-
-/******************************************************************
- * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor,4)
-void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this)
-{
- TRACE("(%p)\n", _this);
- MSVCRT_exception_dtor(_this);
-}
-
-/******************************************************************
- * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals,8)
-bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- MSVCRT_exception_opequals(_this, rhs);
- return _this;
-}
-
-/******************************************************************
- * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor,8)
-void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- if (flags & 2)
- {
- /* we have an array, with the number of elements stored before the first object */
- int i, *ptr = (int *)_this - 1;
-
- for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i);
- MSVCRT_operator_delete(ptr);
- }
- else
- {
- MSVCRT_bad_typeid_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- }
- return _this;
-}
-
-/******************************************************************
- * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor,8)
-void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- MSVCRT_bad_typeid_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- return _this;
-}
-
-/******************************************************************
- * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor,8)
-__non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this,
- const __non_rtti_object * rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- MSVCRT_bad_typeid_copy_ctor(_this, rhs);
- _this->vtable = &MSVCRT___non_rtti_object_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor,8)
-__non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this,
- const char * name)
-{
- TRACE("(%p %s)\n", _this, name);
- EXCEPTION_ctor(_this, &name);
- _this->vtable = &MSVCRT___non_rtti_object_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor,4)
-void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this)
-{
- TRACE("(%p)\n", _this);
- MSVCRT_bad_typeid_dtor(_this);
-}
-
-/******************************************************************
- * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals,8)
-__non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this,
- const __non_rtti_object *rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- MSVCRT_bad_typeid_opequals(_this, rhs);
- return _this;
-}
-
-/******************************************************************
- * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor,8)
-void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- if (flags & 2)
- {
- /* we have an array, with the number of elements stored before the first object */
- int i, *ptr = (int *)_this - 1;
-
- for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i);
- MSVCRT_operator_delete(ptr);
- }
- else
- {
- MSVCRT___non_rtti_object_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- }
- return _this;
-}
-
-/******************************************************************
- * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor,8)
-void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- MSVCRT___non_rtti_object_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- return _this;
-}
-
-/******************************************************************
- * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@)
- * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor,8)
-bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name)
-{
- TRACE("(%p %s)\n", _this, *name);
- EXCEPTION_ctor(_this, name);
- _this->vtable = &MSVCRT_bad_cast_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor,8)
-bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- MSVCRT_exception_copy_ctor(_this, rhs);
- _this->vtable = &MSVCRT_bad_cast_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor_charptr,8)
-bad_cast * __stdcall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name)
-{
- TRACE("(%p %s)\n", _this, name);
- EXCEPTION_ctor(_this, &name);
- _this->vtable = &MSVCRT_bad_cast_vtable;
- return _this;
-}
-
-/******************************************************************
- * ??_Fbad_cast@@QAEXXZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_default_ctor,4)
-bad_cast * __stdcall MSVCRT_bad_cast_default_ctor(bad_cast * _this)
-{
- return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" );
-}
-
-/******************************************************************
- * ??1bad_cast@@UAE@XZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor,4)
-void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this)
-{
- TRACE("(%p)\n", _this);
- MSVCRT_exception_dtor(_this);
-}
-
-/******************************************************************
- * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals,8)
-bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs)
-{
- TRACE("(%p %p)\n", _this, rhs);
- MSVCRT_exception_opequals(_this, rhs);
- return _this;
-}
-
-/******************************************************************
- * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor,8)
-void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- if (flags & 2)
- {
- /* we have an array, with the number of elements stored before the first object */
- int i, *ptr = (int *)_this - 1;
-
- for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_cast_dtor(_this + i);
- MSVCRT_operator_delete(ptr);
- }
- else
- {
- MSVCRT_bad_cast_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- }
- return _this;
-}
-
-/******************************************************************
- * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor,8)
-void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- MSVCRT_bad_cast_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- return _this;
-}
-
-/******************************************************************
- * ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals,8)
-int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs)
-{
- int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1);
- TRACE("(%p %p) returning %d\n", _this, rhs, ret);
- return ret;
-}
-
-/******************************************************************
- * ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals,8)
-int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs)
-{
- int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1);
- TRACE("(%p %p) returning %d\n", _this, rhs, ret);
- return ret;
-}
-
-/******************************************************************
- * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before,8)
-int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs)
-{
- int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0;
- TRACE("(%p %p) returning %d\n", _this, rhs, ret);
- return ret;
-}
-
-/******************************************************************
- * ??1type_info@@UAE@XZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor,4)
-void __stdcall MSVCRT_type_info_dtor(type_info * _this)
-{
- TRACE("(%p)\n", _this);
- MSVCRT_free(_this->name);
-}
-
-/******************************************************************
- * ?name@type_info@@QBEPBDXZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name,4)
-const char * __stdcall MSVCRT_type_info_name(type_info * _this)
-{
- if (!_this->name)
- {
- /* Create and set the demangled name */
- /* Note: mangled name in type_info struct always starts with a '.', while
- * it isn't valid for mangled name.
- * Is this '.' really part of the mangled name, or has it some other meaning ?
- */
- char* name = __unDName(0, _this->mangled + 1, 0,
- MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
- if (name)
- {
- size_t len = strlen(name);
-
- /* It seems _unDName may leave blanks at the end of the demangled name */
- while (len && name[--len] == ' ')
- name[len] = '\0';
-
- if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
- {
- /* Another thread set this member since we checked above - use it */
- MSVCRT_free(name);
- }
- }
- }
- TRACE("(%p) returning %s\n", _this, _this->name);
- return _this->name;
-}
-
-/******************************************************************
- * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
- */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name,4)
-const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this)
-{
- TRACE("(%p) returning %s\n", _this, _this->mangled);
- return _this->mangled;
-}
-
-/* Unexported */
-DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor,8)
-void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags)
-{
- TRACE("(%p %x)\n", _this, flags);
- if (flags & 2)
- {
- /* we have an array, with the number of elements stored before the first object */
- int i, *ptr = (int *)_this - 1;
-
- for (i = *ptr - 1; i >= 0; i--) MSVCRT_type_info_dtor(_this + i);
- MSVCRT_operator_delete(ptr);
- }
- else
- {
- MSVCRT_type_info_dtor(_this);
- if (flags & 1) MSVCRT_operator_delete(_this);
- }
- return _this;
-}
-
-/* vtables */
-
-#ifdef __GNUC__
-#ifdef _WIN64
-
-#define __ASM_VTABLE(name,funcs) \
- __asm__(".data\n" \
- "\t.align 8\n" \
- "\t.quad " __ASM_NAME(#name "_rtti") "\n" \
- "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \
- __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \
- "\t.quad " THISCALL_NAME(MSVCRT_ ## name ## _vector_dtor) "\n" \
- funcs "\n\t.text");
-
-#define __ASM_EXCEPTION_VTABLE(name) \
- __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCRT_what_exception) )
-
-#else
-
-#define __ASM_VTABLE(name,funcs) \
- __asm__(".data\n" \
- "\t.align 4\n" \
- "\t.long " __ASM_NAME(#name "_rtti") "\n" \
- "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \
- __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \
- "\t.long " THISCALL_NAME(MSVCRT_ ## name ## _vector_dtor) "\n" \
- funcs "\n\t.text");
-
-#define __ASM_EXCEPTION_VTABLE(name) \
- __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCRT_what_exception) )
-
-#endif /* _WIN64 */
-
-#ifndef __GNUC__
-void __asm_dummy_vtables(void) {
-#endif
-
-__ASM_VTABLE(type_info,"")
-__ASM_EXCEPTION_VTABLE(exception)
-__ASM_EXCEPTION_VTABLE(bad_typeid)
-__ASM_EXCEPTION_VTABLE(bad_cast)
-__ASM_EXCEPTION_VTABLE(__non_rtti_object)
-
-#ifndef __GNUC__
-}
-#endif
-#endif
-
-/* Static RTTI for exported objects */
-
-static const type_info exception_type_info =
-{
- &MSVCRT_type_info_vtable,
- NULL,
- ".?AVexception@@"
-};
-
-static const rtti_base_descriptor exception_rtti_base_descriptor =
-{
- &exception_type_info,
- 0,
- { 0, -1, 0 },
- 0
-};
-
-static const rtti_base_array exception_rtti_base_array =
-{
- {
- &exception_rtti_base_descriptor,
- NULL,
- NULL
- }
-};
-
-static const rtti_object_hierarchy exception_type_hierarchy =
-{
- 0,
- 0,
- 1,
- &exception_rtti_base_array
-};
-
-const rtti_object_locator exception_rtti =
-{
- 0,
- 0,
- 0,
- &exception_type_info,
- &exception_type_hierarchy
-};
-
-static const cxx_type_info exception_cxx_type_info =
-{
- 0,
- &exception_type_info,
- { 0, -1, 0 },
- sizeof(exception),
- (cxx_copy_ctor)THISCALL(MSVCRT_exception_copy_ctor)
-};
-
-static const type_info bad_typeid_type_info =
-{
- &MSVCRT_type_info_vtable,
- NULL,
- ".?AVbad_typeid@@"
-};
-
-static const rtti_base_descriptor bad_typeid_rtti_base_descriptor =
-{
- &bad_typeid_type_info,
- 1,
- { 0, -1, 0 },
- 0
-};
-
-static const rtti_base_array bad_typeid_rtti_base_array =
-{
- {
- &bad_typeid_rtti_base_descriptor,
- &exception_rtti_base_descriptor,
- NULL
- }
-};
-
-static const rtti_object_hierarchy bad_typeid_type_hierarchy =
-{
- 0,
- 0,
- 2,
- &bad_typeid_rtti_base_array
-};
-
-const rtti_object_locator bad_typeid_rtti =
-{
- 0,
- 0,
- 0,
- &bad_typeid_type_info,
- &bad_typeid_type_hierarchy
-};
-
-static const cxx_type_info bad_typeid_cxx_type_info =
-{
- 0,
- &bad_typeid_type_info,
- { 0, -1, 0 },
- sizeof(exception),
- (cxx_copy_ctor)THISCALL(MSVCRT_bad_typeid_copy_ctor)
-};
-
-static const type_info bad_cast_type_info =
-{
- &MSVCRT_type_info_vtable,
- NULL,
- ".?AVbad_cast@@"
-};
-
-static const rtti_base_descriptor bad_cast_rtti_base_descriptor =
-{
- &bad_cast_type_info,
- 1,
- { 0, -1, 0 },
- 0
-};
-
-static const rtti_base_array bad_cast_rtti_base_array =
-{
- {
- &bad_cast_rtti_base_descriptor,
- &exception_rtti_base_descriptor,
- NULL
- }
-};
-
-static const rtti_object_hierarchy bad_cast_type_hierarchy =
-{
- 0,
- 0,
- 2,
- &bad_cast_rtti_base_array
-};
-
-const rtti_object_locator bad_cast_rtti =
-{
- 0,
- 0,
- 0,
- &bad_cast_type_info,
- &bad_cast_type_hierarchy
-};
-
-static const cxx_type_info bad_cast_cxx_type_info =
-{
- 0,
- &bad_cast_type_info,
- { 0, -1, 0 },
- sizeof(exception),
- (cxx_copy_ctor)THISCALL(MSVCRT_bad_cast_copy_ctor)
-};
-
-static const type_info __non_rtti_object_type_info =
-{
- &MSVCRT_type_info_vtable,
- NULL,
- ".?AV__non_rtti_object@@"
-};
-
-static const rtti_base_descriptor __non_rtti_object_rtti_base_descriptor =
-{
- &__non_rtti_object_type_info,
- 2,
- { 0, -1, 0 },
- 0
-};
-
-static const rtti_base_array __non_rtti_object_rtti_base_array =
-{
- {
- &__non_rtti_object_rtti_base_descriptor,
- &bad_typeid_rtti_base_descriptor,
- &exception_rtti_base_descriptor
- }
-};
-
-static const rtti_object_hierarchy __non_rtti_object_type_hierarchy =
-{
- 0,
- 0,
- 3,
- &__non_rtti_object_rtti_base_array
-};
-
-const rtti_object_locator __non_rtti_object_rtti =
-{
- 0,
- 0,
- 0,
- &__non_rtti_object_type_info,
- &__non_rtti_object_type_hierarchy
-};
-
-static const cxx_type_info __non_rtti_object_cxx_type_info =
-{
- 0,
- &__non_rtti_object_type_info,
- { 0, -1, 0 },
- sizeof(exception),
- (cxx_copy_ctor)THISCALL(MSVCRT___non_rtti_object_copy_ctor)
-};
-
-static const type_info type_info_type_info =
-{
- &MSVCRT_type_info_vtable,
- NULL,
- ".?AVtype_info@@"
-};
-
-static const rtti_base_descriptor type_info_rtti_base_descriptor =
-{
- &type_info_type_info,
- 0,
- { 0, -1, 0 },
- 0
-};
-
-static const rtti_base_array type_info_rtti_base_array =
-{
- {
- &type_info_rtti_base_descriptor,
- NULL,
- NULL
- }
-};
-
-static const rtti_object_hierarchy type_info_type_hierarchy =
-{
- 0,
- 0,
- 1,
- &type_info_rtti_base_array
-};
-
-const rtti_object_locator type_info_rtti =
-{
- 0,
- 0,
- 0,
- &type_info_type_info,
- &type_info_type_hierarchy
-};
-
-/*
- * Exception RTTI for cpp objects
- */
-static const cxx_type_info_table bad_cast_type_info_table =
-{
- 3,
- {
- &__non_rtti_object_cxx_type_info,
- &bad_typeid_cxx_type_info,
- &exception_cxx_type_info
- }
-};
-
-static const cxx_exception_type bad_cast_exception_type =
-{
- 0,
- (void*)THISCALL(MSVCRT_bad_cast_dtor),
- NULL,
- &bad_cast_type_info_table
-};
-
-static const cxx_type_info_table bad_typeid_type_info_table =
-{
- 2,
- {
- &bad_cast_cxx_type_info,
- &exception_cxx_type_info,
- NULL
- }
-};
-
-static const cxx_exception_type bad_typeid_exception_type =
-{
- 0,
- (void*)THISCALL(MSVCRT_bad_typeid_dtor),
- NULL,
- &bad_cast_type_info_table
-};
-
-static const cxx_exception_type __non_rtti_object_exception_type =
-{
- 0,
- (void*)THISCALL(MSVCRT___non_rtti_object_dtor),
- NULL,
- &bad_typeid_type_info_table
-};
-
-
-/******************************************************************
- * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
- *
- * Install a handler to be called when terminate() is called.
- *
- * PARAMS
- * func [I] Handler function to install
- *
- * RETURNS
- * The previously installed handler function, if any.
- */
-terminate_function CDECL MSVCRT_set_terminate(terminate_function func)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- terminate_function previous = data->terminate_handler;
- TRACE("(%p) returning %p\n",func,previous);
- data->terminate_handler = func;
- return previous;
-}
-
-/******************************************************************
- * _get_terminate (MSVCRT.@)
- */
-terminate_function CDECL _get_terminate(void)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- return data->terminate_handler;
-}
-
-/******************************************************************
- * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
- *
- * Install a handler to be called when unexpected() is called.
- *
- * PARAMS
- * func [I] Handler function to install
- *
- * RETURNS
- * The previously installed handler function, if any.
- */
-unexpected_function CDECL MSVCRT_set_unexpected(unexpected_function func)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- unexpected_function previous = data->unexpected_handler;
- TRACE("(%p) returning %p\n",func,previous);
- data->unexpected_handler = func;
- return previous;
-}
-
-/******************************************************************
- * _get_unexpected (MSVCRT.@)
- */
-unexpected_function CDECL _get_unexpected(void)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- return data->unexpected_handler;
-}
-
-/******************************************************************
- * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
- */
-_se_translator_function CDECL MSVCRT__set_se_translator(_se_translator_function func)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- _se_translator_function previous = data->se_translator;
- TRACE("(%p) returning %p\n",func,previous);
- data->se_translator = func;
- return previous;
-}
-
-/******************************************************************
- * ?terminate@@YAXXZ (MSVCRT.@)
- *
- * Default handler for an unhandled exception.
- *
- * PARAMS
- * None.
- *
- * RETURNS
- * This function does not return. Either control resumes from any
- * handler installed by calling set_terminate(), or (by default) abort()
- * is called.
- */
-void CDECL MSVCRT_terminate(void)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- if (data->terminate_handler) data->terminate_handler();
- abort();
-}
-
-/******************************************************************
- * ?unexpected@@YAXXZ (MSVCRT.@)
- */
-void CDECL MSVCRT_unexpected(void)
-{
- thread_data_t *data = msvcrt_get_thread_data();
- if (data->unexpected_handler) data->unexpected_handler();
- MSVCRT_terminate();
-}
-
-
-/******************************************************************
- * __RTtypeid (MSVCRT.@)
- *
- * Retrieve the Run Time Type Information (RTTI) for a C++ object.
- *
- * PARAMS
- * cppobj [I] C++ object to get type information for.
- *
- * RETURNS
- * Success: A type_info object describing cppobj.
- * Failure: If the object to be cast has no RTTI, a __non_rtti_object
- * exception is thrown. If cppobj is NULL, a bad_typeid exception
- * is thrown. In either case, this function does not return.
- *
- * NOTES
- * This function is usually called by compiler generated code as a result
- * of using one of the C++ dynamic cast statements.
- */
-const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
-{
- const type_info *ret;
-
- if (!cppobj)
- {
- bad_typeid e;
- MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
- _CxxThrowException( &e, &bad_typeid_exception_type );
- return NULL;
- }
-
- __TRY
- {
- const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
- ret = obj_locator->type_descriptor;
- }
- __EXCEPT_PAGE_FAULT
- {
- __non_rtti_object e;
- MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
- _CxxThrowException( &e, &__non_rtti_object_exception_type );
- return NULL;
- }
- __ENDTRY
- return ret;
-}
-
-/******************************************************************
- * __RTDynamicCast (MSVCRT.@)
- *
- * Dynamically cast a C++ object to one of its base classes.
- *
- * PARAMS
- * cppobj [I] Any C++ object to cast
- * unknown [I] Reserved, set to 0
- * src [I] type_info object describing cppobj
- * dst [I] type_info object describing the base class to cast to
- * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
- *
- * RETURNS
- * Success: The address of cppobj, cast to the object described by dst.
- * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
- * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
- * is thrown and this function does not return.
- *
- * NOTES
- * This function is usually called by compiler generated code as a result
- * of using one of the C++ dynamic cast statements.
- */
-void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
- type_info *src, type_info *dst,
- int do_throw)
-{
- void *ret;
-
- if (!cppobj) return NULL;
-
- TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
- cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
-
- /* To cast an object at runtime:
- * 1.Find out the true type of the object from the typeinfo at vtable[-1]
- * 2.Search for the destination type in the class hierarchy
- * 3.If destination type is found, return base object address + dest offset
- * Otherwise, fail the cast
- *
- * FIXME: the unknown parameter doesn't seem to be used for anything
- */
- __TRY
- {
- int i;
- const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
- const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy;
- const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases;
-
- if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
-
- ret = NULL;
- for (i = 0; i < obj_bases->array_len; i++)
- {
- const type_info *typ = base_desc[i]->type_descriptor;
-
- if (!strcmp(typ->mangled, dst->mangled))
- {
- /* compute the correct this pointer for that base class */
- void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
- ret = get_this_pointer( &base_desc[i]->offsets, this_ptr );
- break;
- }
- }
- /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
- * to a reference, since references cannot be NULL.
- */
- if (!ret && do_throw)
- {
- const char *msg = "Bad dynamic_cast!";
- bad_cast e;
- MSVCRT_bad_cast_ctor( &e, &msg );
- _CxxThrowException( &e, &bad_cast_exception_type );
- }
- }
- __EXCEPT_PAGE_FAULT
- {
- __non_rtti_object e;
- MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
- _CxxThrowException( &e, &__non_rtti_object_exception_type );
- return NULL;
- }
- __ENDTRY
- return ret;
-}
-
-
-/******************************************************************
- * __RTCastToVoid (MSVCRT.@)
- *
- * Dynamically cast a C++ object to a void*.
- *
- * PARAMS
- * cppobj [I] The C++ object to cast
- *
- * RETURNS
- * Success: The base address of the object as a void*.
- * Failure: NULL, if cppobj is NULL or has no RTTI.
- *
- * NOTES
- * This function is usually called by compiler generated code as a result
- * of using one of the C++ dynamic cast statements.
- */
-void* CDECL MSVCRT___RTCastToVoid(void *cppobj)
-{
- void *ret;
-
- if (!cppobj) return NULL;
-
- __TRY
- {
- const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
- ret = (char *)cppobj - obj_locator->base_class_offset;
- }
- __EXCEPT_PAGE_FAULT
- {
- __non_rtti_object e;
- MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
- _CxxThrowException( &e, &__non_rtti_object_exception_type );
- return NULL;
- }
- __ENDTRY
- return ret;
-}
diff --git a/sdk/lib/crt/except/cppexcept.c b/sdk/lib/crt/except/cppexcept.c
deleted file mode 100644
index e1352a608be..00000000000
--- a/sdk/lib/crt/except/cppexcept.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * msvcrt C++ exception handling
- *
- * Copyright 2002 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * NOTES
- * A good reference is the article "How a C++ compiler implements
- * exception handling" by Vishal Kochhar, available on
- * www.thecodeproject.com.
- */
-
-#define __WINE_DEBUG_CHANNEL__
-#include
-#include
-
-#include
-#include
-#include
-
-#ifdef __i386__ /* CxxFrameHandler is not supported on non-i386 */
-
-WINE_DEFAULT_DEBUG_CHANNEL(seh);
-
-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 */
-#ifdef _MSC_VER
-#pragma warning(disable:4731) // don't warn about modification of ebp
-#endif
-static inline void *call_ebp_func( void *func, void *_ebp )
-{
- void *result;
-#ifdef _MSC_VER
- __asm
- {
- mov eax, func
- push ebx
- push ebp
- mov ebp, _ebp
- call eax
- pop ebp
- pop ebx
- mov result, eax
- }
-#else
- 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" (result), "=S" (dummy), "=D" (dummy)
- : "0" (func), "1" (_ebp) : "ecx", "edx", "memory" );
-#endif
- return result;
-}
-#ifdef _MSC_VER
-#pragma warning(default:4731)
-#endif
-
-/* call a copy constructor */
-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 );
-#ifdef _MSC_VER
- if (has_vbase)
- {
- __asm
- {
- mov ecx, this
- push 1
- push src
- call func
- }
- }
- else
- {
- __asm
- {
- mov ecx, this
- push src
- call func
- }
- }
-#else
- 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), "r" (src) : "eax", "edx", "memory" );
- else
- __asm__ __volatile__("pushl %2; call *%0"
- : : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" );
-#endif
-}
-
-/* call the destructor of the exception object */
-static inline void call_dtor( void *func, void *object )
-{
-#ifdef _MSC_VER
- __asm
- {
- mov ecx, object
- call func
- }
-#else
- __asm__ __volatile__("call *%0" : : "r" (func), "c" (object) : "eax", "edx", "memory" );
-#endif
-}
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4731)
-/* continue execution to the specified address after exception is caught */
-__forceinline void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr )
-{
- __asm
- {
- mov eax, addr
- mov edx, frame
- mov esp, [edx-4]
- lea ebp, [edx+12]
- jmp eax
- }
- for (;;) ; /* unreached */
-}
-#pragma warning(pop)
-#else
-/* 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 */
-}
-#endif
-
-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),
- type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
- type->size, type->copy_ctor );
-}
-
-static void dump_exception_type( const cxx_exception_type *type )
-{
- UINT i;
-
- 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++)
- {
- TRACE( " %d: ", i );
- dump_type( type->type_info_table->info[i] );
- }
-}
-
-static void dump_function_descr( const cxx_function_descr *descr )
-{
-#ifndef WINE_NO_TRACE_MSGS
- UINT i;
- int j;
-
- 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++)
- {
- TRACE( " %d: prev %d func %p\n", i,
- descr->unwind_table[i].prev, descr->unwind_table[i].handler );
- }
- TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
- for (i = 0; i < descr->tryblock_count; 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++)
- {
- 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 ) );
- }
- }
-#endif
- if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
- TRACE( "expect list: %p\n", descr->expect_list );
- if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
- TRACE( "flags: %08x\n", descr->flags );
-}
-
-/* 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,
- const catchblock_info *catchblock )
-{
- UINT i;
-
- for (i = 0; i < exc_type->type_info_table->count; i++)
- {
- const cxx_type_info *type = exc_type->type_info_table->info[i];
-
- if (!catchblock->type_info) return type; /* catch(...) matches any type */
- if (catchblock->type_info != type->type_info)
- {
- if (strcmp( catchblock->type_info->mangled, type->type_info->mangled )) continue;
- }
- /* type is the same, now check the flags */
- if ((exc_type->flags & TYPE_FLAG_CONST) &&
- !(catchblock->flags & TYPE_FLAG_CONST)) continue;
- if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
- !(catchblock->flags & TYPE_FLAG_VOLATILE)) continue;
- return type; /* it matched */
- }
- return NULL;
-}
-
-
-/* copy the exception object where the catch block wants it */
-static void copy_exception( void *object, cxx_exception_frame *frame,
- const catchblock_info *catchblock, const cxx_type_info *type )
-{
- void **dest_ptr;
-
- if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return;
- if (!catchblock->offset) return;
- dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset);
-
- if (catchblock->flags & TYPE_FLAG_REFERENCE)
- {
- *dest_ptr = get_this_pointer( &type->offsets, object );
- }
- else if (type->flags & CLASS_IS_SIMPLE_TYPE)
- {
- memmove( dest_ptr, object, type->size );
- /* if it is a pointer, adjust it */
- if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( &type->offsets, *dest_ptr );
- }
- else /* copy the object */
- {
- if (type->copy_ctor)
- call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(&type->offsets,object),
- (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) );
- else
- memmove( dest_ptr, get_this_pointer(&type->offsets,object), type->size );
- }
-}
-
-/* unwind the local function up to a given trylevel */
-static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
-{
- void (*handler)(void);
- int trylevel = frame->trylevel;
-
- while (trylevel != last_level)
- {
- if (trylevel < 0 || (unsigned)trylevel >= descr->unwind_count)
- {
- ERR( "invalid trylevel %d\n", trylevel );
- MSVCRT_terminate();
- }
- handler = descr->unwind_table[trylevel].handler;
- 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;
-}
-
-/* exception frame for nested exceptions in catch block */
-struct catch_func_nested_frame
-{
- 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 */
- 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 */
-static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
- CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
-{
- struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame;
-
- if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
- {
- msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec;
- return ExceptionContinueSearch;
- }
-
- 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 */
-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;
- void *addr, *object = (void *)rec->ExceptionInformation[1];
- struct catch_func_nested_frame nested_frame;
- int trylevel = frame->trylevel;
- thread_data_t *thread_data = msvcrt_get_thread_data();
- DWORD save_esp = ((DWORD*)frame)[-1];
-
- for (i = 0; i < descr->tryblock_count; i++)
- {
- const tryblock_info *tryblock = &descr->tryblock[i];
-
- if (trylevel < tryblock->start_level) continue;
- if (trylevel > tryblock->end_level) continue;
-
- /* got a try block */
- for (j = 0; j < tryblock->catchblock_count; j++)
- {
- 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 );
- cxx_local_unwind( frame, descr, tryblock->start_level );
- frame->trylevel = tryblock->end_level + 1;
-
- /* call the catch block */
- 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 = (PEXCEPTION_ROUTINE)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;
- addr = call_ebp_func( catchblock->handler, &frame->ebp );
- thread_data->exc_record = nested_frame.prev_rec;
- __wine_pop_frame( &nested_frame.frame );
-
- ((DWORD*)frame)[-1] = save_esp;
- if (info && info->destructor) call_dtor( info->destructor, object );
- TRACE( "done, continuing at %p\n", addr );
-
- continue_after_catch( frame, addr );
- }
- }
-}
-
-
-/*********************************************************************
- * cxx_frame_handler
- *
- * Implementation of __CxxFrameHandler.
- */
-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;
-
- if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
- {
- ERR( "invalid frame magic %x\n", descr->magic );
- return ExceptionContinueSearch;
- }
- if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
- (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
- (rec->ExceptionCode != CXX_EXCEPTION))
- return ExceptionContinueSearch; /* handle only c++ exceptions */
-
- if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
- {
- if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 );
- return ExceptionContinueSearch;
- }
- if (!descr->tryblock_count) return ExceptionContinueSearch;
-
- if(rec->ExceptionCode == CXX_EXCEPTION)
- {
- exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
-
- if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 &&
- exc_type->custom_handler)
- {
- return exc_type->custom_handler( rec, frame, context, dispatch,
- descr, nested_trylevel, nested_frame, 0 );
- }
-
- 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.@)
- */
-extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
- PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch );
-#ifdef _MSC_VER
-DWORD _declspec(naked) __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
- PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch )
-{
- __asm
- {
- push 0
- push 0
- push eax
- push [esp + 28]
- push [esp + 28]
- push [esp + 28]
- push [esp + 28]
- call cxx_frame_handler
- add esp, 28
- ret
- }
-}
-#else
-__ASM_GLOBAL_FUNC( __CxxFrameHandler,
- "pushl $0\n\t" /* nested_trylevel */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "pushl $0\n\t" /* nested_frame */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "pushl %eax\n\t" /* descr */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "pushl 28(%esp)\n\t" /* dispatch */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "pushl 28(%esp)\n\t" /* context */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "pushl 28(%esp)\n\t" /* frame */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "pushl 28(%esp)\n\t" /* rec */
- __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
- "call " __ASM_NAME("cxx_frame_handler") "\n\t"
- "add $28,%esp\n\t"
- __ASM_CFI(".cfi_adjust_cfa_offset -28\n\t")
- "ret" )
-#endif
-
-/*********************************************************************
- * __CxxLongjmpUnwind (MSVCRT.@)
- *
- * Callback meant to be used as UnwindFunc for setjmp/longjmp.
- */
-void __stdcall __CxxLongjmpUnwind( const struct __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__ */
-
-
-/*********************************************************************
- * __CppXcptFilter (MSVCRT.@)
- */
-int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
-{
- /* only filter c++ exceptions */
- if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
- return _XcptFilter( ex, ptr );
-}
-
-/*********************************************************************
- * _CxxThrowException (MSVCRT.@)
- */
-void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type )
-{
- ULONG_PTR args[3];
-
- args[0] = CXX_FRAME_MAGIC_VC6;
- args[1] = (ULONG_PTR)object;
- args[2] = (ULONG_PTR)type;
- RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
-}
-
-/*********************************************************************
- * __CxxDetectRethrow (MSVCRT.@)
- */
-BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
-{
- PEXCEPTION_RECORD rec;
-
- if (!ptrs)
- return FALSE;
-
- rec = ptrs->ExceptionRecord;
-
- if (rec->ExceptionCode == CXX_EXCEPTION &&
- rec->NumberParameters == 3 &&
- rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
- rec->ExceptionInformation[2])
- {
- ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
- return TRUE;
- }
- return (msvcrt_get_thread_data()->exc_record == rec);
-}
-
-/*********************************************************************
- * __CxxQueryExceptionSize (MSVCRT.@)
- */
-unsigned int CDECL __CxxQueryExceptionSize(void)
-{
- return sizeof(cxx_exception_type);
-}
diff --git a/sdk/lib/crt/except/except.c b/sdk/lib/crt/except/except.c
deleted file mode 100644
index a3ed19bf545..00000000000
--- a/sdk/lib/crt/except/except.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * msvcrt.dll exception handling
- *
- * Copyright 2000 Jon Griffiths
- * Copyright 2005 Juan Lang
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * FIXME: Incomplete support for nested exceptions/try block cleanup.
- */
-
-#include
-#include "excpt.h"
-#include "cppexcept.h"
-#include
-
-void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame);
-
-typedef void (__cdecl *MSVCRT_security_error_handler)(int, void *);
-static MSVCRT_security_error_handler security_error_handler;
-
-/* VC++ extensions to Win32 SEH */
-typedef struct _SCOPETABLE
-{
- int previousTryLevel;
- int (*lpfnFilter)(PEXCEPTION_POINTERS);
- int (*lpfnHandler)(void);
-} SCOPETABLE, *PSCOPETABLE;
-
-typedef struct _MSVCRT_EXCEPTION_FRAME
-{
- EXCEPTION_REGISTRATION_RECORD *prev;
- void (*handler)(PEXCEPTION_RECORD, EXCEPTION_REGISTRATION_RECORD*,
- PCONTEXT, PEXCEPTION_RECORD);
- PSCOPETABLE scopetable;
- int trylevel;
- int _ebp;
- PEXCEPTION_POINTERS xpointers;
-} MSVCRT_EXCEPTION_FRAME;
-
-typedef struct
-{
- int gs_cookie_offset;
- ULONG gs_cookie_xor;
- int eh_cookie_offset;
- ULONG eh_cookie_xor;
- SCOPETABLE entries[1];
-} SCOPETABLE_V4;
-
-#ifdef __i386__
-
-static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie )
-{
- return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie);
-}
-
-#if defined(__GNUC__)
-static inline void call_finally_block( void *code_block, void *base_ptr )
-{
- __asm__ __volatile__ ("movl %1,%%ebp; call *%%eax"
- : : "a" (code_block), "g" (base_ptr));
-}
-
-static inline int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp )
-{
- int ret;
- __asm__ __volatile__ ("pushl %%ebp; pushl %3; movl %2,%%ebp; call *%%eax; popl %%ebp; popl %%ebp"
- : "=a" (ret)
- : "0" (func), "r" (ebp), "r" (arg)
- : "ecx", "edx", "memory" );
- return ret;
-}
-static inline int call_unwind_func( int (*func)(void), void *ebp )
-{
- int ret;
- __asm__ __volatile__ ("pushl %%ebp\n\t"
- "pushl %%ebx\n\t"
- "pushl %%esi\n\t"
- "pushl %%edi\n\t"
- "movl %2,%%ebp\n\t"
- "call *%0\n\t"
- "popl %%edi\n\t"
- "popl %%esi\n\t"
- "popl %%ebx\n\t"
- "popl %%ebp"
- : "=a" (ret)
- : "0" (func), "r" (ebp)
- : "ecx", "edx", "memory" );
- return ret;
-}
-#elif defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable:4731) // Don't complain about changing ebp
-void __inline call_finally_block( void *code_block, void *base_ptr )
-{
- __asm
- {
- mov eax, code_block
- mov ebp, base_ptr
- call [eax]
- }
-}
-
-int __inline call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *_ebp )
-{
- int _ret;
- __asm
- {
- push ebp
- mov eax, arg
- push eax
- mov ebp, _ebp
- mov eax, func
- call [eax]
- mov _ret, eax
- pop ebp
- pop ebp
- }
- return _ret;
-}
-int __inline call_unwind_func( int (*func)(void), void *_ebp )
-{
- int _ret;
-
- __asm
- {
- push ebp
- push ebx
- push esi
- push edi
- mov ebp, _ebp
- call dword ptr [func]
- mov _ret, eax
- pop edi
- pop esi
- pop ebx
- pop ebp
- }
- return _ret;
-}
-#pragma warning(pop)
-#endif
-
-static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
- EXCEPTION_REGISTRATION_RECORD* frame,
- PCONTEXT context,
- EXCEPTION_REGISTRATION_RECORD** dispatch)
-{
- if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))
- return ExceptionContinueSearch;
- *dispatch = frame;
- return ExceptionCollidedUnwind;
-}
-
-void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp )
-{
- EXCEPTION_REGISTRATION_RECORD reg;
- const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie );
-
- TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
-
- /* Register a handler in case of a nested exception */
- reg.Handler = (PEXCEPTION_ROUTINE)MSVCRT_nested_handler;
- reg.Prev = NtCurrentTeb()->NtTib.ExceptionList;
- __wine_push_frame(®);
-
- while (frame->trylevel != -2 && frame->trylevel != trylevel)
- {
- int level = frame->trylevel;
- frame->trylevel = scopetable->entries[level].previousTryLevel;
- if (!scopetable->entries[level].lpfnFilter)
- {
- TRACE( "__try block cleanup level %d handler %p ebp %p\n",
- level, scopetable->entries[level].lpfnHandler, ebp );
- call_unwind_func( scopetable->entries[level].lpfnHandler, ebp );
- }
- }
- __wine_pop_frame(®);
- TRACE("unwound OK\n");
-}
-
-/*********************************************************************
- * _except_handler4_common (MSVCRT.@)
- */
-int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void),
- EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame,
- CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
-{
- int retval, trylevel;
- EXCEPTION_POINTERS exceptPtrs;
- const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie );
-
- TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n",
- rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
- frame->handler, context, dispatcher, *cookie, scope_table,
- scope_table->gs_cookie_offset, scope_table->gs_cookie_xor,
- scope_table->eh_cookie_offset, scope_table->eh_cookie_xor );
-
- /* FIXME: no cookie validation yet */
-
- if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
- {
- /* Unwinding the current frame */
- msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp );
- TRACE("unwound current frame, returning ExceptionContinueSearch\n");
- return ExceptionContinueSearch;
- }
- else
- {
- /* Hunting for handler */
- exceptPtrs.ExceptionRecord = rec;
- exceptPtrs.ContextRecord = context;
- *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
- trylevel = frame->trylevel;
-
- while (trylevel != -2)
- {
- TRACE( "level %d prev %d filter %p\n", trylevel,
- scope_table->entries[trylevel].previousTryLevel,
- scope_table->entries[trylevel].lpfnFilter );
- if (scope_table->entries[trylevel].lpfnFilter)
- {
- retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
-
- TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
- "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
- "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
-
- if (retval == EXCEPTION_CONTINUE_EXECUTION)
- return ExceptionContinueExecution;
-
- if (retval == EXCEPTION_EXECUTE_HANDLER)
- {
- /* Unwind all higher frames, this one will handle the exception */
- _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
- msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
-
- /* Set our trylevel to the enclosing block, and call the __finally
- * code, which won't return
- */
- frame->trylevel = scope_table->entries[trylevel].previousTryLevel;
- TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler);
- call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp);
- ERR("Returned from __finally block - expect crash!\n");
- }
- }
- trylevel = scope_table->entries[trylevel].previousTryLevel;
- }
- }
- TRACE("reached -2, returning ExceptionContinueSearch\n");
- return ExceptionContinueSearch;
-}
-
-/*******************************************************************
- * _local_unwind4 (MSVCRT.@)
- */
-void CDECL _local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel )
-{
- msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
-}
-
-/*********************************************************************
- * _seh_longjmp_unwind4 (MSVCRT.@)
- */
-void __stdcall _seh_longjmp_unwind4(struct __JUMP_BUFFER *jmp)
-{
- msvcrt_local_unwind4( (void *)jmp->Cookie, (MSVCRT_EXCEPTION_FRAME *)jmp->Registration,
- jmp->TryLevel, (void *)jmp->Ebp );
-}
-
-#endif
-
-/******************************************************************
- * __uncaught_exception
- */
-BOOL CDECL __uncaught_exception(void)
-{
- return FALSE;
-}
-
-/* _set_security_error_handler - not exported in native msvcrt, added in msvcr70 */
-MSVCRT_security_error_handler CDECL _set_security_error_handler(
- MSVCRT_security_error_handler handler )
-{
- MSVCRT_security_error_handler old = security_error_handler;
-
- TRACE("(%p)\n", handler);
-
- security_error_handler = handler;
- return old;
-}
-
-/*********************************************************************
- * __DestructExceptionObject (MSVCRT.@)
- */
-void CDECL __DestructExceptionObject(EXCEPTION_RECORD* rec)
-{
- cxx_exception_type* info = (cxx_exception_type*)rec->ExceptionInformation[2];
- void* object = (void*)rec->ExceptionInformation[1];
-
- TRACE("(%p)\n", rec);
-
- if (rec->ExceptionCode != CXX_EXCEPTION) return;
-#ifndef __x86_64__
- if (rec->NumberParameters != 3) return;
-#else
- if (rec->NumberParameters != 4) return;
-#endif
- if (rec->ExceptionInformation[0] < CXX_FRAME_MAGIC_VC6 ||
- rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8) return;
-
- if (!info || !info->destructor)
- return;
-
-#if defined(__i386__)
- #ifdef _MSC_VER
- ((void(__fastcall*)(void*))info->destructor)(object);
- #else
- __asm__ __volatile__("call *%0" : : "r" (info->destructor), "c" (object) : "eax", "edx", "memory");
- #endif
-#elif defined(__x86_64__)
- ((void(__cdecl*)(void*))(info->destructor + rec->ExceptionInformation[3]))(object);
-#else
- ((void(__cdecl*)(void*))info->destructor)(object);
-#endif
-}
diff --git a/sdk/lib/crt/except/i386/cpp.s b/sdk/lib/crt/except/i386/cpp.s
index a77d02aa93d..0eaa5bc64f7 100644
--- a/sdk/lib/crt/except/i386/cpp.s
+++ b/sdk/lib/crt/except/i386/cpp.s
@@ -5,53 +5,53 @@
.code
.align 4
-MACRO(DEFINE_THISCALL_WRAPPER, cxxname, stdcallname)
-EXTERN &stdcallname:PROC
-PUBLIC &cxxname
-&cxxname:
- pop eax
- push ecx
- push eax
- jmp &stdcallname
+MACRO(DEFINE_THISCALL_ALIAS, cxxname, target)
+#ifdef _USE_ML
+ EXTERN ___thiscall&target:PROC
+ ALIAS <&cxxname> = <___thiscall&target>
+#else
+ PUBLIC cxxname
+ .weakref &cxxname, &target
+#endif
ENDM
-DEFINE_THISCALL_WRAPPER ??0exception@@QAE@ABQBD@Z, _MSVCRT_exception_ctor@8
-DEFINE_THISCALL_WRAPPER ??0exception@@QAE@ABQBDH@Z, _MSVCRT_exception_ctor_noalloc@12
-DEFINE_THISCALL_WRAPPER ??0exception@@QAE@ABV0@@Z, _MSVCRT_exception_copy_ctor@8
-DEFINE_THISCALL_WRAPPER ??0exception@@QAE@XZ, _MSVCRT_exception_default_ctor@4
-DEFINE_THISCALL_WRAPPER ??1exception@@UAE@XZ, _MSVCRT_exception_dtor@4
-DEFINE_THISCALL_WRAPPER ??4exception@@QAEAAV0@ABV0@@Z, _MSVCRT_exception_opequals@8
-DEFINE_THISCALL_WRAPPER ??_Eexception@@UAEPAXI@Z, _MSVCRT_exception_vector_dtor@8
-DEFINE_THISCALL_WRAPPER ??_Gexception@@UAEPAXI@Z, _MSVCRT_exception_scalar_dtor@8
-DEFINE_THISCALL_WRAPPER ?what@exception@@UBEPBDXZ, _MSVCRT_what_exception@4
-DEFINE_THISCALL_WRAPPER ??0bad_typeid@@QAE@ABV0@@Z, _MSVCRT_bad_typeid_copy_ctor@8
-DEFINE_THISCALL_WRAPPER ??0bad_typeid@@QAE@PBD@Z, _MSVCRT_bad_typeid_ctor@8
-DEFINE_THISCALL_WRAPPER ??_Fbad_typeid@@QAEXXZ, _MSVCRT_bad_typeid_default_ctor@4
-DEFINE_THISCALL_WRAPPER ??1bad_typeid@@UAE@XZ, _MSVCRT_bad_typeid_dtor@4
-DEFINE_THISCALL_WRAPPER ??4bad_typeid@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_typeid_opequals@8
-DEFINE_THISCALL_WRAPPER ??_Ebad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_vector_dtor@8
-DEFINE_THISCALL_WRAPPER ??_Gbad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_scalar_dtor@8
-DEFINE_THISCALL_WRAPPER ??0__non_rtti_object@@QAE@ABV0@@Z, _MSVCRT___non_rtti_object_copy_ctor@8
-DEFINE_THISCALL_WRAPPER ??0__non_rtti_object@@QAE@PBD@Z, _MSVCRT___non_rtti_object_ctor@8
-DEFINE_THISCALL_WRAPPER ??1__non_rtti_object@@UAE@XZ, _MSVCRT___non_rtti_object_dtor@4
-DEFINE_THISCALL_WRAPPER ??4__non_rtti_object@@QAEAAV0@ABV0@@Z, _MSVCRT___non_rtti_object_opequals@8
-DEFINE_THISCALL_WRAPPER ??_E__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_vector_dtor@8
-DEFINE_THISCALL_WRAPPER ??_G__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_scalar_dtor@8
-DEFINE_THISCALL_WRAPPER ??0bad_cast@@AAE@PBQBD@Z, _MSVCRT_bad_cast_ctor@8
-DEFINE_THISCALL_WRAPPER ??0bad_cast@@QAE@ABQBD@Z, _MSVCRT_bad_cast_ctor@8
-DEFINE_THISCALL_WRAPPER ??0bad_cast@@QAE@ABV0@@Z, _MSVCRT_bad_cast_copy_ctor@8
-DEFINE_THISCALL_WRAPPER ??0bad_cast@@QAE@PBD@Z, _MSVCRT_bad_cast_ctor_charptr@8
-DEFINE_THISCALL_WRAPPER ??_Fbad_cast@@QAEXXZ, _MSVCRT_bad_cast_default_ctor@4
-DEFINE_THISCALL_WRAPPER ??1bad_cast@@UAE@XZ, _MSVCRT_bad_cast_dtor@4
-DEFINE_THISCALL_WRAPPER ??4bad_cast@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_cast_opequals@8
-DEFINE_THISCALL_WRAPPER ??_Ebad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_vector_dtor@8
-DEFINE_THISCALL_WRAPPER ??_Gbad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_scalar_dtor@8
-DEFINE_THISCALL_WRAPPER ??8type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opequals_equals@8
-DEFINE_THISCALL_WRAPPER ??9type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opnot_equals@8
-DEFINE_THISCALL_WRAPPER ?before@type_info@@QBEHABV1@@Z, _MSVCRT_type_info_before@8
-DEFINE_THISCALL_WRAPPER ??1type_info@@UAE@XZ, _MSVCRT_type_info_dtor@4
-DEFINE_THISCALL_WRAPPER ?name@type_info@@QBEPBDXZ, _MSVCRT_type_info_name@4
-DEFINE_THISCALL_WRAPPER ?raw_name@type_info@@QBEPBDXZ, _MSVCRT_type_info_raw_name@4
+DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBD@Z, _MSVCRT_exception_ctor
+DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABQBDH@Z, _MSVCRT_exception_ctor_noalloc
+DEFINE_THISCALL_ALIAS ??0exception@@QAE@ABV0@@Z, _MSVCRT_exception_copy_ctor
+DEFINE_THISCALL_ALIAS ??0exception@@QAE@XZ, _MSVCRT_exception_default_ctor
+DEFINE_THISCALL_ALIAS ??1exception@@UAE@XZ, _MSVCRT_exception_dtor
+DEFINE_THISCALL_ALIAS ??4exception@@QAEAAV0@ABV0@@Z, _MSVCRT_exception_opequals
+DEFINE_THISCALL_ALIAS ??_Eexception@@UAEPAXI@Z, _MSVCRT_exception_vector_dtor
+DEFINE_THISCALL_ALIAS ??_Gexception@@UAEPAXI@Z, _MSVCRT_exception_scalar_dtor
+DEFINE_THISCALL_ALIAS ?what@exception@@UBEPBDXZ, _MSVCRT_what_exception
+DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@ABV0@@Z, _MSVCRT_bad_typeid_copy_ctor
+DEFINE_THISCALL_ALIAS ??0bad_typeid@@QAE@PBD@Z, _MSVCRT_bad_typeid_ctor
+DEFINE_THISCALL_ALIAS ??_Fbad_typeid@@QAEXXZ, _MSVCRT_bad_typeid_default_ctor
+DEFINE_THISCALL_ALIAS ??1bad_typeid@@UAE@XZ, _MSVCRT_bad_typeid_dtor
+DEFINE_THISCALL_ALIAS ??4bad_typeid@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_typeid_opequals
+DEFINE_THISCALL_ALIAS ??_Ebad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_vector_dtor
+DEFINE_THISCALL_ALIAS ??_Gbad_typeid@@UAEPAXI@Z, _MSVCRT_bad_typeid_scalar_dtor
+DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@ABV0@@Z, _MSVCRT___non_rtti_object_copy_ctor
+DEFINE_THISCALL_ALIAS ??0__non_rtti_object@@QAE@PBD@Z, _MSVCRT___non_rtti_object_ctor
+DEFINE_THISCALL_ALIAS ??1__non_rtti_object@@UAE@XZ, _MSVCRT___non_rtti_object_dtor
+DEFINE_THISCALL_ALIAS ??4__non_rtti_object@@QAEAAV0@ABV0@@Z, _MSVCRT___non_rtti_object_opequals
+DEFINE_THISCALL_ALIAS ??_E__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_vector_dtor
+DEFINE_THISCALL_ALIAS ??_G__non_rtti_object@@UAEPAXI@Z, _MSVCRT___non_rtti_object_scalar_dtor
+DEFINE_THISCALL_ALIAS ??0bad_cast@@AAE@PBQBD@Z, _MSVCRT_bad_cast_ctor
+DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABQBD@Z, _MSVCRT_bad_cast_ctor
+DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@ABV0@@Z, _MSVCRT_bad_cast_copy_ctor
+DEFINE_THISCALL_ALIAS ??0bad_cast@@QAE@PBD@Z, _MSVCRT_bad_cast_ctor_charptr
+DEFINE_THISCALL_ALIAS ??_Fbad_cast@@QAEXXZ, _MSVCRT_bad_cast_default_ctor
+DEFINE_THISCALL_ALIAS ??1bad_cast@@UAE@XZ, _MSVCRT_bad_cast_dtor
+DEFINE_THISCALL_ALIAS ??4bad_cast@@QAEAAV0@ABV0@@Z, _MSVCRT_bad_cast_opequals
+DEFINE_THISCALL_ALIAS ??_Ebad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_vector_dtor
+DEFINE_THISCALL_ALIAS ??_Gbad_cast@@UAEPAXI@Z, _MSVCRT_bad_cast_scalar_dtor
+DEFINE_THISCALL_ALIAS ??8type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opequals_equals
+DEFINE_THISCALL_ALIAS ??9type_info@@QBEHABV0@@Z, _MSVCRT_type_info_opnot_equals
+DEFINE_THISCALL_ALIAS ?before@type_info@@QBEHABV1@@Z, _MSVCRT_type_info_before
+DEFINE_THISCALL_ALIAS ??1type_info@@UAE@XZ, _MSVCRT_type_info_dtor
+DEFINE_THISCALL_ALIAS ?name@type_info@@QBEPBDXZ, _MSVCRT_type_info_name
+DEFINE_THISCALL_ALIAS ?raw_name@type_info@@QBEPBDXZ, _MSVCRT_type_info_raw_name
#undef _MSVCRT_
@@ -108,5 +108,63 @@ DEFINE_ALIAS ?terminate@@YAXXZ, _MSVCRT_terminate, PROC
DEFINE_ALIAS ?unexpected@@YAXXZ, _MSVCRT_unexpected, PROC
+// void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
+PUBLIC _call_copy_ctor
+_call_copy_ctor:
+ push ebp
+ CFI_ADJUST_CFA_OFFSET 4
+ CFI_REL_OFFSET ebp, 0
+ mov ebp, esp
+ CFI_DEF_CFA_REGISTER ebp
+ push 1
+ mov ecx, [ebp + 12]
+ push dword ptr [ebp + 16]
+ call dword ptr [ebp + 8]
+ leave
+ CFI_DEF_CFA esp, 4
+ CFI_SAME_VALUE ebp
+ ret
+
+// void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr );
+PUBLIC _continue_after_catch
+_continue_after_catch:
+ mov edx, [esp + 4]
+ mov eax, [esp + 8]
+ mov esp, [edx - 4]
+ lea ebp, [edx + 12]
+ jmp eax
+
+// void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr );
+PUBLIC _call_finally_block
+_call_finally_block:
+ mov ebp, [esp +8]
+ jmp dword ptr [esp + 4]
+
+// int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp );
+PUBLIC _call_filter
+_call_filter:
+ push ebp
+ push [esp + 12]
+ mov ebp, [esp + 20]
+ call dword ptr [esp + 12]
+ pop ebp
+ pop ebp
+ ret
+
+// void *call_handler( void * (*func)(void), void *ebp );
+PUBLIC _call_handler
+_call_handler:
+ push ebp
+ push ebx
+ push esi
+ push edi
+ mov ebp, [esp + 24]
+ call dword ptr [esp + 29]
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+
END
diff --git a/sdk/lib/crt/except/i386/unwind.c b/sdk/lib/crt/except/i386/unwind.c
deleted file mode 100644
index f2317bd826b..00000000000
--- a/sdk/lib/crt/except/i386/unwind.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#define WIN32_NO_STATUS
-#include
-#define NTOS_MODE_USER
-#include
-#include
-#include
-#include
-
-/* VC++ extensions to Win32 SEH */
-typedef struct _SCOPETABLE
-{
- int previousTryLevel;
- int (*lpfnFilter)(PEXCEPTION_POINTERS);
- int (*lpfnHandler)(void);
-} SCOPETABLE, *PSCOPETABLE;
-
-typedef struct _MSVCRT_EXCEPTION_FRAME
-{
- PEXCEPTION_REGISTRATION_RECORD *prev;
- void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION_RECORD,
- PCONTEXT, PEXCEPTION_RECORD);
- PSCOPETABLE scopetable;
- int trylevel;
- int _ebp;
- PEXCEPTION_POINTERS xpointers;
-} MSVCRT_EXCEPTION_FRAME;
-
-void
-_local_unwind2(MSVCRT_EXCEPTION_FRAME *RegistrationFrame,
- LONG TryLevel);
-
-/*
- * @implemented
-*/
-
-void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp)
-{
- _local_unwind2((MSVCRT_EXCEPTION_FRAME*) jmp->Registration, jmp->TryLevel);
-}
diff --git a/sdk/lib/crt/except/matherr.c b/sdk/lib/crt/except/matherr.c
index da94b71ffc4..d7e6c5bf35b 100644
--- a/sdk/lib/crt/except/matherr.c
+++ b/sdk/lib/crt/except/matherr.c
@@ -47,19 +47,3 @@ void CDECL __setusermatherr(MSVCRT_matherr_func func)
MSVCRT_default_matherr_func = func;
TRACE(":new matherr handler %p\n", func);
}
-
-
-#define _FPIEEE_RECORD void
-
-/*
- * @unimplemented
- */
-int _fpieee_flt(
- unsigned long exception_code,
- struct _EXCEPTION_POINTERS* ExceptionPointer,
- int (*handler)(_FPIEEE_RECORD*)
- )
-{
- FIXME("Unimplemented!\n");
- return 0;
-}
diff --git a/sdk/lib/crt/except/xcptfil.c b/sdk/lib/crt/except/xcptfil.c
deleted file mode 100644
index c5b8d1d1e76..00000000000
--- a/sdk/lib/crt/except/xcptfil.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include
-#include "internal/wine/msvcrt.h"
-#include "internal/wine/cppexcept.h"
-
-typedef void (*sighandler_t)(int);
-static sighandler_t sighandlers[NSIG] = { SIG_DFL };
-
-/* The exception codes are actually NTSTATUS values */
-static const struct
-{
- NTSTATUS status;
- int signal;
-} float_exception_map[] = {
- { EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
- { EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
- { EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
- { EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
- { EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
- { EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
- { EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
-};
-
-/*
- * @implemented
- */
-int CDECL
-_XcptFilter(NTSTATUS ExceptionCode,
- struct _EXCEPTION_POINTERS * except)
-{
- LONG ret = EXCEPTION_CONTINUE_SEARCH;
- sighandler_t handler;
-
- if (!except || !except->ExceptionRecord)
- return EXCEPTION_CONTINUE_SEARCH;
-
- switch (except->ExceptionRecord->ExceptionCode)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- if ((handler = sighandlers[SIGSEGV]) != SIG_DFL)
- {
- if (handler != SIG_IGN)
- {
- sighandlers[SIGSEGV] = SIG_DFL;
- handler(SIGSEGV);
- }
- ret = EXCEPTION_CONTINUE_EXECUTION;
- }
- break;
- /* According to msdn,
- * the FPE signal handler takes as a second argument the type of
- * floating point exception.
- */
- case EXCEPTION_FLT_DENORMAL_OPERAND:
- case EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case EXCEPTION_FLT_INEXACT_RESULT:
- case EXCEPTION_FLT_INVALID_OPERATION:
- case EXCEPTION_FLT_OVERFLOW:
- case EXCEPTION_FLT_STACK_CHECK:
- case EXCEPTION_FLT_UNDERFLOW:
- if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
- {
- if (handler != SIG_IGN)
- {
- unsigned int i;
- int float_signal = _FPE_INVALID;
-
- sighandlers[SIGFPE] = SIG_DFL;
- for (i = 0; i < sizeof(float_exception_map) /
- sizeof(float_exception_map[0]); i++)
- {
- if (float_exception_map[i].status ==
- except->ExceptionRecord->ExceptionCode)
- {
- float_signal = float_exception_map[i].signal;
- break;
- }
- }
- ((float_handler)handler)(SIGFPE, float_signal);
- }
- ret = EXCEPTION_CONTINUE_EXECUTION;
- }
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- case EXCEPTION_PRIV_INSTRUCTION:
- if ((handler = sighandlers[SIGILL]) != SIG_DFL)
- {
- if (handler != SIG_IGN)
- {
- sighandlers[SIGILL] = SIG_DFL;
- handler(SIGILL);
- }
- ret = EXCEPTION_CONTINUE_EXECUTION;
- }
- break;
- }
- return ret;
-}
-
diff --git a/sdk/lib/crt/include/internal/wine_msc.h b/sdk/lib/crt/include/internal/wine_msc.h
index d7c799a09f2..ebe023b48d0 100644
--- a/sdk/lib/crt/include/internal/wine_msc.h
+++ b/sdk/lib/crt/include/internal/wine_msc.h
@@ -1,50 +1,100 @@
-#define DEFINE_THISCALL_WRAPPER(func, args) \
- void __declspec(naked) __thiscall_ ## func (void) \
- { \
- __asm { pop eax } \
- __asm { push ecx } \
- __asm { push eax } \
- __asm { jmp func } \
- }
-
-exception * __stdcall MSVCRT_exception_ctor(exception * _this, const char ** name);
-exception * __stdcall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc);
-exception * __stdcall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs);
-exception * __stdcall MSVCRT_exception_default_ctor(exception * _this);
-void __stdcall MSVCRT_exception_dtor(exception * _this);
-exception * __stdcall MSVCRT_exception_opequals(exception * _this, const exception * rhs);
-void * __stdcall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags);
-void * __stdcall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags);
-const char * __stdcall MSVCRT_what_exception(exception * _this);
-bad_typeid * __stdcall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs);
-bad_typeid * __stdcall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name);
-bad_typeid * __stdcall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this);
-void __stdcall MSVCRT_bad_typeid_dtor(bad_typeid * _this);
-bad_typeid * __stdcall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs);
-void * __stdcall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags);
-void * __stdcall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags);
-__non_rtti_object * __stdcall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, const __non_rtti_object * rhs);
-__non_rtti_object * __stdcall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, const char * name);
-void __stdcall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this);
-__non_rtti_object * __stdcall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, const __non_rtti_object *rhs);
-void * __stdcall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags);
-void * __stdcall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags);
-bad_cast * __stdcall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name);
-bad_cast * __stdcall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs);
-bad_cast * __stdcall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name);
-bad_cast * __stdcall MSVCRT_bad_cast_default_ctor(bad_cast * _this);
-void __stdcall MSVCRT_bad_cast_dtor(bad_cast * _this);
-bad_cast * __stdcall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs);
-void * __stdcall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags);
-void * __stdcall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags);
-int __stdcall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs);
-int __stdcall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs);
-int __stdcall MSVCRT_type_info_before(type_info * _this, const type_info * rhs);
-void __stdcall MSVCRT_type_info_dtor(type_info * _this);
-const char * __stdcall MSVCRT_type_info_name(type_info * _this);
-const char * __stdcall MSVCRT_type_info_raw_name(type_info * _this);
-void * __stdcall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags);
-
-#define __ASM_VTABLE(name,funcs)
-//void *MSVCRT_ ## name ##_vtable[] =
+exception * __thiscall MSVCRT_exception_ctor(exception * _this, const char ** name);
+exception * __thiscall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc);
+exception * __thiscall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs);
+exception * __thiscall MSVCRT_exception_default_ctor(exception * _this);
+void __thiscall MSVCRT_exception_dtor(exception * _this);
+exception * __thiscall MSVCRT_exception_opequals(exception * _this, const exception * rhs);
+void * __thiscall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags);
+void * __thiscall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags);
+const char * __thiscall MSVCRT_what_exception(exception * _this);
+bad_typeid * __thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs);
+bad_typeid * __thiscall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name);
+bad_typeid * __thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this);
+void __thiscall MSVCRT_bad_typeid_dtor(bad_typeid * _this);
+bad_typeid * __thiscall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs);
+void * __thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags);
+void * __thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags);
+__non_rtti_object * __thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, const __non_rtti_object * rhs);
+__non_rtti_object * __thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, const char * name);
+void __thiscall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this);
+__non_rtti_object * __thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, const __non_rtti_object *rhs);
+void * __thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags);
+void * __thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags);
+bad_cast * __thiscall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name);
+bad_cast * __thiscall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs);
+bad_cast * __thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name);
+bad_cast * __thiscall MSVCRT_bad_cast_default_ctor(bad_cast * _this);
+void __thiscall MSVCRT_bad_cast_dtor(bad_cast * _this);
+bad_cast * __thiscall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs);
+void * __thiscall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags);
+void * __thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags);
+int __thiscall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs);
+int __thiscall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs);
+int __thiscall MSVCRT_type_info_before(type_info * _this, const type_info * rhs);
+void __thiscall MSVCRT_type_info_dtor(type_info * _this);
+const char * __thiscall MSVCRT_type_info_name(type_info * _this);
+const char * __thiscall MSVCRT_type_info_raw_name(type_info * _this);
+void * __thiscall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags);
+#if _MSVCR_VER >= 80
+bad_alloc* __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc* _this, const bad_alloc* rhs);
+bad_alloc* __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc* _this, const bad_alloc* rhs);
+void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc* _this);
+#endif /* _MSVCR_VER >= 80 */
+#if _MSVCR_VER >= 100
+scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor_name(
+ scheduler_resource_allocation_error* this, const char* name, HRESULT hr);
+scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor(
+ scheduler_resource_allocation_error* this, HRESULT hr);
+scheduler_resource_allocation_error* __thiscall MSVCRT_scheduler_resource_allocation_error_copy_ctor(
+ scheduler_resource_allocation_error* this,
+ const scheduler_resource_allocation_error* rhs);
+HRESULT __thiscall scheduler_resource_allocation_error_get_error_code(
+ const scheduler_resource_allocation_error* this);
+void __thiscall MSVCRT_scheduler_resource_allocation_error_dtor(
+ scheduler_resource_allocation_error* this);
+improper_lock* __thiscall improper_lock_ctor_str(improper_lock* this, const char* str);
+improper_lock* __thiscall improper_lock_ctor(improper_lock* this);
+improper_lock* __thiscall MSVCRT_improper_lock_copy_ctor(improper_lock* _this, const improper_lock* rhs);
+void __thiscall MSVCRT_improper_lock_dtor(improper_lock* _this);
+invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str(
+ invalid_scheduler_policy_key* this, const char* str);
+invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor(
+ invalid_scheduler_policy_key* this);
+invalid_scheduler_policy_key* __thiscall MSVCRT_invalid_scheduler_policy_key_copy_ctor(
+ invalid_scheduler_policy_key* _this, const invalid_scheduler_policy_key* rhs);
+void __thiscall MSVCRT_invalid_scheduler_policy_key_dtor(
+ invalid_scheduler_policy_key* _this);
+invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str(
+ invalid_scheduler_policy_value* this, const char* str);
+invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor(
+ invalid_scheduler_policy_value* this);
+invalid_scheduler_policy_value* __thiscall MSVCRT_invalid_scheduler_policy_value_copy_ctor(
+ invalid_scheduler_policy_value* _this, const invalid_scheduler_policy_value* rhs);
+void __thiscall MSVCRT_invalid_scheduler_policy_value_dtor(
+ invalid_scheduler_policy_value* _this);
+invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str(
+ invalid_scheduler_policy_thread_specification* this, const char* str);
+invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor(
+ invalid_scheduler_policy_thread_specification* this);
+invalid_scheduler_policy_thread_specification* __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor(
+ invalid_scheduler_policy_thread_specification* _this, const invalid_scheduler_policy_thread_specification* rhs);
+void __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_dtor(
+ invalid_scheduler_policy_thread_specification* _this);
+improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str(
+ improper_scheduler_attach* this, const char* str);
+improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor(
+ improper_scheduler_attach* this);
+improper_scheduler_attach* __thiscall MSVCRT_improper_scheduler_attach_copy_ctor(
+ improper_scheduler_attach* _this, const improper_scheduler_attach* rhs);
+void __thiscall MSVCRT_improper_scheduler_attach_dtor(
+ improper_scheduler_attach* _this);
+improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str(
+ improper_scheduler_detach* this, const char* str);
+improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor(
+ improper_scheduler_detach* this);
+improper_scheduler_detach* __thiscall MSVCRT_improper_scheduler_detach_copy_ctor(
+ improper_scheduler_detach* _this, const improper_scheduler_detach* rhs);
+void __thiscall MSVCRT_improper_scheduler_detach_dtor(
+ improper_scheduler_detach* _this);
+#endif
diff --git a/sdk/lib/crt/wine/cpp.c b/sdk/lib/crt/wine/cpp.c
new file mode 100644
index 00000000000..4b12b2dfbe1
--- /dev/null
+++ b/sdk/lib/crt/wine/cpp.c
@@ -0,0 +1,2189 @@
+/*
+ * msvcrt.dll C++ objects
+ *
+ * Copyright 2000 Jon Griffiths
+ * Copyright 2003, 2004 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include
+
+#include "windef.h"
+#include "winternl.h"
+#include "wine/exception.h"
+#include "wine/debug.h"
+#include "msvcrt.h"
+#include "cppexcept.h"
+#include "mtdll.h"
+#include "cxx.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
+
+struct __type_info_node
+{
+ void *memPtr;
+ struct __type_info_node* next;
+};
+
+typedef exception bad_cast;
+typedef exception bad_typeid;
+typedef exception __non_rtti_object;
+
+extern const vtable_ptr MSVCRT_exception_vtable;
+extern const vtable_ptr MSVCRT_bad_typeid_vtable;
+extern const vtable_ptr MSVCRT_bad_cast_vtable;
+extern const vtable_ptr MSVCRT___non_rtti_object_vtable;
+extern const vtable_ptr MSVCRT_type_info_vtable;
+
+/* get the vtable pointer for a C++ object */
+static inline const vtable_ptr *get_vtable( void *obj )
+{
+ return *(const vtable_ptr **)obj;
+}
+
+static inline const rtti_object_locator *get_obj_locator( void *cppobj )
+{
+ const vtable_ptr *vtable = get_vtable( cppobj );
+ return (const rtti_object_locator *)vtable[-1];
+}
+
+#ifndef __x86_64__
+static void dump_obj_locator( const rtti_object_locator *ptr )
+{
+ int i;
+ const rtti_object_hierarchy *h = ptr->type_hierarchy;
+
+ TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
+ ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
+ ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy );
+ TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
+ h->signature, h->attributes, h->array_len, h->base_classes );
+ for (i = 0; i < h->array_len; i++)
+ {
+ TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
+ h->base_classes->bases[i],
+ h->base_classes->bases[i]->num_base_classes,
+ h->base_classes->bases[i]->offsets.this_offset,
+ h->base_classes->bases[i]->offsets.vbase_descr,
+ h->base_classes->bases[i]->offsets.vbase_offset,
+ h->base_classes->bases[i]->attributes,
+ h->base_classes->bases[i]->type_descriptor,
+ dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) );
+ }
+}
+
+#else
+
+static void dump_obj_locator( const rtti_object_locator *ptr )
+{
+ int i;
+ char *base = ptr->signature == 0 ? RtlPcToFileHeader((void*)ptr, (void**)&base) : (char*)ptr - ptr->object_locator;
+ const rtti_object_hierarchy *h = (const rtti_object_hierarchy*)(base + ptr->type_hierarchy);
+ const type_info *type_descriptor = (const type_info*)(base + ptr->type_descriptor);
+
+ TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n",
+ ptr, ptr->signature, ptr->base_class_offset, ptr->flags,
+ type_descriptor, dbgstr_type_info(type_descriptor), h );
+ TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n",
+ h->signature, h->attributes, h->array_len, base + h->base_classes );
+ for (i = 0; i < h->array_len; i++)
+ {
+ const rtti_base_descriptor *bases = (rtti_base_descriptor*)(base +
+ ((const rtti_base_array*)(base + h->base_classes))->bases[i]);
+
+ TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n",
+ bases,
+ bases->num_base_classes,
+ bases->offsets.this_offset,
+ bases->offsets.vbase_descr,
+ bases->offsets.vbase_offset,
+ bases->attributes,
+ base + bases->type_descriptor,
+ dbgstr_type_info((const type_info*)(base + bases->type_descriptor)) );
+ }
+}
+#endif
+
+/* Internal common ctor for exception */
+static void EXCEPTION_ctor(exception *_this, const char** name)
+{
+ _this->vtable = &MSVCRT_exception_vtable;
+ if (*name)
+ {
+ unsigned int name_len = strlen(*name) + 1;
+ _this->name = MSVCRT_malloc(name_len);
+ memcpy(_this->name, *name, name_len);
+ _this->do_free = TRUE;
+ }
+ else
+ {
+ _this->name = NULL;
+ _this->do_free = FALSE;
+ }
+}
+
+#ifdef __REACTOS__
+#include
+#endif /* __REACTOS__ */
+
+/******************************************************************
+ * ??0exception@@QAE@ABQBD@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor,8)
+exception * __thiscall MSVCRT_exception_ctor(exception * _this, const char ** name)
+{
+ TRACE("(%p,%s)\n", _this, *name);
+ EXCEPTION_ctor(_this, name);
+ return _this;
+}
+
+/******************************************************************
+ * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor_noalloc,12)
+exception * __thiscall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc)
+{
+ TRACE("(%p,%s)\n", _this, *name);
+ _this->vtable = &MSVCRT_exception_vtable;
+ _this->name = *name;
+ _this->do_free = FALSE;
+ return _this;
+}
+
+/******************************************************************
+ * ??0exception@@QAE@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor,8)
+exception * __thiscall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs)
+{
+ TRACE("(%p,%p)\n", _this, rhs);
+
+ if (!rhs->do_free)
+ {
+ _this->vtable = &MSVCRT_exception_vtable;
+ _this->name = rhs->name;
+ _this->do_free = FALSE;
+ }
+ else
+ EXCEPTION_ctor(_this, (const char**)&rhs->name);
+ TRACE("name = %s\n", _this->name);
+ return _this;
+}
+
+/******************************************************************
+ * ??0exception@@QAE@XZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor,4)
+exception * __thiscall MSVCRT_exception_default_ctor(exception * _this)
+{
+ static const char* empty = NULL;
+
+ TRACE("(%p)\n", _this);
+ EXCEPTION_ctor(_this, &empty);
+ return _this;
+}
+
+/******************************************************************
+ * ??1exception@@UAE@XZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor,4)
+void __thiscall MSVCRT_exception_dtor(exception * _this)
+{
+ TRACE("(%p)\n", _this);
+ _this->vtable = &MSVCRT_exception_vtable;
+ if (_this->do_free) MSVCRT_free(_this->name);
+}
+
+/******************************************************************
+ * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals,8)
+exception * __thiscall MSVCRT_exception_opequals(exception * _this, const exception * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ if (_this != rhs)
+ {
+ MSVCRT_exception_dtor(_this);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ }
+ TRACE("name = %s\n", _this->name);
+ return _this;
+}
+
+/******************************************************************
+ * ??_Eexception@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor,8)
+void * __thiscall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ if (flags & 2)
+ {
+ /* we have an array, with the number of elements stored before the first object */
+ INT_PTR i, *ptr = (INT_PTR *)_this - 1;
+
+ for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i);
+ MSVCRT_operator_delete(ptr);
+ }
+ else
+ {
+ MSVCRT_exception_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ }
+ return _this;
+}
+
+/******************************************************************
+ * ??_Gexception@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor,8)
+void * __thiscall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ MSVCRT_exception_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ return _this;
+}
+
+/******************************************************************
+ * ?what@exception@@UBEPBDXZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception,4)
+const char * __thiscall MSVCRT_what_exception(exception * _this)
+{
+ TRACE("(%p) returning %s\n", _this, _this->name);
+ return _this->name ? _this->name : "Unknown exception";
+}
+
+/******************************************************************
+ * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor,8)
+bad_typeid * __thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_bad_typeid_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor,8)
+bad_typeid * __thiscall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name)
+{
+ TRACE("(%p %s)\n", _this, name);
+ EXCEPTION_ctor(_this, &name);
+ _this->vtable = &MSVCRT_bad_typeid_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_default_ctor,4)
+bad_typeid * __thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this)
+{
+ return MSVCRT_bad_typeid_ctor( _this, "bad typeid" );
+}
+
+/******************************************************************
+ * ??1bad_typeid@@UAE@XZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor,4)
+void __thiscall MSVCRT_bad_typeid_dtor(bad_typeid * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+/******************************************************************
+ * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals,8)
+bad_typeid * __thiscall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_opequals(_this, rhs);
+ return _this;
+}
+
+/******************************************************************
+ * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor,8)
+void * __thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ if (flags & 2)
+ {
+ /* we have an array, with the number of elements stored before the first object */
+ INT_PTR i, *ptr = (INT_PTR *)_this - 1;
+
+ for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i);
+ MSVCRT_operator_delete(ptr);
+ }
+ else
+ {
+ MSVCRT_bad_typeid_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ }
+ return _this;
+}
+
+/******************************************************************
+ * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor,8)
+void * __thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ MSVCRT_bad_typeid_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ return _this;
+}
+
+/******************************************************************
+ * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor,8)
+__non_rtti_object * __thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this,
+ const __non_rtti_object * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_bad_typeid_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT___non_rtti_object_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor,8)
+__non_rtti_object * __thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this,
+ const char * name)
+{
+ TRACE("(%p %s)\n", _this, name);
+ EXCEPTION_ctor(_this, &name);
+ _this->vtable = &MSVCRT___non_rtti_object_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor,4)
+void __thiscall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_bad_typeid_dtor(_this);
+}
+
+/******************************************************************
+ * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals,8)
+__non_rtti_object * __thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this,
+ const __non_rtti_object *rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_bad_typeid_opequals(_this, rhs);
+ return _this;
+}
+
+/******************************************************************
+ * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor,8)
+void * __thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ if (flags & 2)
+ {
+ /* we have an array, with the number of elements stored before the first object */
+ INT_PTR i, *ptr = (INT_PTR *)_this - 1;
+
+ for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i);
+ MSVCRT_operator_delete(ptr);
+ }
+ else
+ {
+ MSVCRT___non_rtti_object_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ }
+ return _this;
+}
+
+/******************************************************************
+ * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor,8)
+void * __thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ MSVCRT___non_rtti_object_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ return _this;
+}
+
+/******************************************************************
+ * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@)
+ * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor,8)
+bad_cast * __thiscall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name)
+{
+ TRACE("(%p %s)\n", _this, *name);
+ EXCEPTION_ctor(_this, name);
+ _this->vtable = &MSVCRT_bad_cast_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor,8)
+bad_cast * __thiscall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_bad_cast_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor_charptr,8)
+bad_cast * __thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name)
+{
+ TRACE("(%p %s)\n", _this, name);
+ EXCEPTION_ctor(_this, &name);
+ _this->vtable = &MSVCRT_bad_cast_vtable;
+ return _this;
+}
+
+/******************************************************************
+ * ??_Fbad_cast@@QAEXXZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_default_ctor,4)
+bad_cast * __thiscall MSVCRT_bad_cast_default_ctor(bad_cast * _this)
+{
+ return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" );
+}
+
+/******************************************************************
+ * ??1bad_cast@@UAE@XZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor,4)
+void __thiscall MSVCRT_bad_cast_dtor(bad_cast * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+/******************************************************************
+ * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals,8)
+bad_cast * __thiscall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_opequals(_this, rhs);
+ return _this;
+}
+
+/******************************************************************
+ * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor,8)
+void * __thiscall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ if (flags & 2)
+ {
+ /* we have an array, with the number of elements stored before the first object */
+ INT_PTR i, *ptr = (INT_PTR *)_this - 1;
+
+ for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_cast_dtor(_this + i);
+ MSVCRT_operator_delete(ptr);
+ }
+ else
+ {
+ MSVCRT_bad_cast_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ }
+ return _this;
+}
+
+/******************************************************************
+ * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor,8)
+void * __thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ MSVCRT_bad_cast_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ return _this;
+}
+
+/******************************************************************
+ * ??8type_info@@QBEHABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals,8)
+int __thiscall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs)
+{
+ int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1);
+ TRACE("(%p %p) returning %d\n", _this, rhs, ret);
+ return ret;
+}
+
+/******************************************************************
+ * ??9type_info@@QBEHABV0@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals,8)
+int __thiscall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs)
+{
+ int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1);
+ TRACE("(%p %p) returning %d\n", _this, rhs, ret);
+ return ret;
+}
+
+/******************************************************************
+ * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before,8)
+int __thiscall MSVCRT_type_info_before(type_info * _this, const type_info * rhs)
+{
+ int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0;
+ TRACE("(%p %p) returning %d\n", _this, rhs, ret);
+ return ret;
+}
+
+/******************************************************************
+ * ??1type_info@@UAE@XZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor,4)
+void __thiscall MSVCRT_type_info_dtor(type_info * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_free(_this->name);
+}
+
+/******************************************************************
+ * ?name@type_info@@QBEPBDXZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name,4)
+const char * __thiscall MSVCRT_type_info_name(type_info * _this)
+{
+ if (!_this->name)
+ {
+ /* Create and set the demangled name */
+ /* Note: mangled name in type_info struct always starts with a '.', while
+ * it isn't valid for mangled name.
+ * Is this '.' really part of the mangled name, or has it some other meaning ?
+ */
+ char* name = __unDName(0, _this->mangled + 1, 0,
+ MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
+ if (name)
+ {
+ unsigned int len = strlen(name);
+
+ /* It seems _unDName may leave blanks at the end of the demangled name */
+ while (len && name[--len] == ' ')
+ name[len] = '\0';
+
+ if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL))
+ {
+ /* Another thread set this member since we checked above - use it */
+ MSVCRT_free(name);
+ }
+ }
+ }
+ TRACE("(%p) returning %s\n", _this, _this->name);
+ return _this->name;
+}
+
+/******************************************************************
+ * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@)
+ */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name,4)
+const char * __thiscall MSVCRT_type_info_raw_name(type_info * _this)
+{
+ TRACE("(%p) returning %s\n", _this, _this->mangled);
+ return _this->mangled;
+}
+
+/* Unexported */
+DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor,8)
+void * __thiscall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags)
+{
+ TRACE("(%p %x)\n", _this, flags);
+ if (flags & 2)
+ {
+ /* we have an array, with the number of elements stored before the first object */
+ INT_PTR i, *ptr = (INT_PTR *)_this - 1;
+
+ for (i = *ptr - 1; i >= 0; i--) MSVCRT_type_info_dtor(_this + i);
+ MSVCRT_operator_delete(ptr);
+ }
+ else
+ {
+ MSVCRT_type_info_dtor(_this);
+ if (flags & 1) MSVCRT_operator_delete(_this);
+ }
+ return _this;
+}
+
+#if _MSVCR_VER >= 80
+
+typedef exception bad_alloc;
+extern const vtable_ptr MSVCRT_bad_alloc_vtable;
+
+static void bad_alloc_ctor(bad_alloc *this, const char **name)
+{
+ MSVCRT_exception_ctor(this, name);
+ this->vtable = &MSVCRT_bad_alloc_vtable;
+}
+
+/* bad_alloc class implementation */
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_copy_ctor,8)
+bad_alloc * __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_bad_alloc_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_dtor,4)
+void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+#endif /* _MSVCR_VER >= 80 */
+
+#if _MSVCR_VER >= 100
+
+typedef struct {
+ exception e;
+ HRESULT hr;
+} scheduler_resource_allocation_error;
+extern const vtable_ptr MSVCRT_scheduler_resource_allocation_error_vtable;
+
+/* ??0scheduler_resource_allocation_error@Concurrency@@QAE@PBDJ@Z */
+/* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@PEBDJ@Z */
+DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor_name, 12)
+scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor_name(
+ scheduler_resource_allocation_error *this, const char *name, HRESULT hr)
+{
+ TRACE("(%p %s %x)\n", this, wine_dbgstr_a(name), hr);
+ MSVCRT_exception_ctor(&this->e, &name);
+ this->e.vtable = &MSVCRT_scheduler_resource_allocation_error_vtable;
+ this->hr = hr;
+ return this;
+}
+
+/* ??0scheduler_resource_allocation_error@Concurrency@@QAE@J@Z */
+/* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@J@Z */
+DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor, 8)
+scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor(
+ scheduler_resource_allocation_error *this, HRESULT hr)
+{
+ return scheduler_resource_allocation_error_ctor_name(this, NULL, hr);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_copy_ctor,8)
+scheduler_resource_allocation_error* __thiscall MSVCRT_scheduler_resource_allocation_error_copy_ctor(
+ scheduler_resource_allocation_error *this,
+ const scheduler_resource_allocation_error *rhs)
+{
+ TRACE("(%p,%p)\n", this, rhs);
+
+ if (!rhs->e.do_free)
+ memcpy(this, rhs, sizeof(*this));
+ else
+ scheduler_resource_allocation_error_ctor_name(this, rhs->e.name, rhs->hr);
+ return this;
+}
+
+/* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QBEJXZ */
+/* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QEBAJXZ */
+DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_get_error_code, 4)
+HRESULT __thiscall scheduler_resource_allocation_error_get_error_code(
+ const scheduler_resource_allocation_error *this)
+{
+ TRACE("(%p)\n", this);
+ return this->hr;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_dtor,4)
+void __thiscall MSVCRT_scheduler_resource_allocation_error_dtor(
+ scheduler_resource_allocation_error * this)
+{
+ TRACE("(%p)\n", this);
+ MSVCRT_exception_dtor(&this->e);
+}
+
+typedef exception improper_lock;
+extern const vtable_ptr MSVCRT_improper_lock_vtable;
+
+/* ??0improper_lock@Concurrency@@QAE@PBD@Z */
+/* ??0improper_lock@Concurrency@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(improper_lock_ctor_str, 8)
+improper_lock* __thiscall improper_lock_ctor_str(improper_lock *this, const char *str)
+{
+ TRACE("(%p %p)\n", this, str);
+ MSVCRT_exception_ctor(this, &str);
+ this->vtable = &MSVCRT_improper_lock_vtable;
+ return this;
+}
+
+/* ??0improper_lock@Concurrency@@QAE@XZ */
+/* ??0improper_lock@Concurrency@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(improper_lock_ctor, 4)
+improper_lock* __thiscall improper_lock_ctor(improper_lock *this)
+{
+ return improper_lock_ctor_str(this, NULL);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_copy_ctor,8)
+improper_lock * __thiscall MSVCRT_improper_lock_copy_ctor(improper_lock * _this, const improper_lock * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_improper_lock_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_dtor,4)
+void __thiscall MSVCRT_improper_lock_dtor(improper_lock * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+typedef exception invalid_scheduler_policy_key;
+extern const vtable_ptr MSVCRT_invalid_scheduler_policy_key_vtable;
+
+/* ??0invalid_scheduler_policy_key@Concurrency@@QAE@PBD@Z */
+/* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor_str, 8)
+invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str(
+ invalid_scheduler_policy_key *this, const char *str)
+{
+ TRACE("(%p %p)\n", this, str);
+ MSVCRT_exception_ctor(this, &str);
+ this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable;
+ return this;
+}
+
+/* ??0invalid_scheduler_policy_key@Concurrency@@QAE@XZ */
+/* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor, 4)
+invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor(
+ invalid_scheduler_policy_key *this)
+{
+ return invalid_scheduler_policy_key_ctor_str(this, NULL);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_copy_ctor,8)
+invalid_scheduler_policy_key * __thiscall MSVCRT_invalid_scheduler_policy_key_copy_ctor(
+ invalid_scheduler_policy_key * _this, const invalid_scheduler_policy_key * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_dtor,4)
+void __thiscall MSVCRT_invalid_scheduler_policy_key_dtor(
+ invalid_scheduler_policy_key * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+typedef exception invalid_scheduler_policy_value;
+extern const vtable_ptr MSVCRT_invalid_scheduler_policy_value_vtable;
+
+/* ??0invalid_scheduler_policy_value@Concurrency@@QAE@PBD@Z */
+/* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor_str, 8)
+invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str(
+ invalid_scheduler_policy_value *this, const char *str)
+{
+ TRACE("(%p %p)\n", this, str);
+ MSVCRT_exception_ctor(this, &str);
+ this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable;
+ return this;
+}
+
+/* ??0invalid_scheduler_policy_value@Concurrency@@QAE@XZ */
+/* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor, 4)
+invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor(
+ invalid_scheduler_policy_value *this)
+{
+ return invalid_scheduler_policy_value_ctor_str(this, NULL);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_copy_ctor,8)
+invalid_scheduler_policy_value * __thiscall MSVCRT_invalid_scheduler_policy_value_copy_ctor(
+ invalid_scheduler_policy_value * _this, const invalid_scheduler_policy_value * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_dtor,4)
+void __thiscall MSVCRT_invalid_scheduler_policy_value_dtor(
+ invalid_scheduler_policy_value * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+typedef exception invalid_scheduler_policy_thread_specification;
+extern const vtable_ptr MSVCRT_invalid_scheduler_policy_thread_specification_vtable;
+
+/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@PBD@Z */
+/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor_str, 8)
+invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str(
+ invalid_scheduler_policy_thread_specification *this, const char *str)
+{
+ TRACE("(%p %p)\n", this, str);
+ MSVCRT_exception_ctor(this, &str);
+ this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable;
+ return this;
+}
+
+/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@XZ */
+/* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor, 4)
+invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor(
+ invalid_scheduler_policy_thread_specification *this)
+{
+ return invalid_scheduler_policy_thread_specification_ctor_str(this, NULL);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor,8)
+invalid_scheduler_policy_thread_specification * __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor(
+ invalid_scheduler_policy_thread_specification * _this, const invalid_scheduler_policy_thread_specification * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_dtor,4)
+void __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_dtor(
+ invalid_scheduler_policy_thread_specification * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+typedef exception improper_scheduler_attach;
+extern const vtable_ptr MSVCRT_improper_scheduler_attach_vtable;
+
+/* ??0improper_scheduler_attach@Concurrency@@QAE@PBD@Z */
+/* ??0improper_scheduler_attach@Concurrency@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor_str, 8)
+improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str(
+ improper_scheduler_attach *this, const char *str)
+{
+ TRACE("(%p %p)\n", this, str);
+ MSVCRT_exception_ctor(this, &str);
+ this->vtable = &MSVCRT_improper_scheduler_attach_vtable;
+ return this;
+}
+
+/* ??0improper_scheduler_attach@Concurrency@@QAE@XZ */
+/* ??0improper_scheduler_attach@Concurrency@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor, 4)
+improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor(
+ improper_scheduler_attach *this)
+{
+ return improper_scheduler_attach_ctor_str(this, NULL);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_copy_ctor,8)
+improper_scheduler_attach * __thiscall MSVCRT_improper_scheduler_attach_copy_ctor(
+ improper_scheduler_attach * _this, const improper_scheduler_attach * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_improper_scheduler_attach_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_dtor,4)
+void __thiscall MSVCRT_improper_scheduler_attach_dtor(
+ improper_scheduler_attach * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+typedef exception improper_scheduler_detach;
+extern const vtable_ptr MSVCRT_improper_scheduler_detach_vtable;
+
+/* ??0improper_scheduler_detach@Concurrency@@QAE@PBD@Z */
+/* ??0improper_scheduler_detach@Concurrency@@QEAA@PEBD@Z */
+DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor_str, 8)
+improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str(
+ improper_scheduler_detach *this, const char *str)
+{
+ TRACE("(%p %p)\n", this, str);
+ MSVCRT_exception_ctor(this, &str);
+ this->vtable = &MSVCRT_improper_scheduler_detach_vtable;
+ return this;
+}
+
+/* ??0improper_scheduler_detach@Concurrency@@QAE@XZ */
+/* ??0improper_scheduler_detach@Concurrency@@QEAA@XZ */
+DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor, 4)
+improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor(
+ improper_scheduler_detach *this)
+{
+ return improper_scheduler_detach_ctor_str(this, NULL);
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_copy_ctor,8)
+improper_scheduler_detach * __thiscall MSVCRT_improper_scheduler_detach_copy_ctor(
+ improper_scheduler_detach * _this, const improper_scheduler_detach * rhs)
+{
+ TRACE("(%p %p)\n", _this, rhs);
+ MSVCRT_exception_copy_ctor(_this, rhs);
+ _this->vtable = &MSVCRT_improper_scheduler_detach_vtable;
+ return _this;
+}
+
+DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_dtor,4)
+void __thiscall MSVCRT_improper_scheduler_detach_dtor(
+ improper_scheduler_detach * _this)
+{
+ TRACE("(%p)\n", _this);
+ MSVCRT_exception_dtor(_this);
+}
+
+#endif /* _MSVCR_VER >= 100 */
+
+#ifndef _MSC_VER
+#ifndef __GNUC__
+void __asm_dummy_vtables(void) {
+#endif
+
+__ASM_VTABLE(type_info,
+ VTABLE_ADD_FUNC(MSVCRT_type_info_vector_dtor));
+__ASM_VTABLE(exception,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+#if _MSVCR_VER >= 80
+__ASM_VTABLE(exception_old,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(bad_alloc,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+#endif
+__ASM_VTABLE(bad_typeid,
+ VTABLE_ADD_FUNC(MSVCRT_bad_typeid_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(bad_cast,
+ VTABLE_ADD_FUNC(MSVCRT_bad_cast_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(__non_rtti_object,
+ VTABLE_ADD_FUNC(MSVCRT___non_rtti_object_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+#if _MSVCR_VER >= 100
+__ASM_VTABLE(scheduler_resource_allocation_error,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(improper_lock,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(invalid_scheduler_policy_key,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(invalid_scheduler_policy_value,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(invalid_scheduler_policy_thread_specification,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(improper_scheduler_attach,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+__ASM_VTABLE(improper_scheduler_detach,
+ VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor)
+ VTABLE_ADD_FUNC(MSVCRT_what_exception));
+#endif
+
+#ifndef __GNUC__
+}
+#endif
+#endif /* !_MSC_VER */
+
+DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" )
+#if _MSVCR_VER >= 80
+DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@std@@" )
+DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" )
+DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" )
+DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" )
+DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" )
+DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" )
+#else
+DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@@" )
+DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" )
+DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" )
+DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" )
+#endif
+#if _MSVCR_VER >= 100
+DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &exception_rtti_base_descriptor,
+ ".?AVscheduler_resource_allocation_error@Concurrency@@")
+DEFINE_RTTI_DATA1(improper_lock, 0, &exception_rtti_base_descriptor, ".?AVimproper_lock@Concurrency@@" )
+DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &exception_rtti_base_descriptor,
+ ".?AVinvalid_scheduler_policy_key@Concurrency@@" )
+DEFINE_RTTI_DATA1(invalid_scheduler_policy_value, 0, &exception_rtti_base_descriptor,
+ ".?AVinvalid_scheduler_policy_value@Concurrency@@" )
+DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &exception_rtti_base_descriptor,
+ ".?AVinvalid_scheduler_policy_thread_specification@Concurrency@@" )
+DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &exception_rtti_base_descriptor,
+ ".?AVimproper_scheduler_attach@Concurrency@@" )
+DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor,
+ ".?AVimproper_scheduler_detach@Concurrency@@" )
+#endif
+
+DEFINE_EXCEPTION_TYPE_INFO( exception, 0, NULL, NULL )
+DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL )
+DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL )
+DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info )
+#if _MSVCR_VER >= 80
+DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL )
+#endif
+#if _MSVCR_VER >= 100
+DEFINE_EXCEPTION_TYPE_INFO(scheduler_resource_allocation_error, 1, &exception_cxx_type_info, NULL)
+DEFINE_EXCEPTION_TYPE_INFO(improper_lock, 1, &exception_cxx_type_info, NULL)
+DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_key, 1, &exception_cxx_type_info, NULL)
+DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_value, 1, &exception_cxx_type_info, NULL)
+DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_thread_specification, 1, &exception_cxx_type_info, NULL)
+DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_attach, 1, &exception_cxx_type_info, NULL)
+DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_detach, 1, &exception_cxx_type_info, NULL)
+#endif
+
+void msvcrt_init_exception(void *base)
+{
+#ifdef __x86_64__
+ init_type_info_rtti(base);
+ init_exception_rtti(base);
+#if _MSVCR_VER >= 80
+ init_exception_old_rtti(base);
+ init_bad_alloc_rtti(base);
+#endif
+ init_bad_typeid_rtti(base);
+ init_bad_cast_rtti(base);
+ init___non_rtti_object_rtti(base);
+#if _MSVCR_VER >= 100
+ init_scheduler_resource_allocation_error_rtti(base);
+ init_improper_lock_rtti(base);
+ init_invalid_scheduler_policy_key_rtti(base);
+ init_invalid_scheduler_policy_value_rtti(base);
+ init_invalid_scheduler_policy_thread_specification_rtti(base);
+ init_improper_scheduler_attach_rtti(base);
+ init_improper_scheduler_detach_rtti(base);
+#endif
+
+ init_exception_cxx(base);
+ init_bad_typeid_cxx(base);
+ init_bad_cast_cxx(base);
+ init___non_rtti_object_cxx(base);
+#if _MSVCR_VER >= 80
+ init_bad_alloc_cxx(base);
+#endif
+#if _MSVCR_VER >= 100
+ init_scheduler_resource_allocation_error_cxx(base);
+ init_improper_lock_cxx(base);
+ init_invalid_scheduler_policy_key_cxx(base);
+ init_invalid_scheduler_policy_value_cxx(base);
+ init_invalid_scheduler_policy_thread_specification_cxx(base);
+ init_improper_scheduler_attach_cxx(base);
+ init_improper_scheduler_detach_cxx(base);
+#endif
+#endif
+}
+
+#if _MSVCR_VER >= 80
+void throw_exception(exception_type et, HRESULT hr, const char *str)
+{
+ switch(et) {
+ case EXCEPTION_BAD_ALLOC: {
+ bad_alloc e;
+ bad_alloc_ctor(&e, &str);
+ _CxxThrowException(&e, &bad_alloc_exception_type);
+ }
+#if _MSVCR_VER >= 100
+ case EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR: {
+ scheduler_resource_allocation_error e;
+ scheduler_resource_allocation_error_ctor_name(&e, str, hr);
+ _CxxThrowException(&e.e, &scheduler_resource_allocation_error_exception_type);
+ }
+ case EXCEPTION_IMPROPER_LOCK: {
+ improper_lock e;
+ improper_lock_ctor_str(&e, str);
+ _CxxThrowException(&e, &improper_lock_exception_type);
+ }
+ case EXCEPTION_INVALID_SCHEDULER_POLICY_KEY: {
+ invalid_scheduler_policy_key e;
+ invalid_scheduler_policy_key_ctor_str(&e, str);
+ _CxxThrowException(&e, &invalid_scheduler_policy_key_exception_type);
+ }
+ case EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE: {
+ invalid_scheduler_policy_value e;
+ invalid_scheduler_policy_value_ctor_str(&e, str);
+ _CxxThrowException(&e, &invalid_scheduler_policy_value_exception_type);
+ }
+ case EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION: {
+ invalid_scheduler_policy_thread_specification e;
+ invalid_scheduler_policy_thread_specification_ctor_str(&e, str);
+ _CxxThrowException(&e, &invalid_scheduler_policy_thread_specification_exception_type);
+ }
+ case EXCEPTION_IMPROPER_SCHEDULER_ATTACH: {
+ improper_scheduler_attach e;
+ improper_scheduler_attach_ctor_str(&e, str);
+ _CxxThrowException(&e, &improper_scheduler_attach_exception_type);
+ }
+ case EXCEPTION_IMPROPER_SCHEDULER_DETACH: {
+ improper_scheduler_detach e;
+ improper_scheduler_detach_ctor_str(&e, str);
+ _CxxThrowException(&e, &improper_scheduler_detach_exception_type);
+ }
+#endif
+ }
+}
+#endif
+
+/******************************************************************
+ * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
+ *
+ * Install a handler to be called when terminate() is called.
+ *
+ * PARAMS
+ * func [I] Handler function to install
+ *
+ * RETURNS
+ * The previously installed handler function, if any.
+ */
+MSVCRT_terminate_function CDECL MSVCRT_set_terminate(MSVCRT_terminate_function func)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ MSVCRT_terminate_function previous = data->terminate_handler;
+ TRACE("(%p) returning %p\n",func,previous);
+ data->terminate_handler = func;
+ return previous;
+}
+
+/******************************************************************
+ * _get_terminate (MSVCRT.@)
+ */
+MSVCRT_terminate_function CDECL MSVCRT__get_terminate(void)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ TRACE("returning %p\n", data->terminate_handler);
+ return data->terminate_handler;
+}
+
+/******************************************************************
+ * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
+ *
+ * Install a handler to be called when unexpected() is called.
+ *
+ * PARAMS
+ * func [I] Handler function to install
+ *
+ * RETURNS
+ * The previously installed handler function, if any.
+ */
+MSVCRT_unexpected_function CDECL MSVCRT_set_unexpected(MSVCRT_unexpected_function func)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ MSVCRT_unexpected_function previous = data->unexpected_handler;
+ TRACE("(%p) returning %p\n",func,previous);
+ data->unexpected_handler = func;
+ return previous;
+}
+
+/******************************************************************
+ * _get_unexpected (MSVCRT.@)
+ */
+MSVCRT_unexpected_function CDECL MSVCRT__get_unexpected(void)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ TRACE("returning %p\n", data->unexpected_handler);
+ return data->unexpected_handler;
+}
+
+/******************************************************************
+ * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@)
+ */
+MSVCRT__se_translator_function CDECL MSVCRT__set_se_translator(MSVCRT__se_translator_function func)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ MSVCRT__se_translator_function previous = data->se_translator;
+ TRACE("(%p) returning %p\n",func,previous);
+ data->se_translator = func;
+ return previous;
+}
+
+/******************************************************************
+ * ?terminate@@YAXXZ (MSVCRT.@)
+ *
+ * Default handler for an unhandled exception.
+ *
+ * PARAMS
+ * None.
+ *
+ * RETURNS
+ * This function does not return. Either control resumes from any
+ * handler installed by calling set_terminate(), or (by default) abort()
+ * is called.
+ */
+void CDECL MSVCRT_terminate(void)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ if (data->terminate_handler) data->terminate_handler();
+ MSVCRT_abort();
+}
+
+/******************************************************************
+ * ?unexpected@@YAXXZ (MSVCRT.@)
+ */
+void CDECL MSVCRT_unexpected(void)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ if (data->unexpected_handler) data->unexpected_handler();
+ MSVCRT_terminate();
+}
+
+
+/******************************************************************
+ * __RTtypeid (MSVCRT.@)
+ *
+ * Retrieve the Run Time Type Information (RTTI) for a C++ object.
+ *
+ * PARAMS
+ * cppobj [I] C++ object to get type information for.
+ *
+ * RETURNS
+ * Success: A type_info object describing cppobj.
+ * Failure: If the object to be cast has no RTTI, a __non_rtti_object
+ * exception is thrown. If cppobj is NULL, a bad_typeid exception
+ * is thrown. In either case, this function does not return.
+ *
+ * NOTES
+ * This function is usually called by compiler generated code as a result
+ * of using one of the C++ dynamic cast statements.
+ */
+#ifndef __x86_64__
+const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
+{
+ const type_info *ret;
+
+ if (!cppobj)
+ {
+ bad_typeid e;
+ MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
+ _CxxThrowException( &e, &bad_typeid_exception_type );
+ return NULL;
+ }
+
+ __TRY
+ {
+ const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
+ ret = obj_locator->type_descriptor;
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ __non_rtti_object e;
+ MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
+ _CxxThrowException( &e, &__non_rtti_object_exception_type );
+ return NULL;
+ }
+ __ENDTRY
+ return ret;
+}
+
+#else
+
+const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
+{
+ const type_info *ret;
+
+ if (!cppobj)
+ {
+ bad_typeid e;
+ MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" );
+ _CxxThrowException( &e, &bad_typeid_exception_type );
+ return NULL;
+ }
+
+ __TRY
+ {
+ const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
+ char *base;
+
+ if(obj_locator->signature == 0)
+ base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
+ else
+ base = (char*)obj_locator - obj_locator->object_locator;
+
+ ret = (type_info*)(base + obj_locator->type_descriptor);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ __non_rtti_object e;
+ MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" );
+ _CxxThrowException( &e, &__non_rtti_object_exception_type );
+ return NULL;
+ }
+ __ENDTRY
+ return ret;
+}
+#endif
+
+/******************************************************************
+ * __RTDynamicCast (MSVCRT.@)
+ *
+ * Dynamically cast a C++ object to one of its base classes.
+ *
+ * PARAMS
+ * cppobj [I] Any C++ object to cast
+ * unknown [I] Reserved, set to 0
+ * src [I] type_info object describing cppobj
+ * dst [I] type_info object describing the base class to cast to
+ * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
+ *
+ * RETURNS
+ * Success: The address of cppobj, cast to the object described by dst.
+ * Failure: NULL, If the object to be cast has no RTTI, or dst is not a
+ * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
+ * is thrown and this function does not return.
+ *
+ * NOTES
+ * This function is usually called by compiler generated code as a result
+ * of using one of the C++ dynamic cast statements.
+ */
+#ifndef __x86_64__
+void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
+ type_info *src, type_info *dst,
+ int do_throw)
+{
+ void *ret;
+
+ if (!cppobj) return NULL;
+
+ TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
+ cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
+
+ /* To cast an object at runtime:
+ * 1.Find out the true type of the object from the typeinfo at vtable[-1]
+ * 2.Search for the destination type in the class hierarchy
+ * 3.If destination type is found, return base object address + dest offset
+ * Otherwise, fail the cast
+ *
+ * FIXME: the unknown parameter doesn't seem to be used for anything
+ */
+ __TRY
+ {
+ int i;
+ const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
+ const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy;
+ const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases;
+
+ if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
+
+ ret = NULL;
+ for (i = 0; i < obj_bases->array_len; i++)
+ {
+ const type_info *typ = base_desc[i]->type_descriptor;
+
+ if (!strcmp(typ->mangled, dst->mangled))
+ {
+ /* compute the correct this pointer for that base class */
+ void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
+ ret = get_this_pointer( &base_desc[i]->offsets, this_ptr );
+ break;
+ }
+ }
+ /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
+ * to a reference, since references cannot be NULL.
+ */
+ if (!ret && do_throw)
+ {
+ const char *msg = "Bad dynamic_cast!";
+ bad_cast e;
+ MSVCRT_bad_cast_ctor( &e, &msg );
+ _CxxThrowException( &e, &bad_cast_exception_type );
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ __non_rtti_object e;
+ MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
+ _CxxThrowException( &e, &__non_rtti_object_exception_type );
+ return NULL;
+ }
+ __ENDTRY
+ return ret;
+}
+
+#else
+
+void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
+ type_info *src, type_info *dst,
+ int do_throw)
+{
+ void *ret;
+
+ if (!cppobj) return NULL;
+
+ TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n",
+ cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw);
+
+ __TRY
+ {
+ int i;
+ const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
+ const rtti_object_hierarchy *obj_bases;
+ const rtti_base_array *base_array;
+ char *base;
+
+ if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator);
+
+ if(obj_locator->signature == 0)
+ base = RtlPcToFileHeader((void*)obj_locator, (void**)&base);
+ else
+ base = (char*)obj_locator - obj_locator->object_locator;
+
+ obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy);
+ base_array = (const rtti_base_array*)(base + obj_bases->base_classes);
+
+ ret = NULL;
+ for (i = 0; i < obj_bases->array_len; i++)
+ {
+ const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]);
+ const type_info *typ = (const type_info*)(base + base_desc->type_descriptor);
+
+ if (!strcmp(typ->mangled, dst->mangled))
+ {
+ void *this_ptr = (char *)cppobj - obj_locator->base_class_offset;
+ ret = get_this_pointer( &base_desc->offsets, this_ptr );
+ break;
+ }
+ }
+ if (!ret && do_throw)
+ {
+ const char *msg = "Bad dynamic_cast!";
+ bad_cast e;
+ MSVCRT_bad_cast_ctor( &e, &msg );
+ _CxxThrowException( &e, &bad_cast_exception_type );
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ __non_rtti_object e;
+ MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
+ _CxxThrowException( &e, &__non_rtti_object_exception_type );
+ return NULL;
+ }
+ __ENDTRY
+ return ret;
+}
+#endif
+
+
+/******************************************************************
+ * __RTCastToVoid (MSVCRT.@)
+ *
+ * Dynamically cast a C++ object to a void*.
+ *
+ * PARAMS
+ * cppobj [I] The C++ object to cast
+ *
+ * RETURNS
+ * Success: The base address of the object as a void*.
+ * Failure: NULL, if cppobj is NULL or has no RTTI.
+ *
+ * NOTES
+ * This function is usually called by compiler generated code as a result
+ * of using one of the C++ dynamic cast statements.
+ */
+void* CDECL MSVCRT___RTCastToVoid(void *cppobj)
+{
+ void *ret;
+
+ if (!cppobj) return NULL;
+
+ __TRY
+ {
+ const rtti_object_locator *obj_locator = get_obj_locator( cppobj );
+ ret = (char *)cppobj - obj_locator->base_class_offset;
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ __non_rtti_object e;
+ MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" );
+ _CxxThrowException( &e, &__non_rtti_object_exception_type );
+ return NULL;
+ }
+ __ENDTRY
+ return ret;
+}
+
+
+/*********************************************************************
+ * _CxxThrowException (MSVCRT.@)
+ */
+#ifndef __x86_64__
+void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type )
+{
+ ULONG_PTR args[3];
+
+ args[0] = CXX_FRAME_MAGIC_VC6;
+ args[1] = (ULONG_PTR)object;
+ args[2] = (ULONG_PTR)type;
+ RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
+}
+#else
+void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type )
+{
+ ULONG_PTR args[4];
+
+ args[0] = CXX_FRAME_MAGIC_VC6;
+ args[1] = (ULONG_PTR)object;
+ args[2] = (ULONG_PTR)type;
+ RtlPcToFileHeader( (void*)type, (void**)&args[3]);
+ RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 4, args );
+}
+#endif
+
+#if _MSVCR_VER >= 80
+
+/*********************************************************************
+ * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z
+ * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z
+ */
+#ifndef __x86_64__
+int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep)
+{
+ int ret = -1;
+
+ TRACE("(%p %p)\n", ti, ep);
+
+ __TRY
+ {
+ EXCEPTION_RECORD *rec = ep->ExceptionRecord;
+
+ if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 &&
+ (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 ||
+ rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 ||
+ rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8))
+ {
+ const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table;
+ int i;
+
+ for (i=0; icount; i++) {
+ if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled))
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ if (i == tit->count)
+ ret = 0;
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ __ENDTRY
+
+ if(ret == -1)
+ MSVCRT_terminate();
+ return ret;
+}
+#else
+int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep)
+{
+ int ret = -1;
+
+ TRACE("(%p %p)\n", ti, ep);
+
+ __TRY
+ {
+ EXCEPTION_RECORD *rec = ep->ExceptionRecord;
+
+ if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 &&
+ (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 ||
+ rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 ||
+ rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8))
+ {
+ const cxx_exception_type *et = (cxx_exception_type*)rec->ExceptionInformation[2];
+ const cxx_type_info_table *tit = (const cxx_type_info_table*)(rec->ExceptionInformation[3]+et->type_info_table);
+ int i;
+
+ for (i=0; icount; i++) {
+ const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]);
+ const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info);
+ if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled))
+ {
+ ret = 1;
+ break;
+ }
+ }
+
+ if (i == tit->count)
+ ret = 0;
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ __ENDTRY
+
+ if(ret == -1)
+ MSVCRT_terminate();
+ return ret;
+}
+#endif
+
+/*********************************************************************
+ * __clean_type_info_names_internal (MSVCR80.@)
+ */
+void CDECL __clean_type_info_names_internal(void *p)
+{
+ FIXME("(%p) stub\n", p);
+}
+
+/*********************************************************************
+ * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@)
+ */
+DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8)
+const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node)
+{
+ static int once;
+ if (node && !once++) FIXME("type_info_node parameter ignored\n");
+
+ return MSVCRT_type_info_name(_this);
+}
+
+#endif /* _MSVCR_VER >= 80 */
+
+/* std::exception_ptr class helpers */
+typedef struct
+{
+ EXCEPTION_RECORD *rec;
+ int *ref; /* not binary compatible with native msvcr100 */
+} exception_ptr;
+
+#if _MSVCR_VER >= 100
+
+/*********************************************************************
+ * ?__ExceptionPtrCreate@@YAXPAX@Z
+ * ?__ExceptionPtrCreate@@YAXPEAX@Z
+ */
+void __cdecl __ExceptionPtrCreate(exception_ptr *ep)
+{
+ TRACE("(%p)\n", ep);
+
+ ep->rec = NULL;
+ ep->ref = NULL;
+}
+
+#if defined(__i386__) && !defined(__MINGW32__)
+extern void call_dtor(const cxx_exception_type *type, void *func, void *object);
+
+__ASM_GLOBAL_FUNC( call_dtor,
+ "movl 12(%esp),%ecx\n\t"
+ "call *8(%esp)\n\t"
+ "ret" );
+#elif __x86_64__
+static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object)
+{
+ char *base = RtlPcToFileHeader((void*)type, (void**)&base);
+ void (__cdecl *func)(void*) = (void*)(base + dtor);
+ func(object);
+}
+#else
+#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object)
+#endif
+
+/*********************************************************************
+ * ?__ExceptionPtrDestroy@@YAXPAX@Z
+ * ?__ExceptionPtrDestroy@@YAXPEAX@Z
+ */
+void __cdecl __ExceptionPtrDestroy(exception_ptr *ep)
+{
+ TRACE("(%p)\n", ep);
+
+ if (!ep->rec)
+ return;
+
+ if (!InterlockedDecrement(ep->ref))
+ {
+ if (ep->rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2];
+ void *obj = (void*)ep->rec->ExceptionInformation[1];
+
+ if (type && type->destructor) call_dtor(type, type->destructor, obj);
+ HeapFree(GetProcessHeap(), 0, obj);
+ }
+
+ HeapFree(GetProcessHeap(), 0, ep->rec);
+ HeapFree(GetProcessHeap(), 0, ep->ref);
+ }
+}
+
+/*********************************************************************
+ * ?__ExceptionPtrCopy@@YAXPAXPBX@Z
+ * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z
+ */
+void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy)
+{
+ TRACE("(%p %p)\n", ep, copy);
+
+ /* don't destroy object stored in ep */
+ *ep = *copy;
+ if (ep->ref)
+ InterlockedIncrement(copy->ref);
+}
+
+/*********************************************************************
+ * ?__ExceptionPtrAssign@@YAXPAXPBX@Z
+ * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z
+ */
+void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign)
+{
+ TRACE("(%p %p)\n", ep, assign);
+
+ /* don't destroy object stored in ep */
+ if (ep->ref)
+ InterlockedDecrement(ep->ref);
+
+ *ep = *assign;
+ if (ep->ref)
+ InterlockedIncrement(ep->ref);
+}
+
+#endif /* _MSVCR_VER >= 100 */
+
+/*********************************************************************
+ * ?__ExceptionPtrRethrow@@YAXPBX@Z
+ * ?__ExceptionPtrRethrow@@YAXPEBX@Z
+ */
+void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep)
+{
+ TRACE("(%p)\n", ep);
+
+ if (!ep->rec)
+ {
+ static const char *exception_msg = "bad exception";
+ exception e;
+
+ MSVCRT_exception_ctor(&e, &exception_msg);
+ _CxxThrowException(&e, &exception_exception_type);
+ return;
+ }
+
+ RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING),
+ ep->rec->NumberParameters, ep->rec->ExceptionInformation);
+}
+
+#if _MSVCR_VER >= 100
+
+#ifdef __i386__
+extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
+#else
+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)
+ ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1);
+ else
+ ((void (__cdecl*)(void*, void*))func)(this, src);
+}
+#endif
+
+/*********************************************************************
+ * ?__ExceptionPtrCurrentException@@YAXPAX@Z
+ * ?__ExceptionPtrCurrentException@@YAXPEAX@Z
+ */
+#ifndef __x86_64__
+void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
+{
+ EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
+
+ TRACE("(%p)\n", ep);
+
+ if (!rec)
+ {
+ ep->rec = NULL;
+ ep->ref = NULL;
+ return;
+ }
+
+ ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
+ ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
+
+ *ep->rec = *rec;
+ *ep->ref = 1;
+
+ if (ep->rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
+ const cxx_type_info *ti;
+ void **data, *obj;
+
+ ti = et->type_info_table->info[0];
+ data = HeapAlloc(GetProcessHeap(), 0, ti->size);
+
+ obj = (void*)ep->rec->ExceptionInformation[1];
+ if (ti->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memcpy(data, obj, ti->size);
+ if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
+ }
+ else if (ti->copy_ctor)
+ {
+ call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
+ ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
+ }
+ else
+ memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
+ ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
+ }
+ return;
+}
+#else
+void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep)
+{
+ EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record;
+
+ TRACE("(%p)\n", ep);
+
+ if (!rec)
+ {
+ ep->rec = NULL;
+ ep->ref = NULL;
+ return;
+ }
+
+ ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
+ ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
+
+ *ep->rec = *rec;
+ *ep->ref = 1;
+
+ if (ep->rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2];
+ const cxx_type_info *ti;
+ void **data, *obj;
+ char *base = RtlPcToFileHeader((void*)et, (void**)&base);
+
+ ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]);
+ data = HeapAlloc(GetProcessHeap(), 0, ti->size);
+
+ obj = (void*)ep->rec->ExceptionInformation[1];
+ if (ti->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memcpy(data, obj, ti->size);
+ if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
+ }
+ else if (ti->copy_ctor)
+ {
+ call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj),
+ ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
+ }
+ else
+ memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size);
+ ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
+ }
+ return;
+}
+#endif
+
+#endif /* _MSVCR_VER >= 100 */
+
+#if _MSVCR_VER >= 110
+/*********************************************************************
+ * ?__ExceptionPtrToBool@@YA_NPBX@Z
+ * ?__ExceptionPtrToBool@@YA_NPEBX@Z
+ */
+MSVCRT_bool __cdecl __ExceptionPtrToBool(exception_ptr *ep)
+{
+ return !!ep->rec;
+}
+#endif
+
+#if _MSVCR_VER >= 100
+
+/*********************************************************************
+ * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z
+ * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z
+ */
+#ifndef __x86_64__
+void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
+ exception *object, const cxx_exception_type *type)
+{
+ const cxx_type_info *ti;
+ void **data;
+
+ __ExceptionPtrDestroy(ep);
+
+ ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
+ ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
+ *ep->ref = 1;
+
+ memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
+ ep->rec->ExceptionCode = CXX_EXCEPTION;
+ ep->rec->ExceptionFlags = EH_NONCONTINUABLE;
+ ep->rec->NumberParameters = 3;
+ ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6;
+ ep->rec->ExceptionInformation[2] = (ULONG_PTR)type;
+
+ ti = type->type_info_table->info[0];
+ data = HeapAlloc(GetProcessHeap(), 0, ti->size);
+ if (ti->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memcpy(data, object, ti->size);
+ if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
+ }
+ else if (ti->copy_ctor)
+ {
+ call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
+ ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
+ }
+ else
+ memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
+ ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
+}
+#else
+void __cdecl __ExceptionPtrCopyException(exception_ptr *ep,
+ exception *object, const cxx_exception_type *type)
+{
+ const cxx_type_info *ti;
+ void **data;
+ char *base;
+
+ RtlPcToFileHeader((void*)type, (void**)&base);
+ __ExceptionPtrDestroy(ep);
+
+ ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD));
+ ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int));
+ *ep->ref = 1;
+
+ memset(ep->rec, 0, sizeof(EXCEPTION_RECORD));
+ ep->rec->ExceptionCode = CXX_EXCEPTION;
+ ep->rec->ExceptionFlags = EH_NONCONTINUABLE;
+ ep->rec->NumberParameters = 4;
+ ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6;
+ ep->rec->ExceptionInformation[2] = (ULONG_PTR)type;
+ ep->rec->ExceptionInformation[3] = (ULONG_PTR)base;
+
+ ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]);
+ data = HeapAlloc(GetProcessHeap(), 0, ti->size);
+ if (ti->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memcpy(data, object, ti->size);
+ if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data);
+ }
+ else if (ti->copy_ctor)
+ {
+ call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object),
+ ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS);
+ }
+ else
+ memcpy(data, get_this_pointer(&ti->offsets, object), ti->size);
+ ep->rec->ExceptionInformation[1] = (ULONG_PTR)data;
+}
+#endif
+
+MSVCRT_bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2)
+{
+ return ep1->rec == ep2->rec;
+}
+
+#endif /* _MSVCR_VER >= 100 */
+
+#if _MSVCR_VER >= 80
+void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off)
+{
+ return get_this_pointer(off, obj);
+}
+#endif
+
+#if _MSVCR_VER >= 140
+
+typedef struct
+{
+ char *name;
+ char mangled[1];
+} type_info140;
+
+typedef struct
+{
+ SLIST_ENTRY entry;
+ char name[1];
+} type_info_entry;
+
+static void* CDECL type_info_entry_malloc(MSVCRT_size_t size)
+{
+ type_info_entry *ret = MSVCRT_malloc(FIELD_OFFSET(type_info_entry, name) + size);
+ return ret->name;
+}
+
+static void CDECL type_info_entry_free(void *ptr)
+{
+ ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name);
+ MSVCRT_free(ptr);
+}
+
+/******************************************************************
+ * __std_type_info_compare (UCRTBASE.@)
+ */
+int CDECL MSVCRT_type_info_compare(const type_info140 *l, const type_info140 *r)
+{
+ int ret;
+
+ if (l == r) ret = 0;
+ else ret = MSVCRT_strcmp(l->mangled + 1, r->mangled + 1);
+ TRACE("(%p %p) returning %d\n", l, r, ret);
+ return ret;
+}
+
+/******************************************************************
+ * __std_type_info_name (UCRTBASE.@)
+ */
+const char* CDECL MSVCRT_type_info_name_list(type_info140 *ti, SLIST_HEADER *header)
+{
+ if (!ti->name)
+ {
+ char* name = __unDName(0, ti->mangled + 1, 0,
+ type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE);
+ if (name)
+ {
+ unsigned int len = strlen(name);
+
+ while (len && name[--len] == ' ')
+ name[len] = '\0';
+
+ if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL))
+ {
+ type_info_entry_free(name);
+ }
+ else
+ {
+ type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name));
+ InterlockedPushEntrySList(header, &entry->entry);
+ }
+ }
+ }
+ TRACE("(%p) returning %s\n", ti, ti->name);
+ return ti->name;
+}
+
+/******************************************************************
+ * __std_type_info_destroy_list (UCRTBASE.@)
+ */
+void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header)
+{
+ SLIST_ENTRY *cur, *next;
+
+ TRACE("(%p)\n", header);
+
+ for(cur = InterlockedFlushSList(header); cur; cur = next)
+ {
+ next = cur->Next;
+ MSVCRT_free(cur);
+ }
+}
+
+/******************************************************************
+ * __std_type_info_hash (UCRTBASE.@)
+ */
+MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti)
+{
+ MSVCRT_size_t hash, fnv_prime;
+ const char *p;
+
+#ifdef _WIN64
+ hash = 0xcbf29ce484222325;
+ fnv_prime = 0x100000001b3;
+#else
+ hash = 0x811c9dc5;
+ fnv_prime = 0x1000193;
+#endif
+
+ TRACE("(%p)->%s\n", ti, ti->mangled);
+
+ for(p = ti->mangled+1; *p; p++) {
+ hash ^= *p;
+ hash *= fnv_prime;
+ }
+
+#ifdef _WIN64
+ hash ^= hash >> 32;
+#endif
+
+ return hash;
+}
+
+#endif /* _MSVCR_VER >= 140 */
+
+#if _MSVCR_VER >= 100
+
+enum ConcRT_EventType
+{
+ CONCRT_EVENT_GENERIC,
+ CONCRT_EVENT_START,
+ CONCRT_EVENT_END,
+ CONCRT_EVENT_BLOCK,
+ CONCRT_EVENT_UNBLOCK,
+ CONCRT_EVENT_YIELD,
+ CONCRT_EVENT_ATTACH,
+ CONCRT_EVENT_DETACH
+};
+
+/* ?_Trace_ppl_function@Concurrency@@YAXABU_GUID@@EW4ConcRT_EventType@1@@Z */
+/* ?_Trace_ppl_function@Concurrency@@YAXAEBU_GUID@@EW4ConcRT_EventType@1@@Z */
+void __cdecl Concurrency__Trace_ppl_function(const GUID *guid, unsigned char level, enum ConcRT_EventType type)
+{
+ FIXME("(%s %u %i) stub\n", debugstr_guid(guid), level, type);
+}
+
+#endif /* _MSVCR_VER >= 100 */
diff --git a/sdk/lib/crt/except/cppexcept.h b/sdk/lib/crt/wine/cppexcept.h
similarity index 77%
rename from sdk/lib/crt/except/cppexcept.h
rename to sdk/lib/crt/wine/cppexcept.h
index 254d3ddd1be..69fb3c5eed9 100644
--- a/sdk/lib/crt/except/cppexcept.h
+++ b/sdk/lib/crt/wine/cppexcept.h
@@ -21,6 +21,8 @@
#ifndef __MSVCRT_CPPEXCEPT_H
#define __MSVCRT_CPPEXCEPT_H
+#include "wine/asm.h"
+
#define CXX_FRAME_MAGIC_VC6 0x19930520
#define CXX_FRAME_MAGIC_VC7 0x19930521
#define CXX_FRAME_MAGIC_VC8 0x19930522
@@ -33,17 +35,17 @@ typedef void (*vtable_ptr)(void);
/* type_info object, see cpp.c for implementation */
typedef struct __type_info
{
- const vtable_ptr* vtable;
- char* name; /* Unmangled name, allocated lazily */
- char mangled[64]; /* Variable length, but we declare it large enough for static RTTI */
+ const vtable_ptr *vtable;
+ char *name; /* Unmangled name, allocated lazily */
+ char mangled[64]; /* Variable length, but we declare it large enough for static RTTI */
} type_info;
/* exception object */
typedef struct __exception
{
- const vtable_ptr* vtable;
- char* name; /* Name of this exception, always a new copy for each object */
- BOOL do_free; /* Whether to free 'name' in our dtor */
+ const vtable_ptr *vtable;
+ char *name; /* Name of this exception, always a new copy for each object */
+ BOOL do_free; /* Whether to free 'name' in our dtor */
} exception;
typedef void (*cxx_copy_ctor)(void);
@@ -61,7 +63,7 @@ typedef struct
typedef struct __cxx_type_info
{
UINT flags; /* flags (see CLASS_* flags below) */
- const type_info* type_info; /* C++ type info */
+ const type_info *type_info; /* C++ type info */
this_ptr_offsets offsets; /* offsets for computing the this pointer */
unsigned int size; /* object size */
cxx_copy_ctor copy_ctor; /* copy constructor */
@@ -85,7 +87,7 @@ typedef struct __cxx_type_info
typedef struct __cxx_type_info_table
{
UINT count; /* number of types */
- const cxx_type_info* info[3]; /* variable length, we declare it large enough for static RTTI */
+ const cxx_type_info *info[3]; /* variable length, we declare it large enough for static RTTI */
} cxx_type_info_table;
#else
typedef struct __cxx_type_info_table
@@ -98,10 +100,10 @@ typedef struct __cxx_type_info_table
struct __cxx_exception_frame;
struct __cxx_function_descr;
-typedef DWORD(*cxx_exc_custom_handler)(PEXCEPTION_RECORD, struct __cxx_exception_frame*,
- PCONTEXT, EXCEPTION_REGISTRATION_RECORD**,
- const struct __cxx_function_descr*, int nested_trylevel,
- EXCEPTION_REGISTRATION_RECORD* nested_frame, DWORD unknown3);
+typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, struct __cxx_exception_frame*,
+ PCONTEXT, EXCEPTION_REGISTRATION_RECORD**,
+ const struct __cxx_function_descr*, int nested_trylevel,
+ EXCEPTION_REGISTRATION_RECORD *nested_frame, DWORD unknown3 );
/* type information for an exception object */
#ifndef __x86_64__
@@ -110,7 +112,7 @@ typedef struct __cxx_exception_type
UINT flags; /* TYPE_FLAG flags */
void (*destructor)(void);/* exception object destructor */
cxx_exc_custom_handler custom_handler; /* custom handler for this exception */
- const cxx_type_info_table* type_info_table; /* list of types for this exception object */
+ const cxx_type_info_table *type_info_table; /* list of types for this exception object */
} cxx_exception_type;
#else
typedef struct
@@ -122,33 +124,33 @@ typedef struct
} cxx_exception_type;
#endif
-void WINAPI _CxxThrowException(exception*, const cxx_exception_type*);
+void WINAPI _CxxThrowException(exception*,const cxx_exception_type*);
int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS);
-static inline const char* dbgstr_type_info(const type_info* info)
+static inline const char *dbgstr_type_info( const type_info *info )
{
if (!info) return "{}";
- return wine_dbg_sprintf("{vtable=%p name=%s (%s)}",
- info->vtable, info->mangled, info->name ? info->name : "");
+ return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}",
+ info->vtable, info->mangled, info->name ? info->name : "" );
}
/* compute the this pointer for a base class of a given type */
-static inline void* get_this_pointer(const this_ptr_offsets* off, void* object)
+static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
{
if (!object) return NULL;
if (off->vbase_descr >= 0)
{
- int* offset_ptr;
+ int *offset_ptr;
/* move this ptr to vbase descriptor */
- object = (char*)object + off->vbase_descr;
+ object = (char *)object + off->vbase_descr;
/* and fetch additional offset from vbase descriptor */
- offset_ptr = (int*)(*(char**)object + off->vbase_offset);
- object = (char*)object + *offset_ptr;
+ offset_ptr = (int *)(*(char **)object + off->vbase_offset);
+ object = (char *)object + *offset_ptr;
}
- object = (char*)object + off->this_offset;
+ object = (char *)object + off->this_offset;
return object;
}
diff --git a/sdk/lib/crt/wine/cxx.h b/sdk/lib/crt/wine/cxx.h
new file mode 100644
index 00000000000..b22ff22cc85
--- /dev/null
+++ b/sdk/lib/crt/wine/cxx.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2012 Piotr Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/asm.h"
+
+#ifdef _WIN64
+
+#define VTABLE_ADD_FUNC(name) "\t.quad " THISCALL_NAME(name) "\n"
+
+#define __ASM_VTABLE(name,funcs) \
+ __asm__(".data\n" \
+ "\t.balign 8\n" \
+ "\t.quad " __ASM_NAME(#name "_rtti") "\n" \
+ "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \
+ __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \
+ funcs "\n\t.text")
+
+#else
+
+#define VTABLE_ADD_FUNC(name) "\t.long " THISCALL_NAME(name) "\n"
+
+#define __ASM_VTABLE(name,funcs) \
+ __asm__(".data\n" \
+ "\t.balign 4\n" \
+ "\t.long " __ASM_NAME(#name "_rtti") "\n" \
+ "\t.globl " __ASM_NAME("MSVCRT_" #name "_vtable") "\n" \
+ __ASM_NAME("MSVCRT_" #name "_vtable") ":\n" \
+ funcs "\n\t.text")
+
+#endif /* _WIN64 */
+
+#ifndef __x86_64__
+
+#define DEFINE_RTTI_DATA(name, off, base_classes_no, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \
+ static type_info name ## _type_info = { \
+ &MSVCRT_type_info_vtable, \
+ NULL, \
+ mangled_name \
+ }; \
+\
+static const rtti_base_descriptor name ## _rtti_base_descriptor = { \
+ &name ##_type_info, \
+ base_classes_no, \
+ { 0, -1, 0}, \
+ 64 \
+}; \
+\
+static const rtti_base_array name ## _rtti_base_array = { \
+ { \
+ &name ## _rtti_base_descriptor, \
+ cl1, \
+ cl2, \
+ cl3, \
+ cl4, \
+ cl5, \
+ cl6, \
+ cl7, \
+ cl8, \
+ cl9, \
+ } \
+}; \
+\
+static const rtti_object_hierarchy name ## _hierarchy = { \
+ 0, \
+ 0, \
+ base_classes_no+1, \
+ &name ## _rtti_base_array \
+}; \
+\
+const rtti_object_locator name ## _rtti = { \
+ 0, \
+ off, \
+ 0, \
+ &name ## _type_info, \
+ &name ## _hierarchy \
+};
+
+#else
+
+#define DEFINE_RTTI_DATA(name, off, base_classes_no, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \
+ static type_info name ## _type_info = { \
+ &MSVCRT_type_info_vtable, \
+ NULL, \
+ mangled_name \
+ }; \
+\
+static rtti_base_descriptor name ## _rtti_base_descriptor = { \
+ 0xdeadbeef, \
+ base_classes_no, \
+ { 0, -1, 0}, \
+ 64 \
+}; \
+\
+static rtti_base_array name ## _rtti_base_array = { \
+ { \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ } \
+}; \
+\
+static rtti_object_hierarchy name ## _hierarchy = { \
+ 0, \
+ 0, \
+ base_classes_no+1, \
+ 0xdeadbeef \
+}; \
+\
+rtti_object_locator name ## _rtti = { \
+ 1, \
+ off, \
+ 0, \
+ 0xdeadbeef, \
+ 0xdeadbeef, \
+ 0xdeadbeef \
+};\
+\
+static void init_ ## name ## _rtti(char *base) \
+{ \
+ name ## _rtti_base_descriptor.type_descriptor = (char*)&name ## _type_info - base; \
+ name ## _rtti_base_array.bases[0] = (char*)&name ## _rtti_base_descriptor - base; \
+ name ## _rtti_base_array.bases[1] = (char*)cl1 - base; \
+ name ## _rtti_base_array.bases[2] = (char*)cl2 - base; \
+ name ## _rtti_base_array.bases[3] = (char*)cl3 - base; \
+ name ## _rtti_base_array.bases[4] = (char*)cl4 - base; \
+ name ## _rtti_base_array.bases[5] = (char*)cl5 - base; \
+ name ## _rtti_base_array.bases[6] = (char*)cl6 - base; \
+ name ## _rtti_base_array.bases[7] = (char*)cl7 - base; \
+ name ## _rtti_base_array.bases[8] = (char*)cl8 - base; \
+ name ## _rtti_base_array.bases[9] = (char*)cl9 - base; \
+ name ## _hierarchy.base_classes = (char*)&name ## _rtti_base_array - base; \
+ name ## _rtti.type_descriptor = (char*)&name ## _type_info - base; \
+ name ## _rtti.type_hierarchy = (char*)&name ## _hierarchy - base; \
+ name ## _rtti.object_locator = (char*)&name ## _rtti - base; \
+}
+
+#endif
+
+#define DEFINE_RTTI_DATA0(name, off, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
+#define DEFINE_RTTI_DATA1(name, off, cl1, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 1, cl1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
+#define DEFINE_RTTI_DATA2(name, off, cl1, cl2, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 2, cl1, cl2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
+#define DEFINE_RTTI_DATA3(name, off, cl1, cl2, cl3, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 3, cl1, cl2, cl3, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name)
+#define DEFINE_RTTI_DATA4(name, off, cl1, cl2, cl3, cl4, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 4, cl1, cl2, cl3, cl4, NULL, NULL, NULL, NULL, NULL, mangled_name)
+#define DEFINE_RTTI_DATA8(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 8, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, NULL, mangled_name)
+#define DEFINE_RTTI_DATA9(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \
+ DEFINE_RTTI_DATA(name, off, 9, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name)
+
+#ifndef __x86_64__
+
+typedef struct _rtti_base_descriptor
+{
+ const type_info *type_descriptor;
+ int num_base_classes;
+ this_ptr_offsets offsets; /* offsets for computing the this pointer */
+ unsigned int attributes;
+} rtti_base_descriptor;
+
+typedef struct _rtti_base_array
+{
+ const rtti_base_descriptor *bases[10]; /* First element is the class itself */
+} rtti_base_array;
+
+typedef struct _rtti_object_hierarchy
+{
+ unsigned int signature;
+ unsigned int attributes;
+ int array_len; /* Size of the array pointed to by 'base_classes' */
+ const rtti_base_array *base_classes;
+} rtti_object_hierarchy;
+
+typedef struct _rtti_object_locator
+{
+ unsigned int signature;
+ int base_class_offset;
+ unsigned int flags;
+ const type_info *type_descriptor;
+ const rtti_object_hierarchy *type_hierarchy;
+} rtti_object_locator;
+
+#else
+
+typedef struct
+{
+ unsigned int type_descriptor;
+ int num_base_classes;
+ this_ptr_offsets offsets; /* offsets for computing the this pointer */
+ unsigned int attributes;
+} rtti_base_descriptor;
+
+typedef struct
+{
+ unsigned int bases[10]; /* First element is the class itself */
+} rtti_base_array;
+
+typedef struct
+{
+ unsigned int signature;
+ unsigned int attributes;
+ int array_len; /* Size of the array pointed to by 'base_classes' */
+ unsigned int base_classes;
+} rtti_object_hierarchy;
+
+typedef struct
+{
+ unsigned int signature;
+ int base_class_offset;
+ unsigned int flags;
+ unsigned int type_descriptor;
+ unsigned int type_hierarchy;
+ unsigned int object_locator;
+} rtti_object_locator;
+
+#endif
+
+#if defined(__i386__) && !defined(__MINGW32__)
+
+#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args
+
+extern void *vtbl_wrapper_0;
+extern void *vtbl_wrapper_4;
+extern void *vtbl_wrapper_8;
+extern void *vtbl_wrapper_12;
+extern void *vtbl_wrapper_16;
+extern void *vtbl_wrapper_20;
+extern void *vtbl_wrapper_24;
+extern void *vtbl_wrapper_28;
+extern void *vtbl_wrapper_32;
+extern void *vtbl_wrapper_36;
+extern void *vtbl_wrapper_40;
+extern void *vtbl_wrapper_44;
+extern void *vtbl_wrapper_48;
+
+#else
+
+#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__thiscall***)type)this)[0][off/4]args
+
+#endif
+
+//exception* __thiscall MSVCRT_exception_ctor(exception*, const char**);
diff --git a/sdk/lib/crt/wine/except.c b/sdk/lib/crt/wine/except.c
new file mode 100644
index 00000000000..147ed5e9ef0
--- /dev/null
+++ b/sdk/lib/crt/wine/except.c
@@ -0,0 +1,545 @@
+/*
+ * msvcrt.dll exception handling
+ *
+ * Copyright 2000 Jon Griffiths
+ * Copyright 2005 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * FIXME: Incomplete support for nested exceptions/try block cleanup.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "wine/exception.h"
+#include "msvcrt.h"
+#include "excpt.h"
+#include "wincon.h"
+#include "wine/debug.h"
+
+#include "cppexcept.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
+
+#if _MSVCR_VER>=70 && _MSVCR_VER<=71
+static MSVCRT_security_error_handler security_error_handler;
+#endif
+
+static MSVCRT___sighandler_t sighandlers[MSVCRT_NSIG] = { MSVCRT_SIG_DFL };
+
+static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType)
+{
+ BOOL ret = FALSE;
+
+ switch (ctrlType)
+ {
+ case CTRL_C_EVENT:
+ if (sighandlers[MSVCRT_SIGINT])
+ {
+ if (sighandlers[MSVCRT_SIGINT] != MSVCRT_SIG_IGN)
+ sighandlers[MSVCRT_SIGINT](MSVCRT_SIGINT);
+ ret = TRUE;
+ }
+ break;
+ }
+ return ret;
+}
+
+/*********************************************************************
+ * __pxcptinfoptrs (MSVCRT.@)
+ */
+void** CDECL MSVCRT___pxcptinfoptrs(void)
+{
+ return (void**)&msvcrt_get_thread_data()->xcptinfo;
+}
+
+typedef void (CDECL *float_handler)(int, int);
+
+/* The exception codes are actually NTSTATUS values */
+static const struct
+{
+ NTSTATUS status;
+ int signal;
+} float_exception_map[] = {
+ { EXCEPTION_FLT_DENORMAL_OPERAND, MSVCRT__FPE_DENORMAL },
+ { EXCEPTION_FLT_DIVIDE_BY_ZERO, MSVCRT__FPE_ZERODIVIDE },
+ { EXCEPTION_FLT_INEXACT_RESULT, MSVCRT__FPE_INEXACT },
+ { EXCEPTION_FLT_INVALID_OPERATION, MSVCRT__FPE_INVALID },
+ { EXCEPTION_FLT_OVERFLOW, MSVCRT__FPE_OVERFLOW },
+ { EXCEPTION_FLT_STACK_CHECK, MSVCRT__FPE_STACKOVERFLOW },
+ { EXCEPTION_FLT_UNDERFLOW, MSVCRT__FPE_UNDERFLOW },
+};
+
+static LONG msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except)
+{
+ LONG ret = EXCEPTION_CONTINUE_SEARCH;
+ MSVCRT___sighandler_t handler;
+
+ if (!except || !except->ExceptionRecord)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ switch (except->ExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ if ((handler = sighandlers[MSVCRT_SIGSEGV]) != MSVCRT_SIG_DFL)
+ {
+ if (handler != MSVCRT_SIG_IGN)
+ {
+ EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep;
+
+ old_ep = *ep;
+ *ep = except;
+ sighandlers[MSVCRT_SIGSEGV] = MSVCRT_SIG_DFL;
+ handler(MSVCRT_SIGSEGV);
+ *ep = old_ep;
+ }
+ ret = EXCEPTION_CONTINUE_EXECUTION;
+ }
+ break;
+ /* According to msdn,
+ * the FPE signal handler takes as a second argument the type of
+ * floating point exception.
+ */
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ case EXCEPTION_FLT_OVERFLOW:
+ case EXCEPTION_FLT_STACK_CHECK:
+ case EXCEPTION_FLT_UNDERFLOW:
+ if ((handler = sighandlers[MSVCRT_SIGFPE]) != MSVCRT_SIG_DFL)
+ {
+ if (handler != MSVCRT_SIG_IGN)
+ {
+ EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep;
+ unsigned int i;
+ int float_signal = MSVCRT__FPE_INVALID;
+
+ sighandlers[MSVCRT_SIGFPE] = MSVCRT_SIG_DFL;
+ for (i = 0; i < ARRAY_SIZE(float_exception_map); i++)
+ {
+ if (float_exception_map[i].status ==
+ except->ExceptionRecord->ExceptionCode)
+ {
+ float_signal = float_exception_map[i].signal;
+ break;
+ }
+ }
+
+ old_ep = *ep;
+ *ep = except;
+ ((float_handler)handler)(MSVCRT_SIGFPE, float_signal);
+ *ep = old_ep;
+ }
+ ret = EXCEPTION_CONTINUE_EXECUTION;
+ }
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ case EXCEPTION_PRIV_INSTRUCTION:
+ if ((handler = sighandlers[MSVCRT_SIGILL]) != MSVCRT_SIG_DFL)
+ {
+ if (handler != MSVCRT_SIG_IGN)
+ {
+ EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep;
+
+ old_ep = *ep;
+ *ep = except;
+ sighandlers[MSVCRT_SIGILL] = MSVCRT_SIG_DFL;
+ handler(MSVCRT_SIGILL);
+ *ep = old_ep;
+ }
+ ret = EXCEPTION_CONTINUE_EXECUTION;
+ }
+ break;
+ }
+ return ret;
+}
+
+void msvcrt_init_signals(void)
+{
+ SetConsoleCtrlHandler(msvcrt_console_handler, TRUE);
+}
+
+void msvcrt_free_signals(void)
+{
+ SetConsoleCtrlHandler(msvcrt_console_handler, FALSE);
+}
+
+/*********************************************************************
+ * signal (MSVCRT.@)
+ * Some signals may never be generated except through an explicit call to
+ * raise.
+ */
+MSVCRT___sighandler_t CDECL MSVCRT_signal(int sig, MSVCRT___sighandler_t func)
+{
+ MSVCRT___sighandler_t ret = MSVCRT_SIG_ERR;
+
+ TRACE("(%d, %p)\n", sig, func);
+
+ if (func == MSVCRT_SIG_ERR) return MSVCRT_SIG_ERR;
+
+ switch (sig)
+ {
+ /* Cases handled internally. Note SIGTERM is never generated by Windows,
+ * so we effectively mask it.
+ */
+ case MSVCRT_SIGABRT:
+ case MSVCRT_SIGFPE:
+ case MSVCRT_SIGILL:
+ case MSVCRT_SIGSEGV:
+ case MSVCRT_SIGINT:
+ case MSVCRT_SIGTERM:
+ case MSVCRT_SIGBREAK:
+ ret = sighandlers[sig];
+ sighandlers[sig] = func;
+ break;
+ default:
+ ret = MSVCRT_SIG_ERR;
+ }
+ return ret;
+}
+
+/*********************************************************************
+ * raise (MSVCRT.@)
+ */
+int CDECL MSVCRT_raise(int sig)
+{
+ MSVCRT___sighandler_t handler;
+
+ TRACE("(%d)\n", sig);
+
+ switch (sig)
+ {
+ case MSVCRT_SIGFPE:
+ case MSVCRT_SIGILL:
+ case MSVCRT_SIGSEGV:
+ handler = sighandlers[sig];
+ if (handler == MSVCRT_SIG_DFL) MSVCRT__exit(3);
+ if (handler != MSVCRT_SIG_IGN)
+ {
+ EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep;
+
+ sighandlers[sig] = MSVCRT_SIG_DFL;
+
+ old_ep = *ep;
+ *ep = NULL;
+ if (sig == MSVCRT_SIGFPE)
+ ((float_handler)handler)(sig, MSVCRT__FPE_EXPLICITGEN);
+ else
+ handler(sig);
+ *ep = old_ep;
+ }
+ break;
+ case MSVCRT_SIGABRT:
+ case MSVCRT_SIGINT:
+ case MSVCRT_SIGTERM:
+ case MSVCRT_SIGBREAK:
+ handler = sighandlers[sig];
+ if (handler == MSVCRT_SIG_DFL) MSVCRT__exit(3);
+ if (handler != MSVCRT_SIG_IGN)
+ {
+ sighandlers[sig] = MSVCRT_SIG_DFL;
+ handler(sig);
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/*********************************************************************
+ * _XcptFilter (MSVCRT.@)
+ */
+int CDECL _XcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
+{
+ TRACE("(%08x,%p)\n", ex, ptr);
+ /* I assume ptr->ExceptionRecord->ExceptionCode is the same as ex */
+ return msvcrt_exception_filter(ptr);
+}
+
+#ifndef __REACTOS__
+/*********************************************************************
+ * _abnormal_termination (MSVCRT.@)
+ */
+int CDECL _abnormal_termination(void)
+{
+ FIXME("(void)stub\n");
+ return 0;
+}
+#endif /* __REACTOS__ */
+
+/******************************************************************
+ * __uncaught_exception (MSVCRT.@)
+ */
+BOOL CDECL MSVCRT___uncaught_exception(void)
+{
+ return msvcrt_get_thread_data()->processing_throw != 0;
+}
+
+#if _MSVCR_VER>=70 && _MSVCR_VER<=71
+
+/*********************************************************************
+ * _set_security_error_handler (MSVCR70.@)
+ */
+MSVCRT_security_error_handler CDECL _set_security_error_handler(
+ MSVCRT_security_error_handler handler )
+{
+ MSVCRT_security_error_handler old = security_error_handler;
+
+ TRACE("(%p)\n", handler);
+
+ security_error_handler = handler;
+ return old;
+}
+
+/*********************************************************************
+ * __security_error_handler (MSVCR70.@)
+ */
+void CDECL __security_error_handler(int code, void *data)
+{
+ if(security_error_handler)
+ security_error_handler(code, data);
+ else
+ FIXME("(%d, %p) stub\n", code, data);
+
+ MSVCRT__exit(3);
+}
+
+#endif /* _MSVCR_VER>=70 && _MSVCR_VER<=71 */
+
+#if _MSVCR_VER>=110
+/*********************************************************************
+ * __crtSetUnhandledExceptionFilter (MSVCR110.@)
+ */
+LPTOP_LEVEL_EXCEPTION_FILTER CDECL MSVCR110__crtSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER filter)
+{
+ return SetUnhandledExceptionFilter(filter);
+}
+#endif
+
+/*********************************************************************
+ * _CreateFrameInfo (MSVCR80.@)
+ */
+frame_info* CDECL _CreateFrameInfo(frame_info *fi, void *obj)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ TRACE("(%p, %p)\n", fi, obj);
+
+ fi->next = data->frame_info_head;
+ data->frame_info_head = fi;
+ fi->object = obj;
+ return fi;
+}
+
+/*********************************************************************
+ * _FindAndUnlinkFrame (MSVCR80.@)
+ */
+void CDECL _FindAndUnlinkFrame(frame_info *fi)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+ frame_info *cur = data->frame_info_head;
+
+ TRACE("(%p)\n", fi);
+
+ if (cur == fi)
+ {
+ data->frame_info_head = cur->next;
+ return;
+ }
+
+ for (; cur->next; cur = cur->next)
+ {
+ if (cur->next == fi)
+ {
+ cur->next = fi->next;
+ return;
+ }
+ }
+
+ ERR("frame not found, native crashes in this case\n");
+}
+
+/*********************************************************************
+ * _IsExceptionObjectToBeDestroyed (MSVCR80.@)
+ */
+BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
+{
+ frame_info *cur;
+
+ TRACE( "%p\n", obj );
+
+ for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next)
+ {
+ if (cur->object == obj)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*********************************************************************
+ * __DestructExceptionObject (MSVCRT.@)
+ */
+void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
+{
+ cxx_exception_type *info = (cxx_exception_type*) rec->ExceptionInformation[2];
+ void *object = (void*)rec->ExceptionInformation[1];
+
+ TRACE("(%p)\n", rec);
+
+ if (rec->ExceptionCode != CXX_EXCEPTION) return;
+#ifndef __x86_64__
+ if (rec->NumberParameters != 3) return;
+#else
+ if (rec->NumberParameters != 4) return;
+#endif
+ if (rec->ExceptionInformation[0] < CXX_FRAME_MAGIC_VC6 ||
+ rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8) return;
+
+ if (!info || !info->destructor)
+ return;
+
+#if defined(__i386__)
+#ifdef _MSC_VER
+ ((void(__fastcall*)(void*))info->destructor)(object);
+#else
+ __asm__ __volatile__("call *%0" : : "r" (info->destructor), "c" (object) : "eax", "edx", "memory");
+#endif
+#elif defined(__x86_64__)
+ ((void (__cdecl*)(void*))(info->destructor+rec->ExceptionInformation[3]))(object);
+#else
+ ((void (__cdecl*)(void*))info->destructor)(object);
+#endif
+}
+
+/*********************************************************************
+ * __CxxRegisterExceptionObject (MSVCRT.@)
+ */
+BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ TRACE("(%p, %p)\n", ep, frame_info);
+
+ if (!ep || !ep->ExceptionRecord)
+ {
+ frame_info->rec = (void*)-1;
+ frame_info->context = (void*)-1;
+ return TRUE;
+ }
+
+ frame_info->rec = data->exc_record;
+ frame_info->context = data->ctx_record;
+ data->exc_record = ep->ExceptionRecord;
+ data->ctx_record = ep->ContextRecord;
+ _CreateFrameInfo(&frame_info->frame_info, (void*)ep->ExceptionRecord->ExceptionInformation[1]);
+ return TRUE;
+}
+
+/*********************************************************************
+ * __CxxUnregisterExceptionObject (MSVCRT.@)
+ */
+void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
+{
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ TRACE("(%p)\n", frame_info);
+
+ if(frame_info->rec == (void*)-1)
+ return;
+
+ _FindAndUnlinkFrame(&frame_info->frame_info);
+ if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use
+ && _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1]))
+ __DestructExceptionObject(data->exc_record);
+ data->exc_record = frame_info->rec;
+ data->ctx_record = frame_info->context;
+}
+
+struct __std_exception_data {
+ char *what;
+ MSVCRT_bool dofree;
+};
+
+#if _MSVCR_VER>=140
+
+/*********************************************************************
+ * __std_exception_copy (UCRTBASE.@)
+ */
+void CDECL MSVCRT___std_exception_copy(const struct __std_exception_data *src,
+ struct __std_exception_data *dst)
+{
+ TRACE("(%p %p)\n", src, dst);
+
+ if(src->dofree && src->what) {
+ dst->what = MSVCRT__strdup(src->what);
+ dst->dofree = 1;
+ } else {
+ dst->what = src->what;
+ dst->dofree = 0;
+ }
+}
+
+/*********************************************************************
+ * __std_exception_destroy (UCRTBASE.@)
+ */
+void CDECL MSVCRT___std_exception_destroy(struct __std_exception_data *data)
+{
+ TRACE("(%p)\n", data);
+
+ if(data->dofree)
+ MSVCRT_free(data->what);
+ data->what = NULL;
+ data->dofree = 0;
+}
+
+/*********************************************************************
+ * __current_exception (UCRTBASE.@)
+ */
+void** CDECL __current_exception(void)
+{
+ TRACE("()\n");
+ return (void**)&msvcrt_get_thread_data()->exc_record;
+}
+
+/*********************************************************************
+ * __current_exception_context (UCRTBASE.@)
+ */
+void** CDECL __current_exception_context(void)
+{
+ TRACE("()\n");
+ return (void**)&msvcrt_get_thread_data()->ctx_record;
+}
+
+/*********************************************************************
+ * __processing_throw (UCRTBASE.@)
+ */
+int* CDECL __processing_throw(void)
+{
+ TRACE("()\n");
+ return &msvcrt_get_thread_data()->processing_throw;
+}
+
+#endif /* _MSVCR_VER>=140 */
diff --git a/sdk/lib/crt/wine/except_arm.c b/sdk/lib/crt/wine/except_arm.c
new file mode 100644
index 00000000000..41b0c1c7d3e
--- /dev/null
+++ b/sdk/lib/crt/wine/except_arm.c
@@ -0,0 +1,147 @@
+/*
+ * msvcrt C++ exception handling
+ *
+ * Copyright 2011 Alexandre Julliard
+ * Copyright 2013 André Hentschel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef __arm__
+
+#include
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "msvcrt.h"
+#include "wine/exception.h"
+#include "excpt.h"
+#include "wine/debug.h"
+
+#include "cppexcept.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
+
+
+/*********************************************************************
+ * __CxxExceptionFilter (MSVCRT.@)
+ */
+int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
+ const type_info *ti, int flags, void **copy )
+{
+ FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy );
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*********************************************************************
+ * __CxxFrameHandler (MSVCRT.@)
+ */
+EXCEPTION_DISPOSITION CDECL __CxxFrameHandler(EXCEPTION_RECORD *rec, DWORD frame, CONTEXT *context,
+ DISPATCHER_CONTEXT *dispatch)
+{
+ FIXME("%p %x %p %p: not implemented\n", rec, frame, context, dispatch);
+ return ExceptionContinueSearch;
+}
+
+
+/*********************************************************************
+ * __CppXcptFilter (MSVCRT.@)
+ */
+int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
+{
+ /* only filter c++ exceptions */
+ if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
+ return _XcptFilter(ex, ptr);
+}
+
+
+/*********************************************************************
+ * __CxxDetectRethrow (MSVCRT.@)
+ */
+BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
+{
+ PEXCEPTION_RECORD rec;
+
+ if (!ptrs)
+ return FALSE;
+
+ rec = ptrs->ExceptionRecord;
+
+ if (rec->ExceptionCode == CXX_EXCEPTION &&
+ rec->NumberParameters == 3 &&
+ rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
+ rec->ExceptionInformation[2])
+ {
+ ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
+ return TRUE;
+ }
+ return (msvcrt_get_thread_data()->exc_record == rec);
+}
+
+
+/*********************************************************************
+ * __CxxQueryExceptionSize (MSVCRT.@)
+ */
+unsigned int CDECL __CxxQueryExceptionSize(void)
+{
+ return sizeof(cxx_exception_type);
+}
+
+
+/*******************************************************************
+ * _setjmp (MSVCRT.@)
+ */
+__ASM_GLOBAL_FUNC(MSVCRT__setjmp,
+ "mov r1, #0\n\t" /* frame */
+ "b " __ASM_NAME("__wine_setjmpex"));
+
+/*******************************************************************
+ * longjmp (MSVCRT.@)
+ */
+void __cdecl MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval)
+{
+ EXCEPTION_RECORD rec;
+
+ if (!retval) retval = 1;
+ if (jmp->Frame)
+ {
+ rec.ExceptionCode = STATUS_LONGJUMP;
+ rec.ExceptionFlags = 0;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = NULL;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = (DWORD_PTR)jmp;
+ RtlUnwind((void *)jmp->Frame, (void *)jmp->Pc, &rec, IntToPtr(retval));
+ }
+ __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
+}
+
+/*********************************************************************
+ * _fpieee_flt (MSVCRT.@)
+ */
+int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
+ int (__cdecl *handler)(_FPIEEE_RECORD*))
+{
+ FIXME("(%x %p %p)\n", exception_code, ep, handler);
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#endif /* __arm__ */
diff --git a/sdk/lib/crt/wine/except_arm64.c b/sdk/lib/crt/wine/except_arm64.c
new file mode 100644
index 00000000000..97059d13972
--- /dev/null
+++ b/sdk/lib/crt/wine/except_arm64.c
@@ -0,0 +1,148 @@
+/*
+ * msvcrt C++ exception handling
+ *
+ * Copyright 2011 Alexandre Julliard
+ * Copyright 2013 André Hentschel
+ * Copyright 2017 Martin Storsjo
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef __aarch64__
+
+#include
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "msvcrt.h"
+#include "wine/exception.h"
+#include "excpt.h"
+#include "wine/debug.h"
+
+#include "cppexcept.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
+
+
+/*********************************************************************
+ * __CxxExceptionFilter (MSVCRT.@)
+ */
+int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
+ const type_info *ti, int flags, void **copy )
+{
+ FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy );
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*********************************************************************
+ * __CxxFrameHandler (MSVCRT.@)
+ */
+EXCEPTION_DISPOSITION CDECL __CxxFrameHandler(EXCEPTION_RECORD *rec, DWORD frame, CONTEXT *context,
+ DISPATCHER_CONTEXT *dispatch)
+{
+ FIXME("%p %x %p %p: not implemented\n", rec, frame, context, dispatch);
+ return ExceptionContinueSearch;
+}
+
+
+/*********************************************************************
+ * __CppXcptFilter (MSVCRT.@)
+ */
+int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
+{
+ /* only filter c++ exceptions */
+ if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
+ return _XcptFilter(ex, ptr);
+}
+
+
+/*********************************************************************
+ * __CxxDetectRethrow (MSVCRT.@)
+ */
+BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
+{
+ PEXCEPTION_RECORD rec;
+
+ if (!ptrs)
+ return FALSE;
+
+ rec = ptrs->ExceptionRecord;
+
+ if (rec->ExceptionCode == CXX_EXCEPTION &&
+ rec->NumberParameters == 3 &&
+ rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
+ rec->ExceptionInformation[2])
+ {
+ ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
+ return TRUE;
+ }
+ return (msvcrt_get_thread_data()->exc_record == rec);
+}
+
+
+/*********************************************************************
+ * __CxxQueryExceptionSize (MSVCRT.@)
+ */
+unsigned int CDECL __CxxQueryExceptionSize(void)
+{
+ return sizeof(cxx_exception_type);
+}
+
+
+/*******************************************************************
+ * _setjmp (MSVCRT.@)
+ */
+__ASM_GLOBAL_FUNC(MSVCRT__setjmp,
+ "mov x1, #0\n\t" /* frame */
+ "b " __ASM_NAME("__wine_setjmpex"));
+
+/*******************************************************************
+ * longjmp (MSVCRT.@)
+ */
+void __cdecl MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval)
+{
+ EXCEPTION_RECORD rec;
+
+ if (!retval) retval = 1;
+ if (jmp->Frame)
+ {
+ rec.ExceptionCode = STATUS_LONGJUMP;
+ rec.ExceptionFlags = 0;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = NULL;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = (DWORD_PTR)jmp;
+ RtlUnwind((void *)jmp->Frame, (void *)jmp->Lr, &rec, IntToPtr(retval));
+ }
+ __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
+}
+
+/*********************************************************************
+ * _fpieee_flt (MSVCRT.@)
+ */
+int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
+ int (__cdecl *handler)(_FPIEEE_RECORD*))
+{
+ FIXME("(%x %p %p)\n", exception_code, ep, handler);
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#endif /* __aarch64__ */
diff --git a/sdk/lib/crt/wine/except_i386.c b/sdk/lib/crt/wine/except_i386.c
new file mode 100644
index 00000000000..acb8223075c
--- /dev/null
+++ b/sdk/lib/crt/wine/except_i386.c
@@ -0,0 +1,1235 @@
+/*
+ * msvcrt C++ exception handling
+ *
+ * Copyright 2000 Jon Griffiths
+ * Copyright 2002 Alexandre Julliard
+ * Copyright 2005 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * NOTES
+ * A good reference is the article "How a C++ compiler implements
+ * exception handling" by Vishal Kochhar, available on
+ * www.thecodeproject.com.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef __i386__
+
+#include
+
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "msvcrt.h"
+#include "wine/exception.h"
+#include "excpt.h"
+#include "wine/debug.h"
+
+#include "cppexcept.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
+
+
+/* the exception frame used by CxxFrameHandler */
+typedef struct __cxx_exception_frame
+{
+ EXCEPTION_REGISTRATION_RECORD frame; /* the standard exception frame */
+ int trylevel;
+ DWORD ebp;
+} cxx_exception_frame;
+
+/* info about a single catch {} block */
+typedef struct __catchblock_info
+{
+ UINT flags; /* flags (see below) */
+ const type_info *type_info; /* C++ type caught by this block */
+ int offset; /* stack offset to copy exception object to */
+ void * (*handler)(void);/* catch block handler code */
+} catchblock_info;
+#define TYPE_FLAG_CONST 1
+#define TYPE_FLAG_VOLATILE 2
+#define TYPE_FLAG_REFERENCE 8
+
+/* info about a single try {} block */
+typedef struct __tryblock_info
+{
+ int start_level; /* start trylevel of that block */
+ int end_level; /* end trylevel of that block */
+ int catch_level; /* initial trylevel of the catch block */
+ int catchblock_count; /* count of catch blocks in array */
+ const catchblock_info *catchblock; /* array of catch blocks */
+} tryblock_info;
+
+/* info about the unwind handler for a given trylevel */
+typedef struct __unwind_info
+{
+ int prev; /* prev trylevel unwind handler, to run after this one */
+ void * (*handler)(void);/* unwind handler */
+} unwind_info;
+
+/* descriptor of all try blocks of a given function */
+typedef struct __cxx_function_descr
+{
+ UINT magic; /* must be CXX_FRAME_MAGIC */
+ UINT unwind_count; /* number of unwind handlers */
+ const unwind_info *unwind_table; /* array of unwind handlers */
+ UINT tryblock_count; /* number of try blocks */
+ const tryblock_info *tryblock; /* array of try blocks */
+ UINT ipmap_count;
+ const void *ipmap;
+ const void *expect_list; /* expected exceptions list when magic >= VC7 */
+ UINT flags; /* flags when magic >= VC8 */
+} cxx_function_descr;
+
+typedef struct
+{
+ cxx_exception_frame *frame;
+ const cxx_function_descr *descr;
+ EXCEPTION_REGISTRATION_RECORD *nested_frame;
+} se_translator_ctx;
+
+typedef struct _SCOPETABLE
+{
+ int previousTryLevel;
+ int (*lpfnFilter)(PEXCEPTION_POINTERS);
+ void * (*lpfnHandler)(void);
+} SCOPETABLE, *PSCOPETABLE;
+
+typedef struct _MSVCRT_EXCEPTION_FRAME
+{
+ EXCEPTION_REGISTRATION_RECORD *prev;
+ void (*handler)(PEXCEPTION_RECORD, EXCEPTION_REGISTRATION_RECORD*,
+ PCONTEXT, PEXCEPTION_RECORD);
+ PSCOPETABLE scopetable;
+ int trylevel;
+ int _ebp;
+ PEXCEPTION_POINTERS xpointers;
+} MSVCRT_EXCEPTION_FRAME;
+
+typedef struct
+{
+ int gs_cookie_offset;
+ ULONG gs_cookie_xor;
+ int eh_cookie_offset;
+ ULONG eh_cookie_xor;
+ SCOPETABLE entries[1];
+} SCOPETABLE_V4;
+
+#define TRYLEVEL_END (-1) /* End of trylevel list */
+
+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 ) DECLSPEC_HIDDEN;
+
+/* call a copy constructor */
+extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase );
+
+__ASM_GLOBAL_FUNC( call_copy_ctor,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp, %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "pushl $1\n\t"
+ "movl 12(%ebp), %ecx\n\t"
+ "pushl 16(%ebp)\n\t"
+ "call *8(%ebp)\n\t"
+ "leave\n"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret" );
+
+/* continue execution to the specified address after exception is caught */
+extern void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr );
+
+__ASM_GLOBAL_FUNC( continue_after_catch,
+ "movl 4(%esp), %edx\n\t"
+ "movl 8(%esp), %eax\n\t"
+ "movl -4(%edx), %esp\n\t"
+ "leal 12(%edx), %ebp\n\t"
+ "jmp *%eax" );
+
+extern void DECLSPEC_NORETURN call_finally_block( void *code_block, void *base_ptr );
+
+__ASM_GLOBAL_FUNC( call_finally_block,
+ "movl 8(%esp), %ebp\n\t"
+ "jmp *4(%esp)" );
+
+extern int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp );
+
+__ASM_GLOBAL_FUNC( call_filter,
+ "pushl %ebp\n\t"
+ "pushl 12(%esp)\n\t"
+ "movl 20(%esp), %ebp\n\t"
+ "call *12(%esp)\n\t"
+ "popl %ebp\n\t"
+ "popl %ebp\n\t"
+ "ret" );
+
+extern void *call_handler( void * (*func)(void), void *ebp );
+
+__ASM_GLOBAL_FUNC( call_handler,
+ "pushl %ebp\n\t"
+ "pushl %ebx\n\t"
+ "pushl %esi\n\t"
+ "pushl %edi\n\t"
+ "movl 24(%esp), %ebp\n\t"
+ "call *20(%esp)\n\t"
+ "popl %edi\n\t"
+ "popl %esi\n\t"
+ "popl %ebx\n\t"
+ "popl %ebp\n\t"
+ "ret" );
+
+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),
+ type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
+ type->size, type->copy_ctor );
+}
+
+static void dump_exception_type( const cxx_exception_type *type )
+{
+ UINT i;
+
+ 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++)
+ {
+ TRACE( " %d: ", i );
+ dump_type( type->type_info_table->info[i] );
+ }
+}
+
+static void dump_function_descr( const cxx_function_descr *descr )
+{
+ UINT i;
+ int j;
+
+ 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++)
+ {
+ TRACE( " %d: prev %d func %p\n", i,
+ descr->unwind_table[i].prev, descr->unwind_table[i].handler );
+ }
+ TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
+ for (i = 0; i < descr->tryblock_count; 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++)
+ {
+ 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 ) );
+ }
+ }
+ if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
+ TRACE( "expect list: %p\n", descr->expect_list );
+ if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
+ TRACE( "flags: %08x\n", descr->flags );
+}
+
+/* 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,
+ const type_info *catch_ti, UINT catch_flags )
+{
+ UINT i;
+
+ for (i = 0; i < exc_type->type_info_table->count; i++)
+ {
+ const cxx_type_info *type = exc_type->type_info_table->info[i];
+
+ if (!catch_ti) return type; /* catch(...) matches any type */
+ if (catch_ti != type->type_info)
+ {
+ if (strcmp( catch_ti->mangled, type->type_info->mangled )) continue;
+ }
+ /* type is the same, now check the flags */
+ if ((exc_type->flags & TYPE_FLAG_CONST) &&
+ !(catch_flags & TYPE_FLAG_CONST)) continue;
+ if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
+ !(catch_flags & TYPE_FLAG_VOLATILE)) continue;
+ return type; /* it matched */
+ }
+ return NULL;
+}
+
+
+/* copy the exception object where the catch block wants it */
+static void copy_exception( void *object, cxx_exception_frame *frame,
+ const catchblock_info *catchblock, const cxx_type_info *type )
+{
+ void **dest_ptr;
+
+ if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return;
+ if (!catchblock->offset) return;
+ dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset);
+
+ if (catchblock->flags & TYPE_FLAG_REFERENCE)
+ {
+ *dest_ptr = get_this_pointer( &type->offsets, object );
+ }
+ else if (type->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memmove( dest_ptr, object, type->size );
+ /* if it is a pointer, adjust it */
+ if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( &type->offsets, *dest_ptr );
+ }
+ else /* copy the object */
+ {
+ if (type->copy_ctor)
+ call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(&type->offsets,object),
+ (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) );
+ else
+ memmove( dest_ptr, get_this_pointer(&type->offsets,object), type->size );
+ }
+}
+
+/* unwind the local function up to a given trylevel */
+static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
+{
+ void * (*handler)(void);
+ int trylevel = frame->trylevel;
+
+ while (trylevel != last_level)
+ {
+ if (trylevel < 0 || trylevel >= descr->unwind_count)
+ {
+ ERR( "invalid trylevel %d\n", trylevel );
+ MSVCRT_terminate();
+ }
+ handler = descr->unwind_table[trylevel].handler;
+ if (handler)
+ {
+ TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n",
+ handler, trylevel, last_level, &frame->ebp );
+ call_handler( handler, &frame->ebp );
+ }
+ trylevel = descr->unwind_table[trylevel].prev;
+ }
+ frame->trylevel = last_level;
+}
+
+/* exception frame for nested exceptions in catch block */
+struct catch_func_nested_frame
+{
+ EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
+ cxx_exception_frame *cxx_frame; /* frame of parent exception */
+ const cxx_function_descr *descr; /* descriptor of parent exception */
+ int trylevel; /* current try level */
+ cxx_frame_info frame_info;
+};
+
+/* handler for exceptions happening while calling a catch function */
+static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
+ CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
+{
+ struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame;
+
+ if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
+ {
+ __CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE);
+ return ExceptionContinueSearch;
+ }
+
+ TRACE( "got nested exception in catch function\n" );
+
+ if(rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record;
+
+ if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
+ (prev_rec->ExceptionCode == CXX_EXCEPTION &&
+ rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
+ rec->ExceptionInformation[2] == prev_rec->ExceptionInformation[2]))
+ {
+ /* exception was rethrown */
+ *rec = *prev_rec;
+ rec->ExceptionFlags &= ~EH_UNWINDING;
+ if(TRACE_ON(seh)) {
+ TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
+ if(rec->ExceptionCode == CXX_EXCEPTION)
+ TRACE("re-propagate: obj: %lx, type: %lx\n",
+ rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
+ }
+ }
+ else
+ {
+ TRACE("detect threw new exception in catch block\n");
+ }
+ }
+
+ 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 */
+static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context,
+ cxx_exception_frame *frame,
+ const cxx_function_descr *descr, int nested_trylevel,
+ EXCEPTION_REGISTRATION_RECORD *catch_frame,
+ cxx_exception_type *info )
+{
+ UINT i;
+ int j;
+ void *addr, *object = (void *)rec->ExceptionInformation[1];
+ struct catch_func_nested_frame nested_frame;
+ int trylevel = frame->trylevel;
+ DWORD save_esp = ((DWORD*)frame)[-1];
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ data->processing_throw++;
+ for (i = 0; i < descr->tryblock_count; i++)
+ {
+ const tryblock_info *tryblock = &descr->tryblock[i];
+
+ /* only handle try blocks inside current catch block */
+ if (catch_frame && nested_trylevel > tryblock->start_level) continue;
+
+ if (trylevel < tryblock->start_level) continue;
+ if (trylevel > tryblock->end_level) continue;
+
+ /* got a try block */
+ for (j = 0; j < tryblock->catchblock_count; j++)
+ {
+ const catchblock_info *catchblock = &tryblock->catchblock[j];
+ if(info)
+ {
+ const cxx_type_info *type = find_caught_type( info,
+ catchblock->type_info, catchblock->flags );
+ 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");
+ }
+
+ /* Add frame info here so exception is not freed inside RtlUnwind call */
+ _CreateFrameInfo(&nested_frame.frame_info.frame_info,
+ (void*)rec->ExceptionInformation[1]);
+
+ /* unwind the stack */
+ RtlUnwind( catch_frame ? catch_frame : &frame->frame, 0, rec, 0 );
+ cxx_local_unwind( frame, descr, tryblock->start_level );
+ frame->trylevel = tryblock->end_level + 1;
+
+ nested_frame.frame_info.rec = data->exc_record;
+ nested_frame.frame_info.context = data->ctx_record;
+ data->exc_record = rec;
+ data->ctx_record = context;
+ data->processing_throw--;
+
+ /* call the catch block */
+ 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.cxx_frame = frame;
+ nested_frame.descr = descr;
+ nested_frame.trylevel = nested_trylevel + 1;
+
+ __wine_push_frame( &nested_frame.frame );
+ addr = call_handler( catchblock->handler, &frame->ebp );
+ __wine_pop_frame( &nested_frame.frame );
+
+ ((DWORD*)frame)[-1] = save_esp;
+ __CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE);
+ TRACE( "done, continuing at %p\n", addr );
+
+ continue_after_catch( frame, addr );
+ }
+ }
+ data->processing_throw--;
+}
+
+/*********************************************************************
+ * __CxxExceptionFilter (MSVCRT.@)
+ */
+int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
+ const type_info *ti, int flags, void **copy)
+{
+ const cxx_type_info *type;
+ PEXCEPTION_RECORD rec;
+
+ TRACE( "%p %p %x %p\n", ptrs, ti, flags, copy );
+
+ if (!ptrs) return EXCEPTION_CONTINUE_SEARCH;
+
+ /* handle catch(...) */
+ if (!ti) return EXCEPTION_EXECUTE_HANDLER;
+
+ rec = ptrs->ExceptionRecord;
+ if (rec->ExceptionCode != CXX_EXCEPTION || rec->NumberParameters != 3 ||
+ rec->ExceptionInformation[0] < CXX_FRAME_MAGIC_VC6 ||
+ rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ if (rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
+ {
+ rec = msvcrt_get_thread_data()->exc_record;
+ if (!rec) return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ type = find_caught_type( (cxx_exception_type*)rec->ExceptionInformation[2], ti, flags );
+ if (!type) return EXCEPTION_CONTINUE_SEARCH;
+
+ if (copy)
+ {
+ void *object = (void *)rec->ExceptionInformation[1];
+
+ if (flags & TYPE_FLAG_REFERENCE)
+ {
+ *copy = get_this_pointer( &type->offsets, object );
+ }
+ else if (type->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memmove( copy, object, type->size );
+ /* if it is a pointer, adjust it */
+ if (type->size == sizeof(void*)) *copy = get_this_pointer( &type->offsets, *copy );
+ }
+ else /* copy the object */
+ {
+ if (type->copy_ctor)
+ call_copy_ctor( type->copy_ctor, copy, get_this_pointer(&type->offsets,object),
+ (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) );
+ else
+ memmove( copy, get_this_pointer(&type->offsets,object), type->size );
+ }
+ }
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+static LONG CALLBACK se_translation_filter( EXCEPTION_POINTERS *ep, void *c )
+{
+ se_translator_ctx *ctx = (se_translator_ctx *)c;
+ EXCEPTION_RECORD *rec = ep->ExceptionRecord;
+ cxx_exception_type *exc_type;
+
+ if (rec->ExceptionCode != CXX_EXCEPTION)
+ {
+ TRACE( "non-c++ exception thrown in SEH handler: %x\n", rec->ExceptionCode );
+ MSVCRT_terminate();
+ }
+
+ exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
+ call_catch_block( rec, ep->ContextRecord, ctx->frame, ctx->descr,
+ ctx->frame->trylevel, ctx->nested_frame, exc_type );
+
+ __DestructExceptionObject( rec );
+ return ExceptionContinueSearch;
+}
+
+/*********************************************************************
+ * cxx_frame_handler
+ *
+ * Implementation of __CxxFrameHandler.
+ */
+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;
+
+ if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
+ {
+ ERR( "invalid frame magic %x\n", descr->magic );
+ return ExceptionContinueSearch;
+ }
+ if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
+ (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
+ (rec->ExceptionCode != CXX_EXCEPTION))
+ return ExceptionContinueSearch; /* handle only c++ exceptions */
+
+ if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
+ {
+ if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 );
+ return ExceptionContinueSearch;
+ }
+ if (!descr->tryblock_count) return ExceptionContinueSearch;
+
+ if(rec->ExceptionCode == CXX_EXCEPTION &&
+ rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
+ {
+ *rec = *msvcrt_get_thread_data()->exc_record;
+ rec->ExceptionFlags &= ~EH_UNWINDING;
+ if(TRACE_ON(seh)) {
+ TRACE("detect rethrow: exception code: %x\n", rec->ExceptionCode);
+ if(rec->ExceptionCode == CXX_EXCEPTION)
+ TRACE("re-propagate: obj: %lx, type: %lx\n",
+ rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
+ }
+ }
+
+ if(rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
+
+ if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 &&
+ exc_type->custom_handler)
+ {
+ return exc_type->custom_handler( rec, frame, context, dispatch,
+ descr, nested_trylevel, nested_frame, 0 );
+ }
+
+ 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
+ {
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ 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 );
+
+ if (data->se_translator) {
+ EXCEPTION_POINTERS except_ptrs;
+ se_translator_ctx ctx;
+
+ ctx.frame = frame;
+ ctx.descr = descr;
+ ctx.nested_frame = nested_frame;
+ __TRY
+ {
+ except_ptrs.ExceptionRecord = rec;
+ except_ptrs.ContextRecord = context;
+ data->se_translator( rec->ExceptionCode, &except_ptrs );
+ }
+ __EXCEPT_CTX(se_translation_filter, &ctx)
+ {
+ }
+ __ENDTRY
+ }
+ }
+
+ call_catch_block( rec, context, frame, descr,
+ frame->trylevel, nested_frame, exc_type );
+ return ExceptionContinueSearch;
+}
+
+
+/*********************************************************************
+ * __CxxFrameHandler (MSVCRT.@)
+ */
+extern DWORD CDECL __CxxFrameHandler(PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
+ PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch);
+#ifdef _MSC_VER
+DWORD _declspec(naked) __CxxFrameHandler(PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
+ PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch)
+{
+ __asm
+ {
+ push 0
+ push 0
+ push eax
+ push[esp + 28]
+ push[esp + 28]
+ push[esp + 28]
+ push[esp + 28]
+ call cxx_frame_handler
+ add esp, 28
+ ret
+ }
+}
+#else
+__ASM_GLOBAL_FUNC(__CxxFrameHandler,
+ "pushl $0\n\t" /* nested_trylevel */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl $0\n\t" /* nested_frame */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl %eax\n\t" /* descr */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl 28(%esp)\n\t" /* dispatch */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl 28(%esp)\n\t" /* context */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl 28(%esp)\n\t" /* frame */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl 28(%esp)\n\t" /* rec */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "call " __ASM_NAME("cxx_frame_handler") "\n\t"
+ "add $28,%esp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset -28\n\t")
+ "ret")
+#endif
+
+
+/*********************************************************************
+ * __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 );
+}
+
+/*********************************************************************
+ * __CppXcptFilter (MSVCRT.@)
+ */
+int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
+{
+ /* only filter c++ exceptions */
+ if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
+ return _XcptFilter( ex, ptr );
+}
+
+/*********************************************************************
+ * __CxxDetectRethrow (MSVCRT.@)
+ */
+BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
+{
+ PEXCEPTION_RECORD rec;
+
+ if (!ptrs)
+ return FALSE;
+
+ rec = ptrs->ExceptionRecord;
+
+ if (rec->ExceptionCode == CXX_EXCEPTION &&
+ rec->NumberParameters == 3 &&
+ rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
+ rec->ExceptionInformation[2])
+ {
+ ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
+ return TRUE;
+ }
+ return (msvcrt_get_thread_data()->exc_record == rec);
+}
+
+/*********************************************************************
+ * __CxxQueryExceptionSize (MSVCRT.@)
+ */
+unsigned int CDECL __CxxQueryExceptionSize(void)
+{
+ return sizeof(cxx_exception_type);
+}
+
+
+/*********************************************************************
+ * _EH_prolog (MSVCRT.@)
+ */
+
+/* Provided for VC++ binary compatibility only */
+__ASM_GLOBAL_FUNC(_EH_prolog,
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") /* skip ret addr */
+ "pushl $-1\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl %eax\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "pushl %fs:0\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "movl %esp, %fs:0\n\t"
+ "movl 12(%esp), %eax\n\t"
+ "movl %ebp, 12(%esp)\n\t"
+ "leal 12(%esp), %ebp\n\t"
+ "pushl %eax\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ "ret")
+
+static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie )
+{
+ return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie);
+}
+
+static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
+ EXCEPTION_REGISTRATION_RECORD* frame,
+ PCONTEXT context,
+ EXCEPTION_REGISTRATION_RECORD** dispatch)
+{
+ if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))
+ return ExceptionContinueSearch;
+ *dispatch = frame;
+ return ExceptionCollidedUnwind;
+}
+
+static void msvcrt_local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp)
+{
+ EXCEPTION_REGISTRATION_RECORD reg;
+
+ TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
+
+ /* Register a handler in case of a nested exception */
+ reg.Handler = MSVCRT_nested_handler;
+ reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
+ __wine_push_frame(®);
+
+ while (frame->trylevel != TRYLEVEL_END && frame->trylevel != trylevel)
+ {
+ int level = frame->trylevel;
+ frame->trylevel = frame->scopetable[level].previousTryLevel;
+ if (!frame->scopetable[level].lpfnFilter)
+ {
+ TRACE( "__try block cleanup level %d handler %p ebp %p\n",
+ level, frame->scopetable[level].lpfnHandler, ebp );
+ call_handler( frame->scopetable[level].lpfnHandler, ebp );
+ }
+ }
+ __wine_pop_frame(®);
+ TRACE("unwound OK\n");
+}
+
+static void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp )
+{
+ EXCEPTION_REGISTRATION_RECORD reg;
+ const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie );
+
+ TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
+
+ /* Register a handler in case of a nested exception */
+ reg.Handler = MSVCRT_nested_handler;
+ reg.Prev = NtCurrentTeb()->Tib.ExceptionList;
+ __wine_push_frame(®);
+
+ while (frame->trylevel != -2 && frame->trylevel != trylevel)
+ {
+ int level = frame->trylevel;
+ frame->trylevel = scopetable->entries[level].previousTryLevel;
+ if (!scopetable->entries[level].lpfnFilter)
+ {
+ TRACE( "__try block cleanup level %d handler %p ebp %p\n",
+ level, scopetable->entries[level].lpfnHandler, ebp );
+ call_handler( scopetable->entries[level].lpfnHandler, ebp );
+ }
+ }
+ __wine_pop_frame(®);
+ TRACE("unwound OK\n");
+}
+#ifndef __REACTOS__
+/*******************************************************************
+ * _local_unwind2 (MSVCRT.@)
+ */
+void CDECL _local_unwind2(MSVCRT_EXCEPTION_FRAME* frame, int trylevel)
+{
+ msvcrt_local_unwind2( frame, trylevel, &frame->_ebp );
+}
+#endif
+/*******************************************************************
+ * _local_unwind4 (MSVCRT.@)
+ */
+void CDECL _local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel )
+{
+ msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
+}
+
+#ifndef __REACTOS__
+/*******************************************************************
+ * _global_unwind2 (MSVCRT.@)
+ */
+void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame)
+{
+ TRACE("(%p)\n",frame);
+ RtlUnwind( frame, 0, 0, 0 );
+}
+#else
+void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame);
+#endif
+
+#ifndef __REACTOS__
+/*********************************************************************
+ * _except_handler2 (MSVCRT.@)
+ */
+int CDECL _except_handler2(PEXCEPTION_RECORD rec,
+ EXCEPTION_REGISTRATION_RECORD* frame,
+ PCONTEXT context,
+ EXCEPTION_REGISTRATION_RECORD** dispatcher)
+{
+ FIXME("exception %x flags=%x at %p handler=%p %p %p stub\n",
+ rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
+ frame->Handler, context, dispatcher);
+ return ExceptionContinueSearch;
+}
+
+/*********************************************************************
+ * _except_handler3 (MSVCRT.@)
+ */
+int CDECL _except_handler3(PEXCEPTION_RECORD rec,
+ MSVCRT_EXCEPTION_FRAME* frame,
+ PCONTEXT context, void* dispatcher)
+{
+ int retval, trylevel;
+ EXCEPTION_POINTERS exceptPtrs;
+ PSCOPETABLE pScopeTable;
+
+ TRACE("exception %x flags=%x at %p handler=%p %p %p semi-stub\n",
+ rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
+ frame->handler, context, dispatcher);
+
+#ifdef _MSC_VER
+ __asm{ cld }
+#else
+ __asm__ __volatile__("cld");
+#endif
+ if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
+ {
+ /* Unwinding the current frame */
+ msvcrt_local_unwind2(frame, TRYLEVEL_END, &frame->_ebp);
+ TRACE("unwound current frame, returning ExceptionContinueSearch\n");
+ return ExceptionContinueSearch;
+ }
+ else
+ {
+ /* Hunting for handler */
+ exceptPtrs.ExceptionRecord = rec;
+ exceptPtrs.ContextRecord = context;
+ *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
+ trylevel = frame->trylevel;
+ pScopeTable = frame->scopetable;
+
+ while (trylevel != TRYLEVEL_END)
+ {
+ TRACE( "level %d prev %d filter %p\n", trylevel, pScopeTable[trylevel].previousTryLevel,
+ pScopeTable[trylevel].lpfnFilter );
+ if (pScopeTable[trylevel].lpfnFilter)
+ {
+ retval = call_filter( pScopeTable[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
+
+ TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
+ "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
+ "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
+
+ if (retval == EXCEPTION_CONTINUE_EXECUTION)
+ return ExceptionContinueExecution;
+
+ if (retval == EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Unwind all higher frames, this one will handle the exception */
+ _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
+ msvcrt_local_unwind2(frame, trylevel, &frame->_ebp);
+
+ /* Set our trylevel to the enclosing block, and call the __finally
+ * code, which won't return
+ */
+ frame->trylevel = pScopeTable[trylevel].previousTryLevel;
+ TRACE("__finally block %p\n",pScopeTable[trylevel].lpfnHandler);
+ call_finally_block(pScopeTable[trylevel].lpfnHandler, &frame->_ebp);
+ }
+ }
+ trylevel = pScopeTable[trylevel].previousTryLevel;
+ }
+ }
+ TRACE("reached TRYLEVEL_END, returning ExceptionContinueSearch\n");
+ return ExceptionContinueSearch;
+}
+#endif /* __REACTOS__ */
+/*********************************************************************
+ * _except_handler4_common (MSVCRT.@)
+ */
+int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void),
+ EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame,
+ CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
+{
+ int retval, trylevel;
+ EXCEPTION_POINTERS exceptPtrs;
+ const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie );
+
+ TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n",
+ rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
+ frame->handler, context, dispatcher, *cookie, scope_table,
+ scope_table->gs_cookie_offset, scope_table->gs_cookie_xor,
+ scope_table->eh_cookie_offset, scope_table->eh_cookie_xor );
+
+ /* FIXME: no cookie validation yet */
+
+ if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
+ {
+ /* Unwinding the current frame */
+ msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp );
+ TRACE("unwound current frame, returning ExceptionContinueSearch\n");
+ return ExceptionContinueSearch;
+ }
+ else
+ {
+ /* Hunting for handler */
+ exceptPtrs.ExceptionRecord = rec;
+ exceptPtrs.ContextRecord = context;
+ *((DWORD *)frame-1) = (DWORD)&exceptPtrs;
+ trylevel = frame->trylevel;
+
+ while (trylevel != -2)
+ {
+ TRACE( "level %d prev %d filter %p\n", trylevel,
+ scope_table->entries[trylevel].previousTryLevel,
+ scope_table->entries[trylevel].lpfnFilter );
+ if (scope_table->entries[trylevel].lpfnFilter)
+ {
+ retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
+
+ TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
+ "CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
+ "EXECUTE_HANDLER" : "CONTINUE_SEARCH");
+
+ if (retval == EXCEPTION_CONTINUE_EXECUTION)
+ return ExceptionContinueExecution;
+
+ if (retval == EXCEPTION_EXECUTE_HANDLER)
+ {
+ __DestructExceptionObject(rec);
+
+ /* Unwind all higher frames, this one will handle the exception */
+ _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
+ msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
+
+ /* Set our trylevel to the enclosing block, and call the __finally
+ * code, which won't return
+ */
+ frame->trylevel = scope_table->entries[trylevel].previousTryLevel;
+ TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler);
+ call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp);
+ }
+ }
+ trylevel = scope_table->entries[trylevel].previousTryLevel;
+ }
+ }
+ TRACE("reached -2, returning ExceptionContinueSearch\n");
+ return ExceptionContinueSearch;
+}
+
+
+/*
+ * setjmp/longjmp implementation
+ */
+
+#define MSVCRT_JMP_MAGIC 0x56433230 /* ID value for new jump structure */
+typedef void (__stdcall *MSVCRT_unwind_function)(const struct MSVCRT___JUMP_BUFFER *);
+
+/* define an entrypoint for setjmp/setjmp3 that stores the registers in the jmp buf */
+/* and then jumps to the C backend function */
+#define DEFINE_SETJMP_ENTRYPOINT(name) \
+ __ASM_GLOBAL_FUNC( name, \
+ "movl 4(%esp),%ecx\n\t" /* jmp_buf */ \
+ "movl %ebp,0(%ecx)\n\t" /* jmp_buf.Ebp */ \
+ "movl %ebx,4(%ecx)\n\t" /* jmp_buf.Ebx */ \
+ "movl %edi,8(%ecx)\n\t" /* jmp_buf.Edi */ \
+ "movl %esi,12(%ecx)\n\t" /* jmp_buf.Esi */ \
+ "movl %esp,16(%ecx)\n\t" /* jmp_buf.Esp */ \
+ "movl 0(%esp),%eax\n\t" \
+ "movl %eax,20(%ecx)\n\t" /* jmp_buf.Eip */ \
+ "jmp " __ASM_NAME("__regs_") # name )
+
+/*******************************************************************
+ * _setjmp (MSVCRT.@)
+ */
+DEFINE_SETJMP_ENTRYPOINT(MSVCRT__setjmp)
+int CDECL DECLSPEC_HIDDEN __regs_MSVCRT__setjmp(struct MSVCRT___JUMP_BUFFER *jmp)
+{
+ jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
+ if (jmp->Registration == ~0UL)
+ jmp->TryLevel = TRYLEVEL_END;
+ else
+ jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
+
+ TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
+ jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
+ return 0;
+}
+
+/*******************************************************************
+ * _setjmp3 (MSVCRT.@)
+ */
+DEFINE_SETJMP_ENTRYPOINT( MSVCRT__setjmp3 )
+int WINAPIV DECLSPEC_HIDDEN __regs_MSVCRT__setjmp3(struct MSVCRT___JUMP_BUFFER *jmp, int nb_args, ...)
+{
+ jmp->Cookie = MSVCRT_JMP_MAGIC;
+ jmp->UnwindFunc = 0;
+ jmp->Registration = (unsigned long)NtCurrentTeb()->Tib.ExceptionList;
+ if (jmp->Registration == ~0UL)
+ {
+ jmp->TryLevel = TRYLEVEL_END;
+ }
+ else
+ {
+ int i;
+ va_list args;
+
+ va_start( args, nb_args );
+ if (nb_args > 0) jmp->UnwindFunc = va_arg( args, unsigned long );
+ if (nb_args > 1) jmp->TryLevel = va_arg( args, unsigned long );
+ else jmp->TryLevel = ((MSVCRT_EXCEPTION_FRAME*)jmp->Registration)->trylevel;
+ for (i = 0; i < 6 && i < nb_args - 2; i++)
+ jmp->UnwindData[i] = va_arg( args, unsigned long );
+ va_end( args );
+ }
+
+ TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx\n",
+ jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration );
+ return 0;
+}
+
+/*********************************************************************
+ * longjmp (MSVCRT.@)
+ */
+void CDECL MSVCRT_longjmp(struct MSVCRT___JUMP_BUFFER *jmp, int retval)
+{
+ unsigned long cur_frame = 0;
+
+ TRACE("buf=%p ebx=%08lx esi=%08lx edi=%08lx ebp=%08lx esp=%08lx eip=%08lx frame=%08lx retval=%08x\n",
+ jmp, jmp->Ebx, jmp->Esi, jmp->Edi, jmp->Ebp, jmp->Esp, jmp->Eip, jmp->Registration, retval );
+
+ cur_frame=(unsigned long)NtCurrentTeb()->Tib.ExceptionList;
+ TRACE("cur_frame=%lx\n",cur_frame);
+
+ if (cur_frame != jmp->Registration)
+ _global_unwind2((EXCEPTION_REGISTRATION_RECORD*)jmp->Registration);
+
+ if (jmp->Registration)
+ {
+ if (IsBadReadPtr(&jmp->Cookie, sizeof(long)) || jmp->Cookie != MSVCRT_JMP_MAGIC)
+ {
+ msvcrt_local_unwind2((MSVCRT_EXCEPTION_FRAME*)jmp->Registration,
+ jmp->TryLevel, (void *)jmp->Ebp);
+ }
+ else if(jmp->UnwindFunc)
+ {
+ MSVCRT_unwind_function unwind_func;
+
+ unwind_func=(MSVCRT_unwind_function)jmp->UnwindFunc;
+ unwind_func(jmp);
+ }
+ }
+
+ if (!retval)
+ retval = 1;
+
+ __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
+}
+
+/*********************************************************************
+ * _seh_longjmp_unwind (MSVCRT.@)
+ */
+void __stdcall _seh_longjmp_unwind(struct MSVCRT___JUMP_BUFFER *jmp)
+{
+ msvcrt_local_unwind2( (MSVCRT_EXCEPTION_FRAME *)jmp->Registration, jmp->TryLevel, (void *)jmp->Ebp );
+}
+
+/*********************************************************************
+ * _seh_longjmp_unwind4 (MSVCRT.@)
+ */
+void __stdcall _seh_longjmp_unwind4(struct MSVCRT___JUMP_BUFFER *jmp)
+{
+ msvcrt_local_unwind4( (ULONG *)&jmp->Cookie, (MSVCRT_EXCEPTION_FRAME *)jmp->Registration,
+ jmp->TryLevel, (void *)jmp->Ebp );
+}
+
+/*********************************************************************
+ * _fpieee_flt (MSVCRT.@)
+ */
+int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
+ int (__cdecl *handler)(_FPIEEE_RECORD*))
+{
+ FLOATING_SAVE_AREA *ctx = &ep->ContextRecord->FloatSave;
+ _FPIEEE_RECORD rec;
+ int ret;
+
+ TRACE("(%x %p %p)\n", exception_code, ep, handler);
+
+ switch(exception_code) {
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ case STATUS_FLOAT_INEXACT_RESULT:
+ case STATUS_FLOAT_INVALID_OPERATION:
+ case STATUS_FLOAT_OVERFLOW:
+ case STATUS_FLOAT_UNDERFLOW:
+ break;
+ default:
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ memset(&rec, 0, sizeof(rec));
+ rec.RoundingMode = ctx->ControlWord >> 10;
+ switch((ctx->ControlWord >> 8) & 0x3) {
+ case 0: rec.Precision = 2; break;
+ case 1: rec.Precision = 3; break;
+ case 2: rec.Precision = 1; break;
+ case 3: rec.Precision = 0; break;
+ }
+ rec.Status.InvalidOperation = ctx->StatusWord & 0x1;
+ rec.Status.ZeroDivide = ((ctx->StatusWord & 0x4) != 0);
+ rec.Status.Overflow = ((ctx->StatusWord & 0x8) != 0);
+ rec.Status.Underflow = ((ctx->StatusWord & 0x10) != 0);
+ rec.Status.Inexact = ((ctx->StatusWord & 0x20) != 0);
+ rec.Enable.InvalidOperation = ((ctx->ControlWord & 0x1) == 0);
+ rec.Enable.ZeroDivide = ((ctx->ControlWord & 0x4) == 0);
+ rec.Enable.Overflow = ((ctx->ControlWord & 0x8) == 0);
+ rec.Enable.Underflow = ((ctx->ControlWord & 0x10) == 0);
+ rec.Enable.Inexact = ((ctx->ControlWord & 0x20) == 0);
+ rec.Cause.InvalidOperation = rec.Enable.InvalidOperation & rec.Status.InvalidOperation;
+ rec.Cause.ZeroDivide = rec.Enable.ZeroDivide & rec.Status.ZeroDivide;
+ rec.Cause.Overflow = rec.Enable.Overflow & rec.Status.Overflow;
+ rec.Cause.Underflow = rec.Enable.Underflow & rec.Status.Underflow;
+ rec.Cause.Inexact = rec.Enable.Inexact & rec.Status.Inexact;
+
+ TRACE("opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
+
+ if(*(WORD*)ctx->ErrorOffset == 0x35dc) { /* fdiv m64fp */
+ if(exception_code==STATUS_FLOAT_DIVIDE_BY_ZERO || exception_code==STATUS_FLOAT_INVALID_OPERATION) {
+ rec.Operand1.OperandValid = 1;
+ rec.Result.OperandValid = 0;
+ } else {
+ rec.Operand1.OperandValid = 0;
+ rec.Result.OperandValid = 1;
+ }
+ rec.Operand2.OperandValid = 1;
+ rec.Operation = _FpCodeDivide;
+ rec.Operand1.Format = _FpFormatFp80;
+ memcpy(&rec.Operand1.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
+ rec.Operand2.Format = _FpFormatFp64;
+ rec.Operand2.Value.Fp64Value = *(double*)ctx->DataOffset;
+ rec.Result.Format = _FpFormatFp80;
+ memcpy(&rec.Result.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
+
+ ret = handler(&rec);
+
+ if(ret == EXCEPTION_CONTINUE_EXECUTION)
+ memcpy(ctx->RegisterArea, &rec.Result.Value.Fp80Value, sizeof(rec.Operand1.Value.Fp80Value));
+ return ret;
+ }
+
+ FIXME("unsupported opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#endif /* __i386__ */
diff --git a/sdk/lib/crt/wine/except_x86_64.c b/sdk/lib/crt/wine/except_x86_64.c
new file mode 100644
index 00000000000..e91b8628297
--- /dev/null
+++ b/sdk/lib/crt/wine/except_x86_64.c
@@ -0,0 +1,758 @@
+/*
+ * msvcrt C++ exception handling
+ *
+ * Copyright 2011 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef __x86_64__
+
+#include
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "msvcrt.h"
+#include "wine/exception.h"
+#include "excpt.h"
+#include "wine/debug.h"
+
+#include "cppexcept.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(seh);
+
+typedef struct
+{
+ int prev;
+ UINT handler;
+} unwind_info;
+
+typedef struct
+{
+ UINT flags;
+ UINT type_info;
+ int offset;
+ UINT handler;
+ UINT frame;
+} catchblock_info;
+#define TYPE_FLAG_CONST 1
+#define TYPE_FLAG_VOLATILE 2
+#define TYPE_FLAG_REFERENCE 8
+
+typedef struct
+{
+ int start_level;
+ int end_level;
+ int catch_level;
+ int catchblock_count;
+ UINT catchblock;
+} tryblock_info;
+
+typedef struct
+{
+ int ip;
+ int state;
+} ipmap_info;
+
+typedef struct __cxx_function_descr
+{
+ UINT magic;
+ UINT unwind_count;
+ UINT unwind_table;
+ UINT tryblock_count;
+ UINT tryblock;
+ UINT ipmap_count;
+ UINT ipmap;
+ UINT unwind_help;
+ UINT expect_list;
+ UINT flags;
+} cxx_function_descr;
+
+typedef struct
+{
+ cxx_frame_info frame_info;
+ BOOL rethrow;
+} cxx_catch_ctx;
+
+typedef struct
+{
+ ULONG64 dest_frame;
+ ULONG64 orig_frame;
+ EXCEPTION_RECORD *seh_rec;
+ DISPATCHER_CONTEXT *dispatch;
+ const cxx_function_descr *descr;
+} se_translator_ctx;
+
+static inline void* rva_to_ptr(UINT rva, ULONG64 base)
+{
+ return rva ? (void*)(base+rva) : NULL;
+}
+
+static inline void dump_type(UINT type_rva, ULONG64 base)
+{
+ const cxx_type_info *type = rva_to_ptr(type_rva, base);
+
+ TRACE("flags %x type %x %s offsets %d,%d,%d size %d copy ctor %x(%p)\n",
+ type->flags, type->type_info, dbgstr_type_info(rva_to_ptr(type->type_info, base)),
+ type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
+ type->size, type->copy_ctor, rva_to_ptr(type->copy_ctor, base));
+}
+
+static void dump_exception_type(const cxx_exception_type *type, ULONG64 base)
+{
+ const cxx_type_info_table *type_info_table = rva_to_ptr(type->type_info_table, base);
+ UINT i;
+
+ TRACE("flags %x destr %x(%p) handler %x(%p) type info %x(%p)\n",
+ type->flags, type->destructor, rva_to_ptr(type->destructor, base),
+ type->custom_handler, rva_to_ptr(type->custom_handler, base),
+ type->type_info_table, type_info_table);
+ for (i = 0; i < type_info_table->count; i++)
+ {
+ TRACE(" %d: ", i);
+ dump_type(type_info_table->info[i], base);
+ }
+}
+
+static void dump_function_descr(const cxx_function_descr *descr, ULONG64 image_base)
+{
+ unwind_info *unwind_table = rva_to_ptr(descr->unwind_table, image_base);
+ tryblock_info *tryblock = rva_to_ptr(descr->tryblock, image_base);
+ ipmap_info *ipmap = rva_to_ptr(descr->ipmap, image_base);
+ UINT i, j;
+
+ TRACE("magic %x\n", descr->magic);
+ TRACE("unwind table: %x(%p) %d\n", descr->unwind_table, unwind_table, descr->unwind_count);
+ for (i=0; iunwind_count; i++)
+ {
+ TRACE(" %d: prev %d func %x(%p)\n", i, unwind_table[i].prev,
+ unwind_table[i].handler, rva_to_ptr(unwind_table[i].handler, image_base));
+ }
+ TRACE("try table: %x(%p) %d\n", descr->tryblock, tryblock, descr->tryblock_count);
+ for (i=0; itryblock_count; i++)
+ {
+ catchblock_info *catchblock = rva_to_ptr(tryblock[i].catchblock, image_base);
+
+ TRACE(" %d: start %d end %d catchlevel %d catch %x(%p) %d\n", i,
+ tryblock[i].start_level, tryblock[i].end_level,
+ tryblock[i].catch_level, tryblock[i].catchblock,
+ catchblock, tryblock[i].catchblock_count);
+ for (j=0; jipmap, ipmap, descr->ipmap_count);
+ for (i=0; iipmap_count; i++)
+ {
+ TRACE(" %d: ip %x state %d\n", i, ipmap[i].ip, ipmap[i].state);
+ }
+ TRACE("unwind_help %d\n", descr->unwind_help);
+ if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
+ TRACE("expect list: %x\n", descr->expect_list);
+ if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
+ TRACE("flags: %08x\n", descr->flags);
+}
+
+static inline int ip_to_state(ipmap_info *ipmap, UINT count, int ip)
+{
+ UINT low = 0, high = count-1, med;
+
+ while (low < high) {
+ med = low + (high-low)/2;
+
+ if (ipmap[med].ip <= ip && ipmap[med+1].ip > ip)
+ {
+ low = med;
+ break;
+ }
+ if (ipmap[med].ip < ip) low = med+1;
+ else high = med-1;
+ }
+
+ TRACE("%x -> %d\n", ip, ipmap[low].state);
+ return ipmap[low].state;
+}
+
+/* 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, ULONG64 exc_base,
+ const type_info *catch_ti, UINT catch_flags)
+{
+ const cxx_type_info_table *type_info_table = rva_to_ptr(exc_type->type_info_table, exc_base);
+ UINT i;
+
+ for (i = 0; i < type_info_table->count; i++)
+ {
+ const cxx_type_info *type = rva_to_ptr(type_info_table->info[i], exc_base);
+ const type_info *ti = rva_to_ptr(type->type_info, exc_base);
+
+ if (!catch_ti) return type; /* catch(...) matches any type */
+ if (catch_ti != ti)
+ {
+ if (strcmp( catch_ti->mangled, ti->mangled )) continue;
+ }
+ /* type is the same, now check the flags */
+ if ((exc_type->flags & TYPE_FLAG_CONST) &&
+ !(catch_flags & TYPE_FLAG_CONST)) continue;
+ if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
+ !(catch_flags & TYPE_FLAG_VOLATILE)) continue;
+ return type; /* it matched */
+ }
+ return NULL;
+}
+
+static inline void copy_exception(void *object, ULONG64 frame,
+ DISPATCHER_CONTEXT *dispatch,
+ const catchblock_info *catchblock,
+ const cxx_type_info *type, ULONG64 exc_base)
+{
+ const type_info *catch_ti = rva_to_ptr(catchblock->type_info, dispatch->ImageBase);
+ void **dest = rva_to_ptr(catchblock->offset, frame);
+
+ if (!catch_ti || !catch_ti->mangled[0]) return;
+ if (!catchblock->offset) return;
+
+ if (catchblock->flags & TYPE_FLAG_REFERENCE)
+ {
+ *dest = get_this_pointer(&type->offsets, object);
+ }
+ else if (type->flags & CLASS_IS_SIMPLE_TYPE)
+ {
+ memmove(dest, object, type->size);
+ /* if it is a pointer, adjust it */
+ if (type->size == sizeof(void*)) *dest = get_this_pointer(&type->offsets, *dest);
+ }
+ else /* copy the object */
+ {
+ if (type->copy_ctor)
+ {
+ if (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS)
+ {
+ void (__cdecl *copy_ctor)(void*, void*, int) =
+ rva_to_ptr(type->copy_ctor, exc_base);
+ copy_ctor(dest, get_this_pointer(&type->offsets, object), 1);
+ }
+ else
+ {
+ void (__cdecl *copy_ctor)(void*, void*) =
+ rva_to_ptr(type->copy_ctor, exc_base);
+ copy_ctor(dest, get_this_pointer(&type->offsets, object));
+ }
+ }
+ else
+ memmove(dest, get_this_pointer(&type->offsets,object), type->size);
+ }
+}
+
+static void cxx_local_unwind(ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
+ const cxx_function_descr *descr, int last_level)
+{
+ const unwind_info *unwind_table = rva_to_ptr(descr->unwind_table, dispatch->ImageBase);
+ void (__cdecl *handler)(ULONG64 unk, ULONG64 rbp);
+ int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
+ int trylevel;
+
+ if (unwind_help[0] == -2)
+ {
+ trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
+ descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
+ }
+ else
+ {
+ trylevel = unwind_help[0];
+ }
+
+ TRACE("current level: %d, last level: %d\n", trylevel, last_level);
+ while (trylevel > last_level)
+ {
+ if (trylevel<0 || trylevel>=descr->unwind_count)
+ {
+ ERR("invalid trylevel %d\n", trylevel);
+ MSVCRT_terminate();
+ }
+ handler = rva_to_ptr(unwind_table[trylevel].handler, dispatch->ImageBase);
+ if (handler)
+ {
+ TRACE("handler: %p\n", handler);
+ handler(0, frame);
+ }
+ trylevel = unwind_table[trylevel].prev;
+ }
+ unwind_help[0] = trylevel;
+}
+
+static LONG CALLBACK cxx_rethrow_filter(PEXCEPTION_POINTERS eptrs, void *c)
+{
+ EXCEPTION_RECORD *rec = eptrs->ExceptionRecord;
+ thread_data_t *data = msvcrt_get_thread_data();
+ cxx_catch_ctx *ctx = c;
+
+ if (rec->ExceptionCode != CXX_EXCEPTION)
+ return EXCEPTION_CONTINUE_SEARCH;
+ if (!rec->ExceptionInformation[1] && !rec->ExceptionInformation[2])
+ return EXCEPTION_EXECUTE_HANDLER;
+ if (rec->ExceptionInformation[1] == data->exc_record->ExceptionInformation[1])
+ ctx->rethrow = TRUE;
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+static void CALLBACK cxx_catch_cleanup(BOOL normal, void *c)
+{
+ cxx_catch_ctx *ctx = c;
+ __CxxUnregisterExceptionObject(&ctx->frame_info, ctx->rethrow);
+}
+
+static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
+{
+ ULONG64 frame = rec->ExceptionInformation[1];
+ const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2];
+ EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
+ EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6];
+ CONTEXT *context = (void*)rec->ExceptionInformation[7];
+ void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5];
+ int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
+ EXCEPTION_POINTERS ep = { prev_rec, context };
+ cxx_catch_ctx ctx;
+ void *ret_addr = NULL;
+
+ TRACE("calling handler %p\n", handler);
+
+ ctx.rethrow = FALSE;
+ __CxxRegisterExceptionObject(&ep, &ctx.frame_info);
+ msvcrt_get_thread_data()->processing_throw--;
+ __TRY
+ {
+ __TRY
+ {
+ ret_addr = handler(0, frame);
+ }
+ __EXCEPT_CTX(cxx_rethrow_filter, &ctx)
+ {
+ TRACE("detect rethrow: exception code: %x\n", prev_rec->ExceptionCode);
+ ctx.rethrow = TRUE;
+
+ if (untrans_rec)
+ {
+ __DestructExceptionObject(prev_rec);
+ RaiseException(untrans_rec->ExceptionCode, untrans_rec->ExceptionFlags,
+ untrans_rec->NumberParameters, untrans_rec->ExceptionInformation);
+ }
+ else
+ {
+ RaiseException(prev_rec->ExceptionCode, prev_rec->ExceptionFlags,
+ prev_rec->NumberParameters, prev_rec->ExceptionInformation);
+ }
+ }
+ __ENDTRY
+ }
+ __FINALLY_CTX(cxx_catch_cleanup, &ctx)
+
+ unwind_help[0] = -2;
+ unwind_help[1] = -1;
+ return ret_addr;
+}
+
+static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
+{
+ return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==8 &&
+ rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block;
+}
+
+static inline void find_catch_block(EXCEPTION_RECORD *rec, CONTEXT *context,
+ EXCEPTION_RECORD *untrans_rec,
+ ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
+ const cxx_function_descr *descr,
+ cxx_exception_type *info, ULONG64 orig_frame)
+{
+ ULONG64 exc_base = (rec->NumberParameters == 4 ? rec->ExceptionInformation[3] : 0);
+ int trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
+ descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
+ thread_data_t *data = msvcrt_get_thread_data();
+ const tryblock_info *in_catch;
+ EXCEPTION_RECORD catch_record;
+ CONTEXT ctx;
+ UINT i, j;
+ INT *unwind_help;
+
+ data->processing_throw++;
+ for (i=descr->tryblock_count; i>0; i--)
+ {
+ in_catch = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
+ in_catch = &in_catch[i-1];
+
+ if (trylevel>in_catch->end_level && trylevel<=in_catch->catch_level)
+ break;
+ }
+ if (!i)
+ in_catch = NULL;
+
+ unwind_help = rva_to_ptr(descr->unwind_help, orig_frame);
+ if (trylevel > unwind_help[1])
+ unwind_help[0] = unwind_help[1] = trylevel;
+ else
+ trylevel = unwind_help[1];
+ TRACE("current trylevel: %d\n", trylevel);
+
+ for (i=0; itryblock_count; i++)
+ {
+ const tryblock_info *tryblock = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
+ tryblock = &tryblock[i];
+
+ if (trylevel < tryblock->start_level) continue;
+ if (trylevel > tryblock->end_level) continue;
+
+ if (in_catch)
+ {
+ if(tryblock->start_level <= in_catch->end_level) continue;
+ if(tryblock->end_level > in_catch->catch_level) continue;
+ }
+
+ /* got a try block */
+ for (j=0; jcatchblock_count; j++)
+ {
+ const catchblock_info *catchblock = rva_to_ptr(tryblock->catchblock, dispatch->ImageBase);
+ catchblock = &catchblock[j];
+
+ if (info)
+ {
+ const cxx_type_info *type = find_caught_type(info, exc_base,
+ rva_to_ptr(catchblock->type_info, dispatch->ImageBase),
+ catchblock->flags);
+ 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((void*)rec->ExceptionInformation[1],
+ orig_frame, dispatch, catchblock, type, exc_base);
+ }
+ else
+ {
+ /* no CXX_EXCEPTION only proceed with a catch(...) block*/
+ if (catchblock->type_info)
+ continue;
+ TRACE("found catch(...) block\n");
+ }
+
+ /* unwind stack and call catch */
+ memset(&catch_record, 0, sizeof(catch_record));
+ catch_record.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
+ catch_record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+ catch_record.NumberParameters = 8;
+ catch_record.ExceptionInformation[0] = (ULONG_PTR)call_catch_block;
+ catch_record.ExceptionInformation[1] = orig_frame;
+ catch_record.ExceptionInformation[2] = (ULONG_PTR)descr;
+ catch_record.ExceptionInformation[3] = tryblock->start_level;
+ catch_record.ExceptionInformation[4] = (ULONG_PTR)rec;
+ catch_record.ExceptionInformation[5] =
+ (ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase);
+ catch_record.ExceptionInformation[6] = (ULONG_PTR)untrans_rec;
+ catch_record.ExceptionInformation[7] = (ULONG_PTR)context;
+ RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &ctx, NULL);
+ }
+ }
+
+ TRACE("no matching catch block found\n");
+ data->processing_throw--;
+}
+
+static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c)
+{
+ se_translator_ctx *ctx = (se_translator_ctx *)c;
+ EXCEPTION_RECORD *rec = ep->ExceptionRecord;
+ cxx_exception_type *exc_type;
+
+ if (rec->ExceptionCode != CXX_EXCEPTION)
+ {
+ TRACE("non-c++ exception thrown in SEH handler: %x\n", rec->ExceptionCode);
+ MSVCRT_terminate();
+ }
+
+ exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
+ find_catch_block(rec, ep->ContextRecord, ctx->seh_rec, ctx->dest_frame, ctx->dispatch,
+ ctx->descr, exc_type, ctx->orig_frame);
+
+ __DestructExceptionObject(rec);
+ return ExceptionContinueSearch;
+}
+
+static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
+ CONTEXT *context, DISPATCHER_CONTEXT *dispatch,
+ const cxx_function_descr *descr)
+{
+ int trylevel = ip_to_state(rva_to_ptr(descr->ipmap, dispatch->ImageBase),
+ descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
+ cxx_exception_type *exc_type;
+ ULONG64 orig_frame = frame;
+ ULONG64 throw_base;
+ DWORD throw_func_off;
+ void *throw_func;
+ UINT i, j;
+ int unwindlevel = -1;
+
+ if (descr->magicmagic>CXX_FRAME_MAGIC_VC8)
+ {
+ FIXME("unhandled frame magic %x\n", descr->magic);
+ return ExceptionContinueSearch;
+ }
+
+ if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
+ (descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
+ (rec->ExceptionCode != CXX_EXCEPTION &&
+ !cxx_is_consolidate(rec) &&
+ rec->ExceptionCode != STATUS_LONGJUMP))
+ return ExceptionContinueSearch; /* handle only c++ exceptions */
+
+ /* update orig_frame if it's a nested exception */
+ throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress;
+ throw_func = rva_to_ptr(throw_func_off, throw_base);
+ TRACE("reconstructed handler pointer: %p\n", throw_func);
+ for (i=descr->tryblock_count; i>0; i--)
+ {
+ const tryblock_info *tryblock = rva_to_ptr(descr->tryblock, dispatch->ImageBase);
+ tryblock = &tryblock[i-1];
+
+ if (trylevel>tryblock->end_level && trylevel<=tryblock->catch_level)
+ {
+ for (j=0; jcatchblock_count; j++)
+ {
+ const catchblock_info *catchblock = rva_to_ptr(tryblock->catchblock, dispatch->ImageBase);
+ catchblock = &catchblock[j];
+
+ if (rva_to_ptr(catchblock->handler, dispatch->ImageBase) == throw_func)
+ {
+ TRACE("nested exception detected\n");
+ unwindlevel = tryblock->end_level;
+ orig_frame = *(ULONG64*)rva_to_ptr(catchblock->frame, frame);
+ TRACE("setting orig_frame to %lx\n", orig_frame);
+ }
+ }
+ }
+ }
+
+ if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
+ {
+ if (rec->ExceptionFlags & EH_TARGET_UNWIND)
+ cxx_local_unwind(orig_frame, dispatch, descr,
+ cxx_is_consolidate(rec) ? rec->ExceptionInformation[3] : trylevel);
+ else
+ cxx_local_unwind(orig_frame, dispatch, descr, unwindlevel);
+ return ExceptionContinueSearch;
+ }
+ if (!descr->tryblock_count) return ExceptionContinueSearch;
+
+ if (rec->ExceptionCode == CXX_EXCEPTION)
+ {
+ exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
+
+ if (TRACE_ON(seh))
+ {
+ TRACE("handling C++ exception rec %p frame %lx descr %p\n", rec, frame, descr);
+ dump_exception_type(exc_type, rec->ExceptionInformation[3]);
+ dump_function_descr(descr, dispatch->ImageBase);
+ }
+ }
+ else
+ {
+ thread_data_t *data = msvcrt_get_thread_data();
+
+ exc_type = NULL;
+ TRACE("handling C exception code %x rec %p frame %lx descr %p\n",
+ rec->ExceptionCode, rec, frame, descr);
+
+ if (data->se_translator) {
+ EXCEPTION_POINTERS except_ptrs;
+ se_translator_ctx ctx;
+
+ ctx.dest_frame = frame;
+ ctx.orig_frame = orig_frame;
+ ctx.seh_rec = rec;
+ ctx.dispatch = dispatch;
+ ctx.descr = descr;
+ __TRY
+ {
+ except_ptrs.ExceptionRecord = rec;
+ except_ptrs.ContextRecord = context;
+ data->se_translator(rec->ExceptionCode, &except_ptrs);
+ }
+ __EXCEPT_CTX(se_translation_filter, &ctx)
+ {
+ }
+ __ENDTRY
+ }
+ }
+
+ find_catch_block(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame);
+ return ExceptionContinueSearch;
+}
+
+/*********************************************************************
+ * __CxxExceptionFilter (MSVCRT.@)
+ */
+int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
+ const type_info *ti, int flags, void **copy )
+{
+ FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy );
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*********************************************************************
+ * __CxxFrameHandler (MSVCRT.@)
+ */
+EXCEPTION_DISPOSITION CDECL __CxxFrameHandler( EXCEPTION_RECORD *rec, ULONG64 frame,
+ CONTEXT *context, DISPATCHER_CONTEXT *dispatch )
+{
+ TRACE( "%p %lx %p %p\n", rec, frame, context, dispatch );
+ return cxx_frame_handler( rec, frame, context, dispatch,
+ rva_to_ptr(*(UINT*)dispatch->HandlerData, dispatch->ImageBase) );
+}
+
+
+/*********************************************************************
+ * __CppXcptFilter (MSVCRT.@)
+ */
+int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
+{
+ /* only filter c++ exceptions */
+ if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
+ return _XcptFilter( ex, ptr );
+}
+
+
+/*********************************************************************
+ * __CxxDetectRethrow (MSVCRT.@)
+ */
+BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
+{
+ PEXCEPTION_RECORD rec;
+
+ if (!ptrs)
+ return FALSE;
+
+ rec = ptrs->ExceptionRecord;
+
+ if (rec->ExceptionCode == CXX_EXCEPTION &&
+ rec->NumberParameters == 4 &&
+ rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
+ rec->ExceptionInformation[2])
+ {
+ ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
+ return TRUE;
+ }
+ return (msvcrt_get_thread_data()->exc_record == rec);
+}
+
+
+/*********************************************************************
+ * __CxxQueryExceptionSize (MSVCRT.@)
+ */
+unsigned int CDECL __CxxQueryExceptionSize(void)
+{
+ return sizeof(cxx_exception_type);
+}
+
+
+/*******************************************************************
+ * _setjmp (MSVCRT.@)
+ */
+__ASM_GLOBAL_FUNC( MSVCRT__setjmp,
+ "jmp " __ASM_NAME("__wine_setjmpex") );
+
+/*******************************************************************
+ * longjmp (MSVCRT.@)
+ */
+void __cdecl MSVCRT_longjmp( struct MSVCRT___JUMP_BUFFER *jmp, int retval )
+{
+ EXCEPTION_RECORD rec;
+
+ if (!retval) retval = 1;
+ if (jmp->Frame)
+ {
+ rec.ExceptionCode = STATUS_LONGJUMP;
+ rec.ExceptionFlags = 0;
+ rec.ExceptionRecord = NULL;
+ rec.ExceptionAddress = NULL;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = (DWORD_PTR)jmp;
+ RtlUnwind( (void *)jmp->Frame, (void *)jmp->Rip, &rec, IntToPtr(retval) );
+ }
+ __wine_longjmp( (__wine_jmp_buf *)jmp, retval );
+}
+
+#ifndef __REACTOS__ // different file for ntdll
+/*******************************************************************
+ * _local_unwind (MSVCRT.@)
+ */
+void __cdecl _local_unwind( void *frame, void *target )
+{
+ RtlUnwind( frame, target, NULL, 0 );
+}
+#endif /* __REACTOS__ */
+
+/*********************************************************************
+ * _fpieee_flt (MSVCRT.@)
+ */
+int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
+ int (__cdecl *handler)(_FPIEEE_RECORD*))
+{
+ FIXME("(%x %p %p) opcode: %s\n", exception_code, ep, handler,
+ wine_dbgstr_longlong(*(ULONG64*)ep->ContextRecord->Rip));
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#if _MSVCR_VER>=110 && _MSVCR_VER<=120
+/*********************************************************************
+ * __crtCapturePreviousContext (MSVCR110.@)
+ */
+void __cdecl get_prev_context(CONTEXT *ctx, DWORD64 rip)
+{
+ ULONG64 frame, image_base;
+ RUNTIME_FUNCTION *rf;
+ void *data;
+
+ TRACE("(%p)\n", ctx);
+
+ rf = RtlLookupFunctionEntry(ctx->Rip, &image_base, NULL);
+ if(!rf) {
+ FIXME("RtlLookupFunctionEntry failed\n");
+ return;
+ }
+
+ RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, ctx->Rip,
+ rf, ctx, &data, &frame, NULL);
+}
+
+__ASM_GLOBAL_FUNC( __crtCapturePreviousContext,
+ "movq %rcx,8(%rsp)\n\t"
+ "call " __ASM_NAME("RtlCaptureContext") "\n\t"
+ "movq 8(%rsp),%rcx\n\t" /* context */
+ "leaq 8(%rsp),%rax\n\t"
+ "movq %rax,0x98(%rcx)\n\t" /* context->Rsp */
+ "movq (%rsp),%rax\n\t"
+ "movq %rax,0xf8(%rcx)\n\t" /* context->Rip */
+ "jmp " __ASM_NAME("get_prev_context") )
+#endif
+
+#endif /* __x86_64__ */
diff --git a/sdk/lib/crt/wine/msvcrt.h b/sdk/lib/crt/wine/msvcrt.h
new file mode 100644
index 00000000000..d5dc4cd5366
--- /dev/null
+++ b/sdk/lib/crt/wine/msvcrt.h
@@ -0,0 +1,1494 @@
+/*
+ * Copyright 2001 Jon Griffiths
+ * Copyright 2004 Dimitrie O. Paun
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * NOTES
+ * Naming conventions
+ * - Symbols are prefixed with MSVCRT_ if they conflict
+ * with libc symbols
+ * - Internal symbols are usually prefixed by msvcrt_.
+ * - Exported symbols that are not present in the public
+ * headers are usually kept the same as the original.
+ * Other conventions
+ * - To avoid conflicts with the standard C library,
+ * no msvcrt headers are included in the implementation.
+ * - Instead, symbols are duplicated here, prefixed with
+ * MSVCRT_, as explained above.
+ * - To avoid inconsistencies, a test for each symbol is
+ * added into tests/headers.c. Please always add a
+ * corresponding test when you add a new symbol!
+ */
+
+#ifndef __WINE_MSVCRT_H
+#define __WINE_MSVCRT_H
+
+#include
+
+#include "windef.h"
+#include "winbase.h"
+
+#define MSVCRT_INT_MAX 0x7fffffff
+#define MSVCRT_LONG_MAX 0x7fffffff
+#define MSVCRT_LONG_MIN (-MSVCRT_LONG_MAX-1)
+#define MSVCRT_ULONG_MAX 0xffffffff
+#define MSVCRT_I64_MAX (((__int64)0x7fffffff << 32) | 0xffffffff)
+#define MSVCRT_I64_MIN (-MSVCRT_I64_MAX-1)
+#define MSVCRT_UI64_MAX (((unsigned __int64)0xffffffff << 32) | 0xffffffff)
+#define MSVCRT_MB_LEN_MAX 5
+#define MSVCRT_FLT_MAX_10_EXP 38
+#define MSVCRT_FLT_MIN_10_EXP (-37)
+#define MSVCRT_DBL_MAX_10_EXP 308
+#define MSVCRT_DBL_MIN_10_EXP (-307)
+#define MSVCRT_DBL_DIG 15
+#ifdef _WIN64
+#define MSVCRT_SIZE_MAX MSVCRT_UI64_MAX
+#else
+#define MSVCRT_SIZE_MAX MSVCRT_ULONG_MAX
+#endif
+
+#define MSVCRT__MAX_DRIVE 3
+#define MSVCRT__MAX_DIR 256
+#define MSVCRT__MAX_FNAME 256
+#define MSVCRT__MAX_EXT 256
+
+typedef unsigned char MSVCRT_bool;
+typedef unsigned short MSVCRT_wchar_t;
+typedef unsigned short MSVCRT_wint_t;
+typedef unsigned short MSVCRT_wctrans_t;
+typedef unsigned short MSVCRT_wctype_t;
+typedef unsigned short MSVCRT__ino_t;
+typedef unsigned int MSVCRT__fsize_t;
+typedef int MSVCRT_long;
+typedef unsigned int MSVCRT_ulong;
+typedef __int64 MSVCRT_longlong;
+#ifdef _WIN64
+typedef unsigned __int64 MSVCRT_size_t;
+typedef __int64 MSVCRT_intptr_t;
+typedef unsigned __int64 MSVCRT_uintptr_t;
+#else
+typedef unsigned long MSVCRT_size_t;
+typedef long MSVCRT_intptr_t;
+typedef unsigned long MSVCRT_uintptr_t;
+#endif
+#ifdef _CRTDLL
+typedef short MSVCRT__dev_t;
+#else
+typedef unsigned int MSVCRT__dev_t;
+#endif
+typedef int MSVCRT__off_t;
+typedef int MSVCRT_clock_t;
+typedef int MSVCRT___time32_t;
+typedef __int64 DECLSPEC_ALIGN(8) MSVCRT___time64_t;
+typedef __int64 DECLSPEC_ALIGN(8) MSVCRT_fpos_t;
+typedef int MSVCRT_mbstate_t;
+
+typedef void (__cdecl *MSVCRT_terminate_handler)(void);
+typedef void (__cdecl *MSVCRT_terminate_function)(void);
+typedef void (__cdecl *MSVCRT_unexpected_handler)(void);
+typedef void (__cdecl *MSVCRT_unexpected_function)(void);
+typedef void (__cdecl *MSVCRT__se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info);
+typedef void (__cdecl *MSVCRT__beginthread_start_routine_t)(void *);
+typedef unsigned int (__stdcall *MSVCRT__beginthreadex_start_routine_t)(void *);
+typedef int (__cdecl *MSVCRT__onexit_t)(void);
+typedef void (__cdecl *MSVCRT_invalid_parameter_handler)(const MSVCRT_wchar_t*, const MSVCRT_wchar_t*, const MSVCRT_wchar_t*, unsigned, MSVCRT_uintptr_t);
+typedef void (__cdecl *MSVCRT_purecall_handler)(void);
+typedef void (__cdecl *MSVCRT_security_error_handler)(int, void *);
+
+typedef struct {ULONG x80[3];} MSVCRT__LDOUBLE; /* Intel 80 bit FP format has sizeof() 12 */
+
+struct MSVCRT_tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+
+typedef struct MSVCRT_tagLC_ID {
+ unsigned short wLanguage;
+ unsigned short wCountry;
+ unsigned short wCodePage;
+} MSVCRT_LC_ID, *MSVCRT_LPLC_ID;
+
+typedef struct {
+ union {
+ const char *str[43];
+ struct {
+ const char *short_wday[7];
+ const char *wday[7];
+ const char *short_mon[12];
+ const char *mon[12];
+ const char *am;
+ const char *pm;
+ const char *short_date;
+ const char *date;
+ const char *time;
+ } names;
+ } str;
+#if _MSVCR_VER < 110
+ LCID lcid;
+#endif
+ int unk[2];
+ union {
+ const MSVCRT_wchar_t *wstr[43];
+ struct {
+ const MSVCRT_wchar_t *short_wday[7];
+ const MSVCRT_wchar_t *wday[7];
+ const MSVCRT_wchar_t *short_mon[12];
+ const MSVCRT_wchar_t *mon[12];
+ const MSVCRT_wchar_t *am;
+ const MSVCRT_wchar_t *pm;
+ const MSVCRT_wchar_t *short_date;
+ const MSVCRT_wchar_t *date;
+ const MSVCRT_wchar_t *time;
+ } names;
+ } wstr;
+#if _MSVCR_VER >= 110
+ const MSVCRT_wchar_t *locname;
+#endif
+ char data[1];
+} MSVCRT___lc_time_data;
+
+typedef struct MSVCRT_threadlocaleinfostruct {
+#if _MSVCR_VER >= 140
+ unsigned short *pctype;
+ int mb_cur_max;
+ unsigned int lc_codepage;
+#endif
+
+ int refcount;
+#if _MSVCR_VER < 140
+ unsigned int lc_codepage;
+#endif
+ unsigned int lc_collate_cp;
+ MSVCRT_ulong lc_handle[6];
+ MSVCRT_LC_ID lc_id[6];
+ struct {
+ char *locale;
+ MSVCRT_wchar_t *wlocale;
+ int *refcount;
+ int *wrefcount;
+ } lc_category[6];
+ int lc_clike;
+#if _MSVCR_VER < 140
+ int mb_cur_max;
+#endif
+ int *lconv_intl_refcount;
+ int *lconv_num_refcount;
+ int *lconv_mon_refcount;
+ struct MSVCRT_lconv *lconv;
+ int *ctype1_refcount;
+ unsigned short *ctype1;
+#if _MSVCR_VER < 140
+ unsigned short *pctype;
+#endif
+ unsigned char *pclmap;
+ unsigned char *pcumap;
+ MSVCRT___lc_time_data *lc_time_curr;
+#if _MSVCR_VER >= 110
+ MSVCRT_wchar_t *lc_name[6];
+#endif
+} MSVCRT_threadlocinfo;
+
+typedef struct MSVCRT_threadmbcinfostruct {
+ int refcount;
+ int mbcodepage;
+ int ismbcodepage;
+ int mblcid;
+ unsigned short mbulinfo[6];
+ unsigned char mbctype[257];
+ unsigned char mbcasemap[256];
+} MSVCRT_threadmbcinfo;
+
+typedef struct MSVCRT_threadlocaleinfostruct *MSVCRT_pthreadlocinfo;
+typedef struct MSVCRT_threadmbcinfostruct *MSVCRT_pthreadmbcinfo;
+
+typedef struct MSVCRT_localeinfo_struct
+{
+ MSVCRT_pthreadlocinfo locinfo;
+ MSVCRT_pthreadmbcinfo mbcinfo;
+} MSVCRT__locale_tstruct, *MSVCRT__locale_t;
+
+typedef struct MSVCRT__onexit_table_t
+{
+ MSVCRT__onexit_t *_first;
+ MSVCRT__onexit_t *_last;
+ MSVCRT__onexit_t *_end;
+} MSVCRT__onexit_table_t;
+
+typedef struct _frame_info
+{
+ void *object;
+ struct _frame_info *next;
+} frame_info;
+
+typedef struct
+{
+ frame_info frame_info;
+ EXCEPTION_RECORD *rec;
+ CONTEXT *context;
+} cxx_frame_info;
+
+frame_info* __cdecl _CreateFrameInfo(frame_info *fi, void *obj);
+BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*);
+void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL);
+void CDECL __DestructExceptionObject(EXCEPTION_RECORD*);
+
+/* TLS data */
+extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
+
+/* Keep in sync with msvcr90/tests/msvcr90.c */
+struct __thread_data {
+ DWORD tid;
+ HANDLE handle;
+ int thread_errno;
+ MSVCRT_ulong thread_doserrno;
+ int unk1;
+ unsigned int random_seed; /* seed for rand() */
+ char *strtok_next; /* next ptr for strtok() */
+ MSVCRT_wchar_t *wcstok_next; /* next ptr for wcstok() */
+ unsigned char *mbstok_next; /* next ptr for mbstok() */
+ char *strerror_buffer; /* buffer for strerror */
+ MSVCRT_wchar_t *wcserror_buffer; /* buffer for wcserror */
+ char *tmpnam_buffer; /* buffer for tmpname() */
+ MSVCRT_wchar_t *wtmpnam_buffer; /* buffer for wtmpname() */
+ void *unk2[2];
+ char *asctime_buffer; /* buffer for asctime */
+ MSVCRT_wchar_t *wasctime_buffer; /* buffer for wasctime */
+ struct MSVCRT_tm *time_buffer; /* buffer for localtime/gmtime */
+ char *efcvt_buffer; /* buffer for ecvt/fcvt */
+ int unk3[2];
+ void *unk4[3];
+ EXCEPTION_POINTERS *xcptinfo;
+ int fpecode;
+ MSVCRT_pthreadmbcinfo mbcinfo;
+ MSVCRT_pthreadlocinfo locinfo;
+ BOOL have_locale;
+ int unk5[1];
+ MSVCRT_terminate_function terminate_handler;
+ MSVCRT_unexpected_function unexpected_handler;
+ MSVCRT__se_translator_function se_translator;
+ void *unk6[3];
+ int unk7;
+ EXCEPTION_RECORD *exc_record;
+ CONTEXT *ctx_record;
+ int processing_throw;
+ frame_info *frame_info_head;
+ void *unk8[6];
+ LCID cached_lcid;
+ BOOL cached_sname;
+ int unk9[2];
+ DWORD cached_cp;
+ char cached_locale[131];
+ void *unk10[100];
+#if _MSVCR_VER >= 140
+ MSVCRT_invalid_parameter_handler invalid_parameter_handler;
+#endif
+};
+
+typedef struct __thread_data thread_data_t;
+
+extern thread_data_t *msvcrt_get_thread_data(void) DECLSPEC_HIDDEN;
+
+LCID MSVCRT_locale_to_LCID(const char*, unsigned short*, BOOL*) DECLSPEC_HIDDEN;
+extern MSVCRT__locale_t MSVCRT_locale DECLSPEC_HIDDEN;
+extern MSVCRT___lc_time_data cloc_time_data DECLSPEC_HIDDEN;
+extern unsigned int MSVCRT___lc_codepage;
+extern int MSVCRT___lc_collate_cp;
+extern WORD MSVCRT__ctype [257];
+extern BOOL initial_locale DECLSPEC_HIDDEN;
+
+void msvcrt_set_errno(int) DECLSPEC_HIDDEN;
+#if _MSVCR_VER >= 80
+typedef enum {
+ EXCEPTION_BAD_ALLOC,
+#if _MSVCR_VER >= 100
+ EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR,
+ EXCEPTION_IMPROPER_LOCK,
+ EXCEPTION_INVALID_SCHEDULER_POLICY_KEY,
+ EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE,
+ EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION,
+ EXCEPTION_IMPROPER_SCHEDULER_ATTACH,
+ EXCEPTION_IMPROPER_SCHEDULER_DETACH,
+#endif
+} exception_type;
+void throw_exception(exception_type, HRESULT, const char*) DECLSPEC_HIDDEN;
+#endif
+
+void __cdecl _purecall(void);
+void __cdecl _amsg_exit(int errnum);
+
+extern char **MSVCRT__environ;
+extern MSVCRT_wchar_t **MSVCRT__wenviron;
+
+extern char ** msvcrt_SnapshotOfEnvironmentA(char **) DECLSPEC_HIDDEN;
+extern MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **) DECLSPEC_HIDDEN;
+
+MSVCRT_wchar_t *msvcrt_wstrdupa(const char *) DECLSPEC_HIDDEN;
+
+extern unsigned int MSVCRT__commode;
+
+/* FIXME: This should be declared in new.h but it's not an extern "C" so
+ * it would not be much use anyway. Even for Winelib applications.
+ */
+int __cdecl MSVCRT__set_new_mode(int mode);
+
+void* __cdecl MSVCRT_operator_new(MSVCRT_size_t);
+void __cdecl MSVCRT_operator_delete(void*);
+
+typedef void* (__cdecl *malloc_func_t)(MSVCRT_size_t);
+typedef void (__cdecl *free_func_t)(void*);
+
+/* Setup and teardown multi threaded locks */
+extern void msvcrt_init_mt_locks(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_locks(void) DECLSPEC_HIDDEN;
+
+extern void msvcrt_init_exception(void*) DECLSPEC_HIDDEN;
+extern BOOL msvcrt_init_locale(void) DECLSPEC_HIDDEN;
+extern void msvcrt_init_math(void) DECLSPEC_HIDDEN;
+extern void msvcrt_init_io(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_io(void) DECLSPEC_HIDDEN;
+extern void msvcrt_init_console(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_console(void) DECLSPEC_HIDDEN;
+extern void msvcrt_init_args(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_args(void) DECLSPEC_HIDDEN;
+extern void msvcrt_init_signals(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_signals(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_popen_data(void) DECLSPEC_HIDDEN;
+extern BOOL msvcrt_init_heap(void) DECLSPEC_HIDDEN;
+extern void msvcrt_destroy_heap(void) DECLSPEC_HIDDEN;
+extern void msvcrt_init_clock(void) DECLSPEC_HIDDEN;
+
+#if _MSVCR_VER >= 100
+extern void msvcrt_init_scheduler(void*) DECLSPEC_HIDDEN;
+extern void msvcrt_free_scheduler(void) DECLSPEC_HIDDEN;
+extern void msvcrt_free_scheduler_thread(void) DECLSPEC_HIDDEN;
+#endif
+
+extern unsigned msvcrt_create_io_inherit_block(WORD*, BYTE**) DECLSPEC_HIDDEN;
+
+extern unsigned int __cdecl _control87(unsigned int, unsigned int);
+
+/* run-time error codes */
+#define _RT_STACK 0
+#define _RT_NULLPTR 1
+#define _RT_FLOAT 2
+#define _RT_INTDIV 3
+#define _RT_EXECMEM 5
+#define _RT_EXECFORM 6
+#define _RT_EXECENV 7
+#define _RT_SPACEARG 8
+#define _RT_SPACEENV 9
+#define _RT_ABORT 10
+#define _RT_NPTR 12
+#define _RT_FPTR 13
+#define _RT_BREAK 14
+#define _RT_INT 15
+#define _RT_THREAD 16
+#define _RT_LOCK 17
+#define _RT_HEAP 18
+#define _RT_OPENCON 19
+#define _RT_QWIN 20
+#define _RT_NOMAIN 21
+#define _RT_NONCONT 22
+#define _RT_INVALDISP 23
+#define _RT_ONEXIT 24
+#define _RT_PUREVIRT 25
+#define _RT_STDIOINIT 26
+#define _RT_LOWIOINIT 27
+#define _RT_HEAPINIT 28
+#define _RT_DOMAIN 120
+#define _RT_SING 121
+#define _RT_TLOSS 122
+#define _RT_CRNL 252
+#define _RT_BANNER 255
+
+struct MSVCRT___timeb32 {
+ MSVCRT___time32_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+};
+
+struct MSVCRT___timeb64 {
+ MSVCRT___time64_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+};
+
+struct MSVCRT__iobuf {
+ char* _ptr;
+ int _cnt;
+ char* _base;
+ int _flag;
+ int _file;
+ int _charbuf;
+ int _bufsiz;
+ char* _tmpfname;
+};
+
+typedef struct MSVCRT__iobuf MSVCRT_FILE;
+
+struct MSVCRT_lconv {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+#if _MSVCR_VER >= 100
+ MSVCRT_wchar_t* _W_decimal_point;
+ MSVCRT_wchar_t* _W_thousands_sep;
+ MSVCRT_wchar_t* _W_int_curr_symbol;
+ MSVCRT_wchar_t* _W_currency_symbol;
+ MSVCRT_wchar_t* _W_mon_decimal_point;
+ MSVCRT_wchar_t* _W_mon_thousands_sep;
+ MSVCRT_wchar_t* _W_positive_sign;
+ MSVCRT_wchar_t* _W_negative_sign;
+#endif
+};
+
+struct MSVCRT__exception {
+ int type;
+ char* name;
+ double arg1;
+ double arg2;
+ double retval;
+};
+
+struct MSVCRT__complex {
+ double x; /* Real part */
+ double y; /* Imaginary part */
+};
+typedef struct MSVCRT__complex _Dcomplex;
+
+typedef struct MSVCRT__div_t {
+ int quot; /* quotient */
+ int rem; /* remainder */
+} MSVCRT_div_t;
+
+typedef struct MSVCRT__ldiv_t {
+ MSVCRT_long quot; /* quotient */
+ MSVCRT_long rem; /* remainder */
+} MSVCRT_ldiv_t;
+
+typedef struct MSVCRT__lldiv_t {
+ MSVCRT_longlong quot; /* quotient */
+ MSVCRT_longlong rem; /* remainder */
+} MSVCRT_lldiv_t;
+
+struct MSVCRT__heapinfo {
+ int* _pentry;
+ MSVCRT_size_t _size;
+ int _useflag;
+};
+
+#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];
+};
+#elif defined(__x86_64__)
+struct MSVCRT__SETJMP_FLOAT128
+{
+ unsigned __int64 DECLSPEC_ALIGN(16) Part[2];
+};
+struct MSVCRT___JUMP_BUFFER
+{
+ unsigned __int64 Frame;
+ unsigned __int64 Rbx;
+ unsigned __int64 Rsp;
+ unsigned __int64 Rbp;
+ unsigned __int64 Rsi;
+ unsigned __int64 Rdi;
+ unsigned __int64 R12;
+ unsigned __int64 R13;
+ unsigned __int64 R14;
+ unsigned __int64 R15;
+ unsigned __int64 Rip;
+ unsigned __int64 Spare;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm6;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm7;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm8;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm9;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm10;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm11;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm12;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm13;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm14;
+ struct MSVCRT__SETJMP_FLOAT128 Xmm15;
+};
+#elif defined(__arm__)
+struct MSVCRT___JUMP_BUFFER
+{
+ unsigned long Frame;
+ unsigned long R4;
+ unsigned long R5;
+ unsigned long R6;
+ unsigned long R7;
+ unsigned long R8;
+ unsigned long R9;
+ unsigned long R10;
+ unsigned long R11;
+ unsigned long Sp;
+ unsigned long Pc;
+ unsigned long Fpscr;
+ unsigned long long D[8];
+};
+#elif defined(__aarch64__)
+struct MSVCRT___JUMP_BUFFER
+{
+ unsigned __int64 Frame;
+ unsigned __int64 Reserved;
+ unsigned __int64 X19;
+ unsigned __int64 X20;
+ unsigned __int64 X21;
+ unsigned __int64 X22;
+ unsigned __int64 X23;
+ unsigned __int64 X24;
+ unsigned __int64 X25;
+ unsigned __int64 X26;
+ unsigned __int64 X27;
+ unsigned __int64 X28;
+ unsigned __int64 Fp;
+ unsigned __int64 Lr;
+ unsigned __int64 Sp;
+ unsigned long Fpcr;
+ unsigned long Fpsr;
+ double D[8];
+};
+#endif /* __i386__ */
+
+struct MSVCRT__diskfree_t {
+ unsigned int total_clusters;
+ unsigned int avail_clusters;
+ unsigned int sectors_per_cluster;
+ unsigned int bytes_per_sector;
+};
+
+struct MSVCRT__finddata32_t {
+ unsigned int attrib;
+ MSVCRT___time32_t time_create;
+ MSVCRT___time32_t time_access;
+ MSVCRT___time32_t time_write;
+ MSVCRT__fsize_t size;
+ char name[260];
+};
+
+struct MSVCRT__finddata32i64_t {
+ unsigned int attrib;
+ MSVCRT___time32_t time_create;
+ MSVCRT___time32_t time_access;
+ MSVCRT___time32_t time_write;
+ __int64 DECLSPEC_ALIGN(8) size;
+ char name[260];
+};
+
+struct MSVCRT__finddata64i32_t {
+ unsigned int attrib;
+ MSVCRT___time64_t time_create;
+ MSVCRT___time64_t time_access;
+ MSVCRT___time64_t time_write;
+ MSVCRT__fsize_t size;
+ char name[260];
+};
+
+struct MSVCRT__finddata64_t {
+ unsigned int attrib;
+ MSVCRT___time64_t time_create;
+ MSVCRT___time64_t time_access;
+ MSVCRT___time64_t time_write;
+ __int64 DECLSPEC_ALIGN(8) size;
+ char name[260];
+};
+
+struct MSVCRT__wfinddata32_t {
+ unsigned int attrib;
+ MSVCRT___time32_t time_create;
+ MSVCRT___time32_t time_access;
+ MSVCRT___time32_t time_write;
+ MSVCRT__fsize_t size;
+ MSVCRT_wchar_t name[260];
+};
+
+struct MSVCRT__wfinddata32i64_t {
+ unsigned int attrib;
+ MSVCRT___time32_t time_create;
+ MSVCRT___time32_t time_access;
+ MSVCRT___time32_t time_write;
+ __int64 DECLSPEC_ALIGN(8) size;
+ MSVCRT_wchar_t name[260];
+};
+
+struct MSVCRT__wfinddata64i32_t {
+ unsigned int attrib;
+ MSVCRT___time64_t time_create;
+ MSVCRT___time64_t time_access;
+ MSVCRT___time64_t time_write;
+ MSVCRT__fsize_t size;
+ MSVCRT_wchar_t name[260];
+};
+
+struct MSVCRT__wfinddata64_t {
+ unsigned int attrib;
+ MSVCRT___time64_t time_create;
+ MSVCRT___time64_t time_access;
+ MSVCRT___time64_t time_write;
+ __int64 DECLSPEC_ALIGN(8) size;
+ MSVCRT_wchar_t name[260];
+};
+
+struct MSVCRT___utimbuf32
+{
+ MSVCRT___time32_t actime;
+ MSVCRT___time32_t modtime;
+};
+
+struct MSVCRT___utimbuf64
+{
+ MSVCRT___time64_t actime;
+ MSVCRT___time64_t modtime;
+};
+
+/* for FreeBSD */
+#undef st_atime
+#undef st_ctime
+#undef st_mtime
+
+struct MSVCRT__stat32 {
+ MSVCRT__dev_t st_dev;
+ MSVCRT__ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ MSVCRT__dev_t st_rdev;
+ MSVCRT__off_t st_size;
+ MSVCRT___time32_t st_atime;
+ MSVCRT___time32_t st_mtime;
+ MSVCRT___time32_t st_ctime;
+};
+
+struct MSVCRT__stat32i64 {
+ MSVCRT__dev_t st_dev;
+ MSVCRT__ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ MSVCRT__dev_t st_rdev;
+ __int64 DECLSPEC_ALIGN(8) st_size;
+ MSVCRT___time32_t st_atime;
+ MSVCRT___time32_t st_mtime;
+ MSVCRT___time32_t st_ctime;
+};
+
+struct MSVCRT__stat64i32 {
+ MSVCRT__dev_t st_dev;
+ MSVCRT__ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ MSVCRT__dev_t st_rdev;
+ MSVCRT__off_t st_size;
+ MSVCRT___time64_t st_atime;
+ MSVCRT___time64_t st_mtime;
+ MSVCRT___time64_t st_ctime;
+};
+
+struct MSVCRT__stat64 {
+ MSVCRT__dev_t st_dev;
+ MSVCRT__ino_t st_ino;
+ unsigned short st_mode;
+ short st_nlink;
+ short st_uid;
+ short st_gid;
+ MSVCRT__dev_t st_rdev;
+ __int64 DECLSPEC_ALIGN(8) st_size;
+ MSVCRT___time64_t st_atime;
+ MSVCRT___time64_t st_mtime;
+ MSVCRT___time64_t st_ctime;
+};
+
+#ifdef _WIN64
+#define MSVCRT__finddata_t MSVCRT__finddata64i32_t
+#define MSVCRT__finddatai64_t MSVCRT__finddata64_t
+#define MSVCRT__wfinddata_t MSVCRT__wfinddata64i32_t
+#define MSVCRT__wfinddatai64_t MSVCRT__wfinddata64_t
+#define MSVCRT__stat MSVCRT__stat64i32
+#define MSVCRT__stati64 MSVCRT__stat64
+#else
+#define MSVCRT__finddata_t MSVCRT__finddata32_t
+#define MSVCRT__finddatai64_t MSVCRT__finddata32i64_t
+#define MSVCRT__wfinddata_t MSVCRT__wfinddata32_t
+#define MSVCRT__wfinddatai64_t MSVCRT__wfinddata32i64_t
+#define MSVCRT__stat MSVCRT__stat32
+#define MSVCRT__stati64 MSVCRT__stat32i64
+#endif
+
+#define MSVCRT_WEOF (MSVCRT_wint_t)(0xFFFF)
+#define MSVCRT_EOF (-1)
+#define MSVCRT_TMP_MAX 0x7fff
+#define MSVCRT_TMP_MAX_S 0x7fffffff
+#define MSVCRT_RAND_MAX 0x7fff
+#define MSVCRT_BUFSIZ 512
+
+#define MSVCRT_SEEK_SET 0
+#define MSVCRT_SEEK_CUR 1
+#define MSVCRT_SEEK_END 2
+
+#define MSVCRT_NO_CONSOLE_FD (-2)
+#define MSVCRT_NO_CONSOLE ((HANDLE)MSVCRT_NO_CONSOLE_FD)
+
+#define MSVCRT_STDIN_FILENO 0
+#define MSVCRT_STDOUT_FILENO 1
+#define MSVCRT_STDERR_FILENO 2
+
+/* more file._flag flags, but these conflict with Unix */
+#define MSVCRT__IOFBF 0x0000
+#define MSVCRT__IONBF 0x0004
+#define MSVCRT__IOLBF 0x0040
+
+#define MSVCRT_FILENAME_MAX 260
+#define MSVCRT_DRIVE_MAX 3
+#define MSVCRT_FNAME_MAX 256
+#define MSVCRT_DIR_MAX 256
+#define MSVCRT_EXT_MAX 256
+#define MSVCRT_PATH_MAX 260
+#define MSVCRT_stdin (MSVCRT__iob+MSVCRT_STDIN_FILENO)
+#define MSVCRT_stdout (MSVCRT__iob+MSVCRT_STDOUT_FILENO)
+#define MSVCRT_stderr (MSVCRT__iob+MSVCRT_STDERR_FILENO)
+
+#define MSVCRT__P_WAIT 0
+#define MSVCRT__P_NOWAIT 1
+#define MSVCRT__P_OVERLAY 2
+#define MSVCRT__P_NOWAITO 3
+#define MSVCRT__P_DETACH 4
+
+#define MSVCRT_EPERM 1
+#define MSVCRT_ENOENT 2
+#define MSVCRT_ESRCH 3
+#define MSVCRT_EINTR 4
+#define MSVCRT_EIO 5
+#define MSVCRT_ENXIO 6
+#define MSVCRT_E2BIG 7
+#define MSVCRT_ENOEXEC 8
+#define MSVCRT_EBADF 9
+#define MSVCRT_ECHILD 10
+#define MSVCRT_EAGAIN 11
+#define MSVCRT_ENOMEM 12
+#define MSVCRT_EACCES 13
+#define MSVCRT_EFAULT 14
+#define MSVCRT_EBUSY 16
+#define MSVCRT_EEXIST 17
+#define MSVCRT_EXDEV 18
+#define MSVCRT_ENODEV 19
+#define MSVCRT_ENOTDIR 20
+#define MSVCRT_EISDIR 21
+#define MSVCRT_EINVAL 22
+#define MSVCRT_ENFILE 23
+#define MSVCRT_EMFILE 24
+#define MSVCRT_ENOTTY 25
+#define MSVCRT_EFBIG 27
+#define MSVCRT_ENOSPC 28
+#define MSVCRT_ESPIPE 29
+#define MSVCRT_EROFS 30
+#define MSVCRT_EMLINK 31
+#define MSVCRT_EPIPE 32
+#define MSVCRT_EDOM 33
+#define MSVCRT_ERANGE 34
+#define MSVCRT_EDEADLK 36
+#define MSVCRT_EDEADLOCK MSVCRT_EDEADLK
+#define MSVCRT_ENAMETOOLONG 38
+#define MSVCRT_ENOLCK 39
+#define MSVCRT_ENOSYS 40
+#define MSVCRT_ENOTEMPTY 41
+#define MSVCRT_EILSEQ 42
+#define MSVCRT_STRUNCATE 80
+
+#define MSVCRT_LC_ALL 0
+#define MSVCRT_LC_COLLATE 1
+#define MSVCRT_LC_CTYPE 2
+#define MSVCRT_LC_MONETARY 3
+#define MSVCRT_LC_NUMERIC 4
+#define MSVCRT_LC_TIME 5
+#define MSVCRT_LC_MIN MSVCRT_LC_ALL
+#define MSVCRT_LC_MAX MSVCRT_LC_TIME
+
+#define MSVCRT__HEAPEMPTY -1
+#define MSVCRT__HEAPOK -2
+#define MSVCRT__HEAPBADBEGIN -3
+#define MSVCRT__HEAPBADNODE -4
+#define MSVCRT__HEAPEND -5
+#define MSVCRT__HEAPBADPTR -6
+
+#define MSVCRT__FREEENTRY 0
+#define MSVCRT__USEDENTRY 1
+
+#define MSVCRT__OUT_TO_DEFAULT 0
+#define MSVCRT__OUT_TO_STDERR 1
+#define MSVCRT__OUT_TO_MSGBOX 2
+#define MSVCRT__REPORT_ERRMODE 3
+
+/* ASCII char classification table - binary compatible */
+#define MSVCRT__UPPER 0x0001 /* C1_UPPER */
+#define MSVCRT__LOWER 0x0002 /* C1_LOWER */
+#define MSVCRT__DIGIT 0x0004 /* C1_DIGIT */
+#define MSVCRT__SPACE 0x0008 /* C1_SPACE */
+#define MSVCRT__PUNCT 0x0010 /* C1_PUNCT */
+#define MSVCRT__CONTROL 0x0020 /* C1_CNTRL */
+#define MSVCRT__BLANK 0x0040 /* C1_BLANK */
+#define MSVCRT__HEX 0x0080 /* C1_XDIGIT */
+#define MSVCRT__LEADBYTE 0x8000
+#define MSVCRT__ALPHA (0x0100|MSVCRT__UPPER|MSVCRT__LOWER) /* (C1_ALPHA|_UPPER|_LOWER) */
+
+#define MSVCRT__IOREAD 0x0001
+#define MSVCRT__IOWRT 0x0002
+#define MSVCRT__IOMYBUF 0x0008
+#define MSVCRT__IOEOF 0x0010
+#define MSVCRT__IOERR 0x0020
+#define MSVCRT__IOSTRG 0x0040
+#define MSVCRT__IORW 0x0080
+#define MSVCRT__USERBUF 0x0100
+#define MSVCRT__IOCOMMIT 0x4000
+
+#define MSVCRT__S_IEXEC 0x0040
+#define MSVCRT__S_IWRITE 0x0080
+#define MSVCRT__S_IREAD 0x0100
+#define MSVCRT__S_IFIFO 0x1000
+#define MSVCRT__S_IFCHR 0x2000
+#define MSVCRT__S_IFDIR 0x4000
+#define MSVCRT__S_IFREG 0x8000
+#define MSVCRT__S_IFMT 0xF000
+
+#define MSVCRT__LK_UNLCK 0
+#define MSVCRT__LK_LOCK 1
+#define MSVCRT__LK_NBLCK 2
+#define MSVCRT__LK_RLCK 3
+#define MSVCRT__LK_NBRLCK 4
+
+#define MSVCRT__SH_COMPAT 0x00 /* Compatibility */
+#define MSVCRT__SH_DENYRW 0x10 /* Deny read/write */
+#define MSVCRT__SH_DENYWR 0x20 /* Deny write */
+#define MSVCRT__SH_DENYRD 0x30 /* Deny read */
+#define MSVCRT__SH_DENYNO 0x40 /* Deny nothing */
+
+#define MSVCRT__O_RDONLY 0
+#define MSVCRT__O_WRONLY 1
+#define MSVCRT__O_RDWR 2
+#define MSVCRT__O_ACCMODE (MSVCRT__O_RDONLY|MSVCRT__O_WRONLY|MSVCRT__O_RDWR)
+#define MSVCRT__O_APPEND 0x0008
+#define MSVCRT__O_RANDOM 0x0010
+#define MSVCRT__O_SEQUENTIAL 0x0020
+#define MSVCRT__O_TEMPORARY 0x0040
+#define MSVCRT__O_NOINHERIT 0x0080
+#define MSVCRT__O_CREAT 0x0100
+#define MSVCRT__O_TRUNC 0x0200
+#define MSVCRT__O_EXCL 0x0400
+#define MSVCRT__O_SHORT_LIVED 0x1000
+#define MSVCRT__O_TEXT 0x4000
+#define MSVCRT__O_BINARY 0x8000
+#define MSVCRT__O_RAW MSVCRT__O_BINARY
+#define MSVCRT__O_WTEXT 0x10000
+#define MSVCRT__O_U16TEXT 0x20000
+#define MSVCRT__O_U8TEXT 0x40000
+
+/* _statusfp bit flags */
+#define MSVCRT__SW_INEXACT 0x00000001 /* inexact (precision) */
+#define MSVCRT__SW_UNDERFLOW 0x00000002 /* underflow */
+#define MSVCRT__SW_OVERFLOW 0x00000004 /* overflow */
+#define MSVCRT__SW_ZERODIVIDE 0x00000008 /* zero divide */
+#define MSVCRT__SW_INVALID 0x00000010 /* invalid */
+
+#define MSVCRT__SW_UNEMULATED 0x00000040 /* unemulated instruction */
+#define MSVCRT__SW_SQRTNEG 0x00000080 /* square root of a neg number */
+#define MSVCRT__SW_STACKOVERFLOW 0x00000200 /* FP stack overflow */
+#define MSVCRT__SW_STACKUNDERFLOW 0x00000400 /* FP stack underflow */
+
+#define MSVCRT__SW_DENORMAL 0x00080000 /* denormal status bit */
+
+/* fpclass constants */
+#define MSVCRT__FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
+#define MSVCRT__FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
+#define MSVCRT__FPCLASS_NINF 0x0004 /* Negative Infinity */
+#define MSVCRT__FPCLASS_NN 0x0008 /* Negative Normal */
+#define MSVCRT__FPCLASS_ND 0x0010 /* Negative Denormal */
+#define MSVCRT__FPCLASS_NZ 0x0020 /* Negative Zero */
+#define MSVCRT__FPCLASS_PZ 0x0040 /* Positive Zero */
+#define MSVCRT__FPCLASS_PD 0x0080 /* Positive Denormal */
+#define MSVCRT__FPCLASS_PN 0x0100 /* Positive Normal */
+#define MSVCRT__FPCLASS_PINF 0x0200 /* Positive Infinity */
+
+/* fpclassify constants */
+#define MSVCRT_FP_INFINITE 1
+#define MSVCRT_FP_NAN 2
+#define MSVCRT_FP_NORMAL -1
+#define MSVCRT_FP_SUBNORMAL -2
+#define MSVCRT_FP_ZERO 0
+
+#define MSVCRT__MCW_EM 0x0008001f
+#define MSVCRT__MCW_IC 0x00040000
+#define MSVCRT__MCW_RC 0x00000300
+#define MSVCRT__MCW_PC 0x00030000
+#define MSVCRT__MCW_DN 0x03000000
+
+#define MSVCRT__EM_INVALID 0x00000010
+#define MSVCRT__EM_DENORMAL 0x00080000
+#define MSVCRT__EM_ZERODIVIDE 0x00000008
+#define MSVCRT__EM_OVERFLOW 0x00000004
+#define MSVCRT__EM_UNDERFLOW 0x00000002
+#define MSVCRT__EM_INEXACT 0x00000001
+#define MSVCRT__IC_AFFINE 0x00040000
+#define MSVCRT__IC_PROJECTIVE 0x00000000
+#define MSVCRT__RC_CHOP 0x00000300
+#define MSVCRT__RC_UP 0x00000200
+#define MSVCRT__RC_DOWN 0x00000100
+#define MSVCRT__RC_NEAR 0x00000000
+#define MSVCRT__PC_24 0x00020000
+#define MSVCRT__PC_53 0x00010000
+#define MSVCRT__PC_64 0x00000000
+#define MSVCRT__DN_SAVE 0x00000000
+#define MSVCRT__DN_FLUSH 0x01000000
+#define MSVCRT__DN_FLUSH_OPERANDS_SAVE_RESULTS 0x02000000
+#define MSVCRT__DN_SAVE_OPERANDS_FLUSH_RESULTS 0x03000000
+#define MSVCRT__EM_AMBIGUOUS 0x80000000
+
+typedef struct
+{
+ unsigned int control;
+ unsigned int status;
+} MSVCRT_fenv_t;
+
+#define MSVCRT_CLOCKS_PER_SEC 1000
+
+/* signals */
+#define MSVCRT_SIGINT 2
+#define MSVCRT_SIGILL 4
+#define MSVCRT_SIGFPE 8
+#define MSVCRT_SIGSEGV 11
+#define MSVCRT_SIGTERM 15
+#define MSVCRT_SIGBREAK 21
+#define MSVCRT_SIGABRT 22
+#define MSVCRT_NSIG (MSVCRT_SIGABRT + 1)
+
+typedef void (__cdecl *MSVCRT___sighandler_t)(int);
+
+#define MSVCRT_SIG_DFL ((MSVCRT___sighandler_t)0)
+#define MSVCRT_SIG_IGN ((MSVCRT___sighandler_t)1)
+#define MSVCRT_SIG_ERR ((MSVCRT___sighandler_t)-1)
+
+#define MSVCRT__FPE_INVALID 0x81
+#define MSVCRT__FPE_DENORMAL 0x82
+#define MSVCRT__FPE_ZERODIVIDE 0x83
+#define MSVCRT__FPE_OVERFLOW 0x84
+#define MSVCRT__FPE_UNDERFLOW 0x85
+#define MSVCRT__FPE_INEXACT 0x86
+#define MSVCRT__FPE_UNEMULATED 0x87
+#define MSVCRT__FPE_SQRTNEG 0x88
+#define MSVCRT__FPE_STACKOVERFLOW 0x8a
+#define MSVCRT__FPE_STACKUNDERFLOW 0x8b
+#define MSVCRT__FPE_EXPLICITGEN 0x8c
+
+#define _MS 0x01
+#define _MP 0x02
+#define _M1 0x04
+#define _M2 0x08
+
+#define _SBUP 0x10
+#define _SBLOW 0x20
+
+#define _MBC_SINGLE 0
+#define _MBC_LEAD 1
+#define _MBC_TRAIL 2
+#define _MBC_ILLEGAL -1
+
+#define _MB_CP_SBCS 0
+#define _MB_CP_OEM -2
+#define _MB_CP_ANSI -3
+#define _MB_CP_LOCALE -4
+
+#define MSVCRT__TRUNCATE ((MSVCRT_size_t)-1)
+
+#define _MAX__TIME64_T (((MSVCRT___time64_t)0x00000007 << 32) | 0x93406FFF)
+
+/* _set_abort_behavior codes */
+#define MSVCRT__WRITE_ABORT_MSG 1
+#define MSVCRT__CALL_REPORTFAULT 2
+
+/* _get_output_format return code */
+#define MSVCRT__TWO_DIGIT_EXPONENT 0x1
+
+#define MSVCRT__NLSCMPERROR ((unsigned int)0x7fffffff)
+
+void __cdecl MSVCRT_free(void*);
+void* __cdecl MSVCRT_malloc(MSVCRT_size_t);
+void* __cdecl MSVCRT_calloc(MSVCRT_size_t,MSVCRT_size_t);
+void* __cdecl MSVCRT_realloc(void*,MSVCRT_size_t);
+
+int __cdecl MSVCRT_iswalpha(MSVCRT_wint_t);
+int __cdecl MSVCRT_iswspace(MSVCRT_wint_t);
+int __cdecl MSVCRT_iswdigit(MSVCRT_wint_t);
+int __cdecl MSVCRT_isleadbyte(int);
+int __cdecl MSVCRT__isleadbyte_l(int, MSVCRT__locale_t);
+int __cdecl MSVCRT__isspace_l(int, MSVCRT__locale_t);
+int __cdecl MSVCRT__iswspace_l(MSVCRT_wchar_t, MSVCRT__locale_t);
+
+void __cdecl MSVCRT__lock_file(MSVCRT_FILE*);
+void __cdecl MSVCRT__unlock_file(MSVCRT_FILE*);
+int __cdecl MSVCRT_fgetc(MSVCRT_FILE*);
+int __cdecl MSVCRT__fgetc_nolock(MSVCRT_FILE*);
+int __cdecl MSVCRT__fputc_nolock(int,MSVCRT_FILE*);
+int __cdecl MSVCRT_ungetc(int,MSVCRT_FILE*);
+int __cdecl MSVCRT__ungetc_nolock(int,MSVCRT_FILE*);
+MSVCRT_wint_t __cdecl MSVCRT_fgetwc(MSVCRT_FILE*);
+MSVCRT_wint_t __cdecl MSVCRT__fgetwc_nolock(MSVCRT_FILE*);
+MSVCRT_wint_t __cdecl MSVCRT__fputwc_nolock(MSVCRT_wint_t,MSVCRT_FILE*);
+MSVCRT_wint_t __cdecl MSVCRT_ungetwc(MSVCRT_wint_t,MSVCRT_FILE*);
+MSVCRT_wint_t __cdecl MSVCRT__ungetwc_nolock(MSVCRT_wint_t, MSVCRT_FILE*);
+int __cdecl MSVCRT__fseeki64_nolock(MSVCRT_FILE*,__int64,int);
+__int64 __cdecl MSVCRT__ftelli64(MSVCRT_FILE* file);
+__int64 __cdecl MSVCRT__ftelli64_nolock(MSVCRT_FILE*);
+void __cdecl MSVCRT__exit(int);
+void __cdecl MSVCRT_abort(void);
+MSVCRT_ulong* __cdecl MSVCRT___doserrno(void);
+int* __cdecl MSVCRT__errno(void);
+char* __cdecl MSVCRT_getenv(const char*);
+MSVCRT_size_t __cdecl MSVCRT__fread_nolock(void*,MSVCRT_size_t,MSVCRT_size_t,MSVCRT_FILE*);
+MSVCRT_size_t __cdecl MSVCRT__fread_nolock_s(void*,MSVCRT_size_t,MSVCRT_size_t,MSVCRT_size_t,MSVCRT_FILE*);
+MSVCRT_size_t __cdecl MSVCRT__fwrite_nolock(const void*,MSVCRT_size_t,MSVCRT_size_t,MSVCRT_FILE*);
+int __cdecl MSVCRT_fclose(MSVCRT_FILE*);
+int __cdecl MSVCRT__fclose_nolock(MSVCRT_FILE*);
+int __cdecl MSVCRT__fflush_nolock(MSVCRT_FILE*);
+void __cdecl MSVCRT_terminate(void);
+MSVCRT_FILE* __cdecl MSVCRT__iob_func(void);
+MSVCRT_clock_t __cdecl MSVCRT_clock(void);
+MSVCRT___time32_t __cdecl MSVCRT__time32(MSVCRT___time32_t*);
+MSVCRT___time64_t __cdecl MSVCRT__time64(MSVCRT___time64_t*);
+MSVCRT_FILE* __cdecl MSVCRT__fdopen(int, const char *);
+MSVCRT_FILE* __cdecl MSVCRT__wfdopen(int, const MSVCRT_wchar_t *);
+int __cdecl MSVCRT_vsnprintf(char *str, MSVCRT_size_t len, const char *format, __ms_va_list valist);
+int __cdecl MSVCRT_vsnwprintf(MSVCRT_wchar_t *str, MSVCRT_size_t len,
+ const MSVCRT_wchar_t *format, __ms_va_list valist );
+int WINAPIV MSVCRT__snwprintf(MSVCRT_wchar_t*, unsigned int, const MSVCRT_wchar_t*, ...);
+int WINAPIV MSVCRT_sprintf(char*,const char*,...);
+int WINAPIV MSVCRT__snprintf(char*,unsigned int,const char*,...);
+int WINAPIV MSVCRT__scprintf(const char*,...);
+int __cdecl MSVCRT_raise(int sig);
+int __cdecl MSVCRT__set_printf_count_output(int);
+
+#define MSVCRT__ENABLE_PER_THREAD_LOCALE 1
+#define MSVCRT__DISABLE_PER_THREAD_LOCALE 2
+
+extern MSVCRT__locale_t MSVCRT_locale;
+MSVCRT_pthreadlocinfo get_locinfo(void) DECLSPEC_HIDDEN;
+MSVCRT_pthreadmbcinfo get_mbcinfo(void) DECLSPEC_HIDDEN;
+void __cdecl MSVCRT__free_locale(MSVCRT__locale_t);
+void free_locinfo(MSVCRT_pthreadlocinfo) DECLSPEC_HIDDEN;
+void free_mbcinfo(MSVCRT_pthreadmbcinfo) DECLSPEC_HIDDEN;
+int _setmbcp_l(int, LCID, MSVCRT_pthreadmbcinfo) DECLSPEC_HIDDEN;
+
+#ifndef __WINE_MSVCRT_TEST
+int __cdecl MSVCRT__write(int,const void*,unsigned int);
+int __cdecl _getch(void);
+int __cdecl _ismbblead(unsigned int);
+int __cdecl _ismbblead_l(unsigned int, MSVCRT__locale_t);
+int __cdecl _ismbclegal(unsigned int c);
+int __cdecl _ismbstrail(const unsigned char* start, const unsigned char* str);
+int __cdecl MSVCRT_mbtowc(MSVCRT_wchar_t*,const char*,MSVCRT_size_t);
+int __cdecl MSVCRT_mbtowc_l(MSVCRT_wchar_t*,const char*,MSVCRT_size_t,MSVCRT__locale_t);
+MSVCRT_size_t __cdecl MSVCRT_mbstowcs(MSVCRT_wchar_t*,const char*,MSVCRT_size_t);
+MSVCRT_size_t __cdecl MSVCRT__mbstowcs_l(MSVCRT_wchar_t*, const char*, MSVCRT_size_t, MSVCRT__locale_t);
+int __cdecl MSVCRT__mbstowcs_s_l(MSVCRT_size_t*, MSVCRT_wchar_t*,
+ MSVCRT_size_t, const char*, MSVCRT_size_t, MSVCRT__locale_t);
+MSVCRT_size_t __cdecl MSVCRT_wcstombs(char*,const MSVCRT_wchar_t*,MSVCRT_size_t);
+MSVCRT_size_t __cdecl MSVCRT__wcstombs_l(char*, const MSVCRT_wchar_t*, MSVCRT_size_t, MSVCRT__locale_t);
+MSVCRT_intptr_t __cdecl MSVCRT__spawnve(int,const char*,const char* const *,const char* const *);
+MSVCRT_intptr_t __cdecl MSVRT__spawnvpe(int,const char*,const char* const *,const char* const *);
+MSVCRT_intptr_t __cdecl MSVCRT__wspawnve(int,const MSVCRT_wchar_t*,const MSVCRT_wchar_t* const *,const MSVCRT_wchar_t* const *);
+MSVCRT_intptr_t __cdecl MSVCRT__wspawnvpe(int,const MSVCRT_wchar_t*,const MSVCRT_wchar_t* const *,const MSVCRT_wchar_t* const *);
+void __cdecl MSVCRT__searchenv(const char*,const char*,char*);
+int __cdecl MSVCRT__getdrive(void);
+char* __cdecl MSVCRT__strdup(const char*);
+char* __cdecl MSVCRT__strnset(char*,int,MSVCRT_size_t);
+char* __cdecl _strset(char*,int);
+int __cdecl _ungetch(int);
+int __cdecl _cputs(const char*);
+int WINAPIV _cprintf(const char*,...);
+int WINAPIV _cwprintf(const MSVCRT_wchar_t*,...);
+char*** __cdecl MSVCRT___p__environ(void);
+int* __cdecl __p___mb_cur_max(void);
+int* __cdecl MSVCRT___p__fmode(void);
+MSVCRT_wchar_t* __cdecl MSVCRT__wcsdup(const MSVCRT_wchar_t*);
+MSVCRT_size_t __cdecl MSVCRT_strnlen(const char *,MSVCRT_size_t);
+MSVCRT_size_t __cdecl MSVCRT_wcsnlen(const MSVCRT_wchar_t*,MSVCRT_size_t);
+MSVCRT_wchar_t*** __cdecl MSVCRT___p__wenviron(void);
+INT __cdecl MSVCRT_wctomb(char*,MSVCRT_wchar_t);
+int __cdecl MSVCRT__wctomb_l(char*, MSVCRT_wchar_t, MSVCRT__locale_t);
+char* __cdecl MSVCRT__strdate(char* date);
+char* __cdecl MSVCRT__strtime(char* date);
+int __cdecl _setmbcp(int);
+int __cdecl MSVCRT__close(int);
+int __cdecl MSVCRT__dup(int);
+int __cdecl MSVCRT__dup2(int, int);
+int __cdecl MSVCRT__pipe(int *, unsigned int, int);
+MSVCRT_wchar_t* __cdecl MSVCRT__wgetenv(const MSVCRT_wchar_t*);
+void __cdecl MSVCRT__wsearchenv(const MSVCRT_wchar_t*, const MSVCRT_wchar_t*, MSVCRT_wchar_t*);
+MSVCRT_intptr_t __cdecl MSVCRT__spawnvpe(int, const char*, const char* const*, const char* const*);
+void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_wchar_t *func,
+ const MSVCRT_wchar_t *file, unsigned int line, MSVCRT_uintptr_t arg);
+int __cdecl MSVCRT__toupper_l(int,MSVCRT__locale_t);
+int __cdecl MSVCRT__tolower_l(int,MSVCRT__locale_t);
+int __cdecl MSVCRT__towupper_l(MSVCRT_wint_t,MSVCRT__locale_t);
+int __cdecl MSVCRT__towlower_l(MSVCRT_wint_t,MSVCRT__locale_t);
+int __cdecl MSVCRT__toupper(int); /* only use on lower-case ASCII characters */
+int __cdecl MSVCRT__stricmp(const char*, const char*);
+int __cdecl MSVCRT__strnicmp(const char*, const char*, MSVCRT_size_t);
+int __cdecl MSVCRT__strnicoll_l(const char*, const char*, MSVCRT_size_t, MSVCRT__locale_t);
+int __cdecl MSVCRT__strncoll_l(const char*, const char*, MSVCRT_size_t, MSVCRT__locale_t);
+int __cdecl MSVCRT_strncmp(const char*, const char*, MSVCRT_size_t);
+int __cdecl MSVCRT_strcmp(const char*, const char*);
+char* __cdecl MSVCRT_strstr(const char*, const char*);
+unsigned int __cdecl MSVCRT__get_output_format(void);
+char* __cdecl MSVCRT_strtok_s(char*, const char*, char**);
+double parse_double(MSVCRT_wchar_t (*)(void*), void (*)(void*), void*, MSVCRT_pthreadlocinfo, int*);
+
+/* Maybe one day we'll enable the invalid parameter handlers with the full set of information (msvcrXXd)
+ * #define MSVCRT_INVALID_PMT(x) MSVCRT_call_invalid_parameter_handler(x, __FUNCTION__, __FILE__, __LINE__, 0)
+ * #define MSVCRT_CHECK_PMT(x) ((x) ? TRUE : MSVCRT_INVALID_PMT(#x),FALSE)
+ * Until this is done, just keep the same semantics for CHECK_PMT(), but without generating / sending
+ * any information
+ * NB : MSVCRT_call_invalid_parameter_handler is a wrapper around MSVCRT__invalid_parameter in order
+ * to do the Ansi to Unicode transformation
+ */
+#define MSVCRT_INVALID_PMT(x,err) (*MSVCRT__errno() = (err), MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0))
+#define MSVCRT_CHECK_PMT_ERR(x,err) ((x) || (MSVCRT_INVALID_PMT( 0, (err) ), FALSE))
+#define MSVCRT_CHECK_PMT(x) MSVCRT_CHECK_PMT_ERR((x), MSVCRT_EINVAL)
+#endif
+
+#define MSVCRT__ARGMAX 100
+typedef int (*puts_clbk_a)(void*, int, const char*);
+typedef int (*puts_clbk_w)(void*, int, const MSVCRT_wchar_t*);
+typedef union _printf_arg
+{
+ void *get_ptr;
+ int get_int;
+ LONGLONG get_longlong;
+ double get_double;
+} printf_arg;
+typedef printf_arg (*args_clbk)(void*, int, int, __ms_va_list*);
+int pf_printf_a(puts_clbk_a, void*, const char*, MSVCRT__locale_t,
+ DWORD, args_clbk, void*, __ms_va_list*) DECLSPEC_HIDDEN;
+int pf_printf_w(puts_clbk_w, void*, const MSVCRT_wchar_t*, MSVCRT__locale_t,
+ DWORD, args_clbk, void*, __ms_va_list*) DECLSPEC_HIDDEN;
+int create_positional_ctx_a(void*, const char*, __ms_va_list) DECLSPEC_HIDDEN;
+int create_positional_ctx_w(void*, const MSVCRT_wchar_t*, __ms_va_list) DECLSPEC_HIDDEN;
+printf_arg arg_clbk_valist(void*, int, int, __ms_va_list*) DECLSPEC_HIDDEN;
+printf_arg arg_clbk_positional(void*, int, int, __ms_va_list*) DECLSPEC_HIDDEN;
+
+#define MSVCRT_FLT_MIN 1.175494351e-38F
+#define MSVCRT_DBL_MIN 2.2250738585072014e-308
+#define MSVCRT__OVERFLOW 3
+#define MSVCRT__UNDERFLOW 4
+
+#define MSVCRT_FP_ILOGB0 (-MSVCRT_INT_MAX - 1)
+#define MSVCRT_FP_ILOGBNAN MSVCRT_INT_MAX
+
+typedef struct
+{
+ float f;
+} MSVCRT__CRT_FLOAT;
+
+typedef struct
+{
+ double x;
+} MSVCRT__CRT_DOUBLE;
+
+extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int);
+
+/* __unDName/__unDNameEx flags */
+#define UNDNAME_COMPLETE (0x0000)
+#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) /* Don't show __ in calling convention */
+#define UNDNAME_NO_MS_KEYWORDS (0x0002) /* Don't show calling convention at all */
+#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) /* Don't show function/method return value */
+#define UNDNAME_NO_ALLOCATION_MODEL (0x0008)
+#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010)
+#define UNDNAME_NO_MS_THISTYPE (0x0020)
+#define UNDNAME_NO_CV_THISTYPE (0x0040)
+#define UNDNAME_NO_THISTYPE (0x0060)
+#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) /* Don't show access specifier (public/protected/private) */
+#define UNDNAME_NO_THROW_SIGNATURES (0x0100)
+#define UNDNAME_NO_MEMBER_TYPE (0x0200) /* Don't show static/virtual specifier */
+#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400)
+#define UNDNAME_32_BIT_DECODE (0x0800)
+#define UNDNAME_NAME_ONLY (0x1000) /* Only report the variable/method name */
+#define UNDNAME_NO_ARGUMENTS (0x2000) /* Don't show method arguments */
+#define UNDNAME_NO_SPECIAL_SYMS (0x4000)
+#define UNDNAME_NO_COMPLEX_TYPE (0x8000)
+
+#define UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION (0x0001)
+#define UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR (0x0002)
+#define UCRTBASE_PRINTF_LEGACY_WIDE_SPECIFIERS (0x0004)
+#define UCRTBASE_PRINTF_LEGACY_MSVCRT_COMPATIBILITY (0x0008)
+#define UCRTBASE_PRINTF_LEGACY_THREE_DIGIT_EXPONENTS (0x0010)
+
+#define UCRTBASE_PRINTF_MASK (0x001F)
+
+#define MSVCRT_PRINTF_POSITIONAL_PARAMS (0x0100)
+#define MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER (0x0200)
+
+#define UCRTBASE_SCANF_SECURECRT (0x0001)
+#define UCRTBASE_SCANF_LEGACY_WIDE_SPECIFIERS (0x0002)
+#define UCRTBASE_SCANF_LEGACY_MSVCRT_COMPATIBILITY (0x0004)
+
+#define UCRTBASE_SCANF_MASK (0x0007)
+
+#define COOPERATIVE_TIMEOUT_INFINITE ((unsigned int)-1)
+#define COOPERATIVE_WAIT_TIMEOUT ~0
+
+typedef enum {
+ _FpCodeUnspecified,
+ _FpCodeAdd,
+ _FpCodeSubtract,
+ _FpCodeMultiply,
+ _FpCodeDivide,
+ _FpCodeSquareRoot,
+ _FpCodeRemainder,
+ _FpCodeCompare,
+ _FpCodeConvert,
+ _FpCodeRound,
+ _FpCodeTruncate,
+ _FpCodeFloor,
+ _FpCodeCeil,
+ _FpCodeAcos,
+ _FpCodeAsin,
+ _FpCodeAtan,
+ _FpCodeAtan2,
+ _FpCodeCabs,
+ _FpCodeCos,
+ _FpCodeCosh,
+ _FpCodeExp,
+ _FpCodeFabs,
+ _FpCodeFmod,
+ _FpCodeFrexp,
+ _FpCodeHypot,
+ _FpCodeLdexp,
+ _FpCodeLog,
+ _FpCodeLog10,
+ _FpCodeModf,
+ _FpCodePow,
+ _FpCodeSin,
+ _FpCodeSinh,
+ _FpCodeTan,
+ _FpCodeTanh,
+ _FpCodeY0,
+ _FpCodeY1,
+ _FpCodeYn,
+ _FpCodeLogb,
+ _FpCodeNextafter,
+ _FpCodeNegate,
+ _FpCodeFmin,
+ _FpCodeFmax,
+ _FpCodeConvertTrunc,
+ _XMMIAddps,
+ _XMMIAddss,
+ _XMMISubps,
+ _XMMISubss,
+ _XMMIMulps,
+ _XMMIMulss,
+ _XMMIDivps,
+ _XMMIDivss,
+ _XMMISqrtps,
+ _XMMISqrtss,
+ _XMMIMaxps,
+ _XMMIMaxss,
+ _XMMIMinps,
+ _XMMIMinss,
+ _XMMICmpps,
+ _XMMICmpss,
+ _XMMIComiss,
+ _XMMIUComiss,
+ _XMMICvtpi2ps,
+ _XMMICvtsi2ss,
+ _XMMICvtps2pi,
+ _XMMICvtss2si,
+ _XMMICvttps2pi,
+ _XMMICvttss2si,
+ _XMMIAddsubps,
+ _XMMIHaddps,
+ _XMMIHsubps,
+ _XMMI2Addpd,
+ _XMMI2Addsd,
+ _XMMI2Subpd,
+ _XMMI2Subsd,
+ _XMMI2Mulpd,
+ _XMMI2Mulsd,
+ _XMMI2Divpd,
+ _XMMI2Divsd,
+ _XMMI2Sqrtpd,
+ _XMMI2Sqrtsd,
+ _XMMI2Maxpd,
+ _XMMI2Maxsd,
+ _XMMI2Minpd,
+ _XMMI2Minsd,
+ _XMMI2Cmppd,
+ _XMMI2Cmpsd,
+ _XMMI2Comisd,
+ _XMMI2UComisd,
+ _XMMI2Cvtpd2pi,
+ _XMMI2Cvtsd2si,
+ _XMMI2Cvttpd2pi,
+ _XMMI2Cvttsd2si,
+ _XMMI2Cvtps2pd,
+ _XMMI2Cvtss2sd,
+ _XMMI2Cvtpd2ps,
+ _XMMI2Cvtsd2ss,
+ _XMMI2Cvtdq2ps,
+ _XMMI2Cvttps2dq,
+ _XMMI2Cvtps2dq,
+ _XMMI2Cvttpd2dq,
+ _XMMI2Cvtpd2dq,
+ _XMMI2Addsubpd,
+ _XMMI2Haddpd,
+ _XMMI2Hsubpd,
+} _FP_OPERATION_CODE;
+
+typedef enum {
+ _FpFormatFp32,
+ _FpFormatFp64,
+ _FpFormatFp80,
+ _FpFormatFp128,
+ _FpFormatI16,
+ _FpFormatI32,
+ _FpFormatI64,
+ _FpFormatU16,
+ _FpFormatU32,
+ _FpFormatU64,
+ _FpFormatBcd80,
+ _FpFormatCompare,
+ _FpFormatString,
+} _FPIEEE_FORMAT;
+
+typedef float _FP32;
+typedef double _FP64;
+typedef short _I16;
+typedef int _I32;
+typedef unsigned short _U16;
+typedef unsigned int _U32;
+typedef __int64 _Q64;
+
+typedef struct {
+ unsigned short W[5];
+} _FP80;
+
+typedef struct DECLSPEC_ALIGN(16) {
+ MSVCRT_ulong W[4];
+} _FP128;
+
+typedef struct DECLSPEC_ALIGN(8) {
+ MSVCRT_ulong W[2];
+} _I64;
+
+typedef struct DECLSPEC_ALIGN(8) {
+ MSVCRT_ulong W[2];
+} _U64;
+
+typedef struct {
+ unsigned short W[5];
+} _BCD80;
+
+typedef struct DECLSPEC_ALIGN(16) {
+ _Q64 W[2];
+} _FPQ64;
+
+typedef struct {
+ union {
+ _FP32 Fp32Value;
+ _FP64 Fp64Value;
+ _FP80 Fp80Value;
+ _FP128 Fp128Value;
+ _I16 I16Value;
+ _I32 I32Value;
+ _I64 I64Value;
+ _U16 U16Value;
+ _U32 U32Value;
+ _U64 U64Value;
+ _BCD80 Bcd80Value;
+ char *StringValue;
+ int CompareValue;
+ _Q64 Q64Value;
+ _FPQ64 Fpq64Value;
+ } Value;
+ unsigned int OperandValid : 1;
+ unsigned int Format : 4;
+} _FPIEEE_VALUE;
+
+typedef struct {
+ unsigned int Inexact : 1;
+ unsigned int Underflow : 1;
+ unsigned int Overflow : 1;
+ unsigned int ZeroDivide : 1;
+ unsigned int InvalidOperation : 1;
+} _FPIEEE_EXCEPTION_FLAGS;
+
+typedef struct {
+ unsigned int RoundingMode : 2;
+ unsigned int Precision : 3;
+ unsigned int Operation :12;
+ _FPIEEE_EXCEPTION_FLAGS Cause;
+ _FPIEEE_EXCEPTION_FLAGS Enable;
+ _FPIEEE_EXCEPTION_FLAGS Status;
+ _FPIEEE_VALUE Operand1;
+ _FPIEEE_VALUE Operand2;
+ _FPIEEE_VALUE Result;
+} _FPIEEE_RECORD, *_PFPIEEE_RECORD;
+
+#define INHERIT_THREAD_PRIORITY 0xF000
+
+#ifdef __REACTOS__
+#define __wine_longjmp longjmp
+#define __wine_jmp_buf _JBTYPE
+#endif
+
+#endif /* __WINE_MSVCRT_H */
diff --git a/sdk/lib/crt/wine/mtdll.h b/sdk/lib/crt/wine/mtdll.h
new file mode 100644
index 00000000000..c01beaff93c
--- /dev/null
+++ b/sdk/lib/crt/wine/mtdll.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002, TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef WINE_MTDLL_H
+#define WINE_MTDLL_H
+
+#if defined(_MT)
+
+#define _mlock(locknum) _lock(locknum)
+#define _munlock(locknum) _unlock(locknum)
+
+void __cdecl _unlock( int locknum );
+void __cdecl _lock( int locknum );
+
+#else
+
+#define _mlock(locknum) do {} while(0)
+#define _munlock(locknum) do {} while(0)
+
+#endif
+
+
+#define _SIGNAL_LOCK 1
+#define _IOB_SCAN_LOCK 2
+#define _TMPNAM_LOCK 3
+#define _INPUT_LOCK 4
+#define _OUTPUT_LOCK 5
+#define _CSCANF_LOCK 6
+#define _CPRINTF_LOCK 7
+#define _CONIO_LOCK 8
+#define _HEAP_LOCK 9
+#define _BHEAP_LOCK 10 /* No longer used? */
+#define _TIME_LOCK 11
+#define _ENV_LOCK 12
+#define _EXIT_LOCK1 13
+#define _EXIT_LOCK2 14
+#define _THREADDATA_LOCK 15 /* No longer used? */
+#define _POPEN_LOCK 16
+#define _LOCKTAB_LOCK 17
+#define _OSFHND_LOCK 18
+#define _SETLOCALE_LOCK 19
+#define _LC_COLLATE_LOCK 20 /* No longer used? */
+#define _LC_CTYPE_LOCK 21 /* No longer used? */
+#define _LC_MONETARY_LOCK 22 /* No longer used? */
+#define _LC_NUMERIC_LOCK 23 /* No longer used? */
+#define _LC_TIME_LOCK 24 /* No longer used? */
+#define _MB_CP_LOCK 25
+#define _NLG_LOCK 26
+#define _TYPEINFO_LOCK 27
+#define _STREAM_LOCKS 28
+
+/* Must match definition in msvcrt/stdio.h */
+#define _IOB_ENTRIES 20
+
+#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_IOB_ENTRIES-1)
+
+#define _TOTAL_LOCKS (_LAST_STREAM_LOCK+1)
+
+#endif /* WINE_MTDLL_H */
diff --git a/sdk/lib/crt/wine/winternl.h b/sdk/lib/crt/wine/winternl.h
new file mode 100644
index 00000000000..498c4367108
--- /dev/null
+++ b/sdk/lib/crt/wine/winternl.h
@@ -0,0 +1,313 @@
+/*
+ * Internal NT APIs and data structures
+ *
+ * Copyright (C) the Wine project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_WINTERNL_H
+#define __WINE_WINTERNL_H
+
+#ifndef __REACTOS__
+#include
+#endif /* __REACTOS__ */
+#include
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+#ifndef WINE_NTSTATUS_DECLARED
+#define WINE_NTSTATUS_DECLARED
+ typedef LONG NTSTATUS;
+#endif
+
+#ifndef __UNICODE_STRING_DEFINED__
+#define __UNICODE_STRING_DEFINED__
+ typedef struct _UNICODE_STRING {
+ USHORT Length; /* bytes */
+ USHORT MaximumLength; /* bytes */
+ PWSTR Buffer;
+ } UNICODE_STRING, * PUNICODE_STRING;
+#endif
+
+ typedef struct _CLIENT_ID
+ {
+ HANDLE UniqueProcess;
+ HANDLE UniqueThread;
+ } CLIENT_ID, * PCLIENT_ID;
+
+ typedef struct _CURDIR
+ {
+ UNICODE_STRING DosPath;
+ PVOID Handle;
+ } CURDIR, * PCURDIR;
+
+ typedef struct RTL_DRIVE_LETTER_CURDIR
+ {
+ USHORT Flags;
+ USHORT Length;
+ ULONG TimeStamp;
+ UNICODE_STRING DosPath;
+ } RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;
+
+ typedef struct tagRTL_BITMAP {
+ ULONG SizeOfBitMap; /* Number of bits in the bitmap */
+ PULONG Buffer; /* Bitmap data, assumed sized to a DWORD boundary */
+ } RTL_BITMAP, * PRTL_BITMAP;
+
+ typedef const RTL_BITMAP* PCRTL_BITMAP;
+
+ typedef struct _RTL_USER_PROCESS_PARAMETERS
+ {
+ ULONG AllocationSize;
+ ULONG Size;
+ ULONG Flags;
+ ULONG DebugFlags;
+ HANDLE ConsoleHandle;
+ ULONG ConsoleFlags;
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
+ CURDIR CurrentDirectory;
+ UNICODE_STRING DllPath;
+ UNICODE_STRING ImagePathName;
+ UNICODE_STRING CommandLine;
+ PWSTR Environment;
+ ULONG dwX;
+ ULONG dwY;
+ ULONG dwXSize;
+ ULONG dwYSize;
+ ULONG dwXCountChars;
+ ULONG dwYCountChars;
+ ULONG dwFillAttribute;
+ ULONG dwFlags;
+ ULONG wShowWindow;
+ UNICODE_STRING WindowTitle;
+ UNICODE_STRING Desktop;
+ UNICODE_STRING ShellInfo;
+ UNICODE_STRING RuntimeInfo;
+ RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
+ } RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
+
+ typedef struct _PEB_LDR_DATA
+ {
+ ULONG Length;
+ BOOLEAN Initialized;
+ PVOID SsHandle;
+ LIST_ENTRY InLoadOrderModuleList;
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+ PVOID EntryInProgress;
+ } PEB_LDR_DATA, * PPEB_LDR_DATA;
+
+ typedef struct _GDI_TEB_BATCH
+ {
+ ULONG Offset;
+ HANDLE HDC;
+ ULONG Buffer[0x136];
+ } GDI_TEB_BATCH;
+
+ typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME
+ {
+ struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
+ struct _ACTIVATION_CONTEXT* ActivationContext;
+ ULONG Flags;
+ } RTL_ACTIVATION_CONTEXT_STACK_FRAME, * PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
+
+ typedef struct _ACTIVATION_CONTEXT_STACK
+ {
+ ULONG Flags;
+ ULONG NextCookieSequenceNumber;
+ RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame;
+ LIST_ENTRY FrameListCache;
+ } ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK;
+
+ typedef struct _TEB_ACTIVE_FRAME_CONTEXT
+ {
+ ULONG Flags;
+ const char* FrameName;
+ } TEB_ACTIVE_FRAME_CONTEXT, * PTEB_ACTIVE_FRAME_CONTEXT;
+
+ typedef struct _TEB_ACTIVE_FRAME
+ {
+ ULONG Flags;
+ struct _TEB_ACTIVE_FRAME* Previous;
+ TEB_ACTIVE_FRAME_CONTEXT* Context;
+ } TEB_ACTIVE_FRAME, * PTEB_ACTIVE_FRAME;
+
+ typedef struct _PEB
+ { /* win32/win64 */
+ BOOLEAN InheritedAddressSpace; /* 000/000 */
+ BOOLEAN ReadImageFileExecOptions; /* 001/001 */
+ BOOLEAN BeingDebugged; /* 002/002 */
+ BOOLEAN SpareBool; /* 003/003 */
+ HANDLE Mutant; /* 004/008 */
+ HMODULE ImageBaseAddress; /* 008/010 */
+ PPEB_LDR_DATA LdrData; /* 00c/018 */
+ RTL_USER_PROCESS_PARAMETERS* ProcessParameters; /* 010/020 */
+ PVOID SubSystemData; /* 014/028 */
+ HANDLE ProcessHeap; /* 018/030 */
+ PRTL_CRITICAL_SECTION FastPebLock; /* 01c/038 */
+ PVOID /*PPEBLOCKROUTINE*/ FastPebLockRoutine; /* 020/040 */
+ PVOID /*PPEBLOCKROUTINE*/ FastPebUnlockRoutine; /* 024/048 */
+ ULONG EnvironmentUpdateCount; /* 028/050 */
+ PVOID KernelCallbackTable; /* 02c/058 */
+ ULONG Reserved[2]; /* 030/060 */
+ PVOID /*PPEB_FREE_BLOCK*/ FreeList; /* 038/068 */
+ ULONG TlsExpansionCounter; /* 03c/070 */
+ PRTL_BITMAP TlsBitmap; /* 040/078 */
+ ULONG TlsBitmapBits[2]; /* 044/080 */
+ PVOID ReadOnlySharedMemoryBase; /* 04c/088 */
+ PVOID ReadOnlySharedMemoryHeap; /* 050/090 */
+ PVOID* ReadOnlyStaticServerData; /* 054/098 */
+ PVOID AnsiCodePageData; /* 058/0a0 */
+ PVOID OemCodePageData; /* 05c/0a8 */
+ PVOID UnicodeCaseTableData; /* 060/0b0 */
+ ULONG NumberOfProcessors; /* 064/0b8 */
+ ULONG NtGlobalFlag; /* 068/0bc */
+ LARGE_INTEGER CriticalSectionTimeout; /* 070/0c0 */
+ SIZE_T HeapSegmentReserve; /* 078/0c8 */
+ SIZE_T HeapSegmentCommit; /* 07c/0d0 */
+ SIZE_T HeapDeCommitTotalFreeThreshold; /* 080/0d8 */
+ SIZE_T HeapDeCommitFreeBlockThreshold; /* 084/0e0 */
+ ULONG NumberOfHeaps; /* 088/0e8 */
+ ULONG MaximumNumberOfHeaps; /* 08c/0ec */
+ PVOID* ProcessHeaps; /* 090/0f0 */
+ PVOID GdiSharedHandleTable; /* 094/0f8 */
+ PVOID ProcessStarterHelper; /* 098/100 */
+ PVOID GdiDCAttributeList; /* 09c/108 */
+ PVOID LoaderLock; /* 0a0/110 */
+ ULONG OSMajorVersion; /* 0a4/118 */
+ ULONG OSMinorVersion; /* 0a8/11c */
+ ULONG OSBuildNumber; /* 0ac/120 */
+ ULONG OSPlatformId; /* 0b0/124 */
+ ULONG ImageSubSystem; /* 0b4/128 */
+ ULONG ImageSubSystemMajorVersion; /* 0b8/12c */
+ ULONG ImageSubSystemMinorVersion; /* 0bc/130 */
+ ULONG ImageProcessAffinityMask; /* 0c0/134 */
+ HANDLE GdiHandleBuffer[28]; /* 0c4/138 */
+ ULONG unknown[6]; /* 134/218 */
+ PVOID PostProcessInitRoutine; /* 14c/230 */
+ PRTL_BITMAP TlsExpansionBitmap; /* 150/238 */
+ ULONG TlsExpansionBitmapBits[32]; /* 154/240 */
+ ULONG SessionId; /* 1d4/2c0 */
+ ULARGE_INTEGER AppCompatFlags; /* 1d8/2c8 */
+ ULARGE_INTEGER AppCompatFlagsUser; /* 1e0/2d0 */
+ PVOID ShimData; /* 1e8/2d8 */
+ PVOID AppCompatInfo; /* 1ec/2e0 */
+ UNICODE_STRING CSDVersion; /* 1f0/2e8 */
+ PVOID ActivationContextData; /* 1f8/2f8 */
+ PVOID ProcessAssemblyStorageMap; /* 1fc/300 */
+ PVOID SystemDefaultActivationData; /* 200/308 */
+ PVOID SystemAssemblyStorageMap; /* 204/310 */
+ SIZE_T MinimumStackCommit; /* 208/318 */
+ PVOID* FlsCallback; /* 20c/320 */
+ LIST_ENTRY FlsListHead; /* 210/328 */
+ PRTL_BITMAP FlsBitmap; /* 218/338 */
+ ULONG FlsBitmapBits[4]; /* 21c/340 */
+ } PEB, * PPEB;
+
+ typedef struct _TEB
+ { /* win32/win64 */
+ NT_TIB Tib; /* 000/0000 */
+ PVOID EnvironmentPointer; /* 01c/0038 */
+ CLIENT_ID ClientId; /* 020/0040 */
+ PVOID ActiveRpcHandle; /* 028/0050 */
+ PVOID ThreadLocalStoragePointer; /* 02c/0058 */
+ PPEB Peb; /* 030/0060 */
+ ULONG LastErrorValue; /* 034/0068 */
+ ULONG CountOfOwnedCriticalSections; /* 038/006c */
+ PVOID CsrClientThread; /* 03c/0070 */
+ PVOID Win32ThreadInfo; /* 040/0078 */
+ ULONG Win32ClientInfo[31]; /* 044/0080 used for user32 private data in Wine */
+ PVOID WOW32Reserved; /* 0c0/0100 */
+ ULONG CurrentLocale; /* 0c4/0108 */
+ ULONG FpSoftwareStatusRegister; /* 0c8/010c */
+ PVOID SystemReserved1[54]; /* 0cc/0110 used for kernel32 private data in Wine */
+ LONG ExceptionCode; /* 1a4/02c0 */
+ ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 1a8/02c8 */
+ BYTE SpareBytes1[24]; /* 1bc/02e8 */
+ PVOID SystemReserved2[10]; /* 1d4/0300 used for ntdll platform-specific private data in Wine */
+ GDI_TEB_BATCH GdiTebBatch; /* 1fc/0350 used for ntdll private data in Wine */
+ HANDLE gdiRgn; /* 6dc/0838 */
+ HANDLE gdiPen; /* 6e0/0840 */
+ HANDLE gdiBrush; /* 6e4/0848 */
+ CLIENT_ID RealClientId; /* 6e8/0850 */
+ HANDLE GdiCachedProcessHandle; /* 6f0/0860 */
+ ULONG GdiClientPID; /* 6f4/0868 */
+ ULONG GdiClientTID; /* 6f8/086c */
+ PVOID GdiThreadLocaleInfo; /* 6fc/0870 */
+ ULONG UserReserved[5]; /* 700/0878 */
+ PVOID glDispatchTable[280]; /* 714/0890 */
+ PVOID glReserved1[26]; /* b74/1150 */
+ PVOID glReserved2; /* bdc/1220 */
+ PVOID glSectionInfo; /* be0/1228 */
+ PVOID glSection; /* be4/1230 */
+ PVOID glTable; /* be8/1238 */
+ PVOID glCurrentRC; /* bec/1240 */
+ PVOID glContext; /* bf0/1248 */
+ ULONG LastStatusValue; /* bf4/1250 */
+ UNICODE_STRING StaticUnicodeString; /* bf8/1258 used by advapi32 */
+ WCHAR StaticUnicodeBuffer[261]; /* c00/1268 used by advapi32 */
+ PVOID DeallocationStack; /* e0c/1478 */
+ PVOID TlsSlots[64]; /* e10/1480 */
+ LIST_ENTRY TlsLinks; /* f10/1680 */
+ PVOID Vdm; /* f18/1690 */
+ PVOID ReservedForNtRpc; /* f1c/1698 */
+ PVOID DbgSsReserved[2]; /* f20/16a0 */
+ ULONG HardErrorDisabled; /* f28/16b0 */
+ PVOID Instrumentation[16]; /* f2c/16b8 */
+ PVOID WinSockData; /* f6c/1738 */
+ ULONG GdiBatchCount; /* f70/1740 */
+ ULONG Spare2; /* f74/1744 */
+ ULONG GuaranteedStackBytes; /* f78/1748 */
+ PVOID ReservedForPerf; /* f7c/1750 */
+ PVOID ReservedForOle; /* f80/1758 */
+ ULONG WaitingOnLoaderLock; /* f84/1760 */
+ PVOID Reserved5[3]; /* f88/1768 */
+ PVOID* TlsExpansionSlots; /* f94/1780 */
+#ifdef _WIN64
+ PVOID DeallocationBStore; /* /1788 */
+ PVOID BStoreLimit; /* /1790 */
+#endif
+ ULONG ImpersonationLocale; /* f98/1798 */
+ ULONG IsImpersonating; /* f9c/179c */
+ PVOID NlsCache; /* fa0/17a0 */
+ PVOID ShimData; /* fa4/17a8 */
+ ULONG HeapVirtualAffinity; /* fa8/17b0 */
+ PVOID CurrentTransactionHandle; /* fac/17b8 */
+ TEB_ACTIVE_FRAME* ActiveFrame; /* fb0/17c0 */
+ PVOID* FlsSlots; /* fb4/17c8 */
+ } TEB, * PTEB;
+
+ NTSYSAPI PVOID WINAPI RtlAllocateHeap(HANDLE, ULONG, SIZE_T) __WINE_ALLOC_SIZE(3);
+ NTSYSAPI BOOLEAN WINAPI RtlAreBitsSet(PCRTL_BITMAP, ULONG, ULONG);
+ NTSYSAPI BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP, ULONG, ULONG);
+ NTSYSAPI BOOLEAN WINAPI RtlFreeHeap(HANDLE, ULONG, PVOID);
+ NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG);
+ NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG);
+
+#define ARRAY_SIZE ARRAYSIZE
+#define MSVCRT_free free
+#define MSVCRT_malloc malloc
+//#define MSVCRT_terminate terminate
+#define MSVCRT__exit exit
+#define MSVCRT_abort abort
+
+#endif /* __WINE_WINTERNL_H */