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 "keyimpl.hxx" 32 33 #include "reflcnst.hxx" 34 #include "rtl/alloc.h" 35 #include "rtl/memory.h" 36 #include "rtl/ustrbuf.hxx" 37 38 using rtl::OUString; 39 using rtl::OUStringBuffer; 40 using namespace store; 41 42 namespace { static char const VALUE_PREFIX[] = "$VL_"; } 43 44 //********************************************************************* 45 // ORegKey() 46 // 47 ORegKey::ORegKey(const OUString& keyName, ORegistry* pReg) 48 : m_refCount(1) 49 , m_name(keyName) 50 , m_bDeleted(0) 51 , m_bModified(0) 52 , m_pRegistry(pReg) 53 { 54 } 55 56 //********************************************************************* 57 // ~ORegKey() 58 // 59 ORegKey::~ORegKey() 60 { 61 OSL_POSTCOND(m_refCount == 0, "registry::ORegKey::dtor(): refcount not zero."); 62 } 63 64 //********************************************************************* 65 // acquireKey 66 // 67 RegError ORegKey::acquireKey(RegKeyHandle hKey) 68 { 69 return m_pRegistry->acquireKey(hKey); 70 } 71 72 //********************************************************************* 73 // releaseKey 74 // 75 RegError ORegKey::releaseKey(RegKeyHandle hKey) 76 { 77 return m_pRegistry->releaseKey(hKey); 78 } 79 80 //********************************************************************* 81 // createKey 82 // 83 RegError ORegKey::createKey(const OUString& keyName, RegKeyHandle* phNewKey) 84 { 85 return m_pRegistry->createKey(this, keyName, phNewKey); 86 } 87 88 89 //********************************************************************* 90 // openKey 91 // 92 RegError ORegKey::openKey(const OUString& keyName, RegKeyHandle* phOpenKey) 93 { 94 return m_pRegistry->openKey(this, keyName, phOpenKey); 95 } 96 97 98 //********************************************************************* 99 // openSubKeys 100 // 101 RegError ORegKey::openSubKeys(const OUString& keyName, RegKeyHandle** phOpenSubKeys, sal_uInt32* pnSubKeys) 102 { 103 RegError _ret = REG_NO_ERROR; 104 105 *phOpenSubKeys = 0; 106 *pnSubKeys = 0; 107 108 ORegKey* pKey = this; 109 if ( keyName.getLength() ) 110 { 111 _ret = openKey(keyName, (RegKeyHandle*)&pKey); 112 if (_ret != REG_NO_ERROR) 113 return _ret; 114 } 115 116 sal_uInt32 nSubKeys = pKey->countSubKeys(); 117 *pnSubKeys = nSubKeys; 118 119 ORegKey** pSubKeys; 120 pSubKeys = (ORegKey**)rtl_allocateZeroMemory(nSubKeys * sizeof(ORegKey*)); 121 122 OStoreDirectory::iterator iter; 123 OStoreDirectory rStoreDir(pKey->getStoreDir()); 124 storeError _err = rStoreDir.first(iter); 125 126 nSubKeys = 0; 127 while ( _err == store_E_None ) 128 { 129 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) 130 { 131 OUString const sSubKeyName = iter.m_pszName; 132 133 ORegKey* pOpenSubKey = 0; 134 _ret = pKey->openKey(sSubKeyName, (RegKeyHandle*)&pOpenSubKey); 135 if (_ret != REG_NO_ERROR) 136 { 137 *phOpenSubKeys = NULL; 138 *pnSubKeys = 0; 139 rtl_freeMemory(pSubKeys); // @@@ leaking 'pSubKeys[0...nSubkeys-1]' 140 return _ret; // @@@ leaking 'pKey' 141 } 142 143 pSubKeys[nSubKeys] = pOpenSubKey; 144 145 nSubKeys++; 146 } 147 148 _err = rStoreDir.next(iter); 149 } 150 151 *phOpenSubKeys = (RegKeyHandle*)pSubKeys; 152 if (keyName.getLength()) 153 { 154 (void) releaseKey(pKey); 155 } 156 return REG_NO_ERROR; 157 } 158 159 160 //********************************************************************* 161 // getKeyNames 162 // 163 RegError ORegKey::getKeyNames(const OUString& keyName, 164 rtl_uString*** pSubKeyNames, 165 sal_uInt32* pnSubKeys) 166 { 167 RegError _ret = REG_NO_ERROR; 168 169 *pSubKeyNames = 0; 170 *pnSubKeys = 0; 171 172 ORegKey* pKey = this; 173 if (keyName.getLength()) 174 { 175 _ret = openKey(keyName, (RegKeyHandle*)&pKey); 176 if (_ret != REG_NO_ERROR) 177 return _ret; 178 } 179 180 sal_uInt32 nSubKeys = pKey->countSubKeys(); 181 *pnSubKeys = nSubKeys; 182 183 rtl_uString** pSubKeys = 0; 184 pSubKeys = (rtl_uString**)rtl_allocateZeroMemory(nSubKeys * sizeof(rtl_uString*)); 185 186 OStoreDirectory::iterator iter; 187 OStoreDirectory rStoreDir(pKey->getStoreDir()); 188 storeError _err = rStoreDir.first(iter); 189 190 nSubKeys = 0; 191 192 while ( _err == store_E_None ) 193 { 194 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR) 195 { 196 OUString const sSubKeyName = iter.m_pszName; 197 198 OUString sFullKeyName(pKey->getName()); 199 if (sFullKeyName.getLength() > 1) 200 sFullKeyName += m_pRegistry->ROOT; 201 sFullKeyName += sSubKeyName; 202 203 rtl_uString_newFromString(&pSubKeys[nSubKeys], sFullKeyName.pData); 204 205 nSubKeys++; 206 } 207 208 _err = rStoreDir.next(iter); 209 } 210 211 *pSubKeyNames = pSubKeys; 212 if (keyName.getLength()) 213 { 214 releaseKey(pKey); 215 } 216 return REG_NO_ERROR; 217 } 218 219 220 //********************************************************************* 221 // closeKey 222 // 223 RegError ORegKey::closeKey(RegKeyHandle hKey) 224 { 225 return (m_pRegistry->closeKey(hKey)); 226 } 227 228 229 //********************************************************************* 230 // deleteKey 231 // 232 RegError ORegKey::deleteKey(const OUString& keyName) 233 { 234 return (m_pRegistry->deleteKey(this, keyName)); 235 } 236 237 238 //********************************************************************* 239 // getValueType 240 // 241 RegError ORegKey::getValueInfo(const OUString& valueName, RegValueType* pValueType, sal_uInt32* pValueSize) const 242 { 243 OStoreStream rValue; 244 sal_uInt8* pBuffer; 245 storeAccessMode accessMode = VALUE_MODE_OPEN; 246 247 if (m_pRegistry->isReadOnly()) 248 { 249 accessMode = VALUE_MODE_OPENREAD; 250 } 251 252 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 253 sImplValueName += valueName; 254 255 REG_GUARD(m_pRegistry->m_mutex); 256 257 if ( rValue.create(m_pRegistry->getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) 258 { 259 *pValueType = RG_VALUETYPE_NOT_DEFINED; 260 *pValueSize = 0; 261 return REG_VALUE_NOT_EXISTS; 262 } 263 264 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); 265 266 sal_uInt32 readBytes; 267 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) 268 { 269 rtl_freeMemory(pBuffer); 270 return REG_INVALID_VALUE; 271 } 272 if (readBytes != VALUE_HEADERSIZE) 273 { 274 rtl_freeMemory(pBuffer); 275 return REG_INVALID_VALUE; 276 } 277 278 sal_uInt32 size; 279 sal_uInt8 type = *((sal_uInt8*)pBuffer); 280 readUINT32(pBuffer+VALUE_TYPEOFFSET, size); 281 282 *pValueType = (RegValueType)type; 283 // if (*pValueType == RG_VALUETYPE_UNICODE) 284 // { 285 // *pValueSize = (size / 2) * sizeof(sal_Unicode); 286 // } else 287 // { 288 if (*pValueType > 4) 289 { 290 rtl_freeMemory(pBuffer); 291 pBuffer = (sal_uInt8*)rtl_allocateMemory(4); 292 rValue.readAt(VALUE_HEADEROFFSET, pBuffer, 4, readBytes); 293 294 readUINT32(pBuffer, size); 295 } 296 297 *pValueSize = size; 298 // } 299 300 rtl_freeMemory(pBuffer); 301 return REG_NO_ERROR; 302 } 303 304 305 //********************************************************************* 306 // setValue 307 // 308 RegError ORegKey::setValue(const OUString& valueName, RegValueType vType, RegValue value, sal_uInt32 vSize) 309 { 310 OStoreStream rValue; 311 sal_uInt8* pBuffer; 312 313 if (m_pRegistry->isReadOnly()) 314 { 315 return REG_REGISTRY_READONLY; 316 } 317 318 if (vType > 4) 319 { 320 return REG_INVALID_VALUE; 321 } 322 323 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 324 sImplValueName += valueName; 325 326 REG_GUARD(m_pRegistry->m_mutex); 327 328 if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT , sImplValueName, VALUE_MODE_CREATE) ) 329 { 330 return REG_SET_VALUE_FAILED; 331 } 332 333 sal_uInt32 size = vSize; 334 335 sal_uInt8 type = (sal_uInt8)vType; 336 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); 337 rtl_copyMemory(pBuffer, &type, 1); 338 339 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); 340 341 switch (vType) 342 { 343 case RG_VALUETYPE_NOT_DEFINED: 344 rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, value, size); 345 break; 346 case RG_VALUETYPE_LONG: 347 writeINT32(pBuffer+VALUE_HEADEROFFSET, *((sal_Int32*)value)); 348 break; 349 case RG_VALUETYPE_STRING: 350 writeUtf8(pBuffer+VALUE_HEADEROFFSET, (const sal_Char*)value); 351 break; 352 case RG_VALUETYPE_UNICODE: 353 writeString(pBuffer+VALUE_HEADEROFFSET, (const sal_Unicode*)value); 354 break; 355 case RG_VALUETYPE_BINARY: 356 rtl_copyMemory(pBuffer+VALUE_HEADEROFFSET, value, size); 357 break; 358 default: 359 OSL_ASSERT(false); 360 break; 361 } 362 363 sal_uInt32 writenBytes; 364 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) 365 { 366 rtl_freeMemory(pBuffer); 367 return REG_SET_VALUE_FAILED; 368 } 369 if (writenBytes != (VALUE_HEADERSIZE+size)) 370 { 371 rtl_freeMemory(pBuffer); 372 return REG_SET_VALUE_FAILED; 373 } 374 setModified(); 375 376 rtl_freeMemory(pBuffer); 377 return REG_NO_ERROR; 378 } 379 380 //********************************************************************* 381 // setLongListValue 382 // 383 RegError ORegKey::setLongListValue(const OUString& valueName, sal_Int32* pValueList, sal_uInt32 len) 384 { 385 OStoreStream rValue; 386 sal_uInt8* pBuffer; 387 388 if (m_pRegistry->isReadOnly()) 389 { 390 return REG_REGISTRY_READONLY; 391 } 392 393 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 394 sImplValueName += valueName; 395 396 REG_GUARD(m_pRegistry->m_mutex); 397 398 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) 399 { 400 return REG_SET_VALUE_FAILED; 401 } 402 403 sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge 404 405 size += len * 4; 406 407 sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_LONGLIST; 408 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); 409 rtl_copyMemory(pBuffer, &type, 1); 410 411 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); 412 writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); 413 414 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays 415 416 for (sal_uInt32 i=0; i < len; i++) 417 { 418 writeINT32(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); 419 offset += 4; 420 } 421 422 sal_uInt32 writenBytes; 423 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) 424 { 425 rtl_freeMemory(pBuffer); 426 return REG_SET_VALUE_FAILED; 427 } 428 if (writenBytes != (VALUE_HEADEROFFSET+size)) 429 { 430 rtl_freeMemory(pBuffer); 431 return REG_SET_VALUE_FAILED; 432 } 433 setModified(); 434 435 rtl_freeMemory(pBuffer); 436 return REG_NO_ERROR; 437 } 438 439 //********************************************************************* 440 // setStringListValue 441 // 442 RegError ORegKey::setStringListValue(const OUString& valueName, sal_Char** pValueList, sal_uInt32 len) 443 { 444 OStoreStream rValue; 445 sal_uInt8* pBuffer; 446 447 if (m_pRegistry->isReadOnly()) 448 { 449 return REG_REGISTRY_READONLY; 450 } 451 452 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 453 sImplValueName += valueName; 454 455 REG_GUARD(m_pRegistry->m_mutex); 456 457 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) 458 { 459 return REG_SET_VALUE_FAILED; 460 } 461 462 sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge 463 464 sal_uInt32 i; 465 for (i=0; i < len; i++) 466 { 467 size += 4 + strlen(pValueList[i]) + 1; 468 } 469 470 sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_STRINGLIST; 471 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); 472 rtl_copyMemory(pBuffer, &type, 1); 473 474 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); 475 writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); 476 477 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; 478 sal_uInt32 sLen = 0; 479 480 for (i=0; i < len; i++) 481 { 482 sLen = strlen(pValueList[i]) + 1; 483 writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen); 484 485 offset += 4; 486 writeUtf8(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); 487 offset += sLen; 488 } 489 490 sal_uInt32 writenBytes; 491 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) 492 { 493 rtl_freeMemory(pBuffer); 494 return REG_SET_VALUE_FAILED; 495 } 496 if (writenBytes != (VALUE_HEADERSIZE+size)) 497 { 498 rtl_freeMemory(pBuffer); 499 return REG_SET_VALUE_FAILED; 500 } 501 setModified(); 502 503 rtl_freeMemory(pBuffer); 504 return REG_NO_ERROR; 505 } 506 507 //********************************************************************* 508 // setUnicodeListValue 509 // 510 RegError ORegKey::setUnicodeListValue(const OUString& valueName, sal_Unicode** pValueList, sal_uInt32 len) 511 { 512 OStoreStream rValue; 513 sal_uInt8* pBuffer; 514 515 if (m_pRegistry->isReadOnly()) 516 { 517 return REG_REGISTRY_READONLY; 518 } 519 520 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 521 sImplValueName += valueName; 522 523 REG_GUARD(m_pRegistry->m_mutex); 524 525 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, VALUE_MODE_CREATE) ) 526 { 527 return REG_SET_VALUE_FAILED; 528 } 529 530 sal_uInt32 size = 4; // 4 Bytes (sal_uInt32) fuer die Laenge 531 532 sal_uInt32 i; 533 for (i=0; i < len; i++) 534 { 535 size += 4 + ((rtl_ustr_getLength(pValueList[i]) +1) * 2); 536 } 537 538 sal_uInt8 type = (sal_uInt8)RG_VALUETYPE_UNICODELIST; 539 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE + size); 540 rtl_copyMemory(pBuffer, &type, 1); 541 542 writeUINT32(pBuffer+VALUE_TYPEOFFSET, size); 543 writeUINT32(pBuffer+VALUE_HEADEROFFSET, len); 544 545 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; 546 sal_uInt32 sLen = 0; 547 548 for (i=0; i < len; i++) 549 { 550 sLen = (rtl_ustr_getLength(pValueList[i]) + 1) * 2; 551 writeUINT32(pBuffer+VALUE_HEADEROFFSET+offset, sLen); 552 553 offset += 4; 554 writeString(pBuffer+VALUE_HEADEROFFSET+offset, pValueList[i]); 555 offset += sLen; 556 } 557 558 sal_uInt32 writenBytes; 559 if ( rValue.writeAt(0, pBuffer, VALUE_HEADERSIZE+size, writenBytes) ) 560 { 561 rtl_freeMemory(pBuffer); 562 return REG_SET_VALUE_FAILED; 563 } 564 if (writenBytes != (VALUE_HEADERSIZE+size)) 565 { 566 rtl_freeMemory(pBuffer); 567 return REG_SET_VALUE_FAILED; 568 } 569 setModified(); 570 571 rtl_freeMemory(pBuffer); 572 return REG_NO_ERROR; 573 } 574 575 //********************************************************************* 576 // getValue 577 // 578 RegError ORegKey::getValue(const OUString& valueName, RegValue value) const 579 { 580 OStoreStream rValue; 581 sal_uInt8* pBuffer; 582 RegValueType valueType; 583 sal_uInt32 valueSize; 584 storeAccessMode accessMode = VALUE_MODE_OPEN; 585 586 if (m_pRegistry->isReadOnly()) 587 { 588 accessMode = VALUE_MODE_OPENREAD; 589 } 590 591 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 592 sImplValueName += valueName; 593 594 REG_GUARD(m_pRegistry->m_mutex); 595 596 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) 597 { 598 return REG_VALUE_NOT_EXISTS; 599 } 600 601 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); 602 603 sal_uInt32 readBytes; 604 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) 605 { 606 rtl_freeMemory(pBuffer); 607 return REG_INVALID_VALUE; 608 } 609 if (readBytes != VALUE_HEADERSIZE) 610 { 611 rtl_freeMemory(pBuffer); 612 return REG_INVALID_VALUE; 613 } 614 615 sal_uInt8 type = *((sal_uInt8*)pBuffer); 616 valueType = (RegValueType)type; 617 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); 618 619 rtl_freeMemory(pBuffer); 620 621 if (valueType > 4) 622 { 623 return REG_INVALID_VALUE; 624 } 625 626 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); 627 628 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) 629 { 630 rtl_freeMemory(pBuffer); 631 return REG_INVALID_VALUE; 632 } 633 if (readBytes != valueSize) 634 { 635 rtl_freeMemory(pBuffer); 636 return REG_INVALID_VALUE; 637 } 638 639 switch (valueType) 640 { 641 case RG_VALUETYPE_NOT_DEFINED: 642 rtl_copyMemory(value, pBuffer, valueSize); 643 break; 644 case RG_VALUETYPE_LONG: 645 readINT32(pBuffer, *((sal_Int32*)value)); 646 break; 647 case RG_VALUETYPE_STRING: 648 readUtf8(pBuffer, (sal_Char*)value, valueSize); 649 break; 650 case RG_VALUETYPE_UNICODE: 651 readString(pBuffer, (sal_Unicode*)value, valueSize); 652 break; 653 case RG_VALUETYPE_BINARY: 654 rtl_copyMemory(value, pBuffer, valueSize); 655 break; 656 case RG_VALUETYPE_LONGLIST: 657 case RG_VALUETYPE_STRINGLIST: 658 case RG_VALUETYPE_UNICODELIST: 659 rtl_copyMemory(value, pBuffer, valueSize); 660 break; 661 } 662 663 664 rtl_freeMemory(pBuffer); 665 return REG_NO_ERROR; 666 } 667 668 //********************************************************************* 669 // getLongListValue 670 // 671 RegError ORegKey::getLongListValue(const OUString& valueName, sal_Int32** pValueList, sal_uInt32* pLen) const 672 { 673 OStoreStream rValue; 674 sal_uInt8* pBuffer; 675 RegValueType valueType; 676 sal_uInt32 valueSize; 677 storeAccessMode accessMode = VALUE_MODE_OPEN; 678 679 if (m_pRegistry->isReadOnly()) 680 { 681 accessMode = VALUE_MODE_OPENREAD; 682 } 683 684 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 685 sImplValueName += valueName; 686 687 REG_GUARD(m_pRegistry->m_mutex); 688 689 if (rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) 690 { 691 pValueList = NULL; 692 *pLen = 0; 693 return REG_VALUE_NOT_EXISTS; 694 } 695 696 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); 697 698 sal_uInt32 readBytes; 699 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) 700 { 701 pValueList = NULL; 702 *pLen = 0; 703 rtl_freeMemory(pBuffer); 704 return REG_INVALID_VALUE; 705 } 706 if (readBytes != VALUE_HEADERSIZE) 707 { 708 pValueList = NULL; 709 *pLen = 0; 710 rtl_freeMemory(pBuffer); 711 return REG_INVALID_VALUE; 712 } 713 714 sal_uInt8 type = *((sal_uInt8*)pBuffer); 715 valueType = (RegValueType)type; 716 717 if (valueType != RG_VALUETYPE_LONGLIST) 718 { 719 pValueList = NULL; 720 *pLen = 0; 721 rtl_freeMemory(pBuffer); 722 return REG_INVALID_VALUE; 723 } 724 725 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); 726 727 rtl_freeMemory(pBuffer); 728 729 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); 730 731 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) 732 { 733 pValueList = NULL; 734 *pLen = 0; 735 rtl_freeMemory(pBuffer); 736 return REG_INVALID_VALUE; 737 } 738 if (readBytes != valueSize) 739 { 740 pValueList = NULL; 741 *pLen = 0; 742 rtl_freeMemory(pBuffer); 743 return REG_INVALID_VALUE; 744 } 745 746 sal_uInt32 len = 0; 747 readUINT32(pBuffer, len); 748 749 *pLen = len; 750 sal_Int32* pVList = (sal_Int32*)rtl_allocateZeroMemory(len * sizeof(sal_Int32)); 751 752 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; 753 754 for (sal_uInt32 i=0; i < len; i++) 755 { 756 readINT32(pBuffer+offset, pVList[i]); 757 offset += 4; 758 } 759 760 *pValueList = pVList; 761 rtl_freeMemory(pBuffer); 762 return REG_NO_ERROR; 763 } 764 765 //********************************************************************* 766 // getStringListValue 767 // 768 RegError ORegKey::getStringListValue(const OUString& valueName, sal_Char*** pValueList, sal_uInt32* pLen) const 769 { 770 OStoreStream rValue; 771 sal_uInt8* pBuffer; 772 RegValueType valueType; 773 sal_uInt32 valueSize; 774 storeAccessMode accessMode = VALUE_MODE_OPEN; 775 776 if (m_pRegistry->isReadOnly()) 777 { 778 accessMode = VALUE_MODE_OPENREAD; 779 } 780 781 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 782 sImplValueName += valueName; 783 784 REG_GUARD(m_pRegistry->m_mutex); 785 786 if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) 787 { 788 pValueList = NULL; 789 *pLen = 0; 790 return REG_VALUE_NOT_EXISTS; 791 } 792 793 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); 794 795 sal_uInt32 readBytes; 796 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) 797 { 798 pValueList = NULL; 799 *pLen = 0; 800 rtl_freeMemory(pBuffer); 801 return REG_INVALID_VALUE; 802 } 803 if (readBytes != VALUE_HEADERSIZE) 804 { 805 pValueList = NULL; 806 *pLen = 0; 807 rtl_freeMemory(pBuffer); 808 return REG_INVALID_VALUE; 809 } 810 811 sal_uInt8 type = *((sal_uInt8*)pBuffer); 812 valueType = (RegValueType)type; 813 814 if (valueType != RG_VALUETYPE_STRINGLIST) 815 { 816 pValueList = NULL; 817 *pLen = 0; 818 rtl_freeMemory(pBuffer); 819 return REG_INVALID_VALUE; 820 } 821 822 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); 823 824 rtl_freeMemory(pBuffer); 825 826 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); 827 828 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) 829 { 830 pValueList = NULL; 831 *pLen = 0; 832 rtl_freeMemory(pBuffer); 833 return REG_INVALID_VALUE; 834 } 835 if (readBytes != valueSize) 836 { 837 pValueList = NULL; 838 *pLen = 0; 839 rtl_freeMemory(pBuffer); 840 return REG_INVALID_VALUE; 841 } 842 843 sal_uInt32 len = 0; 844 readUINT32(pBuffer, len); 845 846 *pLen = len; 847 sal_Char** pVList = (sal_Char**)rtl_allocateZeroMemory(len * sizeof(sal_Char*)); 848 849 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; 850 sal_uInt32 sLen = 0; 851 852 sal_Char *pValue; 853 for (sal_uInt32 i=0; i < len; i++) 854 { 855 readUINT32(pBuffer+offset, sLen); 856 857 offset += 4; 858 859 pValue = (sal_Char*)rtl_allocateMemory(sLen); 860 readUtf8(pBuffer+offset, pValue, sLen); 861 pVList[i] = pValue; 862 863 offset += sLen; 864 } 865 866 *pValueList = pVList; 867 rtl_freeMemory(pBuffer); 868 return REG_NO_ERROR; 869 } 870 871 //********************************************************************* 872 // getUnicodeListValue 873 // 874 RegError ORegKey::getUnicodeListValue(const OUString& valueName, sal_Unicode*** pValueList, sal_uInt32* pLen) const 875 { 876 OStoreStream rValue; 877 sal_uInt8* pBuffer; 878 RegValueType valueType; 879 sal_uInt32 valueSize; 880 storeAccessMode accessMode = VALUE_MODE_OPEN; 881 882 if (m_pRegistry->isReadOnly()) 883 { 884 accessMode = VALUE_MODE_OPENREAD; 885 } 886 887 OUString sImplValueName( RTL_CONSTASCII_USTRINGPARAM(VALUE_PREFIX) ); 888 sImplValueName += valueName; 889 890 REG_GUARD(m_pRegistry->m_mutex); 891 892 if ( rValue.create(getStoreFile(), m_name + m_pRegistry->ROOT, sImplValueName, accessMode) ) 893 { 894 pValueList = NULL; 895 *pLen = 0; 896 return REG_VALUE_NOT_EXISTS; 897 } 898 899 pBuffer = (sal_uInt8*)rtl_allocateMemory(VALUE_HEADERSIZE); 900 901 sal_uInt32 readBytes; 902 if ( rValue.readAt(0, pBuffer, VALUE_HEADERSIZE, readBytes) ) 903 { 904 pValueList = NULL; 905 *pLen = 0; 906 rtl_freeMemory(pBuffer); 907 return REG_INVALID_VALUE; 908 } 909 if (readBytes != VALUE_HEADERSIZE) 910 { 911 pValueList = NULL; 912 *pLen = 0; 913 rtl_freeMemory(pBuffer); 914 return REG_INVALID_VALUE; 915 } 916 917 sal_uInt8 type = *((sal_uInt8*)pBuffer); 918 valueType = (RegValueType)type; 919 920 if (valueType != RG_VALUETYPE_UNICODELIST) 921 { 922 pValueList = NULL; 923 *pLen = 0; 924 rtl_freeMemory(pBuffer); 925 return REG_INVALID_VALUE; 926 } 927 928 readUINT32(pBuffer+VALUE_TYPEOFFSET, valueSize); 929 930 rtl_freeMemory(pBuffer); 931 932 pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); 933 934 if ( rValue.readAt(VALUE_HEADEROFFSET, pBuffer, valueSize, readBytes) ) 935 { 936 pValueList = NULL; 937 *pLen = 0; 938 rtl_freeMemory(pBuffer); 939 return REG_INVALID_VALUE; 940 } 941 if (readBytes != valueSize) 942 { 943 pValueList = NULL; 944 *pLen = 0; 945 rtl_freeMemory(pBuffer); 946 return REG_INVALID_VALUE; 947 } 948 949 sal_uInt32 len = 0; 950 readUINT32(pBuffer, len); 951 952 *pLen = len; 953 sal_Unicode** pVList = (sal_Unicode**)rtl_allocateZeroMemory(len * sizeof(sal_Unicode*)); 954 955 sal_uInt32 offset = 4; // initial 4 Bytes fuer die Laenge des Arrays; 956 sal_uInt32 sLen = 0; 957 958 sal_Unicode *pValue; 959 for (sal_uInt32 i=0; i < len; i++) 960 { 961 readUINT32(pBuffer+offset, sLen); 962 963 offset += 4; 964 965 pValue = (sal_Unicode*)rtl_allocateMemory((sLen / 2) * sizeof(sal_Unicode)); 966 readString(pBuffer+offset, pValue, sLen); 967 pVList[i] = pValue; 968 969 offset += sLen; 970 } 971 972 *pValueList = pVList; 973 rtl_freeMemory(pBuffer); 974 return REG_NO_ERROR; 975 } 976 977 //********************************************************************* 978 // getKeyType() 979 // 980 RegError ORegKey::getKeyType(const OUString& name, RegKeyType* pKeyType) const 981 { 982 *pKeyType = RG_KEYTYPE; 983 984 REG_GUARD(m_pRegistry->m_mutex); 985 986 if ( name.getLength() ) 987 { 988 ORegKey* pThis = const_cast< ORegKey* >(this); 989 990 RegKeyHandle hKey = 0; 991 RegError _ret = pThis->openKey(name, &hKey); 992 if (_ret != REG_NO_ERROR) 993 return _ret; 994 (void) pThis->releaseKey(hKey); 995 } 996 997 return REG_NO_ERROR; 998 } 999 1000 RegError ORegKey::getResolvedKeyName(const OUString& keyName, 1001 OUString& resolvedName) 1002 { 1003 if (keyName.getLength() == 0) 1004 return REG_INVALID_KEYNAME; 1005 1006 resolvedName = getFullPath(keyName); 1007 return REG_NO_ERROR; 1008 } 1009 1010 //********************************************************************* 1011 // countSubKeys() 1012 // 1013 sal_uInt32 ORegKey::countSubKeys() 1014 { 1015 REG_GUARD(m_pRegistry->m_mutex); 1016 1017 OStoreDirectory::iterator iter; 1018 OStoreDirectory rStoreDir = getStoreDir(); 1019 storeError _err = rStoreDir.first(iter); 1020 sal_uInt32 count = 0; 1021 1022 while ( _err == store_E_None ) 1023 { 1024 if ( iter.m_nAttrib & STORE_ATTRIB_ISDIR ) 1025 { 1026 count++; 1027 } 1028 1029 _err = rStoreDir.next(iter); 1030 } 1031 1032 return count; 1033 } 1034 1035 OStoreDirectory ORegKey::getStoreDir() 1036 { 1037 OStoreDirectory rStoreDir; 1038 OUString fullPath; 1039 OUString relativName; 1040 storeAccessMode accessMode = KEY_MODE_OPEN; 1041 1042 if ( m_name.equals(m_pRegistry->ROOT) ) 1043 { 1044 fullPath = OUString(); 1045 relativName = OUString(); 1046 } else 1047 { 1048 fullPath = m_name.copy(0, m_name.lastIndexOf('/') + 1); 1049 relativName = m_name.copy(m_name.lastIndexOf('/') + 1); 1050 } 1051 1052 if (m_pRegistry->isReadOnly()) 1053 { 1054 accessMode = KEY_MODE_OPENREAD; 1055 } 1056 1057 rStoreDir.create(getStoreFile(), fullPath, relativName, accessMode); 1058 1059 return rStoreDir; 1060 } 1061 1062 OUString ORegKey::getFullPath(OUString const & path) const { 1063 OSL_ASSERT(m_name.getLength() != 0 && path.getLength() != 0); 1064 OUStringBuffer b(m_name); 1065 if (b.charAt(b.getLength() - 1) == '/') { 1066 if (path[0] == '/') { 1067 b.append(path.getStr() + 1, path.getLength() - 1); 1068 } else { 1069 b.append(path); 1070 } 1071 } else { 1072 if (path[0] != '/') { 1073 b.append(sal_Unicode('/')); 1074 } 1075 b.append(path); 1076 } 1077 return b.makeStringAndClear(); 1078 } 1079