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