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 SAL_DLLPUBLIC_EXPORT
320 Reference< lang::XMultiComponentFactory > bootstrapInitialSF(
321     OUString const & rBootstrapPath )
322     SAL_THROW( (Exception) )
323 {
324     OUString const & bootstrap_path =
325         0 == rBootstrapPath.getLength() ? get_this_libpath() : rBootstrapPath;
326 
327     Reference< lang::XMultiComponentFactory > xMgr(
328         createInstance(
329             loadSharedLibComponentFactory(
330                 OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrap_path,
331                 OUSTR("com.sun.star.comp.stoc.ORegistryServiceManager"),
332                 Reference< lang::XMultiServiceFactory >(),
333                 Reference< registry::XRegistryKey >() ) ),
334         UNO_QUERY );
335 
336     // add initial bootstrap services
337     static char const * ar[] = {
338         "bootstrap.uno" SAL_DLLEXTENSION,
339         "com.sun.star.comp.stoc.OServiceManagerWrapper",
340         "bootstrap.uno" SAL_DLLEXTENSION,
341         "com.sun.star.comp.stoc.DLLComponentLoader",
342         "bootstrap.uno" SAL_DLLEXTENSION,
343         "com.sun.star.comp.stoc.SimpleRegistry",
344         "bootstrap.uno" SAL_DLLEXTENSION,
345         "com.sun.star.comp.stoc.NestedRegistry",
346         "bootstrap.uno" SAL_DLLEXTENSION,
347         "com.sun.star.comp.stoc.TypeDescriptionManager",
348         "bootstrap.uno" SAL_DLLEXTENSION,
349         "com.sun.star.comp.stoc.ImplementationRegistration",
350         "bootstrap.uno" SAL_DLLEXTENSION,
351         "com.sun.star.security.comp.stoc.AccessController",
352         "bootstrap.uno" SAL_DLLEXTENSION,
353         "com.sun.star.security.comp.stoc.FilePolicy",
354         0
355     };
356     addFactories(
357         ar, bootstrap_path,
358         xMgr, Reference< registry::XRegistryKey >() );
359 
360     return xMgr;
361 }
362 
363 // returns context with UNinitialized smgr
364 Reference< XComponentContext > bootstrapInitialContext(
365     Reference< lang::XMultiComponentFactory > const & xSF,
366     Reference< registry::XSimpleRegistry > const & types_xRegistry,
367     Reference< registry::XSimpleRegistry > const & services_xRegistry,
368     OUString const & rBootstrapPath, Bootstrap const & bootstrap )
369     SAL_THROW( (Exception) )
370 {
371     Reference< lang::XInitialization > xSFInit( xSF, UNO_QUERY );
372     if (! xSFInit.is())
373     {
374         throw RuntimeException(
375             OUSTR("servicemanager does not support XInitialization!"),
376             Reference< XInterface >() );
377     }
378 
379     // basic context values
380     ContextEntry_Init entry;
381     ::std::vector< ContextEntry_Init > context_values;
382     context_values.reserve( 14 );
383 
384     // macro expander singleton for loader
385     entry.bLateInitService = true;
386     entry.name = OUSTR("/singletons/com.sun.star.util.theMacroExpander");
387     entry.value <<= create_boostrap_macro_expander_factory();
388     context_values.push_back( entry );
389 
390     // tdmgr singleton
391     entry.bLateInitService = true;
392     entry.name =
393         OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
394     entry.value <<= OUSTR("com.sun.star.comp.stoc.TypeDescriptionManager");
395     context_values.push_back( entry );
396 
397     // read out singleton infos from registry
398     if (services_xRegistry.is())
399     {
400         Reference< registry::XRegistryKey > xKey(
401             services_xRegistry->getRootKey() );
402         if (xKey.is())
403         {
404             xKey = xKey->openKey( OUSTR("/SINGLETONS") );
405             if (xKey.is())
406             {
407                 entry.bLateInitService = true;
408 
409                 Sequence< Reference< registry::XRegistryKey > > keys(
410                     xKey->openKeys() );
411                 Reference< registry::XRegistryKey > const * pKeys =
412                     keys.getConstArray();
413                 for ( sal_Int32 nPos = keys.getLength(); nPos--; )
414                 {
415                     css::uno::Sequence< rtl::OUString > impls(
416                         css::uno::Reference< css::registry::XRegistryKey >(
417                             pKeys[nPos]->openKey(
418                                 rtl::OUString(
419                                     RTL_CONSTASCII_USTRINGPARAM(
420                                         "REGISTERED_BY"))),
421                             css::uno::UNO_SET_THROW)->getAsciiListValue());
422                     switch (impls.getLength()) {
423                     case 0:
424                         throw css::uno::DeploymentException(
425                             (pKeys[nPos]->getKeyName() +
426                              rtl::OUString(
427                                  RTL_CONSTASCII_USTRINGPARAM(
428                                      "/REGISTERED_BY is empty"))),
429                             css::uno::Reference< css::uno::XInterface >());
430                     case 1:
431                         break;
432                     default:
433                         OSL_TRACE(
434                             ("arbitrarily chosing \"%s\" among multiple"
435                              " implementations for \"%s\""),
436                             rtl::OUStringToOString(
437                                 impls[0], RTL_TEXTENCODING_UTF8).getStr(),
438                             rtl::OUStringToOString(
439                                 pKeys[nPos]->getKeyName(),
440                                 RTL_TEXTENCODING_UTF8).getStr());
441                         break;
442                     }
443                     context_values.push_back(
444                         ContextEntry_Init(
445                             (rtl::OUString(
446                                 RTL_CONSTASCII_USTRINGPARAM("/singletons/")) +
447                              pKeys[nPos]->getKeyName().copy(
448                                  RTL_CONSTASCII_LENGTH("/SINGLETONS/"))),
449                             css::uno::makeAny(impls[0]),
450                             true));
451                 }
452             }
453         }
454     }
455 
456     // ac, policy:
457     add_access_control_entries( &context_values, bootstrap );
458 
459     // smgr singleton
460     entry.bLateInitService = false;
461     entry.name = OUSTR("/singletons/com.sun.star.lang.theServiceManager");
462     entry.value <<= xSF;
463     context_values.push_back( entry );
464 
465     Reference< XComponentContext > xContext(
466         createComponentContext(
467             &context_values[ 0 ], context_values.size(),
468             Reference< XComponentContext >() ) );
469     // set default context
470     Reference< beans::XPropertySet > xProps( xSF, UNO_QUERY );
471     OSL_ASSERT( xProps.is() );
472     if (xProps.is())
473     {
474         xProps->setPropertyValue(
475             OUSTR("DefaultContext"), makeAny( xContext ) );
476     }
477 
478     Reference< container::XHierarchicalNameAccess > xTDMgr;
479 
480     // get tdmgr singleton
481     if (xContext->getValueByName(
482             OUSTR("/singletons/"
483                   "com.sun.star.reflection.theTypeDescriptionManager") )
484         >>= xTDMgr)
485     {
486         if (types_xRegistry.is()) // insert rdb provider?
487         {
488             // add registry td provider factory to smgr and instance to tdmgr
489             Reference< lang::XSingleComponentFactory > xFac(
490                 loadSharedLibComponentFactory(
491                     OUSTR("bootstrap.uno" SAL_DLLEXTENSION),
492                     0 == rBootstrapPath.getLength()
493                     ? get_this_libpath() : rBootstrapPath,
494                 OUSTR("com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"),
495                 Reference< lang::XMultiServiceFactory >( xSF, UNO_QUERY ),
496                 Reference< registry::XRegistryKey >() ), UNO_QUERY );
497             OSL_ASSERT( xFac.is() );
498 
499             // smgr
500             Reference< container::XSet > xSet( xSF, UNO_QUERY );
501             xSet->insert( makeAny( xFac ) );
502             OSL_ENSURE(
503                 xSet->has( makeAny( xFac ) ),
504                 "### failed registering registry td provider at smgr!" );
505             // tdmgr
506             xSet.set( xTDMgr, UNO_QUERY );
507             OSL_ASSERT( xSet.is() );
508             Any types_RDB( makeAny( types_xRegistry ) );
509             Any rdbtdp( makeAny( xFac->createInstanceWithArgumentsAndContext(
510                 Sequence< Any >( &types_RDB, 1 ), xContext ) ) );
511             xSet->insert( rdbtdp );
512             OSL_ENSURE(
513                 xSet->has( rdbtdp ),
514                 "### failed inserting registry td provider to tdmgr!" );
515         }
516         // install callback
517         installTypeDescriptionManager( xTDMgr );
518     }
519 
520     return xContext;
521 }
522 
523 static Reference< lang::XMultiComponentFactory > createImplServiceFactory(
524     const OUString & rWriteRegistry,
525     const OUString & rReadRegistry,
526     sal_Bool bReadOnly,
527     const OUString & rBootstrapPath )
528     SAL_THROW( (Exception) )
529 {
530     Reference< lang::XMultiComponentFactory > xSF(
531         bootstrapInitialSF( rBootstrapPath ) );
532 
533     Reference< registry::XSimpleRegistry > xRegistry;
534 
535     // open a registry
536     sal_Bool bRegistryShouldBeValid = sal_False;
537     if (rWriteRegistry.getLength() && !rReadRegistry.getLength())
538     {
539         bRegistryShouldBeValid = sal_True;
540         xRegistry.set( createSimpleRegistry( rBootstrapPath ) );
541         if (xRegistry.is())
542         {
543             if (bReadOnly)
544             {
545                 xRegistry->open( rWriteRegistry, sal_True, sal_False );
546             }
547             else
548             {
549                 xRegistry->open( rWriteRegistry, sal_False, sal_True );
550             }
551         }
552     }
553     else if (rWriteRegistry.getLength() && rReadRegistry.getLength())
554     {
555         // default registry
556         bRegistryShouldBeValid = sal_True;
557         xRegistry.set( createNestedRegistry( rBootstrapPath ) );
558 
559         Reference< registry::XSimpleRegistry > xWriteReg(
560             createSimpleRegistry( rBootstrapPath ) );
561         if (xWriteReg.is())
562         {
563             if (bReadOnly)
564             {
565                 try
566                 {
567                     xWriteReg->open( rWriteRegistry, sal_True, sal_False );
568                 }
569                 catch (registry::InvalidRegistryException &)
570                 {
571                 }
572 
573                 if (! xWriteReg->isValid())
574                 {
575                     throw RuntimeException(
576                         OUSTR("specified first registry "
577                               "could not be open readonly!"),
578                         Reference< XInterface >() );
579                 }
580             }
581             else
582             {
583                 xWriteReg->open( rWriteRegistry, sal_False, sal_True );
584             }
585         }
586 
587         Reference< registry::XSimpleRegistry > xReadReg(
588             createSimpleRegistry( rBootstrapPath ) );
589         if (xReadReg.is())
590         {
591             xReadReg->open( rReadRegistry, sal_True, sal_False );
592         }
593 
594         Reference< lang::XInitialization > xInit( xRegistry, UNO_QUERY );
595         Sequence< Any > aInitSeq( 2 );
596         aInitSeq[ 0 ] <<= xWriteReg;
597         aInitSeq[ 1 ] <<= xReadReg;
598         xInit->initialize( aInitSeq );
599     }
600 
601     if (bRegistryShouldBeValid && (!xRegistry.is() || !xRegistry->isValid()))
602     {
603         throw RuntimeException(
604             OUSTR("specified registry could not be initialized"),
605             Reference< XInterface >() );
606     }
607 
608     Bootstrap bootstrap;
609     Reference< XComponentContext > xContext(
610         bootstrapInitialContext(
611             xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
612 
613     // initialize sf
614     Reference< lang::XInitialization > xInit( xSF, UNO_QUERY );
615     OSL_ASSERT( xInit.is() );
616     Sequence< Any > aSFInit( 1 );
617     aSFInit[ 0 ] <<= xRegistry;
618     xInit->initialize( aSFInit );
619 
620     return xSF;
621 }
622 
623 Reference< lang::XMultiServiceFactory > SAL_CALL createRegistryServiceFactory(
624     const OUString & rWriteRegistry,
625     const OUString & rReadRegistry,
626     sal_Bool bReadOnly,
627     const OUString & rBootstrapPath )
628     SAL_THROW( (Exception) )
629 {
630     return Reference< lang::XMultiServiceFactory >( createImplServiceFactory(
631         rWriteRegistry, rReadRegistry, bReadOnly, rBootstrapPath ), UNO_QUERY );
632 }
633 
634 Reference< XComponentContext > SAL_CALL bootstrap_InitialComponentContext(
635     Reference< registry::XSimpleRegistry > const & xRegistry,
636     OUString const & rBootstrapPath )
637     SAL_THROW( (Exception) )
638 {
639     Bootstrap bootstrap;
640 
641     Reference< lang::XMultiComponentFactory > xSF(
642         bootstrapInitialSF( rBootstrapPath ) );
643     Reference< XComponentContext > xContext(
644         bootstrapInitialContext(
645             xSF, xRegistry, xRegistry, rBootstrapPath, bootstrap ) );
646 
647     // initialize sf
648     Reference< lang::XInitialization > xInit( xSF, UNO_QUERY );
649     OSL_ASSERT( xInit.is() );
650     Sequence< Any > aSFInit( 2 );
651     aSFInit[ 0 ] <<= xRegistry;
652     aSFInit[ 1 ] <<= xContext; // default context
653     xInit->initialize( aSFInit );
654 
655     return xContext;
656 }
657 
658 }
659