xref: /aoo41x/main/registry/source/regimpl.cxx (revision 24c56ab9)
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_registry.hxx"
26 
27 #include    "regimpl.hxx"
28 
29 #include <memory>
30 #include    <string.h>
31 #include	<stdio.h>
32 
33 #if defined(UNX) || defined(OS2)
34 #include    <unistd.h>
35 #endif
36 #ifdef __MINGW32__
37 #include    <unistd.h>
38 #endif
39 
40 #ifndef __REGISTRY_REFLREAD_HXX__
41 #include    <registry/reflread.hxx>
42 #endif
43 
44 #ifndef __REGISTRY_REFLWRIT_HXX__
45 #include    <registry/reflwrit.hxx>
46 #endif
47 
48 #include "registry/reader.hxx"
49 #include "registry/refltype.hxx"
50 #include "registry/types.h"
51 #include "registry/version.h"
52 
53 #include    "reflcnst.hxx"
54 #include    "keyimpl.hxx"
55 
56 #include    <osl/thread.h>
57 #include    <rtl/alloc.h>
58 #include    <rtl/memory.h>
59 #include    <rtl/ustring.hxx>
60 #include    <rtl/ustrbuf.hxx>
61 #include    <osl/file.hxx>
62 
63 using namespace rtl;
64 using namespace osl;
65 using namespace store;
66 
67 #if defined ( GCC ) && ( defined ( SCO ) )
68 sal_helper::ORealDynamicLoader* sal_helper::ODynamicLoader<RegistryTypeReader_Api>::m_pLoader = NULL;
69 #endif
70 
71 namespace {
72 
printString(rtl::OUString const & s)73 void printString(rtl::OUString const & s) {
74     printf("\"");
75     for (sal_Int32 i = 0; i < s.getLength(); ++i) {
76         sal_Unicode c = s[i];
77         if (c == '"' || c == '\\') {
78             printf("\\%c", static_cast< char >(c));
79         } else if (s[i] >= ' ' && s[i] <= '~') {
80             printf("%c", static_cast< char >(c));
81         } else {
82             printf("\\u%04X", static_cast< unsigned int >(c));
83         }
84     }
85     printf("\"");
86 }
87 
printFieldOrReferenceFlag(RTFieldAccess * flags,RTFieldAccess flag,char const * name,bool * first)88 void printFieldOrReferenceFlag(
89     RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first)
90 {
91     if ((*flags & flag) != 0) {
92         if (!*first) {
93             printf("|");
94         }
95         *first = false;
96         printf("%s", name);
97         *flags &= ~flag;
98     }
99 }
100 
printFieldOrReferenceFlags(RTFieldAccess flags)101 void printFieldOrReferenceFlags(RTFieldAccess flags) {
102     if (flags == 0) {
103         printf("none");
104     } else {
105         bool first = true;
106         printFieldOrReferenceFlag(
107             &flags, RT_ACCESS_READONLY, "readonly", &first);
108         printFieldOrReferenceFlag(
109             &flags, RT_ACCESS_OPTIONAL, "optional", &first);
110         printFieldOrReferenceFlag(
111             &flags, RT_ACCESS_MAYBEVOID, "maybevoid", &first);
112         printFieldOrReferenceFlag(&flags, RT_ACCESS_BOUND, "bound", &first);
113         printFieldOrReferenceFlag(
114             &flags, RT_ACCESS_CONSTRAINED, "constrained", &first);
115         printFieldOrReferenceFlag(
116             &flags, RT_ACCESS_TRANSIENT, "transient", &first);
117         printFieldOrReferenceFlag(
118             &flags, RT_ACCESS_MAYBEAMBIGUOUS, "maybeambiguous", &first);
119         printFieldOrReferenceFlag(
120             &flags, RT_ACCESS_MAYBEDEFAULT, "maybedefault", &first);
121         printFieldOrReferenceFlag(
122             &flags, RT_ACCESS_REMOVEABLE, "removeable", &first);
123         printFieldOrReferenceFlag(
124             &flags, RT_ACCESS_ATTRIBUTE, "attribute", &first);
125         printFieldOrReferenceFlag(
126             &flags, RT_ACCESS_PROPERTY, "property", &first);
127         printFieldOrReferenceFlag(&flags, RT_ACCESS_CONST, "const", &first);
128         printFieldOrReferenceFlag(
129             &flags, RT_ACCESS_READWRITE, "readwrite", &first);
130         printFieldOrReferenceFlag(
131             &flags, RT_ACCESS_PARAMETERIZED_TYPE, "parameterized type", &first);
132         printFieldOrReferenceFlag(
133             &flags, RT_ACCESS_PUBLISHED, "published", &first);
134         if (flags != 0) {
135             if (!first) {
136                 printf("|");
137             }
138             printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags));
139         }
140     }
141 }
142 
dumpType(typereg::Reader const & reader,rtl::OString const & indent)143 void dumpType(typereg::Reader const & reader, rtl::OString const & indent) {
144     if (reader.isValid()) {
145         printf("version: %ld\n", static_cast< long >(reader.getVersion()));
146         printf("%sdocumentation: ", indent.getStr());
147         printString(reader.getDocumentation());
148         printf("\n");
149         printf("%sfile name: ", indent.getStr());
150         printString(reader.getFileName());
151         printf("\n");
152         printf("%stype class: ", indent.getStr());
153         if (reader.isPublished()) {
154             printf("published ");
155         }
156         switch (reader.getTypeClass()) {
157         case RT_TYPE_INTERFACE:
158             printf("interface");
159             break;
160 
161         case RT_TYPE_MODULE:
162             printf("module");
163             break;
164 
165         case RT_TYPE_STRUCT:
166             printf("struct");
167             break;
168 
169         case RT_TYPE_ENUM:
170             printf("enum");
171             break;
172 
173         case RT_TYPE_EXCEPTION:
174             printf("exception");
175             break;
176 
177         case RT_TYPE_TYPEDEF:
178             printf("typedef");
179             break;
180 
181         case RT_TYPE_SERVICE:
182             printf("service");
183             break;
184 
185         case RT_TYPE_SINGLETON:
186             printf("singleton");
187             break;
188 
189         case RT_TYPE_CONSTANTS:
190             printf("constants");
191             break;
192 
193         default:
194             printf(
195                 "<invalid (%ld)>", static_cast< long >(reader.getTypeClass()));
196             break;
197         }
198         printf("\n");
199         printf("%stype name: ", indent.getStr());
200         printString(reader.getTypeName());
201         printf("\n");
202         printf(
203             "%ssuper type count: %u\n", indent.getStr(),
204             static_cast< unsigned int >(reader.getSuperTypeCount()));
205         {for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
206             printf(
207                 "%ssuper type name %u: ", indent.getStr(),
208                 static_cast< unsigned int >(i));
209             printString(reader.getSuperTypeName(i));
210             printf("\n");
211         }}
212         printf(
213             "%sfield count: %u\n", indent.getStr(),
214             static_cast< unsigned int >(reader.getFieldCount()));
215         {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
216             printf(
217                 "%sfield %u:\n", indent.getStr(),
218                 static_cast< unsigned int >(i));
219             printf("%s    documentation: ", indent.getStr());
220             printString(reader.getFieldDocumentation(i));
221             printf("\n");
222             printf("%s    file name: ", indent.getStr());
223             printString(reader.getFieldFileName(i));
224             printf("\n");
225             printf("%s    flags: ", indent.getStr());
226             printFieldOrReferenceFlags(reader.getFieldFlags(i));
227             printf("\n");
228             printf("%s    name: ", indent.getStr());
229             printString(reader.getFieldName(i));
230             printf("\n");
231             printf("%s    type name: ", indent.getStr());
232             printString(reader.getFieldTypeName(i));
233             printf("\n");
234             printf("%s    value: ", indent.getStr());
235             RTConstValue value(reader.getFieldValue(i));
236             switch (value.m_type) {
237             case RT_TYPE_NONE:
238                 printf("none");
239                 break;
240 
241             case RT_TYPE_BOOL:
242                 printf("boolean %s", value.m_value.aBool ? "true" : "false");
243                 break;
244 
245             case RT_TYPE_BYTE:
246                 printf(
247                     "byte 0x%02X",
248                     static_cast< unsigned int >(value.m_value.aByte));
249                 break;
250 
251             case RT_TYPE_INT16:
252                 printf("short %d", static_cast< int >(value.m_value.aShort));
253                 break;
254 
255             case RT_TYPE_UINT16:
256                 printf(
257                     "unsigned short %u",
258                     static_cast< unsigned int >(value.m_value.aUShort));
259                 break;
260 
261             case RT_TYPE_INT32:
262                 printf("long %ld", static_cast< long >(value.m_value.aLong));
263                 break;
264 
265             case RT_TYPE_UINT32:
266                 printf(
267                     "unsigned long %lu",
268                     static_cast< unsigned long >(value.m_value.aULong));
269                 break;
270 
271             case RT_TYPE_INT64:
272                 // TODO: no portable way to print hyper values
273                 printf("hyper");
274                 break;
275 
276             case RT_TYPE_UINT64:
277                 // TODO: no portable way to print unsigned hyper values
278                 printf("unsigned hyper");
279                 break;
280 
281             case RT_TYPE_FLOAT:
282                 // TODO: no portable way to print float values
283                 printf("float");
284                 break;
285 
286             case RT_TYPE_DOUBLE:
287                 // TODO: no portable way to print double values
288                 printf("double");
289                 break;
290 
291             case RT_TYPE_STRING:
292                 printf("string ");
293                 printString(value.m_value.aString);
294                 break;
295 
296             default:
297                 printf("<invalid (%ld)>", static_cast< long >(value.m_type));
298                 break;
299             }
300             printf("\n");
301         }}
302         printf(
303             "%smethod count: %u\n", indent.getStr(),
304             static_cast< unsigned int >(reader.getMethodCount()));
305         {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
306             printf(
307                 "%smethod %u:\n", indent.getStr(),
308                 static_cast< unsigned int >(i));
309             printf("%s    documentation: ", indent.getStr());
310             printString(reader.getMethodDocumentation(i));
311             printf("\n");
312             printf("%s    flags: ", indent.getStr());
313             switch (reader.getMethodFlags(i)) {
314             case RT_MODE_ONEWAY:
315                 printf("oneway");
316                 break;
317 
318             case RT_MODE_TWOWAY:
319                 printf("synchronous");
320                 break;
321 
322             case RT_MODE_ATTRIBUTE_GET:
323                 printf("attribute get");
324                 break;
325 
326             case RT_MODE_ATTRIBUTE_SET:
327                 printf("attribute set");
328                 break;
329 
330             default:
331                 printf(
332                     "<invalid (%ld)>",
333                     static_cast< long >(reader.getMethodFlags(i)));
334                 break;
335             }
336             printf("\n");
337             printf("%s    name: ", indent.getStr());
338             printString(reader.getMethodName(i));
339             printf("\n");
340             printf("%s    return type name: ", indent.getStr());
341             printString(reader.getMethodReturnTypeName(i));
342             printf("\n");
343             printf(
344                 "%s    parameter count: %u\n", indent.getStr(),
345                 static_cast< unsigned int >(reader.getMethodParameterCount(i)));
346             for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j)
347             {
348                 printf(
349                     "%s    parameter %u:\n", indent.getStr(),
350                     static_cast< unsigned int >(j));
351                 printf("%s        flags: ", indent.getStr());
352                 RTParamMode flags = reader.getMethodParameterFlags(i, j);
353                 bool rest = (flags & RT_PARAM_REST) != 0;
354                 switch (flags & ~RT_PARAM_REST) {
355                 case RT_PARAM_IN:
356                     printf("in");
357                     break;
358 
359                 case RT_PARAM_OUT:
360                     printf("out");
361                     break;
362 
363                 case RT_PARAM_INOUT:
364                     printf("inout");
365                     break;
366 
367                 default:
368                     printf("<invalid (%ld)>", static_cast< long >(flags));
369                     rest = false;
370                     break;
371                 }
372                 if (rest) {
373                     printf("|rest");
374                 }
375                 printf("\n");
376                 printf("%s        name: ", indent.getStr());
377                 printString(reader.getMethodParameterName(i, j));
378                 printf("\n");
379                 printf("%s        type name: ", indent.getStr());
380                 printString(reader.getMethodParameterTypeName(i, j));
381                 printf("\n");
382             }
383             printf(
384                 "%s    exception count: %u\n", indent.getStr(),
385                 static_cast< unsigned int >(reader.getMethodExceptionCount(i)));
386             for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j)
387             {
388                 printf(
389                     "%s    exception type name %u: ", indent.getStr(),
390                     static_cast< unsigned int >(j));
391                 printString(reader.getMethodExceptionTypeName(i, j));
392                 printf("\n");
393             }
394         }}
395         printf(
396             "%sreference count: %u\n", indent.getStr(),
397             static_cast< unsigned int >(reader.getReferenceCount()));
398         {for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) {
399             printf(
400                 "%sreference %u:\n", indent.getStr(),
401                 static_cast< unsigned int >(i));
402             printf("%s    documentation: ", indent.getStr());
403             printString(reader.getReferenceDocumentation(i));
404             printf("\n");
405             printf("%s    flags: ", indent.getStr());
406             printFieldOrReferenceFlags(reader.getReferenceFlags(i));
407             printf("\n");
408             printf("%s    sort: ", indent.getStr());
409             switch (reader.getReferenceSort(i)) {
410             case RT_REF_SUPPORTS:
411                 printf("supports");
412                 break;
413 
414             case RT_REF_EXPORTS:
415                 printf("exports");
416                 break;
417 
418             case RT_REF_TYPE_PARAMETER:
419                 printf("type parameter");
420                 break;
421 
422             default:
423                 printf(
424                     "<invalid (%ld)>",
425                     static_cast< long >(reader.getReferenceSort(i)));
426                 break;
427             }
428             printf("\n");
429             printf("%s    type name: ", indent.getStr());
430             printString(reader.getReferenceTypeName(i));
431             printf("\n");
432         }}
433     } else {
434         printf("<invalid>\n");
435     }
436 }
437 
438 }
439 
440 //*********************************************************************
441 //  ORegistry()
442 //
ORegistry()443 ORegistry::ORegistry()
444     : m_refCount(1)
445     , m_readOnly(sal_False)
446     , m_isOpen(sal_False)
447 	, ROOT( RTL_CONSTASCII_USTRINGPARAM("/") )
448 {
449 }
450 
451 //*********************************************************************
452 //  ~ORegistry()
453 //
~ORegistry()454 ORegistry::~ORegistry()
455 {
456 	ORegKey* pRootKey = m_openKeyTable[ROOT];
457 	if (pRootKey != 0)
458 		(void) releaseKey(pRootKey);
459 
460     if (m_file.isValid())
461         m_file.close();
462 }
463 
464 
465 //*********************************************************************
466 //  initRegistry
467 //
initRegistry(const OUString & regName,RegAccessMode accessMode)468 RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode)
469 {
470     OStoreFile      rRegFile;
471     storeAccessMode sAccessMode = REG_MODE_OPEN;
472     storeError      errCode;
473 
474     if (accessMode & REG_CREATE)
475     {
476         sAccessMode = REG_MODE_CREATE;
477     } else
478     if (accessMode & REG_READONLY)
479     {
480         sAccessMode = REG_MODE_OPENREAD;
481         m_readOnly = sal_True;
482     }
483 
484     if (0 == regName.getLength() &&
485         store_AccessCreate == sAccessMode)
486     {
487         errCode = rRegFile.createInMemory();
488     }
489     else
490     {
491         errCode = rRegFile.create(regName, sAccessMode, REG_PAGESIZE);
492     }
493 
494     if (errCode)
495     {
496         switch (errCode)
497         {
498             case  store_E_NotExists:
499                 return REG_REGISTRY_NOT_EXISTS;
500             case store_E_LockingViolation:
501                 return REG_CANNOT_OPEN_FOR_READWRITE;
502             default:
503                 return REG_INVALID_REGISTRY;
504         }
505     } else
506     {
507         OStoreDirectory rStoreDir;
508         storeError      _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode);
509 
510         if ( _err == store_E_None )
511         {
512             m_file = rRegFile;
513             m_name = regName;
514             m_isOpen = sal_True;
515 
516             m_openKeyTable[ROOT] = new ORegKey(ROOT, this);
517             return REG_NO_ERROR;
518         } else
519             return REG_INVALID_REGISTRY;
520     }
521 }
522 
523 
524 //*********************************************************************
525 //  closeRegistry
526 //
closeRegistry()527 RegError ORegistry::closeRegistry()
528 {
529     REG_GUARD(m_mutex);
530 
531     if (m_file.isValid())
532     {
533         (void) releaseKey(m_openKeyTable[ROOT]);
534         m_file.close();
535         m_isOpen = sal_False;
536         return REG_NO_ERROR;
537     } else
538     {
539         return REG_REGISTRY_NOT_EXISTS;
540     }
541 }
542 
543 
544 //*********************************************************************
545 //  destroyRegistry
546 //
destroyRegistry(const OUString & regName)547 RegError ORegistry::destroyRegistry(const OUString& regName)
548 {
549     REG_GUARD(m_mutex);
550 
551     if (regName.getLength())
552     {
553         ORegistry* pReg = new ORegistry();
554 
555         if (!pReg->initRegistry(regName, REG_READWRITE))
556         {
557             delete pReg;
558 
559 			OUString systemName;
560 			if ( FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None )
561 				systemName = regName;
562 
563 			OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
564             if( unlink( name.getStr()) != 0)
565             {
566                 return REG_DESTROY_REGISTRY_FAILED;
567             }
568         } else
569         {
570             return REG_DESTROY_REGISTRY_FAILED;
571         }
572     } else
573     {
574         if (m_refCount != 1 || isReadOnly())
575         {
576             return REG_DESTROY_REGISTRY_FAILED;
577         }
578 
579         if (m_file.isValid())
580         {
581             releaseKey(m_openKeyTable[ROOT]);
582             m_file.close();
583             m_isOpen = sal_False;
584 
585             if (m_name.getLength())
586             {
587                 OUString systemName;
588                 if ( FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None )
589                     systemName = m_name;
590 
591                 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
592                 if (unlink(name.getStr()) != 0)
593                 {
594                     return REG_DESTROY_REGISTRY_FAILED;
595                 }
596             }
597         } else
598         {
599             return REG_REGISTRY_NOT_EXISTS;
600         }
601     }
602 
603     return REG_NO_ERROR;
604 }
605 
606 //*********************************************************************
607 //  acquireKey
608 //
acquireKey(RegKeyHandle hKey)609 RegError ORegistry::acquireKey (RegKeyHandle hKey)
610 {
611 	ORegKey* pKey = static_cast< ORegKey* >(hKey);
612 	if (!pKey)
613 		return REG_INVALID_KEY;
614 
615 	REG_GUARD(m_mutex);
616 	pKey->acquire();
617 
618 	return REG_NO_ERROR;
619 }
620 
621 //*********************************************************************
622 //  releaseKey
623 //
releaseKey(RegKeyHandle hKey)624 RegError ORegistry::releaseKey (RegKeyHandle hKey)
625 {
626 	ORegKey* pKey = static_cast< ORegKey* >(hKey);
627 	if (!pKey)
628 		return REG_INVALID_KEY;
629 
630 	REG_GUARD(m_mutex);
631 	if (pKey->release() == 0)
632 	{
633 		m_openKeyTable.erase(pKey->getName());
634 		delete pKey;
635 	}
636 	return REG_NO_ERROR;
637 }
638 
639 //*********************************************************************
640 //  createKey
641 //
createKey(RegKeyHandle hKey,const OUString & keyName,RegKeyHandle * phNewKey)642 RegError ORegistry::createKey(RegKeyHandle hKey, const OUString& keyName,
643                               RegKeyHandle* phNewKey)
644 {
645     ORegKey*    pKey;
646 
647     *phNewKey = NULL;
648 
649     if ( !keyName.getLength() )
650         return REG_INVALID_KEYNAME;
651 
652     REG_GUARD(m_mutex);
653 
654     if (hKey)
655         pKey = (ORegKey*)hKey;
656     else
657         pKey = m_openKeyTable[ROOT];
658 
659     OUString sFullKeyName = pKey->getFullPath(keyName);
660 
661     if (m_openKeyTable.count(sFullKeyName) > 0)
662     {
663         *phNewKey = m_openKeyTable[sFullKeyName];
664         ((ORegKey*)*phNewKey)->acquire();
665         ((ORegKey*)*phNewKey)->setDeleted(sal_False);
666         return REG_NO_ERROR;
667     }
668 
669     OStoreDirectory rStoreDir;
670     OUStringBuffer  sFullPath(sFullKeyName.getLength());
671     OUString        token;
672 
673     sFullPath.append((sal_Unicode)'/');
674 
675     sal_Int32 nIndex = 0;
676     do
677     {
678         token = sFullKeyName.getToken( 0, '/', nIndex );
679         if (token.getLength())
680         {
681             if (rStoreDir.create(pKey->getStoreFile(), sFullPath.getStr(), token, KEY_MODE_CREATE))
682             {
683                 return REG_CREATE_KEY_FAILED;
684             }
685 
686             sFullPath.append(token);
687             sFullPath.append((sal_Unicode)'/');
688         }
689     } while( nIndex != -1 );
690 
691 
692     pKey = new ORegKey(sFullKeyName, this);
693     *phNewKey = pKey;
694     m_openKeyTable[sFullKeyName] = pKey;
695 
696     return REG_NO_ERROR;
697 }
698 
699 
700 //*********************************************************************
701 //  openKey
702 //
openKey(RegKeyHandle hKey,const OUString & keyName,RegKeyHandle * phOpenKey)703 RegError ORegistry::openKey(RegKeyHandle hKey, const OUString& keyName,
704                             RegKeyHandle* phOpenKey)
705 {
706     ORegKey*        pKey;
707 
708     *phOpenKey = NULL;
709 
710     if ( !keyName.getLength() )
711     {
712         return REG_INVALID_KEYNAME;
713     }
714 
715     REG_GUARD(m_mutex);
716 
717     if (hKey)
718         pKey = (ORegKey*)hKey;
719     else
720         pKey = m_openKeyTable[ROOT];
721 
722     OUString path(pKey->getFullPath(keyName));
723     KeyMap::iterator i(m_openKeyTable.find(path));
724     if (i == m_openKeyTable.end()) {
725         sal_Int32 n = path.lastIndexOf('/') + 1;
726         switch (OStoreDirectory().create(
727                     pKey->getStoreFile(), path.copy(0, n), path.copy(n),
728                     isReadOnly() ? KEY_MODE_OPENREAD : KEY_MODE_OPEN))
729         {
730         case store_E_NotExists:
731             return REG_KEY_NOT_EXISTS;
732         case store_E_WrongFormat:
733             return REG_INVALID_KEY;
734         default:
735             break;
736         }
737 
738         std::auto_ptr< ORegKey > p(new ORegKey(path, this));
739         i = m_openKeyTable.insert(std::make_pair(path, p.get())).first;
740         p.release();
741     } else {
742         i->second->acquire();
743     }
744     *phOpenKey = i->second;
745     return REG_NO_ERROR;
746 }
747 
748 
749 //*********************************************************************
750 //  closeKey
751 //
closeKey(RegKeyHandle hKey)752 RegError ORegistry::closeKey(RegKeyHandle hKey)
753 {
754     ORegKey* pKey = static_cast< ORegKey* >(hKey);
755 
756     REG_GUARD(m_mutex);
757 
758 	OUString const aKeyName (pKey->getName());
759     if (!(m_openKeyTable.count(aKeyName) > 0))
760         return REG_KEY_NOT_OPEN;
761 
762 	if (pKey->isModified())
763 	{
764 		ORegKey * pRootKey = getRootKey();
765 		if (pKey != pRootKey)
766 		{
767 			// propagate "modified" state to RootKey.
768 			pRootKey->setModified();
769 		}
770 		else
771 		{
772 			// closing modified RootKey, flush registry file.
773 			OSL_TRACE("registry::ORegistry::closeKey(): flushing modified RootKey");
774 			(void) m_file.flush();
775 		}
776 		pKey->setModified(false);
777 		(void) releaseKey(pRootKey);
778 	}
779 
780 	return releaseKey(pKey);
781 }
782 
783 //*********************************************************************
784 //  deleteKey
785 //
deleteKey(RegKeyHandle hKey,const OUString & keyName)786 RegError ORegistry::deleteKey(RegKeyHandle hKey, const OUString& keyName)
787 {
788     ORegKey* pKey = static_cast< ORegKey* >(hKey);
789     if ( !keyName.getLength() )
790         return REG_INVALID_KEYNAME;
791 
792     REG_GUARD(m_mutex);
793 
794 	if (!pKey)
795 		pKey = m_openKeyTable[ROOT];
796 
797     OUString sFullKeyName(pKey->getFullPath(keyName));
798     return eraseKey(m_openKeyTable[ROOT], sFullKeyName);
799 }
800 
eraseKey(ORegKey * pKey,const OUString & keyName)801 RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName)
802 {
803     RegError _ret = REG_NO_ERROR;
804 
805     if ( !keyName.getLength() )
806     {
807         return REG_INVALID_KEYNAME;
808     }
809 
810     OUString     sFullKeyName(pKey->getName());
811     OUString     sFullPath(sFullKeyName);
812     OUString     sRelativKey;
813     sal_Int32	 lastIndex = keyName.lastIndexOf('/');
814 
815     if ( lastIndex >= 0 )
816     {
817         sRelativKey += keyName.copy(lastIndex + 1);
818 
819         if (sFullKeyName.getLength() > 1)
820             sFullKeyName += keyName;
821         else
822             sFullKeyName += keyName.getStr() + 1;
823 
824         sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1);
825     } else
826     {
827         if (sFullKeyName.getLength() > 1)
828             sFullKeyName += ROOT;
829 
830         sRelativKey += keyName;
831         sFullKeyName += keyName;
832 
833         if (sFullPath.getLength() > 1)
834             sFullPath += ROOT;
835     }
836 
837     ORegKey* pOldKey = 0;
838     _ret = pKey->openKey(keyName, (RegKeyHandle*)&pOldKey);
839     if (_ret != REG_NO_ERROR)
840         return _ret;
841 
842     _ret = deleteSubkeysAndValues(pOldKey);
843     if (_ret != REG_NO_ERROR)
844     {
845         pKey->closeKey(pOldKey);
846         return _ret;
847     }
848 
849     OUString tmpName(sRelativKey);
850     tmpName += ROOT;
851 
852     OStoreFile sFile(pKey->getStoreFile());
853     if ( sFile.isValid() && sFile.remove(sFullPath, tmpName) )
854     {
855         return REG_DELETE_KEY_FAILED;
856     }
857 	pOldKey->setModified();
858 
859     // set flag deleted !!!
860     pOldKey->setDeleted(sal_True);
861 
862     return pKey->closeKey(pOldKey);
863 }
864 
865 //*********************************************************************
866 //  deleteSubKeysAndValues
867 //
deleteSubkeysAndValues(ORegKey * pKey)868 RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey)
869 {
870     OStoreDirectory::iterator   iter;
871     RegError                    _ret = REG_NO_ERROR;
872     OStoreDirectory             rStoreDir(pKey->getStoreDir());
873     storeError                  _err = rStoreDir.first(iter);
874 
875     while ( _err == store_E_None )
876     {
877         OUString const keyName = iter.m_pszName;
878 
879         if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
880         {
881             _ret = eraseKey(pKey, keyName);
882             if (_ret)
883                 return _ret;
884         }
885 		else
886         {
887             OUString sFullPath(pKey->getName());
888 
889             if (sFullPath.getLength() > 1)
890                 sFullPath += ROOT;
891 
892             if ( ((OStoreFile&)pKey->getStoreFile()).remove(sFullPath, keyName) )
893             {
894                 return REG_DELETE_VALUE_FAILED;
895             }
896 			pKey->setModified();
897         }
898 
899         _err = rStoreDir.next(iter);
900     }
901 
902     return REG_NO_ERROR;
903 }
904 
905 
906 //*********************************************************************
907 //  loadKey
908 //
loadKey(RegKeyHandle hKey,const OUString & regFileName,sal_Bool bWarnings,sal_Bool bReport)909 RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName,
910                             sal_Bool bWarnings, sal_Bool bReport)
911 {
912     RegError _ret = REG_NO_ERROR;
913     ORegKey* pKey = static_cast< ORegKey* >(hKey);
914 
915     std::auto_ptr< ORegistry > pReg (new ORegistry());
916     _ret = pReg->initRegistry(regFileName, REG_READONLY);
917     if (_ret != REG_NO_ERROR)
918         return _ret;
919     ORegKey* pRootKey = pReg->getRootKey();
920 
921     REG_GUARD(m_mutex);
922 
923     OStoreDirectory::iterator   iter;
924     OStoreDirectory             rStoreDir(pRootKey->getStoreDir());
925     storeError                  _err = rStoreDir.first(iter);
926 
927     while ( _err == store_E_None )
928     {
929 		OUString const keyName = iter.m_pszName;
930 
931         if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
932         {
933             _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport);
934         }
935 		else
936         {
937             _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport);
938         }
939 
940         if (_ret == REG_MERGE_ERROR)
941 			break;
942 		if (_ret == REG_MERGE_CONFLICT && bWarnings)
943 			break;
944 
945         _err = rStoreDir.next(iter);
946     }
947 
948     rStoreDir = OStoreDirectory();
949     (void) pReg->releaseKey(pRootKey);
950     return _ret;
951 }
952 
953 
954 //*********************************************************************
955 //  saveKey
956 //
saveKey(RegKeyHandle hKey,const OUString & regFileName,sal_Bool bWarnings,sal_Bool bReport)957 RegError ORegistry::saveKey(RegKeyHandle hKey, const OUString& regFileName,
958                             sal_Bool bWarnings, sal_Bool bReport)
959 {
960     RegError _ret = REG_NO_ERROR;
961     ORegKey* pKey = static_cast< ORegKey* >(hKey);
962 
963     std::auto_ptr< ORegistry > pReg (new ORegistry());
964     _ret = pReg->initRegistry(regFileName, REG_CREATE);
965     if (_ret != REG_NO_ERROR)
966         return _ret;
967     ORegKey* pRootKey = pReg->getRootKey();
968 
969     REG_GUARD(m_mutex);
970 
971     OStoreDirectory::iterator   iter;
972     OStoreDirectory             rStoreDir(pKey->getStoreDir());
973     storeError                  _err = rStoreDir.first(iter);
974 
975     while ( _err == store_E_None )
976     {
977 		OUString const keyName = iter.m_pszName;
978 
979         if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
980         {
981             _ret = loadAndSaveKeys(pRootKey, pKey, keyName,
982                                    pKey->getName().getLength(),
983                                    bWarnings, bReport);
984         }
985 		else
986         {
987             _ret = loadAndSaveValue(pRootKey, pKey, keyName,
988                                     pKey->getName().getLength(),
989                                     bWarnings, bReport);
990         }
991 
992         if (_ret != REG_NO_ERROR)
993 			break;
994 
995         _err = rStoreDir.next(iter);
996     }
997 
998     (void) pReg->releaseKey(pRootKey);
999     return _ret;
1000 }
1001 
1002 
1003 //*********************************************************************
1004 //  loadAndSaveValue()
1005 //
loadAndSaveValue(ORegKey * pTargetKey,ORegKey * pSourceKey,const OUString & valueName,sal_uInt32 nCut,sal_Bool bWarnings,sal_Bool bReport)1006 RegError ORegistry::loadAndSaveValue(ORegKey* pTargetKey,
1007                                      ORegKey* pSourceKey,
1008                                      const OUString& valueName,
1009                                      sal_uInt32 nCut,
1010                                      sal_Bool bWarnings,
1011                                      sal_Bool bReport)
1012 {
1013     OStoreStream    rValue;
1014     sal_uInt8*      pBuffer;
1015     RegValueType    valueType;
1016     sal_uInt32      valueSize;
1017     sal_uInt32      nSize;
1018     storeAccessMode sourceAccess = VALUE_MODE_OPEN;
1019     OUString        sTargetPath(pTargetKey->getName());
1020     OUString        sSourcePath(pSourceKey->getName());
1021 
1022     if (pSourceKey->isReadOnly())
1023     {
1024         sourceAccess = VALUE_MODE_OPENREAD;
1025     }
1026 
1027     if (nCut)
1028     {
1029         sTargetPath = sSourcePath.copy(nCut);
1030     } else
1031     {
1032         if (sTargetPath.getLength() > 1)
1033         {
1034             if (sSourcePath.getLength() > 1)
1035                 sTargetPath += sSourcePath;
1036         } else
1037             sTargetPath = sSourcePath;
1038     }
1039 
1040     if (sTargetPath.getLength() > 1) sTargetPath += ROOT;
1041     if (sSourcePath.getLength() > 1) sSourcePath += ROOT;
1042 
1043     if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess))
1044     {
1045         return REG_VALUE_NOT_EXISTS;
1046     }
1047 
1048     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1049 
1050     sal_uInt32  rwBytes;
1051     if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1052     {
1053         rtl_freeMemory(pBuffer);
1054         return REG_INVALID_VALUE;
1055     }
1056     if (rwBytes != VALUE_HEADERSIZE)
1057     {
1058         rtl_freeMemory(pBuffer);
1059         return REG_INVALID_VALUE;
1060     }
1061 
1062     RegError _ret = REG_NO_ERROR;
1063     sal_uInt8   type = *((sal_uInt8*)pBuffer);
1064     valueType = (RegValueType)type;
1065     readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1066     rtl_freeMemory(pBuffer);
1067 
1068     nSize = VALUE_HEADERSIZE + valueSize;
1069     pBuffer = (sal_uInt8*)rtl_allocateMemory(nSize);
1070 
1071     if (rValue.readAt(0, pBuffer, nSize, rwBytes))
1072     {
1073         rtl_freeMemory(pBuffer);
1074         return REG_INVALID_VALUE;
1075     }
1076     if (rwBytes != nSize)
1077     {
1078         rtl_freeMemory(pBuffer);
1079         return REG_INVALID_VALUE;
1080     }
1081 
1082     OStoreFile  rTargetFile(pTargetKey->getStoreFile());
1083 
1084     if (!rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_OPEN))
1085     {
1086         if (valueType == RG_VALUETYPE_BINARY)
1087         {
1088             _ret = checkBlop(
1089                 rValue, sTargetPath, valueSize, pBuffer+VALUE_HEADEROFFSET,
1090                 bReport);
1091             if (_ret)
1092             {
1093                 if (_ret == REG_MERGE_ERROR ||
1094                     (_ret == REG_MERGE_CONFLICT && bWarnings))
1095                 {
1096                     rtl_freeMemory(pBuffer);
1097                     return _ret;
1098                 }
1099             } else
1100             {
1101                 rtl_freeMemory(pBuffer);
1102                 return _ret;
1103             }
1104         }
1105     }
1106 
1107     // write
1108     if (rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_CREATE))
1109     {
1110         rtl_freeMemory(pBuffer);
1111         return REG_INVALID_VALUE;
1112     }
1113     if (rValue.writeAt(0, pBuffer, nSize, rwBytes))
1114     {
1115         rtl_freeMemory(pBuffer);
1116         return REG_INVALID_VALUE;
1117     }
1118 
1119     if (rwBytes != nSize)
1120     {
1121         rtl_freeMemory(pBuffer);
1122         return REG_INVALID_VALUE;
1123     }
1124 	pTargetKey->setModified();
1125 
1126     rtl_freeMemory(pBuffer);
1127     return _ret;
1128 }
1129 
1130 
1131 //*********************************************************************
1132 //  checkblop()
1133 //
checkBlop(OStoreStream & rValue,const OUString & sTargetPath,sal_uInt32 srcValueSize,sal_uInt8 * pSrcBuffer,sal_Bool bReport)1134 RegError ORegistry::checkBlop(OStoreStream& rValue,
1135                               const OUString& sTargetPath,
1136                               sal_uInt32 srcValueSize,
1137                               sal_uInt8* pSrcBuffer,
1138                               sal_Bool bReport)
1139 {
1140     RegistryTypeReader reader(pSrcBuffer, srcValueSize, sal_False);
1141 
1142     if (reader.getTypeClass() == RT_TYPE_INVALID)
1143     {
1144         return REG_INVALID_VALUE;
1145     }
1146 
1147     sal_uInt8*      pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1148     RegValueType    valueType;
1149     sal_uInt32      valueSize;
1150     sal_uInt32      rwBytes;
1151 	OString 		targetPath( OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8) );
1152 
1153     if (!rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes) &&
1154         (rwBytes == VALUE_HEADERSIZE))
1155     {
1156         sal_uInt8 type = *((sal_uInt8*)pBuffer);
1157         valueType = (RegValueType)type;
1158         readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1159         rtl_freeMemory(pBuffer);
1160 
1161         if (valueType == RG_VALUETYPE_BINARY)
1162         {
1163             pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
1164             if (!rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes) &&
1165                 (rwBytes == valueSize))
1166             {
1167                 RegistryTypeReader reader2(pBuffer, valueSize, sal_False);
1168 
1169                 if ((reader.getTypeClass() != reader2.getTypeClass())
1170                     || reader2.getTypeClass() == RT_TYPE_INVALID)
1171                 {
1172                     rtl_freeMemory(pBuffer);
1173 
1174                     if (bReport)
1175                     {
1176                         fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n",
1177                                 targetPath.getStr());
1178                     }
1179                     return REG_MERGE_ERROR;
1180                 }
1181 
1182                 if (reader.getTypeClass() == RT_TYPE_MODULE)
1183                 {
1184                     if (reader.getFieldCount() > 0 &&
1185                         reader2.getFieldCount() > 0)
1186                     {
1187                         mergeModuleValue(rValue, reader, reader2);
1188 
1189                         rtl_freeMemory(pBuffer);
1190                         return REG_NO_ERROR;
1191                     } else
1192                     if (reader2.getFieldCount() > 0)
1193                     {
1194                         rtl_freeMemory(pBuffer);
1195                         return REG_NO_ERROR;
1196                     } else
1197                     {
1198                         rtl_freeMemory(pBuffer);
1199                         return REG_MERGE_CONFLICT;
1200                     }
1201                 } else
1202                 {
1203                     rtl_freeMemory(pBuffer);
1204 
1205                     if (bReport)
1206                     {
1207                         fprintf(stdout, "WARNING: value of key \"%s\" already exists.\n",
1208                                 targetPath.getStr());
1209                     }
1210                     return REG_MERGE_CONFLICT;
1211                 }
1212             } else
1213             {
1214                 rtl_freeMemory(pBuffer);
1215                 if (bReport)
1216                 {
1217                     fprintf(stdout, "ERROR: values of key \"%s\" contains bad data.\n",
1218                             targetPath.getStr());
1219                 }
1220                 return REG_MERGE_ERROR;
1221             }
1222         } else
1223         {
1224             rtl_freeMemory(pBuffer);
1225             if (bReport)
1226             {
1227                 fprintf(stdout, "ERROR: values of key \"%s\" has different types.\n",
1228                         targetPath.getStr());
1229             }
1230             return REG_MERGE_ERROR;
1231         }
1232     } else
1233     {
1234         rtl_freeMemory(pBuffer);
1235         return REG_INVALID_VALUE;
1236     }
1237 }
1238 
checkTypeReaders(RegistryTypeReader & reader1,RegistryTypeReader & reader2,std::set<OUString> & nameSet)1239 static sal_uInt32 checkTypeReaders(RegistryTypeReader& reader1,
1240                                    RegistryTypeReader& reader2,
1241                                    std::set< OUString >& nameSet)
1242 {
1243     sal_uInt32 count=0;
1244     sal_uInt16 i;
1245     for (i=0 ; i < reader1.getFieldCount(); i++)
1246     {
1247         nameSet.insert(reader1.getFieldName(i));
1248         count++;
1249     }
1250     for (i=0 ; i < reader2.getFieldCount(); i++)
1251     {
1252         if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1253         {
1254             nameSet.insert(reader2.getFieldName(i));
1255             count++;
1256         }
1257     }
1258     return count;
1259 }
1260 
1261 //*********************************************************************
1262 //  mergeModuleValue()
1263 //
mergeModuleValue(OStoreStream & rTargetValue,RegistryTypeReader & reader,RegistryTypeReader & reader2)1264 RegError ORegistry::mergeModuleValue(OStoreStream& rTargetValue,
1265                                      RegistryTypeReader& reader,
1266                                      RegistryTypeReader& reader2)
1267 {
1268     sal_uInt16                  index = 0;
1269 
1270     std::set< OUString > nameSet;
1271     sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet);
1272 
1273     if (count != reader.getFieldCount())
1274     {
1275         RegistryTypeWriter writer(reader.getTypeClass(),
1276                                   reader.getTypeName(),
1277                                   reader.getSuperTypeName(),
1278                                   (sal_uInt16)count,
1279                                   0,
1280                                   0);
1281 
1282         sal_uInt16 i;
1283         for (i=0 ; i < reader.getFieldCount(); i++)
1284         {
1285             writer.setFieldData(index,
1286                                reader.getFieldName(i),
1287                                reader.getFieldType(i),
1288                                reader.getFieldDoku(i),
1289                                reader.getFieldFileName(i),
1290                                reader.getFieldAccess(i),
1291                                reader.getFieldConstValue(i));
1292             index++;
1293         }
1294         for (i=0 ; i < reader2.getFieldCount(); i++)
1295         {
1296             if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1297             {
1298                 writer.setFieldData(index,
1299                                    reader2.getFieldName(i),
1300                                    reader2.getFieldType(i),
1301                                    reader2.getFieldDoku(i),
1302                                    reader2.getFieldFileName(i),
1303                                    reader2.getFieldAccess(i),
1304                                    reader2.getFieldConstValue(i));
1305                 index++;
1306             }
1307         }
1308 
1309         const sal_uInt8*    pBlop = writer.getBlop();
1310         sal_uInt32          aBlopSize = writer.getBlopSize();
1311 
1312         sal_uInt8   type = (sal_uInt8)RG_VALUETYPE_BINARY;
1313         sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + aBlopSize);
1314 
1315         rtl_copyMemory(pBuffer, &type, 1);
1316         writeUINT32(pBuffer+VALUE_TYPEOFFSET, aBlopSize);
1317         rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, pBlop, aBlopSize);
1318 
1319         sal_uInt32  rwBytes;
1320         if (rTargetValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+aBlopSize, rwBytes))
1321         {
1322             rtl_freeMemory(pBuffer);
1323             return REG_INVALID_VALUE;
1324         }
1325 
1326         if (rwBytes != VALUE_HEADERSIZE+aBlopSize)
1327         {
1328             rtl_freeMemory(pBuffer);
1329             return REG_INVALID_VALUE;
1330         }
1331 
1332         rtl_freeMemory(pBuffer);
1333     }
1334     return REG_NO_ERROR;
1335 }
1336 
1337 //*********************************************************************
1338 //  loadAndSaveKeys()
1339 //
loadAndSaveKeys(ORegKey * pTargetKey,ORegKey * pSourceKey,const OUString & keyName,sal_uInt32 nCut,sal_Bool bWarnings,sal_Bool bReport)1340 RegError ORegistry::loadAndSaveKeys(ORegKey* pTargetKey,
1341                                     ORegKey* pSourceKey,
1342                                     const OUString& keyName,
1343                                     sal_uInt32 nCut,
1344                                     sal_Bool bWarnings,
1345                                     sal_Bool bReport)
1346 {
1347     RegError    _ret = REG_NO_ERROR;
1348     OUString    sRelPath(pSourceKey->getName().copy(nCut));
1349     OUString    sFullPath;
1350 
1351     if(pTargetKey->getName().getLength() > 1)
1352         sFullPath += pTargetKey->getName();
1353     sFullPath += sRelPath;
1354     if (sRelPath.getLength() > 1 || sFullPath.getLength() == 0)
1355         sFullPath += ROOT;
1356 
1357     OUString sFullKeyName = sFullPath;
1358     sFullKeyName += keyName;
1359 
1360     OStoreDirectory rStoreDir;
1361     if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, KEY_MODE_CREATE))
1362     {
1363         return REG_CREATE_KEY_FAILED;
1364     }
1365 
1366     if (m_openKeyTable.count(sFullKeyName) > 0)
1367     {
1368         m_openKeyTable[sFullKeyName]->setDeleted(sal_False);
1369     }
1370 
1371     ORegKey* pTmpKey = 0;
1372     _ret = pSourceKey->openKey(keyName, (RegKeyHandle*)&pTmpKey);
1373     if (_ret != REG_NO_ERROR)
1374         return _ret;
1375 
1376     OStoreDirectory::iterator   iter;
1377     OStoreDirectory             rTmpStoreDir(pTmpKey->getStoreDir());
1378     storeError                  _err = rTmpStoreDir.first(iter);
1379 
1380     while ( _err == store_E_None)
1381     {
1382 		OUString const sName = iter.m_pszName;
1383 
1384         if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1385         {
1386             _ret = loadAndSaveKeys(pTargetKey, pTmpKey,
1387                                    sName, nCut, bWarnings, bReport);
1388         } else
1389         {
1390             _ret = loadAndSaveValue(pTargetKey, pTmpKey,
1391                                     sName, nCut, bWarnings, bReport);
1392         }
1393 
1394         if (_ret == REG_MERGE_ERROR)
1395 			break;
1396 		if (_ret == REG_MERGE_CONFLICT && bWarnings)
1397 			break;
1398 
1399         _err = rTmpStoreDir.next(iter);
1400     }
1401 
1402     pSourceKey->releaseKey(pTmpKey);
1403     return _ret;
1404 }
1405 
1406 
1407 //*********************************************************************
1408 //  getRootKey()
1409 //
getRootKey()1410 ORegKey* ORegistry::getRootKey()
1411 {
1412     m_openKeyTable[ROOT]->acquire();
1413     return m_openKeyTable[ROOT];
1414 }
1415 
1416 
1417 //*********************************************************************
1418 //  dumpRegistry()
1419 //
dumpRegistry(RegKeyHandle hKey) const1420 RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const
1421 {
1422     ORegKey                     *pKey = (ORegKey*)hKey;
1423     OUString                    sName;
1424     RegError                    _ret = REG_NO_ERROR;
1425     OStoreDirectory::iterator   iter;
1426     OStoreDirectory             rStoreDir(pKey->getStoreDir());
1427     storeError                  _err = rStoreDir.first(iter);
1428 
1429 	OString regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) );
1430 	OString keyName( OUStringToOString( pKey->getName(), RTL_TEXTENCODING_UTF8 ) );
1431     fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr());
1432 
1433     while ( _err == store_E_None )
1434     {
1435         sName = iter.m_pszName;
1436 
1437         if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1438         {
1439             _ret = dumpKey(pKey->getName(), sName, 1);
1440         } else
1441         {
1442             _ret = dumpValue(pKey->getName(), sName, 1);
1443         }
1444 
1445         if (_ret)
1446         {
1447             return _ret;
1448         }
1449 
1450         _err = rStoreDir.next(iter);
1451     }
1452 
1453     return REG_NO_ERROR;
1454 }
1455 
1456 //*********************************************************************
1457 //  dumpValue()
1458 //
dumpValue(const OUString & sPath,const OUString & sName,sal_Int16 nSpc) const1459 RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const
1460 {
1461     OStoreStream    rValue;
1462     sal_uInt8*      pBuffer;
1463     sal_uInt32      valueSize;
1464     RegValueType    valueType;
1465     OUString        sFullPath(sPath);
1466     OString         sIndent;
1467     storeAccessMode accessMode = VALUE_MODE_OPEN;
1468 
1469     if (isReadOnly())
1470     {
1471         accessMode = VALUE_MODE_OPENREAD;
1472     }
1473 
1474     for (int i= 0; i < nSpc; i++) sIndent += " ";
1475 
1476     if (sFullPath.getLength() > 1)
1477 	{
1478         sFullPath += ROOT;
1479 	}
1480     if (rValue.create(m_file, sFullPath, sName, accessMode))
1481     {
1482         return REG_VALUE_NOT_EXISTS;
1483     }
1484 
1485     pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1486 
1487     sal_uInt32  rwBytes;
1488     if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1489     {
1490         rtl_freeMemory(pBuffer);
1491         return REG_INVALID_VALUE;
1492     }
1493     if (rwBytes != (VALUE_HEADERSIZE))
1494     {
1495         rtl_freeMemory(pBuffer);
1496         return REG_INVALID_VALUE;
1497     }
1498 
1499     sal_uInt8 type = *((sal_uInt8*)pBuffer);
1500     valueType = (RegValueType)type;
1501     readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1502 
1503     pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
1504     if (rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes))
1505     {
1506         rtl_freeMemory(pBuffer);
1507         return REG_INVALID_VALUE;
1508     }
1509     if (rwBytes != valueSize)
1510     {
1511         rtl_freeMemory(pBuffer);
1512         return REG_INVALID_VALUE;
1513     }
1514 
1515     const sal_Char* indent = sIndent.getStr();
1516     switch (valueType)
1517     {
1518         case 0:
1519             fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent);
1520             break;
1521         case 1:
1522             {
1523                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONG\n", indent);
1524                 fprintf(
1525                     stdout, "%s       Size = %lu\n", indent,
1526                     sal::static_int_cast< unsigned long >(valueSize));
1527                 fprintf(stdout, "%s       Data = ", indent);
1528 
1529                 sal_Int32 value;
1530                 readINT32(pBuffer, value);
1531                 fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value));
1532             }
1533             break;
1534         case 2:
1535             {
1536                 sal_Char* value = (sal_Char*)rtl_allocateMemory(valueSize);
1537                 readUtf8(pBuffer, value, valueSize);
1538                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRING\n", indent);
1539                 fprintf(
1540                     stdout, "%s       Size = %lu\n", indent,
1541                     sal::static_int_cast< unsigned long >(valueSize));
1542                 fprintf(stdout, "%s       Data = \"%s\"\n", indent, value);
1543                 rtl_freeMemory(value);
1544             }
1545             break;
1546         case 3:
1547             {
1548                 sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode);
1549                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODE\n", indent);
1550                 fprintf(
1551                     stdout, "%s       Size = %lu\n", indent,
1552                     sal::static_int_cast< unsigned long >(valueSize));
1553                 fprintf(stdout, "%s       Data = ", indent);
1554 
1555                 sal_Unicode* value = new sal_Unicode[size];
1556                 readString(pBuffer, value, size);
1557 
1558                 OString uStr = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
1559                 fprintf(stdout, "L\"%s\"\n", uStr.getStr());
1560                 delete[] value;
1561             }
1562             break;
1563         case 4:
1564             {
1565                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_BINARY\n", indent);
1566                 fprintf(
1567                     stdout, "%s       Size = %lu\n", indent,
1568                     sal::static_int_cast< unsigned long >(valueSize));
1569                 fprintf(stdout, "%s       Data = ", indent);
1570                 dumpType(
1571                     typereg::Reader(
1572                         pBuffer, valueSize, false, TYPEREG_VERSION_1),
1573                     sIndent + "              ");
1574             }
1575             break;
1576         case 5:
1577             {
1578                 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1579                 sal_uInt32 len = 0;
1580 
1581                 readUINT32(pBuffer, len);
1582 
1583                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONGLIST\n", indent);
1584                 fprintf(
1585                     stdout, "%s       Size = %lu\n", indent,
1586                     sal::static_int_cast< unsigned long >(valueSize));
1587                 fprintf(
1588                     stdout, "%s       Len  = %lu\n", indent,
1589                     sal::static_int_cast< unsigned long >(len));
1590                 fprintf(stdout, "%s       Data = ", indent);
1591 
1592                 sal_Int32 longValue;
1593                 for (sal_uInt32 i=0; i < len; i++)
1594                 {
1595                     readINT32(pBuffer+offset, longValue);
1596 
1597                     if (offset > 4)
1598                         fprintf(stdout, "%s              ", indent);
1599 
1600                     fprintf(
1601                         stdout, "%lu = %ld\n",
1602                         sal::static_int_cast< unsigned long >(i),
1603                         sal::static_int_cast< long >(longValue));
1604                     offset += 4; // 4 Bytes fuer sal_Int32
1605                 }
1606             }
1607             break;
1608         case 6:
1609             {
1610                 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1611                 sal_uInt32 sLen = 0;
1612                 sal_uInt32 len = 0;
1613 
1614                 readUINT32(pBuffer, len);
1615 
1616                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRINGLIST\n", indent);
1617                 fprintf(
1618                     stdout, "%s       Size = %lu\n", indent,
1619                     sal::static_int_cast< unsigned long >(valueSize));
1620                 fprintf(
1621                     stdout, "%s       Len  = %lu\n", indent,
1622                     sal::static_int_cast< unsigned long >(len));
1623                 fprintf(stdout, "%s       Data = ", indent);
1624 
1625                 sal_Char *pValue;
1626                 for (sal_uInt32 i=0; i < len; i++)
1627                 {
1628                     readUINT32(pBuffer+offset, sLen);
1629 
1630                     offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1631 
1632                     pValue = (sal_Char*)rtl_allocateMemory(sLen);
1633                     readUtf8(pBuffer+offset, pValue, sLen);
1634 
1635                     if (offset > 8)
1636                         fprintf(stdout, "%s              ", indent);
1637 
1638                     fprintf(
1639                         stdout, "%lu = \"%s\"\n",
1640                         sal::static_int_cast< unsigned long >(i), pValue);
1641                     offset += sLen;
1642                 }
1643             }
1644             break;
1645         case 7:
1646             {
1647                 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1648                 sal_uInt32 sLen = 0;
1649                 sal_uInt32 len = 0;
1650 
1651                 readUINT32(pBuffer, len);
1652 
1653                 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODELIST\n", indent);
1654                 fprintf(
1655                     stdout, "%s       Size = %lu\n", indent,
1656                     sal::static_int_cast< unsigned long >(valueSize));
1657                 fprintf(
1658                     stdout, "%s       Len  = %lu\n", indent,
1659                     sal::static_int_cast< unsigned long >(len));
1660                 fprintf(stdout, "%s       Data = ", indent);
1661 
1662                 sal_Unicode *pValue;
1663                 OString uStr;
1664                 for (sal_uInt32 i=0; i < len; i++)
1665                 {
1666                     readUINT32(pBuffer+offset, sLen);
1667 
1668                     offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1669 
1670                     pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode));
1671                     readString(pBuffer+offset, pValue, sLen);
1672 
1673                     if (offset > 8)
1674                         fprintf(stdout, "%s              ", indent);
1675 
1676                     uStr = OUStringToOString(pValue, RTL_TEXTENCODING_UTF8);
1677                     fprintf(
1678                         stdout, "%lu = L\"%s\"\n",
1679                         sal::static_int_cast< unsigned long >(i),
1680                         uStr.getStr());
1681 
1682                     offset += sLen;
1683 
1684                     rtl_freeMemory(pValue);
1685                 }
1686             }
1687             break;
1688     }
1689 
1690     fprintf(stdout, "\n");
1691 
1692     rtl_freeMemory(pBuffer);
1693     return REG_NO_ERROR;
1694 }
1695 
1696 //*********************************************************************
1697 //  dumpKey()
1698 //
dumpKey(const OUString & sPath,const OUString & sName,sal_Int16 nSpace) const1699 RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const
1700 {
1701     OStoreDirectory 	rStoreDir;
1702     OUString          	sFullPath(sPath);
1703     OString             sIndent;
1704     storeAccessMode     accessMode = KEY_MODE_OPEN;
1705     RegError            _ret = REG_NO_ERROR;
1706 
1707     if (isReadOnly())
1708     {
1709         accessMode = KEY_MODE_OPENREAD;
1710     }
1711 
1712     for (int i= 0; i < nSpace; i++) sIndent += " ";
1713 
1714     if (sFullPath.getLength() > 1)
1715         sFullPath += ROOT;
1716 
1717     storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode);
1718 
1719     if (_err == store_E_NotExists)
1720         return REG_KEY_NOT_EXISTS;
1721     else
1722     if (_err == store_E_WrongFormat)
1723         return REG_INVALID_KEY;
1724 
1725     fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
1726 
1727     OUString sSubPath(sFullPath);
1728     OUString sSubName;
1729     sSubPath += sName;
1730 
1731     OStoreDirectory::iterator   iter;
1732 
1733     _err = rStoreDir.first(iter);
1734 
1735     while ( _err == store_E_None)
1736     {
1737         sSubName = iter.m_pszName;
1738 
1739         if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
1740         {
1741             _ret = dumpKey(sSubPath, sSubName, nSpace+2);
1742         } else
1743         {
1744             _ret = dumpValue(sSubPath, sSubName, nSpace+2);
1745         }
1746 
1747         if (_ret)
1748         {
1749             return _ret;
1750         }
1751 
1752         _err = rStoreDir.next(iter);
1753     }
1754 
1755     return REG_NO_ERROR;
1756 }
1757