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 .
22 #include <string_view>
24 #include "keyimpl.hxx"
26 #include "reflcnst.hxx"
27 #include <rtl/alloc.h>
28 #include <rtl/ustrbuf.hxx>
29 #include <osl/diagnose.h>
30 #include <sal/log.hxx>
34 using namespace store
;
36 namespace { char const VALUE_PREFIX
[] = "$VL_"; }
38 ORegKey::ORegKey(OUString keyName
, ORegistry
* pReg
)
40 , m_name(std::move(keyName
))
49 SAL_WARN_IF(m_refCount
!= 0, "registry", "registry::ORegKey::dtor(): refcount not zero.");
52 RegError
ORegKey::releaseKey(RegKeyHandle hKey
)
54 return m_pRegistry
->releaseKey(hKey
);
57 RegError
ORegKey::createKey(std::u16string_view keyName
, RegKeyHandle
* phNewKey
)
59 return m_pRegistry
->createKey(this, keyName
, phNewKey
);
62 RegError
ORegKey::openKey(std::u16string_view keyName
, RegKeyHandle
* phOpenKey
)
64 return m_pRegistry
->openKey(this, keyName
, phOpenKey
);
67 RegError
ORegKey::openSubKeys(std::u16string_view keyName
, RegKeyHandle
** phOpenSubKeys
, sal_uInt32
* pnSubKeys
)
69 RegError _ret
= RegError::NO_ERROR
;
71 *phOpenSubKeys
= nullptr;
75 if ( !keyName
.empty() )
77 _ret
= openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pKey
));
78 if (_ret
!= RegError::NO_ERROR
)
82 sal_uInt32 nSubKeys
= pKey
->countSubKeys();
83 *pnSubKeys
= nSubKeys
;
86 pSubKeys
= static_cast<ORegKey
**>(rtl_allocateZeroMemory(nSubKeys
* sizeof(ORegKey
*)));
88 OStoreDirectory::iterator iter
;
89 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
90 storeError _err
= rStoreDir
.first(iter
);
93 while ( _err
== store_E_None
)
95 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
97 OUString
const sSubKeyName(iter
.m_pszName
, iter
.m_nLength
);
99 ORegKey
* pOpenSubKey
= nullptr;
100 _ret
= pKey
->openKey(sSubKeyName
, reinterpret_cast<RegKeyHandle
*>(&pOpenSubKey
));
101 if (_ret
!= RegError::NO_ERROR
)
103 *phOpenSubKeys
= nullptr;
105 std::free(pSubKeys
); // @@@ leaking 'pSubKeys[0...nSubkeys-1]'
106 return _ret
; // @@@ leaking 'pKey'
109 pSubKeys
[nSubKeys
] = pOpenSubKey
;
114 _err
= rStoreDir
.next(iter
);
117 *phOpenSubKeys
= reinterpret_cast<RegKeyHandle
*>(pSubKeys
);
118 if (!keyName
.empty())
120 (void) releaseKey(pKey
);
122 return RegError::NO_ERROR
;
125 RegError
ORegKey::getKeyNames(std::u16string_view keyName
,
126 rtl_uString
*** pSubKeyNames
,
127 sal_uInt32
* pnSubKeys
)
129 *pSubKeyNames
= nullptr;
132 ORegKey
* pKey
= this;
133 if (!keyName
.empty())
135 RegError _ret
= openKey(keyName
, reinterpret_cast<RegKeyHandle
*>(&pKey
));
136 if (_ret
!= RegError::NO_ERROR
)
140 sal_uInt32 nSubKeys
= pKey
->countSubKeys();
141 *pnSubKeys
= nSubKeys
;
143 rtl_uString
** pSubKeys
144 = static_cast<rtl_uString
**>(rtl_allocateZeroMemory(nSubKeys
* sizeof(rtl_uString
*)));
146 OStoreDirectory::iterator iter
;
147 OStoreDirectory
rStoreDir(pKey
->getStoreDir());
148 storeError _err
= rStoreDir
.first(iter
);
152 while ( _err
== store_E_None
)
154 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
156 OUString
const sSubKeyName(iter
.m_pszName
, iter
.m_nLength
);
158 OUString
sFullKeyName(pKey
->getName());
159 if (sFullKeyName
.getLength() > 1)
160 sFullKeyName
+= ORegistry::ROOT
;
161 sFullKeyName
+= sSubKeyName
;
163 rtl_uString_newFromString(&pSubKeys
[nSubKeys
], sFullKeyName
.pData
);
168 _err
= rStoreDir
.next(iter
);
171 *pSubKeyNames
= pSubKeys
;
172 if (!keyName
.empty())
176 return RegError::NO_ERROR
;
179 RegError
ORegKey::closeKey(RegKeyHandle hKey
)
181 return m_pRegistry
->closeKey(hKey
);
184 RegError
ORegKey::deleteKey(std::u16string_view keyName
)
186 return m_pRegistry
->deleteKey(this, keyName
);
189 RegError
ORegKey::getValueInfo(std::u16string_view valueName
, RegValueType
* pValueType
, sal_uInt32
* pValueSize
) const
192 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
193 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
195 if (m_pRegistry
->isReadOnly())
197 accessMode
= storeAccessMode::ReadOnly
;
200 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
202 REG_GUARD(m_pRegistry
->m_mutex
);
204 if ( rValue
.create(m_pRegistry
->getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, accessMode
) )
206 *pValueType
= RegValueType::NOT_DEFINED
;
208 return RegError::VALUE_NOT_EXISTS
;
211 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
]);
213 sal_uInt32 readBytes
;
214 if ( rValue
.readAt(0, pBuffer
.get(), VALUE_HEADERSIZE
, readBytes
) )
216 return RegError::INVALID_VALUE
;
218 if (readBytes
!= VALUE_HEADERSIZE
)
220 return RegError::INVALID_VALUE
;
224 sal_uInt8 type
= pBuffer
[0];
225 readUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, size
);
227 *pValueType
= static_cast<RegValueType
>(type
);
228 if (*pValueType
> RegValueType::BINARY
)
230 pBuffer
.reset(new sal_uInt8
[4]);
231 rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
.get(), 4, readBytes
);
233 readUINT32(pBuffer
.get(), size
);
238 return RegError::NO_ERROR
;
241 RegError
ORegKey::setValue(std::u16string_view valueName
, RegValueType vType
, RegValue value
, sal_uInt32 vSize
)
244 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
246 if (m_pRegistry
->isReadOnly())
248 return RegError::REGISTRY_READONLY
;
251 if (vType
> RegValueType::BINARY
)
253 return RegError::INVALID_VALUE
;
256 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
258 REG_GUARD(m_pRegistry
->m_mutex
);
260 if ( rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, storeAccessMode::Create
) )
262 return RegError::SET_VALUE_FAILED
;
265 sal_uInt32 size
= vSize
;
267 sal_uInt8 type
= static_cast<sal_uInt8
>(vType
);
268 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
+ size
]);
269 memcpy(pBuffer
.get(), &type
, 1);
271 writeUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, size
);
275 case RegValueType::NOT_DEFINED
:
276 memcpy(pBuffer
.get()+VALUE_HEADEROFFSET
, value
, size
);
278 case RegValueType::LONG
:
279 writeINT32(pBuffer
.get()+VALUE_HEADEROFFSET
, *static_cast<sal_Int32
*>(value
));
281 case RegValueType::STRING
:
282 writeUtf8(pBuffer
.get()+VALUE_HEADEROFFSET
, static_cast<const char*>(value
));
284 case RegValueType::UNICODE
:
285 writeString(pBuffer
.get()+VALUE_HEADEROFFSET
, static_cast<const sal_Unicode
*>(value
));
287 case RegValueType::BINARY
:
288 memcpy(pBuffer
.get()+VALUE_HEADEROFFSET
, value
, size
);
295 sal_uInt32 writenBytes
;
296 if ( rValue
.writeAt(0, pBuffer
.get(), VALUE_HEADERSIZE
+size
, writenBytes
) )
298 return RegError::SET_VALUE_FAILED
;
300 if (writenBytes
!= (VALUE_HEADERSIZE
+size
))
302 return RegError::SET_VALUE_FAILED
;
306 return RegError::NO_ERROR
;
309 RegError
ORegKey::setLongListValue(std::u16string_view valueName
, sal_Int32
const * pValueList
, sal_uInt32 len
)
312 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
314 if (m_pRegistry
->isReadOnly())
316 return RegError::REGISTRY_READONLY
;
319 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
321 REG_GUARD(m_pRegistry
->m_mutex
);
323 if (rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, storeAccessMode::Create
) )
325 return RegError::SET_VALUE_FAILED
;
328 sal_uInt32 size
= 4; // 4 bytes (sal_uInt32) for the length
332 sal_uInt8 type
= sal_uInt8(RegValueType::LONGLIST
);
333 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
+ size
]);
334 memcpy(pBuffer
.get(), &type
, 1);
336 writeUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, size
);
337 writeUINT32(pBuffer
.get()+VALUE_HEADEROFFSET
, len
);
339 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array
341 for (sal_uInt32 i
=0; i
< len
; i
++)
343 writeINT32(pBuffer
.get()+VALUE_HEADEROFFSET
+offset
, pValueList
[i
]);
347 sal_uInt32 writenBytes
;
348 if ( rValue
.writeAt(0, pBuffer
.get(), VALUE_HEADERSIZE
+size
, writenBytes
) )
350 return RegError::SET_VALUE_FAILED
;
352 if (writenBytes
!= (VALUE_HEADEROFFSET
+size
))
354 return RegError::SET_VALUE_FAILED
;
358 return RegError::NO_ERROR
;
361 RegError
ORegKey::setStringListValue(
362 std::u16string_view valueName
, char** pValueList
, sal_uInt32 len
)
365 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
367 if (m_pRegistry
->isReadOnly())
369 return RegError::REGISTRY_READONLY
;
372 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
374 REG_GUARD(m_pRegistry
->m_mutex
);
376 if (rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, storeAccessMode::Create
) )
378 return RegError::SET_VALUE_FAILED
;
381 sal_uInt32 size
= 4; // 4 bytes (sal_uInt32) for the length
384 for (i
=0; i
< len
; i
++)
386 size
+= 4 + strlen(pValueList
[i
]) + 1;
389 sal_uInt8 type
= sal_uInt8(RegValueType::STRINGLIST
);
390 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
+ size
]);
391 memcpy(pBuffer
.get(), &type
, 1);
393 writeUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, size
);
394 writeUINT32(pBuffer
.get()+VALUE_HEADEROFFSET
, len
);
396 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
399 for (i
=0; i
< len
; i
++)
401 sLen
= strlen(pValueList
[i
]) + 1;
402 writeUINT32(pBuffer
.get()+VALUE_HEADEROFFSET
+offset
, sLen
);
405 writeUtf8(pBuffer
.get()+VALUE_HEADEROFFSET
+offset
, pValueList
[i
]);
409 sal_uInt32 writenBytes
;
410 if ( rValue
.writeAt(0, pBuffer
.get(), VALUE_HEADERSIZE
+size
, writenBytes
) )
412 return RegError::SET_VALUE_FAILED
;
414 if (writenBytes
!= (VALUE_HEADERSIZE
+size
))
416 return RegError::SET_VALUE_FAILED
;
420 return RegError::NO_ERROR
;
423 RegError
ORegKey::setUnicodeListValue(std::u16string_view valueName
, sal_Unicode
** pValueList
, sal_uInt32 len
)
426 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
428 if (m_pRegistry
->isReadOnly())
430 return RegError::REGISTRY_READONLY
;
433 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
435 REG_GUARD(m_pRegistry
->m_mutex
);
437 if (rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, storeAccessMode::Create
) )
439 return RegError::SET_VALUE_FAILED
;
442 sal_uInt32 size
= 4; // 4 bytes (sal_uInt32) for the length
445 for (i
=0; i
< len
; i
++)
447 size
+= 4 + ((rtl_ustr_getLength(pValueList
[i
]) +1) * 2);
450 sal_uInt8 type
= sal_uInt8(RegValueType::UNICODELIST
);
451 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
+ size
]);
452 memcpy(pBuffer
.get(), &type
, 1);
454 writeUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, size
);
455 writeUINT32(pBuffer
.get()+VALUE_HEADEROFFSET
, len
);
457 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
460 for (i
=0; i
< len
; i
++)
462 sLen
= (rtl_ustr_getLength(pValueList
[i
]) + 1) * 2;
463 writeUINT32(pBuffer
.get()+VALUE_HEADEROFFSET
+offset
, sLen
);
466 writeString(pBuffer
.get()+VALUE_HEADEROFFSET
+offset
, pValueList
[i
]);
470 sal_uInt32 writenBytes
;
471 if ( rValue
.writeAt(0, pBuffer
.get(), VALUE_HEADERSIZE
+size
, writenBytes
) )
473 return RegError::SET_VALUE_FAILED
;
475 if (writenBytes
!= (VALUE_HEADERSIZE
+size
))
477 return RegError::SET_VALUE_FAILED
;
481 return RegError::NO_ERROR
;
484 RegError
ORegKey::getValue(std::u16string_view valueName
, RegValue value
) const
487 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
488 RegValueType valueType
;
489 sal_uInt32 valueSize
;
490 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
492 if (m_pRegistry
->isReadOnly())
494 accessMode
= storeAccessMode::ReadOnly
;
497 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
499 REG_GUARD(m_pRegistry
->m_mutex
);
501 if (rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, accessMode
) )
503 return RegError::VALUE_NOT_EXISTS
;
506 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
]);
508 sal_uInt32 readBytes
;
509 if ( rValue
.readAt(0, pBuffer
.get(), VALUE_HEADERSIZE
, readBytes
) )
511 return RegError::INVALID_VALUE
;
513 if (readBytes
!= VALUE_HEADERSIZE
)
515 return RegError::INVALID_VALUE
;
518 sal_uInt8 type
= pBuffer
[0];
519 valueType
= static_cast<RegValueType
>(type
);
520 readUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, valueSize
);
522 if (valueType
> RegValueType::BINARY
)
524 return RegError::INVALID_VALUE
;
527 pBuffer
.reset(new sal_uInt8
[valueSize
]);
529 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
.get(), valueSize
, readBytes
) )
531 return RegError::INVALID_VALUE
;
533 if (readBytes
!= valueSize
)
535 return RegError::INVALID_VALUE
;
540 case RegValueType::LONG
:
541 readINT32(pBuffer
.get(), *static_cast<sal_Int32
*>(value
));
543 case RegValueType::STRING
:
544 readUtf8(pBuffer
.get(), static_cast<char*>(value
), valueSize
);
546 case RegValueType::UNICODE
:
547 readString(pBuffer
.get(), static_cast<sal_Unicode
*>(value
), valueSize
);
549 case RegValueType::BINARY
:
550 memcpy(value
, pBuffer
.get(), valueSize
);
553 memcpy(value
, pBuffer
.get(), valueSize
);
557 return RegError::NO_ERROR
;
560 RegError
ORegKey::getLongListValue(std::u16string_view valueName
, sal_Int32
** pValueList
, sal_uInt32
* pLen
) const
563 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
564 RegValueType valueType
;
565 sal_uInt32 valueSize
;
566 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
568 if (m_pRegistry
->isReadOnly())
570 accessMode
= storeAccessMode::ReadOnly
;
573 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
575 REG_GUARD(m_pRegistry
->m_mutex
);
577 if (rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, accessMode
) )
579 pValueList
= nullptr;
581 return RegError::VALUE_NOT_EXISTS
;
584 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
]);
586 sal_uInt32 readBytes
;
587 if ( rValue
.readAt(0, pBuffer
.get(), VALUE_HEADERSIZE
, readBytes
) )
589 pValueList
= nullptr;
591 return RegError::INVALID_VALUE
;
593 if (readBytes
!= VALUE_HEADERSIZE
)
595 pValueList
= nullptr;
597 return RegError::INVALID_VALUE
;
600 sal_uInt8 type
= pBuffer
[0];
601 valueType
= static_cast<RegValueType
>(type
);
603 if (valueType
!= RegValueType::LONGLIST
)
605 pValueList
= nullptr;
607 return RegError::INVALID_VALUE
;
610 readUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, valueSize
);
612 /* check for 'reasonable' value */
613 /* surely 10 millions entry in a registry list should be enough */
614 if(valueSize
> 40000000)
616 pValueList
= nullptr;
618 return RegError::INVALID_VALUE
;
620 pBuffer
.reset(new sal_uInt8
[valueSize
]);
622 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
.get(), valueSize
, readBytes
) )
624 pValueList
= nullptr;
626 return RegError::INVALID_VALUE
;
628 if (readBytes
!= valueSize
)
630 pValueList
= nullptr;
632 return RegError::INVALID_VALUE
;
636 readUINT32(pBuffer
.get(), len
);
638 /* make sure the declared size of the array is consistent with the amount of data we have read */
639 if(len
> (valueSize
- 4) / 4)
641 pValueList
= nullptr;
643 return RegError::INVALID_VALUE
;
646 sal_Int32
* pVList
= static_cast<sal_Int32
*>(rtl_allocateZeroMemory(len
* sizeof(sal_Int32
)));
648 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
650 for (sal_uInt32 i
= 0; i
< len
; i
++)
652 readINT32(pBuffer
.get()+offset
, pVList
[i
]);
656 *pValueList
= pVList
;
657 return RegError::NO_ERROR
;
660 RegError
ORegKey::getStringListValue(std::u16string_view valueName
, char*** pValueList
, sal_uInt32
* pLen
) const
663 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
664 RegValueType valueType
;
665 sal_uInt32 valueSize
;
666 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
668 if (m_pRegistry
->isReadOnly())
670 accessMode
= storeAccessMode::ReadOnly
;
673 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
675 REG_GUARD(m_pRegistry
->m_mutex
);
677 if ( rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, accessMode
) )
679 pValueList
= nullptr;
681 return RegError::VALUE_NOT_EXISTS
;
684 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
]);
686 sal_uInt32 readBytes
;
687 if ( rValue
.readAt(0, pBuffer
.get(), VALUE_HEADERSIZE
, readBytes
) )
689 pValueList
= nullptr;
691 return RegError::INVALID_VALUE
;
693 if (readBytes
!= VALUE_HEADERSIZE
)
695 pValueList
= nullptr;
697 return RegError::INVALID_VALUE
;
700 sal_uInt8 type
= pBuffer
[0];
701 valueType
= static_cast<RegValueType
>(type
);
703 if (valueType
!= RegValueType::STRINGLIST
)
705 pValueList
= nullptr;
707 return RegError::INVALID_VALUE
;
710 readUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, valueSize
);
712 pBuffer
.reset(new sal_uInt8
[valueSize
]);
714 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
.get(), valueSize
, readBytes
) )
716 pValueList
= nullptr;
718 return RegError::INVALID_VALUE
;
720 if (readBytes
!= valueSize
)
722 pValueList
= nullptr;
724 return RegError::INVALID_VALUE
;
728 readUINT32(pBuffer
.get(), len
);
731 char** pVList
= static_cast<char**>(rtl_allocateZeroMemory(len
* sizeof(char*)));
733 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
737 for (sal_uInt32 i
=0; i
< len
; i
++)
739 readUINT32(pBuffer
.get()+offset
, sLen
);
743 pValue
= static_cast<char*>(std::malloc(sLen
));
744 readUtf8(pBuffer
.get()+offset
, pValue
, sLen
);
750 *pValueList
= pVList
;
751 return RegError::NO_ERROR
;
754 RegError
ORegKey::getUnicodeListValue(std::u16string_view valueName
, sal_Unicode
*** pValueList
, sal_uInt32
* pLen
) const
757 std::unique_ptr
<sal_uInt8
[]> pBuffer
;
758 RegValueType valueType
;
759 sal_uInt32 valueSize
;
760 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
762 if (m_pRegistry
->isReadOnly())
764 accessMode
= storeAccessMode::ReadOnly
;
767 OUString sImplValueName
= OUString::Concat(VALUE_PREFIX
) + valueName
;
769 REG_GUARD(m_pRegistry
->m_mutex
);
771 if ( rValue
.create(getStoreFile(), m_name
+ ORegistry::ROOT
, sImplValueName
, accessMode
) )
773 pValueList
= nullptr;
775 return RegError::VALUE_NOT_EXISTS
;
778 pBuffer
.reset(new sal_uInt8
[VALUE_HEADERSIZE
]);
780 sal_uInt32 readBytes
;
781 if ( rValue
.readAt(0, pBuffer
.get(), VALUE_HEADERSIZE
, readBytes
) )
783 pValueList
= nullptr;
785 return RegError::INVALID_VALUE
;
787 if (readBytes
!= VALUE_HEADERSIZE
)
789 pValueList
= nullptr;
791 return RegError::INVALID_VALUE
;
794 sal_uInt8 type
= pBuffer
[0];
795 valueType
= static_cast<RegValueType
>(type
);
797 if (valueType
!= RegValueType::UNICODELIST
)
799 pValueList
= nullptr;
801 return RegError::INVALID_VALUE
;
804 readUINT32(pBuffer
.get()+VALUE_TYPEOFFSET
, valueSize
);
806 pBuffer
.reset(new sal_uInt8
[valueSize
]);
808 if ( rValue
.readAt(VALUE_HEADEROFFSET
, pBuffer
.get(), valueSize
, readBytes
) )
810 pValueList
= nullptr;
812 return RegError::INVALID_VALUE
;
814 if (readBytes
!= valueSize
)
816 pValueList
= nullptr;
818 return RegError::INVALID_VALUE
;
822 readUINT32(pBuffer
.get(), len
);
825 sal_Unicode
** pVList
= static_cast<sal_Unicode
**>(rtl_allocateZeroMemory(len
* sizeof(sal_Unicode
*)));
827 sal_uInt32 offset
= 4; // initial 4 bytes for the size of the array;
831 for (sal_uInt32 i
=0; i
< len
; i
++)
833 readUINT32(pBuffer
.get()+offset
, sLen
);
837 pValue
= static_cast<sal_Unicode
*>(std::malloc((sLen
/ 2) * sizeof(sal_Unicode
)));
838 readString(pBuffer
.get()+offset
, pValue
, sLen
);
844 *pValueList
= pVList
;
845 return RegError::NO_ERROR
;
849 RegError
ORegKey::getResolvedKeyName(std::u16string_view keyName
,
850 OUString
& resolvedName
) const
853 return RegError::INVALID_KEYNAME
;
855 resolvedName
= getFullPath(keyName
);
856 return RegError::NO_ERROR
;
859 sal_uInt32
ORegKey::countSubKeys()
861 REG_GUARD(m_pRegistry
->m_mutex
);
863 OStoreDirectory::iterator iter
;
864 OStoreDirectory rStoreDir
= getStoreDir();
865 storeError _err
= rStoreDir
.first(iter
);
866 sal_uInt32 count
= 0;
868 while ( _err
== store_E_None
)
870 if ( iter
.m_nAttrib
& STORE_ATTRIB_ISDIR
)
875 _err
= rStoreDir
.next(iter
);
881 OStoreDirectory
ORegKey::getStoreDir() const
883 OStoreDirectory rStoreDir
;
885 OUString relativName
;
886 storeAccessMode accessMode
= storeAccessMode::ReadWrite
;
888 if ( m_name
== ORegistry::ROOT
)
894 fullPath
= m_name
.copy(0, m_name
.lastIndexOf('/') + 1);
895 relativName
= m_name
.copy(m_name
.lastIndexOf('/') + 1);
898 if (m_pRegistry
->isReadOnly())
900 accessMode
= storeAccessMode::ReadOnly
;
903 rStoreDir
.create(getStoreFile(), fullPath
, relativName
, accessMode
);
908 OUString
ORegKey::getFullPath(std::u16string_view path
) const {
909 OSL_ASSERT(!m_name
.isEmpty() && !path
.empty());
910 OUStringBuffer
b(32);
912 if (!b
.isEmpty() && b
[b
.getLength() - 1] == '/') {
913 if (path
[0] == '/') {
914 b
.append(path
.substr(1));
919 if (path
[0] != '/') {
924 return b
.makeStringAndClear();
927 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */