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 { static 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;
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 {
150 
151  *pSubKeyNames = nullptr;
152  *pnSubKeys = 0;
153 
154  ORegKey* pKey = this;
155  if (!keyName.isEmpty())
156  {
157  _ret = openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pKey));
158  if (_ret != RegError::NO_ERROR)
159  return _ret;
160  }
161 
162  sal_uInt32 nSubKeys = pKey->countSubKeys();
163  *pnSubKeys = nSubKeys;
164 
165  rtl_uString** pSubKeys
166  = static_cast<rtl_uString**>(rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*)));
167 
169  OStoreDirectory rStoreDir(pKey->getStoreDir());
170  storeError _err = rStoreDir.first(iter);
171 
172  nSubKeys = 0;
173 
174  while ( _err == store_E_None )
175  {
176  if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR)
177  {
178  OUString const sSubKeyName = iter.m_pszName;
179 
180  OUString sFullKeyName(pKey->getName());
181  if (sFullKeyName.getLength() > 1)
182  sFullKeyName += ORegistry::ROOT;
183  sFullKeyName += sSubKeyName;
184 
185  rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData);
186 
187  nSubKeys++;
188  }
189 
190  _err = rStoreDir.next(iter);
191  }
192 
193  *pSubKeyNames = pSubKeys;
194  if (!keyName.isEmpty())
195  {
196  releaseKey(pKey);
197  }
198  return RegError::NO_ERROR;
199 }
200 
201 
202 // closeKey
203 
205 {
206  return m_pRegistry->closeKey(hKey);
207 }
208 
209 
210 // deleteKey
211 
212 RegError ORegKey::deleteKey(const OUString& keyName)
213 {
214  return m_pRegistry->deleteKey(this, keyName);
215 }
216 
217 
218 // getValueType
219 
220 RegError ORegKey::getValueInfo(const OUString& valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const
221 {
223  std::unique_ptr<sal_uInt8[]> pBuffer;
224  storeAccessMode accessMode = storeAccessMode::ReadWrite;
225 
226  if (m_pRegistry->isReadOnly())
227  {
228  accessMode = storeAccessMode::ReadOnly;
229  }
230 
231  OUString sImplValueName = VALUE_PREFIX + valueName;
232 
234 
235  if ( rValue.create(m_pRegistry->getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
236  {
237  *pValueType = RegValueType::NOT_DEFINED;
238  *pValueSize = 0;
240  }
241 
242  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
243 
244  sal_uInt32 readBytes;
245  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
246  {
248  }
249  if (readBytes != VALUE_HEADERSIZE)
250  {
252  }
253 
254  sal_uInt32 size;
255  sal_uInt8 type = pBuffer[0];
256  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
257 
258  *pValueType = static_cast<RegValueType>(type);
259  if (*pValueType > RegValueType::BINARY)
260  {
261  pBuffer.reset(new sal_uInt8[4]);
262  rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), 4, readBytes);
263 
264  readUINT32(pBuffer.get(), size);
265  }
266 
267  *pValueSize = size;
268 
269  return RegError::NO_ERROR;
270 }
271 
272 
273 // setValue
274 
275 RegError ORegKey::setValue(const OUString& valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
276 {
278  std::unique_ptr<sal_uInt8[]> pBuffer;
279 
280  if (m_pRegistry->isReadOnly())
281  {
283  }
284 
285  if (vType > RegValueType::BINARY)
286  {
288  }
289 
290  OUString sImplValueName = VALUE_PREFIX + valueName;
291 
293 
294  if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT , sImplValueName, storeAccessMode::Create) )
295  {
297  }
298 
299  sal_uInt32 size = vSize;
300 
301  sal_uInt8 type = static_cast<sal_uInt8>(vType);
302  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
303  memcpy(pBuffer.get(), &type, 1);
304 
305  writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
306 
307  switch (vType)
308  {
310  memcpy(pBuffer.get()+VALUE_HEADEROFFSET, value, size);
311  break;
312  case RegValueType::LONG:
313  writeINT32(pBuffer.get()+VALUE_HEADEROFFSET, *static_cast<sal_Int32*>(value));
314  break;
316  writeUtf8(pBuffer.get()+VALUE_HEADEROFFSET, static_cast<const char*>(value));
317  break;
319  writeString(pBuffer.get()+VALUE_HEADEROFFSET, static_cast<const sal_Unicode*>(value));
320  break;
322  memcpy(pBuffer.get()+VALUE_HEADEROFFSET, value, size);
323  break;
324  default:
325  OSL_ASSERT(false);
326  break;
327  }
328 
329  sal_uInt32 writenBytes;
330  if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
331  {
333  }
334  if (writenBytes != (VALUE_HEADERSIZE+size))
335  {
337  }
338  setModified();
339 
340  return RegError::NO_ERROR;
341 }
342 
343 
344 // setLongListValue
345 
346 RegError ORegKey::setLongListValue(const OUString& valueName, sal_Int32 const * pValueList, sal_uInt32 len)
347 {
349  std::unique_ptr<sal_uInt8[]> pBuffer;
350 
351  if (m_pRegistry->isReadOnly())
352  {
354  }
355 
356  OUString sImplValueName = VALUE_PREFIX + valueName;
357 
359 
360  if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, storeAccessMode::Create) )
361  {
363  }
364 
365  sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
366 
367  size += len * 4;
368 
370  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
371  memcpy(pBuffer.get(), &type, 1);
372 
373  writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
374  writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET, len);
375 
376  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
377 
378  for (sal_uInt32 i=0; i < len; i++)
379  {
380  writeINT32(pBuffer.get()+VALUE_HEADEROFFSET+offset, pValueList[i]);
381  offset += 4;
382  }
383 
384  sal_uInt32 writenBytes;
385  if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
386  {
388  }
389  if (writenBytes != (VALUE_HEADEROFFSET+size))
390  {
392  }
393  setModified();
394 
395  return RegError::NO_ERROR;
396 }
397 
398 
399 // setStringListValue
400 
401 RegError ORegKey::setStringListValue(const OUString& valueName, char** pValueList, sal_uInt32 len)
402 {
404  std::unique_ptr<sal_uInt8[]> pBuffer;
405 
406  if (m_pRegistry->isReadOnly())
407  {
409  }
410 
411  OUString sImplValueName = VALUE_PREFIX + valueName;
412 
414 
415  if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, storeAccessMode::Create) )
416  {
418  }
419 
420  sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
421 
422  sal_uInt32 i;
423  for (i=0; i < len; i++)
424  {
425  size += 4 + strlen(pValueList[i]) + 1;
426  }
427 
429  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
430  memcpy(pBuffer.get(), &type, 1);
431 
432  writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
433  writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET, len);
434 
435  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
436  sal_uInt32 sLen = 0;
437 
438  for (i=0; i < len; i++)
439  {
440  sLen = strlen(pValueList[i]) + 1;
441  writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET+offset, sLen);
442 
443  offset += 4;
444  writeUtf8(pBuffer.get()+VALUE_HEADEROFFSET+offset, pValueList[i]);
445  offset += sLen;
446  }
447 
448  sal_uInt32 writenBytes;
449  if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
450  {
452  }
453  if (writenBytes != (VALUE_HEADERSIZE+size))
454  {
456  }
457  setModified();
458 
459  return RegError::NO_ERROR;
460 }
461 
462 
463 // setUnicodeListValue
464 
465 RegError ORegKey::setUnicodeListValue(const OUString& valueName, sal_Unicode** pValueList, sal_uInt32 len)
466 {
468  std::unique_ptr<sal_uInt8[]> pBuffer;
469 
470  if (m_pRegistry->isReadOnly())
471  {
473  }
474 
475  OUString sImplValueName = VALUE_PREFIX + valueName;
476 
478 
479  if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, storeAccessMode::Create) )
480  {
482  }
483 
484  sal_uInt32 size = 4; // 4 bytes (sal_uInt32) for the length
485 
486  sal_uInt32 i;
487  for (i=0; i < len; i++)
488  {
489  size += 4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2);
490  }
491 
492  sal_uInt8 type = sal_uInt8(RegValueType::UNICODELIST);
493  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE + size]);
494  memcpy(pBuffer.get(), &type, 1);
495 
496  writeUINT32(pBuffer.get()+VALUE_TYPEOFFSET, size);
497  writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET, len);
498 
499  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
500  sal_uInt32 sLen = 0;
501 
502  for (i=0; i < len; i++)
503  {
504  sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2;
505  writeUINT32(pBuffer.get()+VALUE_HEADEROFFSET+offset, sLen);
506 
507  offset += 4;
508  writeString(pBuffer.get()+VALUE_HEADEROFFSET+offset, pValueList[i]);
509  offset += sLen;
510  }
511 
512  sal_uInt32 writenBytes;
513  if ( rValue.writeAt(0, pBuffer.get(), VALUE_HEADERSIZE+size, writenBytes) )
514  {
516  }
517  if (writenBytes != (VALUE_HEADERSIZE+size))
518  {
520  }
521  setModified();
522 
523  return RegError::NO_ERROR;
524 }
525 
526 
527 // getValue
528 
529 RegError ORegKey::getValue(const OUString& valueName, RegValue value) const
530 {
532  std::unique_ptr<sal_uInt8[]> pBuffer;
533  RegValueType valueType;
534  sal_uInt32 valueSize;
535  storeAccessMode accessMode = storeAccessMode::ReadWrite;
536 
537  if (m_pRegistry->isReadOnly())
538  {
539  accessMode = storeAccessMode::ReadOnly;
540  }
541 
542  OUString sImplValueName = VALUE_PREFIX + valueName;
543 
545 
546  if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
547  {
549  }
550 
551  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
552 
553  sal_uInt32 readBytes;
554  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
555  {
557  }
558  if (readBytes != VALUE_HEADERSIZE)
559  {
561  }
562 
563  sal_uInt8 type = pBuffer[0];
564  valueType = static_cast<RegValueType>(type);
565  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
566 
567  if (valueType > RegValueType::BINARY)
568  {
570  }
571 
572  pBuffer.reset(new sal_uInt8[valueSize]);
573 
574  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
575  {
577  }
578  if (readBytes != valueSize)
579  {
581  }
582 
583  switch (valueType)
584  {
586  memcpy(value, pBuffer.get(), valueSize);
587  break;
588  case RegValueType::LONG:
589  readINT32(pBuffer.get(), *static_cast<sal_Int32*>(value));
590  break;
592  readUtf8(pBuffer.get(), static_cast<char*>(value), valueSize);
593  break;
595  readString(pBuffer.get(), static_cast<sal_Unicode*>(value), valueSize);
596  break;
598  memcpy(value, pBuffer.get(), valueSize);
599  break;
600  // coverity[dead_error_begin] - following conditions exist to avoid compiler warning
603  case RegValueType::UNICODELIST:
604  memcpy(value, pBuffer.get(), valueSize);
605  break;
606  }
607 
608  return RegError::NO_ERROR;
609 }
610 
611 
612 // getLongListValue
613 
614 RegError ORegKey::getLongListValue(const OUString& valueName, sal_Int32** pValueList, sal_uInt32* pLen) const
615 {
617  std::unique_ptr<sal_uInt8[]> pBuffer;
618  RegValueType valueType;
619  sal_uInt32 valueSize;
620  storeAccessMode accessMode = storeAccessMode::ReadWrite;
621 
622  if (m_pRegistry->isReadOnly())
623  {
624  accessMode = storeAccessMode::ReadOnly;
625  }
626 
627  OUString sImplValueName = VALUE_PREFIX + valueName;
628 
630 
631  if (rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
632  {
633  pValueList = nullptr;
634  *pLen = 0;
636  }
637 
638  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
639 
640  sal_uInt32 readBytes;
641  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
642  {
643  pValueList = nullptr;
644  *pLen = 0;
646  }
647  if (readBytes != VALUE_HEADERSIZE)
648  {
649  pValueList = nullptr;
650  *pLen = 0;
652  }
653 
654  sal_uInt8 type = pBuffer[0];
655  valueType = static_cast<RegValueType>(type);
656 
657  if (valueType != RegValueType::LONGLIST)
658  {
659  pValueList = nullptr;
660  *pLen = 0;
662  }
663 
664  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
665 
666  /* check for 'reasonable' value */
667  /* surely 10 millions entry in a registry list should be enough */
668  if(valueSize > 40000000)
669  {
670  pValueList = nullptr;
671  *pLen = 0;
673  }
674  pBuffer.reset(new sal_uInt8[valueSize]);
675 
676  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
677  {
678  pValueList = nullptr;
679  *pLen = 0;
681  }
682  if (readBytes != valueSize)
683  {
684  pValueList = nullptr;
685  *pLen = 0;
687  }
688 
689  sal_uInt32 len = 0;
690  readUINT32(pBuffer.get(), len);
691 
692  /* make sure the declared size of the array is consistent with the amount of data we have read */
693  if(len > (valueSize - 4) / 4)
694  {
695  pValueList = nullptr;
696  *pLen = 0;
698  }
699  *pLen = len;
700  sal_Int32* pVList = static_cast<sal_Int32*>(rtl_allocateZeroMemory(len * sizeof(sal_Int32)));
701 
702  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
703 
704  for (sal_uInt32 i = 0; i < len; i++)
705  {
706  readINT32(pBuffer.get()+offset, pVList[i]);
707  offset += 4;
708  }
709 
710  *pValueList = pVList;
711  return RegError::NO_ERROR;
712 }
713 
714 
715 // getStringListValue
716 
717 RegError ORegKey::getStringListValue(const OUString& valueName, char*** pValueList, sal_uInt32* pLen) const
718 {
720  std::unique_ptr<sal_uInt8[]> pBuffer;
721  RegValueType valueType;
722  sal_uInt32 valueSize;
723  storeAccessMode accessMode = storeAccessMode::ReadWrite;
724 
725  if (m_pRegistry->isReadOnly())
726  {
727  accessMode = storeAccessMode::ReadOnly;
728  }
729 
730  OUString sImplValueName = VALUE_PREFIX + valueName;
731 
733 
734  if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
735  {
736  pValueList = nullptr;
737  *pLen = 0;
739  }
740 
741  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
742 
743  sal_uInt32 readBytes;
744  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
745  {
746  pValueList = nullptr;
747  *pLen = 0;
749  }
750  if (readBytes != VALUE_HEADERSIZE)
751  {
752  pValueList = nullptr;
753  *pLen = 0;
755  }
756 
757  sal_uInt8 type = pBuffer[0];
758  valueType = static_cast<RegValueType>(type);
759 
760  if (valueType != RegValueType::STRINGLIST)
761  {
762  pValueList = nullptr;
763  *pLen = 0;
765  }
766 
767  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
768 
769  pBuffer.reset(new sal_uInt8[valueSize]);
770 
771  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
772  {
773  pValueList = nullptr;
774  *pLen = 0;
776  }
777  if (readBytes != valueSize)
778  {
779  pValueList = nullptr;
780  *pLen = 0;
782  }
783 
784  sal_uInt32 len = 0;
785  readUINT32(pBuffer.get(), len);
786 
787  *pLen = len;
788  char** pVList = static_cast<char**>(rtl_allocateZeroMemory(len * sizeof(char*)));
789 
790  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
791  sal_uInt32 sLen = 0;
792 
793  char *pValue;
794  for (sal_uInt32 i=0; i < len; i++)
795  {
796  readUINT32(pBuffer.get()+offset, sLen);
797 
798  offset += 4;
799 
800  pValue = static_cast<char*>(std::malloc(sLen));
801  readUtf8(pBuffer.get()+offset, pValue, sLen);
802  pVList[i] = pValue;
803 
804  offset += sLen;
805  }
806 
807  *pValueList = pVList;
808  return RegError::NO_ERROR;
809 }
810 
811 
812 // getUnicodeListValue
813 
814 RegError ORegKey::getUnicodeListValue(const OUString& valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const
815 {
817  std::unique_ptr<sal_uInt8[]> pBuffer;
818  RegValueType valueType;
819  sal_uInt32 valueSize;
820  storeAccessMode accessMode = storeAccessMode::ReadWrite;
821 
822  if (m_pRegistry->isReadOnly())
823  {
824  accessMode = storeAccessMode::ReadOnly;
825  }
826 
827  OUString sImplValueName = VALUE_PREFIX + valueName;
828 
830 
831  if ( rValue.create(getStoreFile(), m_name + ORegistry::ROOT, sImplValueName, accessMode) )
832  {
833  pValueList = nullptr;
834  *pLen = 0;
836  }
837 
838  pBuffer.reset(new sal_uInt8[VALUE_HEADERSIZE]);
839 
840  sal_uInt32 readBytes;
841  if ( rValue.readAt(0, pBuffer.get(), VALUE_HEADERSIZE, readBytes) )
842  {
843  pValueList = nullptr;
844  *pLen = 0;
846  }
847  if (readBytes != VALUE_HEADERSIZE)
848  {
849  pValueList = nullptr;
850  *pLen = 0;
852  }
853 
854  sal_uInt8 type = pBuffer[0];
855  valueType = static_cast<RegValueType>(type);
856 
857  if (valueType != RegValueType::UNICODELIST)
858  {
859  pValueList = nullptr;
860  *pLen = 0;
862  }
863 
864  readUINT32(pBuffer.get()+VALUE_TYPEOFFSET, valueSize);
865 
866  pBuffer.reset(new sal_uInt8[valueSize]);
867 
868  if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer.get(), valueSize, readBytes) )
869  {
870  pValueList = nullptr;
871  *pLen = 0;
873  }
874  if (readBytes != valueSize)
875  {
876  pValueList = nullptr;
877  *pLen = 0;
879  }
880 
881  sal_uInt32 len = 0;
882  readUINT32(pBuffer.get(), len);
883 
884  *pLen = len;
885  sal_Unicode** pVList = static_cast<sal_Unicode**>(rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)));
886 
887  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array;
888  sal_uInt32 sLen = 0;
889 
890  sal_Unicode *pValue;
891  for (sal_uInt32 i=0; i < len; i++)
892  {
893  readUINT32(pBuffer.get()+offset, sLen);
894 
895  offset += 4;
896 
897  pValue = static_cast<sal_Unicode*>(std::malloc((sLen / 2) * sizeof(sal_Unicode)));
898  readString(pBuffer.get()+offset, pValue, sLen);
899  pVList[i] = pValue;
900 
901  offset += sLen;
902  }
903 
904  *pValueList = pVList;
905  return RegError::NO_ERROR;
906 }
907 
908 
909 RegError ORegKey::getResolvedKeyName(const OUString& keyName,
910  OUString& resolvedName) const
911 {
912  if (keyName.isEmpty())
914 
915  resolvedName = getFullPath(keyName);
916  return RegError::NO_ERROR;
917 }
918 
919 
920 // countSubKeys()
921 
923 {
925 
927  OStoreDirectory rStoreDir = getStoreDir();
928  storeError _err = rStoreDir.first(iter);
929  sal_uInt32 count = 0;
930 
931  while ( _err == store_E_None )
932  {
933  if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
934  {
935  count++;
936  }
937 
938  _err = rStoreDir.next(iter);
939  }
940 
941  return count;
942 }
943 
945 {
946  OStoreDirectory rStoreDir;
947  OUString fullPath;
948  OUString relativName;
949  storeAccessMode accessMode = storeAccessMode::ReadWrite;
950 
951  if ( m_name == ORegistry::ROOT )
952  {
953  fullPath.clear();
954  relativName.clear();
955  } else
956  {
957  fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1);
958  relativName = m_name.copy(m_name.lastIndexOf('/') + 1);
959  }
960 
961  if (m_pRegistry->isReadOnly())
962  {
963  accessMode = storeAccessMode::ReadOnly;
964  }
965 
966  rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode);
967 
968  return rStoreDir;
969 }
970 
971 OUString ORegKey::getFullPath(OUString const & path) const {
972  OSL_ASSERT(!m_name.isEmpty() && !path.isEmpty());
973  OUStringBuffer b(32);
974  b.append(m_name);
975  if (!b.isEmpty() && b[b.getLength() - 1] == '/') {
976  if (path[0] == '/') {
977  b.append(std::u16string_view(path).substr(1));
978  } else {
979  b.append(path);
980  }
981  } else {
982  if (path[0] != '/') {
983  b.append('/');
984  }
985  b.append(path);
986  }
987  return b.makeStringAndClear();
988 }
989 
990 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const OUString & getName() const
Definition: keyimpl.hxx:120
RegError setUnicodeListValue(const OUString &valueName, sal_Unicode **pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:465
RegError setValue(const OUString &valueName, RegValueType vType, RegValue value, sal_uInt32 vSize)
Definition: keyimpl.cxx:275
STRINGLIST
The key has a value of type ascii string list.
Definition: regtype.h:62
STRING
The key has a value of type ascii string.
Definition: regtype.h:62
const size_t count(pCandidateA->getBorderLines().size())
NO_ERROR
no error.
Definition: regtype.h:83
#define VALUE_HEADEROFFSET
Definition: regimpl.hxx:34
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:32
UNICODE
The key has a value of type unicode string.
Definition: regtype.h:62
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:909
LONG
The key has a value of type long.
Definition: regtype.h:62
RegError deleteKey(const OUString &keyName)
Definition: keyimpl.cxx:212
LONGLIST
The key has a value of type long list.
Definition: regtype.h:62
RegError deleteKey(RegKeyHandle hKey, const OUString &keyName)
Definition: regimpl.cxx:736
RegError releaseKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:60
RegError createKey(RegKeyHandle hKey, const OUString &keyName, RegKeyHandle *phNewKey)
Definition: regimpl.cxx:604
NOT_DEFINED
The key has no value or the value type is unknown.
Definition: regtype.h:62
sal_uInt32 readUINT32(const sal_uInt8 *buffer, sal_uInt32 &v)
Definition: reflcnst.hxx:167
css::uno::Any const & rValue
sal_uInt16 sal_Unicode
bool isReadOnly() const
Definition: regimpl.hxx:85
sal_uInt32 m_refCount
Definition: keyimpl.hxx:126
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:80
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:62
RegError closeKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:204
osl::Mutex m_mutex
Definition: regimpl.hxx:141
SET_VALUE_FAILED
setting the specified value of a key failed.
Definition: regtype.h:83
enum SAL_DLLPUBLIC_RTTI RegValueType
defines the type of a key value.
Definition: regtype.h:59
VALUE_NOT_EXISTS
the key has no value
Definition: regtype.h:83
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
store::OStoreDirectory getStoreDir() const
Definition: keyimpl.cxx:944
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)
RegError setStringListValue(const OUString &valueName, char **pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:401
RegError getValue(const OUString &valueName, RegValue value) const
Definition: keyimpl.cxx:529
INVALID_KEYNAME
the keyname is invalid.
Definition: regtype.h:83
RegError createKey(const OUString &keyName, RegKeyHandle *phNewKey)
Definition: keyimpl.cxx:68
sal_uInt32 countSubKeys()
Definition: keyimpl.cxx:922
size
sal_uInt32 readINT32(const sal_uInt8 *buffer, sal_Int32 &v)
Definition: reflcnst.hxx:145
OUString m_name
Definition: keyimpl.hxx:127
RegError getUnicodeListValue(const OUString &valueName, sal_Unicode ***pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:814
RegError getValueInfo(const OUString &valueName, RegValueType *pValueTye, sal_uInt32 *pValueSize) const
Definition: keyimpl.cxx:220
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
RegError getLongListValue(const OUString &valueName, sal_Int32 **pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:614
#define REG_GUARD(mutex)
Definition: regimpl.hxx:36
INVALID_VALUE
the key has an invalid value or the value type is unknown.
Definition: regtype.h:83
sal_Unicode m_pszName[STORE_MAXIMUM_NAMESIZE]
#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:83
RegError releaseKey(RegKeyHandle hKey)
Definition: regimpl.cxx:589
RegError closeKey(RegKeyHandle hKey)
Definition: regimpl.cxx:706
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
#define VALUE_TYPEOFFSET
Definition: regimpl.hxx:33
sal_uInt32 m_nAttrib
RegError setLongListValue(const OUString &valueName, sal_Int32 const *pValueList, sal_uInt32 len)
Definition: keyimpl.cxx:346
RegError getStringListValue(const OUString &valueName, char ***pValueList, sal_uInt32 *pLen) const
Definition: keyimpl.cxx:717
~ORegKey()
Definition: keyimpl.cxx:52
void setModified(bool bModified=true)
Definition: keyimpl.hxx:104
ResultType type
RegError openKey(const OUString &keyName, RegKeyHandle *phOpenKey)
Definition: keyimpl.cxx:76
const store::OStoreFile & getStoreFile() const
Definition: keyimpl.hxx:115
static constexpr OUStringLiteral ROOT
Definition: regimpl.hxx:148
const store::OStoreFile & getStoreFile() const
Definition: regimpl.hxx:93
OUString getFullPath(OUString const &path) const
Definition: keyimpl.cxx:971
storeError next(iterator &it)
ORegistry * m_pRegistry
Definition: keyimpl.hxx:130
RegError openKey(RegKeyHandle hKey, const OUString &keyName, RegKeyHandle *phOpenKey)
Definition: regimpl.cxx:661
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo