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