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 */ 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 */ 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 */ 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 */ 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 */ 94 std::wstring RegistryKeyImpl::GetName() const 95 { 96 return m_KeyName; 97 } 98 99 //----------------------------------------------------- 100 /** 101 */ 102 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 */ 113 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 */ 121 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 */ 135 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 { 147 CompareNamesCaseInsensitive(const std::wstring& Name) : 148 name_(Name) 149 {} 150 151 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 */ 168 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 */ 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 */ 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 */ 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