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