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_cppuhelper.hxx" 26 27 #include <string.h> 28 #include <vector> 29 30 #include "rtl/process.h" 31 #include "rtl/bootstrap.hxx" 32 #include "rtl/random.h" 33 #include "rtl/string.hxx" 34 #include "rtl/ustrbuf.hxx" 35 #include "rtl/uri.hxx" 36 #if OSL_DEBUG_LEVEL > 0 37 #include "rtl/strbuf.hxx" 38 #endif 39 #include "osl/diagnose.h" 40 #include "osl/file.hxx" 41 #include "osl/module.hxx" 42 #include "osl/security.hxx" 43 #include "osl/thread.hxx" 44 45 #include "cppuhelper/shlib.hxx" 46 #include "cppuhelper/bootstrap.hxx" 47 #include "cppuhelper/component_context.hxx" 48 #include "cppuhelper/access_control.hxx" 49 #include "cppuhelper/findsofficepath.h" 50 51 #include <cppuhelper/com/sun/star/container/XElementAccess.hpp> 52 53 #include "com/sun/star/uno/XComponentContext.hpp" 54 #include "com/sun/star/uno/XCurrentContext.hpp" 55 56 #include "com/sun/star/lang/XSingleServiceFactory.hpp" 57 #include "com/sun/star/lang/XSingleComponentFactory.hpp" 58 #include "com/sun/star/lang/XInitialization.hpp" 59 #include "com/sun/star/lang/XServiceInfo.hpp" 60 #include "com/sun/star/registry/XSimpleRegistry.hpp" 61 #include "com/sun/star/container/XSet.hpp" 62 #include "com/sun/star/beans/PropertyValue.hpp" 63 #include "com/sun/star/io/IOException.hpp" 64 #include "com/sun/star/bridge/UnoUrlResolver.hpp" 65 #include "com/sun/star/bridge/XUnoUrlResolver.hpp" 66 67 #include "macro_expander.hxx" 68 69 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 70 #define ARLEN(x) sizeof (x) / sizeof *(x) 71 72 void primeWeakMap( void); // as defined in primeweak.cxx 73 74 using namespace ::rtl; 75 using namespace ::osl; 76 using namespace ::com::sun::star; 77 using namespace ::com::sun::star::uno; 78 79 namespace cppu 80 { 81 82 OUString const & get_this_libpath() 83 { 84 static OUString s_path; 85 if (0 == s_path.getLength()) 86 { 87 OUString path; 88 Module::getUrlFromAddress( reinterpret_cast<oslGenericFunction>(get_this_libpath), path ); 89 path = path.copy( 0, path.lastIndexOf( '/' ) ); 90 MutexGuard guard( Mutex::getGlobalMutex() ); 91 if (0 == s_path.getLength()) 92 s_path = path; 93 } 94 return s_path; 95 } 96 97 Bootstrap const & get_unorc() SAL_THROW( () ) 98 { 99 static rtlBootstrapHandle s_bstrap = 0; 100 if (! s_bstrap) 101 { 102 OUString iniName( 103 get_this_libpath() + OUSTR("/" SAL_CONFIGFILE("uno")) ); 104 rtlBootstrapHandle bstrap = rtl_bootstrap_args_open( iniName.pData ); 105 106 ClearableMutexGuard guard( Mutex::getGlobalMutex() ); 107 if (s_bstrap) 108 { 109 guard.clear(); 110 rtl_bootstrap_args_close( bstrap ); 111 } 112 else 113 { 114 s_bstrap = bstrap; 115 } 116 } 117 return *(Bootstrap const *)&s_bstrap; 118 } 119 120 121 void addFactories( 122 char const * const * ppNames /* lib, implname, ..., 0 */, 123 OUString const & bootstrapPath, 124 Reference< lang::XMultiComponentFactory > const & xMgr, 125 Reference< registry::XRegistryKey > const & xKey ) 126 SAL_THROW( (Exception) ) 127 { 128 Reference< container::XSet > xSet( xMgr, UNO_QUERY ); 129 OSL_ASSERT( xSet.is() ); 130 Reference< lang::XMultiServiceFactory > xSF( xMgr, UNO_QUERY ); 131 132 while (*ppNames) 133 { 134 OUString lib( OUString::createFromAscii( *ppNames++ ) ); 135 OUString implName( OUString::createFromAscii( *ppNames++ ) ); 136 137 Any aFac( makeAny( loadSharedLibComponentFactory( 138 lib, bootstrapPath, implName, xSF, xKey ) ) ); 139 xSet->insert( aFac ); 140 #if OSL_DEBUG_LEVEL > 1 141 if (xSet->has( aFac )) 142 { 143 Reference< lang::XServiceInfo > xInfo; 144 if (aFac >>= xInfo) 145 { 146 ::fprintf( 147 stderr, "> implementation %s supports: ", ppNames[ -1 ] ); 148 Sequence< OUString > supported( 149 xInfo->getSupportedServiceNames() ); 150 for ( sal_Int32 nPos = supported.getLength(); nPos--; ) 151 { 152 OString str( OUStringToOString( 153 supported[ nPos ], RTL_TEXTENCODING_ASCII_US ) ); 154 ::fprintf( stderr, nPos ? "%s, " : "%s\n", str.getStr() ); 155 } 156 } 157 else 158 { 159 ::fprintf( 160 stderr, 161 "> implementation %s provides NO lang::XServiceInfo!!!\n", 162 ppNames[ -1 ] ); 163 } 164 } 165 #endif 166 #if OSL_DEBUG_LEVEL > 0 167 if (! xSet->has( aFac )) 168 { 169 OStringBuffer buf( 64 ); 170 buf.append( "### failed inserting shared lib \"" ); 171 buf.append( ppNames[ -2 ] ); 172 buf.append( "\"!!!" ); 173 OString str( buf.makeStringAndClear() ); 174 OSL_ENSURE( 0, str.getStr() ); 175 } 176 #endif 177 } 178 } 179 180 // private forward decl 181 Reference< lang::XMultiComponentFactory > bootstrapInitialSF( 182 OUString const & rBootstrapPath ) 183 SAL_THROW( (Exception) ); 184 185 Reference< XComponentContext > bootstrapInitialContext( 186 Reference< lang::XMultiComponentFactory > const & xSF, 187 Reference< registry::XSimpleRegistry > const & types_xRegistry, 188 Reference< registry::XSimpleRegistry > const & services_xRegistry, 189 OUString const & rBootstrapPath, Bootstrap const & bootstrap ) 190 SAL_THROW( (Exception) ); 191 192 Reference< XComponentContext > SAL_CALL createInitialCfgComponentContext( 193 ContextEntry_Init const * pEntries, sal_Int32 nEntries, 194 Reference< XComponentContext > const & xDelegate ) 195 SAL_THROW( () ); 196 197 Reference< registry::XSimpleRegistry > SAL_CALL createRegistryWrapper( 198 const Reference< XComponentContext >& xContext ); 199 200 namespace { 201 202 template< class T > 203 inline beans::PropertyValue createPropertyValue( 204 OUString const & name, T const & value ) 205 SAL_THROW( () ) 206 { 207 return beans::PropertyValue( 208 name, -1, makeAny( value ), beans::PropertyState_DIRECT_VALUE ); 209 } 210 211 OUString findBoostrapArgument( 212 const Bootstrap & bootstrap, 213 const OUString & arg_name, 214 sal_Bool * pFallenBack ) 215 SAL_THROW(()) 216 { 217 OUString result; 218 219 OUString prefixed_arg_name = OUSTR("UNO_"); 220 prefixed_arg_name += arg_name.toAsciiUpperCase(); 221 222 // environment not set -> try relative to executable 223 if(!bootstrap.getFrom(prefixed_arg_name, result)) 224 { 225 if(pFallenBack) 226 *pFallenBack = sal_True; 227 228 OUString fileName; 229 bootstrap.getIniName(fileName); 230 231 // cut the rc extension 232 OUStringBuffer result_buf( 64 ); 233 result_buf.append( 234 fileName.copy( 235 0, fileName.getLength() - strlen(SAL_CONFIGFILE(""))) ); 236 result_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_") ); 237 result_buf.append( arg_name.toAsciiLowerCase() ); 238 result_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".rdb") ); 239 result = result_buf.makeStringAndClear(); 240 241 #if OSL_DEBUG_LEVEL > 1 242 OString result_dbg = 243 OUStringToOString(result, RTL_TEXTENCODING_ASCII_US); 244 OString arg_name_dbg = 245 OUStringToOString(arg_name, RTL_TEXTENCODING_ASCII_US); 246 OSL_TRACE( 247 "cppuhelper::findBoostrapArgument - " 248 "setting %s relative to executable: %s\n", 249 arg_name_dbg.getStr(), 250 result_dbg.getStr() ); 251 #endif 252 } 253 else 254 { 255 if(pFallenBack) 256 *pFallenBack = sal_False; 257 258 #if OSL_DEBUG_LEVEL > 1 259 OString prefixed_arg_name_dbg = OUStringToOString( 260 prefixed_arg_name, RTL_TEXTENCODING_ASCII_US ); 261 OString result_dbg = OUStringToOString( 262 result, RTL_TEXTENCODING_ASCII_US ); 263 OSL_TRACE( 264 "cppuhelper::findBoostrapArgument - found %s in env: %s", 265 prefixed_arg_name_dbg.getStr(), 266 result_dbg.getStr() ); 267 #endif 268 } 269 270 return result; 271 } 272 273 Reference< registry::XSimpleRegistry > nestRegistries( 274 const OUString baseDir, 275 const Reference< lang::XSingleServiceFactory > & xSimRegFac, 276 const Reference< lang::XSingleServiceFactory > & xNesRegFac, 277 OUString csl_rdbs, 278 const OUString & write_rdb, 279 sal_Bool forceWrite_rdb, 280 sal_Bool bFallenBack ) 281 SAL_THROW((Exception)) 282 { 283 sal_Int32 index; 284 Reference< registry::XSimpleRegistry > lastRegistry; 285 286 if(write_rdb.getLength()) // is there a write registry given? 287 { 288 lastRegistry.set(xSimRegFac->createInstance(), UNO_QUERY); 289 290 try 291 { 292 lastRegistry->open(write_rdb, sal_False, forceWrite_rdb); 293 } 294 catch (registry::InvalidRegistryException & invalidRegistryException) 295 { 296 (void) invalidRegistryException; 297 #if OSL_DEBUG_LEVEL > 1 298 OString rdb_name_tmp = OUStringToOString( 299 write_rdb, RTL_TEXTENCODING_ASCII_US); 300 OString message_dbg = OUStringToOString( 301 invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US); 302 OSL_TRACE( 303 "warning: couldn't open %s cause of %s", 304 rdb_name_tmp.getStr(), message_dbg.getStr() ); 305 #endif 306 } 307 308 if(!lastRegistry->isValid()) 309 lastRegistry.clear(); 310 } 311 312 do 313 { 314 index = csl_rdbs.indexOf((sal_Unicode)' '); 315 OUString rdb_name = (index == -1) ? csl_rdbs : csl_rdbs.copy(0, index); 316 csl_rdbs = (index == -1) ? OUString() : csl_rdbs.copy(index + 1); 317 318 if (! rdb_name.getLength()) 319 continue; 320 321 bool optional = ('?' == rdb_name[ 0 ]); 322 if (optional) 323 rdb_name = rdb_name.copy( 1 ); 324 325 try 326 { 327 Reference<registry::XSimpleRegistry> simpleRegistry( 328 xSimRegFac->createInstance(), UNO_QUERY_THROW ); 329 330 osl::FileBase::getAbsoluteFileURL(baseDir, rdb_name, rdb_name); 331 simpleRegistry->open(rdb_name, sal_True, sal_False); 332 333 if(lastRegistry.is()) 334 { 335 Reference< registry::XSimpleRegistry > nestedRegistry( 336 xNesRegFac->createInstance(), UNO_QUERY ); 337 Reference< lang::XInitialization > nestedRegistry_xInit( 338 nestedRegistry, UNO_QUERY ); 339 340 Sequence<Any> aArgs(2); 341 aArgs[0] <<= lastRegistry; 342 aArgs[1] <<= simpleRegistry; 343 344 nestedRegistry_xInit->initialize(aArgs); 345 346 lastRegistry = nestedRegistry; 347 } 348 else 349 lastRegistry = simpleRegistry; 350 } 351 catch(registry::InvalidRegistryException & invalidRegistryException) 352 { 353 if (! optional) 354 { 355 // if a registry was explicitly given, the exception shall fly 356 if( ! bFallenBack ) 357 throw; 358 } 359 360 (void) invalidRegistryException; 361 #if OSL_DEBUG_LEVEL > 1 362 OString rdb_name_tmp = OUStringToOString( 363 rdb_name, RTL_TEXTENCODING_ASCII_US ); 364 OString message_dbg = OUStringToOString( 365 invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US ); 366 OSL_TRACE( 367 "warning: couldn't open %s cause of %s", 368 rdb_name_tmp.getStr(), message_dbg.getStr() ); 369 #endif 370 } 371 } 372 while(index != -1 && csl_rdbs.getLength()); // are there more rdbs in list? 373 374 return lastRegistry; 375 } 376 377 Reference< XComponentContext > 378 SAL_CALL defaultBootstrap_InitialComponentContext( 379 Bootstrap const & bootstrap ) 380 SAL_THROW( (Exception) ) 381 { 382 primeWeakMap(); 383 384 OUString bootstrapPath; 385 if (!bootstrap.getFrom( 386 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URE_INTERNAL_LIB_DIR")), 387 bootstrapPath)) 388 { 389 bootstrapPath = get_this_libpath(); 390 } 391 392 OUString iniDir; 393 osl_getProcessWorkingDir(&iniDir.pData); 394 395 Reference<lang::XMultiComponentFactory> smgr_XMultiComponentFactory( 396 bootstrapInitialSF(bootstrapPath) ); 397 Reference<lang::XMultiServiceFactory> smgr_XMultiServiceFactory( 398 smgr_XMultiComponentFactory, UNO_QUERY ); 399 400 Reference<registry::XRegistryKey> xEmptyKey; 401 Reference<lang::XSingleServiceFactory> xSimRegFac( 402 loadSharedLibComponentFactory( 403 OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath, 404 OUSTR("com.sun.star.comp.stoc.SimpleRegistry"), 405 smgr_XMultiServiceFactory, 406 xEmptyKey), 407 UNO_QUERY); 408 409 Reference<lang::XSingleServiceFactory> xNesRegFac( 410 loadSharedLibComponentFactory( 411 OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath, 412 OUSTR("com.sun.star.comp.stoc.NestedRegistry"), 413 smgr_XMultiServiceFactory, 414 xEmptyKey), 415 UNO_QUERY); 416 417 sal_Bool bFallenback_types; 418 OUString cls_uno_types = 419 findBoostrapArgument( bootstrap, OUSTR("TYPES"), &bFallenback_types ); 420 421 Reference<registry::XSimpleRegistry> types_xRegistry = 422 nestRegistries( 423 iniDir, xSimRegFac, xNesRegFac, cls_uno_types, 424 OUString(), sal_False, bFallenback_types ); 425 426 // ==== bootstrap from services registry ==== 427 428 sal_Bool bFallenback_services; 429 OUString cls_uno_services = findBoostrapArgument( 430 bootstrap, OUSTR("SERVICES"), &bFallenback_services ); 431 432 sal_Bool fallenBackWriteRegistry; 433 OUString write_rdb = findBoostrapArgument( 434 bootstrap, OUSTR("WRITERDB"), &fallenBackWriteRegistry ); 435 if (fallenBackWriteRegistry) 436 { 437 // no standard write rdb anymore 438 write_rdb = OUString(); 439 } 440 441 Reference<registry::XSimpleRegistry> services_xRegistry = nestRegistries( 442 iniDir, xSimRegFac, xNesRegFac, cls_uno_services, write_rdb, 443 !fallenBackWriteRegistry, bFallenback_services ); 444 445 Reference< XComponentContext > xContext( 446 bootstrapInitialContext( 447 smgr_XMultiComponentFactory, types_xRegistry, services_xRegistry, 448 bootstrapPath, bootstrap ) ); 449 450 // initialize sf 451 Reference< lang::XInitialization > xInit( 452 smgr_XMultiComponentFactory, UNO_QUERY ); 453 OSL_ASSERT( xInit.is() ); 454 Sequence< Any > aSFInit( 1 ); 455 aSFInit[ 0 ] <<= services_xRegistry; 456 xInit->initialize( aSFInit ); 457 458 return xContext; 459 } 460 461 } 462 463 Reference< XComponentContext > 464 SAL_CALL defaultBootstrap_InitialComponentContext( 465 OUString const & iniFile ) 466 SAL_THROW( (Exception) ) 467 { 468 Bootstrap bootstrap( iniFile ); 469 if (bootstrap.getHandle() == 0) 470 throw io::IOException(OUSTR("Cannot open for reading: ") + iniFile, 0); 471 return defaultBootstrap_InitialComponentContext( bootstrap ); 472 } 473 474 Reference< XComponentContext > 475 SAL_CALL defaultBootstrap_InitialComponentContext() 476 SAL_THROW( (Exception) ) 477 { 478 return defaultBootstrap_InitialComponentContext( get_unorc() ); 479 } 480 481 BootstrapException::BootstrapException() 482 { 483 } 484 485 BootstrapException::BootstrapException( const ::rtl::OUString & rMessage ) 486 :m_aMessage( rMessage ) 487 { 488 } 489 490 BootstrapException::BootstrapException( const BootstrapException & e ) 491 { 492 m_aMessage = e.m_aMessage; 493 } 494 495 BootstrapException::~BootstrapException() 496 { 497 } 498 499 BootstrapException & BootstrapException::operator=( const BootstrapException & e ) 500 { 501 m_aMessage = e.m_aMessage; 502 return *this; 503 } 504 505 const ::rtl::OUString & BootstrapException::getMessage() const 506 { 507 return m_aMessage; 508 } 509 510 Reference< XComponentContext > SAL_CALL bootstrap() 511 { 512 Reference< XComponentContext > xRemoteContext; 513 514 try 515 { 516 char const * p1 = cppuhelper_detail_findSofficePath(); 517 if (p1 == NULL) { 518 throw BootstrapException( 519 OUSTR("no soffice installation found!")); 520 } 521 rtl::OUString p2; 522 if (!rtl_convertStringToUString( 523 &p2.pData, p1, strlen(p1), osl_getThreadTextEncoding(), 524 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | 525 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | 526 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) 527 { 528 throw BootstrapException( 529 OUSTR("bad characters in soffice installation path!")); 530 } 531 OUString path; 532 if (osl::FileBase::getFileURLFromSystemPath(p2, path) != 533 osl::FileBase::E_None) 534 { 535 throw BootstrapException( 536 OUSTR("cannot convert soffice installation path to URL!")); 537 } 538 if (path.getLength() > 0 && path[path.getLength() - 1] != '/') { 539 path += OUSTR("/"); 540 } 541 542 OUString uri; 543 if (!Bootstrap::get(OUSTR("URE_BOOTSTRAP"), uri)) { 544 Bootstrap::set( 545 OUSTR("URE_BOOTSTRAP"), 546 Bootstrap::encode(path + OUSTR(SAL_CONFIGFILE("fundamental")))); 547 } 548 549 // create default local component context 550 Reference< XComponentContext > xLocalContext( 551 defaultBootstrap_InitialComponentContext() ); 552 if ( !xLocalContext.is() ) 553 throw BootstrapException( OUSTR( "no local component context!" ) ); 554 555 // create a random pipe name 556 rtlRandomPool hPool = rtl_random_createPool(); 557 if ( hPool == 0 ) 558 throw BootstrapException( OUSTR( "cannot create random pool!" ) ); 559 sal_uInt8 bytes[ 16 ]; 560 if ( rtl_random_getBytes( hPool, bytes, ARLEN( bytes ) ) 561 != rtl_Random_E_None ) 562 throw BootstrapException( OUSTR( "random pool error!" ) ); 563 rtl_random_destroyPool( hPool ); 564 ::rtl::OUStringBuffer buf; 565 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno" ) ); 566 for ( sal_uInt32 i = 0; i < ARLEN( bytes ); ++i ) 567 buf.append( static_cast< sal_Int32 >( bytes[ i ] ) ); 568 OUString sPipeName( buf.makeStringAndClear() ); 569 570 // accept string 571 OSL_ASSERT( buf.getLength() == 0 ); 572 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "-accept=pipe,name=" ) ); 573 buf.append( sPipeName ); 574 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) ); 575 576 // arguments 577 OUString args [] = { 578 OUSTR( "-nologo" ), 579 OUSTR( "-nodefault" ), 580 OUSTR( "-norestore" ), 581 OUSTR( "-nocrashreport" ), 582 OUSTR( "-nolockcheck" ), 583 buf.makeStringAndClear() 584 }; 585 rtl_uString * ar_args [] = { 586 args[ 0 ].pData, 587 args[ 1 ].pData, 588 args[ 2 ].pData, 589 args[ 3 ].pData, 590 args[ 4 ].pData, 591 args[ 5 ].pData 592 }; 593 ::osl::Security sec; 594 595 // start office process 596 oslProcess hProcess = 0; 597 oslProcessError rc = osl_executeProcess( 598 (path + OUSTR("soffice")).pData, ar_args, ARLEN( ar_args ), 599 osl_Process_DETACHED, 600 sec.getHandle(), 601 0, // => current working dir 602 0, 0, // => no env vars 603 &hProcess ); 604 switch ( rc ) 605 { 606 case osl_Process_E_None: 607 osl_freeProcessHandle( hProcess ); 608 break; 609 case osl_Process_E_NotFound: 610 throw BootstrapException( OUSTR( "image not found!" ) ); 611 case osl_Process_E_TimedOut: 612 throw BootstrapException( OUSTR( "timeout occurred!" ) ); 613 case osl_Process_E_NoPermission: 614 throw BootstrapException( OUSTR( "permission denied!" ) ); 615 case osl_Process_E_Unknown: 616 throw BootstrapException( OUSTR( "unknown error!" ) ); 617 case osl_Process_E_InvalidError: 618 default: 619 throw BootstrapException( OUSTR( "unmapped error!" ) ); 620 } 621 622 // create a URL resolver 623 Reference< bridge::XUnoUrlResolver > xUrlResolver( 624 bridge::UnoUrlResolver::create( xLocalContext ) ); 625 626 // connection string 627 OSL_ASSERT( buf.getLength() == 0 ); 628 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) ); 629 buf.append( sPipeName ); 630 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 631 ";urp;StarOffice.ComponentContext" ) ); 632 OUString sConnectString( buf.makeStringAndClear() ); 633 634 // wait until office is started 635 for ( ; ; ) 636 { 637 try 638 { 639 // try to connect to office 640 xRemoteContext.set( 641 xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW ); 642 break; 643 } 644 catch ( connection::NoConnectException & ) 645 { 646 // wait 500 ms, then try to connect again 647 TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ }; 648 ::osl::Thread::wait( tv ); 649 } 650 } 651 } 652 catch ( Exception & e ) 653 { 654 throw BootstrapException( 655 OUSTR( "unexpected UNO exception caught: " ) + e.Message ); 656 } 657 658 return xRemoteContext; 659 } 660 661 OUString bootstrap_expandUri(OUString const & uri) { 662 static char const PREFIX[] = "vnd.sun.star.expand:"; 663 return uri.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(PREFIX)) 664 ? cppuhelper::detail::expandMacros( 665 rtl::Uri::decode( 666 uri.copy(RTL_CONSTASCII_LENGTH(PREFIX)), 667 rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8)) 668 : uri; 669 } 670 671 } // namespace cppu 672