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