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