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