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