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