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