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_stoc.hxx"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <list>
29 
30 #include <unistd.h>
31 #include <cppuhelper/queryinterface.hxx>
32 #include <cppuhelper/factory.hxx>
33 #include <cppuhelper/weak.hxx>
34 #include <cppuhelper/servicefactory.hxx>
35 #ifndef _CPPUHELPER_IMPLBASE3_HXX
36 #include <cppuhelper/implbase3.hxx>
37 #endif
38 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
39 #include <cppuhelper/implementationentry.hxx>
40 #endif
41 
42 #include <uno/mapping.hxx>
43 #include <osl/thread.h>
44 
45 #include <rtl/ustring.hxx>
46 #include <rtl/ustrbuf.hxx>
47 #include <rtl/strbuf.hxx>
48 #include <osl/process.h>
49 
50 #include <com/sun/star/lang/XServiceInfo.hpp>
51 #include <com/sun/star/lang/XInitialization.hpp>
52 #include <com/sun/star/loader/XImplementationLoader.hpp>
53 #include <com/sun/star/registry/XImplementationRegistration2.hpp>
54 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
55 #include <com/sun/star/reflection/XServiceTypeDescription.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
57 #include "com/sun/star/uno/RuntimeException.hpp"
58 
59 #include "mergekeys.hxx"
60 
61 #if defined(SAL_W32) || defined(SAL_OS2)
62 #include <io.h>
63 #endif
64 
65 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
66 
67 
68 using namespace com::sun::star;
69 using namespace com::sun::star::uno;
70 using namespace com::sun::star::loader;
71 using namespace com::sun::star::beans;
72 using namespace com::sun::star::lang;
73 using namespace com::sun::star::registry;
74 using namespace cppu;
75 using namespace rtl;
76 using namespace osl;
77 
78 
79 #define IMPLNAME "com.sun.star.comp.stoc.ImplementationRegistration"
80 #define SERVICENAME 		"com.sun.star.registry.ImplementationRegistration"
81 namespace stoc_impreg
82 {
83 struct StringPool
84 {
85     OUString sImplementationName;
86     OUString sServiceName;
87     OUString TMP;
88     OUString TEMP;
89     OUString slash_UNO_slash_REGISTRY_LINKS;
90     OUString slash_IMPLEMENTATIONS;
91     OUString slash_UNO;
92     OUString slash_UNO_slash_SERVICES;
93     OUString slash_UNO_slash_SINGLETONS;
94     OUString slash_SERVICES;
95     OUString slash_UNO_slash_LOCATION;
96     OUString slash_UNO_slash_ACTIVATOR;
97     OUString colon_old;
98     OUString com_sun_star_registry_SimpleRegistry;
99     OUString Registry;
StringPoolstoc_impreg::StringPool100     StringPool()
101         : sImplementationName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) )
102         , sServiceName( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) )
103         , TMP( RTL_CONSTASCII_USTRINGPARAM( "TMP" ) )
104         , TEMP( RTL_CONSTASCII_USTRINGPARAM( "TEMP" ) )
105         , slash_UNO_slash_REGISTRY_LINKS( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS"))
106         , slash_IMPLEMENTATIONS( RTL_CONSTASCII_USTRINGPARAM( "/IMPLEMENTATIONS" ) )
107         , slash_UNO( RTL_CONSTASCII_USTRINGPARAM("/UNO"))
108         , slash_UNO_slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES"))
109         , slash_UNO_slash_SINGLETONS( RTL_CONSTASCII_USTRINGPARAM("/UNO/SINGLETONS"))
110         , slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") )
111         , slash_UNO_slash_LOCATION( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") )
112         , slash_UNO_slash_ACTIVATOR( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )
113         , colon_old( RTL_CONSTASCII_USTRINGPARAM(":old"))
114         , com_sun_star_registry_SimpleRegistry(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") )
115         , Registry( RTL_CONSTASCII_USTRINGPARAM("Registry") )
116         {}
117 private:
118     StringPool( const StringPool & );
119 };
120 
spool()121 const StringPool &spool()
122 {
123     static StringPool *pPool = 0;
124     if( ! pPool )
125     {
126         MutexGuard guard( Mutex::getGlobalMutex() );
127         if( ! pPool )
128         {
129             static StringPool pool;
130             pPool = &pool;
131         }
132     }
133     return *pPool;
134 }
135 }
136 
137 extern rtl_StandardModuleCount g_moduleCount;
138 
139 namespace stoc_bootstrap
140 {
impreg_getSupportedServiceNames()141 Sequence< OUString > impreg_getSupportedServiceNames()
142 {
143 	static Sequence < OUString > *pNames = 0;
144 	if( ! pNames )
145 	{
146 		MutexGuard guard( Mutex::getGlobalMutex() );
147 		if( !pNames )
148 		{
149 			static Sequence< OUString > seqNames(1);
150 			seqNames.getArray()[0] = stoc_impreg::spool().sServiceName;
151 			pNames = &seqNames;
152 		}
153 	}
154 	return *pNames;
155 }
156 
impreg_getImplementationName()157 OUString impreg_getImplementationName()
158 {
159     return stoc_impreg::spool().sImplementationName;
160 }
161 }
162 
163 namespace stoc_impreg
164 {
165 //*************************************************************************
166 //	static deleteAllLinkReferences()
167 //
deleteAllLinkReferences(const Reference<XSimpleRegistry> & xReg,const Reference<XRegistryKey> & xSource)168 static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
169 									const Reference < XRegistryKey >& xSource)
170     // throw ( InvalidRegistryException, RuntimeException )
171 {
172     Reference < XRegistryKey > xKey = xSource->openKey(
173         spool().slash_UNO_slash_REGISTRY_LINKS );
174 
175     if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
176     {
177         Sequence<OUString> linkNames = xKey->getAsciiListValue();
178 
179         if (linkNames.getLength())
180         {
181             const OUString* pLinkNames = linkNames.getConstArray();
182 
183             OUString			aLinkName;
184             OUString			aLinkParent;
185             Reference < XRegistryKey >	xLinkParent;
186             const sal_Unicode*	pTmpName = NULL;
187             const sal_Unicode*	pShortName = NULL;
188             sal_Int32		   	sEnd = 0;
189 
190             for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
191             {
192                 aLinkName = pLinkNames[i];
193 
194                 pTmpName = aLinkName.getStr();
195 
196                 if (pTmpName[0] != L'/')
197                     continue;
198 
199                 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
200                 if ( nIndex == -1 )
201                     pShortName = 0;
202                 else
203                     pShortName = pTmpName+nIndex;
204 
205                 while (pShortName && pShortName[1] == L'%')
206                 {
207                     nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
208                     if ( nIndex == -1 )
209                         pShortName = 0;
210                     else
211                         pShortName += nIndex+2;
212                 }
213 
214                 if (pShortName)
215                 {
216                     aLinkName = aLinkName.copy(0, pShortName - pTmpName);
217                 }
218 
219                 xReg->getRootKey()->deleteLink(aLinkName);
220 
221                 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
222 
223                 aLinkParent = aLinkName.copy(0, sEnd);
224 
225                 while(aLinkParent.getLength())
226                 {
227                     xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
228 
229                     if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
230                     {
231                         aLinkName = aLinkParent;
232 
233                         xReg->getRootKey()->deleteKey(aLinkParent);
234 
235                         sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
236 
237                         aLinkParent = aLinkName.copy(0, sEnd);
238                     } else
239                     {
240                         break;
241                     }
242                 }
243             }
244         }
245     }
246 }
247 
248 //*************************************************************************
249 //	static prepareLink
250 //
prepareLink(const Reference<XSimpleRegistry> & xDest,const Reference<XRegistryKey> & xSource,const OUString & link)251 static void prepareLink( const Reference < XSimpleRegistry > & xDest,
252 						 const Reference < XRegistryKey > & xSource,
253 						 const OUString& link)
254     // throw ( InvalidRegistryException, RuntimeException )
255 {
256     OUString linkRefName = xSource->getKeyName();
257     OUString linkName(link);
258     sal_Bool	isRelativ = sal_False;
259 
260     const sal_Unicode*	pTmpName = link.getStr();
261     const sal_Unicode*	pShortName;
262     sal_Int32           nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
263     if ( nIndex == -1 )
264         pShortName = 0;
265     else
266         pShortName = pTmpName+nIndex;
267 
268     if (pTmpName[0] != L'/')
269         isRelativ = sal_True;
270 
271     while (pShortName && pShortName[1] == L'%')
272     {
273         nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
274         if ( nIndex == -1 )
275             pShortName = 0;
276         else
277             pShortName += nIndex+2;
278     }
279 
280     if (pShortName)
281     {
282         linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
283         linkName = link.copy(0, pShortName - pTmpName);
284     }
285 
286     if (isRelativ)
287         xSource->createLink(linkName, linkRefName);
288     else
289         xDest->getRootKey()->createLink(linkName, linkRefName);
290 }
291 
292 //*************************************************************************
293 //	static searchImplForLink
294 //
searchImplForLink(const Reference<XRegistryKey> & xRootKey,const OUString & linkName,const OUString & implName)295 static OUString searchImplForLink(
296     const Reference < XRegistryKey > & xRootKey,
297     const OUString& linkName,
298     const OUString& implName )
299     // throw ( InvalidRegistryException, RuntimeException )
300 {
301     const StringPool & pool = spool();
302     Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
303     if (xKey.is())
304     {
305         Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
306         const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
307         OUString key_name( pool.slash_UNO + linkName );
308 
309         for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
310         {
311             try
312             {
313                 Reference < XRegistryKey > xImplKey( pSubKeys[i] );
314                 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
315                 {
316                     OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
317                     if (implName != oldImplName)
318                     {
319                         return oldImplName;
320                     }
321                 }
322             }
323             catch(InvalidRegistryException&)
324             {
325             }
326         }
327     }
328 
329 	return OUString();
330 }
331 
332 //*************************************************************************
333 //	static searchLinkTargetForImpl
334 //
searchLinkTargetForImpl(const Reference<XRegistryKey> & xRootKey,const OUString & linkName,const OUString & implName)335 static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
336                                         const OUString& linkName,
337                                         const OUString& implName)
338     // throw ( InvalidRegistryException, RuntimeException )
339 {
340 	OUString ret;
341 
342 //  	try
343 //  	{
344         const StringPool & pool = spool();
345 		Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
346 
347 		if (xKey.is())
348 		{
349 			Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
350 
351 			const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
352 			Reference < XRegistryKey > xImplKey;
353 
354 			for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
355 			{
356 				xImplKey = pSubKeys[i];
357 
358 				OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
359                 OUString qualifiedLinkName( pool.slash_UNO );
360                 qualifiedLinkName += linkName;
361 				if (tmpImplName == implName &&
362 					xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
363 				{
364 					return xImplKey->getLinkTarget( qualifiedLinkName );
365 				}
366 			}
367 		}
368 //  	}
369 //  	catch(InvalidRegistryException&)
370 //  	{
371 //  	}
372 
373 	return ret;
374 }
375 
376 //*************************************************************************
377 //	static createUniqueSubEntry
378 //
createUniqueSubEntry(const Reference<XRegistryKey> & xSuperKey,const OUString & value)379 static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
380 								 const OUString& value)
381     // throw ( InvalidRegistryException, RuntimeException )
382 {
383 	if (xSuperKey.is())
384 	{
385 //  		try
386 //  		{
387         if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
388         {
389             sal_Int32 length = 0;
390             sal_Bool bReady = sal_False;
391 
392             Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
393             length = implEntries.getLength();
394 
395             for (sal_Int32 i = 0; !bReady && (i < length); i++)
396             {
397                 bReady = (implEntries.getConstArray()[i] == value);
398             }
399 
400             if (bReady)
401             {
402                 Sequence<OUString> implEntriesNew(length);
403                 implEntriesNew.getArray()[0] = value;
404 
405                 for (sal_Int32 i=0, j=1; i < length; i++)
406                 {
407                     if (implEntries.getConstArray()[i] != value)
408                         implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
409                 }
410                 xSuperKey->setAsciiListValue(implEntriesNew);
411             } else
412             {
413                 Sequence<OUString> implEntriesNew(length+1);
414                 implEntriesNew.getArray()[0] = value;
415 
416                 for (sal_Int32 i = 0; i < length; i++)
417                 {
418                     implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
419                 }
420                 xSuperKey->setAsciiListValue(implEntriesNew);
421             }
422         } else
423         {
424             Sequence<OUString> implEntriesNew(1);
425 
426             implEntriesNew.getArray()[0] = value;
427 
428             xSuperKey->setAsciiListValue(implEntriesNew);
429         }
430 //  		}
431 //  		catch(InvalidRegistryException&)
432 //  		{
433 //  		}
434 	}
435 }
436 
437 //*************************************************************************
438 //	static deleteSubEntry
439 //
deleteSubEntry(const Reference<XRegistryKey> & xSuperKey,const OUString & value)440 static sal_Bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
441     // throw ( InvalidRegistryException, RuntimeException )
442 {
443     if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
444     {
445         Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
446         sal_Int32 length = implEntries.getLength();
447         sal_Int32 equals = 0;
448         sal_Bool hasNoImplementations = sal_False;
449 
450         for (sal_Int32 i = 0; i < length; i++)
451         {
452             if (implEntries.getConstArray()[i] == value)
453                 equals++;
454         }
455 
456         if (equals == length)
457         {
458             hasNoImplementations = sal_True;
459         } else
460         {
461             Sequence<OUString> implEntriesNew(length - equals);
462 
463             sal_Int32 j = 0;
464             for (sal_Int32 i = 0; i < length; i++)
465             {
466                 if (implEntries.getConstArray()[i] != value)
467                 {
468                         implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
469                 }
470             }
471             xSuperKey->setAsciiListValue(implEntriesNew);
472         }
473 
474         if (hasNoImplementations)
475         {
476             return sal_True;
477         }
478     }
479 	return sal_False;
480 }
481 
482 //*************************************************************************
483 //	static prepareUserLink
484 //
prepareUserLink(const Reference<XSimpleRegistry> & xDest,const OUString & linkName,const OUString & linkTarget,const OUString & implName)485 static void	prepareUserLink(const Reference < XSimpleRegistry >& xDest,
486                                 const OUString& linkName,
487                                 const OUString& linkTarget,
488                                 const OUString& implName)
489     // throw ( InvalidRegistryException, RuntimeException )
490 {
491 	sal_Bool ret = sal_False;
492 
493 	Reference < XRegistryKey > xRootKey;
494 
495 //  	try
496 //  	{
497     xRootKey = xDest->getRootKey();
498 
499     if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
500     {
501         OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
502 
503         if (oldImplName.getLength())
504         {
505             createUniqueSubEntry(xDest->getRootKey()->createKey(
506                 linkName + spool().colon_old ), oldImplName);
507         }
508     }
509 //  	}
510 //  	catch (InvalidRegistryException&)
511 //  	{
512 //  	}
513 
514 //  	try
515 //  	{
516     if (xRootKey->isValid())
517     {
518         ret = xRootKey->createLink(linkName, linkTarget);
519     }
520 //  	}
521 //  	catch(InvalidRegistryException&)
522 //  	{
523 //  	}
524 
525 //  	return ret;
526 }
527 
528 //*************************************************************************
529 //	static deleteUserLink
530 //
deletePathIfPossible(const Reference<XRegistryKey> & xRootKey,const OUString & path)531 static void	deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
532 								 const OUString& path)
533 {
534 	try
535 	{
536 		Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
537 
538 		if (keyNames.getLength() == 0 &&
539 			xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
540 		{
541 			xRootKey->deleteKey(path);
542 
543 			OUString tmpPath(path);
544 			OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/'));
545 
546 			if (newPath.getLength() > 1)
547 				deletePathIfPossible(xRootKey, newPath);
548 		}
549 	}
550 	catch(InvalidRegistryException&)
551 	{
552 	}
553 }
554 
555 
556 //*************************************************************************
557 //	static deleteUserLink
558 //
deleteUserLink(const Reference<XRegistryKey> & xRootKey,const OUString & linkName,const OUString & linkTarget,const OUString & implName)559 static void	deleteUserLink(const Reference < XRegistryKey >& xRootKey,
560                                const OUString& linkName,
561                                const OUString& linkTarget,
562                                const OUString& implName)
563     // throw ( InvalidRegistryException, RuntimeException )
564 {
565     sal_Bool bClean = sal_False;
566 
567     if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
568     {
569         OUString tmpTarget = xRootKey->getLinkTarget(linkName);
570 
571         if (tmpTarget == linkTarget)
572         {
573             xRootKey->deleteLink(linkName);
574         }
575     }
576 
577     Reference < XRegistryKey > xOldKey = xRootKey->openKey(
578         linkName + spool().colon_old );
579     if (xOldKey.is())
580     {
581         sal_Bool hasNoImplementations = sal_False;
582 
583         if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
584         {
585             Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
586             sal_Int32 length = implEntries.getLength();
587             sal_Int32 equals = 0;
588 
589             for (sal_Int32 i = 0; i < length; i++)
590             {
591                 if (implEntries.getConstArray()[i] == implName)
592                     equals++;
593             }
594 
595             if (equals == length)
596             {
597                 hasNoImplementations = sal_True;
598             } else
599             {
600                 OUString oldImpl;
601 
602                 if (length > equals + 1)
603                 {
604                     Sequence<OUString> implEntriesNew(length - equals - 1);
605 
606                     sal_Int32 j = 0;
607                     sal_Bool first = sal_True;
608                     for (sal_Int32 i = 0; i < length; i++)
609                     {
610                         if (implEntries.getConstArray()[i] != implName)
611                         {
612                             if (first)
613                             {
614                                 oldImpl = implEntries.getConstArray()[i];
615                                 first = sal_False;
616                             } else
617                             {
618                                 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
619                             }
620                         }
621                     }
622 
623                     xOldKey->setAsciiListValue(implEntriesNew);
624                 } else
625                 {
626                     oldImpl = implEntries.getConstArray()[0];
627                     rtl::OUString path(xOldKey->getKeyName());
628                     xOldKey->closeKey();
629                     xRootKey->deleteKey(path);
630                 }
631 
632                 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
633                 if (oldTarget.getLength())
634                 {
635                     xRootKey->createLink(linkName, oldTarget);
636                 }
637             }
638 
639             if (hasNoImplementations)
640             {
641                 bClean = sal_True;
642                 hasNoImplementations = sal_False;
643                 rtl::OUString path(xOldKey->getKeyName());
644                 xOldKey->closeKey();
645                 xRootKey->deleteKey(path);
646             }
647         }
648     } else
649     {
650         bClean = sal_True;
651     }
652 
653     if (bClean)
654     {
655         OUString tmpName(linkName);
656         OUString path = tmpName.copy(0, tmpName.lastIndexOf('/'));
657         deletePathIfPossible(xRootKey, path);
658     }
659 }
660 
661 //*************************************************************************
662 //	static prepareUserKeys
663 //
prepareUserKeys(const Reference<XSimpleRegistry> & xDest,const Reference<XRegistryKey> & xUnoKey,const Reference<XRegistryKey> & xKey,const OUString & implName,sal_Bool bRegister)664 static void	prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
665                                 const Reference < XRegistryKey >& xUnoKey,
666                                 const Reference < XRegistryKey >& xKey,
667                                 const OUString& implName,
668                                 sal_Bool bRegister)
669     // throw ( InvalidRegistryException, RuntimeException )
670 {
671 	sal_Bool hasSubKeys = sal_False;
672 
673     Sequence<OUString> keyNames = xKey->getKeyNames();
674 
675     OUString relativKey;
676     if (keyNames.getLength())
677         relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
678 
679     if (keyNames.getLength() == 1 &&
680         xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
681     {
682         hasSubKeys = sal_True;
683 
684         OUString linkTarget = xKey->getLinkTarget(relativKey);
685         OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
686 
687         linkName = linkName + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + relativKey;
688 
689         if (bRegister)
690         {
691             prepareUserLink(xDest, linkName, linkTarget, implName);
692         } else
693         {
694             deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
695         }
696     } else
697     {
698         Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
699 
700         if (subKeys.getLength())
701         {
702             hasSubKeys = sal_True;
703             const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
704 
705             for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
706             {
707                 prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
708             }
709         }
710     }
711 
712     if (! hasSubKeys)
713     {
714         OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
715 
716         Reference < XRegistryKey > xRootKey = xDest->getRootKey();
717         if (bRegister)
718         {
719             createUniqueSubEntry(xRootKey->createKey(keyName), implName);
720         }
721         else
722         {
723             Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
724             if( rKey.is() )
725             {
726                 deleteSubEntry(rKey, implName);
727                 xRootKey->deleteKey(keyName);
728             }
729 
730             OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
731             if( path.getLength() )
732             {
733                 deletePathIfPossible(xRootKey, path);
734             }
735         }
736     }
737 	return;
738 }
739 
740 //*************************************************************************
741 //	static deleteAllImplementations
742 //
deleteAllImplementations(const Reference<XSimpleRegistry> & xReg,const Reference<XRegistryKey> & xSource,const OUString & locationUrl,std::list<OUString> & implNames)743 static void deleteAllImplementations(	const Reference < XSimpleRegistry >& xReg,
744 										const Reference < XRegistryKey >& xSource,
745 										const OUString& locationUrl,
746 										std::list<OUString> & implNames)
747     // throw (InvalidRegistryException, RuntimeException)
748 {
749     Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
750 
751     if (subKeys.getLength() > 0)
752     {
753         const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
754         Reference < XRegistryKey > xImplKey;
755         sal_Bool hasLocationUrl = sal_False;
756 
757         const StringPool &pool = spool();
758         for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
759         {
760             xImplKey = pSubKeys[i];
761             Reference < XRegistryKey > xKey = xImplKey->openKey(
762                 pool.slash_UNO_slash_LOCATION );
763 
764             if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
765             {
766                 if (xKey->getAsciiValue() == locationUrl)
767                 {
768                     hasLocationUrl = sal_True;
769 
770                     OUString implName(xImplKey->getKeyName().getStr() + 1);
771                     sal_Int32 firstDot = implName.indexOf('/');
772 
773                     if (firstDot >= 0)
774                         implName = implName.copy(firstDot + 1);
775 
776                     implNames.push_back(implName);
777 
778                     deleteAllLinkReferences(xReg, xImplKey);
779 
780                     xKey = xImplKey->openKey( pool.slash_UNO );
781                     if (xKey.is())
782                     {
783                         Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
784 
785                         if (subKeys2.getLength())
786                         {
787                             const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
788 
789                             for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
790                             {
791                                 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
792                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
793                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
794                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
795                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
796                                 {
797                                     prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, sal_False);
798                                 }
799                             }
800                         }
801                     }
802                 }
803             }
804 
805             if (hasLocationUrl)
806             {
807                 hasLocationUrl = sal_False;
808                 rtl::OUString path(xImplKey->getKeyName());
809                 xImplKey->closeKey();
810                 xReg->getRootKey()->deleteKey(path);
811             }
812         }
813 
814         subKeys = xSource->openKeys();
815         if (subKeys.getLength() == 0)
816         {
817             rtl::OUString path(xSource->getKeyName());
818             xSource->closeKey();
819             xReg->getRootKey()->deleteKey(path);
820         }
821     } else
822     {
823         rtl::OUString path(xSource->getKeyName());
824         xSource->closeKey();
825         xReg->getRootKey()->deleteKey(path);
826     }
827 }
828 
829 //==================================================================================================
delete_all_singleton_entries(Reference<registry::XRegistryKey> const & xSingletons_section,::std::list<OUString> const & impl_names)830 static void delete_all_singleton_entries(
831 	Reference < registry::XRegistryKey > const & xSingletons_section,
832     ::std::list< OUString > const & impl_names )
833     // throw (InvalidRegistryException, RuntimeException)
834 {
835     Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
836     Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
837     for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
838     {
839         Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
840         Reference< registry::XRegistryKey > xRegisteredImplNames(
841             xSingleton->openKey( OUSTR("REGISTERED_BY") ) );
842         if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
843         {
844             Sequence< OUString > registered_implnames;
845             try
846             {
847                 registered_implnames = xRegisteredImplNames->getAsciiListValue();
848             }
849             catch (registry::InvalidValueException &)
850             {
851             }
852             OUString const * p = registered_implnames.getConstArray();
853             sal_Int32 nOrigRegLength = registered_implnames.getLength();
854             sal_Int32 nNewLength = nOrigRegLength;
855             for ( sal_Int32 n = nOrigRegLength; n--; )
856             {
857                 OUString const & registered_implname = p[ n ];
858 
859                 ::std::list< OUString >::const_iterator iPos( impl_names.begin() );
860                 ::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
861                 for ( ; iPos != iEnd; ++iPos )
862                 {
863                     if (iPos->equals( registered_implname ))
864                     {
865                         registered_implnames[ n ] = p[ nNewLength -1 ];
866                         --nNewLength;
867                     }
868                 }
869             }
870 
871             if (nNewLength != nOrigRegLength)
872             {
873                 if (0 == nNewLength)
874                 {
875                     // remove whole entry
876                     xRegisteredImplNames->closeKey();
877                     xSingleton->deleteKey( OUSTR("REGISTERED_BY") );
878                     // registry key cannot provide its relative name, only absolute :(
879                     OUString abs( xSingleton->getKeyName() );
880                     xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
881                 }
882                 else
883                 {
884                     registered_implnames.realloc( nNewLength );
885                     xRegisteredImplNames->setAsciiListValue( registered_implnames );
886                 }
887             }
888         }
889     }
890 }
891 
892 //*************************************************************************
893 //	static deleteAllServiceEntries
894 //
deleteAllServiceEntries(const Reference<XSimpleRegistry> & xReg,const Reference<XRegistryKey> & xSource,const OUString & implName)895 static void deleteAllServiceEntries(	const Reference < XSimpleRegistry >& xReg,
896 										const Reference < XRegistryKey >& xSource,
897 										const OUString& implName)
898     // throw ( InvalidRegistryException, RuntimeException )
899 {
900     Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
901 
902     if (subKeys.getLength() > 0)
903     {
904         const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
905         Reference < XRegistryKey > xServiceKey;
906         sal_Bool hasNoImplementations = sal_False;
907 
908         for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
909         {
910             xServiceKey = pSubKeys[i];
911 
912             if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
913             {
914                 Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
915                 sal_Int32 length = implEntries.getLength();
916                 sal_Int32 equals = 0;
917 
918                 for (sal_Int32 j = 0; j < length; j++)
919                 {
920                     if (implEntries.getConstArray()[j] == implName)
921                         equals++;
922                 }
923 
924                 if (equals == length)
925                 {
926                     hasNoImplementations = sal_True;
927                 } else
928                 {
929                     if (equals > 0)
930                     {
931                         Sequence<OUString> implEntriesNew(length-equals);
932 
933                         sal_Int32 j = 0;
934                         for (sal_Int32 k = 0; k < length; k++)
935                         {
936                             if (implEntries.getConstArray()[k] != implName)
937                             {
938                                 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
939                             }
940                         }
941 
942                         xServiceKey->setAsciiListValue(implEntriesNew);
943                     }
944                 }
945             }
946 
947             if (hasNoImplementations)
948             {
949                 hasNoImplementations = sal_False;
950                 rtl::OUString path(xServiceKey->getKeyName());
951                 xServiceKey->closeKey();
952                 xReg->getRootKey()->deleteKey(path);
953             }
954         }
955 
956         subKeys = xSource->openKeys();
957         if (subKeys.getLength() == 0)
958         {
959             rtl::OUString path(xSource->getKeyName());
960             xSource->closeKey();
961             xReg->getRootKey()->deleteKey(path);
962         }
963     } else
964     {
965         rtl::OUString path(xSource->getKeyName());
966         xSource->closeKey();
967         xReg->getRootKey()->deleteKey(path);
968     }
969 }
970 
971 //--------------------------------------------------------------------------------------------------
is_supported_service(OUString const & service_name,Reference<reflection::XServiceTypeDescription> const & xService_td)972 static bool is_supported_service(
973     OUString const & service_name,
974     Reference< reflection::XServiceTypeDescription > const & xService_td )
975 {
976     if (xService_td->getName().equals( service_name ))
977         return true;
978     Sequence< Reference< reflection::XServiceTypeDescription > > seq(
979         xService_td->getMandatoryServices() );
980     Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
981     for ( sal_Int32 nPos = seq.getLength(); nPos--; )
982     {
983         if (is_supported_service( service_name, p[ nPos ] ))
984             return true;
985     }
986     return false;
987 }
988 
989 //--------------------------------------------------------------------------------------------------
insert_singletons(Reference<registry::XSimpleRegistry> const & xDest,Reference<registry::XRegistryKey> const & xImplKey,Reference<XComponentContext> const & xContext)990 static void insert_singletons(
991     Reference< registry::XSimpleRegistry > const & xDest,
992     Reference< registry::XRegistryKey > const & xImplKey,
993     Reference< XComponentContext > const & xContext )
994     // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
995 {
996     // singletons
997     Reference< registry::XRegistryKey > xKey( xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
998     if (xKey.is() && xKey->isValid())
999     {
1000         OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
1001         // singleton entries
1002         Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
1003         Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
1004         for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
1005         {
1006             Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
1007             OUString singleton_name(
1008                 xSingleton->getKeyName().copy(
1009                     implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
1010             OUString service_name( xSingleton->getStringValue() );
1011 
1012             OUString keyname( OUSTR("/SINGLETONS/") + singleton_name );
1013             Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
1014             if (xKey2.is() && xKey2->isValid())
1015             {
1016                 try
1017                 {
1018                     OUString existing_name( xKey2->getStringValue() );
1019                     if (! existing_name.equals( service_name ))
1020                     {
1021                         Reference< container::XHierarchicalNameAccess > xTDMgr;
1022                         OUString the_tdmgr =
1023                             OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
1024                         xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
1025                         if (! xTDMgr.is())
1026                         {
1027                             throw RuntimeException(
1028                                 OUSTR("cannot get singleton ") + the_tdmgr,
1029                                 Reference< XInterface >() );
1030                         }
1031                         try
1032                         {
1033                             Reference< reflection::XServiceTypeDescription > xExistingService_td;
1034                             xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
1035                             if (! xExistingService_td.is())
1036                             {
1037                                 throw RuntimeException(
1038                                     OUSTR("cannot get service type description: ") + existing_name,
1039                                     Reference< XInterface >() );
1040                             }
1041 
1042                             // everything's fine if existing service entry supports the one
1043                             // to be registered
1044                             if (! is_supported_service( service_name, xExistingService_td ))
1045                             {
1046                                 OUStringBuffer buf( 64 );
1047                                 buf.appendAscii(
1048                                     RTL_CONSTASCII_STRINGPARAM("existing singleton service (") );
1049                                 buf.append( singleton_name );
1050                                 buf.append( (sal_Unicode)'=' );
1051                                 buf.append( existing_name );
1052                                 buf.appendAscii(
1053                                     RTL_CONSTASCII_STRINGPARAM(") does not support given one: ") );
1054                                 buf.append( service_name );
1055                                 throw registry::CannotRegisterImplementationException(
1056                                     buf.makeStringAndClear(), Reference< XInterface >() );
1057                             }
1058                         }
1059                         catch (container::NoSuchElementException & exc)
1060                         {
1061                             throw RuntimeException(
1062                                 OUSTR("cannot get service type description: ") + exc.Message,
1063                                 Reference< XInterface >() );
1064                         }
1065                     }
1066                 }
1067                 catch (registry::InvalidValueException &)
1068                 {
1069                     // repair
1070                     xKey2->setStringValue( service_name );
1071                 }
1072             }
1073             else
1074             {
1075                 // insert singleton entry
1076                 xKey2 = xDest->getRootKey()->createKey( keyname );
1077                 xKey2->setStringValue( service_name );
1078             }
1079 
1080             Reference< registry::XRegistryKey > xRegisteredImplNames(
1081                 xKey2->openKey( OUSTR("REGISTERED_BY") ) );
1082             if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
1083             {
1084                 // create
1085                 xRegisteredImplNames = xKey2->createKey( OUSTR("REGISTERED_BY") );
1086             }
1087 
1088             Sequence< OUString > implnames;
1089             try
1090             {
1091                 implnames = xRegisteredImplNames->getAsciiListValue();
1092             }
1093             catch (registry::InvalidValueException &)
1094             {
1095             }
1096             // check implname is already in
1097             sal_Int32 nPos_implnames = implnames.getLength();
1098             OUString const * pImplnames = implnames.getConstArray();
1099             while (nPos_implnames--)
1100             {
1101                 if (implname.equals( pImplnames[ nPos_implnames ] ))
1102                     break;
1103             }
1104             if (nPos_implnames < 0)
1105             {
1106                 // append and write back
1107                 implnames.realloc( implnames.getLength() +1 );
1108                 implnames[ implnames.getLength() -1 ] = implname;
1109                 xRegisteredImplNames->setAsciiListValue( implnames );
1110             }
1111         }
1112     }
1113 }
1114 
1115 
1116 //*************************************************************************
1117 //	static prepareRegistry
1118 //
prepareRegistry(const Reference<XSimpleRegistry> & xDest,const Reference<XRegistryKey> & xSource,const OUString & implementationLoaderUrl,const OUString & locationUrl,Reference<XComponentContext> const & xContext)1119 static void prepareRegistry(
1120     const Reference < XSimpleRegistry >& xDest,
1121     const Reference < XRegistryKey >& xSource,
1122     const OUString& implementationLoaderUrl,
1123     const OUString& locationUrl,
1124     Reference< XComponentContext > const & xContext )
1125     // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
1126 {
1127     Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1128 
1129     if (!subKeys.getLength())
1130     {
1131         throw InvalidRegistryException(
1132             OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): source registry is empty" ) ),
1133             Reference< XInterface > () );
1134     }
1135 
1136     const StringPool & pool = spool();
1137 
1138     const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1139     Reference < XRegistryKey > xImplKey;
1140 
1141     for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1142     {
1143         xImplKey = pSubKeys[i];
1144 
1145         Reference < XRegistryKey >  xKey = xImplKey->openKey(
1146             pool.slash_UNO_slash_SERVICES );
1147 
1148         if (xKey.is())
1149         {
1150             // update entries in SERVICES section
1151             Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
1152             const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
1153 
1154             OUString implName = OUString(xImplKey->getKeyName().getStr() + 1);
1155             sal_Int32 firstDot = implName.indexOf('/');
1156 
1157             if (firstDot >= 0)
1158                 implName = implName.copy(firstDot + 1);
1159 
1160             sal_Int32 offset = xKey->getKeyName().getLength() + 1;
1161 
1162             for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
1163             {
1164                 OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
1165 
1166                 createUniqueSubEntry(
1167                     xDest->getRootKey()->createKey(
1168                         pool.slash_SERVICES + serviceName ),
1169                     implName);
1170             }
1171 
1172             xKey = xImplKey->openKey( pool.slash_UNO );
1173             if (xKey.is())
1174             {
1175                 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
1176 
1177                 if (subKeys2.getLength())
1178                 {
1179                     const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
1180 
1181                     for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
1182                     {
1183                         if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
1184                             pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
1185                             pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
1186                         {
1187                             prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, sal_True);
1188                         }
1189                     }
1190                 }
1191             }
1192         }
1193 
1194         // update LOCATION entry
1195         xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
1196 
1197         if (xKey.is())
1198         {
1199             xKey->setAsciiValue(locationUrl);
1200         }
1201 
1202         // update ACTIVATOR entry
1203         xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
1204 
1205         if (xKey.is())
1206         {
1207             xKey->setAsciiValue(implementationLoaderUrl);
1208         }
1209 
1210         xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
1211 
1212         if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
1213         {
1214             // update link entries in REGISTRY_LINKS section
1215             Sequence<OUString> linkNames = xKey->getAsciiListValue();
1216 
1217             if (linkNames.getLength())
1218             {
1219                 const OUString* pLinkNames = linkNames.getConstArray();
1220 
1221                 for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
1222                 {
1223                     prepareLink(xDest, xImplKey, pLinkNames[j]);
1224                 }
1225             }
1226         }
1227 
1228         insert_singletons( xDest, xImplKey, xContext );
1229     }
1230 }
1231 
1232 
findImplementations(const Reference<XRegistryKey> & xSource,std::list<OUString> & implNames)1233 static void findImplementations(	const Reference < XRegistryKey > & xSource,
1234 									std::list <OUString>& implNames)
1235 {
1236 	sal_Bool isImplKey = sal_False;
1237 
1238 	try
1239 	{
1240 		Reference < XRegistryKey > xKey = xSource->openKey(
1241 			spool().slash_UNO_slash_SERVICES );
1242 
1243 		if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
1244 		{
1245 			isImplKey = sal_True;
1246 
1247 			OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
1248 			sal_Int32 firstDot = implName.indexOf('.');
1249 
1250 			if (firstDot >= 0)
1251 				implName = implName.copy(firstDot + 1);
1252 
1253 			implNames.push_back(implName);
1254 		}
1255 	}
1256 	catch(InvalidRegistryException&)
1257 	{
1258 	}
1259 
1260 	if (isImplKey) return;
1261 
1262 	try
1263 	{
1264 		Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1265 
1266 		if (subKeys.getLength() > 0)
1267 		{
1268 			const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1269 
1270 			for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1271 			{
1272 				findImplementations(pSubKeys[i], implNames);
1273 			}
1274 
1275 		}
1276 	}
1277 	catch(InvalidRegistryException&)
1278 	{
1279 	}
1280 }
1281 
1282 
1283 class ImplementationRegistration
1284 	: public WeakImplHelper3< XImplementationRegistration2, XServiceInfo, XInitialization >
1285 {
1286 public:
1287     ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
1288     ~ImplementationRegistration();
1289 
1290 	// XServiceInfo
1291 	OUString 						SAL_CALL getImplementationName() throw(RuntimeException);
1292     sal_Bool 						SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException);
1293     Sequence< OUString > 			SAL_CALL getSupportedServiceNames(void) throw(RuntimeException);
1294 
1295 	// XImplementationRegistration
1296     virtual void SAL_CALL registerImplementation(
1297 		const OUString& implementationLoader,
1298 		const OUString& location,
1299 		const Reference < XSimpleRegistry > & xReg)
1300 		throw(	CannotRegisterImplementationException, RuntimeException );
1301 
1302     virtual sal_Bool SAL_CALL revokeImplementation(
1303 		const OUString& location,
1304 		const Reference < XSimpleRegistry >& xReg)
1305 		throw( RuntimeException );
1306 
1307     virtual Sequence< OUString > SAL_CALL getImplementations(
1308 		const OUString& implementationLoader,
1309 		const OUString& location)
1310 		throw( RuntimeException );
1311     virtual Sequence< OUString > SAL_CALL checkInstantiation(
1312 		const OUString& implementationName)
1313 		throw( RuntimeException );
1314 
1315 	// XImplementationRegistration2
1316     virtual void SAL_CALL registerImplementationWithLocation(
1317 		const OUString& implementationLoader,
1318 		const OUString& location,
1319         const OUString& registeredLocation,
1320 		const Reference < XSimpleRegistry > & xReg)
1321 		throw(	CannotRegisterImplementationException, RuntimeException );
1322 
1323     // XInitialization
1324     virtual void SAL_CALL initialize(
1325 		const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
1326 		throw(	::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
1327 
1328 private: // helper methods
1329     void prepareRegister(
1330 		const OUString& implementationLoader,
1331 		const OUString& location,
1332         const OUString& registeredLocation,
1333 		const Reference < XSimpleRegistry > & xReg);
1334     // throw( CannotRegisterImplementationException, RuntimeException )
1335 
1336 	static void doRegister(	const Reference < XMultiComponentFactory >& xSMgr,
1337                             const Reference < XComponentContext > &xCtx,
1338                             const Reference < XImplementationLoader >& xAct,
1339                             const Reference < XSimpleRegistry >& xDest,
1340                             const OUString& implementationLoaderUrl,
1341                             const OUString& locationUrl,
1342                             const OUString& registeredLocationUrl);
1343         /* throw ( InvalidRegistryException,
1344                    MergeConflictException,
1345                    CannotRegisterImplementationException, RuntimeException ) */
1346 
1347     static void doRevoke( const Reference < XSimpleRegistry >& xDest,
1348                           const OUString& locationUrl );
1349         // throw( InvalidRegistryException, RuntimeException )
1350 	Reference< XSimpleRegistry > getRegistryFromServiceManager();
1351 
1352 	static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1353 		const Reference< XMultiComponentFactory > &rSMgr,
1354 		const Reference < XComponentContext > & rCtx );
1355 
1356 private: // members
1357 	Reference < XMultiComponentFactory >	m_xSMgr;
1358 	Reference < XComponentContext >         m_xCtx;
1359 };
1360 
1361 //*************************************************************************
1362 // ImplementationRegistration()
1363 //
ImplementationRegistration(const Reference<XComponentContext> & xCtx)1364 ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1365 	: m_xSMgr( xCtx->getServiceManager() )
1366 	, m_xCtx( xCtx )
1367 {
1368 	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
1369 }
1370 
1371 //*************************************************************************
1372 // ~ImplementationRegistration()
1373 //
~ImplementationRegistration()1374 ImplementationRegistration::~ImplementationRegistration()
1375 {
1376 	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1377 }
1378 
1379 
1380 // XServiceInfo
getImplementationName()1381 OUString ImplementationRegistration::getImplementationName() throw(RuntimeException)
1382 {
1383 	return stoc_bootstrap::impreg_getImplementationName();
1384 }
1385 
1386 // XServiceInfo
supportsService(const OUString & ServiceName)1387 sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw(RuntimeException)
1388 {
1389 	Sequence< OUString > aSNL = getSupportedServiceNames();
1390 	const OUString * pArray = aSNL.getConstArray();
1391 	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1392 		if( pArray[i] == ServiceName )
1393 			return sal_True;
1394 	return sal_False;
1395 }
1396 
1397 // XServiceInfo
getSupportedServiceNames(void)1398 Sequence< OUString > ImplementationRegistration::getSupportedServiceNames(void) throw(RuntimeException)
1399 {
1400 	return stoc_bootstrap::impreg_getSupportedServiceNames();
1401 }
1402 
getRegistryFromServiceManager()1403 Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
1404 {
1405 	Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1406 	Reference < XSimpleRegistry > xRegistry;
1407 
1408 	if( xPropSet.is() ) {
1409 
1410 		try {  // the implementation does not support XIntrospectionAccess !
1411 
1412 			Any aAny = xPropSet->getPropertyValue( spool().Registry );
1413 
1414 			if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )	{
1415 				aAny >>= xRegistry;
1416 			}
1417 	 	}
1418 	 	catch( UnknownPropertyException & ) {
1419 	 		// empty reference is error signal !
1420 		}
1421 	}
1422 
1423 	return xRegistry;
1424 }
1425 
1426 
1427 //************************************************************************
1428 // XInitialization
1429 //
initialize(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Any> & aArgs)1430 void ImplementationRegistration::initialize(
1431 	const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs )
1432 	throw(	::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1433 {
1434 
1435 	if( aArgs.getLength() != 4 ) {
1436         OUStringBuffer buf;
1437         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1438             "ImplementationRegistration::initialize() expects 4 parameters, got "));
1439         buf.append( (sal_Int32) aArgs.getLength() );
1440 		throw IllegalArgumentException( buf.makeStringAndClear(),
1441                                         Reference<XInterface > (),
1442                                         0 );
1443 	}
1444 
1445 	Reference< XImplementationLoader > rLoader;
1446 	OUString loaderServiceName;
1447 	OUString locationUrl;
1448 	Reference< XSimpleRegistry > rReg;
1449 
1450 	// 1st argument : An instance of an implementation loader
1451 	if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1452 		aArgs.getConstArray()[0] >>= rLoader;
1453 	}
1454 	if( !rLoader.is()) {
1455         OUStringBuffer buf;
1456         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1457             "ImplementationRegistration::initialize() invalid first parameter,"
1458             "expected " ) );
1459         buf.append( getCppuType( &rLoader ).getTypeName() );
1460         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", got " ) );
1461         buf.append( aArgs.getConstArray()[0].getValueTypeName() );
1462 		throw IllegalArgumentException( buf.makeStringAndClear(),
1463                                         Reference< XInterface > (),
1464                                         0 );
1465 	}
1466 
1467 	// 2nd argument : The service name of the loader. This name is written into the registry
1468 	if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1469 		aArgs.getConstArray()[1] >>= loaderServiceName;
1470 	}
1471 	if( ! loaderServiceName.getLength() ) {
1472         OUStringBuffer buf;
1473         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1474             "ImplementationRegistration::initialize() invalid second parameter,"
1475             "expected string, got " ) );
1476         buf.append( aArgs.getConstArray()[1].getValueTypeName() );
1477 		throw IllegalArgumentException( buf.makeStringAndClear(),
1478                                         Reference< XInterface > (),
1479                                         0 );
1480 	}
1481 
1482 	// 3rd argument : The file name of the dll, that contains the loader
1483 	if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1484 		aArgs.getConstArray()[2] >>= locationUrl;
1485 	}
1486 	if( ! locationUrl.getLength() ) {
1487         OUStringBuffer buf;
1488         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1489             "ImplementationRegistration::initialize() invalid third parameter,"
1490             "expected string, got " ) );
1491         buf.append( aArgs.getConstArray()[2].getValueTypeName() );
1492 		throw IllegalArgumentException( buf.makeStringAndClear(),
1493                                         Reference< XInterface > (),
1494                                         0 );
1495 	}
1496 
1497 	// 4th argument : The registry, the service should be written to
1498 	if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1499 		aArgs.getConstArray()[3] >>= rReg;
1500 	}
1501 
1502 	if( !rReg.is() ) {
1503 		rReg = getRegistryFromServiceManager();
1504 		if( !rReg.is() ) {
1505             OUStringBuffer buf;
1506             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1507                 "ImplementationRegistration::initialize() invalid fourth parameter,"
1508                 "expected " ));
1509             buf.append( getCppuType( &rReg ).getTypeName() );
1510             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", got " ) );
1511             buf.append( aArgs.getConstArray()[3].getValueTypeName() );
1512             throw IllegalArgumentException( buf.makeStringAndClear(),
1513                                             Reference< XInterface > (),
1514                                             0 );
1515 		}
1516 	}
1517 
1518 	doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1519 }
1520 
1521 
1522 
1523 //*************************************************************************
1524 // virtual function registerImplementationWithLocation of XImplementationRegistration2
1525 //
registerImplementationWithLocation(const OUString & implementationLoaderUrl,const OUString & locationUrl,const OUString & registeredLocationUrl,const Reference<XSimpleRegistry> & xReg)1526 void ImplementationRegistration::registerImplementationWithLocation(
1527 	const OUString& implementationLoaderUrl,
1528 	const OUString& locationUrl,
1529     const OUString& registeredLocationUrl,
1530 	const Reference < XSimpleRegistry > & xReg)
1531 	throw( CannotRegisterImplementationException, RuntimeException )
1532 {
1533     prepareRegister(
1534         implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1535 }
1536 
1537 // helper function
prepareRegister(const OUString & implementationLoaderUrl,const OUString & locationUrl,const OUString & registeredLocationUrl,const Reference<XSimpleRegistry> & xReg)1538 void ImplementationRegistration::prepareRegister(
1539 	const OUString& implementationLoaderUrl,
1540 	const OUString& locationUrl,
1541     const OUString& registeredLocationUrl,
1542 	const Reference < XSimpleRegistry > & xReg)
1543 	// throw( CannotRegisterImplementationException, RuntimeException )
1544 {
1545 	OUString implLoaderUrl(implementationLoaderUrl);
1546 	OUString activatorName;
1547 
1548 	if (implementationLoaderUrl.getLength() > 0)
1549 	{
1550 		OUString tmpActivator(implementationLoaderUrl);
1551         sal_Int32 nIndex = 0;
1552 		activatorName = tmpActivator.getToken(0, ':', nIndex );
1553 	} else
1554 	{
1555 		// check locationUrl to find out what kind of loader is needed
1556 		// set iimplLoaderUrl
1557 	}
1558 
1559 	if( m_xSMgr.is() ) {
1560         try
1561         {
1562             Reference < XImplementationLoader > xAct(
1563                 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1564             if (xAct.is())
1565             {
1566                 Reference < XSimpleRegistry > xRegistry;
1567 
1568                 if (xReg.is())
1569                 {
1570                     // registry supplied by user
1571                     xRegistry = xReg;
1572                 }
1573                 else
1574                 {
1575                     xRegistry = getRegistryFromServiceManager();
1576                 }
1577 
1578                 if ( xRegistry.is())
1579                 {
1580                     doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
1581                                locationUrl, registeredLocationUrl);
1582                 }
1583             }
1584             else
1585             {
1586                 OUStringBuffer buf( 128 );
1587                 buf.appendAscii( "ImplementationRegistration::registerImplementation() - The service " );
1588                 buf.append( activatorName );
1589                 buf.appendAscii( " cannot be instantiated\n" );
1590                 throw CannotRegisterImplementationException(
1591                     buf.makeStringAndClear(), Reference< XInterface > () );
1592             }
1593         }
1594         catch( CannotRegisterImplementationException & )
1595         {
1596             throw;
1597         }
1598         catch( InvalidRegistryException & e )
1599         {
1600             OUStringBuffer buf;
1601             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1602                 "ImplementationRegistration::registerImplementation() "
1603                 "InvalidRegistryException during registration (" ));
1604             buf.append( e.Message );
1605             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1606             throw CannotRegisterImplementationException(
1607                 buf.makeStringAndClear(), Reference< XInterface > () );
1608         }
1609         catch( MergeConflictException & e )
1610         {
1611             OUStringBuffer buf;
1612             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1613                 "ImplementationRegistration::registerImplementation() "
1614                 "MergeConflictException during registration (" ));
1615             buf.append( e.Message );
1616             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1617             throw CannotRegisterImplementationException(
1618                 buf.makeStringAndClear(), Reference< XInterface > () );
1619         }
1620 	}
1621 	else
1622     {
1623         throw CannotRegisterImplementationException(
1624             OUString(RTL_CONSTASCII_USTRINGPARAM(
1625                 "ImplementationRegistration::registerImplementation() "
1626                 "no componentcontext available to instantiate loader")),
1627             Reference< XInterface > () );
1628     }
1629 }
1630 
1631 //*************************************************************************
1632 // virtual function registerImplementation of XImplementationRegistration
1633 //
registerImplementation(const OUString & implementationLoaderUrl,const OUString & locationUrl,const Reference<XSimpleRegistry> & xReg)1634 void ImplementationRegistration::registerImplementation(
1635 	const OUString& implementationLoaderUrl,
1636 	const OUString& locationUrl,
1637 	const Reference < XSimpleRegistry > & xReg)
1638 	throw( CannotRegisterImplementationException, RuntimeException )
1639 {
1640     prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1641 }
1642 
1643 
1644 //*************************************************************************
1645 // virtual function revokeImplementation of XImplementationRegistration
1646 //
revokeImplementation(const OUString & location,const Reference<XSimpleRegistry> & xReg)1647 sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1648 													  const Reference < XSimpleRegistry >& xReg)
1649 	throw ( RuntimeException )
1650 {
1651 	sal_Bool ret = sal_False;
1652 
1653 	Reference < XSimpleRegistry > xRegistry;
1654 
1655 	if (xReg.is()) {
1656 		xRegistry = xReg;
1657 	}
1658 	else {
1659 		Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr );
1660 		if( xPropSet.is() ) {
1661 			try {
1662 				Any aAny = xPropSet->getPropertyValue( spool().Registry );
1663 
1664 				if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1665 				{
1666 					aAny >>= xRegistry;
1667 				}
1668 			}
1669 			catch ( UnknownPropertyException & ) {
1670 			}
1671 		}
1672 	}
1673 
1674 	if (xRegistry.is())
1675 	{
1676         try
1677         {
1678             doRevoke(xRegistry, location);
1679             ret = sal_True;
1680         }
1681         catch( InvalidRegistryException & )
1682         {
1683             // no way to transport the error, as no exception is specified and a runtime
1684             // exception is not appropriate.
1685             OSL_ENSURE( 0 , "InvalidRegistryException during revokeImplementation" );
1686         }
1687 	}
1688 
1689 	return ret;
1690 }
1691 
1692 //*************************************************************************
1693 // virtual function getImplementations of XImplementationRegistration
1694 //
getImplementations(const OUString & implementationLoaderUrl,const OUString & locationUrl)1695 Sequence< OUString > ImplementationRegistration::getImplementations(
1696 	const OUString & implementationLoaderUrl,
1697 	const OUString & locationUrl)
1698 	throw ( RuntimeException )
1699 {
1700 	OUString implLoaderUrl(implementationLoaderUrl);
1701 	OUString activatorName;
1702 
1703 	if (implementationLoaderUrl.getLength() > 0)
1704 	{
1705 		OUString tmpActivator(implementationLoaderUrl);
1706         sal_Int32 nIndex = 0;
1707 		activatorName = tmpActivator.getToken(0, ':', nIndex );
1708 	} else
1709 	{
1710 		// check locationUrl to find out what kind of loader is needed
1711 		// set implLoaderUrl
1712 	}
1713 
1714 	if( m_xSMgr.is() ) {
1715 
1716 		Reference < XImplementationLoader > xAct(
1717 			m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1718 
1719 		if (xAct.is())
1720 		{
1721 
1722 			Reference < XSimpleRegistry > xReg =
1723 				createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1724 
1725 			if (xReg.is())
1726 			{
1727 				try
1728 				{
1729 					xReg->open(OUString() /* in mem */, sal_False, sal_True);
1730 					Reference < XRegistryKey > xImpl;
1731 
1732 					{ // only necessary	for deleting the temporary variable of rootkey
1733 						xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1734 					}
1735 					if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1736 					{
1737 						std::list <OUString> implNames;
1738 
1739 						findImplementations(xImpl, implNames);
1740 
1741 						if (!implNames.empty())
1742 						{
1743 							std::list<OUString>::const_iterator iter = implNames.begin();
1744 
1745 							Sequence<OUString> seqImpl(implNames.size());
1746 							OUString *pImplNames = seqImpl.getArray();
1747 
1748 							sal_Int32 index = 0;
1749 							while (iter != implNames.end())
1750 							{
1751 								pImplNames[index] = *iter;
1752 								index++;
1753 								++iter;
1754 							}
1755 
1756 							xImpl->closeKey();
1757 							return seqImpl;
1758 						}
1759 					}
1760 
1761 					xImpl->closeKey();
1762 				}
1763 				catch(MergeConflictException&)
1764 				{
1765 				}
1766 				catch(InvalidRegistryException&)
1767 				{
1768 				}
1769 			}
1770 		}
1771 	}
1772 
1773 	return Sequence<OUString>();
1774 }
1775 
1776 //*************************************************************************
1777 // virtual function checkInstantiation of XImplementationRegistration
1778 //
checkInstantiation(const OUString &)1779 Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1780 	throw ( RuntimeException )
1781 {
1782 	OSL_ENSURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" );
1783 	return Sequence<OUString>();
1784 }
1785 
1786 //*************************************************************************
1787 // helper function doRegistration
1788 //
1789 
doRevoke(const Reference<XSimpleRegistry> & xDest,const OUString & locationUrl)1790 void ImplementationRegistration::doRevoke(
1791 	const Reference < XSimpleRegistry >& xDest,
1792 	const OUString& locationUrl)
1793     // throw ( InvalidRegistryException, RuntimeException )
1794 {
1795     if( xDest.is() )
1796     {
1797         std::list<OUString> aNames;
1798 
1799         const StringPool &pool = spool();
1800         Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1801 
1802         Reference < XRegistryKey > xKey =
1803             xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
1804         if (xKey.is() && xKey->isValid())
1805         {
1806             deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1807         }
1808 
1809         xKey = xRootKey->openKey( pool.slash_SERVICES );
1810         if (xKey.is())
1811         {
1812             std::list<OUString>::const_iterator iter = aNames.begin();
1813 
1814             while (iter != aNames.end())
1815             {
1816                 deleteAllServiceEntries(xDest, xKey, *iter);
1817                 ++iter;
1818             }
1819         }
1820 
1821         xKey = xRootKey->openKey( OUSTR("/SINGLETONS") );
1822         if (xKey.is() && xKey->isValid())
1823         {
1824             delete_all_singleton_entries( xKey, aNames );
1825         }
1826 
1827         if (xRootKey.is())
1828             xRootKey->closeKey();
1829         if (xKey.is() && xKey->isValid() )
1830             xKey->closeKey();
1831     }
1832 }
1833 
doRegister(const Reference<XMultiComponentFactory> & xSMgr,const Reference<XComponentContext> & xCtx,const Reference<XImplementationLoader> & xAct,const Reference<XSimpleRegistry> & xDest,const OUString & implementationLoaderUrl,const OUString & locationUrl,const OUString & registeredLocationUrl)1834 void ImplementationRegistration::doRegister(
1835 	const Reference< XMultiComponentFactory > & xSMgr,
1836 	const Reference< XComponentContext > &xCtx,
1837 	const Reference < XImplementationLoader > & xAct,
1838 	const Reference < XSimpleRegistry >& xDest,
1839 	const OUString& implementationLoaderUrl,
1840 	const OUString& locationUrl,
1841     const OUString& registeredLocationUrl)
1842     /* throw ( InvalidRegistryException,
1843                MergeConflictException,
1844                CannotRegisterImplementationException, RuntimeException ) */
1845 {
1846     Reference < XSimpleRegistry > 	xReg =
1847         createTemporarySimpleRegistry( xSMgr, xCtx );
1848     Reference < XRegistryKey > 		xSourceKey;
1849 
1850     if (xAct.is() && xReg.is() && xDest.is())
1851     {
1852         try
1853         {
1854             xReg->open(OUString() /* in mem */, sal_False, sal_True);
1855 
1856             { // only necessary	for deleting the temporary variable of rootkey
1857                 xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1858             }
1859 
1860             sal_Bool bSuccess =
1861                 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1862             if ( bSuccess )
1863             {
1864                 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1865 
1866                 xSourceKey->closeKey();
1867 
1868                 xSourceKey = xReg->getRootKey();
1869                 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1870                 mergeKeys( xDestKey, xSourceKey );
1871                 xDestKey->closeKey();
1872                 xSourceKey->closeKey();
1873             }
1874             else
1875             {
1876                 throw CannotRegisterImplementationException(
1877                     OUString( RTL_CONSTASCII_USTRINGPARAM( "ImplementationRegistration::doRegistration() component registration signaled failure" ) ),
1878                     Reference< XInterface > () );
1879             }
1880 
1881             // Cleanup Source registry.
1882             if ( xSourceKey->isValid() )
1883                 xSourceKey->closeKey();
1884         }
1885         catch(CannotRegisterImplementationException&)
1886         {
1887             if ( xSourceKey->isValid() )
1888                 xSourceKey->closeKey();
1889             // and throw again
1890             throw;
1891         }
1892     }
1893 }
1894 
1895 
1896 
createTemporarySimpleRegistry(const Reference<XMultiComponentFactory> & rSMgr,const Reference<XComponentContext> & xCtx)1897 Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1898 	const Reference< XMultiComponentFactory > &rSMgr,
1899 	const Reference < XComponentContext > & xCtx)
1900 {
1901 
1902 	Reference < XSimpleRegistry > xReg(
1903 		rSMgr->createInstanceWithContext(
1904 			spool().com_sun_star_registry_SimpleRegistry,	xCtx ),
1905         UNO_QUERY);
1906 	OSL_ASSERT( xReg.is() );
1907 	return xReg;
1908 }
1909 }
1910 
1911 namespace stoc_bootstrap
1912 {
1913 //*************************************************************************
ImplementationRegistration_CreateInstance(const Reference<XComponentContext> & xCtx)1914 Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance(
1915     const Reference<XComponentContext> & xCtx ) // throw(Exception)
1916 {
1917 	return (XImplementationRegistration *)new stoc_impreg::ImplementationRegistration(xCtx);
1918 }
1919 
1920 }
1921 
1922