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 #pragma once
21 
22 #include <registry/regdllapi.h>
23 #include <registry/regtype.h>
24 #include <rtl/ustring.hxx>
25 
26 extern "C" {
27 
28 /** specifies a collection of function pointers which represents the complete registry C-API.
29 
30     These function pointers are used by the C++ wrapper to call the C-API.
31 */
32 struct Registry_Api
33 {
34     void        (REGISTRY_CALLTYPE *acquire)            (RegHandle);
35     void        (REGISTRY_CALLTYPE *release)            (RegHandle);
36     sal_Bool    (REGISTRY_CALLTYPE *isReadOnly)         (RegHandle);
37     RegError    (REGISTRY_CALLTYPE *openRootKey)        (RegHandle, RegKeyHandle*);
38     RegError    (REGISTRY_CALLTYPE *getName)            (RegHandle, rtl_uString**);
39     RegError    (REGISTRY_CALLTYPE *createRegistry)     (rtl_uString*, RegHandle*);
40     RegError    (REGISTRY_CALLTYPE *openRegistry)       (rtl_uString*, RegHandle*, RegAccessMode);
41     RegError    (REGISTRY_CALLTYPE *closeRegistry)      (RegHandle);
42     RegError    (REGISTRY_CALLTYPE *destroyRegistry)    (RegHandle, rtl_uString*);
43     RegError    (REGISTRY_CALLTYPE *mergeKey)           (RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*, sal_Bool, sal_Bool);
44     void        (REGISTRY_CALLTYPE *acquireKey)         (RegKeyHandle);
45     void        (REGISTRY_CALLTYPE *releaseKey)         (RegKeyHandle);
46     sal_Bool    (REGISTRY_CALLTYPE *isKeyReadOnly)      (RegKeyHandle);
47     RegError    (REGISTRY_CALLTYPE *getKeyName)         (RegKeyHandle, rtl_uString**);
48     RegError    (REGISTRY_CALLTYPE *createKey)          (RegKeyHandle, rtl_uString*, RegKeyHandle*);
49     RegError    (REGISTRY_CALLTYPE *openKey)            (RegKeyHandle, rtl_uString*, RegKeyHandle*);
50     RegError    (REGISTRY_CALLTYPE *openSubKeys)        (RegKeyHandle, rtl_uString*, RegKeyHandle**, sal_uInt32*);
51     RegError    (REGISTRY_CALLTYPE *closeSubKeys)       (RegKeyHandle*, sal_uInt32);
52     RegError    (REGISTRY_CALLTYPE *deleteKey)          (RegKeyHandle, rtl_uString*);
53     RegError    (REGISTRY_CALLTYPE *closeKey)           (RegKeyHandle);
54     RegError    (REGISTRY_CALLTYPE *setValue)           (RegKeyHandle, rtl_uString*, RegValueType, RegValue, sal_uInt32);
55     RegError    (REGISTRY_CALLTYPE *setLongListValue)   (RegKeyHandle, rtl_uString*, sal_Int32 const *, sal_uInt32);
56     RegError    (REGISTRY_CALLTYPE *setStringListValue) (RegKeyHandle, rtl_uString*, char**, sal_uInt32);
57     RegError    (REGISTRY_CALLTYPE *setUnicodeListValue)(RegKeyHandle, rtl_uString*, sal_Unicode**, sal_uInt32);
58     RegError    (REGISTRY_CALLTYPE *getValueInfo)       (RegKeyHandle, rtl_uString*, RegValueType*, sal_uInt32*);
59     RegError    (REGISTRY_CALLTYPE *getValue)           (RegKeyHandle, rtl_uString*, RegValue);
60     RegError    (REGISTRY_CALLTYPE *getLongListValue)   (RegKeyHandle, rtl_uString*, sal_Int32**, sal_uInt32*);
61     RegError    (REGISTRY_CALLTYPE *getStringListValue) (RegKeyHandle, rtl_uString*, char***, sal_uInt32*);
62     RegError    (REGISTRY_CALLTYPE *getUnicodeListValue)(RegKeyHandle, rtl_uString*, sal_Unicode***, sal_uInt32*);
63     RegError    (REGISTRY_CALLTYPE *freeValueList)      (RegValueType, RegValue, sal_uInt32);
64     RegError    (REGISTRY_CALLTYPE *getResolvedKeyName) (RegKeyHandle, rtl_uString*, sal_Bool, rtl_uString**);
65     RegError    (REGISTRY_CALLTYPE *getKeyNames)        (RegKeyHandle, rtl_uString*, rtl_uString***, sal_uInt32*);
66     RegError    (REGISTRY_CALLTYPE *freeKeyNames)       (rtl_uString**, sal_uInt32);
67 };
68 
69 /** the API initialization function.
70 */
71 REG_DLLPUBLIC Registry_Api* REGISTRY_CALLTYPE initRegistry_Api();
72 
73 }
74 
75 class RegistryKey;
76 
77 
78 /** The Registry provides the functionality to read and write information in a registry file.
79 
80     The class is implemented inline and use a C-Api.
81 */
82 class Registry final
83 {
84 public:
85     /** Default constructor.
86      */
87     inline Registry();
88 
89     /// Copy constructor
90     inline Registry(const Registry& toCopy);
91 
Registry(Registry && other)92     Registry(Registry && other) noexcept : m_pApi(other.m_pApi), m_hImpl(other.m_hImpl)
93     { other.m_hImpl = nullptr; }
94 
95     /// Destructor. The Destructor close the registry if it is open.
96     inline ~Registry();
97 
98     /// Assign operator
99     inline Registry& operator = (const Registry& toAssign);
100 
operator =(Registry && other)101     Registry & operator =(Registry && other) {
102         if (m_hImpl != nullptr) {
103             m_pApi->release(m_hImpl);
104         }
105         m_hImpl = other.m_hImpl;
106         other.m_hImpl = nullptr;
107         return *this;
108     }
109 
110     /// checks if the registry points to a valid registry data file.
111     inline bool isValid() const;
112 
113     /** returns the access mode of the registry.
114 
115         @return TRUE if the access mode is readonly else FALSE.
116     */
117     inline bool     isReadOnly() const;
118 
119     /** opens the root key of the registry.
120 
121         @param  rRootKey reference to a RegistryKey which is filled with the rootkey.
122         @return RegError::NO_ERROR if succeeds else an error code.
123     */
124     inline RegError openRootKey(RegistryKey& rRootKey);
125 
126     /// returns the name of the current registry data file.
127     inline OUString getName();
128 
129     /** creates a new registry with the specified name and creates a root key.
130 
131         @param  registryName specifies the name of the new registry.
132         @return RegError::NO_ERROR if succeeds else an error code.
133     */
134     inline RegError create(const OUString& registryName);
135 
136     /** opens a registry with the specified name.
137 
138         If the registry already points to a valid registry, the old registry will be closed.
139         @param  registryName specifies a registry name.
140         @param  accessMode specifies the access mode for the registry, RegAccessMode::READONLY or RegAccessMode::READWRITE.
141         @return RegError::NO_ERROR if succeeds else an error code.
142     */
143     inline RegError open(const OUString& registryName,
144                             RegAccessMode accessMode);
145 
146     /// closes explicitly the current registry data file.
147     inline RegError close();
148 
149     /** destroys a registry.
150 
151         @param registryName specifies a registry name, if the name is an empty string the registry
152                             itself will be destroyed.
153         @return RegError::NO_ERROR if succeeds else an error code.
154     */
155     inline RegError destroy(const OUString& registryName);
156 
157     /** merges the registry information of the specified key with the registry
158         information of the specified file.
159 
160         All existing keys will be extended and existing key values will be overwritten.
161         @param  rKey references a currently open key. The key which information is merged by this
162                      function is a subkey of this key
163         @param  keyName specifies the name of the key which will be merged.
164                         If keyName is an empty string the registry information under the key specified
165                         by rKey is merged with the information from the specified file.
166         @param  regFileName specifies the file containing the registry information.
167         @param  bReport if TRUE the function reports warnings on stdout if a key already exists.
168         @return RegError::NO_ERROR if succeeds else an error code. If it returns an error the registry will
169                 restore the state before merging.
170     */
171     inline RegError mergeKey(RegistryKey& rKey,
172                                 const OUString& keyName,
173                                 const OUString& regFileName,
174                                 bool bReport);
175 
176     friend class RegistryKey;
177     friend class RegistryKeyArray;
178     friend class RegistryKeyNames;
179 
180     /// returns the used registry Api.
getApi() const181     const Registry_Api* getApi() const { return m_pApi; }
182 
183 private:
184     /// stores the used and initialized registry Api.
185     const Registry_Api*                          m_pApi;
186     /// stores the handle of the underlying registry file on which most of the functions work.
187     RegHandle                                    m_hImpl;
188 };
189 
190 
191 /** RegistryKeyArray represents an array of open keys.
192 
193     RegistryKeyArray is a helper class to work with an array of keys.
194 */
195 class RegistryKeyArray
196 {
197 public:
198     /// Default constructor
199     inline RegistryKeyArray();
200 
201     /// Destructor, all subkeys will be closed.
202     inline ~RegistryKeyArray();
203 
204     /// returns the open key specified by index.
205     inline RegistryKey getElement(sal_uInt32 index);
206 
207     /// returns the length of the array.
208     inline sal_uInt32 getLength() const;
209 
210     friend class RegistryKey;
211 protected:
212     /** sets the data of the key array.
213 
214         @param registry specifies the registry files where the keys are located.
215         @param phKeys points to an array of open keys.
216         @param length specifies the length of the array specified by phKeys.
217      */
218     inline void setKeyHandles(Registry const & registry, RegKeyHandle* phKeys, sal_uInt32 length);
219 private:
220     /// stores the number of open subkeys, the number of elements.
221     sal_uInt32      m_length;
222     /// stores an array of open subkeys.
223     RegKeyHandle*   m_phKeys;
224     /// stores the handle to the registry file where the appropriate keys are located.
225     Registry        m_registry;
226 };
227 
228 
229 /** RegistryKeyNames represents an array of key names.
230 
231     RegistryKeyNames is a helper class to work with an array of key names.
232 */
233 class RegistryKeyNames
234 {
235 public:
236     /// Default constructor
237     inline RegistryKeyNames();
238 
239     /// Destructor, the internal array with key names will be deleted.
240     inline ~RegistryKeyNames();
241 
242     /// returns the name of the key specified by index.
243     inline OUString getElement(sal_uInt32 index);
244 
245     /// returns the length of the array.
246     inline sal_uInt32 getLength() const;
247 
248     friend class RegistryKey;
249 protected:
250     /** sets the data of the array.
251 
252         @param registry specifies the registry files where the keys are located.
253         @param pKeyNames points to an array of key names.
254         @param length specifies the length of the array specified by pKeyNames.
255      */
256     inline void setKeyNames(Registry const & registry, rtl_uString** pKeyNames, sal_uInt32 length);
257 private:
258     /// stores the number of key names, the number of elements.
259     sal_uInt32      m_length;
260     /// stores an array of key names.
261     rtl_uString**   m_pKeyNames;
262     /// stores the handle to the registry file where the appropriate keys are located.
263     Registry        m_registry;
264 };
265 
266 
267 /** RegistryValueList represents a value list of the specified type.
268 
269     RegistryValueList is a helper class to work with a list value.
270 */
271 template<class ValueType>
272 class RegistryValueList final
273 {
274 public:
275     /// Default constructor
RegistryValueList()276     RegistryValueList()
277         : m_length(0)
278         , m_pValueList(nullptr)
279         , m_valueType(RegValueType::NOT_DEFINED)
280         {}
281 
282     /// Destructor, the internal value list will be freed.
~RegistryValueList()283     ~RegistryValueList()
284     {
285         if (m_pValueList)
286         {
287             m_registry.getApi()->freeValueList(m_valueType, m_pValueList, m_length);
288         }
289     }
290 
291     /// returns the value of the list specified by index.
getElement(sal_uInt32 index)292     ValueType getElement(sal_uInt32 index)
293     {
294         if (m_registry.isValid() && index < m_length)
295         {
296             return m_pValueList[index];
297         } else
298         {
299             return 0;
300         }
301     }
302 
303     /// returns the length of the list.
getLength()304     sal_uInt32 getLength()
305     {
306         return m_length;
307     }
308 
309     friend class RegistryKey;
310 
311 private:
312     /** sets the data of the value list.
313 
314         @param registry specifies the registry files where the appropriate key is located.
315         @param valueType specifies the type of the list values.
316         @param pValueList points to a value list.
317         @param length specifies the length of the list.
318      */
setValueList(const Registry & registry,RegValueType valueType,ValueType * pValueList,sal_uInt32 length)319     void setValueList(const Registry& registry, RegValueType valueType,
320                       ValueType* pValueList, sal_uInt32 length)
321     {
322         m_length = length;
323         m_pValueList = pValueList;
324         m_valueType = valueType;
325         m_registry = registry;
326     }
327 
328     /// stores the length of the list, the number of elements.
329     sal_uInt32      m_length;
330     /// stores the value list.
331     ValueType*      m_pValueList;
332     /// stores the type of the list elements
333     RegValueType    m_valueType;
334     /** stores the handle to the registry file where the appropriate key to this
335         value is located.
336     */
337     Registry        m_registry;
338 };
339 
340 
341 /** RegistryKey reads or writes information of the underlying key in a registry.
342 
343     Class is inline and use a load on call C-Api.
344 */
345 class RegistryKey
346 {
347 public:
348     /// Default constructor
349     inline RegistryKey();
350 
351     /// Copy constructor
352     inline RegistryKey(const RegistryKey& toCopy);
353 
354     /// Destructor, close the key if it references an open one.
355     inline ~RegistryKey();
356 
357     /// Assign operator
358     inline RegistryKey& operator = (const RegistryKey& toAssign);
359 
360     /// checks if the key points to a valid registry key.
361     inline bool isValid() const;
362 
363     /** returns the access mode of the key.
364 
365         @return TRUE if access mode is read only else FALSE.
366     */
367     inline bool     isReadOnly() const;
368 
369     /// returns the full qualified name of the key beginning with the rootkey.
370     inline OUString getName();
371 
372     /** creates a new key or opens a key if the specified key already exists.
373 
374         The specified keyname is relative to this key.
375         @param  keyName specifies the name of the key which will be opened or created.
376         @param  rNewKey references a RegistryKey which will be filled with the new or open key.
377         @return RegError::NO_ERROR if succeeds else an error code.
378     */
379     inline RegError createKey(const OUString& keyName,
380                               RegistryKey& rNewKey);
381 
382     /** opens the specified key.
383 
384         The specified keyname is relative to this key.
385         @param  keyName specifies the name of the key which will be opened.
386         @param  rOpenKey references a RegistryKey which will be filled with the open key.
387         @return RegError::NO_ERROR if succeeds else an error code.
388     */
389     inline RegError openKey(const OUString& keyName,
390                               RegistryKey& rOpenKey);
391 
392     /** opens all subkeys of the specified key.
393 
394         The specified keyname is relative to this key.
395         @param  keyName specifies the name of the key which subkeys will be opened.
396         @param  rSubKeys reference a RegistryKeyArray which will be filled with the open subkeys.
397         @return RegError::NO_ERROR if succeeds else an error code.
398     */
399     inline RegError openSubKeys(const OUString& keyName,
400                                     RegistryKeyArray& rSubKeys);
401 
402     /** returns an array with the names of all subkeys of the specified key.
403 
404         The specified keyname is relative to this key.
405         @param  keyName specifies the name of the key which subkey names will be returned.
406         @param  rSubKeyNames reference a RegistryKeyNames array which will be filled with the subkey names.
407         @return RegError::NO_ERROR if succeeds else an error code.
408     */
409     inline RegError getKeyNames(const OUString& keyName,
410                                     RegistryKeyNames& rSubKeyNames);
411 
412     /** deletes the specified key.
413 
414         @param  keyName specifies the name of the key which will be deleted.
415         @return RegError::NO_ERROR if succeeds else an error code.
416     */
417     inline RegError deleteKey(const OUString& keyName);
418 
419     /// closes explicitly the current key
420     inline RegError closeKey();
421 
422     /// releases the current key
423     inline void releaseKey();
424 
425     /** sets a value of a key.
426 
427         @param  keyName specifies the name of the key which value will be set.
428                         If keyName is an empty string, the value will be set for the key
429                         specified by hKey.
430         @param  valueType specifies the type of the value.
431         @param  pValue points to a memory block containing the data for the value.
432         @param  valueSize specifies the size of pData in bytes
433         @return RegError::NO_ERROR if succeeds else an error code.
434     */
435     inline RegError setValue(const OUString& keyName,
436                                 RegValueType valueType,
437                                 RegValue pValue,
438                                 sal_uInt32 valueSize);
439 
440     /** sets a long list value of a key.
441 
442         @param  keyName specifies the name of the key which value will be set.
443                         If keyName is an empty string, the value will be set for the key
444                         specified by hKey.
445         @param  pValueList points to an array of longs containing the data for the value.
446         @param  len specifies the length of the list (the array referenced by pValueList).
447         @return RegError::NO_ERROR if succeeds else an error code.
448     */
449     inline RegError setLongListValue(const OUString& keyName,
450                                          sal_Int32 const * pValueList,
451                                          sal_uInt32 len);
452 
453     /** sets an ascii list value of a key.
454 
455         @param  keyName specifies the name of the key which value will be set.
456                         If keyName is an empty string, the value will be set for the key
457                         specified by hKey.
458         @param  pValueList points to an array of char* containing the data for the value.
459         @param  len specifies the length of the list (the array referenced by pValueList).
460         @return RegError::NO_ERROR if succeeds else an error code.
461     */
462     inline RegError setStringListValue(const OUString& keyName,
463                                            char** pValueList,
464                                            sal_uInt32 len);
465 
466     /** sets a unicode string list value of a key.
467 
468         @param  keyName specifies the name of the key which value will be set.
469                         If keyName is an empty string, the value will be set for the key
470                         specified by hKey.
471         @param  pValueList points to an array of sal_Unicode* containing the data for the value.
472         @param  len specifies the length of the list (the array referenced by pValueList).
473         @return RegError::NO_ERROR if succeeds else an error code.
474     */
475     inline RegError setUnicodeListValue(const OUString& keyName,
476                                             sal_Unicode** pValueList,
477                                               sal_uInt32 len);
478 
479     /** gets info about type and size of a value.
480 
481         @param  keyName specifies the name of the key which value info will be returned.
482                         If keyName is an empty string, the value info of the key
483                         specified by hKey will be returned.
484         @param  pValueType returns the type of the value.
485         @param  pValueSize returns the size of the value in bytes or the length of a list value.
486         @return RegError::NO_ERROR if succeeds else an error code.
487     */
488     inline RegError getValueInfo(const OUString& keyName,
489                                     RegValueType* pValueType,
490                                     sal_uInt32* pValueSize);
491 
492     /** gets the value of a key.
493 
494         @param  keyName specifies the name of the key which value will be returned.
495                         If keyName is an empty string, the value is get from the key
496                         specified by hKey.
497         @param  pValue points to an allocated memory block receiving the data of the value.
498         @return RegError::NO_ERROR if succeeds else an error code.
499     */
500     inline RegError getValue(const OUString& keyName,
501                                 RegValue pValue);
502 
503     /** gets a long list value of a key.
504 
505         @param  keyName specifies the name of the key which value will be returned.
506                         If keyName is an empty string, the value is get from the key
507                         specified by hKey.
508         @param  rValueList references a RegistryValueList which will be filled with the long values.
509         @return RegError::NO_ERROR if succeeds else an error code.
510     */
511     inline RegError getLongListValue(const OUString& keyName,
512                                           RegistryValueList<sal_Int32>& rValueList);
513 
514     /** gets an ascii list value of a key.
515 
516         @param  keyName specifies the name of the key which value will be returned.
517                         If keyName is an empty string, the value is get from the key
518                         specified by hKey.
519         @param  rValueList references a RegistryValueList which will be filled with the ascii values.
520         @return RegError::NO_ERROR if succeeds else an error code.
521     */
522     inline RegError getStringListValue(const OUString& keyName,
523                                            RegistryValueList<char*>& rValueList);
524 
525     /** gets a unicode value of a key.
526 
527         @param  keyName specifies the name of the key which value will be returned.
528                         If keyName is an empty string, the value is get from the key
529                         specified by hKey.
530         @param  rValueList reference a RegistryValueList which will be filled with the unicode values.
531         @return RegError::NO_ERROR if succeeds else an error code.
532     */
533     inline RegError getUnicodeListValue(const OUString& keyName,
534                                               RegistryValueList<sal_Unicode*>& rValueList);
535 
536     /** resolves a keyname.
537 
538         @param[in]  keyName specifies the name of the key which will be resolved relative to this key.
539                         The resolved name will be prefixed with the name of this key.
540         @param[out] rResolvedName the resolved name.
541         @return RegError::NO_ERROR if succeeds else an error code.
542      */
543     inline RegError getResolvedKeyName(const OUString& keyName,
544                                            OUString& rResolvedName) const;
545 
546     /// returns the name of the registry in which the key is defined.
547     inline OUString getRegistryName();
548 
549     friend class Registry;
550 public:
551     /// @cond INTERNAL
552 
553     /** Constructor, which initialize a RegistryKey with registry and a valid key handle.
554 
555         This constructor is internal only.
556     */
557     inline RegistryKey(Registry const & registry,
558                        RegKeyHandle hKey);
559 
560 protected:
561     /** sets the internal registry on which this key should work.
562      */
563     inline void setRegistry(Registry const & registry);
564 
565     /// @endcond
566 
567     /// stores the registry on which this key works
568     Registry        m_registry;
569     /// stores the current key handle of this key
570     RegKeyHandle    m_hImpl;
571 };
572 
573 
RegistryKeyArray()574 inline RegistryKeyArray::RegistryKeyArray()
575     : m_length(0)
576     , m_phKeys(nullptr)
577 {
578 }
579 
~RegistryKeyArray()580 inline RegistryKeyArray::~RegistryKeyArray()
581 {
582     if (m_phKeys)
583         m_registry.m_pApi->closeSubKeys(m_phKeys, m_length);
584 }
585 
getElement(sal_uInt32 index)586 inline RegistryKey RegistryKeyArray::getElement(sal_uInt32 index)
587 {
588     if (m_registry.isValid() && index < m_length)
589         return RegistryKey(m_registry, m_phKeys[index]);
590     else
591         return RegistryKey();
592 }
593 
getLength() const594 inline sal_uInt32 RegistryKeyArray::getLength() const
595 {
596     return m_length;
597 }
598 
setKeyHandles(Registry const & registry,RegKeyHandle * phKeys,sal_uInt32 length)599 inline void RegistryKeyArray::setKeyHandles(Registry const & registry,
600                                             RegKeyHandle* phKeys,
601                                             sal_uInt32 length)
602 {
603     m_phKeys = phKeys;
604     m_length = length;
605     m_registry = registry;
606 }
607 
RegistryKeyNames()608 inline RegistryKeyNames::RegistryKeyNames()
609     : m_length(0)
610     , m_pKeyNames(nullptr)
611 {
612 }
613 
~RegistryKeyNames()614 inline RegistryKeyNames::~RegistryKeyNames()
615 {
616     if (m_pKeyNames)
617         m_registry.m_pApi->freeKeyNames(m_pKeyNames, m_length);
618 }
619 
getElement(sal_uInt32 index)620 inline OUString RegistryKeyNames::getElement(sal_uInt32 index)
621 {
622 
623     if (m_pKeyNames && index < m_length)
624         return m_pKeyNames[index];
625     else
626         return OUString();
627 }
628 
getLength() const629 inline sal_uInt32 RegistryKeyNames::getLength() const
630 {
631     return m_length;
632 }
633 
setKeyNames(Registry const & registry,rtl_uString ** pKeyNames,sal_uInt32 length)634 inline void RegistryKeyNames::setKeyNames(Registry const & registry,
635                                           rtl_uString** pKeyNames,
636                                           sal_uInt32 length)
637 {
638     m_pKeyNames = pKeyNames;
639     m_length = length;
640     m_registry = registry;
641 }
642 
RegistryKey()643 inline RegistryKey::RegistryKey()
644     : m_hImpl(nullptr)
645     { }
646 
647 /// @cond INTERNAL
RegistryKey(Registry const & registry,RegKeyHandle hKey)648 inline RegistryKey::RegistryKey(Registry const & registry, RegKeyHandle hKey)
649     : m_registry(registry)
650     , m_hImpl(hKey)
651     {
652         if (m_hImpl)
653             m_registry.m_pApi->acquireKey(m_hImpl);
654     }
655 /// @endcond
656 
RegistryKey(const RegistryKey & toCopy)657 inline RegistryKey::RegistryKey(const RegistryKey& toCopy)
658     : m_registry(toCopy.m_registry)
659     , m_hImpl(toCopy.m_hImpl)
660     {
661         if (m_hImpl)
662             m_registry.m_pApi->acquireKey(m_hImpl);
663     }
664 
665 /// @cond INTERNAL
setRegistry(Registry const & registry)666 inline void RegistryKey::setRegistry(Registry const & registry)
667     {
668         m_registry = registry;
669     }
670 /// @endcond
671 
~RegistryKey()672 inline RegistryKey::~RegistryKey()
673     {
674         if (m_hImpl)
675             m_registry.m_pApi->releaseKey(m_hImpl);
676     }
677 
operator =(const RegistryKey & toAssign)678 inline RegistryKey& RegistryKey::operator = (const RegistryKey& toAssign)
679 {
680     m_registry = toAssign.m_registry;
681 
682     if (toAssign.m_hImpl)
683         m_registry.m_pApi->acquireKey(toAssign.m_hImpl);
684     if (m_hImpl)
685         m_registry.m_pApi->releaseKey(m_hImpl);
686     m_hImpl = toAssign.m_hImpl;
687 
688     return *this;
689 }
690 
isValid() const691 inline bool RegistryKey::isValid() const
692     {  return (m_hImpl != nullptr); }
693 
isReadOnly() const694 inline bool RegistryKey::isReadOnly() const
695     {
696         if  (m_registry.isValid())
697             return m_registry.m_pApi->isKeyReadOnly(m_hImpl);
698         else
699             return false;
700     }
701 
getName()702 inline OUString RegistryKey::getName()
703     {
704         OUString sRet;
705         if (m_registry.isValid())
706             m_registry.m_pApi->getKeyName(m_hImpl, &sRet.pData);
707         return sRet;
708     }
709 
createKey(const OUString & keyName,RegistryKey & rNewKey)710 inline RegError RegistryKey::createKey(const OUString& keyName,
711                                           RegistryKey& rNewKey)
712     {
713         if (rNewKey.isValid()) rNewKey.closeKey();
714         if (m_registry.isValid())
715         {
716             RegError ret = m_registry.m_pApi->createKey(m_hImpl, keyName.pData, &rNewKey.m_hImpl);
717             if (ret == RegError::NO_ERROR) rNewKey.setRegistry(m_registry);
718             return ret;
719         } else
720             return RegError::INVALID_KEY;
721     }
722 
openKey(const OUString & keyName,RegistryKey & rOpenKey)723 inline RegError RegistryKey::openKey(const OUString& keyName,
724                                      RegistryKey& rOpenKey)
725     {
726         if (rOpenKey.isValid()) rOpenKey.closeKey();
727         if (m_registry.isValid())
728         {
729             RegError ret = m_registry.m_pApi->openKey(m_hImpl, keyName.pData,
730                                                     &rOpenKey.m_hImpl);
731             if (ret == RegError::NO_ERROR) rOpenKey.setRegistry(m_registry);
732             return ret;
733         } else
734             return RegError::INVALID_KEY;
735     }
736 
openSubKeys(const OUString & keyName,RegistryKeyArray & rSubKeys)737 inline RegError RegistryKey::openSubKeys(const OUString& keyName,
738                                          RegistryKeyArray& rSubKeys)
739     {
740         if (m_registry.isValid())
741         {
742             RegError        ret = RegError::NO_ERROR;
743             RegKeyHandle*   pSubKeys;
744             sal_uInt32      nSubKeys;
745             ret = m_registry.m_pApi->openSubKeys(m_hImpl, keyName.pData,
746                                                       &pSubKeys, &nSubKeys);
747             if ( ret != RegError::NO_ERROR)
748             {
749                 return ret;
750             } else
751             {
752                 rSubKeys.setKeyHandles(m_registry, pSubKeys, nSubKeys);
753                 return ret;
754             }
755         } else
756             return RegError::INVALID_KEY;
757     }
758 
getKeyNames(const OUString & keyName,RegistryKeyNames & rSubKeyNames)759 inline RegError RegistryKey::getKeyNames(const OUString& keyName,
760                                              RegistryKeyNames& rSubKeyNames)
761     {
762         if (m_registry.isValid())
763         {
764             RegError        ret = RegError::NO_ERROR;
765             rtl_uString**   pSubKeyNames;
766             sal_uInt32      nSubKeys;
767             ret = m_registry.m_pApi->getKeyNames(m_hImpl, keyName.pData,
768                                                   &pSubKeyNames, &nSubKeys);
769             if ( ret != RegError::NO_ERROR)
770             {
771                 return ret;
772             } else
773             {
774                 rSubKeyNames.setKeyNames(m_registry, pSubKeyNames, nSubKeys);
775                 return ret;
776             }
777         } else
778             return RegError::INVALID_KEY;
779     }
780 
deleteKey(const OUString & keyName)781 inline RegError RegistryKey::deleteKey(const OUString& keyName)
782     {
783         if (m_registry.isValid())
784             return m_registry.m_pApi->deleteKey(m_hImpl, keyName.pData);
785         else
786             return RegError::INVALID_KEY;
787     }
788 
closeKey()789 inline RegError RegistryKey::closeKey()
790     {
791         if (m_registry.isValid())
792         {
793             RegError ret = m_registry.m_pApi->closeKey(m_hImpl);
794             if (ret == RegError::NO_ERROR)
795             {
796                 m_hImpl = nullptr;
797                 m_registry = Registry();
798             }
799             return ret;
800         } else
801             return RegError::INVALID_KEY;
802     }
803 
releaseKey()804 inline void RegistryKey::releaseKey()
805 {
806     if (m_registry.isValid() && (m_hImpl != nullptr))
807     {
808         m_registry.m_pApi->releaseKey(m_hImpl);
809         m_hImpl = nullptr;
810     }
811 }
812 
setValue(const OUString & keyName,RegValueType valueType,RegValue pValue,sal_uInt32 valueSize)813 inline RegError RegistryKey::setValue(const OUString& keyName,
814                                               RegValueType valueType,
815                                            RegValue pValue,
816                                               sal_uInt32 valueSize)
817     {
818         if (m_registry.isValid())
819             return m_registry.m_pApi->setValue(m_hImpl, keyName.pData, valueType,
820                                                 pValue, valueSize);
821         else
822             return RegError::INVALID_KEY;
823     }
824 
setLongListValue(const OUString & keyName,sal_Int32 const * pValueList,sal_uInt32 len)825 inline RegError RegistryKey::setLongListValue(const OUString& keyName,
826                                                   sal_Int32 const * pValueList,
827                                                   sal_uInt32 len)
828     {
829         if (m_registry.isValid())
830             return m_registry.m_pApi->setLongListValue(m_hImpl, keyName.pData,
831                                                            pValueList, len);
832         else
833             return RegError::INVALID_KEY;
834     }
835 
setStringListValue(const OUString & keyName,char ** pValueList,sal_uInt32 len)836 inline RegError RegistryKey::setStringListValue(const OUString& keyName,
837                                                    char** pValueList,
838                                                    sal_uInt32 len)
839     {
840         if (m_registry.isValid())
841             return m_registry.m_pApi->setStringListValue(m_hImpl, keyName.pData,
842                                                             pValueList, len);
843         else
844             return RegError::INVALID_KEY;
845     }
846 
setUnicodeListValue(const OUString & keyName,sal_Unicode ** pValueList,sal_uInt32 len)847 inline RegError RegistryKey::setUnicodeListValue(const OUString& keyName,
848                                                         sal_Unicode** pValueList,
849                                                         sal_uInt32 len)
850     {
851         if (m_registry.isValid())
852             return m_registry.m_pApi->setUnicodeListValue(m_hImpl, keyName.pData,
853                                                               pValueList, len);
854         else
855             return RegError::INVALID_KEY;
856     }
857 
getValueInfo(const OUString & keyName,RegValueType * pValueType,sal_uInt32 * pValueSize)858 inline RegError RegistryKey::getValueInfo(const OUString& keyName,
859                                                   RegValueType* pValueType,
860                                                   sal_uInt32* pValueSize)
861     {
862         if (m_registry.isValid())
863             return m_registry.m_pApi->getValueInfo(m_hImpl, keyName.pData, pValueType, pValueSize);
864         else
865             return RegError::INVALID_KEY;
866     }
867 
getValue(const OUString & keyName,RegValue pValue)868 inline RegError RegistryKey::getValue(const OUString& keyName,
869                                         RegValue pValue)
870     {
871         if (m_registry.isValid())
872             return m_registry.m_pApi->getValue(m_hImpl, keyName.pData, pValue);
873         else
874             return RegError::INVALID_KEY;
875     }
876 
getLongListValue(const OUString & keyName,RegistryValueList<sal_Int32> & rValueList)877 inline RegError RegistryKey::getLongListValue(const OUString& keyName,
878                                               RegistryValueList<sal_Int32>& rValueList)
879     {
880         if (m_registry.isValid())
881         {
882             RegError    ret = RegError::NO_ERROR;
883             sal_Int32*  pValueList;
884             sal_uInt32  length;
885             ret = m_registry.m_pApi->getLongListValue(m_hImpl, keyName.pData,
886                                                       &pValueList, &length);
887             if ( ret != RegError::NO_ERROR)
888             {
889                 return ret;
890             } else
891             {
892                 rValueList.setValueList(m_registry, RegValueType::LONGLIST,
893                                         pValueList, length);
894                 return ret;
895             }
896         } else
897             return RegError::INVALID_KEY;
898     }
899 
getStringListValue(const OUString & keyName,RegistryValueList<char * > & rValueList)900 inline RegError RegistryKey::getStringListValue(const OUString& keyName,
901                                                       RegistryValueList<char*>& rValueList)
902     {
903         if (m_registry.isValid())
904         {
905             RegError    ret = RegError::NO_ERROR;
906             char**  pValueList;
907             sal_uInt32  length;
908             ret = m_registry.m_pApi->getStringListValue(m_hImpl, keyName.pData,
909                                                       &pValueList, &length);
910             if ( ret != RegError::NO_ERROR )
911             {
912                 return ret;
913             } else
914             {
915                 rValueList.setValueList(m_registry, RegValueType::STRINGLIST,
916                                         pValueList, length);
917                 return ret;
918             }
919         } else
920             return RegError::INVALID_KEY;
921     }
922 
getUnicodeListValue(const OUString & keyName,RegistryValueList<sal_Unicode * > & rValueList)923 inline RegError RegistryKey::getUnicodeListValue(const OUString& keyName,
924                                               RegistryValueList<sal_Unicode*>& rValueList)
925     {
926         if (m_registry.isValid())
927         {
928             RegError        ret = RegError::NO_ERROR;
929             sal_Unicode**   pValueList;
930             sal_uInt32      length;
931             ret = m_registry.m_pApi->getUnicodeListValue(m_hImpl, keyName.pData,
932                                                       &pValueList, &length);
933             if ( ret != RegError::NO_ERROR )
934             {
935                 return ret;
936             } else
937             {
938                 rValueList.setValueList(m_registry, RegValueType::UNICODELIST,
939                                         pValueList, length);
940                 return ret;
941             }
942         } else
943             return RegError::INVALID_KEY;
944     }
945 
getResolvedKeyName(const OUString & keyName,OUString & rResolvedName) const946 inline RegError RegistryKey::getResolvedKeyName(const OUString& keyName,
947                                                       OUString& rResolvedName) const
948     {
949         if (m_registry.isValid())
950             return m_registry.m_pApi->getResolvedKeyName(m_hImpl,
951                                                          keyName.pData,
952                                                          true,
953                                                          &rResolvedName.pData);
954         else
955             return RegError::INVALID_KEY;
956     }
957 
getRegistryName()958 inline OUString RegistryKey::getRegistryName()
959     {
960         if (m_registry.isValid())
961         {
962             return m_registry.getName();
963         } else
964             return OUString();
965     }
966 
967 
Registry()968 inline Registry::Registry()
969     : m_pApi(initRegistry_Api())
970     , m_hImpl(nullptr)
971     { }
972 
Registry(const Registry & toCopy)973 inline Registry::Registry(const Registry& toCopy)
974     : m_pApi(toCopy.m_pApi)
975     , m_hImpl(toCopy.m_hImpl)
976     {
977         if (m_hImpl)
978             m_pApi->acquire(m_hImpl);
979     }
980 
981 
~Registry()982 inline Registry::~Registry()
983     {
984         if (m_hImpl)
985             m_pApi->release(m_hImpl);
986     }
987 
operator =(const Registry & toAssign)988 inline Registry& Registry::operator = (const Registry& toAssign)
989 {
990     if (toAssign.m_hImpl)
991         toAssign.m_pApi->acquire(toAssign.m_hImpl);
992     if (m_hImpl)
993         m_pApi->release(m_hImpl);
994 
995     m_pApi  = toAssign.m_pApi;
996     m_hImpl = toAssign.m_hImpl;
997 
998     return *this;
999 }
1000 
isValid() const1001 inline bool Registry::isValid() const
1002     {  return ( m_hImpl != nullptr ); }
1003 
isReadOnly() const1004 inline bool Registry::isReadOnly() const
1005     {  return m_pApi->isReadOnly(m_hImpl); }
1006 
openRootKey(RegistryKey & rRootKey)1007 inline RegError Registry::openRootKey(RegistryKey& rRootKey)
1008     {
1009         rRootKey.setRegistry(*this);
1010         return m_pApi->openRootKey(m_hImpl, &rRootKey.m_hImpl);
1011     }
1012 
getName()1013 inline OUString Registry::getName()
1014     {
1015         OUString sRet;
1016         m_pApi->getName(m_hImpl, &sRet.pData);
1017         return sRet;
1018     }
1019 
create(const OUString & registryName)1020 inline RegError Registry::create(const OUString& registryName)
1021     {
1022         if (m_hImpl)
1023             m_pApi->release(m_hImpl);
1024         return m_pApi->createRegistry(registryName.pData, &m_hImpl);
1025     }
1026 
open(const OUString & registryName,RegAccessMode accessMode)1027 inline RegError Registry::open(const OUString& registryName,
1028                                   RegAccessMode accessMode)
1029     {
1030         if (m_hImpl)
1031             m_pApi->release(m_hImpl);
1032         return m_pApi->openRegistry(registryName.pData, &m_hImpl, accessMode);
1033     }
1034 
close()1035 inline RegError Registry::close()
1036     {
1037         RegError ret = m_pApi->closeRegistry(m_hImpl);
1038         if (ret == RegError::NO_ERROR)
1039             m_hImpl = nullptr;
1040         return ret;
1041     }
1042 
destroy(const OUString & registryName)1043 inline RegError Registry::destroy(const OUString& registryName)
1044     {
1045         RegError ret = m_pApi->destroyRegistry(m_hImpl, registryName.pData);
1046         if ( ret == RegError::NO_ERROR && registryName.isEmpty() )
1047             m_hImpl = nullptr;
1048         return ret;
1049     }
1050 
mergeKey(RegistryKey & rKey,const OUString & keyName,const OUString & regFileName,bool bReport)1051 inline RegError Registry::mergeKey(RegistryKey& rKey,
1052                                          const OUString& keyName,
1053                                          const OUString& regFileName,
1054                                          bool bReport)
1055     {  return m_pApi->mergeKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData, false/*bWarnings*/, bReport); }
1056 
1057 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1058