LibreOffice Module registry (master) 1
keyimpl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <string.h>
22#include <string_view>
23
24#include "keyimpl.hxx"
25
26#include "reflcnst.hxx"
27#include <rtl/alloc.h>
28#include <rtl/ustrbuf.hxx>
29#include <osl/diagnose.h>
30#include <sal/log.hxx>
31#include <memory>
32
33using namespace store;
34
35namespace { char const VALUE_PREFIX[] = "$VL_"; }
36
37ORegKey::ORegKey(const OUString& keyName, ORegistry* pReg)
38 : m_refCount(1)
39 , m_name(keyName)
40 , m_bDeleted(false)
41 , m_bModified(false)
42 , m_pRegistry(pReg)
43{
44}
45
47{
48 SAL_WARN_IF(m_refCount != 0, "registry", "registry::ORegKey::dtor(): refcount not zero.");
49}
50
52{
53 return m_pRegistry->releaseKey(hKey);
54}
55
56RegError ORegKey::createKey(std::u16string_view keyName, RegKeyHandle* phNewKey)
57{
58 return m_pRegistry->createKey(this, keyName, phNewKey);
59}
60
61RegError ORegKey::openKey(std::u16string_view keyName, RegKeyHandle* phOpenKey)
62{
63 return m_pRegistry->openKey(this, keyName, phOpenKey);
64}
65
66RegError ORegKey::openSubKeys(std::u16string_view keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys)
67{
69
70 *phOpenSubKeys = nullptr;
71 *pnSubKeys = 0;
72
73 ORegKey* pKey = this;
74 if ( !keyName.empty() )
75 {
76 _ret = openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pKey));
77 if (_ret != RegError::NO_ERROR)
78 return _ret;
79 }
80
81 sal_uInt32 nSubKeys = pKey->countSubKeys();
82 *pnSubKeys = nSubKeys;
83
84 ORegKey** pSubKeys;
85 pSubKeys = static_cast<ORegKey**>(rtl_allocateZeroMemory(nSubKeys * sizeof(ORegKey*)));
86
88 OStoreDirectory rStoreDir(pKey->getStoreDir());
89 storeError _err = rStoreDir.first(iter);
90
91 nSubKeys = 0;
92 while ( _err == store_E_None )
93 {
94 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
95 {
96 OUString const sSubKeyName(iter.m_pszName, iter.m_nLength);
97
98 ORegKey* pOpenSubKey = nullptr;
99 _ret = pKey->openKey(sSubKeyName, reinterpret_cast<RegKeyHandle*>(&pOpenSubKey));
100 if (_ret != RegError::NO_ERROR)
101 {
102 *phOpenSubKeys = nullptr;
103 *pnSubKeys = 0;
104 std::free(pSubKeys); // @@@ leaking 'pSubKeys[0...nSubkeys-1]'
105 return _ret; // @@@ leaking 'pKey'
106 }
107
108 pSubKeys[nSubKeys] = pOpenSubKey;
109
110 nSubKeys++;
111 }
112
113 _err = rStoreDir.next(iter);
114 }
115
116 *phOpenSubKeys = reinterpret_cast<RegKeyHandle*>(pSubKeys);
117 if (!keyName.empty())
118 {
119 (void) releaseKey(pKey);
120 }
121 return RegError::NO_ERROR;
122}
123
124RegError ORegKey::getKeyNames(std::u16string_view keyName,
125 rtl_uString*** pSubKeyNames,
126 sal_uInt32* pnSubKeys)
127{
128 *pSubKeyNames = nullptr;
129 *pnSubKeys = 0;
130
131 ORegKey* pKey = this;
132 if (!keyName.empty())
133 {
134 RegError _ret = openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pKey));
135 if (_ret != RegError::NO_ERROR)
136 return _ret;
137 }
138
139 sal_uInt32 nSubKeys = pKey->countSubKeys();
140 *pnSubKeys = nSubKeys;
141
142 rtl_uString** pSubKeys
143 = static_cast<rtl_uString**>(rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*)));
144
146 OStoreDirectory rStoreDir(pKey->getStoreDir());
147 storeError _err = rStoreDir.first(iter);
148
149 nSubKeys = 0;
150
151 while ( _err == store_E_None )
152 {
153 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR)
154 {
155 OUString const sSubKeyName(iter.m_pszName, iter.m_nLength);
156
157 OUString sFullKeyName(pKey->getName());
158 if (sFullKeyName.getLength() > 1)
159 sFullKeyName += ORegistry::ROOT;
160 sFullKeyName += sSubKeyName;
161
162 rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData);
163
164 nSubKeys++;
165 }
166
167 _err = rStoreDir.next(iter);
168 }
169
170 *pSubKeyNames = pSubKeys;
171 if (!keyName.empty())
172 {
173 releaseKey(pKey);
174 }
175 return RegError::NO_ERROR;
176}
177
179{
180 return m_pRegistry->closeKey(hKey);
181}
182
183RegError ORegKey::deleteKey(std::u16string_view keyName)
184{
185 return m_pRegistry->deleteKey(this, keyName);
186}
187
188RegError ORegKey::getValueInfo(std::u16string_view valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const
189{
190 OStoreStream rValue;
191 std::unique_ptr<sal_uInt8[]> pBuffer;
192 storeAccessMode accessMode = storeAccessMode::ReadWrite;
193
194 if (m_pRegistry->isReadOnly())
195 {
196 accessMode = storeAccessMode::ReadOnly;
197 }
198
199 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
200
202
203 if ( rValue.create(m_pRegistry->getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
204 {
205 *pValueType = RegValueType::NOT_DEFINED;
206 *pValueSize = 0;
208 }
209
210 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
211
212 sal_uInt32 readBytes;
213 if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
214 {
216 }
217 if (readBytes != VALUE_HEADERSIZE)
218 {
220 }
221
222 sal_uInt32 size;
223 sal_uInt8 type = pBuffer[0];
224 readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
225
226 *pValueType = static_cast<RegValueType>(type);
227 if (*pValueType > RegValueType::BINARY)
228 {
229 pBuffer.reset(new sal_uInt8[4]);
230 rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), 4, readBytes);
231
232 readUINT32(pBuffer.get(), size);
233 }
234
235 *pValueSize = size;
236
237 return RegError::NO_ERROR;
238}
239
240RegError ORegKey::setValue(std::u16string_view valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
241{
242 OStoreStream rValue;
243 std::unique_ptr<sal_uInt8[]> pBuffer;
244
245 if (m_pRegistry->isReadOnly())
246 {
248 }
249
250 if (vType > RegValueType::BINARY)
251 {
253 }
254
255 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
256
258
259 if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT , sImplValueName, storeAccessMode::Create) )
260 {
262 }
263
264 sal_uInt32 size = vSize;
265
266 sal_uInt8 type = static_cast<sal_uInt8>(vType);
267 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
268 memcpy(pBuffer.get(), &type, 1);
269
270 writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
271
272 switch (vType)
273 {
275 memcpy(pBuffer.get()+VALUE_HEADEROFFSET, value, size);
276 break;
278 writeINT32(pBuffer.get()+VALUE_HEADEROFFSET, *static_cast<sal_Int32*>(value));
279 break;
281 writeUtf8(pBuffer.get()+VALUE_HEADEROFFSET, static_cast<const char*>(value));
282 break;
284 writeString(pBuffer.get()+VALUE_HEADEROFFSET, static_cast<const sal_Unicode*>(value));
285 break;
287 memcpy(pBuffer.get()+VALUE_HEADEROFFSET, value, size);
288 break;
289 default:
290 OSL_ASSERT(false);
291 break;
292 }
293
294 sal_uInt32 writenBytes;
295 if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
296 {
298 }
299 if (writenBytes != (VALUE_HEADERSIZE+size))
300 {
302 }
303 setModified();
304
305 return RegError::NO_ERROR;
306}
307
308RegError ORegKey::setLongListValue(std::u16string_view valueName, sal_Int32 const * pValueList, sal_uInt32 len)
309{
310 OStoreStream rValue;
311 std::unique_ptr<sal_uInt8[]> pBuffer;
312
313 if (m_pRegistry->isReadOnly())
314 {
316 }
317
318 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
319
321
322 if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, storeAccessMode::Create) )
323 {
325 }
326
327 sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
328
329 size += len * 4;
330
332 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
333 memcpy(pBuffer.get(), &type, 1);
334
335 writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
336 writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET, len);
337
338 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
339
340 for (sal_uInt32 i=0; i < len; i++)
341 {
342 writeINT32(pBuffer.get()+VALUE_HEADEROFFSET+offset, pValueList[i]);
343 offset += 4;
344 }
345
346 sal_uInt32 writenBytes;
347 if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
348 {
350 }
351 if (writenBytes != (VALUE_HEADEROFFSET+size))
352 {
354 }
355 setModified();
356
357 return RegError::NO_ERROR;
358}
359
361 std::u16string_view valueName, char** pValueList, sal_uInt32 len)
362{
363 OStoreStream rValue;
364 std::unique_ptr<sal_uInt8[]> pBuffer;
365
366 if (m_pRegistry->isReadOnly())
367 {
369 }
370
371 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
372
374
375 if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, storeAccessMode::Create) )
376 {
378 }
379
380 sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
381
382 sal_uInt32 i;
383 for (i=0; i < len; i++)
384 {
385 size += 4 + strlen(pValueList[i]) + 1;
386 }
387
389 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
390 memcpy(pBuffer.get(), &type, 1);
391
392 writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
393 writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET, len);
394
395 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
396 sal_uInt32 sLen = 0;
397
398 for (i=0; i < len; i++)
399 {
400 sLen = strlen(pValueList[i]) + 1;
401 writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET+offset, sLen);
402
403 offset += 4;
404 writeUtf8(pBuffer.get()+VALUE_HEADEROFFSET+offset, pValueList[i]);
405 offset += sLen;
406 }
407
408 sal_uInt32 writenBytes;
409 if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
410 {
412 }
413 if (writenBytes != (VALUE_HEADERSIZE+size))
414 {
416 }
417 setModified();
418
419 return RegError::NO_ERROR;
420}
421
422RegError ORegKey::setUnicodeListValue(std::u16string_view valueName, sal_Unicode** pValueList, sal_uInt32 len)
423{
424 OStoreStream rValue;
425 std::unique_ptr<sal_uInt8[]> pBuffer;
426
427 if (m_pRegistry->isReadOnly())
428 {
430 }
431
432 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
433
435
436 if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, storeAccessMode::Create) )
437 {
439 }
440
441 sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
442
443 sal_uInt32 i;
444 for (i=0; i < len; i++)
445 {
446 size += 4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2);
447 }
448
449 sal_uInt8 type = sal_uInt8(RegValueType::UNICODELIST);
450 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
451 memcpy(pBuffer.get(), &type, 1);
452
453 writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
454 writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET, len);
455
456 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
457 sal_uInt32 sLen = 0;
458
459 for (i=0; i < len; i++)
460 {
461 sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2;
462 writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET+offset, sLen);
463
464 offset += 4;
465 writeString(pBuffer.get()+VALUE_HEADEROFFSET+offset, pValueList[i]);
466 offset += sLen;
467 }
468
469 sal_uInt32 writenBytes;
470 if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
471 {
473 }
474 if (writenBytes != (VALUE_HEADERSIZE+size))
475 {
477 }
478 setModified();
479
480 return RegError::NO_ERROR;
481}
482
483RegError ORegKey::getValue(std::u16string_view valueName, RegValue value) const
484{
485 OStoreStream rValue;
486 std::unique_ptr<sal_uInt8[]> pBuffer;
487 RegValueType valueType;
488 sal_uInt32 valueSize;
489 storeAccessMode accessMode = storeAccessMode::ReadWrite;
490
491 if (m_pRegistry->isReadOnly())
492 {
493 accessMode = storeAccessMode::ReadOnly;
494 }
495
496 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
497
499
500 if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
501 {
503 }
504
505 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
506
507 sal_uInt32 readBytes;
508 if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
509 {
511 }
512 if (readBytes != VALUE_HEADERSIZE)
513 {
515 }
516
517 sal_uInt8 type = pBuffer[0];
518 valueType = static_cast<RegValueType>(type);
519 readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
520
521 if (valueType > RegValueType::BINARY)
522 {
524 }
525
526 pBuffer.reset(new sal_uInt8[valueSize]);
527
528 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
529 {
531 }
532 if (readBytes != valueSize)
533 {
535 }
536
537 switch (valueType)
538 {
540 readINT32(pBuffer.get(), *static_cast<sal_Int32*>(value));
541 break;
543 readUtf8(pBuffer.get(), static_cast<char*>(value), valueSize);
544 break;
546 readString(pBuffer.get(), static_cast<sal_Unicode*>(value), valueSize);
547 break;
549 memcpy(value, pBuffer.get(), valueSize);
550 break;
551 default:
552 memcpy(value, pBuffer.get(), valueSize);
553 break;
554 }
555
556 return RegError::NO_ERROR;
557}
558
559RegError ORegKey::getLongListValue(std::u16string_view valueName, sal_Int32** pValueList, sal_uInt32* pLen) const
560{
561 OStoreStream rValue;
562 std::unique_ptr<sal_uInt8[]> pBuffer;
563 RegValueType valueType;
564 sal_uInt32 valueSize;
565 storeAccessMode accessMode = storeAccessMode::ReadWrite;
566
567 if (m_pRegistry->isReadOnly())
568 {
569 accessMode = storeAccessMode::ReadOnly;
570 }
571
572 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
573
575
576 if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
577 {
578 pValueList = nullptr;
579 *pLen = 0;
581 }
582
583 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
584
585 sal_uInt32 readBytes;
586 if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
587 {
588 pValueList = nullptr;
589 *pLen = 0;
591 }
592 if (readBytes != VALUE_HEADERSIZE)
593 {
594 pValueList = nullptr;
595 *pLen = 0;
597 }
598
599 sal_uInt8 type = pBuffer[0];
600 valueType = static_cast<RegValueType>(type);
601
602 if (valueType != RegValueType::LONGLIST)
603 {
604 pValueList = nullptr;
605 *pLen = 0;
607 }
608
609 readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
610
611 /* check for 'reasonable' value */
612 /* surely 10 millions entry in a registry list should be enough */
613 if(valueSize > 40000000)
614 {
615 pValueList = nullptr;
616 *pLen = 0;
618 }
619 pBuffer.reset(new sal_uInt8[valueSize]);
620
621 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
622 {
623 pValueList = nullptr;
624 *pLen = 0;
626 }
627 if (readBytes != valueSize)
628 {
629 pValueList = nullptr;
630 *pLen = 0;
632 }
633
634 sal_uInt32 len = 0;
635 readUINT32(pBuffer.get(), len);
636
637 /* make sure the declared size of the array is consistent with the amount of data we have read */
638 if(len > (valueSize - 4) / 4)
639 {
640 pValueList = nullptr;
641 *pLen = 0;
643 }
644 *pLen = len;
645 sal_Int32* pVList = static_cast<sal_Int32*>(rtl_allocateZeroMemory(len * sizeof(sal_Int32)));
646
647 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
648
649 for (sal_uInt32 i = 0; i < len; i++)
650 {
651 readINT32(pBuffer.get()+offset, pVList[i]);
652 offset += 4;
653 }
654
655 *pValueList = pVList;
656 return RegError::NO_ERROR;
657}
658
659RegError ORegKey::getStringListValue(std::u16string_view valueName, char*** pValueList, sal_uInt32* pLen) const
660{
661 OStoreStream rValue;
662 std::unique_ptr<sal_uInt8[]> pBuffer;
663 RegValueType valueType;
664 sal_uInt32 valueSize;
665 storeAccessMode accessMode = storeAccessMode::ReadWrite;
666
667 if (m_pRegistry->isReadOnly())
668 {
669 accessMode = storeAccessMode::ReadOnly;
670 }
671
672 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
673
675
676 if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
677 {
678 pValueList = nullptr;
679 *pLen = 0;
681 }
682
683 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
684
685 sal_uInt32 readBytes;
686 if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
687 {
688 pValueList = nullptr;
689 *pLen = 0;
691 }
692 if (readBytes != VALUE_HEADERSIZE)
693 {
694 pValueList = nullptr;
695 *pLen = 0;
697 }
698
699 sal_uInt8 type = pBuffer[0];
700 valueType = static_cast<RegValueType>(type);
701
702 if (valueType != RegValueType::STRINGLIST)
703 {
704 pValueList = nullptr;
705 *pLen = 0;
707 }
708
709 readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
710
711 pBuffer.reset(new sal_uInt8[valueSize]);
712
713 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
714 {
715 pValueList = nullptr;
716 *pLen = 0;
718 }
719 if (readBytes != valueSize)
720 {
721 pValueList = nullptr;
722 *pLen = 0;
724 }
725
726 sal_uInt32 len = 0;
727 readUINT32(pBuffer.get(), len);
728
729 *pLen = len;
730 char** pVList = static_cast<char**>(rtl_allocateZeroMemory(len * sizeof(char*)));
731
732 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
733 sal_uInt32 sLen = 0;
734
735 char *pValue;
736 for (sal_uInt32 i=0; i < len; i++)
737 {
738 readUINT32(pBuffer.get()+offset, sLen);
739
740 offset += 4;
741
742 pValue = static_cast<char*>(std::malloc(sLen));
743 readUtf8(pBuffer.get()+offset, pValue, sLen);
744 pVList[i] = pValue;
745
746 offset += sLen;
747 }
748
749 *pValueList = pVList;
750 return RegError::NO_ERROR;
751}
752
753RegError ORegKey::getUnicodeListValue(std::u16string_view valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const
754{
755 OStoreStream rValue;
756 std::unique_ptr<sal_uInt8[]> pBuffer;
757 RegValueType valueType;
758 sal_uInt32 valueSize;
759 storeAccessMode accessMode = storeAccessMode::ReadWrite;
760
761 if (m_pRegistry->isReadOnly())
762 {
763 accessMode = storeAccessMode::ReadOnly;
764 }
765
766 OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
767
769
770 if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
771 {
772 pValueList = nullptr;
773 *pLen = 0;
775 }
776
777 pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
778
779 sal_uInt32 readBytes;
780 if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
781 {
782 pValueList = nullptr;
783 *pLen = 0;
785 }
786 if (readBytes != VALUE_HEADERSIZE)
787 {
788 pValueList = nullptr;
789 *pLen = 0;
791 }
792
793 sal_uInt8 type = pBuffer[0];
794 valueType = static_cast<RegValueType>(type);
795
796 if (valueType != RegValueType::UNICODELIST)
797 {
798 pValueList = nullptr;
799 *pLen = 0;
801 }
802
803 readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
804
805 pBuffer.reset(new sal_uInt8[valueSize]);
806
807 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
808 {
809 pValueList = nullptr;
810 *pLen = 0;
812 }
813 if (readBytes != valueSize)
814 {
815 pValueList = nullptr;
816 *pLen = 0;
818 }
819
820 sal_uInt32 len = 0;
821 readUINT32(pBuffer.get(), len);
822
823 *pLen = len;
824 sal_Unicode** pVList = static_cast<sal_Unicode**>(rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)));
825
826 sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
827 sal_uInt32 sLen = 0;
828
829 sal_Unicode *pValue;
830 for (sal_uInt32 i=0; i < len; i++)
831 {
832 readUINT32(pBuffer.get()+offset, sLen);
833
834 offset += 4;
835
836 pValue = static_cast<sal_Unicode*>(std::malloc((sLen / 2) * sizeof(sal_Unicode)));
837 readString(pBuffer.get()+offset, pValue, sLen);
838 pVList[i] = pValue;
839
840 offset += sLen;
841 }
842
843 *pValueList = pVList;
844 return RegError::NO_ERROR;
845}
846
847
848RegError ORegKey::getResolvedKeyName(std::u16string_view keyName,
849 OUString& resolvedName) const
850{
851 if (keyName.empty())
853
854 resolvedName = getFullPath(keyName);
855 return RegError::NO_ERROR;
856}
857
859{
861
863 OStoreDirectory rStoreDir = getStoreDir();
864 storeError _err = rStoreDir.first(iter);
865 sal_uInt32 count = 0;
866
867 while ( _err == store_E_None )
868 {
869 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
870 {
871 count++;
872 }
873
874 _err = rStoreDir.next(iter);
875 }
876
877 return count;
878}
879
881{
882 OStoreDirectory rStoreDir;
883 OUString fullPath;
884 OUString relativName;
885 storeAccessMode accessMode = storeAccessMode::ReadWrite;
886
887 if ( m_name == ORegistry::ROOT )
888 {
889 fullPath.clear();
890 relativName.clear();
891 } else
892 {
893 fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1);
894 relativName = m_name.copy(m_name.lastIndexOf('/') + 1);
895 }
896
897 if (m_pRegistry->isReadOnly())
898 {
899 accessMode = storeAccessMode::ReadOnly;
900 }
901
902 rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode);
903
904 return rStoreDir;
905}
906
907OUString ORegKey::getFullPath(std::u16string_view path) const {
908 OSL_ASSERT(!m_name.isEmpty() && !path.empty());
909 OUStringBuffer b(32);
910 b.append(m_name);
911 if (!b.isEmpty() && b[b.getLength() - 1] == '/') {
912 if (path[0] == '/') {
913 b.append(path.substr(1));
914 } else {
915 b.append(path);
916 }
917 } else {
918 if (path[0] != '/') {
919 b.append('/');
920 }
921 b.append(path);
922 }
923 return b.makeStringAndClear();
924}
925
926/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
RegError createKey(std::u16string_view keyName, RegKeyHandle *phNewKey)
Definition: keyimpl.cxx:56
sal_uInt32 m_refCount
Definition: keyimpl.hxx:130
RegError setUnicodeListValue(std::u16string_view valueName, sal_Unicode **pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:422
RegError getValueInfo(std::u16string_view valueName, RegValueType *pValueTye, sal_uInt32 *pValueSize) const
Definition: keyimpl.cxx:188
RegError getValue(std::u16string_view valueName, RegValue value) const
Definition: keyimpl.cxx:483
void setModified(bool bModified=true)
Definition: keyimpl.hxx:108
RegError setLongListValue(std::u16string_view valueName, sal_Int32 const *pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:308
OUString getFullPath(std::u16string_view path) const
Definition: keyimpl.cxx:907
RegError releaseKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:51
RegError getResolvedKeyName(std::u16string_view keyName, OUString &resolvedName) const
Definition: keyimpl.cxx:848
sal_uInt32 countSubKeys()
Definition: keyimpl.cxx:858
RegError getStringListValue(std::u16string_view valueName, char ***pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:659
RegError getKeyNames(std::u16string_view keyName, rtl_uString ***pSubKeyNames, sal_uInt32 *pnSubKeys)
Definition: keyimpl.cxx:124
RegError getLongListValue(std::u16string_view valueName, sal_Int32 **pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:559
OUString m_name
Definition: keyimpl.hxx:131
RegError getUnicodeListValue(std::u16string_view valueName, sal_Unicode ***pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:753
const store::OStoreFile & getStoreFile() const
Definition: keyimpl.hxx:119
~ORegKey()
Definition: keyimpl.cxx:46
RegError setValue(std::u16string_view valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
Definition: keyimpl.cxx:240
RegError openKey(std::u16string_view keyName, RegKeyHandle *phOpenKey)
Definition: keyimpl.cxx:61
RegError deleteKey(std::u16string_view keyName)
Definition: keyimpl.cxx:183
RegError openSubKeys(std::u16string_view keyName, RegKeyHandle **phOpenSubKeys, sal_uInt32 *pnSubKeys)
Definition: keyimpl.cxx:66
RegError setStringListValue(std::u16string_view valueName, char **pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:360
RegError closeKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:178
ORegKey(const OUString &keyName, ORegistry *pReg)
Definition: keyimpl.cxx:37
ORegistry * m_pRegistry
Definition: keyimpl.hxx:134
const OUString & getName() const
Definition: keyimpl.hxx:124
store::OStoreDirectory getStoreDir() const
Definition: keyimpl.cxx:880
const store::OStoreFile & getStoreFile() const
Definition: regimpl.hxx:90
RegError closeKey(RegKeyHandle hKey)
Definition: regimpl.cxx:704
RegError openKey(RegKeyHandle hKey, std::u16string_view keyName, RegKeyHandle *phOpenKey)
Definition: regimpl.cxx:659
osl::Mutex m_mutex
Definition: regimpl.hxx:114
RegError deleteKey(RegKeyHandle hKey, std::u16string_view keyName)
Definition: regimpl.cxx:734
bool isReadOnly() const
Definition: regimpl.hxx:82
static constexpr OUStringLiteral ROOT
Definition: regimpl.hxx:121
RegError createKey(RegKeyHandle hKey, std::u16string_view keyName, RegKeyHandle *phNewKey)
Definition: regimpl.cxx:602
RegError releaseKey(RegKeyHandle hKey)
Definition: regimpl.cxx:587
storeError next(iterator &it)
storeError create(storeFileHandle hFile, OUString const &rPath, OUString const &rName, storeAccessMode eMode)
storeError first(iterator &it)
storeError writeAt(sal_uInt32 nOffset, void const *pBuffer, sal_uInt32 nBytes, sal_uInt32 &rnDone)
storeError readAt(sal_uInt32 nOffset, void *pBuffer, sal_uInt32 nBytes, sal_uInt32 &rnDone)
storeError create(storeFileHandle hFile, OUString const &rPath, OUString const &rName, storeAccessMode eMode)
Any value
ULONG m_refCount
#define SAL_WARN_IF(condition, area, stream)
OUString m_name
size
int i
sal_uInt32 writeString(sal_uInt8 *buffer, const sal_Unicode *v)
Definition: reflwrit.cxx:40
sal_uInt32 writeUINT32(sal_uInt8 *buffer, sal_uInt32 v)
Definition: reflcnst.hxx:136
sal_uInt32 readString(const sal_uInt8 *buffer, sal_Unicode *v, sal_uInt32 maxSize)
Definition: reflwrit.cxx:54
sal_uInt32 readINT32(const sal_uInt8 *buffer, sal_Int32 &v)
Definition: reflcnst.hxx:124
sal_uInt32 readUINT32(const sal_uInt8 *buffer, sal_uInt32 &v)
Definition: reflcnst.hxx:146
sal_uInt32 writeINT32(sal_uInt8 *buffer, sal_Int32 v)
Definition: reflcnst.hxx:114
sal_uInt32 readUtf8(const sal_uInt8 *buffer, char *v, sal_uInt32 maxSize)
Definition: reflcnst.hxx:168
sal_uInt32 writeUtf8(sal_uInt8 *buffer, const char *v)
Definition: reflcnst.hxx:159
#define VALUE_HEADEROFFSET
Definition: regimpl.hxx:37
#define VALUE_HEADERSIZE
Definition: regimpl.hxx:35
#define VALUE_TYPEOFFSET
Definition: regimpl.hxx:36
#define REG_GUARD(mutex)
Definition: regimpl.hxx:39
STRINGLIST
The key has a value of type ascii string list.
Definition: regtype.h:76
INVALID_VALUE
the key has an invalid value or the value type is unknown.
Definition: regtype.h:126
VALUE_NOT_EXISTS
the key has no value
Definition: regtype.h:120
void * RegKeyHandle
defines the type of a registry key handle used in the C API.
Definition: regtype.h:30
UNICODE
The key has a value of type unicode string.
Definition: regtype.h:70
REGISTRY_READONLY
registry is open with readonly access rights.
Definition: regtype.h:92
NOT_DEFINED
The key has no value or the value type is unknown.
Definition: regtype.h:64
SET_VALUE_FAILED
setting the specified value of a key failed.
Definition: regtype.h:122
INVALID_KEYNAME
the keyname is invalid.
Definition: regtype.h:115
enum SAL_DLLPUBLIC_RTTI RegValueType
defines the type of a key value.
Definition: regtype.h:62
void * RegValue
defines the type of a registry key value handle used in the C API.
Definition: regtype.h:33
LONGLIST
The key has a value of type long list.
Definition: regtype.h:74
BINARY
The key has a value of type binary.
Definition: regtype.h:72
LONG
The key has a value of type long.
Definition: regtype.h:66
STRING
The key has a value of type ascii string.
Definition: regtype.h:68
NO_ERROR
no error.
Definition: regtype.h:85
enum SAL_DLLPUBLIC_RTTI RegError
specifies the possible error codes which can occur using the registry API.
Definition: regtype.h:83
sal_Unicode m_pszName[STORE_MAXIMUM_NAMESIZE]
sal_uInt32 m_nAttrib
sal_Int32 m_nLength
constexpr sal_uInt32 STORE_ATTRIB_ISDIR
storeAccessMode
unsigned char sal_uInt8
storeError
store_E_None
sal_uInt16 sal_Unicode
ResultType type