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