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 _MSC_VER 999 #ifndef __GNUC__ 1000 void __asm_dummy_vtables(void) { 1001 #endif 1002 1003 __ASM_VTABLE(type_info, 1004 VTABLE_ADD_FUNC(MSVCRT_type_info_vector_dtor)); 1005 __ASM_VTABLE(exception, 1006 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1007 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1008 #if _MSVCR_VER >= 80 1009 __ASM_VTABLE(exception_old, 1010 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1011 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1012 __ASM_VTABLE(bad_alloc, 1013 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1014 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1015 #endif 1016 __ASM_VTABLE(bad_typeid, 1017 VTABLE_ADD_FUNC(MSVCRT_bad_typeid_vector_dtor) 1018 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1019 __ASM_VTABLE(bad_cast, 1020 VTABLE_ADD_FUNC(MSVCRT_bad_cast_vector_dtor) 1021 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1022 __ASM_VTABLE(__non_rtti_object, 1023 VTABLE_ADD_FUNC(MSVCRT___non_rtti_object_vector_dtor) 1024 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1025 #if _MSVCR_VER >= 100 1026 __ASM_VTABLE(scheduler_resource_allocation_error, 1027 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1028 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1029 __ASM_VTABLE(improper_lock, 1030 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1031 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1032 __ASM_VTABLE(invalid_scheduler_policy_key, 1033 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1034 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1035 __ASM_VTABLE(invalid_scheduler_policy_value, 1036 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1037 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1038 __ASM_VTABLE(invalid_scheduler_policy_thread_specification, 1039 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1040 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1041 __ASM_VTABLE(improper_scheduler_attach, 1042 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1043 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1044 __ASM_VTABLE(improper_scheduler_detach, 1045 VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) 1046 VTABLE_ADD_FUNC(MSVCRT_what_exception)); 1047 #endif 1048 1049 #ifndef __GNUC__ 1050 } 1051 #endif 1052 #endif /* !_MSC_VER */ 1053 1054 DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" ) 1055 #if _MSVCR_VER >= 80 1056 DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@std@@" ) 1057 DEFINE_RTTI_DATA0( exception_old, 0, ".?AVexception@@" ) 1058 DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@std@@" ) 1059 DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@std@@" ) 1060 DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@std@@" ) 1061 DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" ) 1062 #else 1063 DEFINE_RTTI_DATA0( exception, 0, ".?AVexception@@" ) 1064 DEFINE_RTTI_DATA1( bad_typeid, 0, &exception_rtti_base_descriptor, ".?AVbad_typeid@@" ) 1065 DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@" ) 1066 DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" ) 1067 #endif 1068 #if _MSVCR_VER >= 100 1069 DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &exception_rtti_base_descriptor, 1070 ".?AVscheduler_resource_allocation_error@Concurrency@@") 1071 DEFINE_RTTI_DATA1(improper_lock, 0, &exception_rtti_base_descriptor, ".?AVimproper_lock@Concurrency@@" ) 1072 DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &exception_rtti_base_descriptor, 1073 ".?AVinvalid_scheduler_policy_key@Concurrency@@" ) 1074 DEFINE_RTTI_DATA1(invalid_scheduler_policy_value, 0, &exception_rtti_base_descriptor, 1075 ".?AVinvalid_scheduler_policy_value@Concurrency@@" ) 1076 DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &exception_rtti_base_descriptor, 1077 ".?AVinvalid_scheduler_policy_thread_specification@Concurrency@@" ) 1078 DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &exception_rtti_base_descriptor, 1079 ".?AVimproper_scheduler_attach@Concurrency@@" ) 1080 DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &exception_rtti_base_descriptor, 1081 ".?AVimproper_scheduler_detach@Concurrency@@" ) 1082 #endif 1083 1084 DEFINE_EXCEPTION_TYPE_INFO( exception, 0, NULL, NULL ) 1085 DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL ) 1086 DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL ) 1087 DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info ) 1088 #if _MSVCR_VER >= 80 1089 DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL ) 1090 #endif 1091 #if _MSVCR_VER >= 100 1092 DEFINE_EXCEPTION_TYPE_INFO(scheduler_resource_allocation_error, 1, &exception_cxx_type_info, NULL) 1093 DEFINE_EXCEPTION_TYPE_INFO(improper_lock, 1, &exception_cxx_type_info, NULL) 1094 DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_key, 1, &exception_cxx_type_info, NULL) 1095 DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_value, 1, &exception_cxx_type_info, NULL) 1096 DEFINE_EXCEPTION_TYPE_INFO(invalid_scheduler_policy_thread_specification, 1, &exception_cxx_type_info, NULL) 1097 DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_attach, 1, &exception_cxx_type_info, NULL) 1098 DEFINE_EXCEPTION_TYPE_INFO(improper_scheduler_detach, 1, &exception_cxx_type_info, NULL) 1099 #endif 1100 1101 void msvcrt_init_exception(void *base) 1102 { 1103 #ifdef __x86_64__ 1104 init_type_info_rtti(base); 1105 init_exception_rtti(base); 1106 #if _MSVCR_VER >= 80 1107 init_exception_old_rtti(base); 1108 init_bad_alloc_rtti(base); 1109 #endif 1110 init_bad_typeid_rtti(base); 1111 init_bad_cast_rtti(base); 1112 init___non_rtti_object_rtti(base); 1113 #if _MSVCR_VER >= 100 1114 init_scheduler_resource_allocation_error_rtti(base); 1115 init_improper_lock_rtti(base); 1116 init_invalid_scheduler_policy_key_rtti(base); 1117 init_invalid_scheduler_policy_value_rtti(base); 1118 init_invalid_scheduler_policy_thread_specification_rtti(base); 1119 init_improper_scheduler_attach_rtti(base); 1120 init_improper_scheduler_detach_rtti(base); 1121 #endif 1122 1123 init_exception_cxx(base); 1124 init_bad_typeid_cxx(base); 1125 init_bad_cast_cxx(base); 1126 init___non_rtti_object_cxx(base); 1127 #if _MSVCR_VER >= 80 1128 init_bad_alloc_cxx(base); 1129 #endif 1130 #if _MSVCR_VER >= 100 1131 init_scheduler_resource_allocation_error_cxx(base); 1132 init_improper_lock_cxx(base); 1133 init_invalid_scheduler_policy_key_cxx(base); 1134 init_invalid_scheduler_policy_value_cxx(base); 1135 init_invalid_scheduler_policy_thread_specification_cxx(base); 1136 init_improper_scheduler_attach_cxx(base); 1137 init_improper_scheduler_detach_cxx(base); 1138 #endif 1139 #endif 1140 } 1141 1142 #if _MSVCR_VER >= 80 1143 void throw_exception(exception_type et, HRESULT hr, const char *str) 1144 { 1145 switch(et) { 1146 case EXCEPTION_BAD_ALLOC: { 1147 bad_alloc e; 1148 bad_alloc_ctor(&e, &str); 1149 _CxxThrowException(&e, &bad_alloc_exception_type); 1150 } 1151 #if _MSVCR_VER >= 100 1152 case EXCEPTION_SCHEDULER_RESOURCE_ALLOCATION_ERROR: { 1153 scheduler_resource_allocation_error e; 1154 scheduler_resource_allocation_error_ctor_name(&e, str, hr); 1155 _CxxThrowException(&e.e, &scheduler_resource_allocation_error_exception_type); 1156 } 1157 case EXCEPTION_IMPROPER_LOCK: { 1158 improper_lock e; 1159 improper_lock_ctor_str(&e, str); 1160 _CxxThrowException(&e, &improper_lock_exception_type); 1161 } 1162 case EXCEPTION_INVALID_SCHEDULER_POLICY_KEY: { 1163 invalid_scheduler_policy_key e; 1164 invalid_scheduler_policy_key_ctor_str(&e, str); 1165 _CxxThrowException(&e, &invalid_scheduler_policy_key_exception_type); 1166 } 1167 case EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE: { 1168 invalid_scheduler_policy_value e; 1169 invalid_scheduler_policy_value_ctor_str(&e, str); 1170 _CxxThrowException(&e, &invalid_scheduler_policy_value_exception_type); 1171 } 1172 case EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION: { 1173 invalid_scheduler_policy_thread_specification e; 1174 invalid_scheduler_policy_thread_specification_ctor_str(&e, str); 1175 _CxxThrowException(&e, &invalid_scheduler_policy_thread_specification_exception_type); 1176 } 1177 case EXCEPTION_IMPROPER_SCHEDULER_ATTACH: { 1178 improper_scheduler_attach e; 1179 improper_scheduler_attach_ctor_str(&e, str); 1180 _CxxThrowException(&e, &improper_scheduler_attach_exception_type); 1181 } 1182 case EXCEPTION_IMPROPER_SCHEDULER_DETACH: { 1183 improper_scheduler_detach e; 1184 improper_scheduler_detach_ctor_str(&e, str); 1185 _CxxThrowException(&e, &improper_scheduler_detach_exception_type); 1186 } 1187 #endif 1188 } 1189 } 1190 #endif 1191 1192 /****************************************************************** 1193 * ?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) 1194 * 1195 * Install a handler to be called when terminate() is called. 1196 * 1197 * PARAMS 1198 * func [I] Handler function to install 1199 * 1200 * RETURNS 1201 * The previously installed handler function, if any. 1202 */ 1203 MSVCRT_terminate_function CDECL MSVCRT_set_terminate(MSVCRT_terminate_function func) 1204 { 1205 thread_data_t *data = msvcrt_get_thread_data(); 1206 MSVCRT_terminate_function previous = data->terminate_handler; 1207 TRACE("(%p) returning %p\n",func,previous); 1208 data->terminate_handler = func; 1209 return previous; 1210 } 1211 1212 /****************************************************************** 1213 * _get_terminate (MSVCRT.@) 1214 */ 1215 MSVCRT_terminate_function CDECL MSVCRT__get_terminate(void) 1216 { 1217 thread_data_t *data = msvcrt_get_thread_data(); 1218 TRACE("returning %p\n", data->terminate_handler); 1219 return data->terminate_handler; 1220 } 1221 1222 /****************************************************************** 1223 * ?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@) 1224 * 1225 * Install a handler to be called when unexpected() is called. 1226 * 1227 * PARAMS 1228 * func [I] Handler function to install 1229 * 1230 * RETURNS 1231 * The previously installed handler function, if any. 1232 */ 1233 MSVCRT_unexpected_function CDECL MSVCRT_set_unexpected(MSVCRT_unexpected_function func) 1234 { 1235 thread_data_t *data = msvcrt_get_thread_data(); 1236 MSVCRT_unexpected_function previous = data->unexpected_handler; 1237 TRACE("(%p) returning %p\n",func,previous); 1238 data->unexpected_handler = func; 1239 return previous; 1240 } 1241 1242 /****************************************************************** 1243 * _get_unexpected (MSVCRT.@) 1244 */ 1245 MSVCRT_unexpected_function CDECL MSVCRT__get_unexpected(void) 1246 { 1247 thread_data_t *data = msvcrt_get_thread_data(); 1248 TRACE("returning %p\n", data->unexpected_handler); 1249 return data->unexpected_handler; 1250 } 1251 1252 /****************************************************************** 1253 * ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z (MSVCRT.@) 1254 */ 1255 MSVCRT__se_translator_function CDECL MSVCRT__set_se_translator(MSVCRT__se_translator_function func) 1256 { 1257 thread_data_t *data = msvcrt_get_thread_data(); 1258 MSVCRT__se_translator_function previous = data->se_translator; 1259 TRACE("(%p) returning %p\n",func,previous); 1260 data->se_translator = func; 1261 return previous; 1262 } 1263 1264 /****************************************************************** 1265 * ?terminate@@YAXXZ (MSVCRT.@) 1266 * 1267 * Default handler for an unhandled exception. 1268 * 1269 * PARAMS 1270 * None. 1271 * 1272 * RETURNS 1273 * This function does not return. Either control resumes from any 1274 * handler installed by calling set_terminate(), or (by default) abort() 1275 * is called. 1276 */ 1277 void CDECL MSVCRT_terminate(void) 1278 { 1279 thread_data_t *data = msvcrt_get_thread_data(); 1280 if (data->terminate_handler) data->terminate_handler(); 1281 MSVCRT_abort(); 1282 } 1283 1284 /****************************************************************** 1285 * ?unexpected@@YAXXZ (MSVCRT.@) 1286 */ 1287 void CDECL MSVCRT_unexpected(void) 1288 { 1289 thread_data_t *data = msvcrt_get_thread_data(); 1290 if (data->unexpected_handler) data->unexpected_handler(); 1291 MSVCRT_terminate(); 1292 } 1293 1294 1295 /****************************************************************** 1296 * __RTtypeid (MSVCRT.@) 1297 * 1298 * Retrieve the Run Time Type Information (RTTI) for a C++ object. 1299 * 1300 * PARAMS 1301 * cppobj [I] C++ object to get type information for. 1302 * 1303 * RETURNS 1304 * Success: A type_info object describing cppobj. 1305 * Failure: If the object to be cast has no RTTI, a __non_rtti_object 1306 * exception is thrown. If cppobj is NULL, a bad_typeid exception 1307 * is thrown. In either case, this function does not return. 1308 * 1309 * NOTES 1310 * This function is usually called by compiler generated code as a result 1311 * of using one of the C++ dynamic cast statements. 1312 */ 1313 #ifndef __x86_64__ 1314 const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) 1315 { 1316 const type_info *ret; 1317 1318 if (!cppobj) 1319 { 1320 bad_typeid e; 1321 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); 1322 _CxxThrowException( &e, &bad_typeid_exception_type ); 1323 return NULL; 1324 } 1325 1326 __TRY 1327 { 1328 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1329 ret = obj_locator->type_descriptor; 1330 } 1331 __EXCEPT_PAGE_FAULT 1332 { 1333 __non_rtti_object e; 1334 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); 1335 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1336 return NULL; 1337 } 1338 __ENDTRY 1339 return ret; 1340 } 1341 1342 #else 1343 1344 const type_info* CDECL MSVCRT___RTtypeid(void *cppobj) 1345 { 1346 const type_info *ret; 1347 1348 if (!cppobj) 1349 { 1350 bad_typeid e; 1351 MSVCRT_bad_typeid_ctor( &e, "Attempted a typeid of NULL pointer!" ); 1352 _CxxThrowException( &e, &bad_typeid_exception_type ); 1353 return NULL; 1354 } 1355 1356 __TRY 1357 { 1358 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1359 char *base; 1360 1361 if(obj_locator->signature == 0) 1362 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base); 1363 else 1364 base = (char*)obj_locator - obj_locator->object_locator; 1365 1366 ret = (type_info*)(base + obj_locator->type_descriptor); 1367 } 1368 __EXCEPT_PAGE_FAULT 1369 { 1370 __non_rtti_object e; 1371 MSVCRT___non_rtti_object_ctor( &e, "Bad read pointer - no RTTI data!" ); 1372 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1373 return NULL; 1374 } 1375 __ENDTRY 1376 return ret; 1377 } 1378 #endif 1379 1380 /****************************************************************** 1381 * __RTDynamicCast (MSVCRT.@) 1382 * 1383 * Dynamically cast a C++ object to one of its base classes. 1384 * 1385 * PARAMS 1386 * cppobj [I] Any C++ object to cast 1387 * unknown [I] Reserved, set to 0 1388 * src [I] type_info object describing cppobj 1389 * dst [I] type_info object describing the base class to cast to 1390 * do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't 1391 * 1392 * RETURNS 1393 * Success: The address of cppobj, cast to the object described by dst. 1394 * Failure: NULL, If the object to be cast has no RTTI, or dst is not a 1395 * valid cast for cppobj. If do_throw is TRUE, a bad_cast exception 1396 * is thrown and this function does not return. 1397 * 1398 * NOTES 1399 * This function is usually called by compiler generated code as a result 1400 * of using one of the C++ dynamic cast statements. 1401 */ 1402 #ifndef __x86_64__ 1403 void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, 1404 type_info *src, type_info *dst, 1405 int do_throw) 1406 { 1407 void *ret; 1408 1409 if (!cppobj) return NULL; 1410 1411 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", 1412 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); 1413 1414 /* To cast an object at runtime: 1415 * 1.Find out the true type of the object from the typeinfo at vtable[-1] 1416 * 2.Search for the destination type in the class hierarchy 1417 * 3.If destination type is found, return base object address + dest offset 1418 * Otherwise, fail the cast 1419 * 1420 * FIXME: the unknown parameter doesn't seem to be used for anything 1421 */ 1422 __TRY 1423 { 1424 int i; 1425 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1426 const rtti_object_hierarchy *obj_bases = obj_locator->type_hierarchy; 1427 const rtti_base_descriptor * const* base_desc = obj_bases->base_classes->bases; 1428 1429 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); 1430 1431 ret = NULL; 1432 for (i = 0; i < obj_bases->array_len; i++) 1433 { 1434 const type_info *typ = base_desc[i]->type_descriptor; 1435 1436 if (!strcmp(typ->mangled, dst->mangled)) 1437 { 1438 /* compute the correct this pointer for that base class */ 1439 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; 1440 ret = get_this_pointer( &base_desc[i]->offsets, this_ptr ); 1441 break; 1442 } 1443 } 1444 /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned 1445 * to a reference, since references cannot be NULL. 1446 */ 1447 if (!ret && do_throw) 1448 { 1449 const char *msg = "Bad dynamic_cast!"; 1450 bad_cast e; 1451 MSVCRT_bad_cast_ctor( &e, &msg ); 1452 _CxxThrowException( &e, &bad_cast_exception_type ); 1453 } 1454 } 1455 __EXCEPT_PAGE_FAULT 1456 { 1457 __non_rtti_object e; 1458 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); 1459 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1460 return NULL; 1461 } 1462 __ENDTRY 1463 return ret; 1464 } 1465 1466 #else 1467 1468 void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown, 1469 type_info *src, type_info *dst, 1470 int do_throw) 1471 { 1472 void *ret; 1473 1474 if (!cppobj) return NULL; 1475 1476 TRACE("obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)\n", 1477 cppobj, unknown, src, dbgstr_type_info(src), dst, dbgstr_type_info(dst), do_throw); 1478 1479 __TRY 1480 { 1481 int i; 1482 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1483 const rtti_object_hierarchy *obj_bases; 1484 const rtti_base_array *base_array; 1485 char *base; 1486 1487 if (TRACE_ON(msvcrt)) dump_obj_locator(obj_locator); 1488 1489 if(obj_locator->signature == 0) 1490 base = RtlPcToFileHeader((void*)obj_locator, (void**)&base); 1491 else 1492 base = (char*)obj_locator - obj_locator->object_locator; 1493 1494 obj_bases = (const rtti_object_hierarchy*)(base + obj_locator->type_hierarchy); 1495 base_array = (const rtti_base_array*)(base + obj_bases->base_classes); 1496 1497 ret = NULL; 1498 for (i = 0; i < obj_bases->array_len; i++) 1499 { 1500 const rtti_base_descriptor *base_desc = (const rtti_base_descriptor*)(base + base_array->bases[i]); 1501 const type_info *typ = (const type_info*)(base + base_desc->type_descriptor); 1502 1503 if (!strcmp(typ->mangled, dst->mangled)) 1504 { 1505 void *this_ptr = (char *)cppobj - obj_locator->base_class_offset; 1506 ret = get_this_pointer( &base_desc->offsets, this_ptr ); 1507 break; 1508 } 1509 } 1510 if (!ret && do_throw) 1511 { 1512 const char *msg = "Bad dynamic_cast!"; 1513 bad_cast e; 1514 MSVCRT_bad_cast_ctor( &e, &msg ); 1515 _CxxThrowException( &e, &bad_cast_exception_type ); 1516 } 1517 } 1518 __EXCEPT_PAGE_FAULT 1519 { 1520 __non_rtti_object e; 1521 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); 1522 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1523 return NULL; 1524 } 1525 __ENDTRY 1526 return ret; 1527 } 1528 #endif 1529 1530 1531 /****************************************************************** 1532 * __RTCastToVoid (MSVCRT.@) 1533 * 1534 * Dynamically cast a C++ object to a void*. 1535 * 1536 * PARAMS 1537 * cppobj [I] The C++ object to cast 1538 * 1539 * RETURNS 1540 * Success: The base address of the object as a void*. 1541 * Failure: NULL, if cppobj is NULL or has no RTTI. 1542 * 1543 * NOTES 1544 * This function is usually called by compiler generated code as a result 1545 * of using one of the C++ dynamic cast statements. 1546 */ 1547 void* CDECL MSVCRT___RTCastToVoid(void *cppobj) 1548 { 1549 void *ret; 1550 1551 if (!cppobj) return NULL; 1552 1553 __TRY 1554 { 1555 const rtti_object_locator *obj_locator = get_obj_locator( cppobj ); 1556 ret = (char *)cppobj - obj_locator->base_class_offset; 1557 } 1558 __EXCEPT_PAGE_FAULT 1559 { 1560 __non_rtti_object e; 1561 MSVCRT___non_rtti_object_ctor( &e, "Access violation - no RTTI data!" ); 1562 _CxxThrowException( &e, &__non_rtti_object_exception_type ); 1563 return NULL; 1564 } 1565 __ENDTRY 1566 return ret; 1567 } 1568 1569 1570 /********************************************************************* 1571 * _CxxThrowException (MSVCRT.@) 1572 */ 1573 #ifndef __x86_64__ 1574 void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) 1575 { 1576 ULONG_PTR args[3]; 1577 1578 args[0] = CXX_FRAME_MAGIC_VC6; 1579 args[1] = (ULONG_PTR)object; 1580 args[2] = (ULONG_PTR)type; 1581 RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); 1582 } 1583 #else 1584 void WINAPI _CxxThrowException( exception *object, const cxx_exception_type *type ) 1585 { 1586 ULONG_PTR args[4]; 1587 1588 args[0] = CXX_FRAME_MAGIC_VC6; 1589 args[1] = (ULONG_PTR)object; 1590 args[2] = (ULONG_PTR)type; 1591 RtlPcToFileHeader( (void*)type, (void**)&args[3]); 1592 RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 4, args ); 1593 } 1594 #endif 1595 1596 #if _MSVCR_VER >= 80 1597 1598 /********************************************************************* 1599 * ?_is_exception_typeof@@YAHABVtype_info@@PAU_EXCEPTION_POINTERS@@@Z 1600 * ?_is_exception_typeof@@YAHAEBVtype_info@@PEAU_EXCEPTION_POINTERS@@@Z 1601 */ 1602 #ifndef __x86_64__ 1603 int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) 1604 { 1605 int ret = -1; 1606 1607 TRACE("(%p %p)\n", ti, ep); 1608 1609 __TRY 1610 { 1611 EXCEPTION_RECORD *rec = ep->ExceptionRecord; 1612 1613 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==3 && 1614 (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 || 1615 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 || 1616 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8)) 1617 { 1618 const cxx_type_info_table *tit = ((cxx_exception_type*)rec->ExceptionInformation[2])->type_info_table; 1619 int i; 1620 1621 for (i=0; i<tit->count; i++) { 1622 if (ti==tit->info[i]->type_info || !strcmp(ti->mangled, tit->info[i]->type_info->mangled)) 1623 { 1624 ret = 1; 1625 break; 1626 } 1627 } 1628 1629 if (i == tit->count) 1630 ret = 0; 1631 } 1632 } 1633 __EXCEPT_PAGE_FAULT 1634 __ENDTRY 1635 1636 if(ret == -1) 1637 MSVCRT_terminate(); 1638 return ret; 1639 } 1640 #else 1641 int __cdecl _is_exception_typeof(const type_info *ti, EXCEPTION_POINTERS *ep) 1642 { 1643 int ret = -1; 1644 1645 TRACE("(%p %p)\n", ti, ep); 1646 1647 __TRY 1648 { 1649 EXCEPTION_RECORD *rec = ep->ExceptionRecord; 1650 1651 if (rec->ExceptionCode==CXX_EXCEPTION && rec->NumberParameters==4 && 1652 (rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC6 || 1653 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC7 || 1654 rec->ExceptionInformation[0]==CXX_FRAME_MAGIC_VC8)) 1655 { 1656 const cxx_exception_type *et = (cxx_exception_type*)rec->ExceptionInformation[2]; 1657 const cxx_type_info_table *tit = (const cxx_type_info_table*)(rec->ExceptionInformation[3]+et->type_info_table); 1658 int i; 1659 1660 for (i=0; i<tit->count; i++) { 1661 const cxx_type_info *cti = (const cxx_type_info*)(rec->ExceptionInformation[3]+tit->info[i]); 1662 const type_info *except_ti = (const type_info*)(rec->ExceptionInformation[3]+cti->type_info); 1663 if (ti==except_ti || !strcmp(ti->mangled, except_ti->mangled)) 1664 { 1665 ret = 1; 1666 break; 1667 } 1668 } 1669 1670 if (i == tit->count) 1671 ret = 0; 1672 } 1673 } 1674 __EXCEPT_PAGE_FAULT 1675 __ENDTRY 1676 1677 if(ret == -1) 1678 MSVCRT_terminate(); 1679 return ret; 1680 } 1681 #endif 1682 1683 /********************************************************************* 1684 * __clean_type_info_names_internal (MSVCR80.@) 1685 */ 1686 void CDECL __clean_type_info_names_internal(void *p) 1687 { 1688 FIXME("(%p) stub\n", p); 1689 } 1690 1691 /********************************************************************* 1692 * ?_name_internal_method@type_info@@QBEPBDPAU__type_info_node@@@Z (MSVCR100.@) 1693 */ 1694 DEFINE_THISCALL_WRAPPER(type_info_name_internal_method,8) 1695 const char * __thiscall type_info_name_internal_method(type_info * _this, struct __type_info_node *node) 1696 { 1697 static int once; 1698 if (node && !once++) FIXME("type_info_node parameter ignored\n"); 1699 1700 return MSVCRT_type_info_name(_this); 1701 } 1702 1703 #endif /* _MSVCR_VER >= 80 */ 1704 1705 /* std::exception_ptr class helpers */ 1706 typedef struct 1707 { 1708 EXCEPTION_RECORD *rec; 1709 int *ref; /* not binary compatible with native msvcr100 */ 1710 } exception_ptr; 1711 1712 #if _MSVCR_VER >= 100 1713 1714 /********************************************************************* 1715 * ?__ExceptionPtrCreate@@YAXPAX@Z 1716 * ?__ExceptionPtrCreate@@YAXPEAX@Z 1717 */ 1718 void __cdecl __ExceptionPtrCreate(exception_ptr *ep) 1719 { 1720 TRACE("(%p)\n", ep); 1721 1722 ep->rec = NULL; 1723 ep->ref = NULL; 1724 } 1725 1726 #if defined(__i386__) && !defined(__MINGW32__) 1727 extern void call_dtor(const cxx_exception_type *type, void *func, void *object); 1728 1729 __ASM_GLOBAL_FUNC( call_dtor, 1730 "movl 12(%esp),%ecx\n\t" 1731 "call *8(%esp)\n\t" 1732 "ret" ); 1733 #elif __x86_64__ 1734 static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object) 1735 { 1736 char *base = RtlPcToFileHeader((void*)type, (void**)&base); 1737 void (__cdecl *func)(void*) = (void*)(base + dtor); 1738 func(object); 1739 } 1740 #else 1741 #define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object) 1742 #endif 1743 1744 /********************************************************************* 1745 * ?__ExceptionPtrDestroy@@YAXPAX@Z 1746 * ?__ExceptionPtrDestroy@@YAXPEAX@Z 1747 */ 1748 void __cdecl __ExceptionPtrDestroy(exception_ptr *ep) 1749 { 1750 TRACE("(%p)\n", ep); 1751 1752 if (!ep->rec) 1753 return; 1754 1755 if (!InterlockedDecrement(ep->ref)) 1756 { 1757 if (ep->rec->ExceptionCode == CXX_EXCEPTION) 1758 { 1759 const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2]; 1760 void *obj = (void*)ep->rec->ExceptionInformation[1]; 1761 1762 if (type && type->destructor) call_dtor(type, type->destructor, obj); 1763 HeapFree(GetProcessHeap(), 0, obj); 1764 } 1765 1766 HeapFree(GetProcessHeap(), 0, ep->rec); 1767 HeapFree(GetProcessHeap(), 0, ep->ref); 1768 } 1769 } 1770 1771 /********************************************************************* 1772 * ?__ExceptionPtrCopy@@YAXPAXPBX@Z 1773 * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z 1774 */ 1775 void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy) 1776 { 1777 TRACE("(%p %p)\n", ep, copy); 1778 1779 /* don't destroy object stored in ep */ 1780 *ep = *copy; 1781 if (ep->ref) 1782 InterlockedIncrement(copy->ref); 1783 } 1784 1785 /********************************************************************* 1786 * ?__ExceptionPtrAssign@@YAXPAXPBX@Z 1787 * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z 1788 */ 1789 void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign) 1790 { 1791 TRACE("(%p %p)\n", ep, assign); 1792 1793 /* don't destroy object stored in ep */ 1794 if (ep->ref) 1795 InterlockedDecrement(ep->ref); 1796 1797 *ep = *assign; 1798 if (ep->ref) 1799 InterlockedIncrement(ep->ref); 1800 } 1801 1802 #endif /* _MSVCR_VER >= 100 */ 1803 1804 /********************************************************************* 1805 * ?__ExceptionPtrRethrow@@YAXPBX@Z 1806 * ?__ExceptionPtrRethrow@@YAXPEBX@Z 1807 */ 1808 void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep) 1809 { 1810 TRACE("(%p)\n", ep); 1811 1812 if (!ep->rec) 1813 { 1814 static const char *exception_msg = "bad exception"; 1815 exception e; 1816 1817 MSVCRT_exception_ctor(&e, &exception_msg); 1818 _CxxThrowException(&e, &exception_exception_type); 1819 return; 1820 } 1821 1822 RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING), 1823 ep->rec->NumberParameters, ep->rec->ExceptionInformation); 1824 } 1825 1826 #if _MSVCR_VER >= 100 1827 1828 #ifdef __i386__ 1829 extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); 1830 #else 1831 static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) 1832 { 1833 TRACE( "calling copy ctor %p object %p src %p\n", func, this, src ); 1834 if (has_vbase) 1835 ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1); 1836 else 1837 ((void (__cdecl*)(void*, void*))func)(this, src); 1838 } 1839 #endif 1840 1841 /********************************************************************* 1842 * ?__ExceptionPtrCurrentException@@YAXPAX@Z 1843 * ?__ExceptionPtrCurrentException@@YAXPEAX@Z 1844 */ 1845 #ifndef __x86_64__ 1846 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) 1847 { 1848 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; 1849 1850 TRACE("(%p)\n", ep); 1851 1852 if (!rec) 1853 { 1854 ep->rec = NULL; 1855 ep->ref = NULL; 1856 return; 1857 } 1858 1859 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 1860 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 1861 1862 *ep->rec = *rec; 1863 *ep->ref = 1; 1864 1865 if (ep->rec->ExceptionCode == CXX_EXCEPTION) 1866 { 1867 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; 1868 const cxx_type_info *ti; 1869 void **data, *obj; 1870 1871 ti = et->type_info_table->info[0]; 1872 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 1873 1874 obj = (void*)ep->rec->ExceptionInformation[1]; 1875 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 1876 { 1877 memcpy(data, obj, ti->size); 1878 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 1879 } 1880 else if (ti->copy_ctor) 1881 { 1882 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), 1883 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 1884 } 1885 else 1886 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); 1887 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 1888 } 1889 return; 1890 } 1891 #else 1892 void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) 1893 { 1894 EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; 1895 1896 TRACE("(%p)\n", ep); 1897 1898 if (!rec) 1899 { 1900 ep->rec = NULL; 1901 ep->ref = NULL; 1902 return; 1903 } 1904 1905 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 1906 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 1907 1908 *ep->rec = *rec; 1909 *ep->ref = 1; 1910 1911 if (ep->rec->ExceptionCode == CXX_EXCEPTION) 1912 { 1913 const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; 1914 const cxx_type_info *ti; 1915 void **data, *obj; 1916 char *base = RtlPcToFileHeader((void*)et, (void**)&base); 1917 1918 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]); 1919 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 1920 1921 obj = (void*)ep->rec->ExceptionInformation[1]; 1922 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 1923 { 1924 memcpy(data, obj, ti->size); 1925 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 1926 } 1927 else if (ti->copy_ctor) 1928 { 1929 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), 1930 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 1931 } 1932 else 1933 memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); 1934 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 1935 } 1936 return; 1937 } 1938 #endif 1939 1940 #endif /* _MSVCR_VER >= 100 */ 1941 1942 #if _MSVCR_VER >= 110 1943 /********************************************************************* 1944 * ?__ExceptionPtrToBool@@YA_NPBX@Z 1945 * ?__ExceptionPtrToBool@@YA_NPEBX@Z 1946 */ 1947 MSVCRT_bool __cdecl __ExceptionPtrToBool(exception_ptr *ep) 1948 { 1949 return !!ep->rec; 1950 } 1951 #endif 1952 1953 #if _MSVCR_VER >= 100 1954 1955 /********************************************************************* 1956 * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z 1957 * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z 1958 */ 1959 #ifndef __x86_64__ 1960 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, 1961 exception *object, const cxx_exception_type *type) 1962 { 1963 const cxx_type_info *ti; 1964 void **data; 1965 1966 __ExceptionPtrDestroy(ep); 1967 1968 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 1969 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 1970 *ep->ref = 1; 1971 1972 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); 1973 ep->rec->ExceptionCode = CXX_EXCEPTION; 1974 ep->rec->ExceptionFlags = EH_NONCONTINUABLE; 1975 ep->rec->NumberParameters = 3; 1976 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; 1977 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; 1978 1979 ti = type->type_info_table->info[0]; 1980 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 1981 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 1982 { 1983 memcpy(data, object, ti->size); 1984 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 1985 } 1986 else if (ti->copy_ctor) 1987 { 1988 call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), 1989 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 1990 } 1991 else 1992 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); 1993 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 1994 } 1995 #else 1996 void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, 1997 exception *object, const cxx_exception_type *type) 1998 { 1999 const cxx_type_info *ti; 2000 void **data; 2001 char *base; 2002 2003 RtlPcToFileHeader((void*)type, (void**)&base); 2004 __ExceptionPtrDestroy(ep); 2005 2006 ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); 2007 ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); 2008 *ep->ref = 1; 2009 2010 memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); 2011 ep->rec->ExceptionCode = CXX_EXCEPTION; 2012 ep->rec->ExceptionFlags = EH_NONCONTINUABLE; 2013 ep->rec->NumberParameters = 4; 2014 ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; 2015 ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; 2016 ep->rec->ExceptionInformation[3] = (ULONG_PTR)base; 2017 2018 ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]); 2019 data = HeapAlloc(GetProcessHeap(), 0, ti->size); 2020 if (ti->flags & CLASS_IS_SIMPLE_TYPE) 2021 { 2022 memcpy(data, object, ti->size); 2023 if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); 2024 } 2025 else if (ti->copy_ctor) 2026 { 2027 call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), 2028 ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); 2029 } 2030 else 2031 memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); 2032 ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; 2033 } 2034 #endif 2035 2036 MSVCRT_bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2) 2037 { 2038 return ep1->rec == ep2->rec; 2039 } 2040 2041 #endif /* _MSVCR_VER >= 100 */ 2042 2043 #if _MSVCR_VER >= 80 2044 void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off) 2045 { 2046 return get_this_pointer(off, obj); 2047 } 2048 #endif 2049 2050 #if _MSVCR_VER >= 140 2051 2052 typedef struct 2053 { 2054 char *name; 2055 char mangled[1]; 2056 } type_info140; 2057 2058 typedef struct 2059 { 2060 SLIST_ENTRY entry; 2061 char name[1]; 2062 } type_info_entry; 2063 2064 static void* CDECL type_info_entry_malloc(MSVCRT_size_t size) 2065 { 2066 type_info_entry *ret = MSVCRT_malloc(FIELD_OFFSET(type_info_entry, name) + size); 2067 return ret->name; 2068 } 2069 2070 static void CDECL type_info_entry_free(void *ptr) 2071 { 2072 ptr = (char*)ptr - FIELD_OFFSET(type_info_entry, name); 2073 MSVCRT_free(ptr); 2074 } 2075 2076 /****************************************************************** 2077 * __std_type_info_compare (UCRTBASE.@) 2078 */ 2079 int CDECL MSVCRT_type_info_compare(const type_info140 *l, const type_info140 *r) 2080 { 2081 int ret; 2082 2083 if (l == r) ret = 0; 2084 else ret = MSVCRT_strcmp(l->mangled + 1, r->mangled + 1); 2085 TRACE("(%p %p) returning %d\n", l, r, ret); 2086 return ret; 2087 } 2088 2089 /****************************************************************** 2090 * __std_type_info_name (UCRTBASE.@) 2091 */ 2092 const char* CDECL MSVCRT_type_info_name_list(type_info140 *ti, SLIST_HEADER *header) 2093 { 2094 if (!ti->name) 2095 { 2096 char* name = __unDName(0, ti->mangled + 1, 0, 2097 type_info_entry_malloc, type_info_entry_free, UNDNAME_NO_ARGUMENTS | UNDNAME_32_BIT_DECODE); 2098 if (name) 2099 { 2100 unsigned int len = strlen(name); 2101 2102 while (len && name[--len] == ' ') 2103 name[len] = '\0'; 2104 2105 if (InterlockedCompareExchangePointer((void**)&ti->name, name, NULL)) 2106 { 2107 type_info_entry_free(name); 2108 } 2109 else 2110 { 2111 type_info_entry *entry = (type_info_entry*)(name-FIELD_OFFSET(type_info_entry, name)); 2112 InterlockedPushEntrySList(header, &entry->entry); 2113 } 2114 } 2115 } 2116 TRACE("(%p) returning %s\n", ti, ti->name); 2117 return ti->name; 2118 } 2119 2120 /****************************************************************** 2121 * __std_type_info_destroy_list (UCRTBASE.@) 2122 */ 2123 void CDECL MSVCRT_type_info_destroy_list(SLIST_HEADER *header) 2124 { 2125 SLIST_ENTRY *cur, *next; 2126 2127 TRACE("(%p)\n", header); 2128 2129 for(cur = InterlockedFlushSList(header); cur; cur = next) 2130 { 2131 next = cur->Next; 2132 MSVCRT_free(cur); 2133 } 2134 } 2135 2136 /****************************************************************** 2137 * __std_type_info_hash (UCRTBASE.@) 2138 */ 2139 MSVCRT_size_t CDECL MSVCRT_type_info_hash(const type_info140 *ti) 2140 { 2141 MSVCRT_size_t hash, fnv_prime; 2142 const char *p; 2143 2144 #ifdef _WIN64 2145 hash = 0xcbf29ce484222325; 2146 fnv_prime = 0x100000001b3; 2147 #else 2148 hash = 0x811c9dc5; 2149 fnv_prime = 0x1000193; 2150 #endif 2151 2152 TRACE("(%p)->%s\n", ti, ti->mangled); 2153 2154 for(p = ti->mangled+1; *p; p++) { 2155 hash ^= *p; 2156 hash *= fnv_prime; 2157 } 2158 2159 #ifdef _WIN64 2160 hash ^= hash >> 32; 2161 #endif 2162 2163 return hash; 2164 } 2165 2166 #endif /* _MSVCR_VER >= 140 */ 2167 2168 #if _MSVCR_VER >= 100 2169 2170 enum ConcRT_EventType 2171 { 2172 CONCRT_EVENT_GENERIC, 2173 CONCRT_EVENT_START, 2174 CONCRT_EVENT_END, 2175 CONCRT_EVENT_BLOCK, 2176 CONCRT_EVENT_UNBLOCK, 2177 CONCRT_EVENT_YIELD, 2178 CONCRT_EVENT_ATTACH, 2179 CONCRT_EVENT_DETACH 2180 }; 2181 2182 /* ?_Trace_ppl_function@Concurrency@@YAXABU_GUID@@EW4ConcRT_EventType@1@@Z */ 2183 /* ?_Trace_ppl_function@Concurrency@@YAXAEBU_GUID@@EW4ConcRT_EventType@1@@Z */ 2184 void __cdecl Concurrency__Trace_ppl_function(const GUID *guid, unsigned char level, enum ConcRT_EventType type) 2185 { 2186 FIXME("(%s %u %i) stub\n", debugstr_guid(guid), level, type); 2187 } 2188 2189 #endif /* _MSVCR_VER >= 100 */ 2190