1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "regimpl.hxx"
34 #include <registry/reflread.hxx>
36 #include <registry/reflwrit.hxx>
38 #include "registry/reader.hxx"
39 #include "registry/refltype.hxx"
40 #include "registry/types.hxx"
41 #include "registry/version.h"
43 #include "reflcnst.hxx"
44 #include "keyimpl.hxx"
46 #include <osl/thread.h>
47 #include <rtl/alloc.h>
48 #include <rtl/ustring.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <osl/file.hxx>
53 using namespace store
;
58 void printString(OUString
const & s
) {
60 for (sal_Int32 i
= 0; i
< s
.getLength(); ++i
) {
62 if (c
== '"' || c
== '\\') {
63 printf("\\%c", static_cast< char >(c
));
64 } else if (s
[i
] >= ' ' && s
[i
] <= '~') {
65 printf("%c", static_cast< char >(c
));
67 printf("\\u%04X", static_cast< unsigned int >(c
));
73 void printFieldOrReferenceFlag(
74 RTFieldAccess
* flags
, RTFieldAccess flag
, char const * name
, bool * first
)
76 if ((*flags
& flag
) != RTFieldAccess::NONE
) {
86 void printFieldOrReferenceFlags(RTFieldAccess flags
) {
87 if (flags
== RTFieldAccess::NONE
) {
91 printFieldOrReferenceFlag(
92 &flags
, RTFieldAccess::READONLY
, "readonly", &first
);
93 printFieldOrReferenceFlag(
94 &flags
, RTFieldAccess::OPTIONAL
, "optional", &first
);
95 printFieldOrReferenceFlag(
96 &flags
, RTFieldAccess::MAYBEVOID
, "maybevoid", &first
);
97 printFieldOrReferenceFlag(&flags
, RTFieldAccess::BOUND
, "bound", &first
);
98 printFieldOrReferenceFlag(
99 &flags
, RTFieldAccess::CONSTRAINED
, "constrained", &first
);
100 printFieldOrReferenceFlag(
101 &flags
, RTFieldAccess::TRANSIENT
, "transient", &first
);
102 printFieldOrReferenceFlag(
103 &flags
, RTFieldAccess::MAYBEAMBIGUOUS
, "maybeambiguous", &first
);
104 printFieldOrReferenceFlag(
105 &flags
, RTFieldAccess::MAYBEDEFAULT
, "maybedefault", &first
);
106 printFieldOrReferenceFlag(
107 &flags
, RTFieldAccess::REMOVABLE
, "removable", &first
);
108 printFieldOrReferenceFlag(
109 &flags
, RTFieldAccess::ATTRIBUTE
, "attribute", &first
);
110 printFieldOrReferenceFlag(
111 &flags
, RTFieldAccess::PROPERTY
, "property", &first
);
112 printFieldOrReferenceFlag(&flags
, RTFieldAccess::CONST
, "const", &first
);
113 printFieldOrReferenceFlag(
114 &flags
, RTFieldAccess::READWRITE
, "readwrite", &first
);
115 printFieldOrReferenceFlag(
116 &flags
, RTFieldAccess::PARAMETERIZED_TYPE
, "parameterized type", &first
);
117 printFieldOrReferenceFlag(
118 &flags
, RTFieldAccess::PUBLISHED
, "published", &first
);
119 if (flags
!= RTFieldAccess::NONE
) {
123 printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags
));
128 void dumpType(typereg::Reader
const & reader
, OString
const & indent
) {
129 if (reader
.isValid()) {
130 printf("version: %ld\n", static_cast< long >(reader
.getVersion()));
131 printf("%sdocumentation: ", indent
.getStr());
132 printString(reader
.getDocumentation());
134 printf("%sfile name: ", indent
.getStr());
135 printString(reader
.getFileName());
137 printf("%stype class: ", indent
.getStr());
138 if (reader
.isPublished()) {
139 printf("published ");
141 switch (reader
.getTypeClass()) {
142 case RT_TYPE_INTERFACE
:
158 case RT_TYPE_EXCEPTION
:
162 case RT_TYPE_TYPEDEF
:
166 case RT_TYPE_SERVICE
:
170 case RT_TYPE_SINGLETON
:
174 case RT_TYPE_CONSTANTS
:
180 "<invalid (%ld)>", static_cast< long >(reader
.getTypeClass()));
184 printf("%stype name: ", indent
.getStr());
185 printString(reader
.getTypeName());
188 "%ssuper type count: %u\n", indent
.getStr(),
189 static_cast< unsigned int >(reader
.getSuperTypeCount()));
190 for (sal_uInt16 i
= 0; i
< reader
.getSuperTypeCount(); ++i
) {
192 "%ssuper type name %u: ", indent
.getStr(),
193 static_cast< unsigned int >(i
));
194 printString(reader
.getSuperTypeName(i
));
198 "%sfield count: %u\n", indent
.getStr(),
199 static_cast< unsigned int >(reader
.getFieldCount()));
200 for (sal_uInt16 i
= 0; i
< reader
.getFieldCount(); ++i
) {
202 "%sfield %u:\n", indent
.getStr(),
203 static_cast< unsigned int >(i
));
204 printf("%s documentation: ", indent
.getStr());
205 printString(reader
.getFieldDocumentation(i
));
207 printf("%s file name: ", indent
.getStr());
208 printString(reader
.getFieldFileName(i
));
210 printf("%s flags: ", indent
.getStr());
211 printFieldOrReferenceFlags(reader
.getFieldFlags(i
));
213 printf("%s name: ", indent
.getStr());
214 printString(reader
.getFieldName(i
));
216 printf("%s type name: ", indent
.getStr());
217 printString(reader
.getFieldTypeName(i
));
219 printf("%s value: ", indent
.getStr());
220 RTConstValue
value(reader
.getFieldValue(i
));
221 switch (value
.m_type
) {
227 printf("boolean %s", value
.m_value
.aBool
? "true" : "false");
231 printf("byte %d", static_cast< int >(value
.m_value
.aByte
));
235 printf("short %d", static_cast< int >(value
.m_value
.aShort
));
241 static_cast< unsigned int >(value
.m_value
.aUShort
));
245 printf("long %ld", static_cast< long >(value
.m_value
.aLong
));
251 static_cast< unsigned long >(value
.m_value
.aULong
));
255 // TODO: no portable way to print hyper values
260 // TODO: no portable way to print unsigned hyper values
261 printf("unsigned hyper");
265 // TODO: no portable way to print float values
270 // TODO: no portable way to print double values
276 printString(value
.m_value
.aString
);
280 printf("<invalid (%ld)>", static_cast< long >(value
.m_type
));
286 "%smethod count: %u\n", indent
.getStr(),
287 static_cast< unsigned int >(reader
.getMethodCount()));
288 for (sal_uInt16 i
= 0; i
< reader
.getMethodCount(); ++i
) {
290 "%smethod %u:\n", indent
.getStr(),
291 static_cast< unsigned int >(i
));
292 printf("%s documentation: ", indent
.getStr());
293 printString(reader
.getMethodDocumentation(i
));
295 printf("%s flags: ", indent
.getStr());
296 switch (reader
.getMethodFlags(i
)) {
297 case RTMethodMode::ONEWAY
:
301 case RTMethodMode::TWOWAY
:
302 printf("synchronous");
305 case RTMethodMode::ATTRIBUTE_GET
:
306 printf("attribute get");
309 case RTMethodMode::ATTRIBUTE_SET
:
310 printf("attribute set");
316 static_cast< long >(reader
.getMethodFlags(i
)));
320 printf("%s name: ", indent
.getStr());
321 printString(reader
.getMethodName(i
));
323 printf("%s return type name: ", indent
.getStr());
324 printString(reader
.getMethodReturnTypeName(i
));
327 "%s parameter count: %u\n", indent
.getStr(),
328 static_cast< unsigned int >(reader
.getMethodParameterCount(i
)));
329 // coverity[tainted_data] cid#1215304 unhelpfully warns about an
330 // untrusted loop bound here:
331 for (sal_uInt16 j
= 0; j
< reader
.getMethodParameterCount(i
); ++j
)
334 "%s parameter %u:\n", indent
.getStr(),
335 static_cast< unsigned int >(j
));
336 printf("%s flags: ", indent
.getStr());
337 RTParamMode flags
= reader
.getMethodParameterFlags(i
, j
);
338 bool rest
= (flags
& RT_PARAM_REST
) != 0;
339 switch (flags
& ~RT_PARAM_REST
) {
353 printf("<invalid (%ld)>", static_cast< long >(flags
));
361 printf("%s name: ", indent
.getStr());
362 printString(reader
.getMethodParameterName(i
, j
));
364 printf("%s type name: ", indent
.getStr());
365 printString(reader
.getMethodParameterTypeName(i
, j
));
369 "%s exception count: %u\n", indent
.getStr(),
370 static_cast< unsigned int >(reader
.getMethodExceptionCount(i
)));
371 // coverity[tainted_data] cid#1215304 unhelpfully warns about an
372 // untrusted loop bound here:
373 for (sal_uInt16 j
= 0; j
< reader
.getMethodExceptionCount(i
); ++j
)
376 "%s exception type name %u: ", indent
.getStr(),
377 static_cast< unsigned int >(j
));
378 printString(reader
.getMethodExceptionTypeName(i
, j
));
383 "%sreference count: %u\n", indent
.getStr(),
384 static_cast< unsigned int >(reader
.getReferenceCount()));
385 for (sal_uInt16 i
= 0; i
< reader
.getReferenceCount(); ++i
) {
387 "%sreference %u:\n", indent
.getStr(),
388 static_cast< unsigned int >(i
));
389 printf("%s documentation: ", indent
.getStr());
390 printString(reader
.getReferenceDocumentation(i
));
392 printf("%s flags: ", indent
.getStr());
393 printFieldOrReferenceFlags(reader
.getReferenceFlags(i
));
395 printf("%s sort: ", indent
.getStr());
396 switch (reader
.getReferenceSort(i
)) {
397 case RTReferenceType::SUPPORTS
:
401 case RTReferenceType::EXPORTS
:
405 case RTReferenceType::TYPE_PARAMETER
:
406 printf("type parameter");
412 static_cast< long >(reader
.getReferenceSort(i
)));
416 printf("%s type name: ", indent
.getStr());
417 printString(reader
.getReferenceTypeName(i
));
421 printf("<invalid>\n");
430 ORegistry::ORegistry()
441 ORegistry::~ORegistry()
443 ORegKey
* pRootKey
= m_openKeyTable
[ROOT
];
445 (void) releaseKey(pRootKey
);
447 if (m_file
.isValid())
455 RegError
ORegistry::initRegistry(const OUString
& regName
, RegAccessMode accessMode
, bool bCreate
)
457 RegError eRet
= RegError::INVALID_REGISTRY
;
459 storeAccessMode sAccessMode
= REG_MODE_OPEN
;
464 sAccessMode
= REG_MODE_CREATE
;
466 else if (accessMode
& RegAccessMode::READONLY
)
468 sAccessMode
= REG_MODE_OPENREAD
;
472 if (regName
.isEmpty() &&
473 store_AccessCreate
== sAccessMode
)
475 errCode
= rRegFile
.createInMemory();
479 errCode
= rRegFile
.create(regName
, sAccessMode
, REG_PAGESIZE
);
486 case store_E_NotExists
:
487 eRet
= RegError::REGISTRY_NOT_EXISTS
;
489 case store_E_LockingViolation
:
490 eRet
= RegError::CANNOT_OPEN_FOR_READWRITE
;
493 eRet
= RegError::INVALID_REGISTRY
;
499 OStoreDirectory rStoreDir
;
500 storeError _err
= rStoreDir
.create(rRegFile
, OUString(), OUString(), sAccessMode
);
502 if ( _err
== store_E_None
)
508 m_openKeyTable
[ROOT
] = new ORegKey(ROOT
, this);
509 eRet
= RegError::NO_ERROR
;
512 eRet
= RegError::INVALID_REGISTRY
;
522 RegError
ORegistry::closeRegistry()
526 if (m_file
.isValid())
528 (void) releaseKey(m_openKeyTable
[ROOT
]);
531 return RegError::NO_ERROR
;
534 return RegError::REGISTRY_NOT_EXISTS
;
542 RegError
ORegistry::destroyRegistry(const OUString
& regName
)
546 if (!regName
.isEmpty())
548 std::unique_ptr
<ORegistry
> pReg(new ORegistry());
550 if (pReg
->initRegistry(regName
, RegAccessMode::READWRITE
) == RegError::NO_ERROR
)
555 if ( FileBase::getSystemPathFromFileURL(regName
, systemName
) != FileBase::E_None
)
556 systemName
= regName
;
558 OString
name( OUStringToOString(systemName
, osl_getThreadTextEncoding()) );
559 if (unlink(name
.getStr()) != 0)
561 return RegError::DESTROY_REGISTRY_FAILED
;
565 return RegError::DESTROY_REGISTRY_FAILED
;
569 if (m_refCount
!= 1 || isReadOnly())
571 return RegError::DESTROY_REGISTRY_FAILED
;
574 if (m_file
.isValid())
576 releaseKey(m_openKeyTable
[ROOT
]);
580 if (!m_name
.isEmpty())
583 if ( FileBase::getSystemPathFromFileURL(m_name
, systemName
) != FileBase::E_None
)
586 OString
name( OUStringToOString(systemName
, osl_getThreadTextEncoding()) );
587 if (unlink(name
.getStr()) != 0)
589 return RegError::DESTROY_REGISTRY_FAILED
;
594 return RegError::REGISTRY_NOT_EXISTS
;
598 return RegError::NO_ERROR
;
604 RegError
ORegistry::acquireKey (RegKeyHandle hKey
)
606 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
608 return RegError::INVALID_KEY
;
613 return RegError::NO_ERROR
;
619 RegError
ORegistry::releaseKey (RegKeyHandle hKey
)
621 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
623 return RegError::INVALID_KEY
;
626 if (pKey
->release() == 0)
628 m_openKeyTable
.erase(pKey
->getName());
631 return RegError::NO_ERROR
;
637 RegError
ORegistry::createKey(RegKeyHandle hKey
, const OUString
& keyName
,
638 RegKeyHandle
* phNewKey
)
644 if ( keyName
.isEmpty() )
645 return RegError::INVALID_KEYNAME
;
650 pKey
= static_cast<ORegKey
*>(hKey
);
652 pKey
= m_openKeyTable
[ROOT
];
654 OUString sFullKeyName
= pKey
->getFullPath(keyName
);
656 if (m_openKeyTable
.count(sFullKeyName
) > 0)
658 *phNewKey
= m_openKeyTable
[sFullKeyName
];
659 static_cast<ORegKey
*>(*phNewKey
)->acquire();
660 static_cast<ORegKey
*>(*phNewKey
)->setDeleted(false);
661 return RegError::NO_ERROR
;
664 OStoreDirectory rStoreDir
;
665 OUStringBuffer
sFullPath(sFullKeyName
.getLength());
668 sFullPath
.append('/');
670 sal_Int32 nIndex
= 0;
673 token
= sFullKeyName
.getToken( 0, '/', nIndex
);
674 if (!token
.isEmpty())
676 if (rStoreDir
.create(pKey
->getStoreFile(), sFullPath
.getStr(), token
, KEY_MODE_CREATE
))
678 return RegError::CREATE_KEY_FAILED
;
681 sFullPath
.append(token
);
682 sFullPath
.append('/');
684 } while( nIndex
!= -1 );
687 pKey
= new ORegKey(sFullKeyName
, this);
689 m_openKeyTable
[sFullKeyName
] = pKey
;
691 return RegError::NO_ERROR
;
698 RegError
ORegistry::openKey(RegKeyHandle hKey
, const OUString
& keyName
,
699 RegKeyHandle
* phOpenKey
)
705 if ( keyName
.isEmpty() )
707 return RegError::INVALID_KEYNAME
;
713 pKey
= static_cast<ORegKey
*>(hKey
);
715 pKey
= m_openKeyTable
[ROOT
];
717 OUString
path(pKey
->getFullPath(keyName
));
718 KeyMap::iterator
i(m_openKeyTable
.find(path
));
719 if (i
== m_openKeyTable
.end()) {
720 sal_Int32 n
= path
.lastIndexOf('/') + 1;
721 switch (OStoreDirectory().create(
722 pKey
->getStoreFile(), path
.copy(0, n
), path
.copy(n
),
723 isReadOnly() ? KEY_MODE_OPENREAD
: KEY_MODE_OPEN
))
725 case store_E_NotExists
:
726 return RegError::KEY_NOT_EXISTS
;
727 case store_E_WrongFormat
:
728 return RegError::INVALID_KEY
;
733 std::unique_ptr
< ORegKey
> p(new ORegKey(path
, this));
734 i
= m_openKeyTable
.insert(std::make_pair(path
, p
.get())).first
;
737 i
->second
->acquire();
739 *phOpenKey
= i
->second
;
740 return RegError::NO_ERROR
;
747 RegError
ORegistry::closeKey(RegKeyHandle hKey
)
749 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
753 OUString
const aKeyName (pKey
->getName());
754 if (!(m_openKeyTable
.count(aKeyName
) > 0))
755 return RegError::KEY_NOT_OPEN
;
757 if (pKey
->isModified())
759 ORegKey
* pRootKey
= getRootKey();
760 if (pKey
!= pRootKey
)
762 // propagate "modified" state to RootKey.
763 pRootKey
->setModified();
767 // closing modified RootKey, flush registry file.
768 OSL_TRACE("registry::ORegistry::closeKey(): flushing modified RootKey");
769 (void) m_file
.flush();
771 pKey
->setModified(false);
772 (void) releaseKey(pRootKey
);
775 return releaseKey(pKey
);
781 RegError
ORegistry::deleteKey(RegKeyHandle hKey
, const OUString
& keyName
)
783 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
784 if ( keyName
.isEmpty() )
785 return RegError::INVALID_KEYNAME
;
790 pKey
= m_openKeyTable
[ROOT
];
792 OUString
sFullKeyName(pKey
->getFullPath(keyName
));
793 return eraseKey(m_openKeyTable
[ROOT
], sFullKeyName
);
796 RegError
ORegistry::eraseKey(ORegKey
* pKey
, const OUString
& keyName
)
798 RegError _ret
= RegError::NO_ERROR
;
800 if ( keyName
.isEmpty() )
802 return RegError::INVALID_KEYNAME
;
805 OUString
sFullKeyName(pKey
->getName());
806 OUString
sFullPath(sFullKeyName
);
807 OUString sRelativKey
;
808 sal_Int32 lastIndex
= keyName
.lastIndexOf('/');
810 if ( lastIndex
>= 0 )
812 sRelativKey
+= keyName
.copy(lastIndex
+ 1);
814 if (sFullKeyName
.getLength() > 1)
815 sFullKeyName
+= keyName
;
817 sFullKeyName
+= keyName
.copy(1);
819 sFullPath
= sFullKeyName
.copy(0, keyName
.lastIndexOf('/') + 1);
822 if (sFullKeyName
.getLength() > 1)
823 sFullKeyName
+= ROOT
;
825 sRelativKey
+= keyName
;
826 sFullKeyName
+= keyName
;
828 if (sFullPath
.getLength() > 1)
832 ORegKey
* pOldKey
= 0;
833 _ret
= pKey
->openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pOldKey
));
834 if (_ret
!= RegError::NO_ERROR
)
837 _ret
= deleteSubkeysAndValues(pOldKey
);
838 if (_ret
!= RegError::NO_ERROR
)
840 pKey
->closeKey(pOldKey
);
844 OUString
tmpName(sRelativKey
);
847 OStoreFile
sFile(pKey
->getStoreFile());
848 if ( sFile
.isValid() && sFile
.remove(sFullPath
, tmpName
) )
850 return RegError::DELETE_KEY_FAILED
;
852 pOldKey
->setModified();
854 // set flag deleted !!!
855 pOldKey
->setDeleted(true);
857 return pKey
->closeKey(pOldKey
);
861 // deleteSubKeysAndValues
863 RegError
ORegistry::deleteSubkeysAndValues(ORegKey
* pKey
)
865 OStoreDirectory::iterator iter
;
866 RegError _ret
= RegError::NO_ERROR
;
867 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
868 storeError _err
= rStoreDir
.first(iter
);
870 while ( _err
== store_E_None
)
872 OUString
const keyName
= iter
.m_pszName
;
874 if (iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
876 _ret
= eraseKey(pKey
, keyName
);
877 if (_ret
!= RegError::NO_ERROR
)
882 OUString
sFullPath(pKey
->getName());
884 if (sFullPath
.getLength() > 1)
887 if ( ((OStoreFile
&)pKey
->getStoreFile()).remove(sFullPath
, keyName
) )
889 return RegError::DELETE_VALUE_FAILED
;
894 _err
= rStoreDir
.next(iter
);
897 return RegError::NO_ERROR
;
904 RegError
ORegistry::loadKey(RegKeyHandle hKey
, const OUString
& regFileName
,
905 bool bWarnings
, bool bReport
)
907 RegError _ret
= RegError::NO_ERROR
;
908 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
910 std::unique_ptr
< ORegistry
> pReg (new ORegistry());
911 _ret
= pReg
->initRegistry(regFileName
, RegAccessMode::READONLY
);
912 if (_ret
!= RegError::NO_ERROR
)
914 ORegKey
* pRootKey
= pReg
->getRootKey();
918 OStoreDirectory::iterator iter
;
919 OStoreDirectory
rStoreDir(pRootKey
->getStoreDir());
920 storeError _err
= rStoreDir
.first(iter
);
922 while ( _err
== store_E_None
)
924 OUString
const keyName
= iter
.m_pszName
;
926 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
928 _ret
= loadAndSaveKeys(pKey
, pRootKey
, keyName
, 0, bWarnings
, bReport
);
932 _ret
= loadAndSaveValue(pKey
, pRootKey
, keyName
, 0, bWarnings
, bReport
);
935 if (_ret
== RegError::MERGE_ERROR
)
937 if (_ret
== RegError::MERGE_CONFLICT
&& bWarnings
)
940 _err
= rStoreDir
.next(iter
);
943 rStoreDir
= OStoreDirectory();
944 (void) pReg
->releaseKey(pRootKey
);
952 RegError
ORegistry::saveKey(RegKeyHandle hKey
, const OUString
& regFileName
,
953 bool bWarnings
, bool bReport
)
955 RegError _ret
= RegError::NO_ERROR
;
956 ORegKey
* pKey
= static_cast< ORegKey
* >(hKey
);
958 std::unique_ptr
< ORegistry
> pReg (new ORegistry());
959 _ret
= pReg
->initRegistry(regFileName
, RegAccessMode::READWRITE
, true/*bCreate*/);
960 if (_ret
!= RegError::NO_ERROR
)
962 ORegKey
* pRootKey
= pReg
->getRootKey();
966 OStoreDirectory::iterator iter
;
967 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
968 storeError _err
= rStoreDir
.first(iter
);
970 while ( _err
== store_E_None
)
972 OUString
const keyName
= iter
.m_pszName
;
974 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
976 _ret
= loadAndSaveKeys(pRootKey
, pKey
, keyName
,
977 pKey
->getName().getLength(),
982 _ret
= loadAndSaveValue(pRootKey
, pKey
, keyName
,
983 pKey
->getName().getLength(),
987 if (_ret
!= RegError::NO_ERROR
)
990 _err
= rStoreDir
.next(iter
);
993 (void) pReg
->releaseKey(pRootKey
);
999 // loadAndSaveValue()
1001 RegError
ORegistry::loadAndSaveValue(ORegKey
* pTargetKey
,
1002 ORegKey
* pSourceKey
,
1003 const OUString
& valueName
,
1008 OStoreStream rValue
;
1010 RegValueType valueType
;
1011 sal_uInt32 valueSize
;
1013 storeAccessMode sourceAccess
= VALUE_MODE_OPEN
;
1014 OUString
sTargetPath(pTargetKey
->getName());
1015 OUString
sSourcePath(pSourceKey
->getName());
1017 if (pSourceKey
->isReadOnly())
1019 sourceAccess
= VALUE_MODE_OPENREAD
;
1024 sTargetPath
= sSourcePath
.copy(nCut
);
1027 if (sTargetPath
.getLength() > 1)
1029 if (sSourcePath
.getLength() > 1)
1030 sTargetPath
+= sSourcePath
;
1032 sTargetPath
= sSourcePath
;
1035 if (sTargetPath
.getLength() > 1) sTargetPath
+= ROOT
;
1036 if (sSourcePath
.getLength() > 1) sSourcePath
+= ROOT
;
1038 if (rValue
.create(pSourceKey
->getStoreFile(), sSourcePath
, valueName
, sourceAccess
))
1040 return RegError::VALUE_NOT_EXISTS
;
1043 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
1046 if (rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, rwBytes
))
1048 rtl_freeMemory(pBuffer
);
1049 return RegError::INVALID_VALUE
;
1051 if (rwBytes
!= VALUE_HEADERSIZE
)
1053 rtl_freeMemory(pBuffer
);
1054 return RegError::INVALID_VALUE
;
1057 RegError _ret
= RegError::NO_ERROR
;
1058 sal_uInt8 type
= *pBuffer
;
1059 valueType
= (RegValueType
)type
;
1060 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
1061 rtl_freeMemory(pBuffer
);
1063 nSize
= VALUE_HEADERSIZE
+ valueSize
;
1064 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(nSize
));
1066 if (rValue
.readAt(0, pBuffer
, nSize
, rwBytes
))
1068 rtl_freeMemory(pBuffer
);
1069 return RegError::INVALID_VALUE
;
1071 if (rwBytes
!= nSize
)
1073 rtl_freeMemory(pBuffer
);
1074 return RegError::INVALID_VALUE
;
1077 OStoreFile
rTargetFile(pTargetKey
->getStoreFile());
1079 if (!rValue
.create(rTargetFile
, sTargetPath
, valueName
, VALUE_MODE_OPEN
))
1081 if (valueType
== RegValueType::BINARY
)
1084 rValue
, sTargetPath
, valueSize
, pBuffer
+VALUE_HEADEROFFSET
,
1086 if (_ret
!= RegError::NO_ERROR
)
1088 if (_ret
== RegError::MERGE_ERROR
||
1089 (_ret
== RegError::MERGE_CONFLICT
&& bWarnings
))
1091 rtl_freeMemory(pBuffer
);
1096 rtl_freeMemory(pBuffer
);
1103 if (rValue
.create(rTargetFile
, sTargetPath
, valueName
, VALUE_MODE_CREATE
))
1105 rtl_freeMemory(pBuffer
);
1106 return RegError::INVALID_VALUE
;
1108 if (rValue
.writeAt(0, pBuffer
, nSize
, rwBytes
))
1110 rtl_freeMemory(pBuffer
);
1111 return RegError::INVALID_VALUE
;
1114 if (rwBytes
!= nSize
)
1116 rtl_freeMemory(pBuffer
);
1117 return RegError::INVALID_VALUE
;
1119 pTargetKey
->setModified();
1121 rtl_freeMemory(pBuffer
);
1129 RegError
ORegistry::checkBlop(OStoreStream
& rValue
,
1130 const OUString
& sTargetPath
,
1131 sal_uInt32 srcValueSize
,
1132 sal_uInt8
* pSrcBuffer
,
1135 RegistryTypeReader
reader(pSrcBuffer
, srcValueSize
, false);
1137 if (reader
.getTypeClass() == RT_TYPE_INVALID
)
1139 return RegError::INVALID_VALUE
;
1142 sal_uInt8
* pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
1143 RegValueType valueType
;
1144 sal_uInt32 valueSize
;
1146 OString
targetPath( OUStringToOString(sTargetPath
, RTL_TEXTENCODING_UTF8
) );
1148 if (!rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, rwBytes
) &&
1149 (rwBytes
== VALUE_HEADERSIZE
))
1151 sal_uInt8 type
= *pBuffer
;
1152 valueType
= (RegValueType
)type
;
1153 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
1154 rtl_freeMemory(pBuffer
);
1156 if (valueType
== RegValueType::BINARY
)
1158 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(valueSize
));
1159 if (!rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, valueSize
, rwBytes
) &&
1160 (rwBytes
== valueSize
))
1162 RegistryTypeReader
reader2(pBuffer
, valueSize
, false);
1164 if ((reader
.getTypeClass() != reader2
.getTypeClass())
1165 || reader2
.getTypeClass() == RT_TYPE_INVALID
)
1167 rtl_freeMemory(pBuffer
);
1171 fprintf(stdout
, "ERROR: values of blop from key \"%s\" has different types.\n",
1172 targetPath
.getStr());
1174 return RegError::MERGE_ERROR
;
1177 if (reader
.getTypeClass() == RT_TYPE_MODULE
)
1179 if (reader
.getFieldCount() > 0 &&
1180 reader2
.getFieldCount() > 0)
1182 mergeModuleValue(rValue
, reader
, reader2
);
1184 rtl_freeMemory(pBuffer
);
1185 return RegError::NO_ERROR
;
1187 if (reader2
.getFieldCount() > 0)
1189 rtl_freeMemory(pBuffer
);
1190 return RegError::NO_ERROR
;
1193 rtl_freeMemory(pBuffer
);
1194 return RegError::MERGE_CONFLICT
;
1198 rtl_freeMemory(pBuffer
);
1202 fprintf(stderr
, "WARNING: value of key \"%s\" already exists.\n",
1203 targetPath
.getStr());
1205 return RegError::MERGE_CONFLICT
;
1209 rtl_freeMemory(pBuffer
);
1212 fprintf(stderr
, "ERROR: values of key \"%s\" contains bad data.\n",
1213 targetPath
.getStr());
1215 return RegError::MERGE_ERROR
;
1219 rtl_freeMemory(pBuffer
);
1222 fprintf(stderr
, "ERROR: values of key \"%s\" has different types.\n",
1223 targetPath
.getStr());
1225 return RegError::MERGE_ERROR
;
1229 rtl_freeMemory(pBuffer
);
1230 return RegError::INVALID_VALUE
;
1234 static sal_uInt32
checkTypeReaders(RegistryTypeReader
& reader1
,
1235 RegistryTypeReader
& reader2
,
1236 std::set
< OUString
>& nameSet
)
1240 for (i
=0 ; i
< reader1
.getFieldCount(); i
++)
1242 nameSet
.insert(reader1
.getFieldName(i
));
1245 for (i
=0 ; i
< reader2
.getFieldCount(); i
++)
1247 if (nameSet
.find(reader2
.getFieldName(i
)) == nameSet
.end())
1249 nameSet
.insert(reader2
.getFieldName(i
));
1257 // mergeModuleValue()
1259 RegError
ORegistry::mergeModuleValue(OStoreStream
& rTargetValue
,
1260 RegistryTypeReader
& reader
,
1261 RegistryTypeReader
& reader2
)
1263 std::set
< OUString
> nameSet
;
1264 sal_uInt32 count
= checkTypeReaders(reader
, reader2
, nameSet
);
1266 if (count
!= reader
.getFieldCount())
1268 sal_uInt16 index
= 0;
1270 RegistryTypeWriter
writer(reader
.getTypeClass(),
1271 reader
.getTypeName(),
1272 reader
.getSuperTypeName(),
1277 for (sal_uInt16 i
=0 ; i
< reader
.getFieldCount(); i
++)
1279 writer
.setFieldData(index
,
1280 reader
.getFieldName(i
),
1281 reader
.getFieldType(i
),
1282 reader
.getFieldDoku(i
),
1283 reader
.getFieldFileName(i
),
1284 reader
.getFieldAccess(i
),
1285 reader
.getFieldConstValue(i
));
1288 for (sal_uInt16 i
=0 ; i
< reader2
.getFieldCount(); i
++)
1290 if (nameSet
.find(reader2
.getFieldName(i
)) == nameSet
.end())
1292 writer
.setFieldData(index
,
1293 reader2
.getFieldName(i
),
1294 reader2
.getFieldType(i
),
1295 reader2
.getFieldDoku(i
),
1296 reader2
.getFieldFileName(i
),
1297 reader2
.getFieldAccess(i
),
1298 reader2
.getFieldConstValue(i
));
1303 const sal_uInt8
* pBlop
= writer
.getBlop();
1304 sal_uInt32 aBlopSize
= writer
.getBlopSize();
1306 sal_uInt8 type
= (sal_uInt8
)RegValueType::BINARY
;
1307 sal_uInt8
* pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
+ aBlopSize
));
1309 memcpy(pBuffer
, &type
, 1);
1310 writeUINT32(pBuffer
+VALUE_TYPEOFFSET
, aBlopSize
);
1311 memcpy(pBuffer
+VALUE_HEADEROFFSET
, pBlop
, aBlopSize
);
1314 if (rTargetValue
.writeAt(0, pBuffer
, VALUE_HEADERSIZE
+aBlopSize
, rwBytes
))
1316 rtl_freeMemory(pBuffer
);
1317 return RegError::INVALID_VALUE
;
1320 if (rwBytes
!= VALUE_HEADERSIZE
+aBlopSize
)
1322 rtl_freeMemory(pBuffer
);
1323 return RegError::INVALID_VALUE
;
1326 rtl_freeMemory(pBuffer
);
1328 return RegError::NO_ERROR
;
1332 // loadAndSaveKeys()
1334 RegError
ORegistry::loadAndSaveKeys(ORegKey
* pTargetKey
,
1335 ORegKey
* pSourceKey
,
1336 const OUString
& keyName
,
1341 RegError _ret
= RegError::NO_ERROR
;
1342 OUString
sRelPath(pSourceKey
->getName().copy(nCut
));
1345 if(pTargetKey
->getName().getLength() > 1)
1346 sFullPath
+= pTargetKey
->getName();
1347 sFullPath
+= sRelPath
;
1348 if (sRelPath
.getLength() > 1 || sFullPath
.isEmpty())
1351 OUString sFullKeyName
= sFullPath
;
1352 sFullKeyName
+= keyName
;
1354 OStoreDirectory rStoreDir
;
1355 if (rStoreDir
.create(pTargetKey
->getStoreFile(), sFullPath
, keyName
, KEY_MODE_CREATE
))
1357 return RegError::CREATE_KEY_FAILED
;
1360 if (m_openKeyTable
.count(sFullKeyName
) > 0)
1362 m_openKeyTable
[sFullKeyName
]->setDeleted(false);
1365 ORegKey
* pTmpKey
= 0;
1366 _ret
= pSourceKey
->openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pTmpKey
));
1367 if (_ret
!= RegError::NO_ERROR
)
1370 OStoreDirectory::iterator iter
;
1371 OStoreDirectory
rTmpStoreDir(pTmpKey
->getStoreDir());
1372 storeError _err
= rTmpStoreDir
.first(iter
);
1374 while ( _err
== store_E_None
)
1376 OUString
const sName
= iter
.m_pszName
;
1378 if (iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
1380 _ret
= loadAndSaveKeys(pTargetKey
, pTmpKey
,
1381 sName
, nCut
, bWarnings
, bReport
);
1384 _ret
= loadAndSaveValue(pTargetKey
, pTmpKey
,
1385 sName
, nCut
, bWarnings
, bReport
);
1388 if (_ret
== RegError::MERGE_ERROR
)
1390 if (_ret
== RegError::MERGE_CONFLICT
&& bWarnings
)
1393 _err
= rTmpStoreDir
.next(iter
);
1396 pSourceKey
->releaseKey(pTmpKey
);
1404 ORegKey
* ORegistry::getRootKey()
1406 m_openKeyTable
[ROOT
]->acquire();
1407 return m_openKeyTable
[ROOT
];
1414 RegError
ORegistry::dumpRegistry(RegKeyHandle hKey
) const
1416 ORegKey
*pKey
= static_cast<ORegKey
*>(hKey
);
1418 RegError _ret
= RegError::NO_ERROR
;
1419 OStoreDirectory::iterator iter
;
1420 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
1421 storeError _err
= rStoreDir
.first(iter
);
1423 OString
regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) );
1424 OString
keyName( OUStringToOString( pKey
->getName(), RTL_TEXTENCODING_UTF8
) );
1425 fprintf(stdout
, "Registry \"%s\":\n\n%s\n", regName
.getStr(), keyName
.getStr());
1427 while ( _err
== store_E_None
)
1429 sName
= iter
.m_pszName
;
1431 if (iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
1433 _ret
= dumpKey(pKey
->getName(), sName
, 1);
1436 _ret
= dumpValue(pKey
->getName(), sName
, 1);
1439 if (_ret
!= RegError::NO_ERROR
)
1444 _err
= rStoreDir
.next(iter
);
1447 return RegError::NO_ERROR
;
1453 RegError
ORegistry::dumpValue(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpc
) const
1455 OStoreStream rValue
;
1457 sal_uInt32 valueSize
;
1458 RegValueType valueType
;
1459 OUString
sFullPath(sPath
);
1461 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
1465 accessMode
= VALUE_MODE_OPENREAD
;
1468 for (int i
= 0; i
< nSpc
; i
++) sIndent
+= " ";
1470 if (sFullPath
.getLength() > 1)
1474 if (rValue
.create(m_file
, sFullPath
, sName
, accessMode
))
1476 return RegError::VALUE_NOT_EXISTS
;
1479 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
1482 if (rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, rwBytes
))
1484 rtl_freeMemory(pBuffer
);
1485 return RegError::INVALID_VALUE
;
1487 if (rwBytes
!= (VALUE_HEADERSIZE
))
1489 rtl_freeMemory(pBuffer
);
1490 return RegError::INVALID_VALUE
;
1493 sal_uInt8 type
= *pBuffer
;
1494 valueType
= (RegValueType
)type
;
1495 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
1497 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(valueSize
));
1498 if (rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, valueSize
, rwBytes
))
1500 rtl_freeMemory(pBuffer
);
1501 return RegError::INVALID_VALUE
;
1503 if (rwBytes
!= valueSize
)
1505 rtl_freeMemory(pBuffer
);
1506 return RegError::INVALID_VALUE
;
1509 const sal_Char
* indent
= sIndent
.getStr();
1512 case RegValueType::NOT_DEFINED
:
1513 fprintf(stdout
, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent
);
1515 case RegValueType::LONG
:
1517 fprintf(stdout
, "%sValue: Type = RegValueType::LONG\n", indent
);
1519 stdout
, "%s Size = %lu\n", indent
,
1520 sal::static_int_cast
< unsigned long >(valueSize
));
1521 fprintf(stdout
, "%s Data = ", indent
);
1524 readINT32(pBuffer
, value
);
1525 fprintf(stdout
, "%ld\n", sal::static_int_cast
< long >(value
));
1528 case RegValueType::STRING
:
1530 sal_Char
* value
= static_cast<sal_Char
*>(rtl_allocateMemory(valueSize
));
1531 readUtf8(pBuffer
, value
, valueSize
);
1532 fprintf(stdout
, "%sValue: Type = RegValueType::STRING\n", indent
);
1534 stdout
, "%s Size = %lu\n", indent
,
1535 sal::static_int_cast
< unsigned long >(valueSize
));
1536 fprintf(stdout
, "%s Data = \"%s\"\n", indent
, value
);
1537 rtl_freeMemory(value
);
1540 case RegValueType::UNICODE
:
1542 sal_uInt32 size
= (valueSize
/ 2) * sizeof(sal_Unicode
);
1543 fprintf(stdout
, "%sValue: Type = RegValueType::UNICODE\n", indent
);
1545 stdout
, "%s Size = %lu\n", indent
,
1546 sal::static_int_cast
< unsigned long >(valueSize
));
1547 fprintf(stdout
, "%s Data = ", indent
);
1549 sal_Unicode
* value
= new sal_Unicode
[size
];
1550 readString(pBuffer
, value
, size
);
1552 OString uStr
= OUStringToOString(value
, RTL_TEXTENCODING_UTF8
);
1553 fprintf(stdout
, "L\"%s\"\n", uStr
.getStr());
1557 case RegValueType::BINARY
:
1559 fprintf(stdout
, "%sValue: Type = RegValueType::BINARY\n", indent
);
1561 stdout
, "%s Size = %lu\n", indent
,
1562 sal::static_int_cast
< unsigned long >(valueSize
));
1563 fprintf(stdout
, "%s Data = ", indent
);
1566 pBuffer
, valueSize
, false, TYPEREG_VERSION_1
),
1570 case RegValueType::LONGLIST
:
1572 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1575 readUINT32(pBuffer
, len
);
1577 fprintf(stdout
, "%sValue: Type = RegValueType::LONGLIST\n", indent
);
1579 stdout
, "%s Size = %lu\n", indent
,
1580 sal::static_int_cast
< unsigned long >(valueSize
));
1582 stdout
, "%s Len = %lu\n", indent
,
1583 sal::static_int_cast
< unsigned long >(len
));
1584 fprintf(stdout
, "%s Data = ", indent
);
1586 sal_Int32 longValue
;
1587 for (sal_uInt32 i
=0; i
< len
; i
++)
1589 readINT32(pBuffer
+offset
, longValue
);
1592 fprintf(stdout
, "%s ", indent
);
1595 stdout
, "%lu = %ld\n",
1596 sal::static_int_cast
< unsigned long >(i
),
1597 sal::static_int_cast
< long >(longValue
));
1598 offset
+= 4; // 4 Bytes fuer sal_Int32
1602 case RegValueType::STRINGLIST
:
1604 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1605 sal_uInt32 sLen
= 0;
1608 readUINT32(pBuffer
, len
);
1610 fprintf(stdout
, "%sValue: Type = RegValueType::STRINGLIST\n", indent
);
1612 stdout
, "%s Size = %lu\n", indent
,
1613 sal::static_int_cast
< unsigned long >(valueSize
));
1615 stdout
, "%s Len = %lu\n", indent
,
1616 sal::static_int_cast
< unsigned long >(len
));
1617 fprintf(stdout
, "%s Data = ", indent
);
1619 for (sal_uInt32 i
=0; i
< len
; i
++)
1621 readUINT32(pBuffer
+offset
, sLen
);
1623 offset
+= 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1625 sal_Char
*pValue
= static_cast<sal_Char
*>(rtl_allocateMemory(sLen
));
1626 readUtf8(pBuffer
+offset
, pValue
, sLen
);
1629 fprintf(stdout
, "%s ", indent
);
1632 stdout
, "%lu = \"%s\"\n",
1633 sal::static_int_cast
< unsigned long >(i
), pValue
);
1634 rtl_freeMemory(pValue
);
1639 case RegValueType::UNICODELIST
:
1641 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
1642 sal_uInt32 sLen
= 0;
1645 readUINT32(pBuffer
, len
);
1647 fprintf(stdout
, "%sValue: Type = RegValueType::UNICODELIST\n", indent
);
1649 stdout
, "%s Size = %lu\n", indent
,
1650 sal::static_int_cast
< unsigned long >(valueSize
));
1652 stdout
, "%s Len = %lu\n", indent
,
1653 sal::static_int_cast
< unsigned long >(len
));
1654 fprintf(stdout
, "%s Data = ", indent
);
1657 for (sal_uInt32 i
=0; i
< len
; i
++)
1659 readUINT32(pBuffer
+offset
, sLen
);
1661 offset
+= 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1663 sal_Unicode
*pValue
= static_cast<sal_Unicode
*>(rtl_allocateMemory((sLen
/ 2) * sizeof(sal_Unicode
)));
1664 readString(pBuffer
+offset
, pValue
, sLen
);
1667 fprintf(stdout
, "%s ", indent
);
1669 uStr
= OUStringToOString(pValue
, RTL_TEXTENCODING_UTF8
);
1671 stdout
, "%lu = L\"%s\"\n",
1672 sal::static_int_cast
< unsigned long >(i
),
1677 rtl_freeMemory(pValue
);
1683 fprintf(stdout
, "\n");
1685 rtl_freeMemory(pBuffer
);
1686 return RegError::NO_ERROR
;
1692 RegError
ORegistry::dumpKey(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpace
) const
1694 OStoreDirectory rStoreDir
;
1695 OUString
sFullPath(sPath
);
1697 storeAccessMode accessMode
= KEY_MODE_OPEN
;
1698 RegError _ret
= RegError::NO_ERROR
;
1702 accessMode
= KEY_MODE_OPENREAD
;
1705 for (int i
= 0; i
< nSpace
; i
++) sIndent
+= " ";
1707 if (sFullPath
.getLength() > 1)
1710 storeError _err
= rStoreDir
.create(m_file
, sFullPath
, sName
, accessMode
);
1712 if (_err
== store_E_NotExists
)
1713 return RegError::KEY_NOT_EXISTS
;
1714 else if (_err
== store_E_WrongFormat
)
1715 return RegError::INVALID_KEY
;
1717 fprintf(stdout
, "%s/ %s\n", sIndent
.getStr(), OUStringToOString(sName
, RTL_TEXTENCODING_UTF8
).getStr());
1719 OUString
sSubPath(sFullPath
);
1723 OStoreDirectory::iterator iter
;
1725 _err
= rStoreDir
.first(iter
);
1727 while ( _err
== store_E_None
)
1729 sSubName
= iter
.m_pszName
;
1731 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
1733 _ret
= dumpKey(sSubPath
, sSubName
, nSpace
+2);
1736 _ret
= dumpValue(sSubPath
, sSubName
, nSpace
+2);
1739 if (_ret
!= RegError::NO_ERROR
)
1744 _err
= rStoreDir
.next(iter
);
1747 return RegError::NO_ERROR
;
1750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */