LibreOffice Module registry (master)  1
regimpl.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 "regimpl.hxx"
22 
23 #include <cstddef>
24 #include <memory>
25 #include <set>
26 #include <string_view>
27 #include <vector>
28 #include <string.h>
29 #include <stdio.h>
30 
31 #if defined(UNX)
32 #include <unistd.h>
33 #endif
34 
35 #include "reflread.hxx"
36 
37 #include "reflwrit.hxx"
38 
39 #include <registry/reader.hxx>
40 #include <registry/refltype.hxx>
41 #include <registry/types.hxx>
42 
43 #include "reflcnst.hxx"
44 #include "keyimpl.hxx"
45 
46 #include <osl/thread.h>
47 #include <rtl/ustring.hxx>
48 #include <rtl/ustrbuf.hxx>
49 #include <osl/file.hxx>
50 
51 using namespace osl;
52 using namespace store;
53 
54 
55 namespace {
56 
57 void printString(std::u16string_view s) {
58  printf("\"");
59  for (std::size_t i = 0; i < s.size(); ++i) {
60  sal_Unicode c = s[i];
61  if (c == '"' || c == '\\') {
62  printf("\\%c", static_cast< char >(c));
63  } else if (s[i] >= ' ' && s[i] <= '~') {
64  printf("%c", static_cast< char >(c));
65  } else {
66  printf("\\u%04X", static_cast< unsigned int >(c));
67  }
68  }
69  printf("\"");
70 }
71 
72 void printFieldOrReferenceFlag(
73  RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first)
74 {
75  if ((*flags & flag) != RTFieldAccess::NONE) {
76  if (!*first) {
77  printf("|");
78  }
79  *first = false;
80  printf("%s", name);
81  *flags &= ~flag;
82  }
83 }
84 
85 void printFieldOrReferenceFlags(RTFieldAccess flags) {
86  if (flags == RTFieldAccess::NONE) {
87  printf("none");
88  } else {
89  bool first = true;
90  printFieldOrReferenceFlag(
91  &flags, RTFieldAccess::READONLY, "readonly", &first);
92  printFieldOrReferenceFlag(
93  &flags, RTFieldAccess::OPTIONAL, "optional", &first);
94  printFieldOrReferenceFlag(
95  &flags, RTFieldAccess::MAYBEVOID, "maybevoid", &first);
96  printFieldOrReferenceFlag(&flags, RTFieldAccess::BOUND, "bound", &first);
97  printFieldOrReferenceFlag(
98  &flags, RTFieldAccess::CONSTRAINED, "constrained", &first);
99  printFieldOrReferenceFlag(
100  &flags, RTFieldAccess::TRANSIENT, "transient", &first);
101  printFieldOrReferenceFlag(
102  &flags, RTFieldAccess::MAYBEAMBIGUOUS, "maybeambiguous", &first);
103  printFieldOrReferenceFlag(
104  &flags, RTFieldAccess::MAYBEDEFAULT, "maybedefault", &first);
105  printFieldOrReferenceFlag(
106  &flags, RTFieldAccess::REMOVABLE, "removable", &first);
107  printFieldOrReferenceFlag(
108  &flags, RTFieldAccess::ATTRIBUTE, "attribute", &first);
109  printFieldOrReferenceFlag(
110  &flags, RTFieldAccess::PROPERTY, "property", &first);
111  printFieldOrReferenceFlag(&flags, RTFieldAccess::CONST, "const", &first);
112  printFieldOrReferenceFlag(
113  &flags, RTFieldAccess::READWRITE, "readwrite", &first);
114  printFieldOrReferenceFlag(
115  &flags, RTFieldAccess::PARAMETERIZED_TYPE, "parameterized type", &first);
116  printFieldOrReferenceFlag(
117  &flags, RTFieldAccess::PUBLISHED, "published", &first);
118  if (flags != RTFieldAccess::NONE) {
119  if (!first) {
120  printf("|");
121  }
122  printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags));
123  }
124  }
125 }
126 
127 void dumpType(typereg::Reader const & reader, OString const & indent) {
128  if (reader.isValid()) {
129  printf("version: %ld\n", static_cast< long >(reader.getVersion()));
130  printf("%sdocumentation: ", indent.getStr());
131  printString(reader.getDocumentation());
132  printf("\n");
133  printf("%sfile name: ", indent.getStr());
134  printString(reader.getFileName());
135  printf("\n");
136  printf("%stype class: ", indent.getStr());
137  if (reader.isPublished()) {
138  printf("published ");
139  }
140  switch (reader.getTypeClass()) {
141  case RT_TYPE_INTERFACE:
142  printf("interface");
143  break;
144 
145  case RT_TYPE_MODULE:
146  printf("module");
147  break;
148 
149  case RT_TYPE_STRUCT:
150  printf("struct");
151  break;
152 
153  case RT_TYPE_ENUM:
154  printf("enum");
155  break;
156 
157  case RT_TYPE_EXCEPTION:
158  printf("exception");
159  break;
160 
161  case RT_TYPE_TYPEDEF:
162  printf("typedef");
163  break;
164 
165  case RT_TYPE_SERVICE:
166  printf("service");
167  break;
168 
169  case RT_TYPE_SINGLETON:
170  printf("singleton");
171  break;
172 
173  case RT_TYPE_CONSTANTS:
174  printf("constants");
175  break;
176 
177  default:
178  printf(
179  "<invalid (%ld)>", static_cast< long >(reader.getTypeClass()));
180  break;
181  }
182  printf("\n");
183  printf("%stype name: ", indent.getStr());
184  printString(reader.getTypeName());
185  printf("\n");
186  printf(
187  "%ssuper type count: %u\n", indent.getStr(),
188  static_cast< unsigned int >(reader.getSuperTypeCount()));
189  for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
190  printf(
191  "%ssuper type name %u: ", indent.getStr(),
192  static_cast< unsigned int >(i));
193  printString(reader.getSuperTypeName(i));
194  printf("\n");
195  }
196  printf(
197  "%sfield count: %u\n", indent.getStr(),
198  static_cast< unsigned int >(reader.getFieldCount()));
199  for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
200  printf(
201  "%sfield %u:\n", indent.getStr(),
202  static_cast< unsigned int >(i));
203  printf("%s documentation: ", indent.getStr());
204  printString(reader.getFieldDocumentation(i));
205  printf("\n");
206  printf("%s file name: ", indent.getStr());
207  printString(reader.getFieldFileName(i));
208  printf("\n");
209  printf("%s flags: ", indent.getStr());
210  printFieldOrReferenceFlags(reader.getFieldFlags(i));
211  printf("\n");
212  printf("%s name: ", indent.getStr());
213  printString(reader.getFieldName(i));
214  printf("\n");
215  printf("%s type name: ", indent.getStr());
216  printString(reader.getFieldTypeName(i));
217  printf("\n");
218  printf("%s value: ", indent.getStr());
219  RTConstValue value(reader.getFieldValue(i));
220  switch (value.m_type) {
221  case RT_TYPE_NONE:
222  printf("none");
223  break;
224 
225  case RT_TYPE_BOOL:
226  printf("boolean %s", value.m_value.aBool ? "true" : "false");
227  break;
228 
229  case RT_TYPE_BYTE:
230  printf("byte %d", static_cast< int >(value.m_value.aByte));
231  break;
232 
233  case RT_TYPE_INT16:
234  printf("short %d", static_cast< int >(value.m_value.aShort));
235  break;
236 
237  case RT_TYPE_UINT16:
238  printf(
239  "unsigned short %u",
240  static_cast< unsigned int >(value.m_value.aUShort));
241  break;
242 
243  case RT_TYPE_INT32:
244  printf("long %ld", static_cast< long >(value.m_value.aLong));
245  break;
246 
247  case RT_TYPE_UINT32:
248  printf(
249  "unsigned long %lu",
250  static_cast< unsigned long >(value.m_value.aULong));
251  break;
252 
253  case RT_TYPE_INT64:
254  // TODO: no portable way to print hyper values
255  printf("hyper");
256  break;
257 
258  case RT_TYPE_UINT64:
259  // TODO: no portable way to print unsigned hyper values
260  printf("unsigned hyper");
261  break;
262 
263  case RT_TYPE_FLOAT:
264  // TODO: no portable way to print float values
265  printf("float");
266  break;
267 
268  case RT_TYPE_DOUBLE:
269  // TODO: no portable way to print double values
270  printf("double");
271  break;
272 
273  case RT_TYPE_STRING:
274  printf("string ");
275  printString(value.m_value.aString);
276  break;
277 
278  default:
279  printf("<invalid (%ld)>", static_cast< long >(value.m_type));
280  break;
281  }
282  printf("\n");
283  }
284  printf(
285  "%smethod count: %u\n", indent.getStr(),
286  static_cast< unsigned int >(reader.getMethodCount()));
287  for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
288  printf(
289  "%smethod %u:\n", indent.getStr(),
290  static_cast< unsigned int >(i));
291  printf("%s documentation: ", indent.getStr());
292  printString(reader.getMethodDocumentation(i));
293  printf("\n");
294  printf("%s flags: ", indent.getStr());
295  switch (reader.getMethodFlags(i)) {
297  printf("oneway");
298  break;
299 
301  printf("synchronous");
302  break;
303 
305  printf("attribute get");
306  break;
307 
309  printf("attribute set");
310  break;
311 
312  default:
313  printf(
314  "<invalid (%ld)>",
315  static_cast< long >(reader.getMethodFlags(i)));
316  break;
317  }
318  printf("\n");
319  printf("%s name: ", indent.getStr());
320  printString(reader.getMethodName(i));
321  printf("\n");
322  printf("%s return type name: ", indent.getStr());
323  printString(reader.getMethodReturnTypeName(i));
324  printf("\n");
325  printf(
326  "%s parameter count: %u\n", indent.getStr(),
327  static_cast< unsigned int >(reader.getMethodParameterCount(i)));
328  // coverity[tainted_data] - cid#1215304 unhelpfully warns about untrusted loop bound
329  for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j)
330  {
331  printf(
332  "%s parameter %u:\n", indent.getStr(),
333  static_cast< unsigned int >(j));
334  printf("%s flags: ", indent.getStr());
335  RTParamMode flags = reader.getMethodParameterFlags(i, j);
336  bool rest = (flags & RT_PARAM_REST) != 0;
337  switch (flags & ~RT_PARAM_REST) {
338  case RT_PARAM_IN:
339  printf("in");
340  break;
341 
342  case RT_PARAM_OUT:
343  printf("out");
344  break;
345 
346  case RT_PARAM_INOUT:
347  printf("inout");
348  break;
349 
350  default:
351  printf("<invalid (%ld)>", static_cast< long >(flags));
352  rest = false;
353  break;
354  }
355  if (rest) {
356  printf("|rest");
357  }
358  printf("\n");
359  printf("%s name: ", indent.getStr());
360  printString(reader.getMethodParameterName(i, j));
361  printf("\n");
362  printf("%s type name: ", indent.getStr());
363  printString(reader.getMethodParameterTypeName(i, j));
364  printf("\n");
365  }
366  printf(
367  "%s exception count: %u\n", indent.getStr(),
368  static_cast< unsigned int >(reader.getMethodExceptionCount(i)));
369  // coverity[tainted_data] - cid#1215304 unhelpfully warns about untrusted loop bound
370  for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j)
371  {
372  printf(
373  "%s exception type name %u: ", indent.getStr(),
374  static_cast< unsigned int >(j));
375  printString(reader.getMethodExceptionTypeName(i, j));
376  printf("\n");
377  }
378  }
379  printf(
380  "%sreference count: %u\n", indent.getStr(),
381  static_cast< unsigned int >(reader.getReferenceCount()));
382  for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) {
383  printf(
384  "%sreference %u:\n", indent.getStr(),
385  static_cast< unsigned int >(i));
386  printf("%s documentation: ", indent.getStr());
387  printString(reader.getReferenceDocumentation(i));
388  printf("\n");
389  printf("%s flags: ", indent.getStr());
390  printFieldOrReferenceFlags(reader.getReferenceFlags(i));
391  printf("\n");
392  printf("%s sort: ", indent.getStr());
393  switch (reader.getReferenceSort(i)) {
395  printf("supports");
396  break;
397 
399  printf("exports");
400  break;
401 
403  printf("type parameter");
404  break;
405 
406  default:
407  printf(
408  "<invalid (%ld)>",
409  static_cast< long >(reader.getReferenceSort(i)));
410  break;
411  }
412  printf("\n");
413  printf("%s type name: ", indent.getStr());
414  printString(reader.getReferenceTypeName(i));
415  printf("\n");
416  }
417  } else {
418  printf("<invalid>\n");
419  }
420 }
421 
422 }
423 
425  : m_refCount(1)
426  , m_readOnly(false)
427  , m_isOpen(false)
428 {
429 }
430 
432 {
433  ORegKey* pRootKey = m_openKeyTable[ROOT];
434  if (pRootKey != nullptr)
435  (void) releaseKey(pRootKey);
436 
437  if (m_file.isValid())
438  m_file.close();
439 }
440 
441 RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode, bool bCreate)
442 {
444  OStoreFile rRegFile;
445  storeAccessMode sAccessMode = storeAccessMode::ReadWrite;
446  storeError errCode;
447 
448  if (bCreate)
449  {
450  sAccessMode = storeAccessMode::Create;
451  }
452  else if (accessMode & RegAccessMode::READONLY)
453  {
454  sAccessMode = storeAccessMode::ReadOnly;
455  m_readOnly = true;
456  }
457 
458  if (regName.isEmpty() &&
459  storeAccessMode::Create == sAccessMode)
460  {
461  errCode = rRegFile.createInMemory();
462  }
463  else
464  {
465  errCode = rRegFile.create(regName, sAccessMode);
466  }
467 
468  if (errCode)
469  {
470  switch (errCode)
471  {
472  case store_E_NotExists:
474  break;
477  break;
478  default:
480  break;
481  }
482  }
483  else
484  {
485  OStoreDirectory rStoreDir;
486  storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode);
487 
488  if (_err == store_E_None)
489  {
490  m_file = rRegFile;
491  m_name = regName;
492  m_isOpen = true;
493 
494  m_openKeyTable[ROOT] = new ORegKey(ROOT, this);
495  eRet = RegError::NO_ERROR;
496  }
497  else
499  }
500 
501  return eRet;
502 }
503 
505 {
507 
508  if (m_file.isValid())
509  {
511  m_file.close();
512  m_isOpen = false;
513  return RegError::NO_ERROR;
514  } else
515  {
517  }
518 }
519 
520 RegError ORegistry::destroyRegistry(const OUString& regName)
521 {
523 
524  if (!regName.isEmpty())
525  {
526  std::unique_ptr<ORegistry> pReg(new ORegistry());
527 
528  if (pReg->initRegistry(regName, RegAccessMode::READWRITE) == RegError::NO_ERROR)
529  {
530  pReg.reset();
531 
532  OUString systemName;
533  if (FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None)
534  systemName = regName;
535 
536  OString name(OUStringToOString(systemName, osl_getThreadTextEncoding()));
537  if (unlink(name.getStr()) != 0)
538  {
540  }
541  } else
542  {
544  }
545  } else
546  {
547  if (m_refCount != 1 || isReadOnly())
548  {
550  }
551 
552  if (m_file.isValid())
553  {
555  m_file.close();
556  m_isOpen = false;
557 
558  if (!m_name.isEmpty())
559  {
560  OUString systemName;
561  if (FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None)
562  systemName = m_name;
563 
564  OString name(OUStringToOString(systemName, osl_getThreadTextEncoding()));
565  if (unlink(name.getStr()) != 0)
566  {
568  }
569  }
570  } else
571  {
573  }
574  }
575 
576  return RegError::NO_ERROR;
577 }
578 
580 {
581  ORegKey* pKey = static_cast< ORegKey* >(hKey);
582  if (!pKey)
583  return RegError::INVALID_KEY;
584 
586  pKey->acquire();
587 
588  return RegError::NO_ERROR;
589 }
590 
592 {
593  ORegKey* pKey = static_cast< ORegKey* >(hKey);
594  if (!pKey)
595  return RegError::INVALID_KEY;
596 
598  if (pKey->release() == 0)
599  {
600  m_openKeyTable.erase(pKey->getName());
601  delete pKey;
602  }
603  return RegError::NO_ERROR;
604 }
605 
606 RegError ORegistry::createKey(RegKeyHandle hKey, std::u16string_view keyName,
607  RegKeyHandle* phNewKey)
608 {
609  ORegKey* pKey;
610 
611  *phNewKey = nullptr;
612 
613  if (keyName.empty())
615 
617 
618  if (hKey)
619  pKey = static_cast<ORegKey*>(hKey);
620  else
621  pKey = m_openKeyTable[ROOT];
622 
623  OUString sFullKeyName = pKey->getFullPath(keyName);
624 
625  if (m_openKeyTable.count(sFullKeyName) > 0)
626  {
627  *phNewKey = m_openKeyTable[sFullKeyName];
628  static_cast<ORegKey*>(*phNewKey)->acquire();
629  static_cast<ORegKey*>(*phNewKey)->setDeleted(false);
630  return RegError::NO_ERROR;
631  }
632 
633  OStoreDirectory rStoreDir;
634  OUStringBuffer sFullPath(sFullKeyName.getLength()+16);
635  OUString token;
636 
637  sFullPath.append('/');
638 
639  sal_Int32 nIndex = 0;
640  do
641  {
642  token = sFullKeyName.getToken(0, '/', nIndex);
643  if (!token.isEmpty())
644  {
645  if (rStoreDir.create(pKey->getStoreFile(), sFullPath.toString(), token, storeAccessMode::Create))
646  {
648  }
649 
650  sFullPath.append(token);
651  sFullPath.append('/');
652  }
653  } while(nIndex != -1);
654 
655 
656  pKey = new ORegKey(sFullKeyName, this);
657  *phNewKey = pKey;
658  m_openKeyTable[sFullKeyName] = pKey;
659 
660  return RegError::NO_ERROR;
661 }
662 
663 RegError ORegistry::openKey(RegKeyHandle hKey, std::u16string_view keyName,
664  RegKeyHandle* phOpenKey)
665 {
666  ORegKey* pKey;
667 
668  *phOpenKey = nullptr;
669 
670  if (keyName.empty())
671  {
673  }
674 
676 
677  if (hKey)
678  pKey = static_cast<ORegKey*>(hKey);
679  else
680  pKey = m_openKeyTable[ROOT];
681 
682  OUString path(pKey->getFullPath(keyName));
683  KeyMap::iterator i(m_openKeyTable.find(path));
684  if (i == m_openKeyTable.end()) {
685  sal_Int32 n = path.lastIndexOf('/') + 1;
686  switch (OStoreDirectory().create(
687  pKey->getStoreFile(), path.copy(0, n), path.copy(n),
688  isReadOnly() ? storeAccessMode::ReadOnly : storeAccessMode::ReadWrite))
689  {
690  case store_E_NotExists:
692  case store_E_WrongFormat:
693  return RegError::INVALID_KEY;
694  default:
695  break;
696  }
697 
698  std::unique_ptr< ORegKey > p(new ORegKey(path, this));
699  i = m_openKeyTable.insert(std::make_pair(path, p.get())).first;
700  p.release();
701  } else {
702  i->second->acquire();
703  }
704  *phOpenKey = i->second;
705  return RegError::NO_ERROR;
706 }
707 
709 {
710  ORegKey* pKey = static_cast< ORegKey* >(hKey);
711 
713 
714  OUString const aKeyName (pKey->getName());
715  if (m_openKeyTable.count(aKeyName) <= 0)
716  return RegError::KEY_NOT_OPEN;
717 
718  if (pKey->isModified())
719  {
720  ORegKey * pRootKey = getRootKey();
721  if (pKey != pRootKey)
722  {
723  // propagate "modified" state to RootKey.
724  pRootKey->setModified();
725  }
726  else
727  {
728  // closing modified RootKey, flush registry file.
729  (void) m_file.flush();
730  }
731  pKey->setModified(false);
732  (void) releaseKey(pRootKey);
733  }
734 
735  return releaseKey(pKey);
736 }
737 
738 RegError ORegistry::deleteKey(RegKeyHandle hKey, std::u16string_view keyName)
739 {
740  ORegKey* pKey = static_cast< ORegKey* >(hKey);
741  if (keyName.empty())
743 
745 
746  if (!pKey)
747  pKey = m_openKeyTable[ROOT];
748 
749  OUString sFullKeyName(pKey->getFullPath(keyName));
750  return eraseKey(m_openKeyTable[ROOT], sFullKeyName);
751 }
752 
753 RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName)
754 {
756 
757  if (keyName.isEmpty())
758  {
760  }
761 
762  OUString sFullKeyName(pKey->getName());
763  OUString sFullPath(sFullKeyName);
764  OUString sRelativKey;
765  sal_Int32 lastIndex = keyName.lastIndexOf('/');
766 
767  if (lastIndex >= 0)
768  {
769  sRelativKey += keyName.subView(lastIndex + 1);
770 
771  if (sFullKeyName.getLength() > 1)
772  sFullKeyName += keyName;
773  else
774  sFullKeyName += keyName.subView(1);
775 
776  sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1);
777  } else
778  {
779  if (sFullKeyName.getLength() > 1)
780  sFullKeyName += ROOT;
781 
782  sRelativKey += keyName;
783  sFullKeyName += keyName;
784 
785  if (sFullPath.getLength() > 1)
786  sFullPath += ROOT;
787  }
788 
789  ORegKey* pOldKey = nullptr;
790  _ret = pKey->openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pOldKey));
791  if (_ret != RegError::NO_ERROR)
792  return _ret;
793 
794  _ret = deleteSubkeysAndValues(pOldKey);
795  if (_ret != RegError::NO_ERROR)
796  {
797  pKey->closeKey(pOldKey);
798  return _ret;
799  }
800 
801  OUString tmpName = sRelativKey + ROOT;
802 
803  OStoreFile sFile(pKey->getStoreFile());
804  if (sFile.isValid() && sFile.remove(sFullPath, tmpName))
805  {
807  }
808  pOldKey->setModified();
809 
810  // set flag deleted !!!
811  pOldKey->setDeleted(true);
812 
813  return pKey->closeKey(pOldKey);
814 }
815 
817 {
820  OStoreDirectory rStoreDir(pKey->getStoreDir());
821  storeError _err = rStoreDir.first(iter);
822 
823  while (_err == store_E_None)
824  {
825  OUString const keyName(iter.m_pszName, iter.m_nLength);
826 
827  if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
828  {
829  _ret = eraseKey(pKey, keyName);
830  if (_ret != RegError::NO_ERROR)
831  return _ret;
832  }
833  else
834  {
835  OUString sFullPath(pKey->getName());
836 
837  if (sFullPath.getLength() > 1)
838  sFullPath += ROOT;
839 
840  if (const_cast<OStoreFile&>(pKey->getStoreFile()).remove(sFullPath, keyName))
841  {
843  }
844  pKey->setModified();
845  }
846 
847  _err = rStoreDir.next(iter);
848  }
849 
850  return RegError::NO_ERROR;
851 }
852 
853 RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName,
854  bool bWarnings, bool bReport)
855 {
856  ORegKey* pKey = static_cast< ORegKey* >(hKey);
857 
858  ORegistry aReg;
859  RegError _ret = aReg.initRegistry(regFileName, RegAccessMode::READONLY);
860  if (_ret != RegError::NO_ERROR)
861  return _ret;
862  ORegKey* pRootKey = aReg.getRootKey();
863 
865 
867  OStoreDirectory rStoreDir(pRootKey->getStoreDir());
868  storeError _err = rStoreDir.first(iter);
869 
870  while (_err == store_E_None)
871  {
872  OUString const keyName(iter.m_pszName, iter.m_nLength);
873 
874  if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
875  {
876  _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport);
877  }
878  else
879  {
880  _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport);
881  }
882 
883  if (_ret == RegError::MERGE_ERROR)
884  break;
885  if (_ret == RegError::MERGE_CONFLICT && bWarnings)
886  break;
887 
888  _err = rStoreDir.next(iter);
889  }
890 
891  rStoreDir = OStoreDirectory();
892  (void) aReg.releaseKey(pRootKey);
893  return _ret;
894 }
895 
897  ORegKey const * pSourceKey,
898  const OUString& valueName,
899  sal_uInt32 nCut,
900  bool bWarnings,
901  bool bReport)
902 {
903  OStoreStream rValue;
904  RegValueType valueType;
905  sal_uInt32 valueSize;
906  sal_uInt32 nSize;
907  storeAccessMode sourceAccess = storeAccessMode::ReadWrite;
908  OUString sTargetPath(pTargetKey->getName());
909  OUString sSourcePath(pSourceKey->getName());
910 
911  if (pSourceKey->isReadOnly())
912  {
913  sourceAccess = storeAccessMode::ReadOnly;
914  }
915 
916  if (nCut)
917  {
918  sTargetPath = sSourcePath.copy(nCut);
919  } else
920  {
921  if (sTargetPath.getLength() > 1)
922  {
923  if (sSourcePath.getLength() > 1)
924  sTargetPath += sSourcePath;
925  } else
926  sTargetPath = sSourcePath;
927  }
928 
929  if (sTargetPath.getLength() > 1) sTargetPath += ROOT;
930  if (sSourcePath.getLength() > 1) sSourcePath += ROOT;
931 
932  if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess))
933  {
935  }
936 
937  std::vector<sal_uInt8> aBuffer(VALUE_HEADERSIZE);
938 
939  sal_uInt32 rwBytes;
940  if (rValue.readAt(0, aBuffer.data(), VALUE_HEADERSIZE, rwBytes))
941  {
943  }
944  if (rwBytes != VALUE_HEADERSIZE)
945  {
947  }
948 
950  sal_uInt8 type = aBuffer[0];
951  valueType = static_cast<RegValueType>(type);
952  readUINT32(aBuffer.data() + VALUE_TYPEOFFSET, valueSize);
953 
954  nSize = VALUE_HEADERSIZE + valueSize;
955  aBuffer.resize(nSize);
956 
957  if (rValue.readAt(0, aBuffer.data(), nSize, rwBytes))
958  {
960  }
961  if (rwBytes != nSize)
962  {
964  }
965 
966  OStoreFile rTargetFile(pTargetKey->getStoreFile());
967 
968  if (!rValue.create(rTargetFile, sTargetPath, valueName, storeAccessMode::ReadWrite))
969  {
970  if (valueType == RegValueType::BINARY)
971  {
972  _ret = checkBlop(
973  rValue, sTargetPath, valueSize, aBuffer.data() + VALUE_HEADEROFFSET,
974  bReport);
975  if (_ret != RegError::NO_ERROR)
976  {
977  if (_ret == RegError::MERGE_ERROR ||
978  (_ret == RegError::MERGE_CONFLICT && bWarnings))
979  {
980  return _ret;
981  }
982  } else
983  {
984  return _ret;
985  }
986  }
987  }
988 
989  if (rValue.create(rTargetFile, sTargetPath, valueName, storeAccessMode::Create))
990  {
992  }
993  if (rValue.writeAt(0, aBuffer.data(), nSize, rwBytes))
994  {
996  }
997 
998  if (rwBytes != nSize)
999  {
1000  return RegError::INVALID_VALUE;
1001  }
1002  pTargetKey->setModified();
1003 
1004  return _ret;
1005 }
1006 
1008  std::u16string_view sTargetPath,
1009  sal_uInt32 srcValueSize,
1010  sal_uInt8 const * pSrcBuffer,
1011  bool bReport)
1012 {
1013  RegistryTypeReader reader(pSrcBuffer, srcValueSize);
1014 
1015  if (reader.getTypeClass() == RT_TYPE_INVALID)
1016  {
1017  return RegError::INVALID_VALUE;
1018  }
1019 
1020  std::vector<sal_uInt8> aBuffer(VALUE_HEADERSIZE);
1021  sal_uInt32 rwBytes;
1022  OString targetPath(OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8));
1023 
1024  if (!rValue.readAt(0, aBuffer.data(), VALUE_HEADERSIZE, rwBytes) &&
1025  (rwBytes == VALUE_HEADERSIZE))
1026  {
1027  sal_uInt8 type = aBuffer[0];
1028  RegValueType valueType = static_cast<RegValueType>(type);
1029  sal_uInt32 valueSize;
1030  readUINT32(aBuffer.data() + VALUE_TYPEOFFSET, valueSize);
1031 
1032  if (valueType == RegValueType::BINARY)
1033  {
1034  aBuffer.resize(valueSize);
1035  if (!rValue.readAt(VALUE_HEADEROFFSET, aBuffer.data(), valueSize, rwBytes) &&
1036  (rwBytes == valueSize))
1037  {
1038  RegistryTypeReader reader2(aBuffer.data(), valueSize);
1039 
1040  if ((reader.getTypeClass() != reader2.getTypeClass())
1041  || reader2.getTypeClass() == RT_TYPE_INVALID)
1042  {
1043  if (bReport)
1044  {
1045  fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n",
1046  targetPath.getStr());
1047  }
1048  return RegError::MERGE_ERROR;
1049  }
1050 
1051  if (reader.getTypeClass() == RT_TYPE_MODULE)
1052  {
1053  if (reader.getFieldCount() > 0 &&
1054  reader2.getFieldCount() > 0)
1055  {
1056  mergeModuleValue(rValue, reader, reader2);
1057 
1058  return RegError::NO_ERROR;
1059  } else
1060  if (reader2.getFieldCount() > 0)
1061  {
1062  return RegError::NO_ERROR;
1063  } else
1064  {
1065  return RegError::MERGE_CONFLICT;
1066  }
1067  } else
1068  {
1069  if (bReport)
1070  {
1071  fprintf(stderr, "WARNING: value of key \"%s\" already exists.\n",
1072  targetPath.getStr());
1073  }
1074  return RegError::MERGE_CONFLICT;
1075  }
1076  } else
1077  {
1078  if (bReport)
1079  {
1080  fprintf(stderr, "ERROR: values of key \"%s\" contains bad data.\n",
1081  targetPath.getStr());
1082  }
1083  return RegError::MERGE_ERROR;
1084  }
1085  } else
1086  {
1087  if (bReport)
1088  {
1089  fprintf(stderr, "ERROR: values of key \"%s\" has different types.\n",
1090  targetPath.getStr());
1091  }
1092  return RegError::MERGE_ERROR;
1093  }
1094  } else
1095  {
1096  return RegError::INVALID_VALUE;
1097  }
1098 }
1099 
1100 static sal_uInt32 checkTypeReaders(RegistryTypeReader const & reader1,
1101  RegistryTypeReader const & reader2,
1102  std::set< OUString >& nameSet)
1103 {
1104  sal_uInt32 count=0;
1105  for (sal_uInt32 i=0 ; i < reader1.getFieldCount(); i++)
1106  {
1107  nameSet.insert(reader1.getFieldName(i));
1108  count++;
1109  }
1110  for (sal_uInt32 i=0 ; i < reader2.getFieldCount(); i++)
1111  {
1112  if (nameSet.insert(reader2.getFieldName(i)).second)
1113  count++;
1114  }
1115  return count;
1116 }
1117 
1119  RegistryTypeReader const & reader,
1120  RegistryTypeReader const & reader2)
1121 {
1122  std::set< OUString > nameSet;
1123  sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet);
1124 
1125  if (count != reader.getFieldCount())
1126  {
1127  sal_uInt16 index = 0;
1128 
1129  RegistryTypeWriter writer(reader.getTypeClass(),
1130  reader.getTypeName(),
1131  reader.getSuperTypeName(),
1132  static_cast<sal_uInt16>(count));
1133 
1134  for (sal_uInt32 i=0 ; i < reader.getFieldCount(); i++)
1135  {
1136  writer.setFieldData(index,
1137  reader.getFieldName(i),
1138  reader.getFieldType(i),
1139  reader.getFieldDoku(i),
1140  reader.getFieldFileName(i),
1141  reader.getFieldAccess(i),
1142  reader.getFieldConstValue(i));
1143  index++;
1144  }
1145  for (sal_uInt32 i=0 ; i < reader2.getFieldCount(); i++)
1146  {
1147  if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1148  {
1149  writer.setFieldData(index,
1150  reader2.getFieldName(i),
1151  reader2.getFieldType(i),
1152  reader2.getFieldDoku(i),
1153  reader2.getFieldFileName(i),
1154  reader2.getFieldAccess(i),
1155  reader2.getFieldConstValue(i));
1156  index++;
1157  }
1158  }
1159 
1160  const sal_uInt8* pBlop = writer.getBlop();
1161  sal_uInt32 aBlopSize = writer.getBlopSize();
1162 
1164  std::vector<sal_uInt8> aBuffer(VALUE_HEADERSIZE + aBlopSize);
1165 
1166  memcpy(aBuffer.data(), &type, 1);
1167  writeUINT32(aBuffer.data() + VALUE_TYPEOFFSET, aBlopSize);
1168  memcpy(aBuffer.data() + VALUE_HEADEROFFSET, pBlop, aBlopSize);
1169 
1170  sal_uInt32 rwBytes;
1171  if (rTargetValue.writeAt(0, aBuffer.data(), VALUE_HEADERSIZE+aBlopSize, rwBytes))
1172  {
1173  return RegError::INVALID_VALUE;
1174  }
1175 
1176  if (rwBytes != VALUE_HEADERSIZE+aBlopSize)
1177  {
1178  return RegError::INVALID_VALUE;
1179  }
1180  }
1181  return RegError::NO_ERROR;
1182 }
1183 
1185  ORegKey* pSourceKey,
1186  const OUString& keyName,
1187  sal_uInt32 nCut,
1188  bool bWarnings,
1189  bool bReport)
1190 {
1192  OUString sRelPath(pSourceKey->getName().copy(nCut));
1193  OUString sFullPath;
1194 
1195  if(pTargetKey->getName().getLength() > 1)
1196  sFullPath += pTargetKey->getName();
1197  sFullPath += sRelPath;
1198  if (sRelPath.getLength() > 1 || sFullPath.isEmpty())
1199  sFullPath += ROOT;
1200 
1201  OUString sFullKeyName = sFullPath + keyName;
1202 
1203  OStoreDirectory rStoreDir;
1204  if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, storeAccessMode::Create))
1205  {
1207  }
1208 
1209  if (m_openKeyTable.count(sFullKeyName) > 0)
1210  {
1211  m_openKeyTable[sFullKeyName]->setDeleted(false);
1212  }
1213 
1214  ORegKey* pTmpKey = nullptr;
1215  _ret = pSourceKey->openKey(keyName, reinterpret_cast<RegKeyHandle*>(&pTmpKey));
1216  if (_ret != RegError::NO_ERROR)
1217  return _ret;
1218 
1220  OStoreDirectory rTmpStoreDir(pTmpKey->getStoreDir());
1221  storeError _err = rTmpStoreDir.first(iter);
1222 
1223  while (_err == store_E_None)
1224  {
1225  OUString const sName(iter.m_pszName, iter.m_nLength);
1226 
1227  if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1228  {
1229  _ret = loadAndSaveKeys(pTargetKey, pTmpKey,
1230  sName, nCut, bWarnings, bReport);
1231  } else
1232  {
1233  _ret = loadAndSaveValue(pTargetKey, pTmpKey,
1234  sName, nCut, bWarnings, bReport);
1235  }
1236 
1237  if (_ret == RegError::MERGE_ERROR)
1238  break;
1239  if (_ret == RegError::MERGE_CONFLICT && bWarnings)
1240  break;
1241 
1242  _err = rTmpStoreDir.next(iter);
1243  }
1244 
1245  pSourceKey->releaseKey(pTmpKey);
1246  return _ret;
1247 }
1248 
1250 {
1251  m_openKeyTable[ROOT]->acquire();
1252  return m_openKeyTable[ROOT];
1253 }
1254 
1256 {
1257  ORegKey *pKey = static_cast<ORegKey*>(hKey);
1258  OUString sName;
1261  OStoreDirectory rStoreDir(pKey->getStoreDir());
1262  storeError _err = rStoreDir.first(iter);
1263 
1264  OString regName(OUStringToOString(getName(), osl_getThreadTextEncoding()));
1265  OString keyName(OUStringToOString(pKey->getName(), RTL_TEXTENCODING_UTF8));
1266  fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr());
1267 
1268  while (_err == store_E_None)
1269  {
1270  sName = OUString(iter.m_pszName, iter.m_nLength);
1271 
1272  if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1273  {
1274  _ret = dumpKey(pKey->getName(), sName, 1);
1275  } else
1276  {
1277  _ret = dumpValue(pKey->getName(), sName, 1);
1278  }
1279 
1280  if (_ret != RegError::NO_ERROR)
1281  {
1282  return _ret;
1283  }
1284 
1285  _err = rStoreDir.next(iter);
1286  }
1287 
1288  return RegError::NO_ERROR;
1289 }
1290 
1291 RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const
1292 {
1293  OStoreStream rValue;
1294  sal_uInt32 valueSize;
1295  RegValueType valueType;
1296  OUString sFullPath(sPath);
1297  OString sIndent;
1298  storeAccessMode accessMode = storeAccessMode::ReadWrite;
1299 
1300  if (isReadOnly())
1301  {
1302  accessMode = storeAccessMode::ReadOnly;
1303  }
1304 
1305  for (int i= 0; i < nSpc; i++) sIndent += " ";
1306 
1307  if (sFullPath.getLength() > 1)
1308  {
1309  sFullPath += ROOT;
1310  }
1311  if (rValue.create(m_file, sFullPath, sName, accessMode))
1312  {
1314  }
1315 
1316  std::vector<sal_uInt8> aBuffer(VALUE_HEADERSIZE);
1317 
1318  sal_uInt32 rwBytes;
1319  if (rValue.readAt(0, aBuffer.data(), VALUE_HEADERSIZE, rwBytes))
1320  {
1321  return RegError::INVALID_VALUE;
1322  }
1323  if (rwBytes != (VALUE_HEADERSIZE))
1324  {
1325  return RegError::INVALID_VALUE;
1326  }
1327 
1328  sal_uInt8 type = aBuffer[0];
1329  valueType = static_cast<RegValueType>(type);
1330  readUINT32(aBuffer.data() + VALUE_TYPEOFFSET, valueSize);
1331 
1332  aBuffer.resize(valueSize);
1333  if (rValue.readAt(VALUE_HEADEROFFSET, aBuffer.data(), valueSize, rwBytes))
1334  {
1335  return RegError::INVALID_VALUE;
1336  }
1337  if (rwBytes != valueSize)
1338  {
1339  return RegError::INVALID_VALUE;
1340  }
1341 
1342  const char* indent = sIndent.getStr();
1343  switch (valueType)
1344  {
1346  fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent);
1347  break;
1348  case RegValueType::LONG:
1349  {
1350  fprintf(stdout, "%sValue: Type = RegValueType::LONG\n", indent);
1351  fprintf(
1352  stdout, "%s Size = %lu\n", indent,
1353  sal::static_int_cast< unsigned long >(valueSize));
1354  fprintf(stdout, "%s Data = ", indent);
1355 
1356  sal_Int32 value;
1357  readINT32(aBuffer.data(), value);
1358  fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value));
1359  }
1360  break;
1361  case RegValueType::STRING:
1362  {
1363  char* value = static_cast<char*>(std::malloc(valueSize));
1364  readUtf8(aBuffer.data(), value, valueSize);
1365  fprintf(stdout, "%sValue: Type = RegValueType::STRING\n", indent);
1366  fprintf(
1367  stdout, "%s Size = %lu\n", indent,
1368  sal::static_int_cast< unsigned long >(valueSize));
1369  fprintf(stdout, "%s Data = \"%s\"\n", indent, value);
1370  std::free(value);
1371  }
1372  break;
1373  case RegValueType::UNICODE:
1374  {
1375  sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode);
1376  fprintf(stdout, "%sValue: Type = RegValueType::UNICODE\n", indent);
1377  fprintf(
1378  stdout, "%s Size = %lu\n", indent,
1379  sal::static_int_cast< unsigned long >(valueSize));
1380  fprintf(stdout, "%s Data = ", indent);
1381 
1382  std::unique_ptr<sal_Unicode[]> value(new sal_Unicode[size]);
1383  readString(aBuffer.data(), value.get(), size);
1384 
1385  OString uStr(value.get(), rtl_ustr_getLength(value.get()), RTL_TEXTENCODING_UTF8);
1386  fprintf(stdout, "L\"%s\"\n", uStr.getStr());
1387  }
1388  break;
1389  case RegValueType::BINARY:
1390  {
1391  fprintf(stdout, "%sValue: Type = RegValueType::BINARY\n", indent);
1392  fprintf(
1393  stdout, "%s Size = %lu\n", indent,
1394  sal::static_int_cast< unsigned long >(valueSize));
1395  fprintf(stdout, "%s Data = ", indent);
1396  dumpType(
1397  typereg::Reader(aBuffer.data(), valueSize),
1398  sIndent + " ");
1399  }
1400  break;
1402  {
1403  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1404  sal_uInt32 len = 0;
1405 
1406  readUINT32(aBuffer.data(), len);
1407 
1408  fprintf(stdout, "%sValue: Type = RegValueType::LONGLIST\n", indent);
1409  fprintf(
1410  stdout, "%s Size = %lu\n", indent,
1411  sal::static_int_cast< unsigned long >(valueSize));
1412  fprintf(
1413  stdout, "%s Len = %lu\n", indent,
1414  sal::static_int_cast< unsigned long >(len));
1415  fprintf(stdout, "%s Data = ", indent);
1416 
1417  sal_Int32 longValue;
1418  for (sal_uInt32 i=0; i < len; i++)
1419  {
1420  readINT32(aBuffer.data() + offset, longValue);
1421 
1422  if (offset > 4)
1423  fprintf(stdout, "%s ", indent);
1424 
1425  fprintf(
1426  stdout, "%lu = %ld\n",
1427  sal::static_int_cast< unsigned long >(i),
1428  sal::static_int_cast< long >(longValue));
1429  offset += 4; // 4 Bytes for sal_Int32
1430  }
1431  }
1432  break;
1434  {
1435  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1436  sal_uInt32 sLen = 0;
1437  sal_uInt32 len = 0;
1438 
1439  readUINT32(aBuffer.data(), len);
1440 
1441  fprintf(stdout, "%sValue: Type = RegValueType::STRINGLIST\n", indent);
1442  fprintf(
1443  stdout, "%s Size = %lu\n", indent,
1444  sal::static_int_cast< unsigned long >(valueSize));
1445  fprintf(
1446  stdout, "%s Len = %lu\n", indent,
1447  sal::static_int_cast< unsigned long >(len));
1448  fprintf(stdout, "%s Data = ", indent);
1449 
1450  for (sal_uInt32 i=0; i < len; i++)
1451  {
1452  readUINT32(aBuffer.data() + offset, sLen);
1453 
1454  offset += 4; // 4 bytes (sal_uInt32) for the string size
1455 
1456  char *pValue = static_cast<char*>(std::malloc(sLen));
1457  readUtf8(aBuffer.data() + offset, pValue, sLen);
1458 
1459  if (offset > 8)
1460  fprintf(stdout, "%s ", indent);
1461 
1462  fprintf(
1463  stdout, "%lu = \"%s\"\n",
1464  sal::static_int_cast< unsigned long >(i), pValue);
1465  std::free(pValue);
1466  offset += sLen;
1467  }
1468  }
1469  break;
1470  case RegValueType::UNICODELIST:
1471  {
1472  sal_uInt32 offset = 4; // initial 4 bytes for the size of the array
1473  sal_uInt32 sLen = 0;
1474  sal_uInt32 len = 0;
1475 
1476  readUINT32(aBuffer.data(), len);
1477 
1478  fprintf(stdout, "%sValue: Type = RegValueType::UNICODELIST\n", indent);
1479  fprintf(
1480  stdout, "%s Size = %lu\n", indent,
1481  sal::static_int_cast< unsigned long >(valueSize));
1482  fprintf(
1483  stdout, "%s Len = %lu\n", indent,
1484  sal::static_int_cast< unsigned long >(len));
1485  fprintf(stdout, "%s Data = ", indent);
1486 
1487  OString uStr;
1488  for (sal_uInt32 i=0; i < len; i++)
1489  {
1490  readUINT32(aBuffer.data() + offset, sLen);
1491 
1492  offset += 4; // 4 bytes (sal_uInt32) for the string size
1493 
1494  sal_Unicode *pValue = static_cast<sal_Unicode*>(std::malloc((sLen / 2) * sizeof(sal_Unicode)));
1495  readString(aBuffer.data() + offset, pValue, sLen);
1496 
1497  if (offset > 8)
1498  fprintf(stdout, "%s ", indent);
1499 
1500  uStr = OString(pValue, rtl_ustr_getLength(pValue), RTL_TEXTENCODING_UTF8);
1501  fprintf(
1502  stdout, "%lu = L\"%s\"\n",
1503  sal::static_int_cast< unsigned long >(i),
1504  uStr.getStr());
1505 
1506  offset += sLen;
1507 
1508  std::free(pValue);
1509  }
1510  }
1511  break;
1512  }
1513 
1514  fprintf(stdout, "\n");
1515 
1516  return RegError::NO_ERROR;
1517 }
1518 
1519 RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const
1520 {
1521  OStoreDirectory rStoreDir;
1522  OUString sFullPath(sPath);
1523  OString sIndent;
1524  storeAccessMode accessMode = storeAccessMode::ReadWrite;
1526 
1527  if (isReadOnly())
1528  {
1529  accessMode = storeAccessMode::ReadOnly;
1530  }
1531 
1532  for (int i= 0; i < nSpace; i++) sIndent += " ";
1533 
1534  if (sFullPath.getLength() > 1)
1535  sFullPath += ROOT;
1536 
1537  storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode);
1538 
1539  if (_err == store_E_NotExists)
1540  return RegError::KEY_NOT_EXISTS;
1541  else if (_err == store_E_WrongFormat)
1542  return RegError::INVALID_KEY;
1543 
1544  fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
1545 
1546  OUString sSubPath(sFullPath);
1547  OUString sSubName;
1548  sSubPath += sName;
1549 
1551 
1552  _err = rStoreDir.first(iter);
1553 
1554  while (_err == store_E_None)
1555  {
1556  sSubName = OUString(iter.m_pszName, iter.m_nLength);
1557 
1558  if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1559  {
1560  _ret = dumpKey(sSubPath, sSubName, nSpace+2);
1561  } else
1562  {
1563  _ret = dumpValue(sSubPath, sSubName, nSpace+2);
1564  }
1565 
1566  if (_ret != RegError::NO_ERROR)
1567  {
1568  return _ret;
1569  }
1570 
1571  _err = rStoreDir.next(iter);
1572  }
1573 
1574  return RegError::NO_ERROR;
1575 }
1576 
1577 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 m_nLength
DESTROY_REGISTRY_FAILED
destroy a registry failed. There are may be any open keys.
Definition: regtype.h:85
Flag for published individual constants.
const OUString & getName() const
Definition: keyimpl.hxx:124
store_E_WrongFormat
OUString getFieldTypeName(sal_uInt16 index) const
Returns the type name of a field of this type reader.
Definition: reader.hxx:308
OUString getMethodParameterName(sal_uInt16 methodIndex, sal_uInt16 parameterIndex) const
Returns the name of a parameter of a method of this type reader.
Definition: reader.hxx:453
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
store_E_LockingViolation
NO_ERROR
no error.
Definition: regtype.h:85
RTParamMode
specifies the mode of a parameter.
Definition: types.hxx:274
sal_Int32 nIndex
sal_uInt16 getFieldCount() const
Returns the number of fields of this type reader.
Definition: reader.hxx:229
#define VALUE_HEADEROFFSET
Definition: regimpl.hxx:37
indicates a in and out parameter which is used also by reference
Definition: types.hxx:286
RegistryTypeReades reads a binary type blob.
Definition: reflread.hxx:37
Indicates an extended attribute getter (that has a 'raises' clause) of an interface type...
OUString getReferenceTypeName(sal_uInt16 index) const
Returns the type name of a reference of this type reader.
Definition: reader.hxx:589
storeError
sal_uInt32 m_refCount
Definition: regimpl.hxx:143
OUString getFieldFileName(sal_uInt16 index) const
returns the IDL filename of the field specified by index.
Definition: reflread.cxx:1753
storeAccessMode
RTConstValue getFieldConstValue(sal_uInt16 index) const
returns the value of the field specified by index.
Definition: reflread.cxx:1739
RegistryTypeWriter writes/creates a binary type blob.
Definition: reflwrit.hxx:39
RegAccessMode
defines the open/access mode of the registry.
Definition: regtype.h:41
OUString getDocumentation() const
Returns the documentation of this type reader.
Definition: reader.hxx:126
constexpr sal_uInt32 STORE_ATTRIB_ISDIR
ULONG m_refCount
const OUString & getName() const
Definition: regimpl.hxx:99
#define VALUE_HEADERSIZE
Definition: regimpl.hxx:35
OUString getFieldDoku(sal_uInt16 index) const
returns the documentation string for the field specified by index.
Definition: reflread.cxx:1746
sal_uInt16 getReferenceCount() const
Returns the number of references of this type reader.
Definition: reader.hxx:532
RegError acquireKey(RegKeyHandle hKey)
Definition: regimpl.cxx:579
specifies that the blob represents an enum type.
Definition: types.hxx:56
UNICODE
The key has a value of type unicode string.
Definition: regtype.h:64
specifies that the blob represents a service type.
Definition: types.hxx:72
storeError create(storeFileHandle hFile, OUString const &rPath, OUString const &rName, storeAccessMode eMode)
sal_Int64 n
store_E_None
bool isModified() const
Definition: keyimpl.hxx:105
LONG
The key has a value of type long.
Definition: regtype.h:64
static RegError checkBlop(store::OStoreStream &rValue, std::u16string_view sTargetPath, sal_uInt32 srcValueSize, sal_uInt8 const *pSrcBuffer, bool bReport)
Definition: regimpl.cxx:1007
OUString getMethodDocumentation(sal_uInt16 index) const
Returns the documentation of a method of this type reader.
Definition: reader.hxx:355
indicates the asynchronous mode of a method
LONGLIST
The key has a value of type long list.
Definition: regtype.h:64
MERGE_CONFLICT
conflicts exists during the merge process of a key.
Definition: regtype.h:85
sal_uInt16 getMethodCount() const
Returns the number of methods of this type reader.
Definition: reader.hxx:342
OUString getFieldName(sal_uInt16 index) const
returns the name of the field specified by index.
Definition: reflread.cxx:1722
RegError releaseKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:60
specifies that the blob represents an interface type.
Definition: types.hxx:41
RTConstValue getFieldValue(sal_uInt16 index) const
Returns the value of a field of this type reader.
Definition: reader.hxx:326
RTFieldAccess getFieldFlags(sal_uInt16 index) const
Returns the flags of a field of this type reader.
Definition: reader.hxx:277
MERGE_ERROR
merging a key, the value and all subkeys failed.
Definition: regtype.h:85
OUString getSuperTypeName() const
returns the full qualified name of the supertype.
Definition: reflread.cxx:1712
A type reader working on a binary blob that represents a UNOIDL type.
Definition: reader.hxx:42
NOT_DEFINED
The key has no value or the value type is unknown.
Definition: regtype.h:64
ORegKey * getRootKey()
Definition: regimpl.cxx:1249
RTParamMode getMethodParameterFlags(sal_uInt16 methodIndex, sal_uInt16 parameterIndex) const
Returns the flags of a parameter of a method of this type reader.
Definition: reader.hxx:433
sal_uInt32 readUINT32(const sal_uInt8 *buffer, sal_uInt32 &v)
Definition: reflcnst.hxx:167
bool isValid() const
Returns whether this type reader is valid.
Definition: reader.hxx:103
static sal_uInt32 checkTypeReaders(RegistryTypeReader const &reader1, RegistryTypeReader const &reader2, std::set< OUString > &nameSet)
Definition: regimpl.cxx:1100
indicates a pure in parameter which is used by value
Definition: types.hxx:280
OUString getMethodName(sal_uInt16 index) const
Returns the name of a method of this type reader.
Definition: reader.hxx:384
sal_uInt16 sal_Unicode
specifies that the blob represents a struct type.
Definition: types.hxx:51
OUString getReferenceDocumentation(sal_uInt16 index) const
Returns the documentation of a reference of this type reader.
Definition: reader.hxx:546
specifies that the field is a constant or enum value
the service exports the specified service that means this service provides also the specified service...
CREATE_KEY_FAILED
the key with the specified keyname cannot be created.
Definition: regtype.h:85
bool isReadOnly() const
Definition: regimpl.hxx:88
specifies that the blob represents a singleton type (a named object) which refers exactly one existin...
Definition: types.hxx:77
storeError flush() const
RTTypeClass getTypeClass() const
Returns the type class of this type reader.
Definition: reader.hxx:163
RTMethodMode getMethodFlags(sal_uInt16 index) const
Returns the flags of a method of this type reader.
Definition: reader.hxx:371
RTFieldAccess getFieldAccess(sal_uInt16 index) const
returns the access mode of the field specified by index.
Definition: reflread.cxx:1736
bool isPublished() const
Returns whether this type reader is published.
Definition: reader.hxx:173
const sal_uInt8 * getBlop()
returns a pointer to the new type blob.
Definition: reflwrit.cxx:1326
This mode allows readonly access.
RegError closeRegistry()
Definition: regimpl.cxx:504
Indicates a rest parameter (currently only valid for service constructors).
Definition: types.hxx:298
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
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
Reference< deployment::XPackageRegistry > create(Reference< deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, Reference< XComponentContext > const &xComponentContext)
storeError first(iterator &it)
specifies that the structure of the given blob is unknown and can't be read.
Definition: types.hxx:36
sal_uInt32 readUtf8(const sal_uInt8 *buffer, char *v, sal_uInt32 maxSize)
Definition: reflcnst.hxx:203
const char * sName
BINARY
The key has a value of type binary.
Definition: regtype.h:64
RegError closeKey(RegKeyHandle hKey)
Definition: keyimpl.cxx:202
store::OStoreFile m_file
Definition: regimpl.hxx:148
OUString getFileName() const
Returns the file name of this type reader.
Definition: reader.hxx:144
osl::Mutex m_mutex
Definition: regimpl.hxx:144
specifies that the property/attribute has read/write access
indicates a pure out parameter which is used by reference
Definition: types.hxx:283
enum SAL_DLLPUBLIC_RTTI RegValueType
defines the type of a key value.
Definition: regtype.h:61
REGISTRY_NOT_EXISTS
registry does not exists.
Definition: regtype.h:85
sal_uInt16 getMethodParameterCount(sal_uInt16 index) const
Returns the number of parameters of a method of this type reader.
Definition: reader.hxx:418
VALUE_NOT_EXISTS
the key has no value
Definition: regtype.h:85
OUString getFieldName(sal_uInt16 index) const
Returns the name of a field of this type reader.
Definition: reader.hxx:290
the service support the interface that means an implementation of this service must implement this in...
bool isReadOnly() const
Definition: keyimpl.hxx:111
sal_uInt16 getMethodExceptionCount(sal_uInt16 index) const
Returns the number of exceptions of a method of this type reader.
Definition: reader.hxx:497
storeError create(storeFileHandle hFile, OUString const &rPath, OUString const &rName, storeAccessMode eMode)
int i
specifies that the blob represents an exception type.
Definition: types.hxx:61
DELETE_VALUE_FAILED
deleting of the key value failed.
Definition: regtype.h:85
bool m_readOnly
Definition: regimpl.hxx:145
store::OStoreDirectory getStoreDir() const
Definition: keyimpl.cxx:937
storeError writeAt(sal_uInt32 nOffset, void const *pBuffer, sal_uInt32 nBytes, sal_uInt32 &rnDone)
void setFieldData(sal_uInt16 index, const OUString &name, const OUString &typeName, const OUString &doku, const OUString &fileName, RTFieldAccess access, const RTConstValue &constValue)
sets the data for a field member of a type blob.
Definition: reflwrit.cxx:1315
INVALID_KEYNAME
the keyname is invalid.
Definition: regtype.h:85
OUString getTypeName() const
Returns the type name of this type reader.
Definition: reader.hxx:185
KEY_NOT_EXISTS
the specified keyname points to a nonexisting key.
Definition: regtype.h:85
static RegError loadAndSaveValue(ORegKey *pTargetKey, ORegKey const *pSourceKey, const OUString &valueName, sal_uInt32 nCut, bool bWarnings, bool bReport)
Definition: regimpl.cxx:896
OUString getMethodParameterTypeName(sal_uInt16 methodIndex, sal_uInt16 parameterIndex) const
Returns the type name of a parameter of a method of this type reader.
Definition: reader.hxx:478
Indicates an extended attribute setter (that has a 'raises' clause) of an interface type...
RegError dumpRegistry(RegKeyHandle hKey) const
Definition: regimpl.cxx:1255
void setDeleted(bool bKeyDeleted)
Definition: keyimpl.hxx:102
OUString m_name
Definition: regimpl.hxx:147
size
KEY_NOT_OPEN
the key or key handle points to an invalid key or closed key.
Definition: regtype.h:85
RegError openKey(RegKeyHandle hKey, std::u16string_view keyName, RegKeyHandle *phOpenKey)
Definition: regimpl.cxx:663
sal_uInt32 getFieldCount() const
returns the number of fields (attributes/properties, enum values or number of constants in a module)...
Definition: reflread.cxx:1719
indicated the synchronous mode of a method
OUString getSuperTypeName(sal_uInt16 index) const
Returns the type name of a super type of this type reader.
Definition: reader.hxx:214
sal_uInt32 readINT32(const sal_uInt8 *buffer, sal_Int32 &v)
Definition: reflcnst.hxx:145
tuple index
OUString getFullPath(std::u16string_view path) const
Definition: keyimpl.cxx:964
RegError loadKey(RegKeyHandle hKey, const OUString &regFileName, bool bWarnings, bool bReport)
Definition: regimpl.cxx:853
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
void acquire()
Definition: keyimpl.hxx:37
friend class ORegKey
Definition: regimpl.hxx:102
Indicates that a member of a polymorphic struct type template is of a parameterized type...
specifies that the blob represents a typedef type.
Definition: types.hxx:66
INVALID_KEY
the key is not in a valid state.
Definition: regtype.h:85
RegError dumpValue(const OUString &sPath, const OUString &sName, sal_Int16 nSpace) const
Definition: regimpl.cxx:1291
sal_Unicode m_pszName[STORE_MAXIMUM_NAMESIZE]
RTTypeClass getTypeClass() const
returns the typeclass of the type represented by this blob.
Definition: reflread.cxx:1702
std::unique_ptr< char[]> aBuffer
~ORegistry()
Definition: regimpl.cxx:431
DELETE_KEY_FAILED
the specified key cannot be deleted. Maybe an open key handle exists to this key. ...
Definition: regtype.h:85
RegError createKey(RegKeyHandle hKey, std::u16string_view keyName, RegKeyHandle *phNewKey)
Definition: regimpl.cxx:606
Indicates a type parameter of a polymorphic struct type template.
storeError createInMemory()
unsigned char sal_uInt8
RegError eraseKey(ORegKey *pKey, const OUString &keyName)
Definition: regimpl.cxx:753
void * RegKeyHandle
defines the type of a registry key handle used in the C API.
Definition: regtype.h:30
OUString getFieldDocumentation(sal_uInt16 index) const
Returns the documentation of a field of this type reader.
Definition: reader.hxx:242
RegError releaseKey(RegKeyHandle hKey)
Definition: regimpl.cxx:591
RegError closeKey(RegKeyHandle hKey)
Definition: regimpl.cxx:708
sal_uInt32 writeUINT32(sal_uInt8 *buffer, sal_uInt32 v)
Definition: reflcnst.hxx:157
KeyMap m_openKeyTable
Definition: regimpl.hxx:149
sal_uInt32 getBlopSize()
returns the size of the new type blob in bytes.
Definition: reflwrit.cxx:1331
sal_uInt32 release()
Definition: keyimpl.hxx:40
sal_uInt16 getSuperTypeCount() const
Returns the number of super types of this type reader.
Definition: reader.hxx:200
bool isValid() const
#define VALUE_TYPEOFFSET
Definition: regimpl.hxx:36
sal_uInt32 m_nAttrib
RegError loadAndSaveKeys(ORegKey *pTargetKey, ORegKey *pSourceKey, const OUString &keyName, sal_uInt32 nCut, bool bWarnings, bool bReport)
Definition: regimpl.cxx:1184
void * p
Any value
RegError dumpKey(const OUString &sPath, const OUString &sName, sal_Int16 nSpace) const
Definition: regimpl.cxx:1519
specifies a property as optional that means that it must not be implemented.
store_E_NotExists
void setModified(bool bModified=true)
Definition: keyimpl.hxx:108
RTFieldAccess getReferenceFlags(sal_uInt16 index) const
Returns the flags of a reference of this type reader.
Definition: reader.hxx:563
ROOT
specifies that the blob represents a constants type.
Definition: types.hxx:85
specifies that the blob represents a module type.
Definition: types.hxx:46
ResultType type
OUString getMethodExceptionTypeName(sal_uInt16 methodIndex, sal_uInt16 exceptionIndex) const
Returns the type name of an exception of a method of this type reader.
Definition: reader.hxx:514
RegError initRegistry(const OUString &name, RegAccessMode accessMode, bool bCreate=false)
Definition: regimpl.cxx:441
RegError deleteSubkeysAndValues(ORegKey *pKey)
Definition: regimpl.cxx:816
RegError destroyRegistry(const OUString &name)
Definition: regimpl.cxx:520
const store::OStoreFile & getStoreFile() const
Definition: keyimpl.hxx:119
typereg_Version getVersion() const
Returns the binary blob version of this type reader.
Definition: reader.hxx:114
static RegError mergeModuleValue(store::OStoreStream &rTargetValue, RegistryTypeReader const &reader, RegistryTypeReader const &reader2)
Definition: regimpl.cxx:1118
OUString getFieldType(sal_uInt16 index) const
returns the full qualified name of the field specified by index.
Definition: reflread.cxx:1729
RegError openKey(std::u16string_view keyName, RegKeyHandle *phOpenKey)
Definition: keyimpl.cxx:76
OUString getFieldFileName(sal_uInt16 index) const
Returns the file name of a field of this type reader.
Definition: reader.hxx:261
RTFieldAccess
specifies the type for the field access.
Definition: types.hxx:133
RTReferenceType getReferenceSort(sal_uInt16 index) const
Returns the sort of a reference of this type reader.
Definition: reader.hxx:575
OUString getMethodReturnTypeName(sal_uInt16 index) const
Returns the return type name of a method of this type reader.
Definition: reader.hxx:402
RegError deleteKey(RegKeyHandle hKey, std::u16string_view keyName)
Definition: regimpl.cxx:738
OUString getTypeName() const
returns the full qualified name of the type.
Definition: reflread.cxx:1705
CANNOT_OPEN_FOR_READWRITE
registry cannot be opened with readwrite access because the registry is already open with readwrite a...
Definition: regtype.h:85
storeError create(OUString const &rFilename, storeAccessMode eAccessMode)
INVALID_REGISTRY
registry is in an invalid state or the registry does not point to a valid registry data file...
Definition: regtype.h:85
bool m_isOpen
Definition: regimpl.hxx:146
specifies a readonly property/attribute
storeError next(iterator &it)
specifies that the field is a property
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
specifies a helper class for const values.
Definition: refltype.hxx:42