xref: /trunk/main/registry/source/keyimpl.cxx (revision 51134e9e)
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