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 .
23 #include "keyimpl.hxx"
25 #include "reflcnst.hxx"
26 #include "rtl/alloc.h"
27 #include "rtl/ustrbuf.hxx"
28 #include <osl/diagnose.h>
29 #include <sal/log.hxx>
31 using namespace store
;
33 namespace { static char const VALUE_PREFIX
[] = "$VL_"; }
38 ORegKey::ORegKey(const OUString
& keyName
, ORegistry
* pReg
)
52 SAL_WARN_IF(m_refCount
!= 0, "registry", "registry::ORegKey::dtor(): refcount not zero.");
58 RegError
ORegKey::releaseKey(RegKeyHandle hKey
)
60 return m_pRegistry
->releaseKey(hKey
);
66 RegError
ORegKey::createKey(const OUString
& keyName
, RegKeyHandle
* phNewKey
)
68 return m_pRegistry
->createKey(this, keyName
, phNewKey
);
75 RegError
ORegKey::openKey(const OUString
& keyName
, RegKeyHandle
* phOpenKey
)
77 return m_pRegistry
->openKey(this, keyName
, phOpenKey
);
84 RegError
ORegKey::openSubKeys(const OUString
& keyName
, RegKeyHandle
** phOpenSubKeys
, sal_uInt32
* pnSubKeys
)
86 RegError _ret
= RegError::NO_ERROR
;
92 if ( !keyName
.isEmpty() )
94 _ret
= openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pKey
));
95 if (_ret
!= RegError::NO_ERROR
)
99 sal_uInt32 nSubKeys
= pKey
->countSubKeys();
100 *pnSubKeys
= nSubKeys
;
103 pSubKeys
= static_cast<ORegKey
**>(rtl_allocateZeroMemory(nSubKeys
* sizeof(ORegKey
*)));
105 OStoreDirectory::iterator iter
;
106 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
107 storeError _err
= rStoreDir
.first(iter
);
110 while ( _err
== store_E_None
)
112 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
114 OUString
const sSubKeyName
= iter
.m_pszName
;
116 ORegKey
* pOpenSubKey
= 0;
117 _ret
= pKey
->openKey(sSubKeyName
, reinterpret_cast<RegKeyHandle
*>(&pOpenSubKey
));
118 if (_ret
!= RegError::NO_ERROR
)
120 *phOpenSubKeys
= NULL
;
122 rtl_freeMemory(pSubKeys
); // @@@ leaking 'pSubKeys[0...nSubkeys-1]'
123 return _ret
; // @@@ leaking 'pKey'
126 pSubKeys
[nSubKeys
] = pOpenSubKey
;
131 _err
= rStoreDir
.next(iter
);
134 *phOpenSubKeys
= reinterpret_cast<RegKeyHandle
*>(pSubKeys
);
135 if (!keyName
.isEmpty())
137 (void) releaseKey(pKey
);
139 return RegError::NO_ERROR
;
146 RegError
ORegKey::getKeyNames(const OUString
& keyName
,
147 rtl_uString
*** pSubKeyNames
,
148 sal_uInt32
* pnSubKeys
)
150 RegError _ret
= RegError::NO_ERROR
;
155 ORegKey
* pKey
= this;
156 if (!keyName
.isEmpty())
158 _ret
= openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pKey
));
159 if (_ret
!= RegError::NO_ERROR
)
163 sal_uInt32 nSubKeys
= pKey
->countSubKeys();
164 *pnSubKeys
= nSubKeys
;
166 rtl_uString
** pSubKeys
= 0;
167 pSubKeys
= static_cast<rtl_uString
**>(rtl_allocateZeroMemory(nSubKeys
* sizeof(rtl_uString
*)));
169 OStoreDirectory::iterator iter
;
170 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
171 storeError _err
= rStoreDir
.first(iter
);
175 while ( _err
== store_E_None
)
177 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
179 OUString
const sSubKeyName
= iter
.m_pszName
;
181 OUString
sFullKeyName(pKey
->getName());
182 if (sFullKeyName
.getLength() > 1)
183 sFullKeyName
+= m_pRegistry
->ROOT
;
184 sFullKeyName
+= sSubKeyName
;
186 rtl_uString_newFromString(&pSubKeys
[nSubKeys
], sFullKeyName
.pData
);
191 _err
= rStoreDir
.next(iter
);
194 *pSubKeyNames
= pSubKeys
;
195 if (!keyName
.isEmpty())
199 return RegError::NO_ERROR
;
206 RegError
ORegKey::closeKey(RegKeyHandle hKey
)
208 return (m_pRegistry
->closeKey(hKey
));
215 RegError
ORegKey::deleteKey(const OUString
& keyName
)
217 return (m_pRegistry
->deleteKey(this, keyName
));
224 RegError
ORegKey::getValueInfo(const OUString
& valueName
, RegValueType
* pValueType
, sal_uInt32
* pValueSize
) const
228 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
230 if (m_pRegistry
->isReadOnly())
232 accessMode
= VALUE_MODE_OPENREAD
;
235 OUString
sImplValueName( VALUE_PREFIX
);
236 sImplValueName
+= valueName
;
238 REG_GUARD(m_pRegistry
->m_mutex
);
240 if ( rValue
.create(m_pRegistry
->getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, accessMode
) )
242 *pValueType
= RegValueType::NOT_DEFINED
;
244 return RegError::VALUE_NOT_EXISTS
;
247 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
249 sal_uInt32 readBytes
;
250 if ( rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, readBytes
) )
252 rtl_freeMemory(pBuffer
);
253 return RegError::INVALID_VALUE
;
255 if (readBytes
!= VALUE_HEADERSIZE
)
257 rtl_freeMemory(pBuffer
);
258 return RegError::INVALID_VALUE
;
262 sal_uInt8 type
= *pBuffer
;
263 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, size
);
265 *pValueType
= (RegValueType
)type
;
266 // if (*pValueType == RegValueType::UNICODE)
268 // *pValueSize = (size / 2) * sizeof(sal_Unicode);
271 if (*pValueType
> RegValueType::BINARY
)
273 rtl_freeMemory(pBuffer
);
274 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(4));
275 rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, 4, readBytes
);
277 readUINT32(pBuffer
, size
);
283 rtl_freeMemory(pBuffer
);
284 return RegError::NO_ERROR
;
291 RegError
ORegKey::setValue(const OUString
& valueName
, RegValueType vType
, RegValue value
, sal_uInt32 vSize
)
296 if (m_pRegistry
->isReadOnly())
298 return RegError::REGISTRY_READONLY
;
301 if (vType
> RegValueType::BINARY
)
303 return RegError::INVALID_VALUE
;
306 OUString
sImplValueName( VALUE_PREFIX
);
307 sImplValueName
+= valueName
;
309 REG_GUARD(m_pRegistry
->m_mutex
);
311 if ( rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, VALUE_MODE_CREATE
) )
313 return RegError::SET_VALUE_FAILED
;
316 sal_uInt32 size
= vSize
;
318 sal_uInt8 type
= (sal_uInt8
)vType
;
319 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
+ size
));
320 memcpy(pBuffer
, &type
, 1);
322 writeUINT32(pBuffer
+VALUE_TYPEOFFSET
, size
);
326 case RegValueType::NOT_DEFINED
:
327 memcpy(pBuffer
+VALUE_HEADEROFFSET
, value
, size
);
329 case RegValueType::LONG
:
330 writeINT32(pBuffer
+VALUE_HEADEROFFSET
, *static_cast<sal_Int32
*>(value
));
332 case RegValueType::STRING
:
333 writeUtf8(pBuffer
+VALUE_HEADEROFFSET
, static_cast<const sal_Char
*>(value
));
335 case RegValueType::UNICODE
:
336 writeString(pBuffer
+VALUE_HEADEROFFSET
, static_cast<const sal_Unicode
*>(value
));
338 case RegValueType::BINARY
:
339 memcpy(pBuffer
+VALUE_HEADEROFFSET
, value
, size
);
346 sal_uInt32 writenBytes
;
347 if ( rValue
.writeAt(0, pBuffer
, VALUE_HEADERSIZE
+size
, writenBytes
) )
349 rtl_freeMemory(pBuffer
);
350 return RegError::SET_VALUE_FAILED
;
352 if (writenBytes
!= (VALUE_HEADERSIZE
+size
))
354 rtl_freeMemory(pBuffer
);
355 return RegError::SET_VALUE_FAILED
;
359 rtl_freeMemory(pBuffer
);
360 return RegError::NO_ERROR
;
366 RegError
ORegKey::setLongListValue(const OUString
& valueName
, sal_Int32
* pValueList
, sal_uInt32 len
)
371 if (m_pRegistry
->isReadOnly())
373 return RegError::REGISTRY_READONLY
;
376 OUString
sImplValueName( VALUE_PREFIX
);
377 sImplValueName
+= valueName
;
379 REG_GUARD(m_pRegistry
->m_mutex
);
381 if (rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, VALUE_MODE_CREATE
) )
383 return RegError::SET_VALUE_FAILED
;
386 sal_uInt32 size
= 4; // 4 bytes (sal_uInt32) for the length
390 sal_uInt8 type
= (sal_uInt8
)RegValueType::LONGLIST
;
391 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
+ size
));
392 memcpy(pBuffer
, &type
, 1);
394 writeUINT32(pBuffer
+VALUE_TYPEOFFSET
, size
);
395 writeUINT32(pBuffer
+VALUE_HEADEROFFSET
, len
);
397 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
399 for (sal_uInt32 i
=0; i
< len
; i
++)
401 writeINT32(pBuffer
+VALUE_HEADEROFFSET
+offset
, pValueList
[i
]);
405 sal_uInt32 writenBytes
;
406 if ( rValue
.writeAt(0, pBuffer
, VALUE_HEADERSIZE
+size
, writenBytes
) )
408 rtl_freeMemory(pBuffer
);
409 return RegError::SET_VALUE_FAILED
;
411 if (writenBytes
!= (VALUE_HEADEROFFSET
+size
))
413 rtl_freeMemory(pBuffer
);
414 return RegError::SET_VALUE_FAILED
;
418 rtl_freeMemory(pBuffer
);
419 return RegError::NO_ERROR
;
423 // setStringListValue
425 RegError
ORegKey::setStringListValue(const OUString
& valueName
, sal_Char
** pValueList
, sal_uInt32 len
)
430 if (m_pRegistry
->isReadOnly())
432 return RegError::REGISTRY_READONLY
;
435 OUString
sImplValueName( VALUE_PREFIX
);
436 sImplValueName
+= valueName
;
438 REG_GUARD(m_pRegistry
->m_mutex
);
440 if (rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, VALUE_MODE_CREATE
) )
442 return RegError::SET_VALUE_FAILED
;
445 sal_uInt32 size
= 4; // 4 bytes (sal_uInt32) for the length
448 for (i
=0; i
< len
; i
++)
450 size
+= 4 + strlen(pValueList
[i
]) + 1;
453 sal_uInt8 type
= (sal_uInt8
)RegValueType::STRINGLIST
;
454 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
+ size
));
455 memcpy(pBuffer
, &type
, 1);
457 writeUINT32(pBuffer
+VALUE_TYPEOFFSET
, size
);
458 writeUINT32(pBuffer
+VALUE_HEADEROFFSET
, len
);
460 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
463 for (i
=0; i
< len
; i
++)
465 sLen
= strlen(pValueList
[i
]) + 1;
466 writeUINT32(pBuffer
+VALUE_HEADEROFFSET
+offset
, sLen
);
469 writeUtf8(pBuffer
+VALUE_HEADEROFFSET
+offset
, pValueList
[i
]);
473 sal_uInt32 writenBytes
;
474 if ( rValue
.writeAt(0, pBuffer
, VALUE_HEADERSIZE
+size
, writenBytes
) )
476 rtl_freeMemory(pBuffer
);
477 return RegError::SET_VALUE_FAILED
;
479 if (writenBytes
!= (VALUE_HEADERSIZE
+size
))
481 rtl_freeMemory(pBuffer
);
482 return RegError::SET_VALUE_FAILED
;
486 rtl_freeMemory(pBuffer
);
487 return RegError::NO_ERROR
;
491 // setUnicodeListValue
493 RegError
ORegKey::setUnicodeListValue(const OUString
& valueName
, sal_Unicode
** pValueList
, sal_uInt32 len
)
498 if (m_pRegistry
->isReadOnly())
500 return RegError::REGISTRY_READONLY
;
503 OUString
sImplValueName( VALUE_PREFIX
);
504 sImplValueName
+= valueName
;
506 REG_GUARD(m_pRegistry
->m_mutex
);
508 if (rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, VALUE_MODE_CREATE
) )
510 return RegError::SET_VALUE_FAILED
;
513 sal_uInt32 size
= 4; // 4 bytes (sal_uInt32) for the length
516 for (i
=0; i
< len
; i
++)
518 size
+= 4 + ((rtl_ustr_getLength(pValueList
[i
]) +1) * 2);
521 sal_uInt8 type
= (sal_uInt8
)RegValueType::UNICODELIST
;
522 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
+ size
));
523 memcpy(pBuffer
, &type
, 1);
525 writeUINT32(pBuffer
+VALUE_TYPEOFFSET
, size
);
526 writeUINT32(pBuffer
+VALUE_HEADEROFFSET
, len
);
528 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
531 for (i
=0; i
< len
; i
++)
533 sLen
= (rtl_ustr_getLength(pValueList
[i
]) + 1) * 2;
534 writeUINT32(pBuffer
+VALUE_HEADEROFFSET
+offset
, sLen
);
537 writeString(pBuffer
+VALUE_HEADEROFFSET
+offset
, pValueList
[i
]);
541 sal_uInt32 writenBytes
;
542 if ( rValue
.writeAt(0, pBuffer
, VALUE_HEADERSIZE
+size
, writenBytes
) )
544 rtl_freeMemory(pBuffer
);
545 return RegError::SET_VALUE_FAILED
;
547 if (writenBytes
!= (VALUE_HEADERSIZE
+size
))
549 rtl_freeMemory(pBuffer
);
550 return RegError::SET_VALUE_FAILED
;
554 rtl_freeMemory(pBuffer
);
555 return RegError::NO_ERROR
;
561 RegError
ORegKey::getValue(const OUString
& valueName
, RegValue value
) const
565 RegValueType valueType
;
566 sal_uInt32 valueSize
;
567 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
569 if (m_pRegistry
->isReadOnly())
571 accessMode
= VALUE_MODE_OPENREAD
;
574 OUString
sImplValueName( VALUE_PREFIX
);
575 sImplValueName
+= valueName
;
577 REG_GUARD(m_pRegistry
->m_mutex
);
579 if (rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, accessMode
) )
581 return RegError::VALUE_NOT_EXISTS
;
584 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
586 sal_uInt32 readBytes
;
587 if ( rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, readBytes
) )
589 rtl_freeMemory(pBuffer
);
590 return RegError::INVALID_VALUE
;
592 if (readBytes
!= VALUE_HEADERSIZE
)
594 rtl_freeMemory(pBuffer
);
595 return RegError::INVALID_VALUE
;
598 sal_uInt8 type
= *pBuffer
;
599 valueType
= (RegValueType
)type
;
600 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
602 rtl_freeMemory(pBuffer
);
604 if (valueType
> RegValueType::BINARY
)
606 return RegError::INVALID_VALUE
;
609 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(valueSize
));
611 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, valueSize
, readBytes
) )
613 rtl_freeMemory(pBuffer
);
614 return RegError::INVALID_VALUE
;
616 if (readBytes
!= valueSize
)
618 rtl_freeMemory(pBuffer
);
619 return RegError::INVALID_VALUE
;
624 case RegValueType::NOT_DEFINED
:
625 memcpy(value
, pBuffer
, valueSize
);
627 case RegValueType::LONG
:
628 readINT32(pBuffer
, *static_cast<sal_Int32
*>(value
));
630 case RegValueType::STRING
:
631 readUtf8(pBuffer
, static_cast<sal_Char
*>(value
), valueSize
);
633 case RegValueType::UNICODE
:
634 readString(pBuffer
, static_cast<sal_Unicode
*>(value
), valueSize
);
636 case RegValueType::BINARY
:
637 memcpy(value
, pBuffer
, valueSize
);
639 // coverity[dead_error_begin] - following conditions exist to avoid compiler warning
640 case RegValueType::LONGLIST
:
641 case RegValueType::STRINGLIST
:
642 case RegValueType::UNICODELIST
:
643 memcpy(value
, pBuffer
, valueSize
);
648 rtl_freeMemory(pBuffer
);
649 return RegError::NO_ERROR
;
655 RegError
ORegKey::getLongListValue(const OUString
& valueName
, sal_Int32
** pValueList
, sal_uInt32
* pLen
) const
659 RegValueType valueType
;
660 sal_uInt32 valueSize
;
661 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
663 if (m_pRegistry
->isReadOnly())
665 accessMode
= VALUE_MODE_OPENREAD
;
668 OUString
sImplValueName( VALUE_PREFIX
);
669 sImplValueName
+= valueName
;
671 REG_GUARD(m_pRegistry
->m_mutex
);
673 if (rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, accessMode
) )
677 return RegError::VALUE_NOT_EXISTS
;
680 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
682 sal_uInt32 readBytes
;
683 if ( rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, readBytes
) )
687 rtl_freeMemory(pBuffer
);
688 return RegError::INVALID_VALUE
;
690 if (readBytes
!= VALUE_HEADERSIZE
)
694 rtl_freeMemory(pBuffer
);
695 return RegError::INVALID_VALUE
;
698 sal_uInt8 type
= *pBuffer
;
699 valueType
= (RegValueType
)type
;
701 if (valueType
!= RegValueType::LONGLIST
)
705 rtl_freeMemory(pBuffer
);
706 return RegError::INVALID_VALUE
;
709 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
711 rtl_freeMemory(pBuffer
);
713 /* check for 'reasonable' value */
714 /* surely 10 millions entry in a registry list should be enough */
715 if(valueSize
> 40000000)
719 rtl_freeMemory(pBuffer
);
720 return RegError::INVALID_VALUE
;
722 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(valueSize
));
724 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, valueSize
, readBytes
) )
728 rtl_freeMemory(pBuffer
);
729 return RegError::INVALID_VALUE
;
731 if (readBytes
!= valueSize
)
735 rtl_freeMemory(pBuffer
);
736 return RegError::INVALID_VALUE
;
740 readUINT32(pBuffer
, len
);
742 /* make sure the declared size of the arry is consistent with the amount of data we have read */
743 if(len
> (valueSize
- 4) / 4)
747 rtl_freeMemory(pBuffer
);
748 return RegError::INVALID_VALUE
;
751 sal_Int32
* pVList
= static_cast<sal_Int32
*>(rtl_allocateZeroMemory(len
* sizeof(sal_Int32
)));
753 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
755 for (sal_uInt32 i
= 0; i
< len
; i
++)
757 readINT32(pBuffer
+offset
, pVList
[i
]);
761 *pValueList
= pVList
;
762 rtl_freeMemory(pBuffer
);
763 return RegError::NO_ERROR
;
767 // getStringListValue
769 RegError
ORegKey::getStringListValue(const OUString
& valueName
, sal_Char
*** pValueList
, sal_uInt32
* pLen
) const
773 RegValueType valueType
;
774 sal_uInt32 valueSize
;
775 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
777 if (m_pRegistry
->isReadOnly())
779 accessMode
= VALUE_MODE_OPENREAD
;
782 OUString
sImplValueName( VALUE_PREFIX
);
783 sImplValueName
+= valueName
;
785 REG_GUARD(m_pRegistry
->m_mutex
);
787 if ( rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, accessMode
) )
791 return RegError::VALUE_NOT_EXISTS
;
794 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
796 sal_uInt32 readBytes
;
797 if ( rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, readBytes
) )
801 rtl_freeMemory(pBuffer
);
802 return RegError::INVALID_VALUE
;
804 if (readBytes
!= VALUE_HEADERSIZE
)
808 rtl_freeMemory(pBuffer
);
809 return RegError::INVALID_VALUE
;
812 sal_uInt8 type
= *pBuffer
;
813 valueType
= (RegValueType
)type
;
815 if (valueType
!= RegValueType::STRINGLIST
)
819 rtl_freeMemory(pBuffer
);
820 return RegError::INVALID_VALUE
;
823 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
825 rtl_freeMemory(pBuffer
);
827 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(valueSize
));
829 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, valueSize
, readBytes
) )
833 rtl_freeMemory(pBuffer
);
834 return RegError::INVALID_VALUE
;
836 if (readBytes
!= valueSize
)
840 rtl_freeMemory(pBuffer
);
841 return RegError::INVALID_VALUE
;
845 readUINT32(pBuffer
, len
);
848 sal_Char
** pVList
= static_cast<sal_Char
**>(rtl_allocateZeroMemory(len
* sizeof(sal_Char
*)));
850 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
854 for (sal_uInt32 i
=0; i
< len
; i
++)
856 readUINT32(pBuffer
+offset
, sLen
);
860 pValue
= static_cast<sal_Char
*>(rtl_allocateMemory(sLen
));
861 readUtf8(pBuffer
+offset
, pValue
, sLen
);
867 *pValueList
= pVList
;
868 rtl_freeMemory(pBuffer
);
869 return RegError::NO_ERROR
;
873 // getUnicodeListValue
875 RegError
ORegKey::getUnicodeListValue(const OUString
& valueName
, sal_Unicode
*** pValueList
, sal_uInt32
* pLen
) const
879 RegValueType valueType
;
880 sal_uInt32 valueSize
;
881 storeAccessMode accessMode
= VALUE_MODE_OPEN
;
883 if (m_pRegistry
->isReadOnly())
885 accessMode
= VALUE_MODE_OPENREAD
;
888 OUString
sImplValueName( VALUE_PREFIX
);
889 sImplValueName
+= valueName
;
891 REG_GUARD(m_pRegistry
->m_mutex
);
893 if ( rValue
.create(getStoreFile(), m_name
+ m_pRegistry
->ROOT
, sImplValueName
, accessMode
) )
897 return RegError::VALUE_NOT_EXISTS
;
900 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(VALUE_HEADERSIZE
));
902 sal_uInt32 readBytes
;
903 if ( rValue
.readAt(0, pBuffer
, VALUE_HEADERSIZE
, readBytes
) )
907 rtl_freeMemory(pBuffer
);
908 return RegError::INVALID_VALUE
;
910 if (readBytes
!= VALUE_HEADERSIZE
)
914 rtl_freeMemory(pBuffer
);
915 return RegError::INVALID_VALUE
;
918 sal_uInt8 type
= *pBuffer
;
919 valueType
= (RegValueType
)type
;
921 if (valueType
!= RegValueType::UNICODELIST
)
925 rtl_freeMemory(pBuffer
);
926 return RegError::INVALID_VALUE
;
929 readUINT32(pBuffer
+VALUE_TYPEOFFSET
, valueSize
);
931 rtl_freeMemory(pBuffer
);
933 pBuffer
= static_cast<sal_uInt8
*>(rtl_allocateMemory(valueSize
));
935 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
, valueSize
, readBytes
) )
939 rtl_freeMemory(pBuffer
);
940 return RegError::INVALID_VALUE
;
942 if (readBytes
!= valueSize
)
946 rtl_freeMemory(pBuffer
);
947 return RegError::INVALID_VALUE
;
951 readUINT32(pBuffer
, len
);
954 sal_Unicode
** pVList
= static_cast<sal_Unicode
**>(rtl_allocateZeroMemory(len
* sizeof(sal_Unicode
*)));
956 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
960 for (sal_uInt32 i
=0; i
< len
; i
++)
962 readUINT32(pBuffer
+offset
, sLen
);
966 pValue
= static_cast<sal_Unicode
*>(rtl_allocateMemory((sLen
/ 2) * sizeof(sal_Unicode
)));
967 readString(pBuffer
+offset
, pValue
, sLen
);
973 *pValueList
= pVList
;
974 rtl_freeMemory(pBuffer
);
975 return RegError::NO_ERROR
;
979 RegError
ORegKey::getResolvedKeyName(const OUString
& keyName
,
980 OUString
& resolvedName
)
982 if (keyName
.isEmpty())
983 return RegError::INVALID_KEYNAME
;
985 resolvedName
= getFullPath(keyName
);
986 return RegError::NO_ERROR
;
992 sal_uInt32
ORegKey::countSubKeys()
994 REG_GUARD(m_pRegistry
->m_mutex
);
996 OStoreDirectory::iterator iter
;
997 OStoreDirectory rStoreDir
= getStoreDir();
998 storeError _err
= rStoreDir
.first(iter
);
999 sal_uInt32 count
= 0;
1001 while ( _err
== store_E_None
)
1003 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
1008 _err
= rStoreDir
.next(iter
);
1014 OStoreDirectory
ORegKey::getStoreDir()
1016 OStoreDirectory rStoreDir
;
1018 OUString relativName
;
1019 storeAccessMode accessMode
= KEY_MODE_OPEN
;
1021 if ( m_name
.equals(m_pRegistry
->ROOT
) )
1024 relativName
.clear();
1027 fullPath
= m_name
.copy(0, m_name
.lastIndexOf('/') + 1);
1028 relativName
= m_name
.copy(m_name
.lastIndexOf('/') + 1);
1031 if (m_pRegistry
->isReadOnly())
1033 accessMode
= KEY_MODE_OPENREAD
;
1036 rStoreDir
.create(getStoreFile(), fullPath
, relativName
, accessMode
);
1041 OUString
ORegKey::getFullPath(OUString
const & path
) const {
1042 OSL_ASSERT(!m_name
.isEmpty() && !path
.isEmpty());
1043 OUStringBuffer
b(m_name
);
1044 if (!b
.isEmpty() && b
[b
.getLength() - 1] == '/') {
1045 if (path
[0] == '/') {
1046 b
.append(path
.getStr() + 1, path
.getLength() - 1);
1051 if (path
[0] != '/') {
1056 return b
.makeStringAndClear();
1059 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */