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(std::u16string_view keyName, RegKeyHandle* phNewKey)
69 {
70  return m_pRegistry->createKey(this, keyName, phNewKey);
71 }
72 
73 
74 // openKey
75 
76 RegError ORegKey::openKey(std::u16string_view keyName, RegKeyHandle* phOpenKey)
77 {
78  return m_pRegistry->openKey(this, keyName, phOpenKey);
79 }
80 
81 
82 // openSubKeys
83 
84 RegError ORegKey::openSubKeys(std::u16string_view keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys)
85 {
87 
88  *phOpenSubKeys = nullptr;
89  *pnSubKeys = 0;
90 
91  ORegKey* pKey = this;
92  if ( !keyName.empty() )
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.empty())
136  {
137  (void) releaseKey(pKey);
138  }
139  return RegError::NO_ERROR;
140 }
141 
142 
143 // getKeyNames
144 
145 RegError ORegKey::getKeyNames(std::u16string_view keyName,
146  rtl_uString*** pSubKeyNames,
147  sal_uInt32* pnSubKeys)
148 {
149  *pSubKeyNames = nullptr;
150  *pnSubKeys = 0;
151 
152  ORegKey* pKey = this;
153  if (!keyName.empty())
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.empty())
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(std::u16string_view 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  {
584  case RegValueType::LONG:
585  readINT32(pBuffer.get(), *static_cast<sal_Int32*>(value));
586  break;
588  readUtf8(pBuffer.get(), static_cast<char*>(value), valueSize);
589  break;
591  readString(pBuffer.get(), static_cast<sal_Unicode*>(value), valueSize);
592  break;
594  memcpy(value, pBuffer.get(), valueSize);
595  break;
596  default:
597  memcpy(value, pBuffer.get(), valueSize);
598  break;
599  }
600 
601  return RegError::NO_ERROR;
602 }
603 
604 
605 // getLongListValue
606 
607 RegError ORegKey::getLongListValue(std::u16string_view valueName, sal_Int32** pValueList, sal_uInt32* pLen) const
608 {
610  std::unique_ptr<sal_uInt8[]> pBuffer;
611  RegValueType valueType;
612  sal_uInt32 valueSize;
613  storeAccessMode accessMode = storeAccessMode::ReadWrite;
614 
615  if (m_pRegistry->isReadOnly())
616  {
617  accessMode = storeAccessMode::ReadOnly;
618  }
619 
620  OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
621 
623 
624  if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
625  {
626  pValueList = nullptr;
627  *pLen = 0;
629  }
630 
631  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
632 
633  sal_uInt32 readBytes;
634  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
635  {
636  pValueList = nullptr;
637  *pLen = 0;
639  }
640  if (readBytes != VALUE_HEADERSIZE)
641  {
642  pValueList = nullptr;
643  *pLen = 0;
645  }
646 
647  sal_uInt8 type = pBuffer[0];
648  valueType = static_cast<RegValueType>(type);
649 
650  if (valueType != RegValueType::LONGLIST)
651  {
652  pValueList = nullptr;
653  *pLen = 0;
655  }
656 
657  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
658 
659  /* check for 'reasonable' value */
660  /* surely 10 millions entry in a registry list should be enough */
661  if(valueSize > 40000000)
662  {
663  pValueList = nullptr;
664  *pLen = 0;
666  }
667  pBuffer.reset(new sal_uInt8[valueSize]);
668 
669  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
670  {
671  pValueList = nullptr;
672  *pLen = 0;
674  }
675  if (readBytes != valueSize)
676  {
677  pValueList = nullptr;
678  *pLen = 0;
680  }
681 
682  sal_uInt32 len = 0;
683  readUINT32(pBuffer.get(), len);
684 
685  /* make sure the declared size of the array is consistent with the amount of data we have read */
686  if(len > (valueSize - 4) / 4)
687  {
688  pValueList = nullptr;
689  *pLen = 0;
691  }
692  *pLen = len;
693  sal_Int32* pVList = static_cast<sal_Int32*>(rtl_allocateZeroMemory(len * sizeof(sal_Int32)));
694 
695  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
696 
697  for (sal_uInt32 i = 0; i < len; i++)
698  {
699  readINT32(pBuffer.get()+offset, pVList[i]);
700  offset += 4;
701  }
702 
703  *pValueList = pVList;
704  return RegError::NO_ERROR;
705 }
706 
707 
708 // getStringListValue
709 
710 RegError ORegKey::getStringListValue(std::u16string_view valueName, char*** pValueList, sal_uInt32* pLen) const
711 {
713  std::unique_ptr<sal_uInt8[]> pBuffer;
714  RegValueType valueType;
715  sal_uInt32 valueSize;
716  storeAccessMode accessMode = storeAccessMode::ReadWrite;
717 
718  if (m_pRegistry->isReadOnly())
719  {
720  accessMode = storeAccessMode::ReadOnly;
721  }
722 
723  OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
724 
726 
727  if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
728  {
729  pValueList = nullptr;
730  *pLen = 0;
732  }
733 
734  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
735 
736  sal_uInt32 readBytes;
737  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
738  {
739  pValueList = nullptr;
740  *pLen = 0;
742  }
743  if (readBytes != VALUE_HEADERSIZE)
744  {
745  pValueList = nullptr;
746  *pLen = 0;
748  }
749 
750  sal_uInt8 type = pBuffer[0];
751  valueType = static_cast<RegValueType>(type);
752 
753  if (valueType != RegValueType::STRINGLIST)
754  {
755  pValueList = nullptr;
756  *pLen = 0;
758  }
759 
760  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
761 
762  pBuffer.reset(new sal_uInt8[valueSize]);
763 
764  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
765  {
766  pValueList = nullptr;
767  *pLen = 0;
769  }
770  if (readBytes != valueSize)
771  {
772  pValueList = nullptr;
773  *pLen = 0;
775  }
776 
777  sal_uInt32 len = 0;
778  readUINT32(pBuffer.get(), len);
779 
780  *pLen = len;
781  char** pVList = static_cast<char**>(rtl_allocateZeroMemory(len * sizeof(char*)));
782 
783  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
784  sal_uInt32 sLen = 0;
785 
786  char *pValue;
787  for (sal_uInt32 i=0; i < len; i++)
788  {
789  readUINT32(pBuffer.get()+offset, sLen);
790 
791  offset += 4;
792 
793  pValue = static_cast<char*>(std::malloc(sLen));
794  readUtf8(pBuffer.get()+offset, pValue, sLen);
795  pVList[i] = pValue;
796 
797  offset += sLen;
798  }
799 
800  *pValueList = pVList;
801  return RegError::NO_ERROR;
802 }
803 
804 
805 // getUnicodeListValue
806 
807 RegError ORegKey::getUnicodeListValue(std::u16string_view valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const
808 {
810  std::unique_ptr<sal_uInt8[]> pBuffer;
811  RegValueType valueType;
812  sal_uInt32 valueSize;
813  storeAccessMode accessMode = storeAccessMode::ReadWrite;
814 
815  if (m_pRegistry->isReadOnly())
816  {
817  accessMode = storeAccessMode::ReadOnly;
818  }
819 
820  OUString sImplValueName = OUString::Concat(VALUE_PREFIX) + valueName;
821 
823 
824  if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
825  {
826  pValueList = nullptr;
827  *pLen = 0;
829  }
830 
831  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
832 
833  sal_uInt32 readBytes;
834  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
835  {
836  pValueList = nullptr;
837  *pLen = 0;
839  }
840  if (readBytes != VALUE_HEADERSIZE)
841  {
842  pValueList = nullptr;
843  *pLen = 0;
845  }
846 
847  sal_uInt8 type = pBuffer[0];
848  valueType = static_cast<RegValueType>(type);
849 
850  if (valueType != RegValueType::UNICODELIST)
851  {
852  pValueList = nullptr;
853  *pLen = 0;
855  }
856 
857  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
858 
859  pBuffer.reset(new sal_uInt8[valueSize]);
860 
861  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
862  {
863  pValueList = nullptr;
864  *pLen = 0;
866  }
867  if (readBytes != valueSize)
868  {
869  pValueList = nullptr;
870  *pLen = 0;
872  }
873 
874  sal_uInt32 len = 0;
875  readUINT32(pBuffer.get(), len);
876 
877  *pLen = len;
878  sal_Unicode** pVList = static_cast<sal_Unicode**>(rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)));
879 
880  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
881  sal_uInt32 sLen = 0;
882 
883  sal_Unicode *pValue;
884  for (sal_uInt32 i=0; i < len; i++)
885  {
886  readUINT32(pBuffer.get()+offset, sLen);
887 
888  offset += 4;
889 
890  pValue = static_cast<sal_Unicode*>(std::malloc((sLen / 2) * sizeof(sal_Unicode)));
891  readString(pBuffer.get()+offset, pValue, sLen);
892  pVList[i] = pValue;
893 
894  offset += sLen;
895  }
896 
897  *pValueList = pVList;
898  return RegError::NO_ERROR;
899 }
900 
901 
902 RegError ORegKey::getResolvedKeyName(std::u16string_view keyName,
903  OUString& resolvedName) const
904 {
905  if (keyName.empty())
907 
908  resolvedName = getFullPath(keyName);
909  return RegError::NO_ERROR;
910 }
911 
912 
913 // countSubKeys()
914 
916 {
918 
920  OStoreDirectory rStoreDir = getStoreDir();
921  storeError _err = rStoreDir.first(iter);
922  sal_uInt32 count = 0;
923 
924  while ( _err == store_E_None )
925  {
926  if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
927  {
928  count++;
929  }
930 
931  _err = rStoreDir.next(iter);
932  }
933 
934  return count;
935 }
936 
938 {
939  OStoreDirectory rStoreDir;
940  OUString fullPath;
941  OUString relativName;
942  storeAccessMode accessMode = storeAccessMode::ReadWrite;
943 
944  if ( m_name == ORegistry::ROOT )
945  {
946  fullPath.clear();
947  relativName.clear();
948  } else
949  {
950  fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1);
951  relativName = m_name.copy(m_name.lastIndexOf('/') + 1);
952  }
953 
954  if (m_pRegistry->isReadOnly())
955  {
956  accessMode = storeAccessMode::ReadOnly;
957  }
958 
959  rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode);
960 
961  return rStoreDir;
962 }
963 
964 OUString ORegKey::getFullPath(std::u16string_view path) const {
965  OSL_ASSERT(!m_name.isEmpty() && !path.empty());
966  OUStringBuffer b(32);
967  b.append(m_name);
968  if (!b.isEmpty() && b[b.getLength() - 1] == '/') {
969  if (path[0] == '/') {
970  b.append(path.substr(1));
971  } else {
972  b.append(path);
973  }
974  } else {
975  if (path[0] != '/') {
976  b.append('/');
977  }
978  b.append(path);
979  }
980  return b.makeStringAndClear();
981 }
982 
983 /* 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
ULONG m_refCount
#define VALUE_HEADERSIZE
Definition: regimpl.hxx:35
UNICODE
The key has a value of type unicode string.
Definition: regtype.h:64
RegError createKey(std::u16string_view keyName, RegKeyHandle *phNewKey)
Definition: keyimpl.cxx:68
storeError create(storeFileHandle hFile, OUString const &rPath, OUString const &rName, storeAccessMode eMode)
store_E_None
LONG
The key has a value of type long.
Definition: regtype.h:64
LONGLIST
The key has a value of type long list.
Definition: regtype.h:64
RegError releaseKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:60
RegError setUnicodeListValue(std::u16string_view valueName, sal_Unicode **pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:464
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
RegError getResolvedKeyName(std::u16string_view keyName, OUString &resolvedName) const
Definition: keyimpl.cxx:902
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:807
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:710
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
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:937
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
sal_uInt32 countSubKeys()
Definition: keyimpl.cxx:915
size
RegError openKey(RegKeyHandle hKey, std::u16string_view keyName, RegKeyHandle *phOpenKey)
Definition: regimpl.cxx:663
sal_uInt32 readINT32(const sal_uInt8 *buffer, sal_Int32 &v)
Definition: reflcnst.hxx:145
OUString m_name
Definition: keyimpl.hxx:131
RegError getKeyNames(std::u16string_view keyName, rtl_uString ***pSubKeyNames, sal_uInt32 *pnSubKeys)
Definition: keyimpl.cxx:145
RegError setValue(std::u16string_view valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
Definition: keyimpl.cxx:273
OUString getFullPath(std::u16string_view path) const
Definition: keyimpl.cxx:964
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 createKey(RegKeyHandle hKey, std::u16string_view keyName, RegKeyHandle *phNewKey)
Definition: regimpl.cxx:606
RegError getLongListValue(std::u16string_view valueName, sal_Int32 **pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:607
RegError openSubKeys(std::u16string_view keyName, RegKeyHandle **phOpenSubKeys, sal_uInt32 *pnSubKeys)
Definition: keyimpl.cxx:84
#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
RegError deleteKey(std::u16string_view keyName)
Definition: keyimpl.cxx:210
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
const store::OStoreFile & getStoreFile() const
Definition: keyimpl.hxx:119
RegError openKey(std::u16string_view keyName, RegKeyHandle *phOpenKey)
Definition: keyimpl.cxx:76
RegError deleteKey(RegKeyHandle hKey, std::u16string_view keyName)
Definition: regimpl.cxx:738
const store::OStoreFile & getStoreFile() const
Definition: regimpl.hxx:96
storeError next(iterator &it)
ORegistry * m_pRegistry
Definition: keyimpl.hxx:134
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo