1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <registry/registry.hxx>
22 
23 #include "keyimpl.hxx"
24 #include "regimpl.hxx"
25 #include "regkey.hxx"
26 
27 #if defined(_WIN32)
28 #include <io.h>
29 #endif
30 
31 extern "C" {
32 
33 
34 //  acquire
35 
acquire(RegHandle hReg)36 static void REGISTRY_CALLTYPE acquire(RegHandle hReg)
37 {
38     ORegistry* pReg = static_cast<ORegistry*>(hReg);
39 
40     if (pReg != nullptr)
41         pReg->acquire();
42 }
43 
44 
45 //  release
46 
release(RegHandle hReg)47 static void REGISTRY_CALLTYPE release(RegHandle hReg)
48 {
49     ORegistry* pReg = static_cast<ORegistry*>(hReg);
50 
51     if (pReg && pReg->release() == 0)
52     {
53         delete pReg;
54         hReg = nullptr;
55     }
56 }
57 
58 
59 //  getName
60 
getName(RegHandle hReg,rtl_uString ** pName)61 static RegError REGISTRY_CALLTYPE getName(RegHandle hReg, rtl_uString** pName)
62 {
63     if (hReg)
64     {
65         ORegistry*  pReg = static_cast<ORegistry*>(hReg);
66         if ( pReg->isOpen() )
67         {
68             rtl_uString_assign(pName, pReg->getName().pData);
69             return RegError::NO_ERROR;
70         } else
71         {
72             rtl_uString_new(pName);
73             return RegError::REGISTRY_NOT_OPEN;
74         }
75     }
76 
77     rtl_uString_new(pName);
78     return RegError::INVALID_REGISTRY;
79 }
80 
81 
82 //  isReadOnly
83 
isReadOnly(RegHandle hReg)84 static sal_Bool REGISTRY_CALLTYPE isReadOnly(RegHandle hReg)
85 {
86     if (hReg)
87         return static_cast<ORegistry*>(hReg)->isReadOnly();
88     else
89         return false;
90 }
91 
92 
93 //  createRegistry
94 
createRegistry(rtl_uString * registryName,RegHandle * phRegistry)95 static RegError REGISTRY_CALLTYPE createRegistry(rtl_uString* registryName,
96                                                  RegHandle* phRegistry)
97 {
98     RegError ret;
99 
100     ORegistry* pReg = new ORegistry();
101     if ((ret = pReg->initRegistry(registryName, RegAccessMode::READWRITE, true/*bCreate*/)) != RegError::NO_ERROR)
102     {
103         delete pReg;
104         *phRegistry = nullptr;
105         return ret;
106     }
107 
108     *phRegistry = pReg;
109 
110     return RegError::NO_ERROR;
111 }
112 
113 
114 //  openRootKey
115 
openRootKey(RegHandle hReg,RegKeyHandle * phRootKey)116 static RegError REGISTRY_CALLTYPE openRootKey(RegHandle hReg,
117                                               RegKeyHandle* phRootKey)
118 {
119     ORegistry* pReg;
120 
121     if (hReg)
122     {
123         pReg = static_cast<ORegistry*>(hReg);
124         if (!pReg->isOpen())
125             return RegError::REGISTRY_NOT_OPEN;
126     } else
127     {
128         phRootKey = nullptr;
129         return RegError::INVALID_REGISTRY;
130     }
131 
132     *phRootKey = pReg->getRootKey();
133 
134     return RegError::NO_ERROR;
135 }
136 
137 
138 //  openRegistry
139 
openRegistry(rtl_uString * registryName,RegHandle * phRegistry,RegAccessMode accessMode)140 static RegError REGISTRY_CALLTYPE openRegistry(rtl_uString* registryName,
141                                                RegHandle* phRegistry,
142                                                RegAccessMode accessMode)
143 {
144     RegError _ret;
145 
146     ORegistry* pReg = new ORegistry();
147     if ((_ret = pReg->initRegistry(registryName, accessMode)) != RegError::NO_ERROR)
148     {
149         *phRegistry = nullptr;
150         delete pReg;
151         return _ret;
152     }
153 
154 
155     *phRegistry = pReg;
156 
157     return RegError::NO_ERROR;
158 }
159 
160 
161 //  closeRegistry
162 
closeRegistry(RegHandle hReg)163 static RegError REGISTRY_CALLTYPE closeRegistry(RegHandle hReg)
164 {
165     ORegistry   *pReg;
166 
167     if (hReg)
168     {
169         pReg = static_cast<ORegistry*>(hReg);
170         if (!pReg->isOpen())
171             return RegError::REGISTRY_NOT_OPEN;
172 
173         RegError ret = RegError::NO_ERROR;
174         if (pReg->release() == 0)
175         {
176             delete pReg;
177             hReg = nullptr;
178         }
179         else
180             ret = pReg->closeRegistry();
181 
182         return ret;
183     } else
184     {
185         return RegError::INVALID_REGISTRY;
186     }
187 }
188 
189 
190 //  destroyRegistry
191 
destroyRegistry(RegHandle hReg,rtl_uString * registryName)192 static RegError REGISTRY_CALLTYPE destroyRegistry(RegHandle hReg,
193                                                   rtl_uString* registryName)
194 {
195     ORegistry   *pReg;
196 
197     if (hReg)
198     {
199         pReg = static_cast<ORegistry*>(hReg);
200         if (!pReg->isOpen())
201             return RegError::INVALID_REGISTRY;
202 
203         RegError ret = pReg->destroyRegistry(registryName);
204         if (ret == RegError::NO_ERROR)
205         {
206             if (!registryName->length)
207             {
208                 delete pReg;
209                 hReg = nullptr;
210             }
211         }
212         return ret;
213     } else
214     {
215         return RegError::INVALID_REGISTRY;
216     }
217 }
218 
219 
220 //  mergeKey
221 
mergeKey(RegHandle hReg,RegKeyHandle hKey,rtl_uString * keyName,rtl_uString * regFileName,sal_Bool bWarnings,sal_Bool bReport)222 static RegError REGISTRY_CALLTYPE mergeKey(RegHandle hReg,
223                                               RegKeyHandle hKey,
224                                            rtl_uString* keyName,
225                                            rtl_uString* regFileName,
226                                            sal_Bool bWarnings,
227                                            sal_Bool bReport)
228 {
229     ORegistry* pReg = static_cast< ORegistry* >(hReg);
230     if (!pReg)
231         return RegError::INVALID_REGISTRY;
232     if (!pReg->isOpen())
233         return RegError::REGISTRY_NOT_OPEN;
234 
235     ORegKey* pKey = static_cast< ORegKey* >(hKey);
236     if (!pKey)
237         return RegError::INVALID_KEY;
238     if (pKey->getRegistry() != pReg)
239         return RegError::INVALID_KEY;
240     if (pKey->isDeleted())
241         return RegError::INVALID_KEY;
242     if (pKey->isReadOnly())
243         return RegError::REGISTRY_READONLY;
244 
245     if (keyName->length)
246     {
247         ORegKey* pNewKey = nullptr;
248         RegError _ret = pKey->createKey(keyName, reinterpret_cast<RegKeyHandle*>(&pNewKey));
249         if (_ret != RegError::NO_ERROR)
250             return _ret;
251 
252         _ret = pReg->loadKey(pNewKey, regFileName, bWarnings, bReport);
253         if (_ret != RegError::NO_ERROR && (_ret != RegError::MERGE_CONFLICT || bWarnings))
254         {
255             if (pNewKey != pKey)
256                 (void) pKey->closeKey(pNewKey);
257             else
258                 (void) pKey->releaseKey(pNewKey);
259             return _ret;
260         }
261 
262         return (pNewKey != pKey) ? pKey->closeKey(pNewKey) : pKey->releaseKey(pNewKey);
263     }
264 
265     return pReg->loadKey(pKey, regFileName, bWarnings, bReport);
266 }
267 
268 
269 //  dumpRegistry
270 
dumpRegistry(RegHandle hReg,RegKeyHandle hKey)271 static RegError REGISTRY_CALLTYPE dumpRegistry(RegHandle hReg,
272                                                RegKeyHandle hKey)
273 {
274     ORegistry* pReg = static_cast< ORegistry* >(hReg);
275     if (!pReg)
276         return RegError::INVALID_REGISTRY;
277     if (!pReg->isOpen())
278         return RegError::REGISTRY_NOT_OPEN;
279 
280     ORegKey* pKey = static_cast< ORegKey* >(hKey);
281     if (!pKey)
282         return RegError::INVALID_KEY;
283     if (pKey->getRegistry() != pReg)
284         return RegError::INVALID_KEY;
285     if (pKey->isDeleted())
286         return RegError::INVALID_KEY;
287 
288     return pReg->dumpRegistry(hKey);
289 }
290 
291 
292 //  initRegistry_Api
293 
initRegistry_Api()294 Registry_Api* REGISTRY_CALLTYPE initRegistry_Api()
295 {
296     static Registry_Api aApi= {&acquire,
297                                &release,
298                                &isReadOnly,
299                                &openRootKey,
300                                &getName,
301                                &createRegistry,
302                                &openRegistry,
303                                &closeRegistry,
304                                &destroyRegistry,
305                                &mergeKey,
306                                &acquireKey,
307                                &releaseKey,
308                                &isKeyReadOnly,
309                                &getKeyName,
310                                &createKey,
311                                &openKey,
312                                &openSubKeys,
313                                &closeSubKeys,
314                                &deleteKey,
315                                &closeKey,
316                                &setValue,
317                                &setLongListValue,
318                                &setStringListValue,
319                                &setUnicodeListValue,
320                                &getValueInfo,
321                                &getValue,
322                                &getLongListValue,
323                                &getStringListValue,
324                                &getUnicodeListValue,
325                                &freeValueList,
326                                &getResolvedKeyName,
327                                &getKeyNames,
328                                &freeKeyNames};
329 
330     return (&aApi);
331 }
332 
333 }
334 
335 
336 //  reg_openRootKey
337 
reg_openRootKey(RegHandle hRegistry,RegKeyHandle * phRootKey)338 RegError REGISTRY_CALLTYPE reg_openRootKey(RegHandle hRegistry,
339                                           RegKeyHandle* phRootKey)
340 {
341     return openRootKey(hRegistry, phRootKey);
342 }
343 
344 
345 //  reg_openRegistry
346 
reg_openRegistry(rtl_uString * registryName,RegHandle * phRegistry)347 RegError REGISTRY_CALLTYPE reg_openRegistry(rtl_uString* registryName,
348                                             RegHandle* phRegistry)
349 {
350     RegError _ret;
351 
352     ORegistry* pReg = new ORegistry();
353     if ((_ret = pReg->initRegistry(registryName, RegAccessMode::READONLY)) != RegError::NO_ERROR)
354     {
355         delete pReg;
356         *phRegistry = nullptr;
357         return _ret;
358     }
359 
360     *phRegistry = pReg;
361 
362     return RegError::NO_ERROR;
363 }
364 
365 
366 //  reg_closeRegistry
367 
reg_closeRegistry(RegHandle hRegistry)368 RegError REGISTRY_CALLTYPE reg_closeRegistry(RegHandle hRegistry)
369 {
370     if (hRegistry)
371     {
372         ORegistry* pReg = static_cast<ORegistry*>(hRegistry);
373         delete pReg;
374         return RegError::NO_ERROR;
375     } else
376     {
377         return RegError::REGISTRY_NOT_OPEN;
378     }
379 }
380 
381 
382 //  reg_dumpRegistry
383 
reg_dumpRegistry(RegKeyHandle hKey)384 RegError REGISTRY_CALLTYPE reg_dumpRegistry(RegKeyHandle hKey)
385 {
386     ORegKey *pKey;
387 
388     if (hKey)
389         pKey = static_cast<ORegKey*>(hKey);
390     else
391         return RegError::INVALID_KEY;
392 
393     return dumpRegistry(pKey->getRegistry(), hKey);
394 }
395 
396 
397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
398