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 <vector>
28 
29 #include "rtl/string.hxx"
30 #include "rtl/bootstrap.hxx"
31 #include "osl/diagnose.h"
32 #include "osl/file.h"
33 #include "osl/module.h"
34 #include "osl/process.h"
35 #include "cppuhelper/shlib.hxx"
36 #include "cppuhelper/factory.hxx"
37 #include "cppuhelper/component_context.hxx"
38 #include "cppuhelper/servicefactory.hxx"
39 #include "cppuhelper/bootstrap.hxx"
40 
41 #include "com/sun/star/uno/DeploymentException.hpp"
42 #include "com/sun/star/uno/XComponentContext.hpp"
43 #include "com/sun/star/lang/XInitialization.hpp"
44 #include "com/sun/star/lang/XSingleServiceFactory.hpp"
45 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
46 #include "com/sun/star/beans/XPropertySet.hpp"
47 #include "com/sun/star/container/XSet.hpp"
48 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
49 #include "com/sun/star/registry/XSimpleRegistry.hpp"
50 #include "com/sun/star/registry/XImplementationRegistration.hpp"
51 #include "com/sun/star/security/XAccessController.hpp"
52 
53 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
54 
55 
56 using namespace ::rtl;
57 using namespace ::osl;
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::uno;
60 namespace css = com::sun::star;
61 
62 namespace cppu
63 {
64 
65 // private forward decl
66 void addFactories(
67     char const * const * ppNames /* lib, implname, ..., 0 */,
68     OUString const & bootstrapPath,
69     Reference< lang::XMultiComponentFactory > const & xMgr,
70     Reference< registry::XRegistryKey > const & xKey )
71     SAL_THROW( (Exception) );
72 
73 Reference< security::XAccessController >
74 createDefaultAccessController() SAL_THROW( () );
75 
76 Reference< lang::XSingleComponentFactory >
77 create_boostrap_macro_expander_factory() SAL_THROW( () );
78 
79 OUString const & get_this_libpath();
80 
81 
82 static Reference< XInterface > SAL_CALL createInstance(
83     Reference< XInterface > const & xFactory,
84     Reference< XComponentContext > const & xContext =
85     Reference< XComponentContext >() )
86 {
87     Reference< lang::XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
88     if (xFac.is())
89     {
90         return xFac->createInstanceWithContext( xContext );
91     }
92     else
93     {
94         Reference< lang::XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
95         if (xFac2.is())
96         {
97             OSL_ENSURE( !xContext.is(), "### ignoring context!" );
98             return xFac2->createInstance();
99         }
100     }
101     throw RuntimeException(
102         OUSTR("no factory object given!"),
103         Reference< XInterface >() );
104 }
105 
106 Reference< registry::XSimpleRegistry > SAL_CALL createSimpleRegistry(
107     OUString const & rBootstrapPath )
108     SAL_THROW( () )
109 {
110     try
111     {
112         return Reference< registry::XSimpleRegistry >(
113             createInstance(
114                 loadSharedLibComponentFactory(
115                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
116                     0 == rBootstrapPath.getLength()
117                     ? get_this_libpath() : rBootstrapPath,
118                     OUSTR("com.sun.star.comp.stoc.SimpleRegistry"),
119                     Reference< lang::XMultiServiceFactory >(),
120                     Reference< registry::XRegistryKey >() ) ),
121             UNO_QUERY );
122     }
123     catch (Exception & exc)
124     {
125 #if OSL_DEBUG_LEVEL > 0
126         OString cstr_msg(
127             OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
128         OSL_ENSURE( !"### exception occurred:", cstr_msg.getStr() );
129 #else
130         (void) exc; // avoid warning about unused variable
131 #endif
132     }
133 
134     return Reference< registry::XSimpleRegistry >();
135 }
136 
137 Reference< registry::XSimpleRegistry > SAL_CALL createNestedRegistry(
138     OUString const & rBootstrapPath )
139     SAL_THROW( () )
140 {
141     try
142     {
143         return Reference< registry::XSimpleRegistry >(
144             createInstance(
145                 loadSharedLibComponentFactory(
146                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
147                     0 == rBootstrapPath.getLength()
148                     ? get_this_libpath() : rBootstrapPath,
149                     OUSTR("com.sun.star.comp.stoc.NestedRegistry"),
150                     Reference< lang::XMultiServiceFactory >(),
151                     Reference< registry::XRegistryKey >() ) ),
152             UNO_QUERY );
153     }
154     catch (Exception & exc)
155     {
156 #if OSL_DEBUG_LEVEL > 0
157         OString cstr_msg(
158             OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
159         OSL_ENSURE( !"### exception occurred:", cstr_msg.getStr() );
160 #else
161         (void) exc; // avoid warning about unused variable
162 #endif
163     }
164 
165     return Reference< registry::XSimpleRegistry >();
166 }
167 
168 
169 /** bootstrap variables:
170 
171     UNO_AC=<mode> [mandatory]
172       -- mode := { on, off, dynamic-only, single-user, single-default-user }
173     UNO_AC_SERVICE=<service_name> [optional]
174       -- override ac singleton service name
175     UNO_AC_SINGLEUSER=<user-id|nothing> [optional]
176       -- run with this user id or with default user policy (<nothing>)
177          set UNO_AC=single-[default-]user
178     UNO_AC_USERCACHE_SIZE=<cache_size>
179       -- number of user permission sets to be cached
180 
181     UNO_AC_POLICYSERVICE=<service_name> [optional]
182       -- override policy singleton service name
183     UNO_AC_POLICYFILE=<file_url> [optional]
184       -- read policy out of simple text file
185 */
186 static void add_access_control_entries(
187     ::std::vector< ContextEntry_Init > * values,
188     Bootstrap const & bootstrap )
189     SAL_THROW( (Exception) )
190 {
191     ContextEntry_Init entry;
192     ::std::vector< ContextEntry_Init > & context_values = *values;
193 
194     OUString ac_policy;
195     if (bootstrap.getFrom( OUSTR("UNO_AC_POLICYSERVICE"), ac_policy ))
196     {
197         // overridden service name
198         // - policy singleton
199         entry.bLateInitService = true;
200         entry.name = OUSTR("/singletons/com.sun.star.security.thePolicy");
201         entry.value <<= ac_policy;
202         context_values.push_back( entry );
203     }
204     else if (bootstrap.getFrom( OUSTR("UNO_AC_POLICYFILE"), ac_policy ))
205     {
206         // check for file policy
207         // - file policy prop: file-name
208         if (0 != ac_policy.compareToAscii(
209                 RTL_CONSTASCII_STRINGPARAM("file:///") ))
210         {
211             // no file url
212             OUString baseDir;
213             if ( ::osl_getProcessWorkingDir( &baseDir.pData )
214                  != osl_Process_E_None )
215             {
216                 OSL_ASSERT( false );
217             }
218             OUString fileURL;
219             if ( ::osl_getAbsoluteFileURL(
220                      baseDir.pData, ac_policy.pData, &fileURL.pData )
221                  != osl_File_E_None )
222             {
223                 OSL_ASSERT( false );
224             }
225             ac_policy = fileURL;
226         }
227 
228         entry.bLateInitService = false;
229         entry.name =
230             OUSTR("/implementations/com.sun.star.security.comp.stoc.FilePolicy/"
231                   "file-name");
232         entry.value <<= ac_policy;
233         context_values.push_back( entry );
234         // - policy singleton
235         entry.bLateInitService = true;
236         entry.name = OUSTR("/singletons/com.sun.star.security.thePolicy");
237         entry.value <<= OUSTR("com.sun.star.security.comp.stoc.FilePolicy");
238         context_values.push_back( entry );
239     } // else policy singleton comes from storage
240 
241     OUString ac_mode;
242     if (! bootstrap.getFrom( OUSTR("UNO_AC"), ac_mode ))
243     {
244         ac_mode = OUSTR("off"); // default
245     }
246     OUString ac_user;
247     if (bootstrap.getFrom( OUSTR("UNO_AC_SINGLEUSER"), ac_user ))
248     {
249         // ac in single-user mode
250         if (ac_user.getLength())
251         {
252             // - ac prop: single-user-id
253             entry.bLateInitService = false;
254             entry.name =
255                 OUSTR("/services/com.sun.star.security.AccessController/"
256                       "single-user-id");
257             entry.value <<= ac_user;
258             context_values.push_back( entry );
259             if (! ac_mode.equalsAsciiL(
260                     RTL_CONSTASCII_STRINGPARAM("single-user") ))
261             {
262                 throw SecurityException(
263                     OUSTR("set UNO_AC=single-user "
264                           "if you set UNO_AC_SINGLEUSER=<user-id>!"),
265                     Reference< XInterface >() );
266             }
267         }
268         else
269         {
270             if (! ac_mode.equalsAsciiL(
271                     RTL_CONSTASCII_STRINGPARAM("single-default-user") ))
272             {
273                 throw SecurityException(
274                     OUSTR("set UNO_AC=single-default-user "
275                           "if you set UNO_AC_SINGLEUSER=<nothing>!"),
276                     Reference< XInterface >() );
277             }
278         }
279     }
280 
281     OUString ac_service;
282     if (! bootstrap.getFrom( OUSTR("UNO_AC_SERVICE"), ac_service ))
283     {
284         // override service name
285         ac_service = OUSTR("com.sun.star.security.AccessController"); // default
286 //          ac = OUSTR("com.sun.star.security.comp.stoc.AccessController");
287     }
288 
289     // - ac prop: user-cache-size
290     OUString ac_cache;
291     if (bootstrap.getFrom( OUSTR("UNO_AC_USERCACHE_SIZE"), ac_cache ))
292     {
293         // ac cache size
294         sal_Int32 n = ac_cache.toInt32();
295         if (0 < n)
296         {
297             entry.bLateInitService = false;
298             entry.name =
299                 OUSTR("/services/com.sun.star.security.AccessController/"
300                       "user-cache-size");
301             entry.value <<= n;
302             context_values.push_back( entry );
303         }
304     }
305 
306     // - ac prop: mode
307     // { "off", "on", "dynamic-only", "single-user", "single-default-user" }
308     entry.bLateInitService = false;
309     entry.name = OUSTR("/services/com.sun.star.security.AccessController/mode");
310     entry.value <<= ac_mode;
311     context_values.push_back( entry );
312     // - ac singleton
313     entry.bLateInitService = true;
314     entry.name = OUSTR("/singletons/com.sun.star.security.theAccessController");
315     entry.value <<= ac_service;
316     context_values.push_back( entry );
317 }
318 
319 Reference< lang::XMultiComponentFactory > bootstrapInitialSF(
320     OUString const & rBootstrapPath )
321     SAL_THROW( (Exception) )
322 {
323     OUString const & bootstrap_path =
324         0 == rBootstrapPath.getLength() ? get_this_libpath() : rBootstrapPath;
325 
326     Reference< lang::XMultiComponentFactory > xMgr(
327         createInstance(
328             loadSharedLibComponentFactory(
329                 OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrap_path,
330                 OUSTR("com.sun.star.comp.stoc.ORegistryServiceManager"),
331                 Reference< lang::XMultiServiceFactory >(),
332                 Reference< registry::XRegistryKey >() ) ),
333         UNO_QUERY );
334 
335     // add initial bootstrap services
336     static char const * ar[] = {
337         "bootstrap.uno" SAL_DLLEXTENSION,
338         "com.sun.star.comp.stoc.OServiceManagerWrapper",
339         "bootstrap.uno" SAL_DLLEXTENSION,
340         "com.sun.star.comp.stoc.DLLComponentLoader",
341         "bootstrap.uno" SAL_DLLEXTENSION,
342         "com.sun.star.comp.stoc.SimpleRegistry",
343         "bootstrap.uno" SAL_DLLEXTENSION,
344         "com.sun.star.comp.stoc.NestedRegistry",
345         "bootstrap.uno" SAL_DLLEXTENSION,
346         "com.sun.star.comp.stoc.TypeDescriptionManager",
347         "bootstrap.uno" SAL_DLLEXTENSION,
348         "com.sun.star.comp.stoc.ImplementationRegistration",
349         "bootstrap.uno" SAL_DLLEXTENSION,
350         "com.sun.star.security.comp.stoc.AccessController",
351         "bootstrap.uno" SAL_DLLEXTENSION,
352         "com.sun.star.security.comp.stoc.FilePolicy",
353         0
354     };
355     addFactories(
356         ar, bootstrap_path,
357         xMgr, Reference< registry::XRegistryKey >() );
358 
359     return xMgr;
360 }
361 
362 // returns context with UNinitialized smgr
363 Reference< XComponentContext > bootstrapInitialContext(
364     Reference< lang::XMultiComponentFactory > const & xSF,
365     Reference< registry::XSimpleRegistry > const & types_xRegistry,
366     Reference< registry::XSimpleRegistry > const & services_xRegistry,
367     OUString const & rBootstrapPath, Bootstrap const & bootstrap )
368     SAL_THROW( (Exception) )
369 {
370     Reference< lang::XInitialization > xSFInit( xSF, UNO_QUERY );
371     if (! xSFInit.is())
372     {
373         throw RuntimeException(
374             OUSTR("servicemanager does not support XInitialization!"),
375             Reference< XInterface >() );
376     }
377 
378     // basic context values
379     ContextEntry_Init entry;
380     ::std::vector< ContextEntry_Init > context_values;
381     context_values.reserve( 14 );
382 
383     // macro expander singleton for loader
384     entry.bLateInitService = true;
385     entry.name = OUSTR("/singletons/com.sun.star.util.theMacroExpander");
386     entry.value <<= create_boostrap_macro_expander_factory();
387     context_values.push_back( entry );
388 
389     // tdmgr singleton
390     entry.bLateInitService = true;
391     entry.name =
392         OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
393     entry.value <<= OUSTR("com.sun.star.comp.stoc.TypeDescriptionManager");
394     context_values.push_back( entry );
395 
396     // read out singleton infos from registry
397     if (services_xRegistry.is())
398     {
399         Reference< registry::XRegistryKey > xKey(
400             services_xRegistry->getRootKey() );
401         if (xKey.is())
402         {
403             xKey = xKey->openKey( OUSTR("/SINGLETONS") );
404             if (xKey.is())
405             {
406                 entry.bLateInitService = true;
407 
408                 Sequence< Reference< registry::XRegistryKey > > keys(
409                     xKey->openKeys() );
410                 Reference< registry::XRegistryKey > const * pKeys =
411                     keys.getConstArray();
412                 for ( sal_Int32 nPos = keys.getLength(); nPos--; )
413                 {
414                     css::uno::Sequence< rtl::OUString > impls(
415                         css::uno::Reference< css::registry::XRegistryKey >(
416                             pKeys[nPos]->openKey(
417                                 rtl::OUString(
418                                     RTL_CONSTASCII_USTRINGPARAM(
419                                         "REGISTERED_BY"))),
420                             css::uno::UNO_SET_THROW)->getAsciiListValue());
421                     switch (impls.getLength()) {
422                     case 0:
423                         throw css::uno::DeploymentException(
424                             (pKeys[nPos]->getKeyName() +
425                              rtl::OUString(
426                                  RTL_CONSTASCII_USTRINGPARAM(
427                                      "/REGISTERED_BY is empty"))),
428                             css::uno::Reference< css::uno::XInterface >());
429                     case 1:
430                         break;
431                     default:
432                         OSL_TRACE(
433                             ("arbitrarily chosing \"%s\" among multiple"
434                              " implementations for \"%s\""),
435                             rtl::OUStringToOString(
436                                 impls[0], RTL_TEXTENCODING_UTF8).getStr(),
437                             rtl::OUStringToOString(
438                                 pKeys[nPos]->getKeyName(),
439                                 RTL_TEXTENCODING_UTF8).getStr());
440                         break;
441                     }
442                     context_values.push_back(
443                         ContextEntry_Init(
444                             (rtl::OUString(
445                                 RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
446                              pKeys[nPos]->getKeyName().copy(
447                                  RTL_CONSTASCII_LENGTH("/SINGLETONS/"))),
448                             css::uno::makeAny(impls[0]),
449                             true));
450                 }
451             }
452         }
453     }
454 
455     // ac, policy:
456     add_access_control_entries( &context_values, bootstrap );
457 
458     // smgr singleton
459     entry.bLateInitService = false;
460     entry.name = OUSTR("/singletons/com.sun.star.lang.theServiceManager");
461     entry.value <<= xSF;
462     context_values.push_back( entry );
463 
464     Reference< XComponentContext > xContext(
465         createComponentContext(
466             &context_values[ 0 ], context_values.size(),
467             Reference< XComponentContext >() ) );
468     // set default context
469     Reference< beans::XPropertySet > xProps( xSF, UNO_QUERY );
470     OSL_ASSERT( xProps.is() );
471     if (xProps.is())
472     {
473         xProps->setPropertyValue(
474             OUSTR("DefaultContext"), makeAny( xContext ) );
475     }
476 
477     Reference< container::XHierarchicalNameAccess > xTDMgr;
478 
479     // get tdmgr singleton
480     if (xContext->getValueByName(
481             OUSTR("/singletons/"
482                   "com.sun.star.reflection.theTypeDescriptionManager") )
483         >>= xTDMgr)
484     {
485         if (types_xRegistry.is()) // insert rdb provider?
486         {
487             // add registry td provider factory to smgr and instance to tdmgr
488             Reference< lang::XSingleComponentFactory > xFac(
489                 loadSharedLibComponentFactory(
490                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
491                     0 == rBootstrapPath.getLength()
492                     ? get_this_libpath() : rBootstrapPath,
493                 OUSTR("com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"),
494                 Reference< lang::XMultiServiceFactory >( xSF, UNO_QUERY ),
495                 Reference< registry::XRegistryKey >() ), UNO_QUERY );
496             OSL_ASSERT( xFac.is() );
497 
498             // smgr
499             Reference< container::XSet > xSet( xSF, UNO_QUERY );
500             xSet->insert( makeAny( xFac ) );
501             OSL_ENSURE(
502                 xSet->has( makeAny( xFac ) ),
503                 "### failed registering registry td provider at smgr!" );
504             // tdmgr
505             xSet.set( xTDMgr, UNO_QUERY );
506             OSL_ASSERT( xSet.is() );
507             Any types_RDB( makeAny( types_xRegistry ) );
508             Any rdbtdp( makeAny( xFac->createInstanceWithArgumentsAndContext(
509                 Sequence< Any >( &types_RDB, 1 ), xContext ) ) );
510             xSet->insert( rdbtdp );
511             OSL_ENSURE(
512                 xSet->has( rdbtdp ),
513                 "### failed inserting registry td provider to tdmgr!" );
514         }
515         // install callback
516         installTypeDescriptionManager( xTDMgr );
517     }
518 
519     return xContext;
520 }
521 
522 static Reference< lang::XMultiComponentFactory > createImplServiceFactory(
523     const OUString & rWriteRegistry,
524     const OUString & rReadRegistry,
525     sal_Bool bReadOnly,
526     const OUString & rBootstrapPath )
527     SAL_THROW( (Exception) )
528 {
529     Reference< lang::XMultiComponentFactory > xSF(
530         bootstrapInitialSF( rBootstrapPath ) );
531 
532     Reference< registry::XSimpleRegistry > xRegistry;
533 
534     // open a registry
535     sal_Bool bRegistryShouldBeValid = sal_False;
536     if (rWriteRegistry.getLength() && !rReadRegistry.getLength())
537     {
538         bRegistryShouldBeValid = sal_True;
539         xRegistry.set( createSimpleRegistry( rBootstrapPath ) );
540         if (xRegistry.is())
541         {
542             if (bReadOnly)
543             {
544                 xRegistry->open( rWriteRegistry, sal_True, sal_False );
545             }
546             else
547             {
548                 xRegistry->open( rWriteRegistry, sal_False, sal_True );
549             }
550         }
551     }
552     else if (rWriteRegistry.getLength() && rReadRegistry.getLength())
553     {
554         // default registry
555         bRegistryShouldBeValid = sal_True;
556         xRegistry.set( createNestedRegistry( rBootstrapPath ) );
557 
558         Reference< registry::XSimpleRegistry > xWriteReg(
559             createSimpleRegistry( rBootstrapPath ) );
560         if (xWriteReg.is())
561         {
562             if (bReadOnly)
563             {
564                 try
565                 {
566                     xWriteReg->open( rWriteRegistry, sal_True, sal_False );
567                 }
568                 catch (registry::InvalidRegistryException &)
569                 {
570                 }
571 
572                 if (! xWriteReg->isValid())
573                 {
574                     throw RuntimeException(
575                         OUSTR("specified first registry "
576                               "could not be open readonly!"),
577                         Reference< XInterface >() );
578                 }
579             }
580             else
581             {
582                 xWriteReg->open( rWriteRegistry, sal_False, sal_True );
583             }
584         }
585 
586         Reference< registry::XSimpleRegistry > xReadReg(
587             createSimpleRegistry( rBootstrapPath ) );
588         if (xReadReg.is())
589         {
590             xReadReg->open( rReadRegistry, sal_True, sal_False );
591         }
592 
593         Reference< lang::XInitialization > xInit( xRegistry, UNO_QUERY );
594         Sequence< Any > aInitSeq( 2 );
595         aInitSeq[ 0 ] <<= xWriteReg;
596         aInitSeq[ 1 ] <<= xReadReg;
597         xInit->initialize( aInitSeq );
598     }
599 
600     if (bRegistryShouldBeValid && (!xRegistry.is() || !xRegistry->isValid()))
601     {
602         throw RuntimeException(
603             OUSTR("specified registry could not be initialized"),
604             Reference< XInterface >() );
605     }
606 
607     Bootstrap bootstrap;
608     Reference< XComponentContext > xContext(
609         bootstrapInitialContext(
610             xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
611 
612     // initialize sf
613     Reference< lang::XInitialization > xInit( xSF, UNO_QUERY );
614     OSL_ASSERT( xInit.is() );
615     Sequence< Any > aSFInit( 1 );
616     aSFInit[ 0 ] <<= xRegistry;
617     xInit->initialize( aSFInit );
618 
619     return xSF;
620 }
621 
622 Reference< lang::XMultiServiceFactory > SAL_CALL createRegistryServiceFactory(
623     const OUString & rWriteRegistry,
624     const OUString & rReadRegistry,
625     sal_Bool bReadOnly,
626     const OUString & rBootstrapPath )
627     SAL_THROW( (Exception) )
628 {
629     return Reference< lang::XMultiServiceFactory >( createImplServiceFactory(
630         rWriteRegistry, rReadRegistry, bReadOnly, rBootstrapPath ), UNO_QUERY );
631 }
632 
633 Reference< XComponentContext > SAL_CALL bootstrap_InitialComponentContext(
634     Reference< registry::XSimpleRegistry > const & xRegistry,
635     OUString const & rBootstrapPath )
636     SAL_THROW( (Exception) )
637 {
638     Bootstrap bootstrap;
639 
640     Reference< lang::XMultiComponentFactory > xSF(
641         bootstrapInitialSF( rBootstrapPath ) );
642     Reference< XComponentContext > xContext(
643         bootstrapInitialContext(
644             xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
645 
646     // initialize sf
647     Reference< lang::XInitialization > xInit( xSF, UNO_QUERY );
648     OSL_ASSERT( xInit.is() );
649     Sequence< Any > aSFInit( 2 );
650     aSFInit[ 0 ] <<= xRegistry;
651     aSFInit[ 1 ] <<= xContext; // default context
652     xInit->initialize( aSFInit );
653 
654     return xContext;
655 }
656 
657 }
658