xref: /aoo42x/main/registry/inc/registry/registry.hxx (revision 5a5f4a75)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _REGISTRY_REGISTRY_HXX_
25 #define _REGISTRY_REGISTRY_HXX_
26 
27 #include <registry/regtype.h>
28 #include <rtl/ustring.hxx>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /** specifies a collection of function pointers which represents the complete registry C-API.
35 
36     This funtions pointers are used by the C++ wrapper to call the C-API.
37 */
38 struct Registry_Api
39 {
40 	void	  	(REGISTRY_CALLTYPE *acquire) 			(RegHandle);
41 	void	  	(REGISTRY_CALLTYPE *release) 			(RegHandle);
42 	sal_Bool 	(REGISTRY_CALLTYPE *isReadOnly)			(RegHandle);
43 	RegError 	(REGISTRY_CALLTYPE *openRootKey)		(RegHandle, RegKeyHandle*);
44 	RegError	(REGISTRY_CALLTYPE *getName)			(RegHandle, rtl_uString**);
45 	RegError 	(REGISTRY_CALLTYPE *createRegistry)		(rtl_uString*, RegHandle*);
46 	RegError 	(REGISTRY_CALLTYPE *openRegistry)		(rtl_uString*, RegHandle*, RegAccessMode);
47 	RegError 	(REGISTRY_CALLTYPE *closeRegistry)		(RegHandle);
48 	RegError 	(REGISTRY_CALLTYPE *destroyRegistry)	(RegHandle,	rtl_uString*);
49 	RegError 	(REGISTRY_CALLTYPE *loadKey)			(RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*);
50 	RegError 	(REGISTRY_CALLTYPE *saveKey)			(RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*);
51 	RegError 	(REGISTRY_CALLTYPE *mergeKey)			(RegHandle, RegKeyHandle, rtl_uString*, rtl_uString*, sal_Bool, sal_Bool);
52 	RegError 	(REGISTRY_CALLTYPE *dumpRegistry) 		(RegHandle, RegKeyHandle);
53 	void	  	(REGISTRY_CALLTYPE *acquireKey) 	  	(RegKeyHandle);
54 	void	  	(REGISTRY_CALLTYPE *releaseKey) 	  	(RegKeyHandle);
55 	sal_Bool 	(REGISTRY_CALLTYPE *isKeyReadOnly)	  	(RegKeyHandle);
56 	RegError  	(REGISTRY_CALLTYPE *getKeyName)			(RegKeyHandle, rtl_uString**);
57 	RegError 	(REGISTRY_CALLTYPE *createKey)			(RegKeyHandle, rtl_uString*, RegKeyHandle*);
58 	RegError 	(REGISTRY_CALLTYPE *openKey)			(RegKeyHandle, rtl_uString*, RegKeyHandle*);
59 	RegError 	(REGISTRY_CALLTYPE *openSubKeys)		(RegKeyHandle, rtl_uString*, RegKeyHandle**, sal_uInt32*);
60 	RegError 	(REGISTRY_CALLTYPE *closeSubKeys)		(RegKeyHandle*, sal_uInt32);
61 	RegError 	(REGISTRY_CALLTYPE *deleteKey)			(RegKeyHandle, rtl_uString*);
62 	RegError 	(REGISTRY_CALLTYPE *closeKey)			(RegKeyHandle);
63 	RegError 	(REGISTRY_CALLTYPE *setValue)			(RegKeyHandle, rtl_uString*, RegValueType, RegValue, sal_uInt32);
64 	RegError 	(REGISTRY_CALLTYPE *setLongListValue)	(RegKeyHandle, rtl_uString*, sal_Int32*, sal_uInt32);
65 	RegError 	(REGISTRY_CALLTYPE *setStringListValue)	(RegKeyHandle, rtl_uString*, sal_Char**, sal_uInt32);
66 	RegError 	(REGISTRY_CALLTYPE *setUnicodeListValue)(RegKeyHandle, rtl_uString*, sal_Unicode**, sal_uInt32);
67 	RegError 	(REGISTRY_CALLTYPE *getValueInfo)		(RegKeyHandle, rtl_uString*, RegValueType*, sal_uInt32*);
68 	RegError 	(REGISTRY_CALLTYPE *getValue)			(RegKeyHandle, rtl_uString*, RegValue);
69 	RegError 	(REGISTRY_CALLTYPE *getLongListValue)	(RegKeyHandle, rtl_uString*, sal_Int32**, sal_uInt32*);
70 	RegError 	(REGISTRY_CALLTYPE *getStringListValue)	(RegKeyHandle, rtl_uString*, sal_Char***, sal_uInt32*);
71 	RegError 	(REGISTRY_CALLTYPE *getUnicodeListValue)(RegKeyHandle, rtl_uString*, sal_Unicode***, sal_uInt32*);
72 	RegError 	(REGISTRY_CALLTYPE *freeValueList)		(RegValueType, RegValue, sal_uInt32);
73 	RegError 	(REGISTRY_CALLTYPE *createLink) 		(RegKeyHandle, rtl_uString*, rtl_uString*);
74 	RegError 	(REGISTRY_CALLTYPE *deleteLink)			(RegKeyHandle, rtl_uString*);
75 	RegError 	(REGISTRY_CALLTYPE *getKeyType)			(RegKeyHandle, rtl_uString*, RegKeyType*);
76 	RegError 	(REGISTRY_CALLTYPE *getLinkTarget)		(RegKeyHandle, rtl_uString*, rtl_uString**);
77 	RegError 	(REGISTRY_CALLTYPE *getResolvedKeyName)	(RegKeyHandle, rtl_uString*, sal_Bool, rtl_uString**);
78 	RegError 	(REGISTRY_CALLTYPE *getKeyNames)		(RegKeyHandle, rtl_uString*, rtl_uString***, sal_uInt32*);
79 	RegError 	(REGISTRY_CALLTYPE *freeKeyNames)		(rtl_uString**, sal_uInt32);
80 };
81 
82 /** the API initialization function.
83 */
84 Registry_Api* REGISTRY_CALLTYPE initRegistry_Api(void);
85 
86 #ifdef __cplusplus
87 }
88 #endif
89 
90 
91 class RegistryKey;
92 
93 //-----------------------------------------------------------------------------
94 
95 /** The Registry provides the functionality to read and write information in a registry file.
96 
97 	The class is implemented inline and use a C-Api.
98 */
99 class Registry
100 {
101 public:
102 	/** Default constructor.
103 	 */
104 	inline Registry();
105 
106 	/// Copy constructcor
107 	inline Registry(const Registry& toCopy);
108 
109 	/// Destructor. The Destructor close the registry if it is open.
110 	inline ~Registry();
111 
112 	/// Assign operator
113 	inline Registry& operator = (const Registry& toAssign);
114 
115 	/// checks if the registry points to a valid registry data file.
116 	inline sal_Bool	isValid() const;
117 
118 	/**	returns the access mode of the registry.
119 
120 		@return	TRUE if the access mode is readonly else FALSE.
121 	*/
122 	inline sal_Bool 	isReadOnly() const;
123 
124 	/**	opens the root key of the registry.
125 
126 		@param 	rRootKey reference to a RegistryKey which is filled with the rootkey.
127 		@return	REG_NO_ERROR if succeeds else an error code.
128 	*/
129 	inline RegError openRootKey(RegistryKey& rRootKey);
130 
131 	/// returns the name of the current registry data file.
132 	inline ::rtl::OUString getName();
133 
134 	/**	creates a new registry with the specified name and creates a root key.
135 
136 		@param	registryName specifies the name of the new registry.
137 		@return	REG_NO_ERROR if succeeds else an error code.
138 	*/
139 	inline RegError create(const ::rtl::OUString& registryName);
140 
141 	/**	opens a registry with the specified name.
142 
143         If the registry already points to a valid registry, the old registry will be closed.
144 		@param	registryName specifies a registry name.
145 		@param 	accessMode specifies the access mode for the registry, REG_READONLY or REG_READWRITE.
146 		@return	REG_NO_ERROR if succeeds else an error code.
147 	*/
148 	inline RegError open(const ::rtl::OUString& registryName,
149 					   	 RegAccessMode accessMode);
150 
151 	/// closes explicitly the current registry data file.
152 	inline RegError close();
153 
154 	/**	destroys a registry.
155 
156 		@param registryName specifies a registry name, if the name is an empty string the registry
157                             itselfs will be destroyed.
158 		@return	REG_NO_ERROR if succeeds else an error code.
159 	*/
160 	inline RegError destroy(const ::rtl::OUString& registryName);
161 
162 	/**	loads registry information from a specified file and save it under the
163 		specified keyName.
164 
165         @param	rKey references a currently open key. The key which should store the registry information
166                      is a subkey of this key.
167         @param	keyName	specifies the name of the key which stores the registry information. If keyName is
168                         is an empty string the registry information will be saved under the key specified
169                         by rKey.
170 		@param	regFileName	specifies the file containing the registry information.
171 		@return	REG_NO_ERROR if succeeds else an error code.
172 	*/
173 	inline RegError loadKey(RegistryKey& rKey,
174 				  			 const ::rtl::OUString& keyName,
175 				  			 const ::rtl::OUString& regFileName);
176 
177 	/**	saves the registry information of the specified key and all subkeys and save
178 		it in the specified file.
179 
180 		@param	rKey references a currently open key. The key which information is saved by this
181                      function is a subkey of this key.
182 		@param	keyName	specifies the name of the key which information should be stored.
183                         If keyName is an empty string the registry information under the key specified
184                         by rKey is saved in the specified file.
185 		@param	regFileName	specifies the file containing the registry information.
186 		@return	REG_NO_ERROR if succeeds else an error code.
187 	*/
188 	inline RegError saveKey(RegistryKey& rKey,
189 				  			 const ::rtl::OUString& keyName,
190 				  			 const ::rtl::OUString& regFileName);
191 
192 	/**	merges the registry information of the specified key with the registry
193 		information of the specified file.
194 
195         All existing keys will be extended and existing key values will be overwritten.
196 		@param	rKey references a currently open key. The key which information is merged by this
197                      function is a subkey of this key
198 		@param	keyName	specifies the name of the key which will be merged.
199                         If keyName is an empty string the registry information under the key specified
200                         by rKey is merged with the information from the specified file.
201 		@param	regFileName	specifies the file containing the registry information.
202 		@param	bWarnings if TRUE the function returns an error if a key already exists.
203 		@param	bReport if TRUE the function reports warnings on stdout if a key already exists.
204 		@return	REG_NO_ERROR if succeeds else an error code. If it returns an error the registry will
205                 restore the state before merging.
206 	*/
207 	inline RegError mergeKey(RegistryKey& rKey,
208 				   			 const ::rtl::OUString& keyName,
209 				   			 const ::rtl::OUString& regFileName,
210 							 sal_Bool bWarnings = sal_False,
211 				   			 sal_Bool bReport = sal_False);
212 
213     /**	This function reports the complete registry information of a key and all of its subkeys.
214 
215         All information which are available (keynames, value types, values, ...)
216         will be printed to stdout for report issues only.
217 	    @param	rKey references a currently open key which content will be reported.
218 	    @return	REG_NO_ERROR if succeeds else an error code.
219     */
220 	inline RegError dumpRegistry(RegistryKey& rKey);
221 
222 	friend class RegistryKey;
223 	friend class RegistryKeyArray;
224 	friend class RegistryKeyNames;
225 
226     /// returns the used registry Api.
227 	const Registry_Api* getApi() { return m_pApi; }
228 protected:
229 
230     /// stores the used and initialized registry Api.
231 	const Registry_Api*							 m_pApi;
232     /// stores the handle of the underlying registry file on which most of the functions work.
233 	RegHandle									 m_hImpl;
234 };
235 
236 
237 //-----------------------------------------------------------------------------
238 
239 /** RegistryKeyArray represents an array of open keys.
240 
241 	RegistryKeyArray is a helper class to work with an array of keys.
242 */
243 class RegistryKeyArray
244 {
245 public:
246 	/// Default constructor
247 	inline RegistryKeyArray();
248 
249 	/// Destructor, all subkeys will be closed.
250 	inline ~RegistryKeyArray();
251 
252 	/// returns the open key specified by index.
253 	inline RegistryKey getElement(sal_uInt32 index);
254 
255 	/// returns the length of the array.
256 	inline sal_uInt32 getLength();
257 
258 	friend class RegistryKey;
259 protected:
260     /** sets the data of the key array.
261 
262         @param registry specifies the registry files where the keys are located.
263         @param phKeys points to an array of open keys.
264         @param length specifies the length of the array specified by phKeys.
265      */
266 	inline void setKeyHandles(Registry& registry, RegKeyHandle* phKeys, sal_uInt32 length);
267     /// close all subkeys
268 	inline RegError closeKeyHandles();
269 
270     /// stores the number of open subkeys, the number of elements.
271 	sal_uInt32 	   	m_length;
272     /// stores an array of open subkeys.
273 	RegKeyHandle*	m_phKeys;
274     /// stores the handle to the registry file where the appropriate keys are located.
275 	Registry		m_registry;
276 };
277 
278 
279 /** RegistryKeyNames represents an array of key names.
280 
281 	RegistryKeyNames is a helper class to work with an array of key names.
282 */
283 class RegistryKeyNames
284 {
285 public:
286 	/// Default constructor
287 	inline RegistryKeyNames();
288 
289 	/// Destructor, the internal array with key names will be deleted.
290 	inline ~RegistryKeyNames();
291 
292 	/// returns the name of the key sepecified by index.
293 	inline ::rtl::OUString getElement(sal_uInt32 index);
294 
295 	/// returns the length of the array.
296 	inline sal_uInt32 getLength();
297 
298 	friend class RegistryKey;
299 protected:
300     /** sets the data of the array.
301 
302         @param registry specifies the registry files where the keys are located.
303         @param pKeyNames points to an array of key names.
304         @param length specifies the length of the array specified by pKeyNames.
305      */
306 	inline void setKeyNames(Registry& registry, rtl_uString** pKeyNames, sal_uInt32 length);
307     /// delete the array of key names.
308 	inline RegError freeKeyNames();
309 
310     /// stores the number of key names, the number of elements.
311 	sal_uInt32 		m_length;
312     /// stores an array of key names.
313 	rtl_uString**	m_pKeyNames;
314     /// stores the handle to the registry file where the appropriate keys are located.
315 	Registry		m_registry;
316 };
317 
318 //-----------------------------------------------------------------------------
319 
320 /** RegistryValueList represents a value list of the specified type.
321 
322 	RegistryValueList is a helper class to work with a list value.
323 */
324 template<class ValueType>
325 class RegistryValueList
326 {
327 public:
328 	/// Default constructor
329 	RegistryValueList()
330 		: m_length(0)
331 		, m_pValueList(NULL)
332 		, m_valueType(RG_VALUETYPE_NOT_DEFINED)
333 		{}
334 
335 	/// Destructor, the internal value list will be freed.
336 	~RegistryValueList()
337 	{
338 		if (m_pValueList)
339 		{
340 			m_registry.getApi()->freeValueList(m_valueType, m_pValueList, m_length);
341 		}
342 	}
343 
344 	/// returns the value of the list specified by index.
345 	ValueType getElement(sal_uInt32 index)
346 	{
347 		if (m_registry.isValid() && index < m_length)
348 		{
349 			return m_pValueList[index];
350 		} else
351 		{
352 			return 0;
353 		}
354 	}
355 
356 	/// returns the length of the list.
357 	sal_uInt32 getLength()
358 	{
359 		return m_length;
360 	}
361 
362 	friend class RegistryKey;
363 protected:
364     /** sets the data of the value list.
365 
366         @param registry specifies the registry files where the appropriate key is located.
367         @param valueType specifies the type of the list values.
368         @param pValueList points to a value list.
369         @param length specifies the length of the list.
370      */
371 	void setValueList(Registry& registry, RegValueType valueType,
372 					  ValueType* pValueList, sal_uInt32 length)
373 	{
374 		m_length = length;
375 		m_pValueList = pValueList;
376 		m_valueType = valueType;
377 		m_registry = registry;
378 	}
379 
380     /// stores the length of the list, the number of elements.
381 	sal_uInt32 		m_length;
382     /// stores the value list.
383 	ValueType*		m_pValueList;
384     /// stores the type of the list elements
385 	RegValueType	m_valueType;
386     /** stores the handle to the registry file where the appropriate key to this
387         value is located.
388     */
389 	Registry		m_registry;
390 };
391 
392 //-----------------------------------------------------------------------------
393 
394 /** RegistryKey reads or writes information of the underlying key in a registry.
395 
396 	Class is inline and use a load on call C-Api.
397 */
398 class RegistryKey
399 {
400 public:
401 	/// Default constructor
402 	inline RegistryKey();
403 
404 	/// Copy constructor
405 	inline RegistryKey(const RegistryKey& toCopy);
406 
407 	/// Destructor, close the key if it references an open one.
408 	inline ~RegistryKey();
409 
410 	/// Assign operator
411 	inline RegistryKey& operator = (const RegistryKey& toAssign);
412 
413 	/// checks if the key points to a valid registry key.
414 	inline sal_Bool	isValid() const;
415 
416 	/**	returns the access mode of the key.
417 
418 		@return	TRUE if access mode is read only else FALSE.
419 	*/
420 	inline sal_Bool 	isReadOnly() const;
421 
422 	/// returns the full qualified name of the key beginning with the rootkey.
423 	inline ::rtl::OUString getName();
424 
425 	/**	creates a new key or opens a key if the specified key already exists.
426 
427         The specified keyname is relativ to this key.
428 		@param	keyName	specifies the name of the key which will be opened or created.
429 		@param	rNewKey	references a RegistryKey which will be filled with the new or open key.
430 		@return	REG_NO_ERROR if succeeds else an error code.
431 	*/
432 	inline RegError createKey(const ::rtl::OUString& keyName,
433 							  RegistryKey& rNewKey);
434 
435 	/**	opens the specified key.
436 
437         The specified keyname is relativ to this key.
438 		@param	keyName	specifies the name of the key which will be opened.
439 		@param	rOpenKey references a RegistryKey which will be filled with the open key.
440 		@return	REG_NO_ERROR if succeeds else an error code.
441 	*/
442 	inline RegError openKey(const ::rtl::OUString& keyName,
443 				  			RegistryKey& rOpenKey);
444 
445 	/**	opens all subkeys of the specified key.
446 
447         The specified keyname is relativ to this key.
448 		@param	keyName	specifies the name of the key which subkeys will be opened.
449 		@param	rSubKeys reference a RegistryKeyArray which will be filled with the open subkeys.
450 		@return	REG_NO_ERROR if succeeds else an error code.
451 	*/
452 	inline RegError openSubKeys(const ::rtl::OUString& keyName,
453 					  	  		RegistryKeyArray& rSubKeys);
454 
455 	/**	returns an array with the names of all subkeys of the specified key.
456 
457         The specified keyname is relativ to this key.
458 		@param	keyName	specifies the name of the key which subkey names will be returned.
459 		@param	rSubKeyNames reference a RegistryKeyNames array which will be filled with the subkey names.
460 		@return	REG_NO_ERROR if succeeds else an error code.
461 	*/
462 	inline RegError getKeyNames(const ::rtl::OUString& keyName,
463 					  	  		RegistryKeyNames& rSubKeyNames);
464 
465 	/**	closes all keys specified in the array.
466 
467 		@param	rSubKeys reference a RegistryKeyArray which contains the open keys.
468 		@return	REG_NO_ERROR if succeeds else an error code.
469 	*/
470 	inline RegError closeSubKeys(RegistryKeyArray& rSubKeys);
471 
472 	/**	deletes the specified key.
473 
474 		@param	keyName	specifies the name of the key which will be deleted.
475 		@return	REG_NO_ERROR if succeeds else an error code.
476 	*/
477 	inline RegError deleteKey(const ::rtl::OUString& keyName);
478 
479 	/// closes explicitly the current key
480 	inline RegError closeKey();
481 
482 	/// releases the current key
483 	inline void releaseKey();
484 
485 	/**	sets a value of a key.
486 
487 		@param	keyName	specifies the name of the key which value will be set.
488                         If keyName is an empty string, the value will be set for the key
489                         specified by hKey.
490 		@param	valueType specifies the type of the value.
491 		@param	pData points to a memory block containing the data for the value.
492 		@param	valueSize specifies the size of pData in bytes
493 		@return	REG_NO_ERROR if succeeds else an error code.
494 	*/
495 	inline RegError setValue(const ::rtl::OUString& keyName,
496 				   			 RegValueType valueType,
497 				   			 RegValue pValue,
498 				   			 sal_uInt32 valueSize);
499 
500 	/**	sets a long list value of a key.
501 
502 		@param	keyName	specifies the name of the key which value will be set.
503                         If keyName is an empty string, the value will be set for the key
504                         specified by hKey.
505 		@param	pValueList points to an array of longs containing the data for the value.
506 		@param	len specifies the length of the list (the array referenced by pValueList).
507 		@return	REG_NO_ERROR if succeeds else an error code.
508 	*/
509 	inline RegError setLongListValue(const ::rtl::OUString& keyName,
510 				   			 		 sal_Int32* pValueList,
511 				   			 		 sal_uInt32 len);
512 
513 	/**	sets an ascii list value of a key.
514 
515 		@param	keyName	specifies the name of the key which value will be set.
516                         If keyName is an empty string, the value will be set for the key
517                         specified by hKey.
518 		@param	pValueList points to an array of sal_Char* containing the data for the value.
519 		@param	len specifies the length of the list (the array referenced by pValueList).
520 		@return	REG_NO_ERROR if succeeds else an error code.
521 	*/
522 	inline RegError setStringListValue(const ::rtl::OUString& keyName,
523 				   			 		   sal_Char** pValueList,
524 				   			 		   sal_uInt32 len);
525 
526 	/**	sets an unicode string list value of a key.
527 
528 		@param	keyName	specifies the name of the key which value will be set.
529                         If keyName is an empty string, the value will be set for the key
530                         specified by hKey.
531 		@param	pValueList points to an array of sal_Unicode* containing the data for the value.
532 		@param	len specifies the length of the list (the array referenced by pValueList).
533 		@return	REG_NO_ERROR if succeeds else an error code.
534 	*/
535 	inline RegError setUnicodeListValue(const ::rtl::OUString& keyName,
536 				   			 		    sal_Unicode** pValueList,
537 				   			 		  	sal_uInt32 len);
538 
539 	/**	gets info about type and size of a value.
540 
541 		@param	keyName	specifies the name of the key which value info will be returned.
542                         If keyName is an empty string, the value info of the key
543                         specified by hKey will be returned.
544 		@param	pValueType returns the type of the value.
545 		@param	pValueSize returns the size of the value in bytes or the length of a list value.
546 		@return	REG_NO_ERROR if succeeds else an error code.
547 	*/
548 	inline RegError getValueInfo(const ::rtl::OUString& keyName,
549 					   			 RegValueType* pValueType,
550 					   			 sal_uInt32* pValueSize);
551 
552 	/**	gets the value of a key.
553 
554 		@param	keyName	specifies the name of the key which value will be returned.
555                         If keyName is an empty string, the value is get from the key
556                         specified by hKey.
557 		@param	pValue points to an allocated memory block receiving the data of the value.
558 		@return	REG_NO_ERROR if succeeds else an error code.
559 	*/
560 	inline RegError getValue(const ::rtl::OUString& keyName,
561 				   			 RegValue pValue);
562 
563 	/**	gets a long list value of a key.
564 
565 		@param	keyName	specifies the name of the key which value will be returned.
566                         If keyName is an empty string, the value is get from the key
567                         specified by hKey.
568 		@param	rValueList references a RegistryValueList which will be filled with the long values.
569 		@return	REG_NO_ERROR if succeeds else an error code.
570 	*/
571 	inline RegError getLongListValue(const ::rtl::OUString& keyName,
572 					  	  			  RegistryValueList<sal_Int32>& rValueList);
573 
574 	/**	gets an ascii list value of a key.
575 
576 		@param	keyName	specifies the name of the key which value will be returned.
577                         If keyName is an empty string, the value is get from the key
578                         specified by hKey.
579 		@param	rValueList references a RegistryValueList which will be filled with the ascii values.
580 		@return	REG_NO_ERROR if succeeds else an error code.
581 	*/
582 	inline RegError getStringListValue(const ::rtl::OUString& keyName,
583 					  	  			   RegistryValueList<sal_Char*>& rValueList);
584 
585 	/**	gets a unicode value of a key.
586 
587 		@param	keyName	specifies the name of the key which value will be returned.
588                         If keyName is an empty string, the value is get from the key
589                         specified by hKey.
590 		@param	rValueList reference a RegistryValueList which will be filled with the unicode values.
591 		@return	REG_NO_ERROR if succeeds else an error code.
592 	*/
593 	inline RegError getUnicodeListValue(const ::rtl::OUString& keyName,
594 					  	  			  	RegistryValueList<sal_Unicode*>& rValueList);
595 
596     /** used to create a link.
597 
598         @obsolete Links are no longer supported.
599 
600         @return	REG_INVALID_LINK
601      */
602 	inline RegError	createLink(const ::rtl::OUString& linkName,
603 							   const ::rtl::OUString& linkTarget);
604 
605     /** used to delete a link.
606 
607         @obsolete Links are no longer supported.
608 
609         @return	REG_INVALID_LINK
610      */
611 	inline RegError	deleteLink(const ::rtl::OUString& linkName);
612 
613     /** returns the type of the specified key.
614 
615         @param name specifies the name of the key or link.
616         @param pKeyType returns the type of the key (always RG_KEYTYPE).
617 		@return	REG_NO_ERROR if succeeds else an error code.
618      */
619 	inline RegError	getKeyType(const ::rtl::OUString& name,
620 						   	   RegKeyType* pKeyType) const;
621 
622     /** used to return the target of a link.
623 
624         @obsolete Links are no longer supported.
625 
626         @return	REG_INVALID_LINK
627      */
628 	inline RegError getLinkTarget(const ::rtl::OUString& linkName,
629 							  	  ::rtl::OUString& rLinkTarget) const;
630 
631 	/** resolves a keyname.
632 
633 		@param	keyName specifies the name of the key which will be resolved relativ to this key.
634                         The resolved name will be prefixed with the name of this key.
635         @param firstLinkOnly ignored
636 		@return	REG_NO_ERROR if succeeds else an error code.
637 	 */
638 	inline RegError getResolvedKeyName(const ::rtl::OUString& keyName,
639 									   sal_Bool firstLinkOnly,
640 						  	  		   ::rtl::OUString& rResolvedName) const;
641 
642 	/// returns the name of the registry in which the key is defined.
643 	inline ::rtl::OUString getRegistryName();
644 
645 	/// returns the registry in which the key is defined.
646 	Registry getRegistry() const { return m_registry; }
647 
648 	friend class Registry;
649 public:
650     /** Constructor, which initialize a RegistryKey with registry and an valid key handle.
651 
652         This constructor is internal only.
653         @internal
654     */
655 	inline RegistryKey(Registry&	registry,
656 					   RegKeyHandle hKey);
657 
658     /** returns the internal key handle.
659 
660         @internal
661      */
662 	RegKeyHandle getKeyHandle() const { return m_hImpl; }
663 
664 protected:
665     /** sets the internal registry on which this key should work.
666 
667         @internal
668      */
669 	inline void setRegistry(Registry& registry);
670 
671     /// stores the registry on which this key works
672 	Registry		m_registry;
673     /// stores the current key handle of this key
674 	RegKeyHandle	m_hImpl;
675 };
676 
677 
678 //-----------------------------------------------------------------------------
679 
680 inline RegistryKeyArray::RegistryKeyArray()
681 	: m_length(0)
682 	, m_phKeys(NULL)
683 {
684 }
685 
686 inline RegistryKeyArray::~RegistryKeyArray()
687 {
688 	if (m_phKeys)
689 		m_registry.m_pApi->closeSubKeys(m_phKeys, m_length);
690 }
691 
692 inline RegistryKey RegistryKeyArray::getElement(sal_uInt32 index)
693 {
694 	if (m_registry.isValid() && index < m_length)
695 		return RegistryKey(m_registry, m_phKeys[index]);
696 	else
697 		return RegistryKey();
698 }
699 
700 inline sal_uInt32 RegistryKeyArray::getLength()
701 {
702 	return m_length;
703 }
704 
705 inline void RegistryKeyArray::setKeyHandles(Registry& registry,
706 											RegKeyHandle* phKeys,
707 											sal_uInt32 length)
708 {
709 	m_phKeys = phKeys;
710 	m_length = length;
711 	m_registry = registry;
712 }
713 
714 inline RegError RegistryKeyArray::closeKeyHandles()
715 {
716 	if (m_registry.isValid() && m_phKeys)
717 	{
718 		RegError ret;
719 		ret = m_registry.m_pApi->closeSubKeys(m_phKeys, m_length);
720 		m_registry = Registry();
721 		m_length = 0;
722 		m_phKeys = NULL;
723 		return ret;
724 	} else
725 		return(REG_INVALID_KEY);
726 }
727 
728 //-----------------------------------------------------------------------------
729 
730 inline RegistryKeyNames::RegistryKeyNames()
731 	: m_length(0)
732 	, m_pKeyNames(NULL)
733 {
734 }
735 
736 inline RegistryKeyNames::~RegistryKeyNames()
737 {
738 	if (m_pKeyNames)
739 		m_registry.m_pApi->freeKeyNames(m_pKeyNames, m_length);
740 }
741 
742 inline ::rtl::OUString RegistryKeyNames::getElement(sal_uInt32 index)
743 {
744 
745 	if (m_pKeyNames && index < m_length)
746 		return m_pKeyNames[index];
747 	else
748 		return ::rtl::OUString();
749 }
750 
751 inline sal_uInt32 RegistryKeyNames::getLength()
752 {
753 	return m_length;
754 }
755 
756 inline void RegistryKeyNames::setKeyNames(Registry& registry,
757 										  rtl_uString** pKeyNames,
758 										  sal_uInt32 length)
759 {
760 	m_pKeyNames = pKeyNames;
761 	m_length = length;
762 	m_registry = registry;
763 }
764 
765 inline RegError RegistryKeyNames::freeKeyNames()
766 {
767 	if (m_registry.isValid() && m_pKeyNames)
768 	{
769 		RegError ret = REG_NO_ERROR;
770 		ret = m_registry.m_pApi->freeKeyNames(m_pKeyNames, m_length);
771 		m_registry = Registry();
772 		m_length = 0;
773 		m_pKeyNames = NULL;
774 		return ret;
775 	} else
776 		return REG_INVALID_KEY;
777 }
778 
779 //-----------------------------------------------------------------------------
780 
781 inline RegistryKey::RegistryKey()
782 	: m_hImpl(NULL)
783 	{ }
784 
785 inline RegistryKey::RegistryKey(Registry& registry, RegKeyHandle hKey)
786 	: m_registry(registry)
787 	, m_hImpl(hKey)
788 	{
789 		if (m_hImpl)
790 			m_registry.m_pApi->acquireKey(m_hImpl);
791 	}
792 
793 inline RegistryKey::RegistryKey(const RegistryKey& toCopy)
794 	: m_registry(toCopy.m_registry)
795 	, m_hImpl(toCopy.m_hImpl)
796 	{
797 		if (m_hImpl)
798 			m_registry.m_pApi->acquireKey(m_hImpl);
799 	}
800 
801 inline void RegistryKey::setRegistry(Registry& registry)
802 	{
803 		m_registry = registry;
804 	}
805 
806 inline RegistryKey::~RegistryKey()
807 	{
808 		if (m_hImpl)
809 			m_registry.m_pApi->releaseKey(m_hImpl);
810 	}
811 
812 inline RegistryKey& RegistryKey::operator = (const RegistryKey& toAssign)
813 {
814 	m_registry = toAssign.m_registry;
815 
816 	if (toAssign.m_hImpl)
817 		m_registry.m_pApi->acquireKey(toAssign.m_hImpl);
818 	if (m_hImpl)
819 		m_registry.m_pApi->releaseKey(m_hImpl);
820 	m_hImpl = toAssign.m_hImpl;
821 
822 	return *this;
823 }
824 
825 inline sal_Bool RegistryKey::isValid() const
826 	{  return (m_hImpl != NULL); }
827 
828 inline sal_Bool RegistryKey::isReadOnly() const
829 	{
830 		if 	(m_registry.isValid())
831 			return (m_registry.m_pApi)->isKeyReadOnly(m_hImpl);
832 		else
833 			return sal_False;
834 	}
835 
836 inline ::rtl::OUString RegistryKey::getName()
837 	{
838 		::rtl::OUString sRet;
839 		if (m_registry.isValid())
840 			m_registry.m_pApi->getKeyName(m_hImpl, &sRet.pData);
841 		return sRet;;
842 	}
843 
844 inline RegError RegistryKey::createKey(const ::rtl::OUString& keyName,
845 						   			   RegistryKey& rNewKey)
846 	{
847 		if (rNewKey.isValid()) rNewKey.closeKey();
848 		if (m_registry.isValid())
849 		{
850 			RegError ret = m_registry.m_pApi->createKey(m_hImpl, keyName.pData, &rNewKey.m_hImpl);
851 			if (!ret) rNewKey.setRegistry(m_registry);
852 			return ret;
853 		} else
854 			return REG_INVALID_KEY;
855 	}
856 
857 inline RegError RegistryKey::openKey(const ::rtl::OUString& keyName,
858 			  			 		  RegistryKey& rOpenKey)
859 	{
860 		if (rOpenKey.isValid()) rOpenKey.closeKey();
861 		if (m_registry.isValid())
862 		{
863 			RegError ret = m_registry.m_pApi->openKey(m_hImpl, keyName.pData,
864 													&rOpenKey.m_hImpl);
865 			if (!ret) rOpenKey.setRegistry(m_registry);
866 			return ret;
867 		} else
868 			return REG_INVALID_KEY;
869 	}
870 
871 inline RegError RegistryKey::openSubKeys(const ::rtl::OUString& keyName,
872 										 RegistryKeyArray& rSubKeys)
873 	{
874 		if (m_registry.isValid())
875 		{
876 			RegError 		ret = REG_NO_ERROR;
877 			RegKeyHandle* 	pSubKeys;
878 			sal_uInt32 		nSubKeys;
879 	 		ret = m_registry.m_pApi->openSubKeys(m_hImpl, keyName.pData,
880 	 												 &pSubKeys, &nSubKeys);
881 	 		if ( ret )
882 			{
883 				return ret;
884 			} else
885 			{
886 				rSubKeys.setKeyHandles(m_registry, pSubKeys, nSubKeys);
887 				return ret;
888 			}
889 		} else
890 			return REG_INVALID_KEY;
891 	}
892 
893 inline RegError RegistryKey::getKeyNames(const ::rtl::OUString& keyName,
894 					  	  				 RegistryKeyNames& rSubKeyNames)
895 	{
896 		if (m_registry.isValid())
897 		{
898 			RegError 		ret = REG_NO_ERROR;
899 			rtl_uString**	pSubKeyNames;
900 			sal_uInt32 		nSubKeys;
901 	 		ret = m_registry.m_pApi->getKeyNames(m_hImpl, keyName.pData,
902 	 											 &pSubKeyNames, &nSubKeys);
903 	 		if ( ret )
904 			{
905 				return ret;
906 			} else
907 			{
908 				rSubKeyNames.setKeyNames(m_registry, pSubKeyNames, nSubKeys);
909 				return ret;
910 			}
911 		} else
912 			return REG_INVALID_KEY;
913 	}
914 
915 inline RegError RegistryKey::closeSubKeys(RegistryKeyArray& rSubKeys)
916 	{
917 		if (m_registry.isValid())
918 			return rSubKeys.closeKeyHandles();
919 		else
920 			return REG_INVALID_KEY;
921 	}
922 
923 inline RegError RegistryKey::deleteKey(const ::rtl::OUString& keyName)
924 	{
925 		if (m_registry.isValid())
926 			return m_registry.m_pApi->deleteKey(m_hImpl, keyName.pData);
927 		else
928 			return REG_INVALID_KEY;
929 	}
930 
931 inline RegError RegistryKey::closeKey()
932 	{
933 		if (m_registry.isValid())
934 		{
935 			RegError ret = m_registry.m_pApi->closeKey(m_hImpl);
936 			if (!ret)
937 			{
938 				m_hImpl = NULL;
939 				m_registry = Registry();
940 			}
941 			return ret;
942 		} else
943 			return REG_INVALID_KEY;
944 	}
945 
946 inline void RegistryKey::releaseKey()
947 {
948 	if (m_registry.isValid() && (m_hImpl != 0))
949 	{
950 		m_registry.m_pApi->releaseKey(m_hImpl), m_hImpl = 0;
951 	}
952 }
953 
954 inline RegError RegistryKey::setValue(const ::rtl::OUString& keyName,
955 			   			  		   	  RegValueType valueType,
956 			   			  		      RegValue pValue,
957 			   			  		   	  sal_uInt32 valueSize)
958 	{
959 		if (m_registry.isValid())
960 			return m_registry.m_pApi->setValue(m_hImpl, keyName.pData, valueType,
961 								 			   pValue, valueSize);
962 		else
963 			return REG_INVALID_KEY;
964 	}
965 
966 inline RegError RegistryKey::setLongListValue(const ::rtl::OUString& keyName,
967 			   			 					  sal_Int32* pValueList,
968 						   			 		  sal_uInt32 len)
969 	{
970 		if (m_registry.isValid())
971 			return m_registry.m_pApi->setLongListValue(m_hImpl, keyName.pData,
972 								 			   		   pValueList, len);
973 		else
974 			return REG_INVALID_KEY;
975 	}
976 
977 inline RegError RegistryKey::setStringListValue(const ::rtl::OUString& keyName,
978 			   			 					   sal_Char** pValueList,
979 						   			 		   sal_uInt32 len)
980 	{
981 		if (m_registry.isValid())
982 			return m_registry.m_pApi->setStringListValue(m_hImpl, keyName.pData,
983 								 			   			pValueList, len);
984 		else
985 			return REG_INVALID_KEY;
986 	}
987 
988 inline RegError RegistryKey::setUnicodeListValue(const ::rtl::OUString& keyName,
989 			   			 					   	 sal_Unicode** pValueList,
990 						   			 		   	 sal_uInt32 len)
991 	{
992 		if (m_registry.isValid())
993 			return m_registry.m_pApi->setUnicodeListValue(m_hImpl, keyName.pData,
994 								 			   			  pValueList, len);
995 		else
996 			return REG_INVALID_KEY;
997 	}
998 
999 inline RegError RegistryKey::getValueInfo(const ::rtl::OUString& keyName,
1000 				   			  		   	  RegValueType* pValueType,
1001 				   			  		   	  sal_uInt32* pValueSize)
1002 	{
1003 		if (m_registry.isValid())
1004 			return m_registry.m_pApi->getValueInfo(m_hImpl, keyName.pData, pValueType, pValueSize);
1005 		else
1006 			return REG_INVALID_KEY;
1007 	}
1008 
1009 inline RegError RegistryKey::getValue(const ::rtl::OUString& keyName,
1010 			   			  		   RegValue pValue)
1011 	{
1012 		if (m_registry.isValid())
1013 			return m_registry.m_pApi->getValue(m_hImpl, keyName.pData, pValue);
1014 		else
1015 			return REG_INVALID_KEY;
1016 	}
1017 
1018 inline RegError RegistryKey::getLongListValue(const ::rtl::OUString& keyName,
1019 				  	  			  		RegistryValueList<sal_Int32>& rValueList)
1020 	{
1021 		if (m_registry.isValid())
1022 		{
1023 			RegError 	ret = REG_NO_ERROR;
1024 			sal_Int32* 	pValueList;
1025 			sal_uInt32 	length;
1026 	 		ret = m_registry.m_pApi->getLongListValue(m_hImpl, keyName.pData,
1027 	 												 &pValueList, &length);
1028 	 		if ( ret )
1029 			{
1030 				return ret;
1031 			} else
1032 			{
1033 				rValueList.setValueList(m_registry, RG_VALUETYPE_LONGLIST,
1034 										pValueList, length);
1035 				return ret;
1036 			}
1037 		} else
1038 			return REG_INVALID_KEY;
1039 	}
1040 
1041 inline RegError RegistryKey::getStringListValue(const ::rtl::OUString& keyName,
1042 				  	  			  				RegistryValueList<sal_Char*>& rValueList)
1043 	{
1044 		if (m_registry.isValid())
1045 		{
1046 			RegError 	ret = REG_NO_ERROR;
1047 			sal_Char** 	pValueList;
1048 			sal_uInt32 	length;
1049 	 		ret = m_registry.m_pApi->getStringListValue(m_hImpl, keyName.pData,
1050 	 												 &pValueList, &length);
1051 	 		if ( ret )
1052 			{
1053 				return ret;
1054 			} else
1055 			{
1056 				rValueList.setValueList(m_registry, RG_VALUETYPE_STRINGLIST,
1057 										pValueList, length);
1058 				return ret;
1059 			}
1060 		} else
1061 			return REG_INVALID_KEY;
1062 	}
1063 
1064 inline RegError RegistryKey::getUnicodeListValue(const ::rtl::OUString& keyName,
1065 				  	  			  		RegistryValueList<sal_Unicode*>& rValueList)
1066 	{
1067 		if (m_registry.isValid())
1068 		{
1069 			RegError 		ret = REG_NO_ERROR;
1070 			sal_Unicode** 	pValueList;
1071 			sal_uInt32 		length;
1072 	 		ret = m_registry.m_pApi->getUnicodeListValue(m_hImpl, keyName.pData,
1073 	 												 &pValueList, &length);
1074 	 		if ( ret )
1075 			{
1076 				return ret;
1077 			} else
1078 			{
1079 				rValueList.setValueList(m_registry, RG_VALUETYPE_UNICODELIST,
1080 										pValueList, length);
1081 				return ret;
1082 			}
1083 		} else
1084 			return REG_INVALID_KEY;
1085 	}
1086 
1087 inline RegError	RegistryKey::createLink(const ::rtl::OUString& linkName,
1088 						   				const ::rtl::OUString& linkTarget)
1089 	{
1090 		if (m_registry.isValid())
1091 			return m_registry.m_pApi->createLink(m_hImpl, linkName.pData, linkTarget.pData);
1092 		else
1093 			return REG_INVALID_KEY;
1094 	}
1095 
1096 inline RegError	RegistryKey::deleteLink(const ::rtl::OUString& linkName)
1097 	{
1098 		if (m_registry.isValid())
1099 			return m_registry.m_pApi->deleteLink(m_hImpl, linkName.pData);
1100 		else
1101 			return REG_INVALID_KEY;
1102 	}
1103 
1104 inline RegError	RegistryKey::getKeyType(const ::rtl::OUString& keyName,
1105 					   	   				RegKeyType* pKeyType) const
1106 	{
1107 		if (m_registry.isValid())
1108 			return m_registry.m_pApi->getKeyType(m_hImpl, keyName.pData, pKeyType);
1109 		else
1110 			return REG_INVALID_KEY;
1111 	}
1112 
1113 inline RegError RegistryKey::getLinkTarget(const ::rtl::OUString& linkName,
1114 						  	  			   ::rtl::OUString& rLinkTarget) const
1115 	{
1116 		if (m_registry.isValid())
1117 		{
1118 			return m_registry.m_pApi->getLinkTarget(m_hImpl,
1119 													linkName.pData,
1120 													&rLinkTarget.pData);
1121 		} else
1122 			return REG_INVALID_KEY;
1123 	}
1124 
1125 
1126 inline RegError RegistryKey::getResolvedKeyName(const ::rtl::OUString& keyName,
1127 								   				sal_Bool firstLinkOnly,
1128 					  	  		   				::rtl::OUString& rResolvedName) const
1129 	{
1130 		if (m_registry.isValid())
1131 			return m_registry.m_pApi->getResolvedKeyName(m_hImpl,
1132 														 keyName.pData,
1133 														 firstLinkOnly,
1134 														 &rResolvedName.pData);
1135 		else
1136 			return REG_INVALID_KEY;
1137 	}
1138 
1139 inline ::rtl::OUString RegistryKey::getRegistryName()
1140 	{
1141 		if (m_registry.isValid())
1142 		{
1143 			return m_registry.getName();
1144 		} else
1145 			return ::rtl::OUString();
1146 	}
1147 
1148 //-----------------------------------------------------------------------------
1149 
1150 inline Registry::Registry()
1151 	: m_pApi(initRegistry_Api())
1152 	, m_hImpl(NULL)
1153 	{ }
1154 
1155 inline Registry::Registry(const Registry& toCopy)
1156 	: m_pApi(toCopy.m_pApi)
1157 	, m_hImpl(toCopy.m_hImpl)
1158 	{
1159 		if (m_hImpl)
1160 			m_pApi->acquire(m_hImpl);
1161 	}
1162 
1163 
1164 inline Registry::~Registry()
1165 	{
1166 		if (m_hImpl)
1167 			m_pApi->release(m_hImpl);
1168 	}
1169 
1170 inline Registry& Registry::operator = (const Registry& toAssign)
1171 {
1172 	if (toAssign.m_hImpl)
1173 		toAssign.m_pApi->acquire(toAssign.m_hImpl);
1174 	if (m_hImpl)
1175 		m_pApi->release(m_hImpl);
1176 
1177 	m_pApi  = toAssign.m_pApi;
1178 	m_hImpl = toAssign.m_hImpl;
1179 
1180 	return *this;
1181 }
1182 
1183 inline sal_Bool Registry::isValid() const
1184 	{  return ( m_hImpl != NULL ); }
1185 
1186 inline sal_Bool Registry::isReadOnly() const
1187 	{  return m_pApi->isReadOnly(m_hImpl); }
1188 
1189 inline RegError Registry::openRootKey(RegistryKey& rRootKey)
1190 	{
1191 		rRootKey.setRegistry(*this);
1192 		return m_pApi->openRootKey(m_hImpl, &rRootKey.m_hImpl);
1193 	}
1194 
1195 inline ::rtl::OUString Registry::getName()
1196 	{
1197 		::rtl::OUString sRet;
1198 		m_pApi->getName(m_hImpl, &sRet.pData);
1199 		return sRet;
1200 	}
1201 
1202 inline RegError Registry::create(const ::rtl::OUString& registryName)
1203 	{
1204 		if (m_hImpl)
1205 			m_pApi->release(m_hImpl);
1206 		return m_pApi->createRegistry(registryName.pData, &m_hImpl);
1207 	}
1208 
1209 inline RegError Registry::open(const ::rtl::OUString& registryName,
1210 				   			   RegAccessMode accessMode)
1211 	{
1212 		if (m_hImpl)
1213 			m_pApi->release(m_hImpl);
1214 		return m_pApi->openRegistry(registryName.pData, &m_hImpl, accessMode);
1215 	}
1216 
1217 inline RegError Registry::close()
1218 	{
1219 		RegError ret = m_pApi->closeRegistry(m_hImpl);
1220 		if (!ret)
1221 			m_hImpl = NULL;
1222 		return ret;
1223 	}
1224 
1225 inline RegError Registry::destroy(const ::rtl::OUString& registryName)
1226 	{
1227 		RegError ret = m_pApi->destroyRegistry(m_hImpl, registryName.pData);
1228 		if ( !ret && (registryName.getLength() == 0) )
1229 			m_hImpl = NULL;
1230 		return ret;
1231 	}
1232 
1233 inline RegError Registry::loadKey(RegistryKey& rKey,
1234 			  			 		   const ::rtl::OUString& keyName,
1235 			  			 		   const ::rtl::OUString& regFileName)
1236 	{  return m_pApi->loadKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData); }
1237 
1238 inline RegError Registry::saveKey(RegistryKey& rKey,
1239 			  			 		  const ::rtl::OUString& keyName,
1240 			  			 		  const ::rtl::OUString& regFileName)
1241 	{  return m_pApi->saveKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData); }
1242 
1243 inline RegError Registry::mergeKey(RegistryKey& rKey,
1244 			   			  			const ::rtl::OUString& keyName,
1245 			   			  			const ::rtl::OUString& regFileName,
1246 			   			  			sal_Bool bWarnings,
1247 			   			  			sal_Bool bReport)
1248 	{  return m_pApi->mergeKey(m_hImpl, rKey.m_hImpl, keyName.pData, regFileName.pData, bWarnings, bReport); }
1249 
1250 inline RegError Registry::dumpRegistry(RegistryKey& rKey)
1251 	{  return m_pApi->dumpRegistry(m_hImpl, rKey.m_hImpl); }
1252 
1253 
1254 #endif
1255