1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
38 #if defined(UNX) || defined(OS2)
46 // Get the store.hxx inlines non-inline, solves crashes in cppumaker
50 #include "regimpl.hxx"
53 // Get the store.hxx inlines non-inline, solves crashes in cppumaker
57 #ifndef __REGISTRY_REFLREAD_HXX__
58 #include <registry/reflread.hxx>
61 #ifndef __REGISTRY_REFLWRIT_HXX__
62 #include <registry/reflwrit.hxx>
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"
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>
84 #if defined ( GCC ) && ( defined ( SCO ) )
85 sal_helper::ORealDynamicLoader
* sal_helper::ODynamicLoader
<RegistryTypeReader_Api
>::m_pLoader
= NULL
;
90 void printString(rtl::OUString
const & s
) {
92 for (sal_Int32 i
= 0; i
< s
.getLength(); ++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
));
99 printf("\\u%04X", static_cast< unsigned int >(c
));
105 void printFieldOrReferenceFlag(
106 RTFieldAccess
* flags
, RTFieldAccess flag
, char const * name
, bool * first
)
108 if ((*flags
& flag
) != 0) {
118 void printFieldOrReferenceFlags(RTFieldAccess flags
) {
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
);
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());
166 printf("%sfile name: ", indent
.getStr());
167 printString(reader
.getFileName());
169 printf("%stype class: ", indent
.getStr());
170 if (reader
.isPublished()) {
171 printf("published ");
173 switch (reader
.getTypeClass()) {
174 case RT_TYPE_INTERFACE
:
190 case RT_TYPE_EXCEPTION
:
194 case RT_TYPE_TYPEDEF
:
198 case RT_TYPE_SERVICE
:
202 case RT_TYPE_SINGLETON
:
206 case RT_TYPE_CONSTANTS
:
212 "<invalid (%ld)>", static_cast< long >(reader
.getTypeClass()));
216 printf("%stype name: ", indent
.getStr());
217 printString(reader
.getTypeName());
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
) {
224 "%ssuper type name %u: ", indent
.getStr(),
225 static_cast< unsigned int >(i
));
226 printString(reader
.getSuperTypeName(i
));
230 "%sfield count: %u\n", indent
.getStr(),
231 static_cast< unsigned int >(reader
.getFieldCount()));
232 {for (sal_uInt16 i
= 0; i
< reader
.getFieldCount(); ++i
) {
234 "%sfield %u:\n", indent
.getStr(),
235 static_cast< unsigned int >(i
));
236 printf("%s documentation: ", indent
.getStr());
237 printString(reader
.getFieldDocumentation(i
));
239 printf("%s file name: ", indent
.getStr());
240 printString(reader
.getFieldFileName(i
));
242 printf("%s flags: ", indent
.getStr());
243 printFieldOrReferenceFlags(reader
.getFieldFlags(i
));
245 printf("%s name: ", indent
.getStr());
246 printString(reader
.getFieldName(i
));
248 printf("%s type name: ", indent
.getStr());
249 printString(reader
.getFieldTypeName(i
));
251 printf("%s value: ", indent
.getStr());
252 RTConstValue
value(reader
.getFieldValue(i
));
253 switch (value
.m_type
) {
259 printf("boolean %s", value
.m_value
.aBool
? "true" : "false");
265 static_cast< unsigned int >(value
.m_value
.aByte
));
269 printf("short %d", static_cast< int >(value
.m_value
.aShort
));
275 static_cast< unsigned int >(value
.m_value
.aUShort
));
279 printf("long %ld", static_cast< long >(value
.m_value
.aLong
));
285 static_cast< unsigned long >(value
.m_value
.aULong
));
289 // TODO: no portable way to print hyper values
294 // TODO: no portable way to print unsigned hyper values
295 printf("unsigned hyper");
299 // TODO: no portable way to print float values
304 // TODO: no portable way to print double values
310 printString(value
.m_value
.aString
);
314 printf("<invalid (%ld)>", static_cast< long >(value
.m_type
));
320 "%smethod count: %u\n", indent
.getStr(),
321 static_cast< unsigned int >(reader
.getMethodCount()));
322 {for (sal_uInt16 i
= 0; i
< reader
.getMethodCount(); ++i
) {
324 "%smethod %u:\n", indent
.getStr(),
325 static_cast< unsigned int >(i
));
326 printf("%s documentation: ", indent
.getStr());
327 printString(reader
.getMethodDocumentation(i
));
329 printf("%s flags: ", indent
.getStr());
330 switch (reader
.getMethodFlags(i
)) {
336 printf("synchronous");
339 case RT_MODE_ATTRIBUTE_GET
:
340 printf("attribute get");
343 case RT_MODE_ATTRIBUTE_SET
:
344 printf("attribute set");
350 static_cast< long >(reader
.getMethodFlags(i
)));
354 printf("%s name: ", indent
.getStr());
355 printString(reader
.getMethodName(i
));
357 printf("%s return type name: ", indent
.getStr());
358 printString(reader
.getMethodReturnTypeName(i
));
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
)
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
) {
385 printf("<invalid (%ld)>", static_cast< long >(flags
));
393 printf("%s name: ", indent
.getStr());
394 printString(reader
.getMethodParameterName(i
, j
));
396 printf("%s type name: ", indent
.getStr());
397 printString(reader
.getMethodParameterTypeName(i
, j
));
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
)
406 "%s exception type name %u: ", indent
.getStr(),
407 static_cast< unsigned int >(j
));
408 printString(reader
.getMethodExceptionTypeName(i
, j
));
413 "%sreference count: %u\n", indent
.getStr(),
414 static_cast< unsigned int >(reader
.getReferenceCount()));
415 {for (sal_uInt16 i
= 0; i
< reader
.getReferenceCount(); ++i
) {
417 "%sreference %u:\n", indent
.getStr(),
418 static_cast< unsigned int >(i
));
419 printf("%s documentation: ", indent
.getStr());
420 printString(reader
.getReferenceDocumentation(i
));
422 printf("%s flags: ", indent
.getStr());
423 printFieldOrReferenceFlags(reader
.getReferenceFlags(i
));
425 printf("%s sort: ", indent
.getStr());
426 switch (reader
.getReferenceSort(i
)) {
427 case RT_REF_SUPPORTS
:
435 case RT_REF_TYPE_PARAMETER
:
436 printf("type parameter");
442 static_cast< long >(reader
.getReferenceSort(i
)));
446 printf("%s type name: ", indent
.getStr());
447 printString(reader
.getReferenceTypeName(i
));
451 printf("<invalid>\n");
457 //*********************************************************************
460 ORegistry::ORegistry()
462 , m_readOnly(sal_False
)
463 , m_isOpen(sal_False
)
464 , ROOT( RTL_CONSTASCII_USTRINGPARAM("/") )
468 //*********************************************************************
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())
484 //*********************************************************************
487 RegError
ORegistry::initRegistry(const OUString
& regName
, RegAccessMode accessMode
)
490 storeAccessMode sAccessMode
= REG_MODE_OPEN
;
493 if (accessMode
& REG_CREATE
)
495 sAccessMode
= REG_MODE_CREATE
;
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();
510 errCode
= rRegFile
.create(regName
, sAccessMode
, REG_PAGESIZE
);
517 case store_E_NotExists
:
518 return REG_REGISTRY_NOT_EXISTS
;
519 case store_E_LockingViolation
:
520 return REG_CANNOT_OPEN_FOR_READWRITE
;
522 return REG_INVALID_REGISTRY
;
526 OStoreDirectory rStoreDir
;
527 storeError _err
= rStoreDir
.create(rRegFile
, OUString(), OUString(), sAccessMode
);
529 if ( _err
== store_E_None
)
535 m_openKeyTable
[ROOT
] = new ORegKey(ROOT
, this);
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 //*********************************************************************
549 RegError
ORegistry::closeRegistry()
553 if (m_file
.isValid())
555 closeKey(m_openKeyTable
[ROOT
]);
557 m_isOpen
= sal_False
;
561 return REG_REGISTRY_NOT_EXISTS
;
566 //*********************************************************************
569 RegError
ORegistry::destroyRegistry(const OUString
& regName
)
573 if (regName
.getLength())
575 ORegistry
* pReg
= new ORegistry();
577 if (!pReg
->initRegistry(regName
, REG_READWRITE
))
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
;
592 return REG_DESTROY_REGISTRY_FAILED
;
596 if (m_refCount
!= 1 || isReadOnly())
598 return REG_DESTROY_REGISTRY_FAILED
;
601 if (m_file
.isValid())
603 closeKey(m_openKeyTable
[ROOT
]);
605 m_isOpen
= sal_False
;
607 if (m_name
.getLength())
610 if ( FileBase::getSystemPathFromFileURL(m_name
, systemName
) != FileBase::E_None
)
613 OString
name( OUStringToOString(systemName
, osl_getThreadTextEncoding()) );
614 if (unlink(name
.getStr()) != 0)
616 return REG_DESTROY_REGISTRY_FAILED
;
621 return REG_REGISTRY_NOT_EXISTS
;
628 //*********************************************************************
631 RegError
ORegistry::createKey(RegKeyHandle hKey
, const OUString
& keyName
,
632 RegKeyHandle
* phNewKey
)
638 if ( !keyName
.getLength() )
639 return REG_INVALID_KEYNAME
;
644 pKey
= (ORegKey
*)hKey
;
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
);
658 OStoreDirectory rStoreDir
;
659 OUStringBuffer
sFullPath(sFullKeyName
.getLength());
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);
683 m_openKeyTable
[sFullKeyName
] = pKey
;
689 //*********************************************************************
692 RegError
ORegistry::openKey(RegKeyHandle hKey
, const OUString
& keyName
,
693 RegKeyHandle
* phOpenKey
)
699 if ( !keyName
.getLength() )
701 return REG_INVALID_KEYNAME
;
707 pKey
= (ORegKey
*)hKey
;
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
;
726 std::auto_ptr
< ORegKey
> p(new ORegKey(path
, this));
727 i
= m_openKeyTable
.insert(std::make_pair(path
, p
.get())).first
;
730 i
->second
->acquire();
732 *phOpenKey
= i
->second
;
737 //*********************************************************************
740 RegError
ORegistry::closeKey(RegKeyHandle hKey
)
742 ORegKey
* pKey
= (ORegKey
*)hKey
;
746 if (m_openKeyTable
.count(pKey
->getName()) > 0)
748 if (pKey
->getRefCount() == 1)
750 m_openKeyTable
.erase(pKey
->getName());
761 return REG_KEY_NOT_OPEN
;
766 //*********************************************************************
769 RegError
ORegistry::deleteKey(RegKeyHandle hKey
, const OUString
& keyName
)
772 RegError _ret
= REG_NO_ERROR
;
774 if ( !keyName
.getLength() )
776 return REG_INVALID_KEYNAME
;
782 pKey
= (ORegKey
*)hKey
;
784 pKey
= m_openKeyTable
[ROOT
];
786 OUString sFullKeyName
= pKey
->getFullPath(keyName
);
788 pKey
= m_openKeyTable
[ROOT
];
789 _ret
= eraseKey(pKey
, sFullKeyName
);
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
;
815 sFullKeyName
+= (keyName
+1);
817 sFullPath
= sFullKeyName
.copy(0, keyName
.lastIndexOf('/') + 1);
820 if (sFullKeyName
.getLength() > 1)
821 sFullKeyName
+= ROOT
;
823 sRelativKey
+= keyName
;
824 sFullKeyName
+= keyName
;
826 if (sFullPath
.getLength() > 1)
830 RegKeyHandle hOldKey
;
831 _ret
= pKey
->openKey(keyName
, &hOldKey
);
837 _ret
= deleteSubkeysAndValues((ORegKey
*)hOldKey
);
840 pKey
->closeKey(hOldKey
);
844 OUString
tmpName(sRelativKey
);
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
);
867 //*********************************************************************
870 RegError
ORegistry::deleteSubkeysAndValues(ORegKey
* pKey
)
872 OStoreDirectory::iterator iter
;
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
);
889 OUString
sFullPath(pKey
->getName());
891 if (sFullPath
.getLength() > 1)
894 if ( ((OStoreFile
&)pKey
->getStoreFile()).remove(sFullPath
, keyName
) )
896 return REG_DELETE_VALUE_FAILED
;
900 _err
= rStoreDir
.next(iter
);
907 //*********************************************************************
910 RegError
ORegistry::loadKey(RegKeyHandle hKey
, const OUString
& regFileName
,
911 sal_Bool bWarnings
, sal_Bool bReport
)
913 RegError _ret
= REG_NO_ERROR
;
915 ORegKey
*pKey
, *pRootKey
;
917 pReg
= new ORegistry();
918 _ret
= pReg
->initRegistry(regFileName
, REG_READONLY
);
924 pKey
= (ORegKey
*)hKey
;
925 pRootKey
= pReg
->getRootKey();
929 OStoreDirectory::iterator iter
;
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
);
943 _ret
= loadAndSaveValue(pKey
, pRootKey
, keyName
, 0, bWarnings
, bReport
);
946 if (_ret
== REG_MERGE_ERROR
||
947 (_ret
== REG_MERGE_CONFLICT
&& bWarnings
))
949 rStoreDir
= OStoreDirectory();
955 _err
= rStoreDir
.next(iter
);
958 rStoreDir
= OStoreDirectory();
965 //*********************************************************************
968 RegError
ORegistry::saveKey(RegKeyHandle hKey
, const OUString
& regFileName
,
969 sal_Bool bWarnings
, sal_Bool bReport
)
971 RegError _ret
= REG_NO_ERROR
;
973 ORegKey
*pKey
, *pRootKey
;
975 pReg
= new ORegistry();
976 _ret
= pReg
->initRegistry(regFileName
, REG_CREATE
);
982 pKey
= (ORegKey
*)hKey
;
983 pRootKey
= pReg
->getRootKey();
987 OStoreDirectory::iterator iter
;
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
);
1003 _ret
= loadAndSaveValue(pRootKey
, pKey
, keyName
,
1004 pKey
->getName().getLength(),
1005 bWarnings
, bReport
);
1010 pRootKey
->release();
1015 _err
= rStoreDir
.next(iter
);
1018 pRootKey
->release();
1020 return REG_NO_ERROR
;
1024 //*********************************************************************
1027 RegError
ORegistry::loadAndSaveValue(ORegKey
* pTargetKey
,
1028 ORegKey
* pSourceKey
,
1029 const OUString
& valueName
,
1034 OStoreStream rValue
;
1036 RegValueType valueType
;
1037 sal_uInt32 valueSize
;
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
;
1050 sTargetPath
= sSourcePath
.copy(nCut
);
1053 if (sTargetPath
.getLength() > 1)
1055 if (sSourcePath
.getLength() > 1)
1056 sTargetPath
+= sSourcePath
;
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
);
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
)
1110 rValue
, sTargetPath
, valueSize
, pBuffer
+VALUE_HEADEROFFSET
,
1114 if (_ret
== REG_MERGE_ERROR
||
1115 (_ret
== REG_MERGE_CONFLICT
&& bWarnings
))
1117 rtl_freeMemory(pBuffer
);
1122 rtl_freeMemory(pBuffer
);
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
);
1151 //*********************************************************************
1154 RegError
ORegistry::checkBlop(OStoreStream
& rValue
,
1155 const OUString
& sTargetPath
,
1156 sal_uInt32 srcValueSize
,
1157 sal_uInt8
* pSrcBuffer
,
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
;
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
);
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
;
1212 if (reader2
.getFieldCount() > 0)
1214 rtl_freeMemory(pBuffer
);
1215 return REG_NO_ERROR
;
1218 rtl_freeMemory(pBuffer
);
1219 return REG_MERGE_CONFLICT
;
1223 rtl_freeMemory(pBuffer
);
1227 fprintf(stdout
, "WARNING: value of key \"%s\" already exists.\n",
1228 targetPath
.getStr());
1230 return REG_MERGE_CONFLICT
;
1234 rtl_freeMemory(pBuffer
);
1237 fprintf(stdout
, "ERROR: values of key \"%s\" contains bad data.\n",
1238 targetPath
.getStr());
1240 return REG_MERGE_ERROR
;
1244 rtl_freeMemory(pBuffer
);
1247 fprintf(stdout
, "ERROR: values of key \"%s\" has different types.\n",
1248 targetPath
.getStr());
1250 return REG_MERGE_ERROR
;
1254 rtl_freeMemory(pBuffer
);
1255 return REG_INVALID_VALUE
;
1259 static sal_uInt32
checkTypeReaders(RegistryTypeReader
& reader1
,
1260 RegistryTypeReader
& reader2
,
1261 std::set
< OUString
>& nameSet
)
1265 for (i
=0 ; i
< reader1
.getFieldCount(); i
++)
1267 nameSet
.insert(reader1
.getFieldName(i
));
1270 for (i
=0 ; i
< reader2
.getFieldCount(); i
++)
1272 if (nameSet
.find(reader2
.getFieldName(i
)) == nameSet
.end())
1274 nameSet
.insert(reader2
.getFieldName(i
));
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(),
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
));
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
));
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
);
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 //*********************************************************************
1360 RegError
ORegistry::loadAndSaveKeys(ORegKey
* pTargetKey
,
1361 ORegKey
* pSourceKey
,
1362 const OUString
& keyName
,
1368 RegError _ret
= REG_NO_ERROR
;
1369 OUString
sRelPath(pSourceKey
->getName().copy(nCut
));
1372 if(pTargetKey
->getName().getLength() > 1)
1373 sFullPath
+= pTargetKey
->getName();
1374 sFullPath
+= sRelPath
;
1375 if (sRelPath
.getLength() > 1 || sFullPath
.getLength() == 0)
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
);
1400 OStoreDirectory::iterator iter
;
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
);
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
);
1426 _err
= rTmpStoreDir
.next(iter
);
1429 pSourceKey
->closeKey(pTmpKey
);
1434 //*********************************************************************
1437 ORegKey
* ORegistry::getRootKey()
1439 m_openKeyTable
[ROOT
]->acquire();
1440 return m_openKeyTable
[ROOT
];
1444 //*********************************************************************
1447 RegError
ORegistry::dumpRegistry(RegKeyHandle hKey
) const
1449 ORegKey
*pKey
= (ORegKey
*)hKey
;
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);
1469 _ret
= dumpValue(pKey
->getName(), sName
, 1);
1477 _err
= rStoreDir
.next(iter
);
1480 return REG_NO_ERROR
;
1484 //*********************************************************************
1487 RegError
ORegistry::dumpValue(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpc
) const
1489 OStoreStream rValue
;
1491 sal_uInt32 valueSize
;
1492 RegValueType valueType
;
1493 OUString
sFullPath(sPath
);
1495 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
1499 accessMode
= VALUE_MODE_OPENREAD
;
1502 for (int i
= 0; i
< nSpc
; i
++) sIndent
+= " ";
1504 if (sFullPath
.getLength() > 1)
1508 if (rValue
.create(m_file
, sFullPath
, sName
, accessMode
))
1510 return REG_VALUE_NOT_EXISTS
;
1513 pBuffer
= (sal_uInt8
*)rtl_allocateMemory(VALUE_HEADERSIZE
);
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();
1547 fprintf(stdout
, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent
);
1551 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_LONG\n", indent
);
1553 stdout
, "%s Size = %lu\n", indent
,
1554 sal::static_int_cast
< unsigned long >(valueSize
));
1555 fprintf(stdout
, "%s Data = ", indent
);
1558 readINT32(pBuffer
, value
);
1559 fprintf(stdout
, "%ld\n", sal::static_int_cast
< long >(value
));
1564 sal_Char
* value
= (sal_Char
*)rtl_allocateMemory(valueSize
);
1565 readUtf8(pBuffer
, value
, valueSize
);
1566 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_STRING\n", indent
);
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
);
1576 sal_uInt32 size
= (valueSize
/ 2) * sizeof(sal_Unicode
);
1577 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_UNICODE\n", indent
);
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());
1593 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_BINARY\n", indent
);
1595 stdout
, "%s Size = %lu\n", indent
,
1596 sal::static_int_cast
< unsigned long >(valueSize
));
1597 fprintf(stdout
, "%s Data = ", indent
);
1600 pBuffer
, valueSize
, false, TYPEREG_VERSION_1
),
1606 sal_uInt32 offset
= 4; // initial 4 Bytes fuer die Laenge des Arrays
1609 readUINT32(pBuffer
, len
);
1611 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_LONGLIST\n", indent
);
1613 stdout
, "%s Size = %lu\n", indent
,
1614 sal::static_int_cast
< unsigned long >(valueSize
));
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
);
1626 fprintf(stdout
, "%s ", indent
);
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
1638 sal_uInt32 offset
= 4; // initial 4 Bytes fuer die Laenge des Arrays
1639 sal_uInt32 sLen
= 0;
1642 readUINT32(pBuffer
, len
);
1644 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_STRINGLIST\n", indent
);
1646 stdout
, "%s Size = %lu\n", indent
,
1647 sal::static_int_cast
< unsigned long >(valueSize
));
1649 stdout
, "%s Len = %lu\n", indent
,
1650 sal::static_int_cast
< unsigned long >(len
));
1651 fprintf(stdout
, "%s Data = ", indent
);
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
);
1664 fprintf(stdout
, "%s ", indent
);
1667 stdout
, "%lu = \"%s\"\n",
1668 sal::static_int_cast
< unsigned long >(i
), pValue
);
1675 sal_uInt32 offset
= 4; // initial 4 Bytes fuer die Laenge des Arrays
1676 sal_uInt32 sLen
= 0;
1679 readUINT32(pBuffer
, len
);
1681 fprintf(stdout
, "%sValue: Type = RG_VALUETYPE_UNICODELIST\n", indent
);
1683 stdout
, "%s Size = %lu\n", indent
,
1684 sal::static_int_cast
< unsigned long >(valueSize
));
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
;
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
);
1702 fprintf(stdout
, "%s ", indent
);
1704 uStr
= OUStringToOString(pValue
, RTL_TEXTENCODING_UTF8
);
1706 stdout
, "%lu = L\"%s\"\n",
1707 sal::static_int_cast
< unsigned long >(i
),
1712 rtl_freeMemory(pValue
);
1718 fprintf(stdout
, "\n");
1720 rtl_freeMemory(pBuffer
);
1721 return REG_NO_ERROR
;
1724 //*********************************************************************
1727 RegError
ORegistry::dumpKey(const OUString
& sPath
, const OUString
& sName
, sal_Int16 nSpace
) const
1729 OStoreDirectory rStoreDir
;
1730 OUString
sFullPath(sPath
);
1732 storeAccessMode accessMode
= KEY_MODE_OPEN
;
1733 RegError _ret
= REG_NO_ERROR
;
1737 accessMode
= KEY_MODE_OPENREAD
;
1740 for (int i
= 0; i
< nSpace
; i
++) sIndent
+= " ";
1742 if (sFullPath
.getLength() > 1)
1745 storeError _err
= rStoreDir
.create(m_file
, sFullPath
, sName
, accessMode
);
1747 if (_err
== store_E_NotExists
)
1748 return REG_KEY_NOT_EXISTS
;
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
);
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);
1772 _ret
= dumpValue(sSubPath
, sSubName
, nSpace
+2);
1780 _err
= rStoreDir
.next(iter
);
1783 return REG_NO_ERROR
;