xref: /AOO41X/main/setup_native/source/win32/customactions/reg4msdoc/registry.cxx (revision 32b1fd08cf0851da51c0ed68f50bc63c4ee660e0)
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 #include "registry.hxx"
25 
26 #include <Shlwapi.h>
27 #include <assert.h>
28 #include <algorithm>
29 
30 #ifdef _MSC_VER
31 #pragma warning(disable : 4786 4350)
32 #endif
33 
34 //-----------------------------------------------------
35 /** Create instance and open the specified Registry key
36 
37     @throws  RegistryWriteAccessDenyException
38              RegistryAccessDenyException
39              RegistryKeyNotFoundException
40 */
RegistryKeyImpl(HKEY RootKey,const std::wstring & KeyName)41 RegistryKeyImpl::RegistryKeyImpl(HKEY RootKey, const std::wstring& KeyName) :
42     m_hRootKey(RootKey),
43     m_hSubKey(0),
44     m_KeyName(KeyName),
45     m_IsWriteable(false)
46 {
47 }
48 
49 //-----------------------------------------------------
50 /** Create instance and open the specified Registry key
51 
52     @throws  RegistryWriteAccessDenyException
53              RegistryAccessDenyException
54              RegistryKeyNotFoundException
55 */
RegistryKeyImpl(HKEY RootKey)56 RegistryKeyImpl::RegistryKeyImpl(HKEY RootKey) :
57     m_hRootKey(RootKey),
58     m_hSubKey(0),
59     m_IsWriteable(false)
60 {
61 }
62 
63 //-----------------------------------------------------
64 /** Create an instances of the specified Registry key,
65     the key is assumed to be already opened.
66 */
RegistryKeyImpl(HKEY RootKey,HKEY SubKey,const std::wstring & KeyName,bool Writeable)67 RegistryKeyImpl::RegistryKeyImpl(HKEY RootKey, HKEY SubKey, const std::wstring& KeyName, bool Writeable) :
68     m_hRootKey(RootKey),
69     m_hSubKey(SubKey),
70     m_KeyName(KeyName),
71     m_IsWriteable(Writeable)
72 {
73 }
74 
75 //-----------------------------------------------------
76 /**
77 */
~RegistryKeyImpl()78 RegistryKeyImpl::~RegistryKeyImpl()
79 {
80     if (IsOpen())
81         Close();
82 }
83 
84 
85 //############################################
86 // Queries
87 //############################################
88 
89 
90 //-----------------------------------------------------
91 /** The name of the key at hand, maybe empty
92     if this is any of the root keys
93 */
GetName() const94 std::wstring RegistryKeyImpl::GetName() const
95 {
96     return m_KeyName;
97 }
98 
99 //-----------------------------------------------------
100 /**
101 */
IsOpen() const102 bool RegistryKeyImpl::IsOpen() const
103 {
104     return m_hSubKey != 0;
105 }
106 
107 //-----------------------------------------------------
108 /** Is this one of the root keys
109     HKEY_CLASSES_ROOT
110     HKEY_CURRENT_USER
111     etc.
112 */
IsRootKey() const113 bool RegistryKeyImpl::IsRootKey() const
114 {
115     return (0 == m_KeyName.length());
116 }
117 
118 //-----------------------------------------------------
119 /** Do we have write access on the key at hand
120 */
IsWriteable() const121 bool RegistryKeyImpl::IsWriteable() const
122 {
123     return m_IsWriteable;
124 }
125 
126 //-----------------------------------------------------
127 /** Convenience function to determine if the
128     Registry key at hand has the specified
129     value
130 
131     @precond IsOpen = true
132 
133     throws RegistryAccessDenyException
134 */
HasValue(const std::wstring & Name) const135 bool RegistryKeyImpl::HasValue(const std::wstring& Name) const
136 {
137     StringListPtr names = GetSubValueNames();
138 
139     StringList::iterator iter_end = names->end();
140     StringList::iterator iter = std::find(names->begin(), iter_end, Name);
141 
142     return (iter != iter_end);
143 }
144 
145 struct CompareNamesCaseInsensitive
146 {
CompareNamesCaseInsensitiveCompareNamesCaseInsensitive147     CompareNamesCaseInsensitive(const std::wstring& Name) :
148         name_(Name)
149     {}
150 
operator ()CompareNamesCaseInsensitive151     bool operator() (const std::wstring& value)
152     {
153         return (0 == StrCmpI(value.c_str(), name_.c_str()));
154     }
155 
156     std::wstring name_;
157 };
158 
159 //-----------------------------------------------------
160 /** Convenience function to determine if the
161     Registry key at hand has the specified
162     sub-key
163 
164     @precond IsOpen = true
165 
166     throws RegistryAccessDenyException
167 */
HasSubKey(const std::wstring & Name) const168 bool RegistryKeyImpl::HasSubKey(const std::wstring& Name) const
169 {
170     StringListPtr names = GetSubKeyNames();
171 
172     StringList::iterator iter_end = names->end();
173     StringList::iterator iter = std::find_if(names->begin(), iter_end, CompareNamesCaseInsensitive(Name));
174 
175     return (iter != iter_end);
176 }
177 
178 //-----------------------------------------------------
179 /**
180 */
Close()181 void RegistryKeyImpl::Close()
182 {
183     if (RegCloseKey(m_hSubKey) != ERROR_SUCCESS) {
184         assert(false);
185     }
186 
187     m_hSubKey = 0;
188     m_IsWriteable = false;
189 }
190 
191 //-----------------------------------------------------
192 /** Copies the specified value from RegistryKey to
193     the registry key at hand, if a value with this
194     name already exist under the registry key at hand
195     it will be overwritten
196 
197     @precond IsOpen = true
198              IsWriteable = true
199              RegistryKey.HasSubValue(Name) = true
200 
201     @throws RegistryIOException
202             RegistryWriteAccessDeniedException
203             RegistryValueNotFoundException
204 */
CopyValue(const RegistryKey & RegistryKey,const std::wstring & Name)205 void RegistryKeyImpl::CopyValue(const RegistryKey& RegistryKey, const std::wstring& Name)
206 {
207     assert(RegistryKey->HasValue(Name));
208 #ifdef __MINGW32__
209     SetValue((const RegistryValue&)(RegistryKey->GetValue(Name)));
210 #else
211     SetValue(RegistryKey->GetValue(Name));
212 #endif
213     assert(HasValue(Name));
214 }
215 
216 /** Copies the specified value from RegistryKey to
217     the registry key at hand under a new name,
218     if a value with this name already exist there
219     it will be overwritten
220 
221     @precond IsOpen = true
222              IsWriteable = true
223              RegistryKey.HasSubValue(Name) = true
224 
225     @throws RegistryIOException
226             RegistryWriteAccessDeniedException
227             RegistryValueNotFoundException
228 */
CopyValue(const RegistryKey & RegistryKey,const std::wstring & Name,const std::wstring & NewName)229 void RegistryKeyImpl::CopyValue(const RegistryKey& RegistryKey, const std::wstring& Name, const std::wstring& NewName)
230 {
231     assert(RegistryKey->HasValue(Name));
232 
233     RegistryValue RegVal = RegistryKey->GetValue(Name);
234     RegVal->SetName(NewName);
235     SetValue(RegVal);
236 
237     assert(HasValue(NewName));
238 }
239