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