diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 4de2266fd58..76328ac188e 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -428,8 +428,8 @@ @ stub ?_inconsistency@@YAXXZ @ cdecl -arch=win32 ?_invalid_parameter@@YAXPBG00II@Z(wstr wstr wstr long long) msvcrt._invalid_parameter @ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter -@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *) -@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64) +@ cdecl -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof +@ cdecl -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof @ cdecl -arch=arm ?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z(ptr ptr) type_info_name_internal_method @ thiscall -arch=i386 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) type_info_name_internal_method @ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) type_info_name_internal_method diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index a656f4e0188..ba588f9f56b 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -710,8 +710,8 @@ @ stub ?_inconsistency@@YAXXZ @ cdecl -arch=win32 ?_invalid_parameter@@YAXPBG00II@Z(wstr wstr wstr long long) msvcrt._invalid_parameter @ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter -@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *) -@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64) +@ cdecl -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof +@ cdecl -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof @ cdecl -arch=arm ?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z(ptr ptr) msvcr100.?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z @ thiscall -arch=i386 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) msvcr100.?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z @ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) msvcr100.?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index db174f42925..11c4e2f6337 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -84,8 +84,8 @@ @ stub ?_inconsistency@@YAXXZ @ cdecl -arch=win32 ?_invalid_parameter@@YAXPBG00II@Z(wstr wstr wstr long long) msvcrt._invalid_parameter @ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter -@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *) -@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64) +@ cdecl -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof +@ cdecl -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof @ cdecl -arch=arm ?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z(ptr ptr) type_info_name_internal_method @ thiscall -arch=i386 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) type_info_name_internal_method @ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) type_info_name_internal_method diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 2b260e006f6..79a6e536896 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -84,8 +84,8 @@ @ stub ?_inconsistency@@YAXXZ @ cdecl -arch=win32 ?_invalid_parameter@@YAXPBG00II@Z(wstr wstr wstr long long) msvcrt._invalid_parameter @ cdecl -arch=win64 ?_invalid_parameter@@YAXPEBG00I_K@Z(wstr wstr wstr long long) msvcrt._invalid_parameter -@ stub -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const &,struct _EXCEPTION_POINTERS *) -@ stub -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z # int __cdecl _is_exception_typeof(class type_info const & __ptr64,struct _EXCEPTION_POINTERS * __ptr64) +@ cdecl -arch=win32 ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof +@ cdecl -arch=win64 ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z(ptr ptr) msvcrt._is_exception_typeof @ cdecl -arch=arm ?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z(ptr ptr) msvcr100.?_name_internal_method@type_info@@QBAPBDPAU__type_info_node@@@Z @ thiscall -arch=i386 ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z(ptr ptr) msvcr100.?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z @ cdecl -arch=win64 ?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z(ptr ptr) msvcr100.?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index a1b0f5f6efd..1c8da4ef3fe 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -133,7 +133,6 @@ typedef struct __type_info char mangled[16]; } type_info; - struct __type_info_node { void *memPtr; @@ -143,6 +142,76 @@ struct __type_info_node static char* (WINAPI *p_type_info_name_internal_method)(type_info*, struct __type_info_node *); static void (WINAPI *ptype_info_dtor)(type_info*); +#define CXX_FRAME_MAGIC_VC6 0x19930520 +#define CXX_EXCEPTION 0xe06d7363 + +/* offsets for computing the this pointer */ +typedef struct +{ + int this_offset; /* offset of base class this pointer from start of object */ + int vbase_descr; /* offset of virtual base class descriptor */ + int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ +} this_ptr_offsets; + +typedef void (*cxx_copy_ctor)(void); + +/* complete information about a C++ type */ +#ifndef __x86_64__ +typedef struct __cxx_type_info +{ + UINT flags; /* flags (see CLASS_* flags below) */ + 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 */ +} cxx_type_info; +#else +typedef struct __cxx_type_info +{ + UINT flags; + unsigned int type_info; + this_ptr_offsets offsets; + unsigned int size; + unsigned int copy_ctor; +} cxx_type_info; +#endif + +/* table of C++ types that apply for a given object */ +#ifndef __x86_64__ +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 */ +} cxx_type_info_table; +#else +typedef struct __cxx_type_info_table +{ + UINT count; + unsigned int info[3]; +} cxx_type_info_table; +#endif + +/* type information for an exception object */ +#ifndef __x86_64__ +typedef struct __cxx_exception_type +{ + UINT flags; /* TYPE_FLAG flags */ + void (*destructor)(void);/* exception object destructor */ + void *custom_handler; /* custom handler for this exception */ + const cxx_type_info_table *type_info_table; /* list of types for this exception object */ +} cxx_exception_type; +#else +typedef struct +{ + UINT flags; + unsigned int destructor; + unsigned int custom_handler; + unsigned int type_info_table; +} cxx_exception_type; +#endif + +static int (__cdecl *p_is_exception_typeof)(const type_info*, EXCEPTION_POINTERS*); + static void* (WINAPI *pEncodePointer)(void *); static int cb_called[4]; @@ -312,6 +381,7 @@ static BOOL init(void) { SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QEBAPEBDPEAU__type_info_node@@@Z"); SET(ptype_info_dtor, "??1type_info@@UEAA@XZ"); + SET(p_is_exception_typeof, "?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z"); } else { @@ -322,6 +392,7 @@ static BOOL init(void) SET(p_type_info_name_internal_method, "?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z"); SET(ptype_info_dtor, "??1type_info@@UAE@XZ"); #endif + SET(p_is_exception_typeof, "?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z"); } hkernel32 = GetModuleHandleA("kernel32.dll"); @@ -1303,6 +1374,51 @@ static void test_access_s(void) ok(errno == ENOENT, "got %x\n", res); } +#ifndef __x86_64__ +#define EXCEPTION_REF(instance, name) &instance.name +#else +#define EXCEPTION_REF(instance, name) FIELD_OFFSET(struct _exception_data, name) +#endif +static void test_is_exception_typeof(void) +{ + const type_info ti1 = {NULL, NULL, {'.','?','A','V','t','e','s','t','1','@','@',0}}; + const type_info ti2 = {NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0}}; + const type_info ti3 = {NULL, NULL, {'.','?','A','V','t','e','s','t','3','@','@',0}}; + + const struct _exception_data { + type_info ti1; + type_info ti2; + cxx_type_info cti1; + cxx_type_info cti2; + cxx_type_info_table tit; + cxx_exception_type et; + } exception_data = { + {NULL, NULL, {'.','?','A','V','t','e','s','t','1','@','@',0}}, + {NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0}}, + {0, EXCEPTION_REF(exception_data, ti1)}, + {0, EXCEPTION_REF(exception_data, ti2)}, + {2, {EXCEPTION_REF(exception_data, cti1), EXCEPTION_REF(exception_data, cti2)}}, + {0, 0, 0, EXCEPTION_REF(exception_data, tit)} + }; + + EXCEPTION_RECORD rec = {CXX_EXCEPTION, 0, NULL, NULL, 3, {CXX_FRAME_MAGIC_VC6, 0, (ULONG_PTR)&exception_data.et}}; + EXCEPTION_POINTERS except_ptrs = {&rec, NULL}; + + int ret; + +#ifdef __x86_64__ + rec.NumberParameters = 4; + rec.ExceptionInformation[3] = (ULONG_PTR)&exception_data; +#endif + + ret = p_is_exception_typeof(&ti1, &except_ptrs); + ok(ret == 1, "_is_exception_typeof returned %d\n", ret); + ret = p_is_exception_typeof(&ti2, &except_ptrs); + ok(ret == 1, "_is_exception_typeof returned %d\n", ret); + ret = p_is_exception_typeof(&ti3, &except_ptrs); + ok(ret == 0, "_is_exception_typeof returned %d\n", ret); +} + START_TEST(msvcr90) { if(!init()) @@ -1329,4 +1445,5 @@ START_TEST(msvcr90) test_nonblocking_file_access(); test_byteswap(); test_access_s(); + test_is_exception_typeof(); } diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index a3ee6b96327..bc023d56e50 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -1084,3 +1084,88 @@ void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *typ args[2] = (ULONG_PTR)type; RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); } + +/********************************************************************* + * ?_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 diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 7f59bdb0729..e4827843413 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1537,3 +1537,4 @@ @ cdecl fread_s(ptr long long long ptr) @ cdecl _fstat32(long ptr) @ cdecl _fstat64i32(long ptr) +@ cdecl _is_exception_typeof(ptr ptr)