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 */
get_vtable(void * obj)55 static inline const vtable_ptr *get_vtable( void *obj )
56 {
57 return *(const vtable_ptr **)obj;
58 }
59
get_obj_locator(void * cppobj)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__
dump_obj_locator(const rtti_object_locator * ptr)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
dump_obj_locator(const rtti_object_locator * ptr)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 */
EXCEPTION_ctor(exception * _this,const char ** name)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)
MSVCRT_exception_ctor(exception * _this,const char ** name)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)
MSVCRT_exception_ctor_noalloc(exception * _this,char ** name,int noalloc)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)
MSVCRT_exception_copy_ctor(exception * _this,const exception * rhs)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)
MSVCRT_exception_default_ctor(exception * _this)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)
MSVCRT_exception_dtor(exception * _this)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)
MSVCRT_exception_opequals(exception * _this,const exception * rhs)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)
MSVCRT_exception_vector_dtor(exception * _this,unsigned int flags)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)
MSVCRT_exception_scalar_dtor(exception * _this,unsigned int flags)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)
MSVCRT_what_exception(exception * _this)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)
MSVCRT_bad_typeid_copy_ctor(bad_typeid * _this,const bad_typeid * rhs)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)
MSVCRT_bad_typeid_ctor(bad_typeid * _this,const char * name)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)
MSVCRT_bad_typeid_default_ctor(bad_typeid * _this)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)
MSVCRT_bad_typeid_dtor(bad_typeid * _this)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)
MSVCRT_bad_typeid_opequals(bad_typeid * _this,const bad_typeid * rhs)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)
MSVCRT_bad_typeid_vector_dtor(bad_typeid * _this,unsigned int flags)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)
MSVCRT_bad_typeid_scalar_dtor(bad_typeid * _this,unsigned int flags)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)
MSVCRT___non_rtti_object_copy_ctor(__non_rtti_object * _this,const __non_rtti_object * rhs)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)
MSVCRT___non_rtti_object_ctor(__non_rtti_object * _this,const char * name)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)
MSVCRT___non_rtti_object_dtor(__non_rtti_object * _this)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)
MSVCRT___non_rtti_object_opequals(__non_rtti_object * _this,const __non_rtti_object * rhs)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)
MSVCRT___non_rtti_object_vector_dtor(__non_rtti_object * _this,unsigned int flags)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)
MSVCRT___non_rtti_object_scalar_dtor(__non_rtti_object * _this,unsigned int flags)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)
MSVCRT_bad_cast_ctor(bad_cast * _this,const char ** name)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)
MSVCRT_bad_cast_copy_ctor(bad_cast * _this,const bad_cast * rhs)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)
MSVCRT_bad_cast_ctor_charptr(bad_cast * _this,const char * name)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)
MSVCRT_bad_cast_default_ctor(bad_cast * _this)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)
MSVCRT_bad_cast_dtor(bad_cast * _this)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)
MSVCRT_bad_cast_opequals(bad_cast * _this,const bad_cast * rhs)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)
MSVCRT_bad_cast_vector_dtor(bad_cast * _this,unsigned int flags)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)
MSVCRT_bad_cast_scalar_dtor(bad_cast * _this,unsigned int flags)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)
MSVCRT_type_info_opequals_equals(type_info * _this,const type_info * rhs)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)
MSVCRT_type_info_opnot_equals(type_info * _this,const type_info * rhs)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)
MSVCRT_type_info_before(type_info * _this,const type_info * rhs)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)
MSVCRT_type_info_dtor(type_info * _this)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)
MSVCRT_type_info_name(type_info * _this)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)
MSVCRT_type_info_raw_name(type_info * _this)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)
MSVCRT_type_info_vector_dtor(type_info * _this,unsigned int flags)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
bad_alloc_ctor(bad_alloc * this,const char ** name)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)
MSVCRT_bad_alloc_copy_ctor(bad_alloc * _this,const bad_alloc * rhs)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)
MSVCRT_bad_alloc_dtor(bad_alloc * _this)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)
scheduler_resource_allocation_error_ctor_name(scheduler_resource_allocation_error * this,const char * name,HRESULT hr)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)
scheduler_resource_allocation_error_ctor(scheduler_resource_allocation_error * this,HRESULT hr)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)
MSVCRT_scheduler_resource_allocation_error_copy_ctor(scheduler_resource_allocation_error * this,const scheduler_resource_allocation_error * rhs)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)
scheduler_resource_allocation_error_get_error_code(const scheduler_resource_allocation_error * this)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)
MSVCRT_scheduler_resource_allocation_error_dtor(scheduler_resource_allocation_error * this)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)
improper_lock_ctor_str(improper_lock * this,const char * str)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)
improper_lock_ctor(improper_lock * this)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)
MSVCRT_improper_lock_copy_ctor(improper_lock * _this,const improper_lock * rhs)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)
MSVCRT_improper_lock_dtor(improper_lock * _this)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)
invalid_scheduler_policy_key_ctor_str(invalid_scheduler_policy_key * this,const char * str)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)
invalid_scheduler_policy_key_ctor(invalid_scheduler_policy_key * this)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)
MSVCRT_invalid_scheduler_policy_key_copy_ctor(invalid_scheduler_policy_key * _this,const invalid_scheduler_policy_key * rhs)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)
MSVCRT_invalid_scheduler_policy_key_dtor(invalid_scheduler_policy_key * _this)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)
invalid_scheduler_policy_value_ctor_str(invalid_scheduler_policy_value * this,const char * str)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)
invalid_scheduler_policy_value_ctor(invalid_scheduler_policy_value * this)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)
MSVCRT_invalid_scheduler_policy_value_copy_ctor(invalid_scheduler_policy_value * _this,const invalid_scheduler_policy_value * rhs)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)
MSVCRT_invalid_scheduler_policy_value_dtor(invalid_scheduler_policy_value * _this)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)
invalid_scheduler_policy_thread_specification_ctor_str(invalid_scheduler_policy_thread_specification * this,const char * str)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)
invalid_scheduler_policy_thread_specification_ctor(invalid_scheduler_policy_thread_specification * this)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)
MSVCRT_invalid_scheduler_policy_thread_specification_copy_ctor(invalid_scheduler_policy_thread_specification * _this,const invalid_scheduler_policy_thread_specification * rhs)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)
MSVCRT_invalid_scheduler_policy_thread_specification_dtor(invalid_scheduler_policy_thread_specification * _this)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)
improper_scheduler_attach_ctor_str(improper_scheduler_attach * this,const char * str)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)
improper_scheduler_attach_ctor(improper_scheduler_attach * this)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)
MSVCRT_improper_scheduler_attach_copy_ctor(improper_scheduler_attach * _this,const improper_scheduler_attach * rhs)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)
MSVCRT_improper_scheduler_attach_dtor(improper_scheduler_attach * _this)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)
improper_scheduler_detach_ctor_str(improper_scheduler_detach * this,const char * str)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)
improper_scheduler_detach_ctor(improper_scheduler_detach * this)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)
MSVCRT_improper_scheduler_detach_copy_ctor(improper_scheduler_detach * _this,const improper_scheduler_detach * rhs)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)
MSVCRT_improper_scheduler_detach_dtor(improper_scheduler_detach * _this)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__
__asm_dummy_vtables(void)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
msvcrt_init_exception(void * base)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
throw_exception(exception_type et,HRESULT hr,const char * str)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 */
MSVCRT_set_terminate(MSVCRT_terminate_function func)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 */
MSVCRT__get_terminate(void)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 */
MSVCRT_set_unexpected(MSVCRT_unexpected_function func)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 */
MSVCRT__get_unexpected(void)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 */
MSVCRT__set_se_translator(MSVCRT__se_translator_function func)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 */
MSVCRT_terminate(void)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 */
MSVCRT_unexpected(void)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__
MSVCRT___RTtypeid(void * cppobj)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
MSVCRT___RTtypeid(void * cppobj)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__
MSVCRT___RTDynamicCast(void * cppobj,int unknown,type_info * src,type_info * dst,int do_throw)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
MSVCRT___RTDynamicCast(void * cppobj,int unknown,type_info * src,type_info * dst,int do_throw)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 */
MSVCRT___RTCastToVoid(void * cppobj)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__
_CxxThrowException(exception * object,const cxx_exception_type * type)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
_CxxThrowException(exception * object,const cxx_exception_type * type)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__
_is_exception_typeof(const type_info * ti,EXCEPTION_POINTERS * ep)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
_is_exception_typeof(const type_info * ti,EXCEPTION_POINTERS * ep)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 */
__clean_type_info_names_internal(void * p)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)
type_info_name_internal_method(type_info * _this,struct __type_info_node * node)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 */
__ExceptionPtrCreate(exception_ptr * ep)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__
call_dtor(const cxx_exception_type * type,unsigned int dtor,void * object)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 */
__ExceptionPtrDestroy(exception_ptr * ep)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 */
__ExceptionPtrCopy(exception_ptr * ep,const exception_ptr * copy)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 */
__ExceptionPtrAssign(exception_ptr * ep,const exception_ptr * assign)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 */
__ExceptionPtrRethrow(const exception_ptr * ep)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
call_copy_ctor(void * func,void * this,void * src,int has_vbase)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__
__ExceptionPtrCurrentException(exception_ptr * ep)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
__ExceptionPtrCurrentException(exception_ptr * ep)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 */
__ExceptionPtrToBool(exception_ptr * ep)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__
__ExceptionPtrCopyException(exception_ptr * ep,exception * object,const cxx_exception_type * type)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
__ExceptionPtrCopyException(exception_ptr * ep,exception * object,const cxx_exception_type * type)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
__ExceptionPtrCompare(const exception_ptr * ep1,const exception_ptr * ep2)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
__AdjustPointer(void * obj,const this_ptr_offsets * off)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
type_info_entry_malloc(MSVCRT_size_t size)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
type_info_entry_free(void * ptr)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 */
MSVCRT_type_info_compare(const type_info140 * l,const type_info140 * r)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 */
MSVCRT_type_info_name_list(type_info140 * ti,SLIST_HEADER * header)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 */
MSVCRT_type_info_destroy_list(SLIST_HEADER * header)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 */
MSVCRT_type_info_hash(const type_info140 * ti)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 */
Concurrency__Trace_ppl_function(const GUID * guid,unsigned char level,enum ConcRT_EventType type)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