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/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
get_this_libpath()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
get_unorc()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
addFactories(char const * const * ppNames,OUString const & bootstrapPath,Reference<lang::XMultiComponentFactory> const & xMgr,Reference<registry::XRegistryKey> const & xKey)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 {
127 Reference< container::XSet > xSet( xMgr, UNO_QUERY );
128 OSL_ASSERT( xSet.is() );
129 Reference< lang::XMultiServiceFactory > xSF( xMgr, UNO_QUERY );
130
131 while (*ppNames)
132 {
133 OUString lib( OUString::createFromAscii( *ppNames++ ) );
134 OUString implName( OUString::createFromAscii( *ppNames++ ) );
135
136 Any aFac( makeAny( loadSharedLibComponentFactory(
137 lib, bootstrapPath, implName, xSF, xKey ) ) );
138 xSet->insert( aFac );
139 #if OSL_DEBUG_LEVEL > 1
140 if (xSet->has( aFac ))
141 {
142 Reference< lang::XServiceInfo > xInfo;
143 if (aFac >>= xInfo)
144 {
145 ::fprintf(
146 stderr, "> implementation %s supports: ", ppNames[ -1 ] );
147 Sequence< OUString > supported(
148 xInfo->getSupportedServiceNames() );
149 for ( sal_Int32 nPos = supported.getLength(); nPos--; )
150 {
151 OString str( OUStringToOString(
152 supported[ nPos ], RTL_TEXTENCODING_ASCII_US ) );
153 ::fprintf( stderr, nPos ? "%s, " : "%s\n", str.getStr() );
154 }
155 }
156 else
157 {
158 ::fprintf(
159 stderr,
160 "> implementation %s provides NO lang::XServiceInfo!!!\n",
161 ppNames[ -1 ] );
162 }
163 }
164 #endif
165 #if OSL_DEBUG_LEVEL > 0
166 if (! xSet->has( aFac ))
167 {
168 OStringBuffer buf( 64 );
169 buf.append( "### failed inserting shared lib \"" );
170 buf.append( ppNames[ -2 ] );
171 buf.append( "\"!!!" );
172 OString str( buf.makeStringAndClear() );
173 OSL_ENSURE( 0, str.getStr() );
174 }
175 #endif
176 }
177 }
178
179 // private forward decl
180 Reference< lang::XMultiComponentFactory > bootstrapInitialSF(
181 OUString const & rBootstrapPath );
182
183 Reference< XComponentContext > bootstrapInitialContext(
184 Reference< lang::XMultiComponentFactory > const & xSF,
185 Reference< registry::XSimpleRegistry > const & types_xRegistry,
186 Reference< registry::XSimpleRegistry > const & services_xRegistry,
187 OUString const & rBootstrapPath, Bootstrap const & bootstrap );
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 >
createPropertyValue(OUString const & name,T const & value)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
findBoostrapArgument(const Bootstrap & bootstrap,const OUString & arg_name,sal_Bool * pFallenBack)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
nestRegistries(const OUString baseDir,const Reference<lang::XSingleServiceFactory> & xSimRegFac,const Reference<lang::XSingleServiceFactory> & xNesRegFac,OUString csl_rdbs,const OUString & write_rdb,sal_Bool forceWrite_rdb,sal_Bool bFallenBack)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 {
279 sal_Int32 index;
280 Reference< registry::XSimpleRegistry > lastRegistry;
281
282 if(write_rdb.getLength()) // is there a write registry given?
283 {
284 lastRegistry.set(xSimRegFac->createInstance(), UNO_QUERY);
285
286 try
287 {
288 lastRegistry->open(write_rdb, sal_False, forceWrite_rdb);
289 }
290 catch (registry::InvalidRegistryException & invalidRegistryException)
291 {
292 (void) invalidRegistryException;
293 #if OSL_DEBUG_LEVEL > 1
294 OString rdb_name_tmp = OUStringToOString(
295 write_rdb, RTL_TEXTENCODING_ASCII_US);
296 OString message_dbg = OUStringToOString(
297 invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US);
298 OSL_TRACE(
299 "warning: couldn't open %s cause of %s",
300 rdb_name_tmp.getStr(), message_dbg.getStr() );
301 #endif
302 }
303
304 if(!lastRegistry->isValid())
305 lastRegistry.clear();
306 }
307
308 do
309 {
310 index = csl_rdbs.indexOf((sal_Unicode)' ');
311 OUString rdb_name = (index == -1) ? csl_rdbs : csl_rdbs.copy(0, index);
312 csl_rdbs = (index == -1) ? OUString() : csl_rdbs.copy(index + 1);
313
314 if (! rdb_name.getLength())
315 continue;
316
317 bool optional = ('?' == rdb_name[ 0 ]);
318 if (optional)
319 rdb_name = rdb_name.copy( 1 );
320
321 try
322 {
323 Reference<registry::XSimpleRegistry> simpleRegistry(
324 xSimRegFac->createInstance(), UNO_QUERY_THROW );
325
326 osl::FileBase::getAbsoluteFileURL(baseDir, rdb_name, rdb_name);
327 simpleRegistry->open(rdb_name, sal_True, sal_False);
328
329 if(lastRegistry.is())
330 {
331 Reference< registry::XSimpleRegistry > nestedRegistry(
332 xNesRegFac->createInstance(), UNO_QUERY );
333 Reference< lang::XInitialization > nestedRegistry_xInit(
334 nestedRegistry, UNO_QUERY );
335
336 Sequence<Any> aArgs(2);
337 aArgs[0] <<= lastRegistry;
338 aArgs[1] <<= simpleRegistry;
339
340 nestedRegistry_xInit->initialize(aArgs);
341
342 lastRegistry = nestedRegistry;
343 }
344 else
345 lastRegistry = simpleRegistry;
346 }
347 catch(registry::InvalidRegistryException & invalidRegistryException)
348 {
349 if (! optional)
350 {
351 // if a registry was explicitly given, the exception shall fly
352 if( ! bFallenBack )
353 throw;
354 }
355
356 (void) invalidRegistryException;
357 #if OSL_DEBUG_LEVEL > 1
358 OString rdb_name_tmp = OUStringToOString(
359 rdb_name, RTL_TEXTENCODING_ASCII_US );
360 OString message_dbg = OUStringToOString(
361 invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US );
362 OSL_TRACE(
363 "warning: couldn't open %s cause of %s",
364 rdb_name_tmp.getStr(), message_dbg.getStr() );
365 #endif
366 }
367 }
368 while(index != -1 && csl_rdbs.getLength()); // are there more rdbs in list?
369
370 return lastRegistry;
371 }
372
373 Reference< XComponentContext >
defaultBootstrap_InitialComponentContext(Bootstrap const & bootstrap)374 SAL_CALL defaultBootstrap_InitialComponentContext(
375 Bootstrap const & bootstrap )
376 {
377 primeWeakMap();
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 >
defaultBootstrap_InitialComponentContext(OUString const & iniFile)459 SAL_CALL defaultBootstrap_InitialComponentContext(
460 OUString const & iniFile )
461 {
462 Bootstrap bootstrap( iniFile );
463 if (bootstrap.getHandle() == 0)
464 throw io::IOException(OUSTR("Cannot open for reading: ") + iniFile, 0);
465 return defaultBootstrap_InitialComponentContext( bootstrap );
466 }
467
468 Reference< XComponentContext >
defaultBootstrap_InitialComponentContext()469 SAL_CALL defaultBootstrap_InitialComponentContext()
470 {
471 return defaultBootstrap_InitialComponentContext( get_unorc() );
472 }
473
BootstrapException()474 BootstrapException::BootstrapException()
475 {
476 }
477
BootstrapException(const::rtl::OUString & rMessage)478 BootstrapException::BootstrapException( const ::rtl::OUString & rMessage )
479 :m_aMessage( rMessage )
480 {
481 }
482
BootstrapException(const BootstrapException & e)483 BootstrapException::BootstrapException( const BootstrapException & e )
484 {
485 m_aMessage = e.m_aMessage;
486 }
487
~BootstrapException()488 BootstrapException::~BootstrapException()
489 {
490 }
491
operator =(const BootstrapException & e)492 BootstrapException & BootstrapException::operator=( const BootstrapException & e )
493 {
494 m_aMessage = e.m_aMessage;
495 return *this;
496 }
497
getMessage() const498 const ::rtl::OUString & BootstrapException::getMessage() const
499 {
500 return m_aMessage;
501 }
502
bootstrap()503 Reference< XComponentContext > SAL_CALL bootstrap()
504 {
505 Reference< XComponentContext > xRemoteContext;
506
507 try
508 {
509 char const * p1 = cppuhelper_detail_findSofficePath();
510 if (p1 == NULL) {
511 throw BootstrapException(
512 OUSTR("no soffice installation found!"));
513 }
514 rtl::OUString p2;
515 if (!rtl_convertStringToUString(
516 &p2.pData, p1, strlen(p1), osl_getThreadTextEncoding(),
517 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
518 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
519 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
520 {
521 throw BootstrapException(
522 OUSTR("bad characters in soffice installation path!"));
523 }
524 OUString path;
525 if (osl::FileBase::getFileURLFromSystemPath(p2, path) !=
526 osl::FileBase::E_None)
527 {
528 throw BootstrapException(
529 OUSTR("cannot convert soffice installation path to URL!"));
530 }
531 if (path.getLength() > 0 && path[path.getLength() - 1] != '/') {
532 path += OUSTR("/");
533 }
534
535 OUString uri;
536 if (!Bootstrap::get(OUSTR("URE_BOOTSTRAP"), uri)) {
537 Bootstrap::set(
538 OUSTR("URE_BOOTSTRAP"),
539 Bootstrap::encode(path + OUSTR(SAL_CONFIGFILE("fundamental"))));
540 }
541
542 // create default local component context
543 Reference< XComponentContext > xLocalContext(
544 defaultBootstrap_InitialComponentContext() );
545 if ( !xLocalContext.is() )
546 throw BootstrapException( OUSTR( "no local component context!" ) );
547
548 // create a random pipe name
549 rtlRandomPool hPool = rtl_random_createPool();
550 if ( hPool == 0 )
551 throw BootstrapException( OUSTR( "cannot create random pool!" ) );
552 sal_uInt8 bytes[ 16 ];
553 if ( rtl_random_getBytes( hPool, bytes, ARLEN( bytes ) )
554 != rtl_Random_E_None )
555 throw BootstrapException( OUSTR( "random pool error!" ) );
556 rtl_random_destroyPool( hPool );
557 ::rtl::OUStringBuffer buf;
558 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno" ) );
559 for ( sal_uInt32 i = 0; i < ARLEN( bytes ); ++i )
560 buf.append( static_cast< sal_Int32 >( bytes[ i ] ) );
561 OUString sPipeName( buf.makeStringAndClear() );
562
563 // accept string
564 OSL_ASSERT( buf.getLength() == 0 );
565 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "-accept=pipe,name=" ) );
566 buf.append( sPipeName );
567 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) );
568
569 // arguments
570 OUString args [] = {
571 OUSTR( "-nologo" ),
572 OUSTR( "-nodefault" ),
573 OUSTR( "-norestore" ),
574 OUSTR( "-nocrashreport" ),
575 OUSTR( "-nolockcheck" ),
576 buf.makeStringAndClear()
577 };
578 rtl_uString * ar_args [] = {
579 args[ 0 ].pData,
580 args[ 1 ].pData,
581 args[ 2 ].pData,
582 args[ 3 ].pData,
583 args[ 4 ].pData,
584 args[ 5 ].pData
585 };
586 ::osl::Security sec;
587
588 // start office process
589 oslProcess hProcess = 0;
590 oslProcessError rc = osl_executeProcess(
591 (path + OUSTR("soffice")).pData, ar_args, ARLEN( ar_args ),
592 osl_Process_DETACHED,
593 sec.getHandle(),
594 0, // => current working dir
595 0, 0, // => no env vars
596 &hProcess );
597 switch ( rc )
598 {
599 case osl_Process_E_None:
600 osl_freeProcessHandle( hProcess );
601 break;
602 case osl_Process_E_NotFound:
603 throw BootstrapException( OUSTR( "image not found!" ) );
604 case osl_Process_E_TimedOut:
605 throw BootstrapException( OUSTR( "timeout occurred!" ) );
606 case osl_Process_E_NoPermission:
607 throw BootstrapException( OUSTR( "permission denied!" ) );
608 case osl_Process_E_Unknown:
609 throw BootstrapException( OUSTR( "unknown error!" ) );
610 case osl_Process_E_InvalidError:
611 default:
612 throw BootstrapException( OUSTR( "unmapped error!" ) );
613 }
614
615 // create a URL resolver
616 Reference< bridge::XUnoUrlResolver > xUrlResolver(
617 bridge::UnoUrlResolver::create( xLocalContext ) );
618
619 // connection string
620 OSL_ASSERT( buf.getLength() == 0 );
621 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) );
622 buf.append( sPipeName );
623 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
624 ";urp;StarOffice.ComponentContext" ) );
625 OUString sConnectString( buf.makeStringAndClear() );
626
627 // wait until office is started
628 for ( ; ; )
629 {
630 try
631 {
632 // try to connect to office
633 xRemoteContext.set(
634 xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW );
635 break;
636 }
637 catch ( connection::NoConnectException & )
638 {
639 // wait 500 ms, then try to connect again
640 TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ };
641 ::osl::Thread::wait( tv );
642 }
643 }
644 }
645 catch ( Exception & e )
646 {
647 throw BootstrapException(
648 OUSTR( "unexpected UNO exception caught: " ) + e.Message );
649 }
650
651 return xRemoteContext;
652 }
653
bootstrap_expandUri(OUString const & uri)654 OUString bootstrap_expandUri(OUString const & uri) {
655 static char const PREFIX[] = "vnd.sun.star.expand:";
656 return uri.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(PREFIX))
657 ? cppuhelper::detail::expandMacros(
658 rtl::Uri::decode(
659 uri.copy(RTL_CONSTASCII_LENGTH(PREFIX)),
660 rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8))
661 : uri;
662 }
663
664 } // namespace cppu
665