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