xref: /reactos/sdk/lib/crt/wine/cpp.c (revision c332b917)
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