xref: /trunk/main/registry/source/registry.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_registry.hxx"
30 
31 #include <registry/registry.h>
32 #include <registry/registry.hxx>
33 #include <osl/process.h>
34 
35 #include "keyimpl.hxx"
36 #include "regimpl.hxx"
37 #include "regkey.hxx"
38 
39 #if defined(WIN32) || defined(WNT) || defined(OS2)
40 #include <io.h>
41 #endif
42 
43 #include <string.h>
44 #if defined(UNX)
45 #include <stdlib.h>
46 #include <unistd.h>
47 #endif
48 
49 #if defined ( GCC ) && ( defined ( SCO ) )
50 ORealDynamicLoader* ODynamicLoader<Registry_Api>::m_pLoader = NULL;
51 #endif
52 
53 extern "C" {
54 
55 //*********************************************************************
56 //	acquire
57 //
58 static void REGISTRY_CALLTYPE acquire(RegHandle hReg)
59 {
60 	ORegistry* pReg = (ORegistry*) hReg;
61 
62 	if (pReg != NULL)
63 		pReg->acquire();
64 }
65 
66 
67 //*********************************************************************
68 //	release
69 //
70 static void REGISTRY_CALLTYPE release(RegHandle hReg)
71 {
72 	ORegistry* pReg = (ORegistry*) hReg;
73 
74 	if (pReg)
75 	{
76 		if (pReg->release() == 0)
77 		{
78 			delete pReg;
79 			hReg = NULL;
80 		}
81 	}
82 }
83 
84 
85 //*********************************************************************
86 //	getName
87 //
88 static RegError REGISTRY_CALLTYPE getName(RegHandle hReg, rtl_uString** pName)
89 {
90 	ORegistry* 	pReg;
91 
92 	if (hReg)
93 	{
94 		pReg = (ORegistry*)hReg;
95 		if ( pReg->isOpen() )
96 		{
97 			rtl_uString_assign(pName, pReg->getName().pData);
98 			return REG_NO_ERROR;
99 		} else
100 		{
101 			rtl_uString_new(pName);
102 			return REG_REGISTRY_NOT_OPEN;
103 		}
104 	}
105 
106 	rtl_uString_new(pName);
107 	return REG_INVALID_REGISTRY;
108 }
109 
110 
111 //*********************************************************************
112 //	isReadOnly
113 //
114 static sal_Bool REGISTRY_CALLTYPE isReadOnly(RegHandle hReg)
115 {
116 	if (hReg)
117 		return ((ORegistry*)hReg)->isReadOnly();
118 	else
119 		return sal_False;
120 }
121 
122 
123 //*********************************************************************
124 //	createRegistry
125 //
126 static RegError REGISTRY_CALLTYPE createRegistry(rtl_uString* registryName,
127 											     RegHandle* phRegistry)
128 {
129 	RegError ret;
130 
131 	ORegistry* pReg = new ORegistry();
132 	if ((ret = pReg->initRegistry(registryName, REG_CREATE)))
133 	{
134 		*phRegistry = NULL;
135 		return ret;
136 	}
137 
138 	*phRegistry = pReg;
139 
140 	return REG_NO_ERROR;
141 }
142 
143 //*********************************************************************
144 //	openRootKey
145 //
146 static RegError REGISTRY_CALLTYPE openRootKey(RegHandle hReg,
147 											  RegKeyHandle* phRootKey)
148 {
149 	ORegistry* pReg;
150 
151 	if (hReg)
152 	{
153 		pReg = (ORegistry*)hReg;
154 		if (!pReg->isOpen())
155 			return REG_REGISTRY_NOT_OPEN;
156 	} else
157 	{
158 		phRootKey = NULL;
159 		return REG_INVALID_REGISTRY;
160 	}
161 
162 	*phRootKey = pReg->getRootKey();
163 
164 	return REG_NO_ERROR;
165 }
166 
167 
168 //*********************************************************************
169 //	openRegistry
170 //
171 static RegError REGISTRY_CALLTYPE openRegistry(rtl_uString* registryName,
172 											   RegHandle* phRegistry,
173 											   RegAccessMode accessMode)
174 {
175 	RegError _ret;
176 
177 	ORegistry* pReg = new ORegistry();
178 	if ((_ret = pReg->initRegistry(registryName, accessMode)))
179 	{
180 		*phRegistry = NULL;
181 		delete pReg;
182 		return _ret;
183 	}
184 
185 
186 	*phRegistry = pReg;
187 
188 	return REG_NO_ERROR;
189 }
190 
191 //*********************************************************************
192 //	closeRegistry
193 //
194 static RegError REGISTRY_CALLTYPE closeRegistry(RegHandle hReg)
195 {
196 	ORegistry	*pReg;
197 
198 	if (hReg)
199 	{
200 		pReg = (ORegistry*)hReg;
201 		if (!pReg->isOpen())
202 			return REG_REGISTRY_NOT_OPEN;
203 
204 		RegError ret = REG_NO_ERROR;
205 		if (pReg->release() == 0)
206 		{
207 			delete(pReg);
208 			hReg = NULL;
209 		}
210 		else
211 			ret = pReg->closeRegistry();
212 
213 		return ret;
214 	} else
215 	{
216 		return REG_INVALID_REGISTRY;
217 	}
218 }
219 
220 
221 //*********************************************************************
222 //	destroyRegistry
223 //
224 static RegError REGISTRY_CALLTYPE destroyRegistry(RegHandle hReg,
225 												  rtl_uString* registryName)
226 {
227 	ORegistry	*pReg;
228 
229 	if (hReg)
230 	{
231 		pReg = (ORegistry*)hReg;
232 		if (!pReg->isOpen())
233 			return REG_INVALID_REGISTRY;
234 
235 		RegError ret = pReg->destroyRegistry(registryName);
236 		if (!ret)
237 		{
238 			if (!registryName->length)
239 			{
240 				delete(pReg);
241 				hReg = NULL;
242 			}
243 		}
244 		return ret;
245 	} else
246 	{
247 		return REG_INVALID_REGISTRY;
248 	}
249 }
250 
251 
252 //*********************************************************************
253 //	loadRegKey
254 //
255 static RegError REGISTRY_CALLTYPE loadKey(RegHandle hReg,
256 								   		   RegKeyHandle hKey,
257 										   rtl_uString* keyName,
258 										   rtl_uString* regFileName)
259 {
260 
261 	ORegistry* pReg = static_cast< ORegistry* >(hReg);
262 	if (!pReg)
263 		return REG_INVALID_REGISTRY;
264 
265 	if (!pReg->isOpen())
266 		return REG_REGISTRY_NOT_OPEN;
267 
268 	ORegKey* pKey = static_cast< ORegKey* >(hKey);
269 	if (!pKey)
270 		return REG_INVALID_KEY;
271 
272 	if (pKey->getRegistry() != pReg)
273 		return REG_INVALID_KEY;
274 	if (pKey->isDeleted())
275 		return REG_INVALID_KEY;
276 	if (pKey->isReadOnly())
277 		return REG_REGISTRY_READONLY;
278 
279 
280 	ORegKey* pNewKey = 0;
281 	RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pNewKey);
282 	if (_ret == REG_NO_ERROR)
283 	{
284 		pKey->releaseKey(pNewKey);
285 		pKey->deleteKey(keyName);
286 	}
287 
288 	_ret = pKey->createKey(keyName, (RegKeyHandle*)&pNewKey);
289 	if (_ret != REG_NO_ERROR)
290 		return _ret;
291 
292 	_ret = pReg->loadKey(pNewKey, regFileName);
293 	if (_ret != REG_NO_ERROR)
294 	{
295 		pKey->releaseKey(pNewKey);
296 		pKey->deleteKey(keyName);
297 		return _ret;
298 	}
299 
300 	return pKey->closeKey(pNewKey);
301 }
302 
303 //*********************************************************************
304 //	saveKey
305 //
306 static RegError REGISTRY_CALLTYPE saveKey(RegHandle hReg,
307 								   		   RegKeyHandle hKey,
308 										   rtl_uString* keyName,
309 										   rtl_uString* regFileName)
310 {
311 
312 	ORegistry* pReg = static_cast< ORegistry* >(hReg);
313 	if (!pReg)
314 		return REG_INVALID_REGISTRY;
315 
316 	if (!pReg->isOpen())
317 		return REG_REGISTRY_NOT_OPEN;
318 
319 	ORegKey* pKey = static_cast< ORegKey* >(hKey);
320 	if (!pKey)
321 		return REG_INVALID_KEY;
322 
323 	if (pKey->getRegistry() != pReg)
324 		return REG_INVALID_KEY;
325 	if (pKey->isDeleted())
326 		return REG_INVALID_KEY;
327 
328 	ORegKey* pNewKey = 0;
329 	RegError _ret = pKey->openKey(keyName, (RegKeyHandle*)&pNewKey);
330 	if (_ret != REG_NO_ERROR)
331 		return _ret;
332 
333 	_ret = pReg->saveKey(pNewKey, regFileName);
334 	if (_ret != REG_NO_ERROR)
335 	{
336 		(void) pKey->releaseKey(pNewKey);
337 		return _ret;
338 	}
339 
340 	return pKey->releaseKey(pNewKey);
341 }
342 
343 //*********************************************************************
344 //	mergeKey
345 //
346 static RegError REGISTRY_CALLTYPE mergeKey(RegHandle hReg,
347 								   		   RegKeyHandle hKey,
348 										   rtl_uString* keyName,
349 										   rtl_uString* regFileName,
350 										   sal_Bool bWarnings,
351 										   sal_Bool bReport)
352 {
353 	ORegistry* pReg = static_cast< ORegistry* >(hReg);
354 	if (!pReg)
355 		return REG_INVALID_REGISTRY;
356 	if (!pReg->isOpen())
357 		return REG_REGISTRY_NOT_OPEN;
358 
359 	ORegKey* pKey = static_cast< ORegKey* >(hKey);
360 	if (!pKey)
361 		return REG_INVALID_KEY;
362 	if (pKey->getRegistry() != pReg)
363 		return REG_INVALID_KEY;
364 	if (pKey->isDeleted())
365 		return REG_INVALID_KEY;
366 	if (pKey->isReadOnly())
367 		return REG_REGISTRY_READONLY;
368 
369 	if (keyName->length)
370 	{
371 		ORegKey* pNewKey = 0;
372 		RegError _ret = pKey->createKey(keyName, (RegKeyHandle*)&pNewKey);
373 		if (_ret != REG_NO_ERROR)
374 			return _ret;
375 
376 		_ret = pReg->loadKey(pNewKey, regFileName, bWarnings, bReport);
377 		if (_ret == REG_MERGE_ERROR || (_ret == REG_MERGE_CONFLICT && bWarnings))
378 		{
379 			if (pNewKey != pKey)
380 				(void) pKey->closeKey(pNewKey);
381 			else
382 				(void) pKey->releaseKey(pNewKey);
383 			return _ret;
384 		}
385 
386 		return (pNewKey != pKey) ? pKey->closeKey(pNewKey) : pKey->releaseKey(pNewKey);
387 	}
388 
389 	return pReg->loadKey(pKey, regFileName, bWarnings, bReport);
390 }
391 
392 //*********************************************************************
393 //	dumpRegistry
394 //
395 static RegError REGISTRY_CALLTYPE dumpRegistry(RegHandle hReg,
396 											   RegKeyHandle hKey)
397 {
398 	ORegistry* pReg = static_cast< ORegistry* >(hReg);
399 	if (!pReg)
400 		return REG_INVALID_REGISTRY;
401 	if (!pReg->isOpen())
402 		return REG_REGISTRY_NOT_OPEN;
403 
404 	ORegKey* pKey = static_cast< ORegKey* >(hKey);
405 	if (!pKey)
406 		return REG_INVALID_KEY;
407 	if (pKey->getRegistry() != pReg)
408 		return REG_INVALID_KEY;
409 	if (pKey->isDeleted())
410 		return REG_INVALID_KEY;
411 
412 	return pReg->dumpRegistry(hKey);
413 }
414 
415 //*********************************************************************
416 //	initRegistry_Api
417 //
418 Registry_Api* REGISTRY_CALLTYPE initRegistry_Api(void)
419 {
420 	static Registry_Api aApi= {&acquire,
421 							   &release,
422 							   &isReadOnly,
423 							   &openRootKey,
424 							   &getName,
425 							   &createRegistry,
426 							   &openRegistry,
427 							   &closeRegistry,
428 							   &destroyRegistry,
429 							   &loadKey,
430 							   &saveKey,
431 							   &mergeKey,
432 							   &dumpRegistry,
433 							   &acquireKey,
434 							   &releaseKey,
435 							   &isKeyReadOnly,
436 							   &getKeyName,
437 							   &createKey,
438 							   &openKey,
439 							   &openSubKeys,
440 							   &closeSubKeys,
441 							   &deleteKey,
442 							   &closeKey,
443 							   &setValue,
444 							   &setLongListValue,
445 							   &setStringListValue,
446 							   &setUnicodeListValue,
447 							   &getValueInfo,
448 							   &getValue,
449 							   &getLongListValue,
450 							   &getStringListValue,
451 							   &getUnicodeListValue,
452 							   &freeValueList,
453 							   &createLink,
454 							   &deleteLink,
455 							   &getKeyType,
456 							   &getLinkTarget,
457 							   &getResolvedKeyName,
458 							   &getKeyNames,
459 							   &freeKeyNames};
460 
461 	return (&aApi);
462 }
463 
464 }
465 
466 //*********************************************************************
467 //	reg_loadRegKey
468 //
469 RegError REGISTRY_CALLTYPE reg_loadKey(RegKeyHandle hKey,
470 									   rtl_uString* keyName,
471 									   rtl_uString* regFileName)
472 {
473 	ORegKey *pKey;
474 
475 	if (hKey)
476 		pKey = (ORegKey*)hKey;
477 	else
478 		return REG_INVALID_KEY;
479 
480 	return loadKey(pKey->getRegistry(), hKey, keyName, regFileName);
481 }
482 
483 //*********************************************************************
484 //	reg_saveKey
485 //
486 RegError REGISTRY_CALLTYPE reg_saveKey(RegKeyHandle hKey,
487 									   rtl_uString* keyName,
488 									   rtl_uString* regFileName)
489 {
490 	ORegKey *pKey;
491 
492 	if (hKey)
493 		pKey = (ORegKey*)hKey;
494 	else
495 		return REG_INVALID_KEY;
496 
497 	return saveKey(pKey->getRegistry(), hKey, keyName, regFileName);
498 }
499 
500 //*********************************************************************
501 //	reg_mergeKey
502 //
503 RegError REGISTRY_CALLTYPE reg_mergeKey(RegKeyHandle hKey,
504 									    rtl_uString* keyName,
505 									    rtl_uString* regFileName,
506 										sal_Bool bWarnings,
507 										sal_Bool bReport)
508 {
509 	ORegKey *pKey;
510 
511 	if (hKey)
512 		pKey = (ORegKey*)hKey;
513 	else
514 		return REG_INVALID_KEY;
515 
516 	return mergeKey(pKey->getRegistry(), hKey, keyName, regFileName, bWarnings, bReport);
517 }
518 
519 //*********************************************************************
520 //	reg_createRegistry
521 //
522 RegError REGISTRY_CALLTYPE reg_createRegistry(rtl_uString* registryName,
523 											  RegHandle* phRegistry)
524 {
525 	RegError ret;
526 
527 	ORegistry* pReg = new ORegistry();
528 	if ((ret = pReg->initRegistry(registryName, REG_CREATE)))
529 	{
530 		*phRegistry = NULL;
531 		return ret;
532 	}
533 
534 	*phRegistry = pReg;
535 
536 	return REG_NO_ERROR;
537 }
538 
539 //*********************************************************************
540 //	reg_openRootKey
541 //
542 RegError REGISTRY_CALLTYPE reg_openRootKey(RegHandle hRegistry,
543 										  RegKeyHandle* phRootKey)
544 {
545 	return openRootKey(hRegistry, phRootKey);
546 }
547 
548 
549 //*********************************************************************
550 //	reg_getName
551 //
552 RegError REGISTRY_CALLTYPE reg_getName(RegHandle hRegistry, rtl_uString** pName)
553 {
554 	return getName(hRegistry, pName);
555 }
556 
557 
558 //*********************************************************************
559 //	reg_isReadOnly
560 //
561 sal_Bool REGISTRY_CALLTYPE reg_isReadOnly(RegHandle hRegistry)
562 {
563 	return isReadOnly(hRegistry);
564 }
565 
566 
567 //*********************************************************************
568 //	reg_openRegistry
569 //
570 RegError REGISTRY_CALLTYPE reg_openRegistry(rtl_uString* registryName,
571 											RegHandle* phRegistry,
572 											RegAccessMode accessMode)
573 {
574 	RegError _ret;
575 
576 	ORegistry* pReg = new ORegistry();
577 	if ((_ret = pReg->initRegistry(registryName, accessMode)))
578 	{
579 		*phRegistry = NULL;
580 		return _ret;
581 	}
582 
583 	*phRegistry = pReg;
584 
585 	return REG_NO_ERROR;
586 }
587 
588 //*********************************************************************
589 //	reg_closeRegistry
590 //
591 RegError REGISTRY_CALLTYPE reg_closeRegistry(RegHandle hRegistry)
592 {
593 	ORegistry* pReg;
594 
595 	if (hRegistry)
596 	{
597 		pReg = (ORegistry*)hRegistry;
598 		delete(pReg);
599 		return REG_NO_ERROR;
600 	} else
601 	{
602 		return REG_REGISTRY_NOT_OPEN;
603 	}
604 }
605 
606 
607 //*********************************************************************
608 //	reg_destroyRegistry
609 //
610 RegError REGISTRY_CALLTYPE reg_destroyRegistry(RegHandle hRegistry,
611 											   rtl_uString* registryName)
612 {
613 	return destroyRegistry(hRegistry, registryName);
614 }
615 
616 
617 //*********************************************************************
618 //	reg_dumpRegistry
619 //
620 RegError REGISTRY_CALLTYPE reg_dumpRegistry(RegKeyHandle hKey)
621 {
622 	ORegKey *pKey;
623 
624 	if (hKey)
625 		pKey = (ORegKey*)hKey;
626 	else
627 		return REG_INVALID_KEY;
628 
629 	return dumpRegistry(pKey->getRegistry(), hKey);
630 }
631 
632 
633