1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_registry.hxx"
26
27 #include "regimpl.hxx"
28
29 #include <memory>
30 #include <string.h>
31 #include <stdio.h>
32
33 #if defined(UNX) || defined(OS2)
34 #include <unistd.h>
35 #endif
36 #ifdef __MINGW32__
37 #include <unistd.h>
38 #endif
39
40 #ifndef __REGISTRY_REFLREAD_HXX__
41 #include <registry/reflread.hxx>
42 #endif
43
44 #ifndef __REGISTRY_REFLWRIT_HXX__
45 #include <registry/reflwrit.hxx>
46 #endif
47
48 #include "registry/reader.hxx"
49 #include "registry/refltype.hxx"
50 #include "registry/types.h"
51 #include "registry/version.h"
52
53 #include "reflcnst.hxx"
54 #include "keyimpl.hxx"
55
56 #include <osl/thread.h>
57 #include <rtl/alloc.h>
58 #include <rtl/memory.h>
59 #include <rtl/ustring.hxx>
60 #include <rtl/ustrbuf.hxx>
61 #include <osl/file.hxx>
62
63 using namespace rtl;
64 using namespace osl;
65 using namespace store;
66
67 #if defined ( GCC ) && ( defined ( SCO ) )
68 sal_helper::ORealDynamicLoader* sal_helper::ODynamicLoader<RegistryTypeReader_Api>::m_pLoader = NULL;
69 #endif
70
71 namespace {
72
printString(rtl::OUString const & s)73 void printString(rtl::OUString const & s) {
74 printf("\"");
75 for (sal_Int32 i = 0; i < s.getLength(); ++i) {
76 sal_Unicode c = s[i];
77 if (c == '"' || c == '\\') {
78 printf("\\%c", static_cast< char >(c));
79 } else if (s[i] >= ' ' && s[i] <= '~') {
80 printf("%c", static_cast< char >(c));
81 } else {
82 printf("\\u%04X", static_cast< unsigned int >(c));
83 }
84 }
85 printf("\"");
86 }
87
printFieldOrReferenceFlag(RTFieldAccess * flags,RTFieldAccess flag,char const * name,bool * first)88 void printFieldOrReferenceFlag(
89 RTFieldAccess * flags, RTFieldAccess flag, char const * name, bool * first)
90 {
91 if ((*flags & flag) != 0) {
92 if (!*first) {
93 printf("|");
94 }
95 *first = false;
96 printf("%s", name);
97 *flags &= ~flag;
98 }
99 }
100
printFieldOrReferenceFlags(RTFieldAccess flags)101 void printFieldOrReferenceFlags(RTFieldAccess flags) {
102 if (flags == 0) {
103 printf("none");
104 } else {
105 bool first = true;
106 printFieldOrReferenceFlag(
107 &flags, RT_ACCESS_READONLY, "readonly", &first);
108 printFieldOrReferenceFlag(
109 &flags, RT_ACCESS_OPTIONAL, "optional", &first);
110 printFieldOrReferenceFlag(
111 &flags, RT_ACCESS_MAYBEVOID, "maybevoid", &first);
112 printFieldOrReferenceFlag(&flags, RT_ACCESS_BOUND, "bound", &first);
113 printFieldOrReferenceFlag(
114 &flags, RT_ACCESS_CONSTRAINED, "constrained", &first);
115 printFieldOrReferenceFlag(
116 &flags, RT_ACCESS_TRANSIENT, "transient", &first);
117 printFieldOrReferenceFlag(
118 &flags, RT_ACCESS_MAYBEAMBIGUOUS, "maybeambiguous", &first);
119 printFieldOrReferenceFlag(
120 &flags, RT_ACCESS_MAYBEDEFAULT, "maybedefault", &first);
121 printFieldOrReferenceFlag(
122 &flags, RT_ACCESS_REMOVEABLE, "removeable", &first);
123 printFieldOrReferenceFlag(
124 &flags, RT_ACCESS_ATTRIBUTE, "attribute", &first);
125 printFieldOrReferenceFlag(
126 &flags, RT_ACCESS_PROPERTY, "property", &first);
127 printFieldOrReferenceFlag(&flags, RT_ACCESS_CONST, "const", &first);
128 printFieldOrReferenceFlag(
129 &flags, RT_ACCESS_READWRITE, "readwrite", &first);
130 printFieldOrReferenceFlag(
131 &flags, RT_ACCESS_PARAMETERIZED_TYPE, "parameterized type", &first);
132 printFieldOrReferenceFlag(
133 &flags, RT_ACCESS_PUBLISHED, "published", &first);
134 if (flags != 0) {
135 if (!first) {
136 printf("|");
137 }
138 printf("<invalid (0x%04X)>", static_cast< unsigned int >(flags));
139 }
140 }
141 }
142
dumpType(typereg::Reader const & reader,rtl::OString const & indent)143 void dumpType(typereg::Reader const & reader, rtl::OString const & indent) {
144 if (reader.isValid()) {
145 printf("version: %ld\n", static_cast< long >(reader.getVersion()));
146 printf("%sdocumentation: ", indent.getStr());
147 printString(reader.getDocumentation());
148 printf("\n");
149 printf("%sfile name: ", indent.getStr());
150 printString(reader.getFileName());
151 printf("\n");
152 printf("%stype class: ", indent.getStr());
153 if (reader.isPublished()) {
154 printf("published ");
155 }
156 switch (reader.getTypeClass()) {
157 case RT_TYPE_INTERFACE:
158 printf("interface");
159 break;
160
161 case RT_TYPE_MODULE:
162 printf("module");
163 break;
164
165 case RT_TYPE_STRUCT:
166 printf("struct");
167 break;
168
169 case RT_TYPE_ENUM:
170 printf("enum");
171 break;
172
173 case RT_TYPE_EXCEPTION:
174 printf("exception");
175 break;
176
177 case RT_TYPE_TYPEDEF:
178 printf("typedef");
179 break;
180
181 case RT_TYPE_SERVICE:
182 printf("service");
183 break;
184
185 case RT_TYPE_SINGLETON:
186 printf("singleton");
187 break;
188
189 case RT_TYPE_CONSTANTS:
190 printf("constants");
191 break;
192
193 default:
194 printf(
195 "<invalid (%ld)>", static_cast< long >(reader.getTypeClass()));
196 break;
197 }
198 printf("\n");
199 printf("%stype name: ", indent.getStr());
200 printString(reader.getTypeName());
201 printf("\n");
202 printf(
203 "%ssuper type count: %u\n", indent.getStr(),
204 static_cast< unsigned int >(reader.getSuperTypeCount()));
205 {for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) {
206 printf(
207 "%ssuper type name %u: ", indent.getStr(),
208 static_cast< unsigned int >(i));
209 printString(reader.getSuperTypeName(i));
210 printf("\n");
211 }}
212 printf(
213 "%sfield count: %u\n", indent.getStr(),
214 static_cast< unsigned int >(reader.getFieldCount()));
215 {for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) {
216 printf(
217 "%sfield %u:\n", indent.getStr(),
218 static_cast< unsigned int >(i));
219 printf("%s documentation: ", indent.getStr());
220 printString(reader.getFieldDocumentation(i));
221 printf("\n");
222 printf("%s file name: ", indent.getStr());
223 printString(reader.getFieldFileName(i));
224 printf("\n");
225 printf("%s flags: ", indent.getStr());
226 printFieldOrReferenceFlags(reader.getFieldFlags(i));
227 printf("\n");
228 printf("%s name: ", indent.getStr());
229 printString(reader.getFieldName(i));
230 printf("\n");
231 printf("%s type name: ", indent.getStr());
232 printString(reader.getFieldTypeName(i));
233 printf("\n");
234 printf("%s value: ", indent.getStr());
235 RTConstValue value(reader.getFieldValue(i));
236 switch (value.m_type) {
237 case RT_TYPE_NONE:
238 printf("none");
239 break;
240
241 case RT_TYPE_BOOL:
242 printf("boolean %s", value.m_value.aBool ? "true" : "false");
243 break;
244
245 case RT_TYPE_BYTE:
246 printf(
247 "byte 0x%02X",
248 static_cast< unsigned int >(value.m_value.aByte));
249 break;
250
251 case RT_TYPE_INT16:
252 printf("short %d", static_cast< int >(value.m_value.aShort));
253 break;
254
255 case RT_TYPE_UINT16:
256 printf(
257 "unsigned short %u",
258 static_cast< unsigned int >(value.m_value.aUShort));
259 break;
260
261 case RT_TYPE_INT32:
262 printf("long %ld", static_cast< long >(value.m_value.aLong));
263 break;
264
265 case RT_TYPE_UINT32:
266 printf(
267 "unsigned long %lu",
268 static_cast< unsigned long >(value.m_value.aULong));
269 break;
270
271 case RT_TYPE_INT64:
272 // TODO: no portable way to print hyper values
273 printf("hyper");
274 break;
275
276 case RT_TYPE_UINT64:
277 // TODO: no portable way to print unsigned hyper values
278 printf("unsigned hyper");
279 break;
280
281 case RT_TYPE_FLOAT:
282 // TODO: no portable way to print float values
283 printf("float");
284 break;
285
286 case RT_TYPE_DOUBLE:
287 // TODO: no portable way to print double values
288 printf("double");
289 break;
290
291 case RT_TYPE_STRING:
292 printf("string ");
293 printString(value.m_value.aString);
294 break;
295
296 default:
297 printf("<invalid (%ld)>", static_cast< long >(value.m_type));
298 break;
299 }
300 printf("\n");
301 }}
302 printf(
303 "%smethod count: %u\n", indent.getStr(),
304 static_cast< unsigned int >(reader.getMethodCount()));
305 {for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) {
306 printf(
307 "%smethod %u:\n", indent.getStr(),
308 static_cast< unsigned int >(i));
309 printf("%s documentation: ", indent.getStr());
310 printString(reader.getMethodDocumentation(i));
311 printf("\n");
312 printf("%s flags: ", indent.getStr());
313 switch (reader.getMethodFlags(i)) {
314 case RT_MODE_ONEWAY:
315 printf("oneway");
316 break;
317
318 case RT_MODE_TWOWAY:
319 printf("synchronous");
320 break;
321
322 case RT_MODE_ATTRIBUTE_GET:
323 printf("attribute get");
324 break;
325
326 case RT_MODE_ATTRIBUTE_SET:
327 printf("attribute set");
328 break;
329
330 default:
331 printf(
332 "<invalid (%ld)>",
333 static_cast< long >(reader.getMethodFlags(i)));
334 break;
335 }
336 printf("\n");
337 printf("%s name: ", indent.getStr());
338 printString(reader.getMethodName(i));
339 printf("\n");
340 printf("%s return type name: ", indent.getStr());
341 printString(reader.getMethodReturnTypeName(i));
342 printf("\n");
343 printf(
344 "%s parameter count: %u\n", indent.getStr(),
345 static_cast< unsigned int >(reader.getMethodParameterCount(i)));
346 for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i); ++j)
347 {
348 printf(
349 "%s parameter %u:\n", indent.getStr(),
350 static_cast< unsigned int >(j));
351 printf("%s flags: ", indent.getStr());
352 RTParamMode flags = reader.getMethodParameterFlags(i, j);
353 bool rest = (flags & RT_PARAM_REST) != 0;
354 switch (flags & ~RT_PARAM_REST) {
355 case RT_PARAM_IN:
356 printf("in");
357 break;
358
359 case RT_PARAM_OUT:
360 printf("out");
361 break;
362
363 case RT_PARAM_INOUT:
364 printf("inout");
365 break;
366
367 default:
368 printf("<invalid (%ld)>", static_cast< long >(flags));
369 rest = false;
370 break;
371 }
372 if (rest) {
373 printf("|rest");
374 }
375 printf("\n");
376 printf("%s name: ", indent.getStr());
377 printString(reader.getMethodParameterName(i, j));
378 printf("\n");
379 printf("%s type name: ", indent.getStr());
380 printString(reader.getMethodParameterTypeName(i, j));
381 printf("\n");
382 }
383 printf(
384 "%s exception count: %u\n", indent.getStr(),
385 static_cast< unsigned int >(reader.getMethodExceptionCount(i)));
386 for (sal_uInt16 j = 0; j < reader.getMethodExceptionCount(i); ++j)
387 {
388 printf(
389 "%s exception type name %u: ", indent.getStr(),
390 static_cast< unsigned int >(j));
391 printString(reader.getMethodExceptionTypeName(i, j));
392 printf("\n");
393 }
394 }}
395 printf(
396 "%sreference count: %u\n", indent.getStr(),
397 static_cast< unsigned int >(reader.getReferenceCount()));
398 {for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) {
399 printf(
400 "%sreference %u:\n", indent.getStr(),
401 static_cast< unsigned int >(i));
402 printf("%s documentation: ", indent.getStr());
403 printString(reader.getReferenceDocumentation(i));
404 printf("\n");
405 printf("%s flags: ", indent.getStr());
406 printFieldOrReferenceFlags(reader.getReferenceFlags(i));
407 printf("\n");
408 printf("%s sort: ", indent.getStr());
409 switch (reader.getReferenceSort(i)) {
410 case RT_REF_SUPPORTS:
411 printf("supports");
412 break;
413
414 case RT_REF_EXPORTS:
415 printf("exports");
416 break;
417
418 case RT_REF_TYPE_PARAMETER:
419 printf("type parameter");
420 break;
421
422 default:
423 printf(
424 "<invalid (%ld)>",
425 static_cast< long >(reader.getReferenceSort(i)));
426 break;
427 }
428 printf("\n");
429 printf("%s type name: ", indent.getStr());
430 printString(reader.getReferenceTypeName(i));
431 printf("\n");
432 }}
433 } else {
434 printf("<invalid>\n");
435 }
436 }
437
438 }
439
440 //*********************************************************************
441 // ORegistry()
442 //
ORegistry()443 ORegistry::ORegistry()
444 : m_refCount(1)
445 , m_readOnly(sal_False)
446 , m_isOpen(sal_False)
447 , ROOT( RTL_CONSTASCII_USTRINGPARAM("/") )
448 {
449 }
450
451 //*********************************************************************
452 // ~ORegistry()
453 //
~ORegistry()454 ORegistry::~ORegistry()
455 {
456 ORegKey* pRootKey = m_openKeyTable[ROOT];
457 if (pRootKey != 0)
458 (void) releaseKey(pRootKey);
459
460 if (m_file.isValid())
461 m_file.close();
462 }
463
464
465 //*********************************************************************
466 // initRegistry
467 //
initRegistry(const OUString & regName,RegAccessMode accessMode)468 RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMode)
469 {
470 OStoreFile rRegFile;
471 storeAccessMode sAccessMode = REG_MODE_OPEN;
472 storeError errCode;
473
474 if (accessMode & REG_CREATE)
475 {
476 sAccessMode = REG_MODE_CREATE;
477 } else
478 if (accessMode & REG_READONLY)
479 {
480 sAccessMode = REG_MODE_OPENREAD;
481 m_readOnly = sal_True;
482 }
483
484 if (0 == regName.getLength() &&
485 store_AccessCreate == sAccessMode)
486 {
487 errCode = rRegFile.createInMemory();
488 }
489 else
490 {
491 errCode = rRegFile.create(regName, sAccessMode, REG_PAGESIZE);
492 }
493
494 if (errCode)
495 {
496 switch (errCode)
497 {
498 case store_E_NotExists:
499 return REG_REGISTRY_NOT_EXISTS;
500 case store_E_LockingViolation:
501 return REG_CANNOT_OPEN_FOR_READWRITE;
502 default:
503 return REG_INVALID_REGISTRY;
504 }
505 } else
506 {
507 OStoreDirectory rStoreDir;
508 storeError _err = rStoreDir.create(rRegFile, OUString(), OUString(), sAccessMode);
509
510 if ( _err == store_E_None )
511 {
512 m_file = rRegFile;
513 m_name = regName;
514 m_isOpen = sal_True;
515
516 m_openKeyTable[ROOT] = new ORegKey(ROOT, this);
517 return REG_NO_ERROR;
518 } else
519 return REG_INVALID_REGISTRY;
520 }
521 }
522
523
524 //*********************************************************************
525 // closeRegistry
526 //
closeRegistry()527 RegError ORegistry::closeRegistry()
528 {
529 REG_GUARD(m_mutex);
530
531 if (m_file.isValid())
532 {
533 (void) releaseKey(m_openKeyTable[ROOT]);
534 m_file.close();
535 m_isOpen = sal_False;
536 return REG_NO_ERROR;
537 } else
538 {
539 return REG_REGISTRY_NOT_EXISTS;
540 }
541 }
542
543
544 //*********************************************************************
545 // destroyRegistry
546 //
destroyRegistry(const OUString & regName)547 RegError ORegistry::destroyRegistry(const OUString& regName)
548 {
549 REG_GUARD(m_mutex);
550
551 if (regName.getLength())
552 {
553 ORegistry* pReg = new ORegistry();
554
555 if (!pReg->initRegistry(regName, REG_READWRITE))
556 {
557 delete pReg;
558
559 OUString systemName;
560 if ( FileBase::getSystemPathFromFileURL(regName, systemName) != FileBase::E_None )
561 systemName = regName;
562
563 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
564 if( unlink( name.getStr()) != 0)
565 {
566 return REG_DESTROY_REGISTRY_FAILED;
567 }
568 } else
569 {
570 return REG_DESTROY_REGISTRY_FAILED;
571 }
572 } else
573 {
574 if (m_refCount != 1 || isReadOnly())
575 {
576 return REG_DESTROY_REGISTRY_FAILED;
577 }
578
579 if (m_file.isValid())
580 {
581 releaseKey(m_openKeyTable[ROOT]);
582 m_file.close();
583 m_isOpen = sal_False;
584
585 if (m_name.getLength())
586 {
587 OUString systemName;
588 if ( FileBase::getSystemPathFromFileURL(m_name, systemName) != FileBase::E_None )
589 systemName = m_name;
590
591 OString name( OUStringToOString(systemName, osl_getThreadTextEncoding()) );
592 if (unlink(name.getStr()) != 0)
593 {
594 return REG_DESTROY_REGISTRY_FAILED;
595 }
596 }
597 } else
598 {
599 return REG_REGISTRY_NOT_EXISTS;
600 }
601 }
602
603 return REG_NO_ERROR;
604 }
605
606 //*********************************************************************
607 // acquireKey
608 //
acquireKey(RegKeyHandle hKey)609 RegError ORegistry::acquireKey (RegKeyHandle hKey)
610 {
611 ORegKey* pKey = static_cast< ORegKey* >(hKey);
612 if (!pKey)
613 return REG_INVALID_KEY;
614
615 REG_GUARD(m_mutex);
616 pKey->acquire();
617
618 return REG_NO_ERROR;
619 }
620
621 //*********************************************************************
622 // releaseKey
623 //
releaseKey(RegKeyHandle hKey)624 RegError ORegistry::releaseKey (RegKeyHandle hKey)
625 {
626 ORegKey* pKey = static_cast< ORegKey* >(hKey);
627 if (!pKey)
628 return REG_INVALID_KEY;
629
630 REG_GUARD(m_mutex);
631 if (pKey->release() == 0)
632 {
633 m_openKeyTable.erase(pKey->getName());
634 delete pKey;
635 }
636 return REG_NO_ERROR;
637 }
638
639 //*********************************************************************
640 // createKey
641 //
createKey(RegKeyHandle hKey,const OUString & keyName,RegKeyHandle * phNewKey)642 RegError ORegistry::createKey(RegKeyHandle hKey, const OUString& keyName,
643 RegKeyHandle* phNewKey)
644 {
645 ORegKey* pKey;
646
647 *phNewKey = NULL;
648
649 if ( !keyName.getLength() )
650 return REG_INVALID_KEYNAME;
651
652 REG_GUARD(m_mutex);
653
654 if (hKey)
655 pKey = (ORegKey*)hKey;
656 else
657 pKey = m_openKeyTable[ROOT];
658
659 OUString sFullKeyName = pKey->getFullPath(keyName);
660
661 if (m_openKeyTable.count(sFullKeyName) > 0)
662 {
663 *phNewKey = m_openKeyTable[sFullKeyName];
664 ((ORegKey*)*phNewKey)->acquire();
665 ((ORegKey*)*phNewKey)->setDeleted(sal_False);
666 return REG_NO_ERROR;
667 }
668
669 OStoreDirectory rStoreDir;
670 OUStringBuffer sFullPath(sFullKeyName.getLength());
671 OUString token;
672
673 sFullPath.append((sal_Unicode)'/');
674
675 sal_Int32 nIndex = 0;
676 do
677 {
678 token = sFullKeyName.getToken( 0, '/', nIndex );
679 if (token.getLength())
680 {
681 if (rStoreDir.create(pKey->getStoreFile(), sFullPath.getStr(), token, KEY_MODE_CREATE))
682 {
683 return REG_CREATE_KEY_FAILED;
684 }
685
686 sFullPath.append(token);
687 sFullPath.append((sal_Unicode)'/');
688 }
689 } while( nIndex != -1 );
690
691
692 pKey = new ORegKey(sFullKeyName, this);
693 *phNewKey = pKey;
694 m_openKeyTable[sFullKeyName] = pKey;
695
696 return REG_NO_ERROR;
697 }
698
699
700 //*********************************************************************
701 // openKey
702 //
openKey(RegKeyHandle hKey,const OUString & keyName,RegKeyHandle * phOpenKey)703 RegError ORegistry::openKey(RegKeyHandle hKey, const OUString& keyName,
704 RegKeyHandle* phOpenKey)
705 {
706 ORegKey* pKey;
707
708 *phOpenKey = NULL;
709
710 if ( !keyName.getLength() )
711 {
712 return REG_INVALID_KEYNAME;
713 }
714
715 REG_GUARD(m_mutex);
716
717 if (hKey)
718 pKey = (ORegKey*)hKey;
719 else
720 pKey = m_openKeyTable[ROOT];
721
722 OUString path(pKey->getFullPath(keyName));
723 KeyMap::iterator i(m_openKeyTable.find(path));
724 if (i == m_openKeyTable.end()) {
725 sal_Int32 n = path.lastIndexOf('/') + 1;
726 switch (OStoreDirectory().create(
727 pKey->getStoreFile(), path.copy(0, n), path.copy(n),
728 isReadOnly() ? KEY_MODE_OPENREAD : KEY_MODE_OPEN))
729 {
730 case store_E_NotExists:
731 return REG_KEY_NOT_EXISTS;
732 case store_E_WrongFormat:
733 return REG_INVALID_KEY;
734 default:
735 break;
736 }
737
738 std::auto_ptr< ORegKey > p(new ORegKey(path, this));
739 i = m_openKeyTable.insert(std::make_pair(path, p.get())).first;
740 p.release();
741 } else {
742 i->second->acquire();
743 }
744 *phOpenKey = i->second;
745 return REG_NO_ERROR;
746 }
747
748
749 //*********************************************************************
750 // closeKey
751 //
closeKey(RegKeyHandle hKey)752 RegError ORegistry::closeKey(RegKeyHandle hKey)
753 {
754 ORegKey* pKey = static_cast< ORegKey* >(hKey);
755
756 REG_GUARD(m_mutex);
757
758 OUString const aKeyName (pKey->getName());
759 if (!(m_openKeyTable.count(aKeyName) > 0))
760 return REG_KEY_NOT_OPEN;
761
762 if (pKey->isModified())
763 {
764 ORegKey * pRootKey = getRootKey();
765 if (pKey != pRootKey)
766 {
767 // propagate "modified" state to RootKey.
768 pRootKey->setModified();
769 }
770 else
771 {
772 // closing modified RootKey, flush registry file.
773 OSL_TRACE("registry::ORegistry::closeKey(): flushing modified RootKey");
774 (void) m_file.flush();
775 }
776 pKey->setModified(false);
777 (void) releaseKey(pRootKey);
778 }
779
780 return releaseKey(pKey);
781 }
782
783 //*********************************************************************
784 // deleteKey
785 //
deleteKey(RegKeyHandle hKey,const OUString & keyName)786 RegError ORegistry::deleteKey(RegKeyHandle hKey, const OUString& keyName)
787 {
788 ORegKey* pKey = static_cast< ORegKey* >(hKey);
789 if ( !keyName.getLength() )
790 return REG_INVALID_KEYNAME;
791
792 REG_GUARD(m_mutex);
793
794 if (!pKey)
795 pKey = m_openKeyTable[ROOT];
796
797 OUString sFullKeyName(pKey->getFullPath(keyName));
798 return eraseKey(m_openKeyTable[ROOT], sFullKeyName);
799 }
800
eraseKey(ORegKey * pKey,const OUString & keyName)801 RegError ORegistry::eraseKey(ORegKey* pKey, const OUString& keyName)
802 {
803 RegError _ret = REG_NO_ERROR;
804
805 if ( !keyName.getLength() )
806 {
807 return REG_INVALID_KEYNAME;
808 }
809
810 OUString sFullKeyName(pKey->getName());
811 OUString sFullPath(sFullKeyName);
812 OUString sRelativKey;
813 sal_Int32 lastIndex = keyName.lastIndexOf('/');
814
815 if ( lastIndex >= 0 )
816 {
817 sRelativKey += keyName.copy(lastIndex + 1);
818
819 if (sFullKeyName.getLength() > 1)
820 sFullKeyName += keyName;
821 else
822 sFullKeyName += keyName.getStr() + 1;
823
824 sFullPath = sFullKeyName.copy(0, keyName.lastIndexOf('/') + 1);
825 } else
826 {
827 if (sFullKeyName.getLength() > 1)
828 sFullKeyName += ROOT;
829
830 sRelativKey += keyName;
831 sFullKeyName += keyName;
832
833 if (sFullPath.getLength() > 1)
834 sFullPath += ROOT;
835 }
836
837 ORegKey* pOldKey = 0;
838 _ret = pKey->openKey(keyName, (RegKeyHandle*)&pOldKey);
839 if (_ret != REG_NO_ERROR)
840 return _ret;
841
842 _ret = deleteSubkeysAndValues(pOldKey);
843 if (_ret != REG_NO_ERROR)
844 {
845 pKey->closeKey(pOldKey);
846 return _ret;
847 }
848
849 OUString tmpName(sRelativKey);
850 tmpName += ROOT;
851
852 OStoreFile sFile(pKey->getStoreFile());
853 if ( sFile.isValid() && sFile.remove(sFullPath, tmpName) )
854 {
855 return REG_DELETE_KEY_FAILED;
856 }
857 pOldKey->setModified();
858
859 // set flag deleted !!!
860 pOldKey->setDeleted(sal_True);
861
862 return pKey->closeKey(pOldKey);
863 }
864
865 //*********************************************************************
866 // deleteSubKeysAndValues
867 //
deleteSubkeysAndValues(ORegKey * pKey)868 RegError ORegistry::deleteSubkeysAndValues(ORegKey* pKey)
869 {
870 OStoreDirectory::iterator iter;
871 RegError _ret = REG_NO_ERROR;
872 OStoreDirectory rStoreDir(pKey->getStoreDir());
873 storeError _err = rStoreDir.first(iter);
874
875 while ( _err == store_E_None )
876 {
877 OUString const keyName = iter.m_pszName;
878
879 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
880 {
881 _ret = eraseKey(pKey, keyName);
882 if (_ret)
883 return _ret;
884 }
885 else
886 {
887 OUString sFullPath(pKey->getName());
888
889 if (sFullPath.getLength() > 1)
890 sFullPath += ROOT;
891
892 if ( ((OStoreFile&)pKey->getStoreFile()).remove(sFullPath, keyName) )
893 {
894 return REG_DELETE_VALUE_FAILED;
895 }
896 pKey->setModified();
897 }
898
899 _err = rStoreDir.next(iter);
900 }
901
902 return REG_NO_ERROR;
903 }
904
905
906 //*********************************************************************
907 // loadKey
908 //
loadKey(RegKeyHandle hKey,const OUString & regFileName,sal_Bool bWarnings,sal_Bool bReport)909 RegError ORegistry::loadKey(RegKeyHandle hKey, const OUString& regFileName,
910 sal_Bool bWarnings, sal_Bool bReport)
911 {
912 RegError _ret = REG_NO_ERROR;
913 ORegKey* pKey = static_cast< ORegKey* >(hKey);
914
915 std::auto_ptr< ORegistry > pReg (new ORegistry());
916 _ret = pReg->initRegistry(regFileName, REG_READONLY);
917 if (_ret != REG_NO_ERROR)
918 return _ret;
919 ORegKey* pRootKey = pReg->getRootKey();
920
921 REG_GUARD(m_mutex);
922
923 OStoreDirectory::iterator iter;
924 OStoreDirectory rStoreDir(pRootKey->getStoreDir());
925 storeError _err = rStoreDir.first(iter);
926
927 while ( _err == store_E_None )
928 {
929 OUString const keyName = iter.m_pszName;
930
931 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
932 {
933 _ret = loadAndSaveKeys(pKey, pRootKey, keyName, 0, bWarnings, bReport);
934 }
935 else
936 {
937 _ret = loadAndSaveValue(pKey, pRootKey, keyName, 0, bWarnings, bReport);
938 }
939
940 if (_ret == REG_MERGE_ERROR)
941 break;
942 if (_ret == REG_MERGE_CONFLICT && bWarnings)
943 break;
944
945 _err = rStoreDir.next(iter);
946 }
947
948 rStoreDir = OStoreDirectory();
949 (void) pReg->releaseKey(pRootKey);
950 return _ret;
951 }
952
953
954 //*********************************************************************
955 // saveKey
956 //
saveKey(RegKeyHandle hKey,const OUString & regFileName,sal_Bool bWarnings,sal_Bool bReport)957 RegError ORegistry::saveKey(RegKeyHandle hKey, const OUString& regFileName,
958 sal_Bool bWarnings, sal_Bool bReport)
959 {
960 RegError _ret = REG_NO_ERROR;
961 ORegKey* pKey = static_cast< ORegKey* >(hKey);
962
963 std::auto_ptr< ORegistry > pReg (new ORegistry());
964 _ret = pReg->initRegistry(regFileName, REG_CREATE);
965 if (_ret != REG_NO_ERROR)
966 return _ret;
967 ORegKey* pRootKey = pReg->getRootKey();
968
969 REG_GUARD(m_mutex);
970
971 OStoreDirectory::iterator iter;
972 OStoreDirectory rStoreDir(pKey->getStoreDir());
973 storeError _err = rStoreDir.first(iter);
974
975 while ( _err == store_E_None )
976 {
977 OUString const keyName = iter.m_pszName;
978
979 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
980 {
981 _ret = loadAndSaveKeys(pRootKey, pKey, keyName,
982 pKey->getName().getLength(),
983 bWarnings, bReport);
984 }
985 else
986 {
987 _ret = loadAndSaveValue(pRootKey, pKey, keyName,
988 pKey->getName().getLength(),
989 bWarnings, bReport);
990 }
991
992 if (_ret != REG_NO_ERROR)
993 break;
994
995 _err = rStoreDir.next(iter);
996 }
997
998 (void) pReg->releaseKey(pRootKey);
999 return _ret;
1000 }
1001
1002
1003 //*********************************************************************
1004 // loadAndSaveValue()
1005 //
loadAndSaveValue(ORegKey * pTargetKey,ORegKey * pSourceKey,const OUString & valueName,sal_uInt32 nCut,sal_Bool bWarnings,sal_Bool bReport)1006 RegError ORegistry::loadAndSaveValue(ORegKey* pTargetKey,
1007 ORegKey* pSourceKey,
1008 const OUString& valueName,
1009 sal_uInt32 nCut,
1010 sal_Bool bWarnings,
1011 sal_Bool bReport)
1012 {
1013 OStoreStream rValue;
1014 sal_uInt8* pBuffer;
1015 RegValueType valueType;
1016 sal_uInt32 valueSize;
1017 sal_uInt32 nSize;
1018 storeAccessMode sourceAccess = VALUE_MODE_OPEN;
1019 OUString sTargetPath(pTargetKey->getName());
1020 OUString sSourcePath(pSourceKey->getName());
1021
1022 if (pSourceKey->isReadOnly())
1023 {
1024 sourceAccess = VALUE_MODE_OPENREAD;
1025 }
1026
1027 if (nCut)
1028 {
1029 sTargetPath = sSourcePath.copy(nCut);
1030 } else
1031 {
1032 if (sTargetPath.getLength() > 1)
1033 {
1034 if (sSourcePath.getLength() > 1)
1035 sTargetPath += sSourcePath;
1036 } else
1037 sTargetPath = sSourcePath;
1038 }
1039
1040 if (sTargetPath.getLength() > 1) sTargetPath += ROOT;
1041 if (sSourcePath.getLength() > 1) sSourcePath += ROOT;
1042
1043 if (rValue.create(pSourceKey->getStoreFile(), sSourcePath, valueName, sourceAccess))
1044 {
1045 return REG_VALUE_NOT_EXISTS;
1046 }
1047
1048 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1049
1050 sal_uInt32 rwBytes;
1051 if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1052 {
1053 rtl_freeMemory(pBuffer);
1054 return REG_INVALID_VALUE;
1055 }
1056 if (rwBytes != VALUE_HEADERSIZE)
1057 {
1058 rtl_freeMemory(pBuffer);
1059 return REG_INVALID_VALUE;
1060 }
1061
1062 RegError _ret = REG_NO_ERROR;
1063 sal_uInt8 type = *((sal_uInt8*)pBuffer);
1064 valueType = (RegValueType)type;
1065 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1066 rtl_freeMemory(pBuffer);
1067
1068 nSize = VALUE_HEADERSIZE + valueSize;
1069 pBuffer = (sal_uInt8*)rtl_allocateMemory(nSize);
1070
1071 if (rValue.readAt(0, pBuffer, nSize, rwBytes))
1072 {
1073 rtl_freeMemory(pBuffer);
1074 return REG_INVALID_VALUE;
1075 }
1076 if (rwBytes != nSize)
1077 {
1078 rtl_freeMemory(pBuffer);
1079 return REG_INVALID_VALUE;
1080 }
1081
1082 OStoreFile rTargetFile(pTargetKey->getStoreFile());
1083
1084 if (!rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_OPEN))
1085 {
1086 if (valueType == RG_VALUETYPE_BINARY)
1087 {
1088 _ret = checkBlop(
1089 rValue, sTargetPath, valueSize, pBuffer+VALUE_HEADEROFFSET,
1090 bReport);
1091 if (_ret)
1092 {
1093 if (_ret == REG_MERGE_ERROR ||
1094 (_ret == REG_MERGE_CONFLICT && bWarnings))
1095 {
1096 rtl_freeMemory(pBuffer);
1097 return _ret;
1098 }
1099 } else
1100 {
1101 rtl_freeMemory(pBuffer);
1102 return _ret;
1103 }
1104 }
1105 }
1106
1107 // write
1108 if (rValue.create(rTargetFile, sTargetPath, valueName, VALUE_MODE_CREATE))
1109 {
1110 rtl_freeMemory(pBuffer);
1111 return REG_INVALID_VALUE;
1112 }
1113 if (rValue.writeAt(0, pBuffer, nSize, rwBytes))
1114 {
1115 rtl_freeMemory(pBuffer);
1116 return REG_INVALID_VALUE;
1117 }
1118
1119 if (rwBytes != nSize)
1120 {
1121 rtl_freeMemory(pBuffer);
1122 return REG_INVALID_VALUE;
1123 }
1124 pTargetKey->setModified();
1125
1126 rtl_freeMemory(pBuffer);
1127 return _ret;
1128 }
1129
1130
1131 //*********************************************************************
1132 // checkblop()
1133 //
checkBlop(OStoreStream & rValue,const OUString & sTargetPath,sal_uInt32 srcValueSize,sal_uInt8 * pSrcBuffer,sal_Bool bReport)1134 RegError ORegistry::checkBlop(OStoreStream& rValue,
1135 const OUString& sTargetPath,
1136 sal_uInt32 srcValueSize,
1137 sal_uInt8* pSrcBuffer,
1138 sal_Bool bReport)
1139 {
1140 RegistryTypeReader reader(pSrcBuffer, srcValueSize, sal_False);
1141
1142 if (reader.getTypeClass() == RT_TYPE_INVALID)
1143 {
1144 return REG_INVALID_VALUE;
1145 }
1146
1147 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1148 RegValueType valueType;
1149 sal_uInt32 valueSize;
1150 sal_uInt32 rwBytes;
1151 OString targetPath( OUStringToOString(sTargetPath, RTL_TEXTENCODING_UTF8) );
1152
1153 if (!rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes) &&
1154 (rwBytes == VALUE_HEADERSIZE))
1155 {
1156 sal_uInt8 type = *((sal_uInt8*)pBuffer);
1157 valueType = (RegValueType)type;
1158 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1159 rtl_freeMemory(pBuffer);
1160
1161 if (valueType == RG_VALUETYPE_BINARY)
1162 {
1163 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
1164 if (!rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes) &&
1165 (rwBytes == valueSize))
1166 {
1167 RegistryTypeReader reader2(pBuffer, valueSize, sal_False);
1168
1169 if ((reader.getTypeClass() != reader2.getTypeClass())
1170 || reader2.getTypeClass() == RT_TYPE_INVALID)
1171 {
1172 rtl_freeMemory(pBuffer);
1173
1174 if (bReport)
1175 {
1176 fprintf(stdout, "ERROR: values of blop from key \"%s\" has different types.\n",
1177 targetPath.getStr());
1178 }
1179 return REG_MERGE_ERROR;
1180 }
1181
1182 if (reader.getTypeClass() == RT_TYPE_MODULE)
1183 {
1184 if (reader.getFieldCount() > 0 &&
1185 reader2.getFieldCount() > 0)
1186 {
1187 mergeModuleValue(rValue, reader, reader2);
1188
1189 rtl_freeMemory(pBuffer);
1190 return REG_NO_ERROR;
1191 } else
1192 if (reader2.getFieldCount() > 0)
1193 {
1194 rtl_freeMemory(pBuffer);
1195 return REG_NO_ERROR;
1196 } else
1197 {
1198 rtl_freeMemory(pBuffer);
1199 return REG_MERGE_CONFLICT;
1200 }
1201 } else
1202 {
1203 rtl_freeMemory(pBuffer);
1204
1205 if (bReport)
1206 {
1207 fprintf(stdout, "WARNING: value of key \"%s\" already exists.\n",
1208 targetPath.getStr());
1209 }
1210 return REG_MERGE_CONFLICT;
1211 }
1212 } else
1213 {
1214 rtl_freeMemory(pBuffer);
1215 if (bReport)
1216 {
1217 fprintf(stdout, "ERROR: values of key \"%s\" contains bad data.\n",
1218 targetPath.getStr());
1219 }
1220 return REG_MERGE_ERROR;
1221 }
1222 } else
1223 {
1224 rtl_freeMemory(pBuffer);
1225 if (bReport)
1226 {
1227 fprintf(stdout, "ERROR: values of key \"%s\" has different types.\n",
1228 targetPath.getStr());
1229 }
1230 return REG_MERGE_ERROR;
1231 }
1232 } else
1233 {
1234 rtl_freeMemory(pBuffer);
1235 return REG_INVALID_VALUE;
1236 }
1237 }
1238
checkTypeReaders(RegistryTypeReader & reader1,RegistryTypeReader & reader2,std::set<OUString> & nameSet)1239 static sal_uInt32 checkTypeReaders(RegistryTypeReader& reader1,
1240 RegistryTypeReader& reader2,
1241 std::set< OUString >& nameSet)
1242 {
1243 sal_uInt32 count=0;
1244 sal_uInt16 i;
1245 for (i=0 ; i < reader1.getFieldCount(); i++)
1246 {
1247 nameSet.insert(reader1.getFieldName(i));
1248 count++;
1249 }
1250 for (i=0 ; i < reader2.getFieldCount(); i++)
1251 {
1252 if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1253 {
1254 nameSet.insert(reader2.getFieldName(i));
1255 count++;
1256 }
1257 }
1258 return count;
1259 }
1260
1261 //*********************************************************************
1262 // mergeModuleValue()
1263 //
mergeModuleValue(OStoreStream & rTargetValue,RegistryTypeReader & reader,RegistryTypeReader & reader2)1264 RegError ORegistry::mergeModuleValue(OStoreStream& rTargetValue,
1265 RegistryTypeReader& reader,
1266 RegistryTypeReader& reader2)
1267 {
1268 sal_uInt16 index = 0;
1269
1270 std::set< OUString > nameSet;
1271 sal_uInt32 count = checkTypeReaders(reader, reader2, nameSet);
1272
1273 if (count != reader.getFieldCount())
1274 {
1275 RegistryTypeWriter writer(reader.getTypeClass(),
1276 reader.getTypeName(),
1277 reader.getSuperTypeName(),
1278 (sal_uInt16)count,
1279 0,
1280 0);
1281
1282 sal_uInt16 i;
1283 for (i=0 ; i < reader.getFieldCount(); i++)
1284 {
1285 writer.setFieldData(index,
1286 reader.getFieldName(i),
1287 reader.getFieldType(i),
1288 reader.getFieldDoku(i),
1289 reader.getFieldFileName(i),
1290 reader.getFieldAccess(i),
1291 reader.getFieldConstValue(i));
1292 index++;
1293 }
1294 for (i=0 ; i < reader2.getFieldCount(); i++)
1295 {
1296 if (nameSet.find(reader2.getFieldName(i)) == nameSet.end())
1297 {
1298 writer.setFieldData(index,
1299 reader2.getFieldName(i),
1300 reader2.getFieldType(i),
1301 reader2.getFieldDoku(i),
1302 reader2.getFieldFileName(i),
1303 reader2.getFieldAccess(i),
1304 reader2.getFieldConstValue(i));
1305 index++;
1306 }
1307 }
1308
1309 const sal_uInt8* pBlop = writer.getBlop();
1310 sal_uInt32 aBlopSize = writer.getBlopSize();
1311
1312 sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_BINARY;
1313 sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + aBlopSize);
1314
1315 rtl_copyMemory(pBuffer, &type, 1);
1316 writeUINT32(pBuffer+VALUE_TYPEOFFSET, aBlopSize);
1317 rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, pBlop, aBlopSize);
1318
1319 sal_uInt32 rwBytes;
1320 if (rTargetValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+aBlopSize, rwBytes))
1321 {
1322 rtl_freeMemory(pBuffer);
1323 return REG_INVALID_VALUE;
1324 }
1325
1326 if (rwBytes != VALUE_HEADERSIZE+aBlopSize)
1327 {
1328 rtl_freeMemory(pBuffer);
1329 return REG_INVALID_VALUE;
1330 }
1331
1332 rtl_freeMemory(pBuffer);
1333 }
1334 return REG_NO_ERROR;
1335 }
1336
1337 //*********************************************************************
1338 // loadAndSaveKeys()
1339 //
loadAndSaveKeys(ORegKey * pTargetKey,ORegKey * pSourceKey,const OUString & keyName,sal_uInt32 nCut,sal_Bool bWarnings,sal_Bool bReport)1340 RegError ORegistry::loadAndSaveKeys(ORegKey* pTargetKey,
1341 ORegKey* pSourceKey,
1342 const OUString& keyName,
1343 sal_uInt32 nCut,
1344 sal_Bool bWarnings,
1345 sal_Bool bReport)
1346 {
1347 RegError _ret = REG_NO_ERROR;
1348 OUString sRelPath(pSourceKey->getName().copy(nCut));
1349 OUString sFullPath;
1350
1351 if(pTargetKey->getName().getLength() > 1)
1352 sFullPath += pTargetKey->getName();
1353 sFullPath += sRelPath;
1354 if (sRelPath.getLength() > 1 || sFullPath.getLength() == 0)
1355 sFullPath += ROOT;
1356
1357 OUString sFullKeyName = sFullPath;
1358 sFullKeyName += keyName;
1359
1360 OStoreDirectory rStoreDir;
1361 if (rStoreDir.create(pTargetKey->getStoreFile(), sFullPath, keyName, KEY_MODE_CREATE))
1362 {
1363 return REG_CREATE_KEY_FAILED;
1364 }
1365
1366 if (m_openKeyTable.count(sFullKeyName) > 0)
1367 {
1368 m_openKeyTable[sFullKeyName]->setDeleted(sal_False);
1369 }
1370
1371 ORegKey* pTmpKey = 0;
1372 _ret = pSourceKey->openKey(keyName, (RegKeyHandle*)&pTmpKey);
1373 if (_ret != REG_NO_ERROR)
1374 return _ret;
1375
1376 OStoreDirectory::iterator iter;
1377 OStoreDirectory rTmpStoreDir(pTmpKey->getStoreDir());
1378 storeError _err = rTmpStoreDir.first(iter);
1379
1380 while ( _err == store_E_None)
1381 {
1382 OUString const sName = iter.m_pszName;
1383
1384 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1385 {
1386 _ret = loadAndSaveKeys(pTargetKey, pTmpKey,
1387 sName, nCut, bWarnings, bReport);
1388 } else
1389 {
1390 _ret = loadAndSaveValue(pTargetKey, pTmpKey,
1391 sName, nCut, bWarnings, bReport);
1392 }
1393
1394 if (_ret == REG_MERGE_ERROR)
1395 break;
1396 if (_ret == REG_MERGE_CONFLICT && bWarnings)
1397 break;
1398
1399 _err = rTmpStoreDir.next(iter);
1400 }
1401
1402 pSourceKey->releaseKey(pTmpKey);
1403 return _ret;
1404 }
1405
1406
1407 //*********************************************************************
1408 // getRootKey()
1409 //
getRootKey()1410 ORegKey* ORegistry::getRootKey()
1411 {
1412 m_openKeyTable[ROOT]->acquire();
1413 return m_openKeyTable[ROOT];
1414 }
1415
1416
1417 //*********************************************************************
1418 // dumpRegistry()
1419 //
dumpRegistry(RegKeyHandle hKey) const1420 RegError ORegistry::dumpRegistry(RegKeyHandle hKey) const
1421 {
1422 ORegKey *pKey = (ORegKey*)hKey;
1423 OUString sName;
1424 RegError _ret = REG_NO_ERROR;
1425 OStoreDirectory::iterator iter;
1426 OStoreDirectory rStoreDir(pKey->getStoreDir());
1427 storeError _err = rStoreDir.first(iter);
1428
1429 OString regName( OUStringToOString( getName(), osl_getThreadTextEncoding() ) );
1430 OString keyName( OUStringToOString( pKey->getName(), RTL_TEXTENCODING_UTF8 ) );
1431 fprintf(stdout, "Registry \"%s\":\n\n%s\n", regName.getStr(), keyName.getStr());
1432
1433 while ( _err == store_E_None )
1434 {
1435 sName = iter.m_pszName;
1436
1437 if (iter.m_nAttrib & STORE_ATTRIB_ISDIR)
1438 {
1439 _ret = dumpKey(pKey->getName(), sName, 1);
1440 } else
1441 {
1442 _ret = dumpValue(pKey->getName(), sName, 1);
1443 }
1444
1445 if (_ret)
1446 {
1447 return _ret;
1448 }
1449
1450 _err = rStoreDir.next(iter);
1451 }
1452
1453 return REG_NO_ERROR;
1454 }
1455
1456 //*********************************************************************
1457 // dumpValue()
1458 //
dumpValue(const OUString & sPath,const OUString & sName,sal_Int16 nSpc) const1459 RegError ORegistry::dumpValue(const OUString& sPath, const OUString& sName, sal_Int16 nSpc) const
1460 {
1461 OStoreStream rValue;
1462 sal_uInt8* pBuffer;
1463 sal_uInt32 valueSize;
1464 RegValueType valueType;
1465 OUString sFullPath(sPath);
1466 OString sIndent;
1467 storeAccessMode accessMode = VALUE_MODE_OPEN;
1468
1469 if (isReadOnly())
1470 {
1471 accessMode = VALUE_MODE_OPENREAD;
1472 }
1473
1474 for (int i= 0; i < nSpc; i++) sIndent += " ";
1475
1476 if (sFullPath.getLength() > 1)
1477 {
1478 sFullPath += ROOT;
1479 }
1480 if (rValue.create(m_file, sFullPath, sName, accessMode))
1481 {
1482 return REG_VALUE_NOT_EXISTS;
1483 }
1484
1485 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE);
1486
1487 sal_uInt32 rwBytes;
1488 if (rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, rwBytes))
1489 {
1490 rtl_freeMemory(pBuffer);
1491 return REG_INVALID_VALUE;
1492 }
1493 if (rwBytes != (VALUE_HEADERSIZE))
1494 {
1495 rtl_freeMemory(pBuffer);
1496 return REG_INVALID_VALUE;
1497 }
1498
1499 sal_uInt8 type = *((sal_uInt8*)pBuffer);
1500 valueType = (RegValueType)type;
1501 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize);
1502
1503 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
1504 if (rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, rwBytes))
1505 {
1506 rtl_freeMemory(pBuffer);
1507 return REG_INVALID_VALUE;
1508 }
1509 if (rwBytes != valueSize)
1510 {
1511 rtl_freeMemory(pBuffer);
1512 return REG_INVALID_VALUE;
1513 }
1514
1515 const sal_Char* indent = sIndent.getStr();
1516 switch (valueType)
1517 {
1518 case 0:
1519 fprintf(stdout, "%sValue: Type = VALUETYPE_NOT_DEFINED\n", indent);
1520 break;
1521 case 1:
1522 {
1523 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONG\n", indent);
1524 fprintf(
1525 stdout, "%s Size = %lu\n", indent,
1526 sal::static_int_cast< unsigned long >(valueSize));
1527 fprintf(stdout, "%s Data = ", indent);
1528
1529 sal_Int32 value;
1530 readINT32(pBuffer, value);
1531 fprintf(stdout, "%ld\n", sal::static_int_cast< long >(value));
1532 }
1533 break;
1534 case 2:
1535 {
1536 sal_Char* value = (sal_Char*)rtl_allocateMemory(valueSize);
1537 readUtf8(pBuffer, value, valueSize);
1538 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRING\n", indent);
1539 fprintf(
1540 stdout, "%s Size = %lu\n", indent,
1541 sal::static_int_cast< unsigned long >(valueSize));
1542 fprintf(stdout, "%s Data = \"%s\"\n", indent, value);
1543 rtl_freeMemory(value);
1544 }
1545 break;
1546 case 3:
1547 {
1548 sal_uInt32 size = (valueSize / 2) * sizeof(sal_Unicode);
1549 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODE\n", indent);
1550 fprintf(
1551 stdout, "%s Size = %lu\n", indent,
1552 sal::static_int_cast< unsigned long >(valueSize));
1553 fprintf(stdout, "%s Data = ", indent);
1554
1555 sal_Unicode* value = new sal_Unicode[size];
1556 readString(pBuffer, value, size);
1557
1558 OString uStr = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
1559 fprintf(stdout, "L\"%s\"\n", uStr.getStr());
1560 delete[] value;
1561 }
1562 break;
1563 case 4:
1564 {
1565 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_BINARY\n", indent);
1566 fprintf(
1567 stdout, "%s Size = %lu\n", indent,
1568 sal::static_int_cast< unsigned long >(valueSize));
1569 fprintf(stdout, "%s Data = ", indent);
1570 dumpType(
1571 typereg::Reader(
1572 pBuffer, valueSize, false, TYPEREG_VERSION_1),
1573 sIndent + " ");
1574 }
1575 break;
1576 case 5:
1577 {
1578 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1579 sal_uInt32 len = 0;
1580
1581 readUINT32(pBuffer, len);
1582
1583 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_LONGLIST\n", indent);
1584 fprintf(
1585 stdout, "%s Size = %lu\n", indent,
1586 sal::static_int_cast< unsigned long >(valueSize));
1587 fprintf(
1588 stdout, "%s Len = %lu\n", indent,
1589 sal::static_int_cast< unsigned long >(len));
1590 fprintf(stdout, "%s Data = ", indent);
1591
1592 sal_Int32 longValue;
1593 for (sal_uInt32 i=0; i < len; i++)
1594 {
1595 readINT32(pBuffer+offset, longValue);
1596
1597 if (offset > 4)
1598 fprintf(stdout, "%s ", indent);
1599
1600 fprintf(
1601 stdout, "%lu = %ld\n",
1602 sal::static_int_cast< unsigned long >(i),
1603 sal::static_int_cast< long >(longValue));
1604 offset += 4; // 4 Bytes fuer sal_Int32
1605 }
1606 }
1607 break;
1608 case 6:
1609 {
1610 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1611 sal_uInt32 sLen = 0;
1612 sal_uInt32 len = 0;
1613
1614 readUINT32(pBuffer, len);
1615
1616 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_STRINGLIST\n", indent);
1617 fprintf(
1618 stdout, "%s Size = %lu\n", indent,
1619 sal::static_int_cast< unsigned long >(valueSize));
1620 fprintf(
1621 stdout, "%s Len = %lu\n", indent,
1622 sal::static_int_cast< unsigned long >(len));
1623 fprintf(stdout, "%s Data = ", indent);
1624
1625 sal_Char *pValue;
1626 for (sal_uInt32 i=0; i < len; i++)
1627 {
1628 readUINT32(pBuffer+offset, sLen);
1629
1630 offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1631
1632 pValue = (sal_Char*)rtl_allocateMemory(sLen);
1633 readUtf8(pBuffer+offset, pValue, sLen);
1634
1635 if (offset > 8)
1636 fprintf(stdout, "%s ", indent);
1637
1638 fprintf(
1639 stdout, "%lu = \"%s\"\n",
1640 sal::static_int_cast< unsigned long >(i), pValue);
1641 offset += sLen;
1642 }
1643 }
1644 break;
1645 case 7:
1646 {
1647 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays
1648 sal_uInt32 sLen = 0;
1649 sal_uInt32 len = 0;
1650
1651 readUINT32(pBuffer, len);
1652
1653 fprintf(stdout, "%sValue: Type = RG_VALUETYPE_UNICODELIST\n", indent);
1654 fprintf(
1655 stdout, "%s Size = %lu\n", indent,
1656 sal::static_int_cast< unsigned long >(valueSize));
1657 fprintf(
1658 stdout, "%s Len = %lu\n", indent,
1659 sal::static_int_cast< unsigned long >(len));
1660 fprintf(stdout, "%s Data = ", indent);
1661
1662 sal_Unicode *pValue;
1663 OString uStr;
1664 for (sal_uInt32 i=0; i < len; i++)
1665 {
1666 readUINT32(pBuffer+offset, sLen);
1667
1668 offset += 4; // 4 Bytes (sal_uInt32) fuer die Groesse des strings in Bytes
1669
1670 pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode));
1671 readString(pBuffer+offset, pValue, sLen);
1672
1673 if (offset > 8)
1674 fprintf(stdout, "%s ", indent);
1675
1676 uStr = OUStringToOString(pValue, RTL_TEXTENCODING_UTF8);
1677 fprintf(
1678 stdout, "%lu = L\"%s\"\n",
1679 sal::static_int_cast< unsigned long >(i),
1680 uStr.getStr());
1681
1682 offset += sLen;
1683
1684 rtl_freeMemory(pValue);
1685 }
1686 }
1687 break;
1688 }
1689
1690 fprintf(stdout, "\n");
1691
1692 rtl_freeMemory(pBuffer);
1693 return REG_NO_ERROR;
1694 }
1695
1696 //*********************************************************************
1697 // dumpKey()
1698 //
dumpKey(const OUString & sPath,const OUString & sName,sal_Int16 nSpace) const1699 RegError ORegistry::dumpKey(const OUString& sPath, const OUString& sName, sal_Int16 nSpace) const
1700 {
1701 OStoreDirectory rStoreDir;
1702 OUString sFullPath(sPath);
1703 OString sIndent;
1704 storeAccessMode accessMode = KEY_MODE_OPEN;
1705 RegError _ret = REG_NO_ERROR;
1706
1707 if (isReadOnly())
1708 {
1709 accessMode = KEY_MODE_OPENREAD;
1710 }
1711
1712 for (int i= 0; i < nSpace; i++) sIndent += " ";
1713
1714 if (sFullPath.getLength() > 1)
1715 sFullPath += ROOT;
1716
1717 storeError _err = rStoreDir.create(m_file, sFullPath, sName, accessMode);
1718
1719 if (_err == store_E_NotExists)
1720 return REG_KEY_NOT_EXISTS;
1721 else
1722 if (_err == store_E_WrongFormat)
1723 return REG_INVALID_KEY;
1724
1725 fprintf(stdout, "%s/ %s\n", sIndent.getStr(), OUStringToOString(sName, RTL_TEXTENCODING_UTF8).getStr());
1726
1727 OUString sSubPath(sFullPath);
1728 OUString sSubName;
1729 sSubPath += sName;
1730
1731 OStoreDirectory::iterator iter;
1732
1733 _err = rStoreDir.first(iter);
1734
1735 while ( _err == store_E_None)
1736 {
1737 sSubName = iter.m_pszName;
1738
1739 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR )
1740 {
1741 _ret = dumpKey(sSubPath, sSubName, nSpace+2);
1742 } else
1743 {
1744 _ret = dumpValue(sSubPath, sSubName, nSpace+2);
1745 }
1746
1747 if (_ret)
1748 {
1749 return _ret;
1750 }
1751
1752 _err = rStoreDir.next(iter);
1753 }
1754
1755 return REG_NO_ERROR;
1756 }
1757