1 /* 2 * msvcrt.dll C++ objects 3 * 4 * Copyright 2000 Jon Griffiths 5 * Copyright 2003, 2004 Alexandre Julliard 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "config.h" 23 #include "wine/port.h" 24 25 #include <stdarg.h> 26 27 #include "windef.h" 28 #include "winternl.h" 29 #include "wine/exception.h" 30 #include "wine/debug.h" 31 #include "msvcrt.h" 32 #include "cppexcept.h" 33 #include "mtdll.h" 34 #include "cxx.h" 35 36 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); 37 38 struct __type_info_node 39 { 40 void *memPtr; 41 struct __type_info_node* next; 42 }; 43 44 typedef exception bad_cast; 45 typedef exception bad_typeid; 46 typedef exception __non_rtti_object; 47 48 extern const vtable_ptr MSVCRT_exception_vtable; 49 extern const vtable_ptr MSVCRT_bad_typeid_vtable; 50 extern const vtable_ptr MSVCRT_bad_cast_vtable; 51 extern const vtable_ptr MSVCRT___non_rtti_object_vtable; 52 extern const vtable_ptr MSVCRT_type_info_vtable; 53 54 /* get the vtable pointer for a C++ object */ 55 static inline const vtable_ptr *get_vtable( void *obj ) 56 { 57 return *(const vtable_ptr **)obj; 58 } 59 60 static inline const rtti_object_locator *get_obj_locator( void *cppobj ) 61 { 62 const vtable_ptr *vtable = get_vtable( cppobj ); 63 return (const rtti_object_locator *)vtable[-1]; 64 } 65 66 #ifndef __x86_64__ 67 static void dump_obj_locator( const rtti_object_locator *ptr ) 68 { 69 int i; 70 const rtti_object_hierarchy *h = ptr->type_hierarchy; 71 72 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n", 73 ptr, ptr->signature, ptr->base_class_offset, ptr->flags, 74 ptr->type_descriptor, dbgstr_type_info(ptr->type_descriptor), ptr->type_hierarchy ); 75 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n", 76 h->signature, h->attributes, h->array_len, h->base_classes ); 77 for (i = 0; i < h->array_len; i++) 78 { 79 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n", 80 h->base_classes->bases[i], 81 h->base_classes->bases[i]->num_base_classes, 82 h->base_classes->bases[i]->offsets.this_offset, 83 h->base_classes->bases[i]->offsets.vbase_descr, 84 h->base_classes->bases[i]->offsets.vbase_offset, 85 h->base_classes->bases[i]->attributes, 86 h->base_classes->bases[i]->type_descriptor, 87 dbgstr_type_info(h->base_classes->bases[i]->type_descriptor) ); 88 } 89 } 90 91 #else 92 93 static void dump_obj_locator( const rtti_object_locator *ptr ) 94 { 95 int i; 96 char *base = ptr->signature == 0 ? RtlPcToFileHeader((void*)ptr, (void**)&base) : (char*)ptr - ptr->object_locator; 97 const rtti_object_hierarchy *h = (const rtti_object_hierarchy*)(base + ptr->type_hierarchy); 98 const type_info *type_descriptor = (const type_info*)(base + ptr->type_descriptor); 99 100 TRACE( "%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p\n", 101 ptr, ptr->signature, ptr->base_class_offset, ptr->flags, 102 type_descriptor, dbgstr_type_info(type_descriptor), h ); 103 TRACE( " hierarchy: sig=%08x attr=%08x len=%d base classes=%p\n", 104 h->signature, h->attributes, h->array_len, base + h->base_classes ); 105 for (i = 0; i < h->array_len; i++) 106 { 107 const rtti_base_descriptor *bases = (rtti_base_descriptor*)(base + 108 ((const rtti_base_array*)(base + h->base_classes))->bases[i]); 109 110 TRACE( " base class %p: num %d off %d,%d,%d attr %08x type %p %s\n", 111 bases, 112 bases->num_base_classes, 113 bases->offsets.this_offset, 114 bases->offsets.vbase_descr, 115 bases->offsets.vbase_offset, 116 bases->attributes, 117 base + bases->type_descriptor, 118 dbgstr_type_info((const type_info*)(base + bases->type_descriptor)) ); 119 } 120 } 121 #endif 122 123 /* Internal common ctor for exception */ 124 static void EXCEPTION_ctor(exception *_this, const char** name) 125 { 126 _this->vtable = &MSVCRT_exception_vtable; 127 if (*name) 128 { 129 unsigned int name_len = strlen(*name) + 1; 130 _this->name = MSVCRT_malloc(name_len); 131 memcpy(_this->name, *name, name_len); 132 _this->do_free = TRUE; 133 } 134 else 135 { 136 _this->name = NULL; 137 _this->do_free = FALSE; 138 } 139 } 140 141 #ifdef __REACTOS__ 142 #include <internal/wine_msc.h> 143 #endif /* __REACTOS__ */ 144 145 /****************************************************************** 146 * ??0exception@@QAE@ABQBD@Z (MSVCRT.@) 147 */ 148 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor,8) 149 exception * __thiscall MSVCRT_exception_ctor(exception * _this, const char ** name) 150 { 151 TRACE("(%p,%s)\n", _this, *name); 152 EXCEPTION_ctor(_this, name); 153 return _this; 154 } 155 156 /****************************************************************** 157 * ??0exception@@QAE@ABQBDH@Z (MSVCRT.@) 158 */ 159 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_ctor_noalloc,12) 160 exception * __thiscall MSVCRT_exception_ctor_noalloc(exception * _this, char ** name, int noalloc) 161 { 162 TRACE("(%p,%s)\n", _this, *name); 163 _this->vtable = &MSVCRT_exception_vtable; 164 _this->name = *name; 165 _this->do_free = FALSE; 166 return _this; 167 } 168 169 /****************************************************************** 170 * ??0exception@@QAE@ABV0@@Z (MSVCRT.@) 171 */ 172 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_copy_ctor,8) 173 exception * __thiscall MSVCRT_exception_copy_ctor(exception * _this, const exception * rhs) 174 { 175 TRACE("(%p,%p)\n", _this, rhs); 176 177 if (!rhs->do_free) 178 { 179 _this->vtable = &MSVCRT_exception_vtable; 180 _this->name = rhs->name; 181 _this->do_free = FALSE; 182 } 183 else 184 EXCEPTION_ctor(_this, (const char**)&rhs->name); 185 TRACE("name = %s\n", _this->name); 186 return _this; 187 } 188 189 /****************************************************************** 190 * ??0exception@@QAE@XZ (MSVCRT.@) 191 */ 192 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_default_ctor,4) 193 exception * __thiscall MSVCRT_exception_default_ctor(exception * _this) 194 { 195 static const char* empty = NULL; 196 197 TRACE("(%p)\n", _this); 198 EXCEPTION_ctor(_this, &empty); 199 return _this; 200 } 201 202 /****************************************************************** 203 * ??1exception@@UAE@XZ (MSVCRT.@) 204 */ 205 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_dtor,4) 206 void __thiscall MSVCRT_exception_dtor(exception * _this) 207 { 208 TRACE("(%p)\n", _this); 209 _this->vtable = &MSVCRT_exception_vtable; 210 if (_this->do_free) MSVCRT_free(_this->name); 211 } 212 213 /****************************************************************** 214 * ??4exception@@QAEAAV0@ABV0@@Z (MSVCRT.@) 215 */ 216 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_opequals,8) 217 exception * __thiscall MSVCRT_exception_opequals(exception * _this, const exception * rhs) 218 { 219 TRACE("(%p %p)\n", _this, rhs); 220 if (_this != rhs) 221 { 222 MSVCRT_exception_dtor(_this); 223 MSVCRT_exception_copy_ctor(_this, rhs); 224 } 225 TRACE("name = %s\n", _this->name); 226 return _this; 227 } 228 229 /****************************************************************** 230 * ??_Eexception@@UAEPAXI@Z (MSVCRT.@) 231 */ 232 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_vector_dtor,8) 233 void * __thiscall MSVCRT_exception_vector_dtor(exception * _this, unsigned int flags) 234 { 235 TRACE("(%p %x)\n", _this, flags); 236 if (flags & 2) 237 { 238 /* we have an array, with the number of elements stored before the first object */ 239 INT_PTR i, *ptr = (INT_PTR *)_this - 1; 240 241 for (i = *ptr - 1; i >= 0; i--) MSVCRT_exception_dtor(_this + i); 242 MSVCRT_operator_delete(ptr); 243 } 244 else 245 { 246 MSVCRT_exception_dtor(_this); 247 if (flags & 1) MSVCRT_operator_delete(_this); 248 } 249 return _this; 250 } 251 252 /****************************************************************** 253 * ??_Gexception@@UAEPAXI@Z (MSVCRT.@) 254 */ 255 DEFINE_THISCALL_WRAPPER(MSVCRT_exception_scalar_dtor,8) 256 void * __thiscall MSVCRT_exception_scalar_dtor(exception * _this, unsigned int flags) 257 { 258 TRACE("(%p %x)\n", _this, flags); 259 MSVCRT_exception_dtor(_this); 260 if (flags & 1) MSVCRT_operator_delete(_this); 261 return _this; 262 } 263 264 /****************************************************************** 265 * ?what@exception@@UBEPBDXZ (MSVCRT.@) 266 */ 267 DEFINE_THISCALL_WRAPPER(MSVCRT_what_exception,4) 268 const char * __thiscall MSVCRT_what_exception(exception * _this) 269 { 270 TRACE("(%p) returning %s\n", _this, _this->name); 271 return _this->name ? _this->name : "Unknown exception"; 272 } 273 274 /****************************************************************** 275 * ??0bad_typeid@@QAE@ABV0@@Z (MSVCRT.@) 276 */ 277 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_copy_ctor,8) 278 bad_typeid * __thiscall MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this, const bad_typeid * rhs) 279 { 280 TRACE("(%p %p)\n", _this, rhs); 281 MSVCRT_exception_copy_ctor(_this, rhs); 282 _this->vtable = &MSVCRT_bad_typeid_vtable; 283 return _this; 284 } 285 286 /****************************************************************** 287 * ??0bad_typeid@@QAE@PBD@Z (MSVCRT.@) 288 */ 289 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_ctor,8) 290 bad_typeid * __thiscall MSVCRT_bad_typeid_ctor(bad_typeid * _this, const char * name) 291 { 292 TRACE("(%p %s)\n", _this, name); 293 EXCEPTION_ctor(_this, &name); 294 _this->vtable = &MSVCRT_bad_typeid_vtable; 295 return _this; 296 } 297 298 /****************************************************************** 299 * ??_Fbad_typeid@@QAEXXZ (MSVCRT.@) 300 */ 301 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_default_ctor,4) 302 bad_typeid * __thiscall MSVCRT_bad_typeid_default_ctor(bad_typeid * _this) 303 { 304 return MSVCRT_bad_typeid_ctor( _this, "bad typeid" ); 305 } 306 307 /****************************************************************** 308 * ??1bad_typeid@@UAE@XZ (MSVCRT.@) 309 */ 310 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_dtor,4) 311 void __thiscall MSVCRT_bad_typeid_dtor(bad_typeid * _this) 312 { 313 TRACE("(%p)\n", _this); 314 MSVCRT_exception_dtor(_this); 315 } 316 317 /****************************************************************** 318 * ??4bad_typeid@@QAEAAV0@ABV0@@Z (MSVCRT.@) 319 */ 320 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_opequals,8) 321 bad_typeid * __thiscall MSVCRT_bad_typeid_opequals(bad_typeid * _this, const bad_typeid * rhs) 322 { 323 TRACE("(%p %p)\n", _this, rhs); 324 MSVCRT_exception_opequals(_this, rhs); 325 return _this; 326 } 327 328 /****************************************************************** 329 * ??_Ebad_typeid@@UAEPAXI@Z (MSVCRT.@) 330 */ 331 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_vector_dtor,8) 332 void * __thiscall MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this, unsigned int flags) 333 { 334 TRACE("(%p %x)\n", _this, flags); 335 if (flags & 2) 336 { 337 /* we have an array, with the number of elements stored before the first object */ 338 INT_PTR i, *ptr = (INT_PTR *)_this - 1; 339 340 for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_typeid_dtor(_this + i); 341 MSVCRT_operator_delete(ptr); 342 } 343 else 344 { 345 MSVCRT_bad_typeid_dtor(_this); 346 if (flags & 1) MSVCRT_operator_delete(_this); 347 } 348 return _this; 349 } 350 351 /****************************************************************** 352 * ??_Gbad_typeid@@UAEPAXI@Z (MSVCRT.@) 353 */ 354 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_typeid_scalar_dtor,8) 355 void * __thiscall MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this, unsigned int flags) 356 { 357 TRACE("(%p %x)\n", _this, flags); 358 MSVCRT_bad_typeid_dtor(_this); 359 if (flags & 1) MSVCRT_operator_delete(_this); 360 return _this; 361 } 362 363 /****************************************************************** 364 * ??0__non_rtti_object@@QAE@ABV0@@Z (MSVCRT.@) 365 */ 366 DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_copy_ctor,8) 367 __non_rtti_object * __thiscall MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this, 368 const __non_rtti_object * rhs) 369 { 370 TRACE("(%p %p)\n", _this, rhs); 371 MSVCRT_bad_typeid_copy_ctor(_this, rhs); 372 _this->vtable = &MSVCRT___non_rtti_object_vtable; 373 return _this; 374 } 375 376 /****************************************************************** 377 * ??0__non_rtti_object@@QAE@PBD@Z (MSVCRT.@) 378 */ 379 DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_ctor,8) 380 __non_rtti_object * __thiscall MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this, 381 const char * name) 382 { 383 TRACE("(%p %s)\n", _this, name); 384 EXCEPTION_ctor(_this, &name); 385 _this->vtable = &MSVCRT___non_rtti_object_vtable; 386 return _this; 387 } 388 389 /****************************************************************** 390 * ??1__non_rtti_object@@UAE@XZ (MSVCRT.@) 391 */ 392 DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_dtor,4) 393 void __thiscall MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this) 394 { 395 TRACE("(%p)\n", _this); 396 MSVCRT_bad_typeid_dtor(_this); 397 } 398 399 /****************************************************************** 400 * ??4__non_rtti_object@@QAEAAV0@ABV0@@Z (MSVCRT.@) 401 */ 402 DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_opequals,8) 403 __non_rtti_object * __thiscall MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this, 404 const __non_rtti_object *rhs) 405 { 406 TRACE("(%p %p)\n", _this, rhs); 407 MSVCRT_bad_typeid_opequals(_this, rhs); 408 return _this; 409 } 410 411 /****************************************************************** 412 * ??_E__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) 413 */ 414 DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_vector_dtor,8) 415 void * __thiscall MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this, unsigned int flags) 416 { 417 TRACE("(%p %x)\n", _this, flags); 418 if (flags & 2) 419 { 420 /* we have an array, with the number of elements stored before the first object */ 421 INT_PTR i, *ptr = (INT_PTR *)_this - 1; 422 423 for (i = *ptr - 1; i >= 0; i--) MSVCRT___non_rtti_object_dtor(_this + i); 424 MSVCRT_operator_delete(ptr); 425 } 426 else 427 { 428 MSVCRT___non_rtti_object_dtor(_this); 429 if (flags & 1) MSVCRT_operator_delete(_this); 430 } 431 return _this; 432 } 433 434 /****************************************************************** 435 * ??_G__non_rtti_object@@UAEPAXI@Z (MSVCRT.@) 436 */ 437 DEFINE_THISCALL_WRAPPER(MSVCRT___non_rtti_object_scalar_dtor,8) 438 void * __thiscall MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this, unsigned int flags) 439 { 440 TRACE("(%p %x)\n", _this, flags); 441 MSVCRT___non_rtti_object_dtor(_this); 442 if (flags & 1) MSVCRT_operator_delete(_this); 443 return _this; 444 } 445 446 /****************************************************************** 447 * ??0bad_cast@@AAE@PBQBD@Z (MSVCRT.@) 448 * ??0bad_cast@@QAE@ABQBD@Z (MSVCRT.@) 449 */ 450 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor,8) 451 bad_cast * __thiscall MSVCRT_bad_cast_ctor(bad_cast * _this, const char ** name) 452 { 453 TRACE("(%p %s)\n", _this, *name); 454 EXCEPTION_ctor(_this, name); 455 _this->vtable = &MSVCRT_bad_cast_vtable; 456 return _this; 457 } 458 459 /****************************************************************** 460 * ??0bad_cast@@QAE@ABV0@@Z (MSVCRT.@) 461 */ 462 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_copy_ctor,8) 463 bad_cast * __thiscall MSVCRT_bad_cast_copy_ctor(bad_cast * _this, const bad_cast * rhs) 464 { 465 TRACE("(%p %p)\n", _this, rhs); 466 MSVCRT_exception_copy_ctor(_this, rhs); 467 _this->vtable = &MSVCRT_bad_cast_vtable; 468 return _this; 469 } 470 471 /****************************************************************** 472 * ??0bad_cast@@QAE@PBD@Z (MSVCRT.@) 473 */ 474 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_ctor_charptr,8) 475 bad_cast * __thiscall MSVCRT_bad_cast_ctor_charptr(bad_cast * _this, const char * name) 476 { 477 TRACE("(%p %s)\n", _this, name); 478 EXCEPTION_ctor(_this, &name); 479 _this->vtable = &MSVCRT_bad_cast_vtable; 480 return _this; 481 } 482 483 /****************************************************************** 484 * ??_Fbad_cast@@QAEXXZ (MSVCRT.@) 485 */ 486 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_default_ctor,4) 487 bad_cast * __thiscall MSVCRT_bad_cast_default_ctor(bad_cast * _this) 488 { 489 return MSVCRT_bad_cast_ctor_charptr( _this, "bad cast" ); 490 } 491 492 /****************************************************************** 493 * ??1bad_cast@@UAE@XZ (MSVCRT.@) 494 */ 495 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_dtor,4) 496 void __thiscall MSVCRT_bad_cast_dtor(bad_cast * _this) 497 { 498 TRACE("(%p)\n", _this); 499 MSVCRT_exception_dtor(_this); 500 } 501 502 /****************************************************************** 503 * ??4bad_cast@@QAEAAV0@ABV0@@Z (MSVCRT.@) 504 */ 505 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_opequals,8) 506 bad_cast * __thiscall MSVCRT_bad_cast_opequals(bad_cast * _this, const bad_cast * rhs) 507 { 508 TRACE("(%p %p)\n", _this, rhs); 509 MSVCRT_exception_opequals(_this, rhs); 510 return _this; 511 } 512 513 /****************************************************************** 514 * ??_Ebad_cast@@UAEPAXI@Z (MSVCRT.@) 515 */ 516 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_vector_dtor,8) 517 void * __thiscall MSVCRT_bad_cast_vector_dtor(bad_cast * _this, unsigned int flags) 518 { 519 TRACE("(%p %x)\n", _this, flags); 520 if (flags & 2) 521 { 522 /* we have an array, with the number of elements stored before the first object */ 523 INT_PTR i, *ptr = (INT_PTR *)_this - 1; 524 525 for (i = *ptr - 1; i >= 0; i--) MSVCRT_bad_cast_dtor(_this + i); 526 MSVCRT_operator_delete(ptr); 527 } 528 else 529 { 530 MSVCRT_bad_cast_dtor(_this); 531 if (flags & 1) MSVCRT_operator_delete(_this); 532 } 533 return _this; 534 } 535 536 /****************************************************************** 537 * ??_Gbad_cast@@UAEPAXI@Z (MSVCRT.@) 538 */ 539 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_cast_scalar_dtor,8) 540 void * __thiscall MSVCRT_bad_cast_scalar_dtor(bad_cast * _this, unsigned int flags) 541 { 542 TRACE("(%p %x)\n", _this, flags); 543 MSVCRT_bad_cast_dtor(_this); 544 if (flags & 1) MSVCRT_operator_delete(_this); 545 return _this; 546 } 547 548 /****************************************************************** 549 * ??8type_info@@QBEHABV0@@Z (MSVCRT.@) 550 */ 551 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opequals_equals,8) 552 int __thiscall MSVCRT_type_info_opequals_equals(type_info * _this, const type_info * rhs) 553 { 554 int ret = !strcmp(_this->mangled + 1, rhs->mangled + 1); 555 TRACE("(%p %p) returning %d\n", _this, rhs, ret); 556 return ret; 557 } 558 559 /****************************************************************** 560 * ??9type_info@@QBEHABV0@@Z (MSVCRT.@) 561 */ 562 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_opnot_equals,8) 563 int __thiscall MSVCRT_type_info_opnot_equals(type_info * _this, const type_info * rhs) 564 { 565 int ret = !!strcmp(_this->mangled + 1, rhs->mangled + 1); 566 TRACE("(%p %p) returning %d\n", _this, rhs, ret); 567 return ret; 568 } 569 570 /****************************************************************** 571 * ?before@type_info@@QBEHABV1@@Z (MSVCRT.@) 572 */ 573 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_before,8) 574 int __thiscall MSVCRT_type_info_before(type_info * _this, const type_info * rhs) 575 { 576 int ret = strcmp(_this->mangled + 1, rhs->mangled + 1) < 0; 577 TRACE("(%p %p) returning %d\n", _this, rhs, ret); 578 return ret; 579 } 580 581 /****************************************************************** 582 * ??1type_info@@UAE@XZ (MSVCRT.@) 583 */ 584 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_dtor,4) 585 void __thiscall MSVCRT_type_info_dtor(type_info * _this) 586 { 587 TRACE("(%p)\n", _this); 588 MSVCRT_free(_this->name); 589 } 590 591 /****************************************************************** 592 * ?name@type_info@@QBEPBDXZ (MSVCRT.@) 593 */ 594 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_name,4) 595 const char * __thiscall MSVCRT_type_info_name(type_info * _this) 596 { 597 if (!_this->name) 598 { 599 /* Create and set the demangled name */ 600 /* Note: mangled name in type_info struct always starts with a '.', while 601 * it isn't valid for mangled name. 602 * Is this '.' really part of the mangled name, or has it some other meaning ? 603 */ 604 char* name = __unDName(0, _this->mangled + 1, 0, 605 MSVCRT_malloc, MSVCRT_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); 606 if (name) 607 { 608 unsigned int len = strlen(name); 609 610 /* It seems _unDName may leave blanks at the end of the demangled name */ 611 while (len && name[--len] == ' ') 612 name[len] = '\0'; 613 614 if (InterlockedCompareExchangePointer((void**)&_this->name, name, NULL)) 615 { 616 /* Another thread set this member since we checked above - use it */ 617 MSVCRT_free(name); 618 } 619 } 620 } 621 TRACE("(%p) returning %s\n", _this, _this->name); 622 return _this->name; 623 } 624 625 /****************************************************************** 626 * ?raw_name@type_info@@QBEPBDXZ (MSVCRT.@) 627 */ 628 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_raw_name,4) 629 const char * __thiscall MSVCRT_type_info_raw_name(type_info * _this) 630 { 631 TRACE("(%p) returning %s\n", _this, _this->mangled); 632 return _this->mangled; 633 } 634 635 /* Unexported */ 636 DEFINE_THISCALL_WRAPPER(MSVCRT_type_info_vector_dtor,8) 637 void * __thiscall MSVCRT_type_info_vector_dtor(type_info * _this, unsigned int flags) 638 { 639 TRACE("(%p %x)\n", _this, flags); 640 if (flags & 2) 641 { 642 /* we have an array, with the number of elements stored before the first object */ 643 INT_PTR i, *ptr = (INT_PTR *)_this - 1; 644 645 for (i = *ptr - 1; i >= 0; i--) MSVCRT_type_info_dtor(_this + i); 646 MSVCRT_operator_delete(ptr); 647 } 648 else 649 { 650 MSVCRT_type_info_dtor(_this); 651 if (flags & 1) MSVCRT_operator_delete(_this); 652 } 653 return _this; 654 } 655 656 #if _MSVCR_VER >= 80 657 658 typedef exception bad_alloc; 659 extern const vtable_ptr MSVCRT_bad_alloc_vtable; 660 661 static void bad_alloc_ctor(bad_alloc *this, const char **name) 662 { 663 MSVCRT_exception_ctor(this, name); 664 this->vtable = &MSVCRT_bad_alloc_vtable; 665 } 666 667 /* bad_alloc class implementation */ 668 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_copy_ctor,8) 669 bad_alloc * __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs) 670 { 671 TRACE("(%p %p)\n", _this, rhs); 672 MSVCRT_exception_copy_ctor(_this, rhs); 673 _this->vtable = &MSVCRT_bad_alloc_vtable; 674 return _this; 675 } 676 677 DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_dtor,4) 678 void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc * _this) 679 { 680 TRACE("(%p)\n", _this); 681 MSVCRT_exception_dtor(_this); 682 } 683 684 #endif /* _MSVCR_VER >= 80 */ 685 686 #if _MSVCR_VER >= 100 687 688 typedef struct { 689 exception e; 690 HRESULT hr; 691 } scheduler_resource_allocation_error; 692 extern const vtable_ptr MSVCRT_scheduler_resource_allocation_error_vtable; 693 694 /* ??0scheduler_resource_allocation_error@Concurrency@@QAE@PBDJ@Z */ 695 /* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@PEBDJ@Z */ 696 DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor_name, 12) 697 scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor_name( 698 scheduler_resource_allocation_error *this, const char *name, HRESULT hr) 699 { 700 TRACE("(%p %s %x)\n", this, wine_dbgstr_a(name), hr); 701 MSVCRT_exception_ctor(&this->e, &name); 702 this->e.vtable = &MSVCRT_scheduler_resource_allocation_error_vtable; 703 this->hr = hr; 704 return this; 705 } 706 707 /* ??0scheduler_resource_allocation_error@Concurrency@@QAE@J@Z */ 708 /* ??0scheduler_resource_allocation_error@Concurrency@@QEAA@J@Z */ 709 DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_ctor, 8) 710 scheduler_resource_allocation_error* __thiscall scheduler_resource_allocation_error_ctor( 711 scheduler_resource_allocation_error *this, HRESULT hr) 712 { 713 return scheduler_resource_allocation_error_ctor_name(this, NULL, hr); 714 } 715 716 DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_copy_ctor,8) 717 scheduler_resource_allocation_error* __thiscall MSVCRT_scheduler_resource_allocation_error_copy_ctor( 718 scheduler_resource_allocation_error *this, 719 const scheduler_resource_allocation_error *rhs) 720 { 721 TRACE("(%p,%p)\n", this, rhs); 722 723 if (!rhs->e.do_free) 724 memcpy(this, rhs, sizeof(*this)); 725 else 726 scheduler_resource_allocation_error_ctor_name(this, rhs->e.name, rhs->hr); 727 return this; 728 } 729 730 /* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QBEJXZ */ 731 /* ?get_error_code@scheduler_resource_allocation_error@Concurrency@@QEBAJXZ */ 732 DEFINE_THISCALL_WRAPPER(scheduler_resource_allocation_error_get_error_code, 4) 733 HRESULT __thiscall scheduler_resource_allocation_error_get_error_code( 734 const scheduler_resource_allocation_error *this) 735 { 736 TRACE("(%p)\n", this); 737 return this->hr; 738 } 739 740 DEFINE_THISCALL_WRAPPER(MSVCRT_scheduler_resource_allocation_error_dtor,4) 741 void __thiscall MSVCRT_scheduler_resource_allocation_error_dtor( 742 scheduler_resource_allocation_error * this) 743 { 744 TRACE("(%p)\n", this); 745 MSVCRT_exception_dtor(&this->e); 746 } 747 748 typedef exception improper_lock; 749 extern const vtable_ptr MSVCRT_improper_lock_vtable; 750 751 /* ??0improper_lock@Concurrency@@QAE@PBD@Z */ 752 /* ??0improper_lock@Concurrency@@QEAA@PEBD@Z */ 753 DEFINE_THISCALL_WRAPPER(improper_lock_ctor_str, 8) 754 improper_lock* __thiscall improper_lock_ctor_str(improper_lock *this, const char *str) 755 { 756 TRACE("(%p %p)\n", this, str); 757 MSVCRT_exception_ctor(this, &str); 758 this->vtable = &MSVCRT_improper_lock_vtable; 759 return this; 760 } 761 762 /* ??0improper_lock@Concurrency@@QAE@XZ */ 763 /* ??0improper_lock@Concurrency@@QEAA@XZ */ 764 DEFINE_THISCALL_WRAPPER(improper_lock_ctor, 4) 765 improper_lock* __thiscall improper_lock_ctor(improper_lock *this) 766 { 767 return improper_lock_ctor_str(this, NULL); 768 } 769 770 DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_copy_ctor,8) 771 improper_lock * __thiscall MSVCRT_improper_lock_copy_ctor(improper_lock * _this, const improper_lock * rhs) 772 { 773 TRACE("(%p %p)\n", _this, rhs); 774 MSVCRT_exception_copy_ctor(_this, rhs); 775 _this->vtable = &MSVCRT_improper_lock_vtable; 776 return _this; 777 } 778 779 DEFINE_THISCALL_WRAPPER(MSVCRT_improper_lock_dtor,4) 780 void __thiscall MSVCRT_improper_lock_dtor(improper_lock * _this) 781 { 782 TRACE("(%p)\n", _this); 783 MSVCRT_exception_dtor(_this); 784 } 785 786 typedef exception invalid_scheduler_policy_key; 787 extern const vtable_ptr MSVCRT_invalid_scheduler_policy_key_vtable; 788 789 /* ??0invalid_scheduler_policy_key@Concurrency@@QAE@PBD@Z */ 790 /* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@PEBD@Z */ 791 DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor_str, 8) 792 invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str( 793 invalid_scheduler_policy_key *this, const char *str) 794 { 795 TRACE("(%p %p)\n", this, str); 796 MSVCRT_exception_ctor(this, &str); 797 this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable; 798 return this; 799 } 800 801 /* ??0invalid_scheduler_policy_key@Concurrency@@QAE@XZ */ 802 /* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@XZ */ 803 DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor, 4) 804 invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor( 805 invalid_scheduler_policy_key *this) 806 { 807 return invalid_scheduler_policy_key_ctor_str(this, NULL); 808 } 809 810 DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_copy_ctor,8) 811 invalid_scheduler_policy_key * __thiscall MSVCRT_invalid_scheduler_policy_key_copy_ctor( 812 invalid_scheduler_policy_key * _this, const invalid_scheduler_policy_key * rhs) 813 { 814 TRACE("(%p %p)\n", _this, rhs); 815 MSVCRT_exception_copy_ctor(_this, rhs); 816 _this->vtable = &MSVCRT_invalid_scheduler_policy_key_vtable; 817 return _this; 818 } 819 820 DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_key_dtor,4) 821 void __thiscall MSVCRT_invalid_scheduler_policy_key_dtor( 822 invalid_scheduler_policy_key * _this) 823 { 824 TRACE("(%p)\n", _this); 825 MSVCRT_exception_dtor(_this); 826 } 827 828 typedef exception invalid_scheduler_policy_value; 829 extern const vtable_ptr MSVCRT_invalid_scheduler_policy_value_vtable; 830 831 /* ??0invalid_scheduler_policy_value@Concurrency@@QAE@PBD@Z */ 832 /* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@PEBD@Z */ 833 DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor_str, 8) 834 invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str( 835 invalid_scheduler_policy_value *this, const char *str) 836 { 837 TRACE("(%p %p)\n", this, str); 838 MSVCRT_exception_ctor(this, &str); 839 this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable; 840 return this; 841 } 842 843 /* ??0invalid_scheduler_policy_value@Concurrency@@QAE@XZ */ 844 /* ??0invalid_scheduler_policy_value@Concurrency@@QEAA@XZ */ 845 DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor, 4) 846 invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor( 847 invalid_scheduler_policy_value *this) 848 { 849 return invalid_scheduler_policy_value_ctor_str(this, NULL); 850 } 851 852 DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_copy_ctor,8) 853 invalid_scheduler_policy_value * __thiscall MSVCRT_invalid_scheduler_policy_value_copy_ctor( 854 invalid_scheduler_policy_value * _this, const invalid_scheduler_policy_value * rhs) 855 { 856 TRACE("(%p %p)\n", _this, rhs); 857 MSVCRT_exception_copy_ctor(_this, rhs); 858 _this->vtable = &MSVCRT_invalid_scheduler_policy_value_vtable; 859 return _this; 860 } 861 862 DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_value_dtor,4) 863 void __thiscall MSVCRT_invalid_scheduler_policy_value_dtor( 864 invalid_scheduler_policy_value * _this) 865 { 866 TRACE("(%p)\n", _this); 867 MSVCRT_exception_dtor(_this); 868 } 869 870 typedef exception invalid_scheduler_policy_thread_specification; 871 extern const vtable_ptr MSVCRT_invalid_scheduler_policy_thread_specification_vtable; 872 873 /* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@PBD@Z */ 874 /* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@PEBD@Z */ 875 DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor_str, 8) 876 invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str( 877 invalid_scheduler_policy_thread_specification *this, const char *str) 878 { 879 TRACE("(%p %p)\n", this, str); 880 MSVCRT_exception_ctor(this, &str); 881 this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable; 882 return this; 883 } 884 885 /* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QAE@XZ */ 886 /* ??0invalid_scheduler_policy_thread_specification@Concurrency@@QEAA@XZ */ 887 DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor, 4) 888 invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor( 889 invalid_scheduler_policy_thread_specification *this) 890 { 891 return invalid_scheduler_policy_thread_specification_ctor_str(this, NULL); 892 } 893 894 DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor,8) 895 invalid_scheduler_policy_thread_specification * __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor( 896 invalid_scheduler_policy_thread_specification * _this, const invalid_scheduler_policy_thread_specification * rhs) 897 { 898 TRACE("(%p %p)\n", _this, rhs); 899 MSVCRT_exception_copy_ctor(_this, rhs); 900 _this->vtable = &MSVCRT_invalid_scheduler_policy_thread_specification_vtable; 901 return _this; 902 } 903 904 DEFINE_THISCALL_WRAPPER(MSVCRT_invalid_scheduler_policy_thread_specification_dtor,4) 905 void __thiscall MSVCRT_invalid_scheduler_policy_thread_specification_dtor( 906 invalid_scheduler_policy_thread_specification * _this) 907 { 908 TRACE("(%p)\n", _this); 909 MSVCRT_exception_dtor(_this); 910 } 911 912 typedef exception improper_scheduler_attach; 913 extern const vtable_ptr MSVCRT_improper_scheduler_attach_vtable; 914 915 /* ??0improper_scheduler_attach@Concurrency@@QAE@PBD@Z */ 916 /* ??0improper_scheduler_attach@Concurrency@@QEAA@PEBD@Z */ 917 DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor_str, 8) 918 improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str( 919 improper_scheduler_attach *this, const char *str) 920 { 921 TRACE("(%p %p)\n", this, str); 922 MSVCRT_exception_ctor(this, &str); 923 this->vtable = &MSVCRT_improper_scheduler_attach_vtable; 924 return this; 925 } 926 927 /* ??0improper_scheduler_attach@Concurrency@@QAE@XZ */ 928 /* ??0improper_scheduler_attach@Concurrency@@QEAA@XZ */ 929 DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor, 4) 930 improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor( 931 improper_scheduler_attach *this) 932 { 933 return improper_scheduler_attach_ctor_str(this, NULL); 934 } 935 936 DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_copy_ctor,8) 937 improper_scheduler_attach * __thiscall MSVCRT_improper_scheduler_attach_copy_ctor( 938 improper_scheduler_attach * _this, const improper_scheduler_attach * rhs) 939 { 940 TRACE("(%p %p)\n", _this, rhs); 941 MSVCRT_exception_copy_ctor(_this, rhs); 942 _this->vtable = &MSVCRT_improper_scheduler_attach_vtable; 943 return _this; 944 } 945 946 DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_attach_dtor,4) 947 void __thiscall MSVCRT_improper_scheduler_attach_dtor( 948 improper_scheduler_attach * _this) 949 { 950 TRACE("(%p)\n", _this); 951 MSVCRT_exception_dtor(_this); 952 } 953 954 typedef exception improper_scheduler_detach; 955 extern const vtable_ptr MSVCRT_improper_scheduler_detach_vtable; 956 957 /* ??0improper_scheduler_detach@Concurrency@@QAE@PBD@Z */ 958 /* ??0improper_scheduler_detach@Concurrency@@QEAA@PEBD@Z */ 959 DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor_str, 8) 960 improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str( 961 improper_scheduler_detach *this, const char *str) 962 { 963 TRACE("(%p %p)\n", this, str); 964 MSVCRT_exception_ctor(this, &str); 965 this->vtable = &MSVCRT_improper_scheduler_detach_vtable; 966 return this; 967 } 968 969 /* ??0improper_scheduler_detach@Concurrency@@QAE@XZ */ 970 /* ??0improper_scheduler_detach@Concurrency@@QEAA@XZ */ 971 DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor, 4) 972 improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor( 973 improper_scheduler_detach *this) 974 { 975 return improper_scheduler_detach_ctor_str(this, NULL); 976 } 977 978 DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_copy_ctor,8) 979 improper_scheduler_detach * __thiscall MSVCRT_improper_scheduler_detach_copy_ctor( 980 improper_scheduler_detach * _this, const improper_scheduler_detach * rhs) 981 { 982 TRACE("(%p %p)\n", _this, rhs); 983 MSVCRT_exception_copy_ctor(_this, rhs); 984 _this->vtable = &MSVCRT_improper_scheduler_detach_vtable; 985 return _this; 986 } 987 988 DEFINE_THISCALL_WRAPPER(MSVCRT_improper_scheduler_detach_dtor,4) 989 void __thiscall MSVCRT_improper_scheduler_detach_dtor( 990 improper_scheduler_detach * _this) 991 { 992 TRACE("(%p)\n", _this); 993 MSVCRT_exception_dtor(_this); 994 } 995 996 #endif /* _MSVCR_VER >= 100 */ 997 998 #ifndef __GNUC__ 999 void __asm_dummy_vtables(void) { 1000 #endif 1001 1002 __ASM_VTABLE(type_info, 1003 VTABLE_ADD_FUNC(MSVCRT_type_info_vector_dtor)); 1004 __ASM_VTABLE(exception, 1005 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1006 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1007 #if _MSVCR_VER >= 80 1008 __ASM_VTABLE(exception_old, 1009 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1010 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1011 __ASM_VTABLE(bad_alloc, 1012 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1013 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1014 #endif 1015 __ASM_VTABLE(bad_typeid, 1016 VTABLE_ADD_FUNC(MSVCRT_bad_typeid_vector_dtor) 1017 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1018 __ASM_VTABLE(bad_cast, 1019 VTABLE_ADD_FUNC(MSVCRT_bad_cast_vector_dtor) 1020 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1021 __ASM_VTABLE(__non_rtti_object, 1022 VTABLE_ADD_FUNC(MSVCRT___non_rtti_object_vector_dtor) 1023 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1024 #if _MSVCR_VER >= 100 1025 __ASM_VTABLE(scheduler_resource_allocation_error, 1026 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1027 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1028 __ASM_VTABLE(improper_lock, 1029 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1030 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1031 __ASM_VTABLE(invalid_scheduler_policy_key, 1032 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1033 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1034 __ASM_VTABLE(invalid_scheduler_policy_value, 1035 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1036 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1037 __ASM_VTABLE(invalid_scheduler_policy_thread_specification, 1038 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1039 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1040 __ASM_VTABLE(improper_scheduler_attach, 1041 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1042 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1043 __ASM_VTABLE(improper_scheduler_detach, 1044 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1045 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1046 #endif 1047 1048 #ifndef __GNUC__ 1049 } 1050 #endif 1051 1052 DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" ) 1053 #if _MSVCR_VER >= 80 1054 DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@std@@" ) 1055 DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" ) 1056 DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" ) 1057 DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" ) 1058 DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" ) 1059 DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" ) 1060 #else 1061 DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@@" ) 1062 DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" ) 1063 DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" ) 1064 DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" ) 1065 #endif 1066 #if _MSVCR_VER >= 100 1067 DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &exception_rtti_base_descriptor, 1068 ".?AVscheduler_resource_allocation_error@Concurrency@@") 1069 DEFINE_RTTI_DATA1(improper_lock, 0, &exception_rtti_base_descriptor, ".?AVimproper_lock@Concurrency@@" ) 1070 DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &exception_rtti_base_descriptor, 1071 ".?AVinvalid_scheduler_policy_key@Concurrency@@" ) 1072 DEFINE_RTTI_DATA1(invalid_scheduler_policy_value, 0, &exception_rtti_base_descriptor, 1073 ".?AVinvalid_scheduler_policy_value@Concurrency@@" ) 1074 DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &exception_rtti_base_descriptor, 1075 ".?AVinvalid_scheduler_policy_thread_specification@Concurrency@@" ) 1076 DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &exception_rtti_base_descriptor, 1077 ".?AVimproper_scheduler_attach@Concurrency@@" ) 1078 DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor, 1079 ".?AVimproper_scheduler_detach@Concurrency@@" ) 1080 #endif 1081 1082 DEFINE_EXCEPTION_TYPE_INFO( exception, 0, NULL, NULL ) 1083 DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL ) 1084 DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL ) 1085 DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info ) 1086 #if _MSVCR_VER >= 80 1087 DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL ) 1088 #endif 1089 #if _MSVCR_VER >= 100 1090 DEFINE_EXCEPTION_TYPE_INFO(scheduler_resource_allocation_error, 1, &exception_cxx_type_info, NULL) 1091 DEFINE_EXCEPTION_TYPE_INFO(improper_lock, 1, &exception_cxx_type_info, NULL) 1092 DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_key, 1, &exception_cxx_type_info, NULL) 1093 DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_value, 1, &exception_cxx_type_info, NULL) 1094 DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_thread_specification, 1, &exception_cxx_type_info, NULL) 1095 DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_attach, 1, &exception_cxx_type_info, NULL) 1096 DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_detach, 1, &exception_cxx_type_info, NULL) 1097 #endif 1098 1099 void msvcrt_init_exception(void *base) 1100 { 1101 #ifdef __x86_64__ 1102 init_type_info_rtti(base); 1103 init_exception_rtti(base); 1104 #if _MSVCR_VER >= 80 1105 init_exception_old_rtti(base); 1106 init_bad_alloc_rtti(base); 1107 #endif 1108 init_bad_typeid_rtti(base); 1109 init_bad_cast_rtti(base); 1110 init___non_rtti_object_rtti(base); 1111 #if _MSVCR_VER >= 100 1112 init_scheduler_resource_allocation_error_rtti(base); 1113 init_improper_lock_rtti(base); 1114 init_invalid_scheduler_policy_key_rtti(base); 1115 init_invalid_scheduler_policy_value_rtti(base); 1116 init_invalid_scheduler_policy_thread_specification_rtti(base); 1117 init_improper_scheduler_attach_rtti(base); 1118 init_improper_scheduler_detach_rtti(base); 1119 #endif 1120 1121 init_exception_cxx(base); 1122 init_bad_typeid_cxx(base); 1123 init_bad_cast_cxx(base); 1124 init___non_rtti_object_cxx(base); 1125 #if _MSVCR_VER >= 80 1126 init_bad_alloc_cxx(base); 1127 #endif 1128 #if _MSVCR_VER >= 100 1129 init_scheduler_resource_allocation_error_cxx(base); 1130 init_improper_lock_cxx(base); 1131 init_invalid_scheduler_policy_key_cxx(base); 1132 init_invalid_scheduler_policy_value_cxx(base); 1133 init_invalid_scheduler_policy_thread_specification_cxx(base); 1134 init_improper_scheduler_attach_cxx(base); 1135 init_improper_scheduler_detach_cxx(base); 1136 #endif 1137 #endif 1138 } 1139 1140 #if _MSVCR_VER >= 80 1141 void throw_exception(exception_type et, HRESULT hr, const char *str) 1142 { 1143 switch(et) { 1144 case EXCEPTION_BAD_ALLOC: { 1145 bad_alloc e; 1146 bad_alloc_ctor(&e, &str); 1147 _CxxThrowException(&e, &bad_alloc_exception_type); 1148 } 1149 #if _MSVCR_VER >= 100 1150 case EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR: { 1151 scheduler_resource_allocation_error e; 1152 scheduler_resource_allocation_error_ctor_name(&e, str, hr); 1153 _CxxThrowException(&e.e, &scheduler_resource_allocation_error_exception_type); 1154 } 1155 case EXCEPTION_IMPROPER_LOCK: { 1156 improper_lock e; 1157 improper_lock_ctor_str(&e, str); 1158 _CxxThrowException(&e, &improper_lock_exception_type); 1159 } 1160 case EXCEPTION_INVALID_SCHEDULER_POLICY_KEY: { 1161 invalid_scheduler_policy_key e; 1162 invalid_scheduler_policy_key_ctor_str(&e, str); 1163 _CxxThrowException(&e, &invalid_scheduler_policy_key_exception_type); 1164 } 1165 case EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE: { 1166 invalid_scheduler_policy_value e; 1167 invalid_scheduler_policy_value_ctor_str(&e, str); 1168 _CxxThrowException(&e, &invalid_scheduler_policy_value_exception_type); 1169 } 1170 case EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION: { 1171 invalid_scheduler_policy_thread_specification e; 1172 invalid_scheduler_policy_thread_specification_ctor_str(&e, str); 1173 _CxxThrowException(&e, &invalid_scheduler_policy_thread_specification_exception_type); 1174 } 1175 case EXCEPTION_IMPROPER_SCHEDULER_ATTACH: { 1176 improper_scheduler_attach e; 1177 improper_scheduler_attach_ctor_str(&e, str); 1178 _CxxThrowException(&e, &improper_scheduler_attach_exception_type); 1179 } 1180 case EXCEPTION_IMPROPER_SCHEDULER_DETACH: { 1181 improper_scheduler_detach e; 1182 improper_scheduler_detach_ctor_str(&e, str); 1183 _CxxThrowException(&e, &improper_scheduler_detach_exception_type); 1184 } 1185 #endif 1186 } 1187 } 1188 #endif 1189 1190 /****************************************************************** 1191 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) 1192 * 1193 * Install a handler to be called when terminate() is called. 1194 * 1195 * PARAMS 1196 * func [I] Handler function to install 1197 * 1198 * RETURNS 1199 * The previously installed handler function, if any. 1200 */ 1201 MSVCRT_terminate_function CDECL MSVCRT_set_terminate(MSVCRT_terminate_function func) 1202 { 1203 thread_data_t *data = msvcrt_get_thread_data(); 1204 MSVCRT_terminate_function previous = data->terminate_handler; 1205 TRACE("(%p) returning %p\n",func,previous); 1206 data->terminate_handler = func; 1207 return previous; 1208 } 1209 1210 /****************************************************************** 1211 * _get_terminate (MSVCRT.@) 1212 */ 1213 MSVCRT_terminate_function CDECL MSVCRT__get_terminate(void) 1214 { 1215 thread_data_t *data = msvcrt_get_thread_data(); 1216 TRACE("returning %p\n", data->terminate_handler); 1217 return data->terminate_handler; 1218 } 1219 1220 /****************************************************************** 1221 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) 1222 * 1223 * Install a handler to be called when unexpected() is called. 1224 * 1225 * PARAMS 1226 * func [I] Handler function to install 1227 * 1228 * RETURNS 1229 * The previously installed handler function, if any. 1230 */ 1231 MSVCRT_unexpected_function CDECL MSVCRT_set_unexpected(MSVCRT_unexpected_function func) 1232 { 1233 thread_data_t *data = msvcrt_get_thread_data(); 1234 MSVCRT_unexpected_function previous = data->unexpected_handler; 1235 TRACE("(%p) returning %p\n",func,previous); 1236 data->unexpected_handler = func; 1237 return previous; 1238 } 1239 1240 /****************************************************************** 1241 * _get_unexpected (MSVCRT.@) 1242 */ 1243 MSVCRT_unexpected_function CDECL MSVCRT__get_unexpected(void) 1244 { 1245 thread_data_t *data = msvcrt_get_thread_data(); 1246 TRACE("returning %p\n", data->unexpected_handler); 1247 return data->unexpected_handler; 1248 } 1249 1250 /****************************************************************** 1251 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@) 1252 */ 1253 MSVCRT__se_translator_function CDECL MSVCRT__set_se_translator(MSVCRT__se_translator_function func) 1254 { 1255 thread_data_t *data = msvcrt_get_thread_data(); 1256 MSVCRT__se_translator_function previous = data->se_translator; 1257 TRACE("(%p) returning %p\n",func,previous); 1258 data->se_translator = func; 1259 return previous; 1260 } 1261 1262 /****************************************************************** 1263 * ?terminate@@YAXXZ (MSVCRT.@) 1264 * 1265 * Default handler for an unhandled exception. 1266 * 1267 * PARAMS 1268 * None. 1269 * 1270 * RETURNS 1271 * This function does not return. Either control resumes from any 1272 * handler installed by calling set_terminate(), or (by default) abort() 1273 * is called. 1274 */ 1275 void CDECL MSVCRT_terminate(void) 1276 { 1277 thread_data_t *data = msvcrt_get_thread_data(); 1278 if (data->terminate_handler) data->terminate_handler(); 1279 MSVCRT_abort(); 1280 } 1281 1282 /****************************************************************** 1283 * ?unexpected@@YAXXZ (MSVCRT.@) 1284 */ 1285 void CDECL MSVCRT_unexpected(void) 1286 { 1287 thread_data_t *data = msvcrt_get_thread_data(); 1288 if (data->unexpected_handler) data->unexpected_handler(); 1289 MSVCRT_terminate(); 1290 } 1291 1292 1293 /****************************************************************** 1294 * __RTtypeid (MSVCRT.@) 1295 * 1296 * Retrieve the Run Time Type Information (RTTI) for a C++ object. 1297 * 1298 * PARAMS 1299 * cppobj [I] C++ object to get type information for. 1300 * 1301 * RETURNS 1302 * Success: A type_info object describing cppobj. 1303 * Failure: If the object to be cast has no RTTI, a __non_rtti_object 1304 * exception is thrown. If cppobj is NULL, a bad_typeid exception 1305 * is thrown. In either case, this function does not return. 1306 * 1307 * NOTES 1308 * This function is usually called by compiler generated code as a result 1309 * of using one of the C++ dynamic cast statements. 1310 */ 1311 #ifndef __x86_64__ 1312 const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) 1313 { 1314 const type_info *ret; 1315 1316 if (!cppobj) 1317 { 1318 bad_typeid e; 1319 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); 1320 _CxxThrowException( &e, &bad_typeid_exception_type ); 1321 return NULL; 1322 } 1323 1324 __TRY 1325 { 1326 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1327 ret = obj_locator->type_descriptor; 1328 } 1329 __EXCEPT_PAGE_FAULT 1330 { 1331 __non_rtti_object e; 1332 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); 1333 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1334 return NULL; 1335 } 1336 __ENDTRY 1337 return ret; 1338 } 1339 1340 #else 1341 1342 const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) 1343 { 1344 const type_info *ret; 1345 1346 if (!cppobj) 1347 { 1348 bad_typeid e; 1349 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); 1350 _CxxThrowException( &e, &bad_typeid_exception_type ); 1351 return NULL; 1352 } 1353 1354 __TRY 1355 { 1356 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1357 char *base; 1358 1359 if(obj_locator->signature == 0) 1360 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base); 1361 else 1362 base = (char*)obj_locator - obj_locator->object_locator; 1363 1364 ret = (type_info*)(base + obj_locator->type_descriptor); 1365 } 1366 __EXCEPT_PAGE_FAULT 1367 { 1368 __non_rtti_object e; 1369 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); 1370 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1371 return NULL; 1372 } 1373 __ENDTRY 1374 return ret; 1375 } 1376 #endif 1377 1378 /****************************************************************** 1379 * __RTDynamicCast (MSVCRT.@) 1380 * 1381 * Dynamically cast a C++ object to one of its base classes. 1382 * 1383 * PARAMS 1384 * cppobj [I] Any C++ object to cast 1385 * unknown [I] Reserved, set to 0 1386 * src [I] type_info object describing cppobj 1387 * dst [I] type_info object describing the base class to cast to 1388 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't 1389 * 1390 * RETURNS 1391 * Success: The address of cppobj, cast to the object described by dst. 1392 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a 1393 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception 1394 * is thrown and this function does not return. 1395 * 1396 * NOTES 1397 * This function is usually called by compiler generated code as a result 1398 * of using one of the C++ dynamic cast statements. 1399 */ 1400 #ifndef __x86_64__ 1401 void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, 1402 type_info *src, type_info *dst, 1403 int do_throw) 1404 { 1405 void *ret; 1406 1407 if (!cppobj) return NULL; 1408 1409 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", 1410 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); 1411 1412 /* To cast an object at runtime: 1413 * 1.Find out the true type of the object from the typeinfo at vtable[-1] 1414 * 2.Search for the destination type in the class hierarchy 1415 * 3.If destination type is found, return base object address + dest offset 1416 * Otherwise, fail the cast 1417 * 1418 * FIXME: the unknown parameter doesn't seem to be used for anything 1419 */ 1420 __TRY 1421 { 1422 int i; 1423 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1424 const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy; 1425 const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases; 1426 1427 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); 1428 1429 ret = NULL; 1430 for (i = 0; i < obj_bases->array_len; i++) 1431 { 1432 const type_info *typ = base_desc[i]->type_descriptor; 1433 1434 if (!strcmp(typ->mangled, dst->mangled)) 1435 { 1436 /* compute the correct this pointer for that base class */ 1437 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; 1438 ret = get_this_pointer( &base_desc[i]->offsets, this_ptr ); 1439 break; 1440 } 1441 } 1442 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned 1443 * to a reference, since references cannot be NULL. 1444 */ 1445 if (!ret && do_throw) 1446 { 1447 const char *msg = "Bad dynamic_cast!"; 1448 bad_cast e; 1449 MSVCRT_bad_cast_ctor( &e, &msg ); 1450 _CxxThrowException( &e, &bad_cast_exception_type ); 1451 } 1452 } 1453 __EXCEPT_PAGE_FAULT 1454 { 1455 __non_rtti_object e; 1456 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); 1457 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1458 return NULL; 1459 } 1460 __ENDTRY 1461 return ret; 1462 } 1463 1464 #else 1465 1466 void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, 1467 type_info *src, type_info *dst, 1468 int do_throw) 1469 { 1470 void *ret; 1471 1472 if (!cppobj) return NULL; 1473 1474 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", 1475 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); 1476 1477 __TRY 1478 { 1479 int i; 1480 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1481 const rtti_object_hierarchy *obj_bases; 1482 const rtti_base_array *base_array; 1483 char *base; 1484 1485 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); 1486 1487 if(obj_locator->signature == 0) 1488 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base); 1489 else 1490 base = (char*)obj_locator - obj_locator->object_locator; 1491 1492 obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy); 1493 base_array = (const rtti_base_array*)(base + obj_bases->base_classes); 1494 1495 ret = NULL; 1496 for (i = 0; i < obj_bases->array_len; i++) 1497 { 1498 const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]); 1499 const type_info *typ = (const type_info*)(base + base_desc->type_descriptor); 1500 1501 if (!strcmp(typ->mangled, dst->mangled)) 1502 { 1503 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; 1504 ret = get_this_pointer( &base_desc->offsets, this_ptr ); 1505 break; 1506 } 1507 } 1508 if (!ret && do_throw) 1509 { 1510 const char *msg = "Bad dynamic_cast!"; 1511 bad_cast e; 1512 MSVCRT_bad_cast_ctor( &e, &msg ); 1513 _CxxThrowException( &e, &bad_cast_exception_type ); 1514 } 1515 } 1516 __EXCEPT_PAGE_FAULT 1517 { 1518 __non_rtti_object e; 1519 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); 1520 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1521 return NULL; 1522 } 1523 __ENDTRY 1524 return ret; 1525 } 1526 #endif 1527 1528 1529 /****************************************************************** 1530 * __RTCastToVoid (MSVCRT.@) 1531 * 1532 * Dynamically cast a C++ object to a void*. 1533 * 1534 * PARAMS 1535 * cppobj [I] The C++ object to cast 1536 * 1537 * RETURNS 1538 * Success: The base address of the object as a void*. 1539 * Failure: NULL, if cppobj is NULL or has no RTTI. 1540 * 1541 * NOTES 1542 * This function is usually called by compiler generated code as a result 1543 * of using one of the C++ dynamic cast statements. 1544 */ 1545 void* CDECL MSVCRT___RTCastToVoid(void *cppobj) 1546 { 1547 void *ret; 1548 1549 if (!cppobj) return NULL; 1550 1551 __TRY 1552 { 1553 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1554 ret = (char *)cppobj - obj_locator->base_class_offset; 1555 } 1556 __EXCEPT_PAGE_FAULT 1557 { 1558 __non_rtti_object e; 1559 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); 1560 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1561 return NULL; 1562 } 1563 __ENDTRY 1564 return ret; 1565 } 1566 1567 1568 /********************************************************************* 1569 * _CxxThrowException (MSVCRT.@) 1570 */ 1571 #ifndef __x86_64__ 1572 void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) 1573 { 1574 ULONG_PTR args[3]; 1575 1576 args[0] = CXX_FRAME_MAGIC_VC6; 1577 args[1] = (ULONG_PTR)object; 1578 args[2] = (ULONG_PTR)type; 1579 RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); 1580 } 1581 #else 1582 void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) 1583 { 1584 ULONG_PTR args[4]; 1585 1586 args[0] = CXX_FRAME_MAGIC_VC6; 1587 args[1] = (ULONG_PTR)object; 1588 args[2] = (ULONG_PTR)type; 1589 RtlPcToFileHeader( (void*)type, (void**)&args[3]); 1590 RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 4, args ); 1591 } 1592 #endif 1593 1594 #if _MSVCR_VER >= 80 1595 1596 /********************************************************************* 1597 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z 1598 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z 1599 */ 1600 #ifndef __x86_64__ 1601 int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) 1602 { 1603 int ret = -1; 1604 1605 TRACE("(%p %p)\n", ti, ep); 1606 1607 __TRY 1608 { 1609 EXCEPTION_RECORD *rec = ep->ExceptionRecord; 1610 1611 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 && 1612 (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 || 1613 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 || 1614 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8)) 1615 { 1616 const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table; 1617 int i; 1618 1619 for (i=0; i<tit->count; i++) { 1620 if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled)) 1621 { 1622 ret = 1; 1623 break; 1624 } 1625 } 1626 1627 if (i == tit->count) 1628 ret = 0; 1629 } 1630 } 1631 __EXCEPT_PAGE_FAULT 1632 __ENDTRY 1633 1634 if(ret == -1) 1635 MSVCRT_terminate(); 1636 return ret; 1637 } 1638 #else 1639 int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) 1640 { 1641 int ret = -1; 1642 1643 TRACE("(%p %p)\n", ti, ep); 1644 1645 __TRY 1646 { 1647 EXCEPTION_RECORD *rec = ep->ExceptionRecord; 1648 1649 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 && 1650 (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 || 1651 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 || 1652 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8)) 1653 { 1654 const cxx_exception_type *et = (cxx_exception_type*)rec->ExceptionInformation[2]; 1655 const cxx_type_info_table *tit = (const cxx_type_info_table*)(rec->ExceptionInformation[3]+et->type_info_table); 1656 int i; 1657 1658 for (i=0; i<tit->count; i++) { 1659 const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]); 1660 const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info); 1661 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled)) 1662 { 1663 ret = 1; 1664 break; 1665 } 1666 } 1667 1668 if (i == tit->count) 1669 ret = 0; 1670 } 1671 } 1672 __EXCEPT_PAGE_FAULT 1673 __ENDTRY 1674 1675 if(ret == -1) 1676 MSVCRT_terminate(); 1677 return ret; 1678 } 1679 #endif 1680 1681 /********************************************************************* 1682 * __clean_type_info_names_internal (MSVCR80.@) 1683 */ 1684 void CDECL __clean_type_info_names_internal(void *p) 1685 { 1686 FIXME("(%p) stub\n", p); 1687 } 1688 1689 /********************************************************************* 1690 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@) 1691 */ 1692 DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8) 1693 const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node) 1694 { 1695 static int once; 1696 if (node && !once++) FIXME("type_info_node parameter ignored\n"); 1697 1698 return MSVCRT_type_info_name(_this); 1699 } 1700 1701 #endif /* _MSVCR_VER >= 80 */ 1702 1703 /* std::exception_ptr class helpers */ 1704 typedef struct 1705 { 1706 EXCEPTION_RECORD *rec; 1707 int *ref; /* not binary compatible with native msvcr100 */ 1708 } exception_ptr; 1709 1710 #if _MSVCR_VER >= 100 1711 1712 /********************************************************************* 1713 * ?__ExceptionPtrCreate@@YAXPAX@Z 1714 * ?__ExceptionPtrCreate@@YAXPEAX@Z 1715 */ 1716 void __cdecl __ExceptionPtrCreate(exception_ptr *ep) 1717 { 1718 TRACE("(%p)\n", ep); 1719 1720 ep->rec = NULL; 1721 ep->ref = NULL; 1722 } 1723 1724 #if defined(__i386__) && !defined(__MINGW32__) 1725 extern void call_dtor(const cxx_exception_type *type, void *func, void *object); 1726 1727 __ASM_GLOBAL_FUNC( call_dtor, 1728 "movl 12(%esp),%ecx\n\t" 1729 "call *8(%esp)\n\t" 1730 "ret" ); 1731 #elif __x86_64__ 1732 static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object) 1733 { 1734 char *base = RtlPcToFileHeader((void*)type, (void**)&base); 1735 void (__cdecl *func)(void*) = (void*)(base + dtor); 1736 func(object); 1737 } 1738 #else 1739 #define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object) 1740 #endif 1741 1742 /********************************************************************* 1743 * ?__ExceptionPtrDestroy@@YAXPAX@Z 1744 * ?__ExceptionPtrDestroy@@YAXPEAX@Z 1745 */ 1746 void __cdecl __ExceptionPtrDestroy(exception_ptr *ep) 1747 { 1748 TRACE("(%p)\n", ep); 1749 1750 if (!ep->rec) 1751 return; 1752 1753 if (!InterlockedDecrement(ep->ref)) 1754 { 1755 if (ep->rec->ExceptionCode == CXX_EXCEPTION) 1756 { 1757 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2]; 1758 void *obj = (void*)ep->rec->ExceptionInformation[1]; 1759 1760 if (type && type->destructor) call_dtor(type, type->destructor, obj); 1761 HeapFree(GetProcessHeap(), 0, obj); 1762 } 1763 1764 HeapFree(GetProcessHeap(), 0, ep->rec); 1765 HeapFree(GetProcessHeap(), 0, ep->ref); 1766 } 1767 } 1768 1769 /********************************************************************* 1770 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z 1771 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z 1772 */ 1773 void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy) 1774 { 1775 TRACE("(%p %p)\n", ep, copy); 1776 1777 /* don't destroy object stored in ep */ 1778 *ep = *copy; 1779 if (ep->ref) 1780 InterlockedIncrement(copy->ref); 1781 } 1782 1783 /********************************************************************* 1784 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z 1785 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z 1786 */ 1787 void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign) 1788 { 1789 TRACE("(%p %p)\n", ep, assign); 1790 1791 /* don't destroy object stored in ep */ 1792 if (ep->ref) 1793 InterlockedDecrement(ep->ref); 1794 1795 *ep = *assign; 1796 if (ep->ref) 1797 InterlockedIncrement(ep->ref); 1798 } 1799 1800 #endif /* _MSVCR_VER >= 100 */ 1801 1802 /********************************************************************* 1803 * ?__ExceptionPtrRethrow@@YAXPBX@Z 1804 * ?__ExceptionPtrRethrow@@YAXPEBX@Z 1805 */ 1806 void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep) 1807 { 1808 TRACE("(%p)\n", ep); 1809 1810 if (!ep->rec) 1811 { 1812 static const char *exception_msg = "bad exception"; 1813 exception e; 1814 1815 MSVCRT_exception_ctor(&e, &exception_msg); 1816 _CxxThrowException(&e, &exception_exception_type); 1817 return; 1818 } 1819 1820 RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING), 1821 ep->rec->NumberParameters, ep->rec->ExceptionInformation); 1822 } 1823 1824 #if _MSVCR_VER >= 100 1825 1826 #ifdef __i386__ 1827 extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); 1828 #else 1829 static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) 1830 { 1831 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src ); 1832 if (has_vbase) 1833 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1); 1834 else 1835 ((void (__cdecl*)(void*, void*))func)(this, src); 1836 } 1837 #endif 1838 1839 /********************************************************************* 1840 * ?__ExceptionPtrCurrentException@@YAXPAX@Z 1841 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z 1842 */ 1843 #ifndef __x86_64__ 1844 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) 1845 { 1846 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; 1847 1848 TRACE("(%p)\n", ep); 1849 1850 if (!rec) 1851 { 1852 ep->rec = NULL; 1853 ep->ref = NULL; 1854 return; 1855 } 1856 1857 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 1858 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 1859 1860 *ep->rec = *rec; 1861 *ep->ref = 1; 1862 1863 if (ep->rec->ExceptionCode == CXX_EXCEPTION) 1864 { 1865 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; 1866 const cxx_type_info *ti; 1867 void **data, *obj; 1868 1869 ti = et->type_info_table->info[0]; 1870 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 1871 1872 obj = (void*)ep->rec->ExceptionInformation[1]; 1873 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 1874 { 1875 memcpy(data, obj, ti->size); 1876 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 1877 } 1878 else if (ti->copy_ctor) 1879 { 1880 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), 1881 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 1882 } 1883 else 1884 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); 1885 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 1886 } 1887 return; 1888 } 1889 #else 1890 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) 1891 { 1892 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; 1893 1894 TRACE("(%p)\n", ep); 1895 1896 if (!rec) 1897 { 1898 ep->rec = NULL; 1899 ep->ref = NULL; 1900 return; 1901 } 1902 1903 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 1904 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 1905 1906 *ep->rec = *rec; 1907 *ep->ref = 1; 1908 1909 if (ep->rec->ExceptionCode == CXX_EXCEPTION) 1910 { 1911 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; 1912 const cxx_type_info *ti; 1913 void **data, *obj; 1914 char *base = RtlPcToFileHeader((void*)et, (void**)&base); 1915 1916 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]); 1917 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 1918 1919 obj = (void*)ep->rec->ExceptionInformation[1]; 1920 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 1921 { 1922 memcpy(data, obj, ti->size); 1923 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 1924 } 1925 else if (ti->copy_ctor) 1926 { 1927 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), 1928 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 1929 } 1930 else 1931 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); 1932 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 1933 } 1934 return; 1935 } 1936 #endif 1937 1938 #endif /* _MSVCR_VER >= 100 */ 1939 1940 #if _MSVCR_VER >= 110 1941 /********************************************************************* 1942 * ?__ExceptionPtrToBool@@YA_NPBX@Z 1943 * ?__ExceptionPtrToBool@@YA_NPEBX@Z 1944 */ 1945 MSVCRT_bool __cdecl __ExceptionPtrToBool(exception_ptr *ep) 1946 { 1947 return !!ep->rec; 1948 } 1949 #endif 1950 1951 #if _MSVCR_VER >= 100 1952 1953 /********************************************************************* 1954 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z 1955 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z 1956 */ 1957 #ifndef __x86_64__ 1958 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, 1959 exception *object, const cxx_exception_type *type) 1960 { 1961 const cxx_type_info *ti; 1962 void **data; 1963 1964 __ExceptionPtrDestroy(ep); 1965 1966 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 1967 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 1968 *ep->ref = 1; 1969 1970 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); 1971 ep->rec->ExceptionCode = CXX_EXCEPTION; 1972 ep->rec->ExceptionFlags = EH_NONCONTINUABLE; 1973 ep->rec->NumberParameters = 3; 1974 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; 1975 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; 1976 1977 ti = type->type_info_table->info[0]; 1978 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 1979 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 1980 { 1981 memcpy(data, object, ti->size); 1982 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 1983 } 1984 else if (ti->copy_ctor) 1985 { 1986 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), 1987 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 1988 } 1989 else 1990 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); 1991 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 1992 } 1993 #else 1994 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, 1995 exception *object, const cxx_exception_type *type) 1996 { 1997 const cxx_type_info *ti; 1998 void **data; 1999 char *base; 2000 2001 RtlPcToFileHeader((void*)type, (void**)&base); 2002 __ExceptionPtrDestroy(ep); 2003 2004 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 2005 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 2006 *ep->ref = 1; 2007 2008 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); 2009 ep->rec->ExceptionCode = CXX_EXCEPTION; 2010 ep->rec->ExceptionFlags = EH_NONCONTINUABLE; 2011 ep->rec->NumberParameters = 4; 2012 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; 2013 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; 2014 ep->rec->ExceptionInformation[3] = (ULONG_PTR)base; 2015 2016 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]); 2017 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 2018 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 2019 { 2020 memcpy(data, object, ti->size); 2021 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 2022 } 2023 else if (ti->copy_ctor) 2024 { 2025 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), 2026 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 2027 } 2028 else 2029 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); 2030 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 2031 } 2032 #endif 2033 2034 MSVCRT_bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2) 2035 { 2036 return ep1->rec == ep2->rec; 2037 } 2038 2039 #endif /* _MSVCR_VER >= 100 */ 2040 2041 #if _MSVCR_VER >= 80 2042 void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off) 2043 { 2044 return get_this_pointer(off, obj); 2045 } 2046 #endif 2047 2048 #if _MSVCR_VER >= 140 2049 2050 typedef struct 2051 { 2052 char *name; 2053 char mangled[1]; 2054 } type_info140; 2055 2056 typedef struct 2057 { 2058 SLIST_ENTRY entry; 2059 char name[1]; 2060 } type_info_entry; 2061 2062 static void* CDECL type_info_entry_malloc(MSVCRT_size_t size) 2063 { 2064 type_info_entry *ret = MSVCRT_malloc(FIELD_OFFSET(type_info_entry, name) + size); 2065 return ret->name; 2066 } 2067 2068 static void CDECL type_info_entry_free(void *ptr) 2069 { 2070 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name); 2071 MSVCRT_free(ptr); 2072 } 2073 2074 /****************************************************************** 2075 * __std_type_info_compare (UCRTBASE.@) 2076 */ 2077 int CDECL MSVCRT_type_info_compare(const type_info140 *l, const type_info140 *r) 2078 { 2079 int ret; 2080 2081 if (l == r) ret = 0; 2082 else ret = MSVCRT_strcmp(l->mangled + 1, r->mangled + 1); 2083 TRACE("(%p %p) returning %d\n", l, r, ret); 2084 return ret; 2085 } 2086 2087 /****************************************************************** 2088 * __std_type_info_name (UCRTBASE.@) 2089 */ 2090 const char* CDECL MSVCRT_type_info_name_list(type_info140 *ti, SLIST_HEADER *header) 2091 { 2092 if (!ti->name) 2093 { 2094 char* name = __unDName(0, ti->mangled + 1, 0, 2095 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); 2096 if (name) 2097 { 2098 unsigned int len = strlen(name); 2099 2100 while (len && name[--len] == ' ') 2101 name[len] = '\0'; 2102 2103 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL)) 2104 { 2105 type_info_entry_free(name); 2106 } 2107 else 2108 { 2109 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name)); 2110 InterlockedPushEntrySList(header, &entry->entry); 2111 } 2112 } 2113 } 2114 TRACE("(%p) returning %s\n", ti, ti->name); 2115 return ti->name; 2116 } 2117 2118 /****************************************************************** 2119 * __std_type_info_destroy_list (UCRTBASE.@) 2120 */ 2121 void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header) 2122 { 2123 SLIST_ENTRY *cur, *next; 2124 2125 TRACE("(%p)\n", header); 2126 2127 for(cur = InterlockedFlushSList(header); cur; cur = next) 2128 { 2129 next = cur->Next; 2130 MSVCRT_free(cur); 2131 } 2132 } 2133 2134 /****************************************************************** 2135 * __std_type_info_hash (UCRTBASE.@) 2136 */ 2137 MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti) 2138 { 2139 MSVCRT_size_t hash, fnv_prime; 2140 const char *p; 2141 2142 #ifdef _WIN64 2143 hash = 0xcbf29ce484222325; 2144 fnv_prime = 0x100000001b3; 2145 #else 2146 hash = 0x811c9dc5; 2147 fnv_prime = 0x1000193; 2148 #endif 2149 2150 TRACE("(%p)->%s\n", ti, ti->mangled); 2151 2152 for(p = ti->mangled+1; *p; p++) { 2153 hash ^= *p; 2154 hash *= fnv_prime; 2155 } 2156 2157 #ifdef _WIN64 2158 hash ^= hash >> 32; 2159 #endif 2160 2161 return hash; 2162 } 2163 2164 #endif /* _MSVCR_VER >= 140 */ 2165 2166 #if _MSVCR_VER >= 100 2167 2168 enum ConcRT_EventType 2169 { 2170 CONCRT_EVENT_GENERIC, 2171 CONCRT_EVENT_START, 2172 CONCRT_EVENT_END, 2173 CONCRT_EVENT_BLOCK, 2174 CONCRT_EVENT_UNBLOCK, 2175 CONCRT_EVENT_YIELD, 2176 CONCRT_EVENT_ATTACH, 2177 CONCRT_EVENT_DETACH 2178 }; 2179 2180 /* ?_Trace_ppl_function@Concurrency@@YAXABU_GUID@@EW4ConcRT_EventType@1@@Z */ 2181 /* ?_Trace_ppl_function@Concurrency@@YAXAEBU_GUID@@EW4ConcRT_EventType@1@@Z */ 2182 void __cdecl Concurrency__Trace_ppl_function(const GUID *guid, unsigned char level, enum ConcRT_EventType type) 2183 { 2184 FIXME("(%s %u %i) stub\n", debugstr_guid(guid), level, type); 2185 } 2186 2187 #endif /* _MSVCR_VER >= 100 */ 2188