1*b146d3b3SDamjan Jovanovic /**************************************************************
2*b146d3b3SDamjan Jovanovic  *
3*b146d3b3SDamjan Jovanovic  * Licensed to the Apache Software Foundation (ASF) under one
4*b146d3b3SDamjan Jovanovic  * or more contributor license agreements.  See the NOTICE file
5*b146d3b3SDamjan Jovanovic  * distributed with this work for additional information
6*b146d3b3SDamjan Jovanovic  * regarding copyright ownership.  The ASF licenses this file
7*b146d3b3SDamjan Jovanovic  * to you under the Apache License, Version 2.0 (the
8*b146d3b3SDamjan Jovanovic  * "License"); you may not use this file except in compliance
9*b146d3b3SDamjan Jovanovic  * with the License.  You may obtain a copy of the License at
10*b146d3b3SDamjan Jovanovic  *
11*b146d3b3SDamjan Jovanovic  *   http://www.apache.org/licenses/LICENSE-2.0
12*b146d3b3SDamjan Jovanovic  *
13*b146d3b3SDamjan Jovanovic  * Unless required by applicable law or agreed to in writing,
14*b146d3b3SDamjan Jovanovic  * software distributed under the License is distributed on an
15*b146d3b3SDamjan Jovanovic  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b146d3b3SDamjan Jovanovic  * KIND, either express or implied.  See the License for the
17*b146d3b3SDamjan Jovanovic  * specific language governing permissions and limitations
18*b146d3b3SDamjan Jovanovic  * under the License.
19*b146d3b3SDamjan Jovanovic  *
20*b146d3b3SDamjan Jovanovic  *************************************************************/
21*b146d3b3SDamjan Jovanovic 
22*b146d3b3SDamjan Jovanovic 
23*b146d3b3SDamjan Jovanovic 
24*b146d3b3SDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove
25*b146d3b3SDamjan Jovanovic #include "precompiled_bridges.hxx"
26*b146d3b3SDamjan Jovanovic 
27*b146d3b3SDamjan Jovanovic #pragma warning( disable : 4237 )
28*b146d3b3SDamjan Jovanovic #include <hash_map>
29*b146d3b3SDamjan Jovanovic #include <sal/config.h>
30*b146d3b3SDamjan Jovanovic #include <malloc.h>
31*b146d3b3SDamjan Jovanovic #include <typeinfo.h>
32*b146d3b3SDamjan Jovanovic #include <signal.h>
33*b146d3b3SDamjan Jovanovic 
34*b146d3b3SDamjan Jovanovic #include "rtl/alloc.h"
35*b146d3b3SDamjan Jovanovic #include "rtl/strbuf.hxx"
36*b146d3b3SDamjan Jovanovic #include "rtl/ustrbuf.hxx"
37*b146d3b3SDamjan Jovanovic 
38*b146d3b3SDamjan Jovanovic #include "com/sun/star/uno/Any.hxx"
39*b146d3b3SDamjan Jovanovic 
40*b146d3b3SDamjan Jovanovic #include "mscx.hxx"
41*b146d3b3SDamjan Jovanovic 
42*b146d3b3SDamjan Jovanovic 
43*b146d3b3SDamjan Jovanovic #pragma pack(push, 8)
44*b146d3b3SDamjan Jovanovic 
45*b146d3b3SDamjan Jovanovic using namespace ::com::sun::star::uno;
46*b146d3b3SDamjan Jovanovic using namespace ::std;
47*b146d3b3SDamjan Jovanovic using namespace ::osl;
48*b146d3b3SDamjan Jovanovic using namespace ::rtl;
49*b146d3b3SDamjan Jovanovic 
50*b146d3b3SDamjan Jovanovic namespace CPPU_CURRENT_NAMESPACE
51*b146d3b3SDamjan Jovanovic {
52*b146d3b3SDamjan Jovanovic 
53*b146d3b3SDamjan Jovanovic //==================================================================================================
toUNOname(OUString const & rRTTIname)54*b146d3b3SDamjan Jovanovic static inline OUString toUNOname( OUString const & rRTTIname ) throw ()
55*b146d3b3SDamjan Jovanovic {
56*b146d3b3SDamjan Jovanovic 	OUStringBuffer aRet( 64 );
57*b146d3b3SDamjan Jovanovic 	OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
58*b146d3b3SDamjan Jovanovic     sal_Int32 nPos = aStr.getLength();
59*b146d3b3SDamjan Jovanovic     while (nPos > 0)
60*b146d3b3SDamjan Jovanovic     {
61*b146d3b3SDamjan Jovanovic         sal_Int32 n = aStr.lastIndexOf( '@', nPos );
62*b146d3b3SDamjan Jovanovic         aRet.append( aStr.copy( n +1, nPos -n -1 ) );
63*b146d3b3SDamjan Jovanovic         if (n >= 0)
64*b146d3b3SDamjan Jovanovic         {
65*b146d3b3SDamjan Jovanovic 			aRet.append( (sal_Unicode)'.' );
66*b146d3b3SDamjan Jovanovic         }
67*b146d3b3SDamjan Jovanovic         nPos = n;
68*b146d3b3SDamjan Jovanovic     }
69*b146d3b3SDamjan Jovanovic 	return aRet.makeStringAndClear();
70*b146d3b3SDamjan Jovanovic }
71*b146d3b3SDamjan Jovanovic //==================================================================================================
toRTTIname(OUString const & rUNOname)72*b146d3b3SDamjan Jovanovic static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
73*b146d3b3SDamjan Jovanovic {
74*b146d3b3SDamjan Jovanovic 	OUStringBuffer aRet( 64 );
75*b146d3b3SDamjan Jovanovic 	aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
76*b146d3b3SDamjan Jovanovic     sal_Int32 nPos = rUNOname.getLength();
77*b146d3b3SDamjan Jovanovic     while (nPos > 0)
78*b146d3b3SDamjan Jovanovic     {
79*b146d3b3SDamjan Jovanovic         sal_Int32 n = rUNOname.lastIndexOf( '.', nPos );
80*b146d3b3SDamjan Jovanovic         aRet.append( rUNOname.copy( n +1, nPos -n -1 ) );
81*b146d3b3SDamjan Jovanovic         aRet.append( (sal_Unicode)'@' );
82*b146d3b3SDamjan Jovanovic         nPos = n;
83*b146d3b3SDamjan Jovanovic     }
84*b146d3b3SDamjan Jovanovic 	aRet.append( (sal_Unicode)'@' );
85*b146d3b3SDamjan Jovanovic 	return aRet.makeStringAndClear();
86*b146d3b3SDamjan Jovanovic }
87*b146d3b3SDamjan Jovanovic 
88*b146d3b3SDamjan Jovanovic 
89*b146d3b3SDamjan Jovanovic //##################################################################################################
90*b146d3b3SDamjan Jovanovic //#### RTTI simulation #############################################################################
91*b146d3b3SDamjan Jovanovic //##################################################################################################
92*b146d3b3SDamjan Jovanovic 
93*b146d3b3SDamjan Jovanovic 
94*b146d3b3SDamjan Jovanovic typedef hash_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap;
95*b146d3b3SDamjan Jovanovic 
96*b146d3b3SDamjan Jovanovic //==================================================================================================
97*b146d3b3SDamjan Jovanovic class RTTInfos
98*b146d3b3SDamjan Jovanovic {
99*b146d3b3SDamjan Jovanovic 	Mutex				_aMutex;
100*b146d3b3SDamjan Jovanovic 	t_string2PtrMap		_allRTTI;
101*b146d3b3SDamjan Jovanovic 
102*b146d3b3SDamjan Jovanovic 	static OUString toRawName( OUString const & rUNOname ) throw ();
103*b146d3b3SDamjan Jovanovic public:
104*b146d3b3SDamjan Jovanovic 	type_info * getRTTI( OUString const & rUNOname ) throw ();
105*b146d3b3SDamjan Jovanovic 
106*b146d3b3SDamjan Jovanovic 	RTTInfos();
107*b146d3b3SDamjan Jovanovic 	~RTTInfos();
108*b146d3b3SDamjan Jovanovic };
109*b146d3b3SDamjan Jovanovic 
110*b146d3b3SDamjan Jovanovic //==================================================================================================
111*b146d3b3SDamjan Jovanovic class __type_info
112*b146d3b3SDamjan Jovanovic {
113*b146d3b3SDamjan Jovanovic 	friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
114*b146d3b3SDamjan Jovanovic 	friend int mscx_filterCppException(
115*b146d3b3SDamjan Jovanovic         LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * );
116*b146d3b3SDamjan Jovanovic 
117*b146d3b3SDamjan Jovanovic public:
118*b146d3b3SDamjan Jovanovic     virtual ~__type_info() throw ();
119*b146d3b3SDamjan Jovanovic 
__type_info(void * m_vtable,const char * m_d_name)120*b146d3b3SDamjan Jovanovic 	inline __type_info( void * m_vtable, const char * m_d_name ) throw ()
121*b146d3b3SDamjan Jovanovic 		: _m_vtable( m_vtable )
122*b146d3b3SDamjan Jovanovic 		, _m_name( NULL )
123*b146d3b3SDamjan Jovanovic         { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked
124*b146d3b3SDamjan Jovanovic 
length() const125*b146d3b3SDamjan Jovanovic 	size_t length() const
126*b146d3b3SDamjan Jovanovic 	{
127*b146d3b3SDamjan Jovanovic 		return sizeof(__type_info) + strlen(_m_d_name);
128*b146d3b3SDamjan Jovanovic 	}
129*b146d3b3SDamjan Jovanovic 
130*b146d3b3SDamjan Jovanovic private:
131*b146d3b3SDamjan Jovanovic     void * _m_vtable;
132*b146d3b3SDamjan Jovanovic     char * _m_name;     // cached copy of unmangled name, NULL initially
133*b146d3b3SDamjan Jovanovic     char _m_d_name[1];  // mangled name
134*b146d3b3SDamjan Jovanovic };
135*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
~__type_info()136*b146d3b3SDamjan Jovanovic __type_info::~__type_info() throw ()
137*b146d3b3SDamjan Jovanovic {
138*b146d3b3SDamjan Jovanovic }
139*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
getRTTI(OUString const & rUNOname)140*b146d3b3SDamjan Jovanovic type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
141*b146d3b3SDamjan Jovanovic {
142*b146d3b3SDamjan Jovanovic 	// a must be
143*b146d3b3SDamjan Jovanovic 	OSL_ENSURE( sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!" );
144*b146d3b3SDamjan Jovanovic 
145*b146d3b3SDamjan Jovanovic 	MutexGuard aGuard( _aMutex );
146*b146d3b3SDamjan Jovanovic 	t_string2PtrMap::const_iterator const iFind( _allRTTI.find( rUNOname ) );
147*b146d3b3SDamjan Jovanovic 
148*b146d3b3SDamjan Jovanovic 	// check if type is already available
149*b146d3b3SDamjan Jovanovic 	if (iFind == _allRTTI.end())
150*b146d3b3SDamjan Jovanovic 	{
151*b146d3b3SDamjan Jovanovic 		// insert new type_info
152*b146d3b3SDamjan Jovanovic 		OString aRawName( OUStringToOString( toRTTIname( rUNOname ), RTL_TEXTENCODING_ASCII_US ) );
153*b146d3b3SDamjan Jovanovic 		__type_info * pRTTI = new( ::rtl_allocateMemory( sizeof(__type_info) + aRawName.getLength() ) )
154*b146d3b3SDamjan Jovanovic             __type_info( NULL, aRawName.getStr() );
155*b146d3b3SDamjan Jovanovic 
156*b146d3b3SDamjan Jovanovic 		// put into map
157*b146d3b3SDamjan Jovanovic 		pair< t_string2PtrMap::iterator, bool > insertion(
158*b146d3b3SDamjan Jovanovic             _allRTTI.insert( t_string2PtrMap::value_type( rUNOname, pRTTI ) ) );
159*b146d3b3SDamjan Jovanovic         OSL_ENSURE( insertion.second, "### rtti insertion failed?!" );
160*b146d3b3SDamjan Jovanovic 
161*b146d3b3SDamjan Jovanovic 		return (type_info *)pRTTI;
162*b146d3b3SDamjan Jovanovic 	}
163*b146d3b3SDamjan Jovanovic 	else
164*b146d3b3SDamjan Jovanovic 	{
165*b146d3b3SDamjan Jovanovic 		return (type_info *)iFind->second;
166*b146d3b3SDamjan Jovanovic 	}
167*b146d3b3SDamjan Jovanovic }
168*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
RTTInfos()169*b146d3b3SDamjan Jovanovic RTTInfos::RTTInfos() throw ()
170*b146d3b3SDamjan Jovanovic {
171*b146d3b3SDamjan Jovanovic }
172*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
~RTTInfos()173*b146d3b3SDamjan Jovanovic RTTInfos::~RTTInfos() throw ()
174*b146d3b3SDamjan Jovanovic {
175*b146d3b3SDamjan Jovanovic #if OSL_DEBUG_LEVEL > 1
176*b146d3b3SDamjan Jovanovic 	OSL_TRACE( "> freeing generated RTTI infos... <\n" );
177*b146d3b3SDamjan Jovanovic #endif
178*b146d3b3SDamjan Jovanovic 
179*b146d3b3SDamjan Jovanovic 	MutexGuard aGuard( _aMutex );
180*b146d3b3SDamjan Jovanovic 	for ( t_string2PtrMap::const_iterator iPos( _allRTTI.begin() );
181*b146d3b3SDamjan Jovanovic           iPos != _allRTTI.end(); ++iPos )
182*b146d3b3SDamjan Jovanovic 	{
183*b146d3b3SDamjan Jovanovic 		__type_info * pType = (__type_info *)iPos->second;
184*b146d3b3SDamjan Jovanovic 		pType->~__type_info(); // obsolete, but good style...
185*b146d3b3SDamjan Jovanovic 		::rtl_freeMemory( pType );
186*b146d3b3SDamjan Jovanovic 	}
187*b146d3b3SDamjan Jovanovic }
188*b146d3b3SDamjan Jovanovic 
189*b146d3b3SDamjan Jovanovic 
190*b146d3b3SDamjan Jovanovic //##################################################################################################
191*b146d3b3SDamjan Jovanovic //#### Exception raising ###########################################################################
192*b146d3b3SDamjan Jovanovic //##################################################################################################
193*b146d3b3SDamjan Jovanovic 
194*b146d3b3SDamjan Jovanovic 
195*b146d3b3SDamjan Jovanovic //==================================================================================================
__copyConstruct(void * pExcThis,void * pSource,typelib_TypeDescription * pTypeDescr)196*b146d3b3SDamjan Jovanovic static void * __copyConstruct( void * pExcThis, void * pSource, typelib_TypeDescription *pTypeDescr )
197*b146d3b3SDamjan Jovanovic 	throw ()
198*b146d3b3SDamjan Jovanovic {
199*b146d3b3SDamjan Jovanovic 	::uno_copyData( pExcThis, pSource, pTypeDescr, cpp_acquire );
200*b146d3b3SDamjan Jovanovic 	return pExcThis;
201*b146d3b3SDamjan Jovanovic }
202*b146d3b3SDamjan Jovanovic //==================================================================================================
__destruct(void * pExcThis,typelib_TypeDescription * pTypeDescr)203*b146d3b3SDamjan Jovanovic static void * __destruct( void * pExcThis, typelib_TypeDescription *pTypeDescr )
204*b146d3b3SDamjan Jovanovic 	throw ()
205*b146d3b3SDamjan Jovanovic {
206*b146d3b3SDamjan Jovanovic 	::uno_destructData( pExcThis, pTypeDescr, cpp_release );
207*b146d3b3SDamjan Jovanovic 	return pExcThis;
208*b146d3b3SDamjan Jovanovic }
209*b146d3b3SDamjan Jovanovic 
210*b146d3b3SDamjan Jovanovic //==================================================================================================
211*b146d3b3SDamjan Jovanovic 
212*b146d3b3SDamjan Jovanovic int const codeSnippetSize = 32;
213*b146d3b3SDamjan Jovanovic 
copyConstructCodeSnippet(unsigned char * code,typelib_TypeDescription * pTypeDescr)214*b146d3b3SDamjan Jovanovic void copyConstructCodeSnippet( unsigned char * code, typelib_TypeDescription * pTypeDescr )
215*b146d3b3SDamjan Jovanovic     throw ()
216*b146d3b3SDamjan Jovanovic {
217*b146d3b3SDamjan Jovanovic     unsigned char * p = code;
218*b146d3b3SDamjan Jovanovic 
219*b146d3b3SDamjan Jovanovic     // mov r8, pTypeDescr
220*b146d3b3SDamjan Jovanovic     *p++ = 0x49;
221*b146d3b3SDamjan Jovanovic     *p++ = 0xb8;
222*b146d3b3SDamjan Jovanovic     *p++ = ((sal_uIntPtr)(pTypeDescr)) & 0xff;
223*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 8) & 0xff;
224*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 16) & 0xff;
225*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 24) & 0xff;
226*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 32) & 0xff;
227*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 40) & 0xff;
228*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 48) & 0xff;
229*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 56) & 0xff;
230*b146d3b3SDamjan Jovanovic 
231*b146d3b3SDamjan Jovanovic     // mov r9, __copyConstruct
232*b146d3b3SDamjan Jovanovic     *p++ = 0x49;
233*b146d3b3SDamjan Jovanovic     *p++ = 0xb9;
234*b146d3b3SDamjan Jovanovic     *p++ = ((sal_uIntPtr)(&__copyConstruct)) & 0xff;
235*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 8) & 0xff;
236*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 16) & 0xff;
237*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 24) & 0xff;
238*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 32) & 0xff;
239*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 40) & 0xff;
240*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 48) & 0xff;
241*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__copyConstruct)) >> 56) & 0xff;
242*b146d3b3SDamjan Jovanovic 
243*b146d3b3SDamjan Jovanovic     // jmp r9
244*b146d3b3SDamjan Jovanovic     *p++ = 0x41;
245*b146d3b3SDamjan Jovanovic     *p++ = 0xff;
246*b146d3b3SDamjan Jovanovic     *p++ = 0xe1;
247*b146d3b3SDamjan Jovanovic 
248*b146d3b3SDamjan Jovanovic     OSL_ASSERT(p - code <= codeSnippetSize);
249*b146d3b3SDamjan Jovanovic }
250*b146d3b3SDamjan Jovanovic 
251*b146d3b3SDamjan Jovanovic //==================================================================================================
destructCodeSnippet(unsigned char * code,typelib_TypeDescription * pTypeDescr)252*b146d3b3SDamjan Jovanovic void destructCodeSnippet( unsigned char * code, typelib_TypeDescription * pTypeDescr )
253*b146d3b3SDamjan Jovanovic     throw ()
254*b146d3b3SDamjan Jovanovic {
255*b146d3b3SDamjan Jovanovic     unsigned char * p = code;
256*b146d3b3SDamjan Jovanovic 
257*b146d3b3SDamjan Jovanovic     // mov rdx, pTypeDescr
258*b146d3b3SDamjan Jovanovic     *p++ = 0x48;
259*b146d3b3SDamjan Jovanovic     *p++ = 0xba;
260*b146d3b3SDamjan Jovanovic     *p++ = ((sal_uIntPtr)(pTypeDescr)) & 0xff;
261*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 8) & 0xff;
262*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 16) & 0xff;
263*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 24) & 0xff;
264*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 32) & 0xff;
265*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 40) & 0xff;
266*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 48) & 0xff;
267*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(pTypeDescr)) >> 56) & 0xff;
268*b146d3b3SDamjan Jovanovic 
269*b146d3b3SDamjan Jovanovic     // mov r9, __destruct
270*b146d3b3SDamjan Jovanovic     *p++ = 0x49;
271*b146d3b3SDamjan Jovanovic     *p++ = 0xb9;
272*b146d3b3SDamjan Jovanovic     *p++ = ((sal_uIntPtr)(&__destruct)) & 0xff;
273*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 8) & 0xff;
274*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 16) & 0xff;
275*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 24) & 0xff;
276*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 32) & 0xff;
277*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 40) & 0xff;
278*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 48) & 0xff;
279*b146d3b3SDamjan Jovanovic     *p++ = (((sal_uIntPtr)(&__destruct)) >> 56) & 0xff;
280*b146d3b3SDamjan Jovanovic 
281*b146d3b3SDamjan Jovanovic     // jmp r9
282*b146d3b3SDamjan Jovanovic     *p++ = 0x41;
283*b146d3b3SDamjan Jovanovic     *p++ = 0xff;
284*b146d3b3SDamjan Jovanovic     *p++ = 0xe1;
285*b146d3b3SDamjan Jovanovic 
286*b146d3b3SDamjan Jovanovic     OSL_ASSERT(p - code <= codeSnippetSize);
287*b146d3b3SDamjan Jovanovic }
288*b146d3b3SDamjan Jovanovic 
289*b146d3b3SDamjan Jovanovic //==================================================================================================
align16(size_t size)290*b146d3b3SDamjan Jovanovic static size_t align16(size_t size)
291*b146d3b3SDamjan Jovanovic {
292*b146d3b3SDamjan Jovanovic 	return ((size + 15) >> 4) << 4;
293*b146d3b3SDamjan Jovanovic }
294*b146d3b3SDamjan Jovanovic 
295*b146d3b3SDamjan Jovanovic //==================================================================================================
296*b146d3b3SDamjan Jovanovic // Known as "catchabletype" in https://github.com/icestudent/ontl/blob/master/ntl/nt/exception.hxx
297*b146d3b3SDamjan Jovanovic struct ExceptionType
298*b146d3b3SDamjan Jovanovic {
299*b146d3b3SDamjan Jovanovic 	sal_Int32			_n0;
300*b146d3b3SDamjan Jovanovic  	sal_uInt32			_pTypeInfo;    // type_info *, RVA on Win64
301*b146d3b3SDamjan Jovanovic 	sal_Int32			_n1, _n2, _n3; // pointer to member descriptor, 12 bytes.
302*b146d3b3SDamjan Jovanovic 	sal_uInt32			_n4;
303*b146d3b3SDamjan Jovanovic 	sal_uInt32			_pCopyCtor;    // RVA on Win64
304*b146d3b3SDamjan Jovanovic 	sal_Int32			_n5;
305*b146d3b3SDamjan Jovanovic 
initializeCPPU_CURRENT_NAMESPACE::ExceptionType306*b146d3b3SDamjan Jovanovic 	static void initialize( unsigned char *p, sal_uInt32 typeInfoRVA, typelib_TypeDescription * pTypeDescr, sal_uInt32 copyConstructorRVA ) throw ()
307*b146d3b3SDamjan Jovanovic 	{
308*b146d3b3SDamjan Jovanovic 		ExceptionType *e = (ExceptionType*)p;
309*b146d3b3SDamjan Jovanovic 		e->_n0 = 0;
310*b146d3b3SDamjan Jovanovic 		e->_pTypeInfo = typeInfoRVA;
311*b146d3b3SDamjan Jovanovic 		e->_n1 = 0;
312*b146d3b3SDamjan Jovanovic 		e->_n2 = -1;
313*b146d3b3SDamjan Jovanovic 		e->_n3 = 0;
314*b146d3b3SDamjan Jovanovic 		e->_n4 = pTypeDescr->nSize;
315*b146d3b3SDamjan Jovanovic 		e->_pCopyCtor = copyConstructorRVA;
316*b146d3b3SDamjan Jovanovic 		e->_n5 = 0;
317*b146d3b3SDamjan Jovanovic 	}
318*b146d3b3SDamjan Jovanovic };
319*b146d3b3SDamjan Jovanovic 
320*b146d3b3SDamjan Jovanovic //==================================================================================================
321*b146d3b3SDamjan Jovanovic // Known as "throwinfo" in https://github.com/icestudent/ontl/blob/master/ntl/nt/exception.hxx
322*b146d3b3SDamjan Jovanovic struct RaiseInfo
323*b146d3b3SDamjan Jovanovic {
324*b146d3b3SDamjan Jovanovic 	// Microsoft's fields:
325*b146d3b3SDamjan Jovanovic 	sal_uInt32			_n0;
326*b146d3b3SDamjan Jovanovic 	sal_uInt32			_pDtor; // RVA on Win64
327*b146d3b3SDamjan Jovanovic 	sal_uInt32			_n2;
328*b146d3b3SDamjan Jovanovic 	sal_uInt32			_types; // void *, RVA on Win64
329*b146d3b3SDamjan Jovanovic 
330*b146d3b3SDamjan Jovanovic 	// Our additional fields:
331*b146d3b3SDamjan Jovanovic 	typelib_TypeDescription * pTypeDescr;
332*b146d3b3SDamjan Jovanovic 	unsigned char		*baseAddress; // The RVAs are relative to this field
333*b146d3b3SDamjan Jovanovic 
334*b146d3b3SDamjan Jovanovic 	RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
335*b146d3b3SDamjan Jovanovic 	~RaiseInfo() throw ();
336*b146d3b3SDamjan Jovanovic };
337*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
RaiseInfo(typelib_TypeDescription * pTypeDescr)338*b146d3b3SDamjan Jovanovic RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
339*b146d3b3SDamjan Jovanovic 	: _n0( 0 )
340*b146d3b3SDamjan Jovanovic 	, _n2( 0 )
341*b146d3b3SDamjan Jovanovic {
342*b146d3b3SDamjan Jovanovic 	// a must be
343*b146d3b3SDamjan Jovanovic 	OSL_ENSURE( sizeof(sal_Int32) == sizeof(ExceptionType *), "### pointer size differs from sal_Int32!" );
344*b146d3b3SDamjan Jovanovic 
345*b146d3b3SDamjan Jovanovic 	::typelib_typedescription_acquire( pTypeDescr );
346*b146d3b3SDamjan Jovanovic 	this->pTypeDescr = pTypeDescr;
347*b146d3b3SDamjan Jovanovic 
348*b146d3b3SDamjan Jovanovic 	typelib_CompoundTypeDescription * pCompTypeDescr;
349*b146d3b3SDamjan Jovanovic 
350*b146d3b3SDamjan Jovanovic 	size_t bytesNeeded = codeSnippetSize; // destructCodeSnippet for _pDtor
351*b146d3b3SDamjan Jovanovic 	sal_uInt32 typeCount = 0;
352*b146d3b3SDamjan Jovanovic 	for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
353*b146d3b3SDamjan Jovanovic 		  pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
354*b146d3b3SDamjan Jovanovic 	{
355*b146d3b3SDamjan Jovanovic 		++typeCount;
356*b146d3b3SDamjan Jovanovic 		bytesNeeded += align16( sizeof( ExceptionType ) );
357*b146d3b3SDamjan Jovanovic 		__type_info *typeInfo = (__type_info*) mscx_getRTTI( ((typelib_TypeDescription *)pCompTypeDescr)->pTypeName );
358*b146d3b3SDamjan Jovanovic 		bytesNeeded += align16( typeInfo->length() );
359*b146d3b3SDamjan Jovanovic 		bytesNeeded += codeSnippetSize; // copyConstructCodeSnippet for its _pCopyCtor
360*b146d3b3SDamjan Jovanovic 	}
361*b146d3b3SDamjan Jovanovic 	// type info count accompanied by RVAs of type info ptrs: type, base type, base base type, ...
362*b146d3b3SDamjan Jovanovic     bytesNeeded += align16( sizeof( sal_uInt32 ) + (typeCount * sizeof( sal_uInt32 )) );
363*b146d3b3SDamjan Jovanovic 
364*b146d3b3SDamjan Jovanovic     unsigned char *p = (unsigned char*) ::rtl_allocateMemory( bytesNeeded );
365*b146d3b3SDamjan Jovanovic 	DWORD old_protect;
366*b146d3b3SDamjan Jovanovic #if OSL_DEBUG_LEVEL > 0
367*b146d3b3SDamjan Jovanovic 	BOOL success =
368*b146d3b3SDamjan Jovanovic #endif
369*b146d3b3SDamjan Jovanovic 	VirtualProtect( p, bytesNeeded, PAGE_EXECUTE_READWRITE, &old_protect );
370*b146d3b3SDamjan Jovanovic 	OSL_ENSURE( success, "VirtualProtect() failed!" );
371*b146d3b3SDamjan Jovanovic 	baseAddress = p;
372*b146d3b3SDamjan Jovanovic 
373*b146d3b3SDamjan Jovanovic 	destructCodeSnippet( p, pTypeDescr );
374*b146d3b3SDamjan Jovanovic 	_pDtor = (sal_uInt32)(p - baseAddress);
375*b146d3b3SDamjan Jovanovic 	p += codeSnippetSize;
376*b146d3b3SDamjan Jovanovic 
377*b146d3b3SDamjan Jovanovic 	sal_uInt32 *types = (sal_uInt32*)p;
378*b146d3b3SDamjan Jovanovic 	_types = (sal_uInt32)(p - baseAddress);
379*b146d3b3SDamjan Jovanovic 	p += align16( sizeof( sal_uInt32 ) + (typeCount * sizeof( sal_uInt32 )) );
380*b146d3b3SDamjan Jovanovic 	types[0] = typeCount;
381*b146d3b3SDamjan Jovanovic 	int next = 1;
382*b146d3b3SDamjan Jovanovic 	for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
383*b146d3b3SDamjan Jovanovic 		  pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
384*b146d3b3SDamjan Jovanovic 	{
385*b146d3b3SDamjan Jovanovic 		__type_info *typeInfo = (__type_info*) mscx_getRTTI( ((typelib_TypeDescription *)pCompTypeDescr)->pTypeName );
386*b146d3b3SDamjan Jovanovic 		memcpy(p, typeInfo, typeInfo->length() );
387*b146d3b3SDamjan Jovanovic 		sal_uInt32 typeInfoRVA = (sal_uInt32)(p - baseAddress);
388*b146d3b3SDamjan Jovanovic 		p += align16( typeInfo->length() );
389*b146d3b3SDamjan Jovanovic 
390*b146d3b3SDamjan Jovanovic 		copyConstructCodeSnippet( p, (typelib_TypeDescription *)pCompTypeDescr );
391*b146d3b3SDamjan Jovanovic 		sal_uInt32 copyConstructorRVA = (sal_uInt32)(p - baseAddress);
392*b146d3b3SDamjan Jovanovic 		p += codeSnippetSize;
393*b146d3b3SDamjan Jovanovic 
394*b146d3b3SDamjan Jovanovic 		ExceptionType::initialize( p, typeInfoRVA, (typelib_TypeDescription *)pCompTypeDescr, copyConstructorRVA );
395*b146d3b3SDamjan Jovanovic 		types[next++] = (sal_uInt32)(p - baseAddress);
396*b146d3b3SDamjan Jovanovic 		p += align16( sizeof(ExceptionType) );
397*b146d3b3SDamjan Jovanovic 	}
398*b146d3b3SDamjan Jovanovic 
399*b146d3b3SDamjan Jovanovic 	OSL_ASSERT(p - baseAddress <= bytesNeeded);
400*b146d3b3SDamjan Jovanovic }
401*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
~RaiseInfo()402*b146d3b3SDamjan Jovanovic RaiseInfo::~RaiseInfo() throw ()
403*b146d3b3SDamjan Jovanovic {
404*b146d3b3SDamjan Jovanovic 	::rtl_freeMemory( baseAddress );
405*b146d3b3SDamjan Jovanovic 	::typelib_typedescription_release( pTypeDescr );
406*b146d3b3SDamjan Jovanovic }
407*b146d3b3SDamjan Jovanovic 
408*b146d3b3SDamjan Jovanovic //==================================================================================================
409*b146d3b3SDamjan Jovanovic class ExceptionInfos
410*b146d3b3SDamjan Jovanovic {
411*b146d3b3SDamjan Jovanovic 	Mutex			_aMutex;
412*b146d3b3SDamjan Jovanovic 	t_string2PtrMap	_allRaiseInfos;
413*b146d3b3SDamjan Jovanovic 
414*b146d3b3SDamjan Jovanovic public:
415*b146d3b3SDamjan Jovanovic 	static RaiseInfo * getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
416*b146d3b3SDamjan Jovanovic 
417*b146d3b3SDamjan Jovanovic 	ExceptionInfos() throw ();
418*b146d3b3SDamjan Jovanovic 	~ExceptionInfos() throw ();
419*b146d3b3SDamjan Jovanovic };
420*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
ExceptionInfos()421*b146d3b3SDamjan Jovanovic ExceptionInfos::ExceptionInfos() throw ()
422*b146d3b3SDamjan Jovanovic {
423*b146d3b3SDamjan Jovanovic }
424*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
~ExceptionInfos()425*b146d3b3SDamjan Jovanovic ExceptionInfos::~ExceptionInfos() throw ()
426*b146d3b3SDamjan Jovanovic {
427*b146d3b3SDamjan Jovanovic #if OSL_DEBUG_LEVEL > 1
428*b146d3b3SDamjan Jovanovic 	OSL_TRACE( "> freeing exception infos... <\n" );
429*b146d3b3SDamjan Jovanovic #endif
430*b146d3b3SDamjan Jovanovic 
431*b146d3b3SDamjan Jovanovic 	MutexGuard aGuard( _aMutex );
432*b146d3b3SDamjan Jovanovic 	for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
433*b146d3b3SDamjan Jovanovic           iPos != _allRaiseInfos.end(); ++iPos )
434*b146d3b3SDamjan Jovanovic 	{
435*b146d3b3SDamjan Jovanovic 		delete (RaiseInfo *)iPos->second;
436*b146d3b3SDamjan Jovanovic 	}
437*b146d3b3SDamjan Jovanovic }
438*b146d3b3SDamjan Jovanovic //__________________________________________________________________________________________________
getRaiseInfo(typelib_TypeDescription * pTypeDescr)439*b146d3b3SDamjan Jovanovic RaiseInfo * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
440*b146d3b3SDamjan Jovanovic {
441*b146d3b3SDamjan Jovanovic 	static ExceptionInfos * s_pInfos = 0;
442*b146d3b3SDamjan Jovanovic 	if (! s_pInfos)
443*b146d3b3SDamjan Jovanovic 	{
444*b146d3b3SDamjan Jovanovic 		MutexGuard aGuard( Mutex::getGlobalMutex() );
445*b146d3b3SDamjan Jovanovic 		if (! s_pInfos)
446*b146d3b3SDamjan Jovanovic 		{
447*b146d3b3SDamjan Jovanovic #ifdef LEAK_STATIC_DATA
448*b146d3b3SDamjan Jovanovic 			s_pInfos = new ExceptionInfos();
449*b146d3b3SDamjan Jovanovic #else
450*b146d3b3SDamjan Jovanovic 			static ExceptionInfos s_allExceptionInfos;
451*b146d3b3SDamjan Jovanovic 			s_pInfos = &s_allExceptionInfos;
452*b146d3b3SDamjan Jovanovic #endif
453*b146d3b3SDamjan Jovanovic 		}
454*b146d3b3SDamjan Jovanovic 	}
455*b146d3b3SDamjan Jovanovic 
456*b146d3b3SDamjan Jovanovic 	OSL_ASSERT( pTypeDescr &&
457*b146d3b3SDamjan Jovanovic                 (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
458*b146d3b3SDamjan Jovanovic                  pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION) );
459*b146d3b3SDamjan Jovanovic 
460*b146d3b3SDamjan Jovanovic     void * pRaiseInfo;
461*b146d3b3SDamjan Jovanovic 
462*b146d3b3SDamjan Jovanovic     OUString const & rTypeName = *reinterpret_cast< OUString * >( &pTypeDescr->pTypeName );
463*b146d3b3SDamjan Jovanovic 	MutexGuard aGuard( s_pInfos->_aMutex );
464*b146d3b3SDamjan Jovanovic 	t_string2PtrMap::const_iterator const iFind(
465*b146d3b3SDamjan Jovanovic         s_pInfos->_allRaiseInfos.find( rTypeName ) );
466*b146d3b3SDamjan Jovanovic     if (iFind == s_pInfos->_allRaiseInfos.end())
467*b146d3b3SDamjan Jovanovic     {
468*b146d3b3SDamjan Jovanovic         pRaiseInfo = new RaiseInfo( pTypeDescr );
469*b146d3b3SDamjan Jovanovic         // put into map
470*b146d3b3SDamjan Jovanovic 		pair< t_string2PtrMap::iterator, bool > insertion(
471*b146d3b3SDamjan Jovanovic             s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, pRaiseInfo ) ) );
472*b146d3b3SDamjan Jovanovic         OSL_ENSURE( insertion.second, "### raise info insertion failed?!" );
473*b146d3b3SDamjan Jovanovic     }
474*b146d3b3SDamjan Jovanovic     else
475*b146d3b3SDamjan Jovanovic     {
476*b146d3b3SDamjan Jovanovic         // reuse existing info
477*b146d3b3SDamjan Jovanovic         pRaiseInfo = iFind->second;
478*b146d3b3SDamjan Jovanovic     }
479*b146d3b3SDamjan Jovanovic 
480*b146d3b3SDamjan Jovanovic     return (RaiseInfo*) pRaiseInfo;
481*b146d3b3SDamjan Jovanovic }
482*b146d3b3SDamjan Jovanovic 
483*b146d3b3SDamjan Jovanovic 
484*b146d3b3SDamjan Jovanovic //##################################################################################################
485*b146d3b3SDamjan Jovanovic //#### exported ####################################################################################
486*b146d3b3SDamjan Jovanovic //##################################################################################################
487*b146d3b3SDamjan Jovanovic 
488*b146d3b3SDamjan Jovanovic 
489*b146d3b3SDamjan Jovanovic //##################################################################################################
mscx_getRTTI(OUString const & rUNOname)490*b146d3b3SDamjan Jovanovic type_info * mscx_getRTTI( OUString const & rUNOname )
491*b146d3b3SDamjan Jovanovic {
492*b146d3b3SDamjan Jovanovic 	static RTTInfos * s_pRTTIs = 0;
493*b146d3b3SDamjan Jovanovic 	if (! s_pRTTIs)
494*b146d3b3SDamjan Jovanovic 	{
495*b146d3b3SDamjan Jovanovic 		MutexGuard aGuard( Mutex::getGlobalMutex() );
496*b146d3b3SDamjan Jovanovic 		if (! s_pRTTIs)
497*b146d3b3SDamjan Jovanovic 		{
498*b146d3b3SDamjan Jovanovic #ifdef LEAK_STATIC_DATA
499*b146d3b3SDamjan Jovanovic 			s_pRTTIs = new RTTInfos();
500*b146d3b3SDamjan Jovanovic #else
501*b146d3b3SDamjan Jovanovic 			static RTTInfos s_aRTTIs;
502*b146d3b3SDamjan Jovanovic 			s_pRTTIs = &s_aRTTIs;
503*b146d3b3SDamjan Jovanovic #endif
504*b146d3b3SDamjan Jovanovic 		}
505*b146d3b3SDamjan Jovanovic 	}
506*b146d3b3SDamjan Jovanovic 	return s_pRTTIs->getRTTI( rUNOname );
507*b146d3b3SDamjan Jovanovic }
508*b146d3b3SDamjan Jovanovic 
509*b146d3b3SDamjan Jovanovic //##################################################################################################
mscx_raiseException(uno_Any * pUnoExc,uno_Mapping * pUno2Cpp)510*b146d3b3SDamjan Jovanovic void mscx_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
511*b146d3b3SDamjan Jovanovic {
512*b146d3b3SDamjan Jovanovic     // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
513*b146d3b3SDamjan Jovanovic     // thus this obj file will be compiled without opt, so no inling of
514*b146d3b3SDamjan Jovanovic     // ExceptionInfos::getRaiseInfo()
515*b146d3b3SDamjan Jovanovic 
516*b146d3b3SDamjan Jovanovic 	// construct cpp exception object
517*b146d3b3SDamjan Jovanovic 	typelib_TypeDescription * pTypeDescr = 0;
518*b146d3b3SDamjan Jovanovic 	TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
519*b146d3b3SDamjan Jovanovic 
520*b146d3b3SDamjan Jovanovic 	void * pCppExc = alloca( pTypeDescr->nSize );
521*b146d3b3SDamjan Jovanovic 	::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
522*b146d3b3SDamjan Jovanovic 
523*b146d3b3SDamjan Jovanovic 	// a must be
524*b146d3b3SDamjan Jovanovic 	OSL_ENSURE(
525*b146d3b3SDamjan Jovanovic         sizeof(sal_Int32) == sizeof(void *),
526*b146d3b3SDamjan Jovanovic         "### pointer size differs from sal_Int32!" );
527*b146d3b3SDamjan Jovanovic 	RaiseInfo *raiseInfo = ExceptionInfos::getRaiseInfo( pTypeDescr );
528*b146d3b3SDamjan Jovanovic 	ULONG_PTR arFilterArgs[4];
529*b146d3b3SDamjan Jovanovic 	arFilterArgs[0] = MSVC_magic_number;
530*b146d3b3SDamjan Jovanovic 	arFilterArgs[1] = (ULONG_PTR)pCppExc;
531*b146d3b3SDamjan Jovanovic     arFilterArgs[2] = (ULONG_PTR)raiseInfo;
532*b146d3b3SDamjan Jovanovic     arFilterArgs[3] = (ULONG_PTR)raiseInfo->baseAddress;
533*b146d3b3SDamjan Jovanovic 
534*b146d3b3SDamjan Jovanovic 	// destruct uno exception
535*b146d3b3SDamjan Jovanovic 	::uno_any_destruct( pUnoExc, 0 );
536*b146d3b3SDamjan Jovanovic 	TYPELIB_DANGER_RELEASE( pTypeDescr );
537*b146d3b3SDamjan Jovanovic 
538*b146d3b3SDamjan Jovanovic 	// last point to release anything not affected by stack unwinding
539*b146d3b3SDamjan Jovanovic 	RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 4, arFilterArgs );
540*b146d3b3SDamjan Jovanovic }
541*b146d3b3SDamjan Jovanovic 
542*b146d3b3SDamjan Jovanovic //##############################################################################
mscx_filterCppException(EXCEPTION_POINTERS * pPointers,uno_Any * pUnoExc,uno_Mapping * pCpp2Uno)543*b146d3b3SDamjan Jovanovic int mscx_filterCppException(
544*b146d3b3SDamjan Jovanovic 	EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
545*b146d3b3SDamjan Jovanovic {
546*b146d3b3SDamjan Jovanovic 	if (pPointers == 0)
547*b146d3b3SDamjan Jovanovic         return EXCEPTION_CONTINUE_SEARCH;
548*b146d3b3SDamjan Jovanovic 	EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
549*b146d3b3SDamjan Jovanovic     // handle only C++ exceptions:
550*b146d3b3SDamjan Jovanovic 	if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
551*b146d3b3SDamjan Jovanovic         return EXCEPTION_CONTINUE_SEARCH;
552*b146d3b3SDamjan Jovanovic 
553*b146d3b3SDamjan Jovanovic #if _MSC_VER < 1300 // MSVC -6
554*b146d3b3SDamjan Jovanovic     bool rethrow = (pRecord->NumberParameters < 3 ||
555*b146d3b3SDamjan Jovanovic                     pRecord->ExceptionInformation[ 2 ] == 0);
556*b146d3b3SDamjan Jovanovic #else
557*b146d3b3SDamjan Jovanovic     bool rethrow = __CxxDetectRethrow( &pRecord );
558*b146d3b3SDamjan Jovanovic     OSL_ASSERT( pRecord == pPointers->ExceptionRecord );
559*b146d3b3SDamjan Jovanovic #endif
560*b146d3b3SDamjan Jovanovic     if (rethrow && pRecord == pPointers->ExceptionRecord)
561*b146d3b3SDamjan Jovanovic     {
562*b146d3b3SDamjan Jovanovic         // hack to get msvcrt internal _curexception field:
563*b146d3b3SDamjan Jovanovic         pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(
564*b146d3b3SDamjan Jovanovic             reinterpret_cast< char * >( __pxcptinfoptrs() ) +
565*b146d3b3SDamjan Jovanovic             // as long as we don't demand msvcr source as build prerequisite
566*b146d3b3SDamjan Jovanovic             // (->platform sdk), we have to code those offsets here.
567*b146d3b3SDamjan Jovanovic             //
568*b146d3b3SDamjan Jovanovic             // crt\src\mtdll.h:
569*b146d3b3SDamjan Jovanovic             // offsetof (_tiddata, _curexception) -
570*b146d3b3SDamjan Jovanovic             // offsetof (_tiddata, _tpxcptinfoptrs):
571*b146d3b3SDamjan Jovanovic             48
572*b146d3b3SDamjan Jovanovic             );
573*b146d3b3SDamjan Jovanovic     }
574*b146d3b3SDamjan Jovanovic     // rethrow: handle only C++ exceptions:
575*b146d3b3SDamjan Jovanovic 	if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
576*b146d3b3SDamjan Jovanovic         return EXCEPTION_CONTINUE_SEARCH;
577*b146d3b3SDamjan Jovanovic 
578*b146d3b3SDamjan Jovanovic     if (pRecord->NumberParameters == 4 &&
579*b146d3b3SDamjan Jovanovic //  		pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
580*b146d3b3SDamjan Jovanovic 		pRecord->ExceptionInformation[ 1 ] != 0 &&
581*b146d3b3SDamjan Jovanovic 		pRecord->ExceptionInformation[ 2 ] != 0 &&
582*b146d3b3SDamjan Jovanovic 		pRecord->ExceptionInformation[ 3 ] != 0)
583*b146d3b3SDamjan Jovanovic 	{
584*b146d3b3SDamjan Jovanovic 		unsigned char *baseAddress = (unsigned char*) pRecord->ExceptionInformation[ 3 ];
585*b146d3b3SDamjan Jovanovic 		sal_uInt32 * types = (sal_uInt32*)(baseAddress + reinterpret_cast< RaiseInfo * >(
586*b146d3b3SDamjan Jovanovic             pRecord->ExceptionInformation[ 2 ] )->_types );
587*b146d3b3SDamjan Jovanovic 		if (types != 0 && (sal_uInt32)(types[0]) > 0) // count
588*b146d3b3SDamjan Jovanovic 		{
589*b146d3b3SDamjan Jovanovic 			ExceptionType * pType = reinterpret_cast< ExceptionType * >(
590*b146d3b3SDamjan Jovanovic                 baseAddress + types[ 1 ] );
591*b146d3b3SDamjan Jovanovic 			if (pType != 0 && pType->_pTypeInfo != 0)
592*b146d3b3SDamjan Jovanovic 			{
593*b146d3b3SDamjan Jovanovic                 OUString aRTTIname(
594*b146d3b3SDamjan Jovanovic                     OStringToOUString(
595*b146d3b3SDamjan Jovanovic                         reinterpret_cast< __type_info * >(
596*b146d3b3SDamjan Jovanovic                             baseAddress + pType->_pTypeInfo )->_m_d_name,
597*b146d3b3SDamjan Jovanovic                         RTL_TEXTENCODING_ASCII_US ) );
598*b146d3b3SDamjan Jovanovic 				OUString aUNOname( toUNOname( aRTTIname ) );
599*b146d3b3SDamjan Jovanovic 
600*b146d3b3SDamjan Jovanovic 				typelib_TypeDescription * pExcTypeDescr = 0;
601*b146d3b3SDamjan Jovanovic 				typelib_typedescription_getByName(
602*b146d3b3SDamjan Jovanovic                     &pExcTypeDescr, aUNOname.pData );
603*b146d3b3SDamjan Jovanovic 				if (pExcTypeDescr == 0)
604*b146d3b3SDamjan Jovanovic 				{
605*b146d3b3SDamjan Jovanovic                     OUStringBuffer buf;
606*b146d3b3SDamjan Jovanovic                     buf.appendAscii(
607*b146d3b3SDamjan Jovanovic                         RTL_CONSTASCII_STRINGPARAM(
608*b146d3b3SDamjan Jovanovic                             "[mscx_uno bridge error] UNO type of "
609*b146d3b3SDamjan Jovanovic                             "C++ exception unknown: \"") );
610*b146d3b3SDamjan Jovanovic                     buf.append( aUNOname );
611*b146d3b3SDamjan Jovanovic                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
612*b146d3b3SDamjan Jovanovic                                          "\", RTTI-name=\"") );
613*b146d3b3SDamjan Jovanovic                     buf.append( aRTTIname );
614*b146d3b3SDamjan Jovanovic                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
615*b146d3b3SDamjan Jovanovic                     RuntimeException exc(
616*b146d3b3SDamjan Jovanovic                         buf.makeStringAndClear(), Reference< XInterface >() );
617*b146d3b3SDamjan Jovanovic                     uno_type_any_constructAndConvert(
618*b146d3b3SDamjan Jovanovic                         pUnoExc, &exc,
619*b146d3b3SDamjan Jovanovic                         ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
620*b146d3b3SDamjan Jovanovic #if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
621*b146d3b3SDamjan Jovanovic                     // if (! rethrow):
622*b146d3b3SDamjan Jovanovic                     // though this unknown exception leaks now, no user-defined
623*b146d3b3SDamjan Jovanovic                     // exception is ever thrown through the binary C-UNO dispatcher
624*b146d3b3SDamjan Jovanovic                     // call stack.
625*b146d3b3SDamjan Jovanovic #endif
626*b146d3b3SDamjan Jovanovic 				}
627*b146d3b3SDamjan Jovanovic 				else
628*b146d3b3SDamjan Jovanovic 				{
629*b146d3b3SDamjan Jovanovic 					// construct uno exception any
630*b146d3b3SDamjan Jovanovic 					uno_any_constructAndConvert(
631*b146d3b3SDamjan Jovanovic 						pUnoExc, (void *) pRecord->ExceptionInformation[1],
632*b146d3b3SDamjan Jovanovic 						pExcTypeDescr, pCpp2Uno );
633*b146d3b3SDamjan Jovanovic #if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
634*b146d3b3SDamjan Jovanovic                     if (! rethrow)
635*b146d3b3SDamjan Jovanovic                     {
636*b146d3b3SDamjan Jovanovic                         uno_destructData(
637*b146d3b3SDamjan Jovanovic                             (void *) pRecord->ExceptionInformation[1],
638*b146d3b3SDamjan Jovanovic                             pExcTypeDescr, cpp_release );
639*b146d3b3SDamjan Jovanovic                     }
640*b146d3b3SDamjan Jovanovic #endif
641*b146d3b3SDamjan Jovanovic 					typelib_typedescription_release( pExcTypeDescr );
642*b146d3b3SDamjan Jovanovic 				}
643*b146d3b3SDamjan Jovanovic 
644*b146d3b3SDamjan Jovanovic 				return EXCEPTION_EXECUTE_HANDLER;
645*b146d3b3SDamjan Jovanovic 			}
646*b146d3b3SDamjan Jovanovic 		}
647*b146d3b3SDamjan Jovanovic 	}
648*b146d3b3SDamjan Jovanovic     // though this unknown exception leaks now, no user-defined exception
649*b146d3b3SDamjan Jovanovic     // is ever thrown through the binary C-UNO dispatcher call stack.
650*b146d3b3SDamjan Jovanovic     RuntimeException exc(
651*b146d3b3SDamjan Jovanovic         OUString( RTL_CONSTASCII_USTRINGPARAM(
652*b146d3b3SDamjan Jovanovic                       "[mscx_uno bridge error] unexpected "
653*b146d3b3SDamjan Jovanovic                       "C++ exception occurred!") ),
654*b146d3b3SDamjan Jovanovic         Reference< XInterface >() );
655*b146d3b3SDamjan Jovanovic     uno_type_any_constructAndConvert(
656*b146d3b3SDamjan Jovanovic         pUnoExc, &exc, ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
657*b146d3b3SDamjan Jovanovic     return EXCEPTION_EXECUTE_HANDLER;
658*b146d3b3SDamjan Jovanovic }
659*b146d3b3SDamjan Jovanovic 
660*b146d3b3SDamjan Jovanovic }
661*b146d3b3SDamjan Jovanovic 
662*b146d3b3SDamjan Jovanovic #pragma pack(pop)
663*b146d3b3SDamjan Jovanovic 
664