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