xref: /AOO41X/main/registry/source/keyimpl.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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