update dev300-m58
[ooovba.git] / registry / source / regimpl.cxx
blob6d0513548bf28ded4572b5bc61b4b5a3d4f73ab7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: regimpl.cxx,v $
10 * $Revision: 1.28.10.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_registry.hxx"
34 #include <memory>
35 #include <string.h>
36 #include <stdio.h>
38 #if defined(UNX) || defined(OS2)
39 #include <unistd.h>
40 #endif
41 #ifdef __MINGW32__
42 #include <unistd.h>
43 #endif
45 #ifdef MACOSX
46 // Get the store.hxx inlines non-inline, solves crashes in cppumaker
47 #define inline
48 #endif
50 #include "regimpl.hxx"
52 #ifdef MACOSX
53 // Get the store.hxx inlines non-inline, solves crashes in cppumaker
54 #undef inline
55 #endif
57 #ifndef __REGISTRY_REFLREAD_HXX__
58 #include <registry/reflread.hxx>
59 #endif
61 #ifndef __REGISTRY_REFLWRIT_HXX__
62 #include <registry/reflwrit.hxx>
63 #endif
65 #include "registry/reader.hxx"
66 #include "registry/refltype.hxx"
67 #include "registry/types.h"
68 #include "registry/version.h"
70 #ifndef __REFLCNST_HXX__
71 #include "reflcnst.hxx"
72 #endif
73 #include "keyimpl.hxx"
74 #include <osl/thread.h>
75 #include <rtl/alloc.h>
76 #include <rtl/memory.h>
77 #include <rtl/ustring.hxx>
78 #include <rtl/ustrbuf.hxx>
79 #ifndef _ODL_FILE_HXX_
80 #include <osl/file.hxx>
81 #endif
84 #if defined ( GCC ) && ( defined ( SCO ) )
85 sal_helper::ORealDynamicLoader* sal_helper::ODynamicLoader<RegistryTypeReader_Api>::m_pLoader = NULL;
86 #endif
88 namespace {
90 void printString(rtl::OUString const & s) {
91 printf("\"");
92 for (sal_Int32 i = 0; i < s.getLength(); ++i) {
93 sal_Unicode c = s[i];
94 if (c == '"' || c == '\\') {
95 printf("\\%c", static_cast< char >(c));
96 } else if (s[i] >= ' ' && s[i] <= '~') {
97 printf("%c", static_cast< char >(c));
98 } else {
99 printf("\\u%04X", static_cast< unsigned int >(c));
102 printf("\"");
105 void printFieldOrReferenceFlag(
106 RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first)
108 if ((*flags & flag) != 0) {
109 if (!*first) {
110 printf("|");
112 *first = false;
113 printf("%s", name);
114 *flags &= ~flag;
118 void printFieldOrReferenceFlags(RTFieldAccess flags) {
119 if (flags == 0) {
120 printf("none");
121 } else {
122 bool first = true;
123 printFieldOrReferenceFlag(
124 &flags, RT_ACCESS_READONLY, "readonly", &first);
125 printFieldOrReferenceFlag(
126 &flags, RT_ACCESS_OPTIONAL, "optional", &first);
127 printFieldOrReferenceFlag(
128 &flags, RT_ACCESS_MAYBEVOID, "maybevoid", &first);
129 printFieldOrReferenceFlag(&flags, RT_ACCESS_BOUND, "bound", &first);
130 printFieldOrReferenceFlag(
131 &flags, RT_ACCESS_CONSTRAINED, "constrained", &first);
132 printFieldOrReferenceFlag(
133 &flags, RT_ACCESS_TRANSIENT, "transient", &first);
134 printFieldOrReferenceFlag(
135 &flags, RT_ACCESS_MAYBEAMBIGUOUS, "maybeambiguous", &first);
136 printFieldOrReferenceFlag(
137 &flags, RT_ACCESS_MAYBEDEFAULT, "maybedefault", &first);
138 printFieldOrReferenceFlag(
139 &flags, RT_ACCESS_REMOVEABLE, "removeable", &first);
140 printFieldOrReferenceFlag(
141 &flags, RT_ACCESS_ATTRIBUTE, "attribute", &first);
142 printFieldOrReferenceFlag(
143 &flags, RT_ACCESS_PROPERTY, "property", &first);
144 printFieldOrReferenceFlag(&flags, RT_ACCESS_CONST, "const", &first);
145 printFieldOrReferenceFlag(
146 &flags, RT_ACCESS_READWRITE, "readwrite", &first);
147 printFieldOrReferenceFlag(
148 &flags, RT_ACCESS_PARAMETERIZED_TYPE, "parameterized type", &first);
149 printFieldOrReferenceFlag(
150 &flags, RT_ACCESS_PUBLISHED, "published", &first);
151 if (flags != 0) {
152 if (!first) {
153 printf("|");
155 printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags));
160 void dumpType(typereg::Reader const & reader, rtl::OString const & indent) {
161 if (reader.isValid()) {
162 printf("version: %ld\n", static_cast< long >(reader.getVersion()));
163 printf("%sdocumentation: ", indent.getStr());
164 printString(reader.getDocumentation());
165 printf("\n");
166 printf("%sfile name: ", indent.getStr());
167 printString(reader.getFileName());
168 printf("\n");
169 printf("%stype class: ", indent.getStr());
170 if (reader.isPublished()) {
171 printf("published ");
173 switch (reader.getTypeClass()) {
174 case RT_TYPE_INTERFACE:
175 printf("interface");
176 break;
178 case RT_TYPE_MODULE:
179 printf("module");
180 break;
182 case RT_TYPE_STRUCT:
183 printf("struct");
184 break;
186 case RT_TYPE_ENUM:
187 printf("enum");
188 break;
190 case RT_TYPE_EXCEPTION:
191 printf("exception");
192 break;
194 case RT_TYPE_TYPEDEF:
195 printf("typedef");
196 break;
198 case RT_TYPE_SERVICE:
199 printf("service");
200 break;
202 case RT_TYPE_SINGLETON:
203 printf("singleton");
204 break;
206 case RT_TYPE_CONSTANTS:
207 printf("constants");
208 break;
210 default:
211 printf(
212 "<invalid (%ld)>", static_cast< long >(reader.getTypeClass()));
213 break;
215 printf("\n");
216 printf("%stype name: ", indent.getStr());
217 printString(reader.getTypeName());
218 printf("\n");
219 printf(
220 "%ssuper type count: %u\n", indent.getStr(),
221 static_cast< unsigned int >(reader.getSuperTypeCount()));
222 {for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
223 printf(
224 "%ssuper type name %u: ", indent.getStr(),
225 static_cast< unsigned int >(i));
226 printString(reader.getSuperTypeName(i));
227 printf("\n");
229 printf(
230 "%sfield count: %u\n", indent.getStr(),
231 static_cast< unsigned int >(reader.getFieldCount()));
232 {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
233 printf(
234 "%sfield %u:\n", indent.getStr(),
235 static_cast< unsigned int >(i));
236 printf("%s documentation: ", indent.getStr());
237 printString(reader.getFieldDocumentation(i));
238 printf("\n");
239 printf("%s file name: ", indent.getStr());
240 printString(reader.getFieldFileName(i));
241 printf("\n");
242 printf("%s flags: ", indent.getStr());
243 printFieldOrReferenceFlags(reader.getFieldFlags(i));
244 printf("\n");
245 printf("%s name: ", indent.getStr());
246 printString(reader.getFieldName(i));
247 printf("\n");
248 printf("%s type name: ", indent.getStr());
249 printString(reader.getFieldTypeName(i));
250 printf("\n");
251 printf("%s value: ", indent.getStr());
252 RTConstValue value(reader.getFieldValue(i));
253 switch (value.m_type) {
254 case RT_TYPE_NONE:
255 printf("none");
256 break;
258 case RT_TYPE_BOOL:
259 printf("boolean %s", value.m_value.aBool ? "true" : "false");
260 break;
262 case RT_TYPE_BYTE:
263 printf(
264 "byte 0x%02X",
265 static_cast< unsigned int >(value.m_value.aByte));
266 break;
268 case RT_TYPE_INT16:
269 printf("short %d", static_cast< int >(value.m_value.aShort));
270 break;
272 case RT_TYPE_UINT16:
273 printf(
274 "unsigned short %u",
275 static_cast< unsigned int >(value.m_value.aUShort));
276 break;
278 case RT_TYPE_INT32:
279 printf("long %ld", static_cast< long >(value.m_value.aLong));
280 break;
282 case RT_TYPE_UINT32:
283 printf(
284 "unsigned long %lu",
285 static_cast< unsigned long >(value.m_value.aULong));
286 break;
288 case RT_TYPE_INT64:
289 // TODO: no portable way to print hyper values
290 printf("hyper");
291 break;
293 case RT_TYPE_UINT64:
294 // TODO: no portable way to print unsigned hyper values
295 printf("unsigned hyper");
296 break;
298 case RT_TYPE_FLOAT:
299 // TODO: no portable way to print float values
300 printf("float");
301 break;
303 case RT_TYPE_DOUBLE:
304 // TODO: no portable way to print double values
305 printf("double");
306 break;
308 case RT_TYPE_STRING:
309 printf("string ");
310 printString(value.m_value.aString);
311 break;
313 default:
314 printf("<invalid (%ld)>", static_cast< long >(value.m_type));
315 break;
317 printf("\n");
319 printf(
320 "%smethod count: %u\n", indent.getStr(),
321 static_cast< unsigned int >(reader.getMethodCount()));
322 {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
323 printf(
324 "%smethod %u:\n", indent.getStr(),
325 static_cast< unsigned int >(i));
326 printf("%s documentation: ", indent.getStr());
327 printString(reader.getMethodDocumentation(i));
328 printf("\n");
329 printf("%s flags: ", indent.getStr());
330 switch (reader.getMethodFlags(i)) {
331 case RT_MODE_ONEWAY:
332 printf("oneway");
333 break;
335 case RT_MODE_TWOWAY:
336 printf("synchronous");
337 break;
339 case RT_MODE_ATTRIBUTE_GET:
340 printf("attribute get");
341 break;
343 case RT_MODE_ATTRIBUTE_SET:
344 printf("attribute set");
345 break;
347 default:
348 printf(
349 "<invalid (%ld)>",
350 static_cast< long >(reader.getMethodFlags(i)));
351 break;
353 printf("\n");
354 printf("%s name: ", indent.getStr());
355 printString(reader.getMethodName(i));
356 printf("\n");
357 printf("%s return type name: ", indent.getStr());
358 printString(reader.getMethodReturnTypeName(i));
359 printf("\n");
360 printf(
361 "%s parameter count: %u\n", indent.getStr(),
362 static_cast< unsigned int >(reader.getMethodParameterCount(i)));
363 for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j)
365 printf(
366 "%s parameter %u:\n", indent.getStr(),
367 static_cast< unsigned int >(j));
368 printf("%s flags: ", indent.getStr());
369 RTParamMode flags = reader.getMethodParameterFlags(i, j);
370 bool rest = (flags & RT_PARAM_REST) != 0;
371 switch (flags & ~RT_PARAM_REST) {
372 case RT_PARAM_IN:
373 printf("in");
374 break;
376 case RT_PARAM_OUT:
377 printf("out");
378 break;
380 case RT_PARAM_INOUT:
381 printf("inout");
382 break;
384 default:
385 printf("<invalid (%ld)>", static_cast< long >(flags));
386 rest = false;
387 break;
389 if (rest) {
390 printf("|rest");
392 printf("\n");
393 printf("%s name: ", indent.getStr());
394 printString(reader.getMethodParameterName(i, j));
395 printf("\n");
396 printf("%s type name: ", indent.getStr());
397 printString(reader.getMethodParameterTypeName(i, j));
398 printf("\n");
400 printf(
401 "%s exception count: %u\n", indent.getStr(),
402 static_cast< unsigned int >(reader.getMethodExceptionCount(i)));
403 for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j)
405 printf(
406 "%s exception type name %u: ", indent.getStr(),
407 static_cast< unsigned int >(j));
408 printString(reader.getMethodExceptionTypeName(i, j));
409 printf("\n");
412 printf(
413 "%sreference count: %u\n", indent.getStr(),
414 static_cast< unsigned int >(reader.getReferenceCount()));
415 {for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) {
416 printf(
417 "%sreference %u:\n", indent.getStr(),
418 static_cast< unsigned int >(i));
419 printf("%s documentation: ", indent.getStr());
420 printString(reader.getReferenceDocumentation(i));
421 printf("\n");
422 printf("%s flags: ", indent.getStr());
423 printFieldOrReferenceFlags(reader.getReferenceFlags(i));
424 printf("\n");
425 printf("%s sort: ", indent.getStr());
426 switch (reader.getReferenceSort(i)) {
427 case RT_REF_SUPPORTS:
428 printf("supports");
429 break;
431 case RT_REF_EXPORTS:
432 printf("exports");
433 break;
435 case RT_REF_TYPE_PARAMETER:
436 printf("type parameter");
437 break;
439 default:
440 printf(
441 "<invalid (%ld)>",
442 static_cast< long >(reader.getReferenceSort(i)));
443 break;
445 printf("\n");
446 printf("%s type name: ", indent.getStr());
447 printString(reader.getReferenceTypeName(i));
448 printf("\n");
450 } else {
451 printf("<invalid>\n");
457 //*********************************************************************
458 // ORegistry()
460 ORegistry::ORegistry()
461 : m_refCount(1)
462 , m_readOnly(sal_False)
463 , m_isOpen(sal_False)
464 , ROOT( RTL_CONSTASCII_USTRINGPARAM("/") )
468 //*********************************************************************
469 // ~ORegistry()
471 ORegistry::~ORegistry()
473 if (m_openKeyTable.count(ROOT) > 0)
475 m_openKeyTable[ROOT]->release();
476 delete(m_openKeyTable[ROOT]);
479 if (m_file.isValid())
480 m_file.close();
484 //*********************************************************************
485 // initRegistry
487 RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode)
489 OStoreFile rRegFile;
490 storeAccessMode sAccessMode = REG_MODE_OPEN;
491 storeError errCode;
493 if (accessMode & REG_CREATE)
495 sAccessMode = REG_MODE_CREATE;
496 } else
497 if (accessMode & REG_READONLY)
499 sAccessMode = REG_MODE_OPENREAD;
500 m_readOnly = sal_True;
503 if (0 == regName.getLength() &&
504 store_AccessCreate == sAccessMode)
506 errCode = rRegFile.createInMemory();
508 else
510 errCode = rRegFile.create(regName, sAccessMode, REG_PAGESIZE);
513 if (errCode)
515 switch (errCode)
517 case store_E_NotExists:
518 return REG_REGISTRY_NOT_EXISTS;
519 case store_E_LockingViolation:
520 return REG_CANNOT_OPEN_FOR_READWRITE;
521 default:
522 return REG_INVALID_REGISTRY;
524 } else
526 OStoreDirectory rStoreDir;
527 storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode);
529 if ( _err == store_E_None )
531 m_file = rRegFile;
532 m_name = regName;
533 m_isOpen = sal_True;
535 m_openKeyTable[ROOT] = new ORegKey(ROOT, this);
536 return REG_NO_ERROR;
537 } else
538 return REG_INVALID_REGISTRY;
540 // this line is never accessed
541 // just hack to avoid warning: control reaches end of non-void function
542 return REG_INVALID_REGISTRY;
546 //*********************************************************************
547 // closeRegistry
549 RegError ORegistry::closeRegistry()
551 REG_GUARD(m_mutex);
553 if (m_file.isValid())
555 closeKey(m_openKeyTable[ROOT]);
556 m_file.close();
557 m_isOpen = sal_False;
558 return REG_NO_ERROR;
559 } else
561 return REG_REGISTRY_NOT_EXISTS;
566 //*********************************************************************
567 // destroyRegistry
569 RegError ORegistry::destroyRegistry(const OUString& regName)
571 REG_GUARD(m_mutex);
573 if (regName.getLength())
575 ORegistry* pReg = new ORegistry();
577 if (!pReg->initRegistry(regName, REG_READWRITE))
579 delete pReg;
581 OUString systemName;
582 if ( FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None )
583 systemName = regName;
585 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
586 if (unlink(name) != 0)
588 return REG_DESTROY_REGISTRY_FAILED;
590 } else
592 return REG_DESTROY_REGISTRY_FAILED;
594 } else
596 if (m_refCount != 1 || isReadOnly())
598 return REG_DESTROY_REGISTRY_FAILED;
601 if (m_file.isValid())
603 closeKey(m_openKeyTable[ROOT]);
604 m_file.close();
605 m_isOpen = sal_False;
607 if (m_name.getLength())
609 OUString systemName;
610 if ( FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None )
611 systemName = m_name;
613 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
614 if (unlink(name.getStr()) != 0)
616 return REG_DESTROY_REGISTRY_FAILED;
619 } else
621 return REG_REGISTRY_NOT_EXISTS;
625 return REG_NO_ERROR;
628 //*********************************************************************
629 // createKey
631 RegError ORegistry::createKey(RegKeyHandle hKey, const OUString& keyName,
632 RegKeyHandle* phNewKey)
634 ORegKey* pKey;
636 *phNewKey = NULL;
638 if ( !keyName.getLength() )
639 return REG_INVALID_KEYNAME;
641 REG_GUARD(m_mutex);
643 if (hKey)
644 pKey = (ORegKey*)hKey;
645 else
646 pKey = m_openKeyTable[ROOT];
648 OUString sFullKeyName = pKey->getFullPath(keyName);
650 if (m_openKeyTable.count(sFullKeyName) > 0)
652 *phNewKey = m_openKeyTable[sFullKeyName];
653 ((ORegKey*)*phNewKey)->acquire();
654 ((ORegKey*)*phNewKey)->setDeleted(sal_False);
655 return REG_NO_ERROR;
658 OStoreDirectory rStoreDir;
659 OUStringBuffer sFullPath(sFullKeyName.getLength());
660 OUString token;
662 sFullPath.append((sal_Unicode)'/');
664 sal_Int32 nIndex = 0;
667 token = sFullKeyName.getToken( 0, '/', nIndex );
668 if (token.getLength())
670 if (rStoreDir.create(pKey->getStoreFile(), sFullPath.getStr(), token, KEY_MODE_CREATE))
672 return REG_CREATE_KEY_FAILED;
675 sFullPath.append(token);
676 sFullPath.append((sal_Unicode)'/');
678 } while( nIndex != -1 );
681 pKey = new ORegKey(sFullKeyName, this);
682 *phNewKey = pKey;
683 m_openKeyTable[sFullKeyName] = pKey;
685 return REG_NO_ERROR;
689 //*********************************************************************
690 // openKey
692 RegError ORegistry::openKey(RegKeyHandle hKey, const OUString& keyName,
693 RegKeyHandle* phOpenKey)
695 ORegKey* pKey;
697 *phOpenKey = NULL;
699 if ( !keyName.getLength() )
701 return REG_INVALID_KEYNAME;
704 REG_GUARD(m_mutex);
706 if (hKey)
707 pKey = (ORegKey*)hKey;
708 else
709 pKey = m_openKeyTable[ROOT];
711 OUString path(pKey->getFullPath(keyName));
712 KeyMap::iterator i(m_openKeyTable.find(path));
713 if (i == m_openKeyTable.end()) {
714 sal_Int32 n = path.lastIndexOf('/') + 1;
715 switch (OStoreDirectory().create(
716 pKey->getStoreFile(), path.copy(0, n), path.copy(n),
717 isReadOnly() ? KEY_MODE_OPENREAD : KEY_MODE_OPEN))
719 case store_E_NotExists:
720 return REG_KEY_NOT_EXISTS;
721 case store_E_WrongFormat:
722 return REG_INVALID_KEY;
723 default:
724 break;
726 std::auto_ptr< ORegKey > p(new ORegKey(path, this));
727 i = m_openKeyTable.insert(std::make_pair(path, p.get())).first;
728 p.release();
729 } else {
730 i->second->acquire();
732 *phOpenKey = i->second;
733 return REG_NO_ERROR;
737 //*********************************************************************
738 // closeKey
740 RegError ORegistry::closeKey(RegKeyHandle hKey)
742 ORegKey* pKey = (ORegKey*)hKey;
744 REG_GUARD(m_mutex);
746 if (m_openKeyTable.count(pKey->getName()) > 0)
748 if (pKey->getRefCount() == 1)
750 m_openKeyTable.erase(pKey->getName());
751 delete(pKey);
752 hKey = NULL;
753 } else
755 pKey->release();
758 return REG_NO_ERROR;
759 } else
761 return REG_KEY_NOT_OPEN;
766 //*********************************************************************
767 // deleteKey
769 RegError ORegistry::deleteKey(RegKeyHandle hKey, const OUString& keyName)
771 ORegKey* pKey;
772 RegError _ret = REG_NO_ERROR;
774 if ( !keyName.getLength() )
776 return REG_INVALID_KEYNAME;
779 REG_GUARD(m_mutex);
781 if (hKey)
782 pKey = (ORegKey*)hKey;
783 else
784 pKey = m_openKeyTable[ROOT];
786 OUString sFullKeyName = pKey->getFullPath(keyName);
788 pKey = m_openKeyTable[ROOT];
789 _ret = eraseKey(pKey, sFullKeyName);
791 return _ret;
794 RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName)
796 RegError _ret = REG_NO_ERROR;
798 if ( !keyName.getLength() )
800 return REG_INVALID_KEYNAME;
803 OUString sFullKeyName(pKey->getName());
804 OUString sFullPath(sFullKeyName);
805 OUString sRelativKey;
806 sal_Int32 lastIndex = keyName.lastIndexOf('/');
808 if ( lastIndex >= 0 )
810 sRelativKey += keyName.copy(lastIndex + 1);
812 if (sFullKeyName.getLength() > 1)
813 sFullKeyName += keyName;
814 else
815 sFullKeyName += (keyName+1);
817 sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1);
818 } else
820 if (sFullKeyName.getLength() > 1)
821 sFullKeyName += ROOT;
823 sRelativKey += keyName;
824 sFullKeyName += keyName;
826 if (sFullPath.getLength() > 1)
827 sFullPath += ROOT;
830 RegKeyHandle hOldKey;
831 _ret = pKey->openKey(keyName, &hOldKey);
832 if (_ret)
834 return _ret;
837 _ret = deleteSubkeysAndValues((ORegKey*)hOldKey);
838 if (_ret)
840 pKey->closeKey(hOldKey);
841 return _ret;
844 OUString tmpName(sRelativKey);
845 tmpName += ROOT;
847 OStoreFile sFile(pKey->getStoreFile());
849 if ( sFile.isValid() && sFile.remove(sFullPath, tmpName) )
851 return REG_DELETE_KEY_FAILED;
854 // set flag deleted !!!
855 ((ORegKey*)hOldKey)->setDeleted(sal_True);
857 _ret = pKey->closeKey(hOldKey);
858 if (_ret)
860 return _ret;
863 return REG_NO_ERROR;
867 //*********************************************************************
868 // deleteSubKeys
870 RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey)
872 OStoreDirectory::iterator iter;
873 OUString keyName;
874 RegError _ret = REG_NO_ERROR;
875 OStoreDirectory rStoreDir(pKey->getStoreDir());
876 storeError _err = rStoreDir.first(iter);
878 while ( _err == store_E_None )
880 keyName = iter.m_pszName;
882 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
884 _ret = eraseKey(pKey, keyName);
885 if (_ret)
886 return _ret;
887 } else
889 OUString sFullPath(pKey->getName());
891 if (sFullPath.getLength() > 1)
892 sFullPath += ROOT;
894 if ( ((OStoreFile&)pKey->getStoreFile()).remove(sFullPath, keyName) )
896 return REG_DELETE_VALUE_FAILED;
900 _err = rStoreDir.next(iter);
903 return REG_NO_ERROR;
907 //*********************************************************************
908 // loadKey
910 RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName,
911 sal_Bool bWarnings, sal_Bool bReport)
913 RegError _ret = REG_NO_ERROR;
914 ORegistry* pReg;
915 ORegKey *pKey, *pRootKey;
917 pReg = new ORegistry();
918 _ret = pReg->initRegistry(regFileName, REG_READONLY);
919 if (_ret)
921 return _ret;
924 pKey = (ORegKey*)hKey;
925 pRootKey = pReg->getRootKey();
927 REG_GUARD(m_mutex);
929 OStoreDirectory::iterator iter;
930 OUString keyName;
931 OStoreDirectory rStoreDir(pRootKey->getStoreDir());
932 storeError _err = rStoreDir.first(iter);
934 while ( _err == store_E_None )
936 keyName = iter.m_pszName;
938 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
940 _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport);
941 } else
943 _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport);
946 if (_ret == REG_MERGE_ERROR ||
947 (_ret == REG_MERGE_CONFLICT && bWarnings))
949 rStoreDir = OStoreDirectory();
950 pRootKey->release();
951 delete(pReg);
952 return _ret;
955 _err = rStoreDir.next(iter);
958 rStoreDir = OStoreDirectory();
959 pRootKey->release();
960 delete(pReg);
961 return _ret;
965 //*********************************************************************
966 // loadKey
968 RegError ORegistry::saveKey(RegKeyHandle hKey, const OUString& regFileName,
969 sal_Bool bWarnings, sal_Bool bReport)
971 RegError _ret = REG_NO_ERROR;
972 ORegistry* pReg;
973 ORegKey *pKey, *pRootKey;
975 pReg = new ORegistry();
976 _ret = pReg->initRegistry(regFileName, REG_CREATE);
977 if (_ret)
979 return _ret;
982 pKey = (ORegKey*)hKey;
983 pRootKey = pReg->getRootKey();
985 REG_GUARD(m_mutex);
987 OStoreDirectory::iterator iter;
988 OUString keyName;
989 OStoreDirectory rStoreDir(pKey->getStoreDir());
990 storeError _err = rStoreDir.first(iter);
992 while ( _err == store_E_None )
994 keyName = iter.m_pszName;
996 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
998 _ret = loadAndSaveKeys(pRootKey, pKey, keyName,
999 pKey->getName().getLength(),
1000 bWarnings, bReport);
1001 } else
1003 _ret = loadAndSaveValue(pRootKey, pKey, keyName,
1004 pKey->getName().getLength(),
1005 bWarnings, bReport);
1008 if (_ret)
1010 pRootKey->release();
1011 delete(pReg);
1012 return _ret;
1015 _err = rStoreDir.next(iter);
1018 pRootKey->release();
1019 delete(pReg);
1020 return REG_NO_ERROR;
1024 //*********************************************************************
1025 // loadValue()
1027 RegError ORegistry::loadAndSaveValue(ORegKey* pTargetKey,
1028 ORegKey* pSourceKey,
1029 const OUString& valueName,
1030 sal_uInt32 nCut,
1031 sal_Bool bWarnings,
1032 sal_Bool bReport)
1034 OStoreStream rValue;
1035 sal_uInt8* pBuffer;
1036 RegValueType valueType;
1037 sal_uInt32 valueSize;
1038 sal_uInt32 nSize;
1039 storeAccessMode sourceAccess = VALUE_MODE_OPEN;
1040 OUString sTargetPath(pTargetKey->getName());
1041 OUString sSourcePath(pSourceKey->getName());
1043 if (pSourceKey->isReadOnly())
1045 sourceAccess = VALUE_MODE_OPENREAD;
1048 if (nCut)
1050 sTargetPath = sSourcePath.copy(nCut);
1051 } else
1053 if (sTargetPath.getLength() > 1)
1055 if (sSourcePath.getLength() > 1)
1056 sTargetPath += sSourcePath;
1057 } else
1058 sTargetPath = sSourcePath;
1061 if (sTargetPath.getLength() > 1) sTargetPath += ROOT;
1062 if (sSourcePath.getLength() > 1) sSourcePath += ROOT;
1064 if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess))
1066 return REG_VALUE_NOT_EXISTS;
1069 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1071 sal_uInt32 rwBytes;
1072 if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1074 rtl_freeMemory(pBuffer);
1075 return REG_INVALID_VALUE;
1077 if (rwBytes != VALUE_HEADERSIZE)
1079 rtl_freeMemory(pBuffer);
1080 return REG_INVALID_VALUE;
1083 RegError _ret = REG_NO_ERROR;
1084 sal_uInt8 type = *((sal_uInt8*)pBuffer);
1085 valueType = (RegValueType)type;
1086 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1087 rtl_freeMemory(pBuffer);
1089 nSize = VALUE_HEADERSIZE + valueSize;
1090 pBuffer = (sal_uInt8*)rtl_allocateMemory(nSize);
1092 if (rValue.readAt(0, pBuffer, nSize, rwBytes))
1094 rtl_freeMemory(pBuffer);
1095 return REG_INVALID_VALUE;
1097 if (rwBytes != nSize)
1099 rtl_freeMemory(pBuffer);
1100 return REG_INVALID_VALUE;
1103 OStoreFile rTargetFile(pTargetKey->getStoreFile());
1105 if (!rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_OPEN))
1107 if (valueType == RG_VALUETYPE_BINARY)
1109 _ret = checkBlop(
1110 rValue, sTargetPath, valueSize, pBuffer+VALUE_HEADEROFFSET,
1111 bReport);
1112 if (_ret)
1114 if (_ret == REG_MERGE_ERROR ||
1115 (_ret == REG_MERGE_CONFLICT && bWarnings))
1117 rtl_freeMemory(pBuffer);
1118 return _ret;
1120 } else
1122 rtl_freeMemory(pBuffer);
1123 return _ret;
1128 // write
1129 if (rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_CREATE))
1131 rtl_freeMemory(pBuffer);
1132 return REG_INVALID_VALUE;
1134 if (rValue.writeAt(0, pBuffer, nSize, rwBytes))
1136 rtl_freeMemory(pBuffer);
1137 return REG_INVALID_VALUE;
1140 if (rwBytes != nSize)
1142 rtl_freeMemory(pBuffer);
1143 return REG_INVALID_VALUE;
1146 rtl_freeMemory(pBuffer);
1147 return _ret;
1151 //*********************************************************************
1152 // checkblop()
1154 RegError ORegistry::checkBlop(OStoreStream& rValue,
1155 const OUString& sTargetPath,
1156 sal_uInt32 srcValueSize,
1157 sal_uInt8* pSrcBuffer,
1158 sal_Bool bReport)
1160 RegistryTypeReader reader(pSrcBuffer, srcValueSize, sal_False);
1162 if (reader.getTypeClass() == RT_TYPE_INVALID)
1164 return REG_INVALID_VALUE;
1167 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1168 RegValueType valueType;
1169 sal_uInt32 valueSize;
1170 sal_uInt32 rwBytes;
1171 OString targetPath( OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8) );
1173 if (!rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes) &&
1174 (rwBytes == VALUE_HEADERSIZE))
1176 sal_uInt8 type = *((sal_uInt8*)pBuffer);
1177 valueType = (RegValueType)type;
1178 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1179 rtl_freeMemory(pBuffer);
1181 if (valueType == RG_VALUETYPE_BINARY)
1183 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
1184 if (!rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes) &&
1185 (rwBytes == valueSize))
1187 RegistryTypeReader reader2(pBuffer, valueSize, sal_False);
1189 if ((reader.getTypeClass() != reader2.getTypeClass())
1190 || reader2.getTypeClass() == RT_TYPE_INVALID)
1192 rtl_freeMemory(pBuffer);
1194 if (bReport)
1196 fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n",
1197 targetPath.getStr());
1199 return REG_MERGE_ERROR;
1202 if (reader.getTypeClass() == RT_TYPE_MODULE)
1204 if (reader.getFieldCount() > 0 &&
1205 reader2.getFieldCount() > 0)
1207 mergeModuleValue(rValue, reader, reader2);
1209 rtl_freeMemory(pBuffer);
1210 return REG_NO_ERROR;
1211 } else
1212 if (reader2.getFieldCount() > 0)
1214 rtl_freeMemory(pBuffer);
1215 return REG_NO_ERROR;
1216 } else
1218 rtl_freeMemory(pBuffer);
1219 return REG_MERGE_CONFLICT;
1221 } else
1223 rtl_freeMemory(pBuffer);
1225 if (bReport)
1227 fprintf(stdout, "WARNING: value of key \"%s\" already exists.\n",
1228 targetPath.getStr());
1230 return REG_MERGE_CONFLICT;
1232 } else
1234 rtl_freeMemory(pBuffer);
1235 if (bReport)
1237 fprintf(stdout, "ERROR: values of key \"%s\" contains bad data.\n",
1238 targetPath.getStr());
1240 return REG_MERGE_ERROR;
1242 } else
1244 rtl_freeMemory(pBuffer);
1245 if (bReport)
1247 fprintf(stdout, "ERROR: values of key \"%s\" has different types.\n",
1248 targetPath.getStr());
1250 return REG_MERGE_ERROR;
1252 } else
1254 rtl_freeMemory(pBuffer);
1255 return REG_INVALID_VALUE;
1259 static sal_uInt32 checkTypeReaders(RegistryTypeReader& reader1,
1260 RegistryTypeReader& reader2,
1261 std::set< OUString >& nameSet)
1263 sal_uInt32 count=0;
1264 sal_uInt16 i;
1265 for (i=0 ; i < reader1.getFieldCount(); i++)
1267 nameSet.insert(reader1.getFieldName(i));
1268 count++;
1270 for (i=0 ; i < reader2.getFieldCount(); i++)
1272 if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1274 nameSet.insert(reader2.getFieldName(i));
1275 count++;
1278 return count;
1281 //*********************************************************************
1282 // mergeModuleValue()
1284 RegError ORegistry::mergeModuleValue(OStoreStream& rTargetValue,
1285 RegistryTypeReader& reader,
1286 RegistryTypeReader& reader2)
1288 sal_uInt16 index = 0;
1290 std::set< OUString > nameSet;
1291 sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet);
1293 if (count != reader.getFieldCount())
1295 RegistryTypeWriter writer(reader.getTypeClass(),
1296 reader.getTypeName(),
1297 reader.getSuperTypeName(),
1298 (sal_uInt16)count,
1302 sal_uInt16 i;
1303 for (i=0 ; i < reader.getFieldCount(); i++)
1305 writer.setFieldData(index,
1306 reader.getFieldName(i),
1307 reader.getFieldType(i),
1308 reader.getFieldDoku(i),
1309 reader.getFieldFileName(i),
1310 reader.getFieldAccess(i),
1311 reader.getFieldConstValue(i));
1312 index++;
1314 for (i=0 ; i < reader2.getFieldCount(); i++)
1316 if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1318 writer.setFieldData(index,
1319 reader2.getFieldName(i),
1320 reader2.getFieldType(i),
1321 reader2.getFieldDoku(i),
1322 reader2.getFieldFileName(i),
1323 reader2.getFieldAccess(i),
1324 reader2.getFieldConstValue(i));
1325 index++;
1329 const sal_uInt8* pBlop = writer.getBlop();
1330 sal_uInt32 aBlopSize = writer.getBlopSize();
1332 sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_BINARY;
1333 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + aBlopSize);
1335 rtl_copyMemory(pBuffer, &type, 1);
1336 writeUINT32(pBuffer+VALUE_TYPEOFFSET, aBlopSize);
1337 rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, pBlop, aBlopSize);
1339 sal_uInt32 rwBytes;
1340 if (rTargetValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+aBlopSize, rwBytes))
1342 rtl_freeMemory(pBuffer);
1343 return REG_INVALID_VALUE;
1346 if (rwBytes != VALUE_HEADERSIZE+aBlopSize)
1348 rtl_freeMemory(pBuffer);
1349 return REG_INVALID_VALUE;
1352 rtl_freeMemory(pBuffer);
1354 return REG_NO_ERROR;
1357 //*********************************************************************
1358 // loadKeys()
1360 RegError ORegistry::loadAndSaveKeys(ORegKey* pTargetKey,
1361 ORegKey* pSourceKey,
1362 const OUString& keyName,
1363 sal_uInt32 nCut,
1364 sal_Bool bWarnings,
1365 sal_Bool bReport)
1367 ORegKey* pTmpKey;
1368 RegError _ret = REG_NO_ERROR;
1369 OUString sRelPath(pSourceKey->getName().copy(nCut));
1370 OUString sFullPath;
1372 if(pTargetKey->getName().getLength() > 1)
1373 sFullPath += pTargetKey->getName();
1374 sFullPath += sRelPath;
1375 if (sRelPath.getLength() > 1 || sFullPath.getLength() == 0)
1376 sFullPath += ROOT;
1378 OUString sFullKeyName = sFullPath;
1379 OStoreDirectory rStoreDir;
1381 sFullKeyName += keyName;
1383 if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, KEY_MODE_CREATE))
1385 return REG_CREATE_KEY_FAILED;
1388 if (m_openKeyTable.count(sFullKeyName) > 0)
1390 m_openKeyTable[sFullKeyName]->setDeleted(sal_False);
1393 _ret = pSourceKey->openKey(
1394 keyName, (RegKeyHandle*)&pTmpKey);
1395 if (_ret)
1397 return _ret;
1400 OStoreDirectory::iterator iter;
1401 OUString sName;
1402 OStoreDirectory rTmpStoreDir(pTmpKey->getStoreDir());
1403 storeError _err = rTmpStoreDir.first(iter);
1405 while ( _err == store_E_None)
1407 sName = iter.m_pszName;
1409 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1411 _ret = loadAndSaveKeys(pTargetKey, pTmpKey,
1412 sName, nCut, bWarnings, bReport);
1413 } else
1415 _ret = loadAndSaveValue(pTargetKey, pTmpKey,
1416 sName, nCut, bWarnings, bReport);
1419 if (_ret == REG_MERGE_ERROR ||
1420 (_ret == REG_MERGE_CONFLICT && bWarnings))
1422 pSourceKey->closeKey(pTmpKey);
1423 return _ret;
1426 _err = rTmpStoreDir.next(iter);
1429 pSourceKey->closeKey(pTmpKey);
1430 return _ret;
1434 //*********************************************************************
1435 // getRootKey()
1437 ORegKey* ORegistry::getRootKey()
1439 m_openKeyTable[ROOT]->acquire();
1440 return m_openKeyTable[ROOT];
1444 //*********************************************************************
1445 // dumpRegistry()
1447 RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const
1449 ORegKey *pKey = (ORegKey*)hKey;
1450 OUString sName;
1451 RegError _ret = REG_NO_ERROR;
1452 OStoreDirectory::iterator iter;
1453 OStoreDirectory rStoreDir(pKey->getStoreDir());
1454 storeError _err = rStoreDir.first(iter);
1456 OString regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) );
1457 OString keyName( OUStringToOString( pKey->getName(), RTL_TEXTENCODING_UTF8 ) );
1458 fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr());
1460 while ( _err == store_E_None )
1462 sName = iter.m_pszName;
1464 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1466 _ret = dumpKey(pKey->getName(), sName, 1);
1467 } else
1469 _ret = dumpValue(pKey->getName(), sName, 1);
1472 if (_ret)
1474 return _ret;
1477 _err = rStoreDir.next(iter);
1480 return REG_NO_ERROR;
1484 //*********************************************************************
1485 // dumpValue()
1487 RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const
1489 OStoreStream rValue;
1490 sal_uInt8* pBuffer;
1491 sal_uInt32 valueSize;
1492 RegValueType valueType;
1493 OUString sFullPath(sPath);
1494 OString sIndent;
1495 storeAccessMode accessMode = VALUE_MODE_OPEN;
1497 if (isReadOnly())
1499 accessMode = VALUE_MODE_OPENREAD;
1502 for (int i= 0; i < nSpc; i++) sIndent += " ";
1504 if (sFullPath.getLength() > 1)
1506 sFullPath += ROOT;
1508 if (rValue.create(m_file, sFullPath, sName, accessMode))
1510 return REG_VALUE_NOT_EXISTS;
1513 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1515 sal_uInt32 rwBytes;
1516 if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1518 rtl_freeMemory(pBuffer);
1519 return REG_INVALID_VALUE;
1521 if (rwBytes != (VALUE_HEADERSIZE))
1523 rtl_freeMemory(pBuffer);
1524 return REG_INVALID_VALUE;
1527 sal_uInt8 type = *((sal_uInt8*)pBuffer);
1528 valueType = (RegValueType)type;
1529 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1531 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
1532 if (rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes))
1534 rtl_freeMemory(pBuffer);
1535 return REG_INVALID_VALUE;
1537 if (rwBytes != valueSize)
1539 rtl_freeMemory(pBuffer);
1540 return REG_INVALID_VALUE;
1543 const sal_Char* indent = sIndent.getStr();
1544 switch (valueType)
1546 case 0:
1547 fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent);
1548 break;
1549 case 1:
1551 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONG\n", indent);
1552 fprintf(
1553 stdout, "%s Size = %lu\n", indent,
1554 sal::static_int_cast< unsigned long >(valueSize));
1555 fprintf(stdout, "%s Data = ", indent);
1557 sal_Int32 value;
1558 readINT32(pBuffer, value);
1559 fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value));
1561 break;
1562 case 2:
1564 sal_Char* value = (sal_Char*)rtl_allocateMemory(valueSize);
1565 readUtf8(pBuffer, value, valueSize);
1566 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRING\n", indent);
1567 fprintf(
1568 stdout, "%s Size = %lu\n", indent,
1569 sal::static_int_cast< unsigned long >(valueSize));
1570 fprintf(stdout, "%s Data = \"%s\"\n", indent, value);
1571 rtl_freeMemory(value);
1573 break;
1574 case 3:
1576 sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode);
1577 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODE\n", indent);
1578 fprintf(
1579 stdout, "%s Size = %lu\n", indent,
1580 sal::static_int_cast< unsigned long >(valueSize));
1581 fprintf(stdout, "%s Data = ", indent);
1583 sal_Unicode* value = new sal_Unicode[size];
1584 readString(pBuffer, value, size);
1586 OString uStr = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
1587 fprintf(stdout, "L\"%s\"\n", uStr.getStr());
1588 delete[] value;
1590 break;
1591 case 4:
1593 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_BINARY\n", indent);
1594 fprintf(
1595 stdout, "%s Size = %lu\n", indent,
1596 sal::static_int_cast< unsigned long >(valueSize));
1597 fprintf(stdout, "%s Data = ", indent);
1598 dumpType(
1599 typereg::Reader(
1600 pBuffer, valueSize, false, TYPEREG_VERSION_1),
1601 sIndent + " ");
1603 break;
1604 case 5:
1606 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1607 sal_uInt32 len = 0;
1609 readUINT32(pBuffer, len);
1611 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONGLIST\n", indent);
1612 fprintf(
1613 stdout, "%s Size = %lu\n", indent,
1614 sal::static_int_cast< unsigned long >(valueSize));
1615 fprintf(
1616 stdout, "%s Len = %lu\n", indent,
1617 sal::static_int_cast< unsigned long >(len));
1618 fprintf(stdout, "%s Data = ", indent);
1620 sal_Int32 longValue;
1621 for (sal_uInt32 i=0; i < len; i++)
1623 readINT32(pBuffer+offset, longValue);
1625 if (offset > 4)
1626 fprintf(stdout, "%s ", indent);
1628 fprintf(
1629 stdout, "%lu = %ld\n",
1630 sal::static_int_cast< unsigned long >(i),
1631 sal::static_int_cast< long >(longValue));
1632 offset += 4; // 4 Bytes fuer sal_Int32
1635 break;
1636 case 6:
1638 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1639 sal_uInt32 sLen = 0;
1640 sal_uInt32 len = 0;
1642 readUINT32(pBuffer, len);
1644 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRINGLIST\n", indent);
1645 fprintf(
1646 stdout, "%s Size = %lu\n", indent,
1647 sal::static_int_cast< unsigned long >(valueSize));
1648 fprintf(
1649 stdout, "%s Len = %lu\n", indent,
1650 sal::static_int_cast< unsigned long >(len));
1651 fprintf(stdout, "%s Data = ", indent);
1653 sal_Char *pValue;
1654 for (sal_uInt32 i=0; i < len; i++)
1656 readUINT32(pBuffer+offset, sLen);
1658 offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1660 pValue = (sal_Char*)rtl_allocateMemory(sLen);
1661 readUtf8(pBuffer+offset, pValue, sLen);
1663 if (offset > 8)
1664 fprintf(stdout, "%s ", indent);
1666 fprintf(
1667 stdout, "%lu = \"%s\"\n",
1668 sal::static_int_cast< unsigned long >(i), pValue);
1669 offset += sLen;
1672 break;
1673 case 7:
1675 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1676 sal_uInt32 sLen = 0;
1677 sal_uInt32 len = 0;
1679 readUINT32(pBuffer, len);
1681 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODELIST\n", indent);
1682 fprintf(
1683 stdout, "%s Size = %lu\n", indent,
1684 sal::static_int_cast< unsigned long >(valueSize));
1685 fprintf(
1686 stdout, "%s Len = %lu\n", indent,
1687 sal::static_int_cast< unsigned long >(len));
1688 fprintf(stdout, "%s Data = ", indent);
1690 sal_Unicode *pValue;
1691 OString uStr;
1692 for (sal_uInt32 i=0; i < len; i++)
1694 readUINT32(pBuffer+offset, sLen);
1696 offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1698 pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode));
1699 readString(pBuffer+offset, pValue, sLen);
1701 if (offset > 8)
1702 fprintf(stdout, "%s ", indent);
1704 uStr = OUStringToOString(pValue, RTL_TEXTENCODING_UTF8);
1705 fprintf(
1706 stdout, "%lu = L\"%s\"\n",
1707 sal::static_int_cast< unsigned long >(i),
1708 uStr.getStr());
1710 offset += sLen;
1712 rtl_freeMemory(pValue);
1715 break;
1718 fprintf(stdout, "\n");
1720 rtl_freeMemory(pBuffer);
1721 return REG_NO_ERROR;
1724 //*********************************************************************
1725 // dumpKey()
1727 RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const
1729 OStoreDirectory rStoreDir;
1730 OUString sFullPath(sPath);
1731 OString sIndent;
1732 storeAccessMode accessMode = KEY_MODE_OPEN;
1733 RegError _ret = REG_NO_ERROR;
1735 if (isReadOnly())
1737 accessMode = KEY_MODE_OPENREAD;
1740 for (int i= 0; i < nSpace; i++) sIndent += " ";
1742 if (sFullPath.getLength() > 1)
1743 sFullPath += ROOT;
1745 storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode);
1747 if (_err == store_E_NotExists)
1748 return REG_KEY_NOT_EXISTS;
1749 else
1750 if (_err == store_E_WrongFormat)
1751 return REG_INVALID_KEY;
1753 fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
1755 OUString sSubPath(sFullPath);
1756 OUString sSubName;
1757 sSubPath += sName;
1759 OStoreDirectory::iterator iter;
1761 _err = rStoreDir.first(iter);
1763 while ( _err == store_E_None)
1765 sSubName = iter.m_pszName;
1767 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
1769 _ret = dumpKey(sSubPath, sSubName, nSpace+2);
1770 } else
1772 _ret = dumpValue(sSubPath, sSubName, nSpace+2);
1775 if (_ret)
1777 return _ret;
1780 _err = rStoreDir.next(iter);
1783 return REG_NO_ERROR;