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