1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_WIN_REGISTRY_H_ 6 #define BASE_WIN_REGISTRY_H_ 7 8 #include <stdint.h> 9 #include <windows.h> 10 #include <string> 11 #include <vector> 12 13 #include "base/win/scoped_handle.h" 14 15 namespace base { 16 namespace win { 17 18 // Utility class to read, write and manipulate the Windows Registry. 19 // Registry vocabulary primer: a "key" is like a folder, in which there 20 // are "values", which are <name, data> pairs, with an associated data type. 21 // 22 // Note: 23 // * ReadValue family of functions guarantee that the out-parameter 24 // is not touched in case of failure. 25 // * Functions returning LONG indicate success as ERROR_SUCCESS or an 26 // error as a (non-zero) win32 error code. 27 class RegKey { 28 public: 29 RegKey(); 30 explicit RegKey(HKEY key); 31 RegKey(HKEY rootkey, const char16_t* subkey, REGSAM access); 32 ~RegKey(); 33 34 LONG Create(HKEY rootkey, const char16_t* subkey, REGSAM access); 35 36 LONG CreateWithDisposition(HKEY rootkey, 37 const char16_t* subkey, 38 DWORD* disposition, 39 REGSAM access); 40 41 // Creates a subkey or open it if it already exists. 42 LONG CreateKey(const char16_t* name, REGSAM access); 43 44 // Opens an existing reg key. 45 LONG Open(HKEY rootkey, const char16_t* subkey, REGSAM access); 46 47 // Opens an existing reg key, given the relative key name. 48 LONG OpenKey(const char16_t* relative_key_name, REGSAM access); 49 50 // Closes this reg key. 51 void Close(); 52 53 // Replaces the handle of the registry key and takes ownership of the handle. 54 void Set(HKEY key); 55 56 // Transfers ownership away from this object. 57 HKEY Take(); 58 59 // Returns false if this key does not have the specified value, or if an error 60 // occurs while attempting to access it. 61 bool HasValue(const char16_t* value_name) const; 62 63 // Returns the number of values for this key, or 0 if the number cannot be 64 // determined. 65 DWORD GetValueCount() const; 66 67 // Determines the nth value's name. 68 LONG GetValueNameAt(int index, std::u16string* name) const; 69 70 // True while the key is valid. Valid()71 bool Valid() const { return key_ != NULL; } 72 73 // Kills a key and everything that lives below it; please be careful when 74 // using it. 75 LONG DeleteKey(const char16_t* name); 76 77 // Deletes an empty subkey. If the subkey has subkeys or values then this 78 // will fail. 79 LONG DeleteEmptyKey(const char16_t* name); 80 81 // Deletes a single value within the key. 82 LONG DeleteValue(const char16_t* name); 83 84 // Getters: 85 86 // Reads a REG_DWORD (uint32_t) into |out_value|. If |name| is null or empty, 87 // reads the key's default value, if any. 88 LONG ReadValueDW(const char16_t* name, DWORD* out_value) const; 89 90 // Reads a REG_QWORD (int64_t) into |out_value|. If |name| is null or empty, 91 // reads the key's default value, if any. 92 LONG ReadInt64(const char16_t* name, int64_t* out_value) const; 93 94 // Reads a string into |out_value|. If |name| is null or empty, reads 95 // the key's default value, if any. 96 LONG ReadValue(const char16_t* name, std::u16string* out_value) const; 97 98 // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears 99 // |values| initially and adds further strings to the list. Returns 100 // ERROR_CANTREAD if type is not REG_MULTI_SZ. 101 LONG ReadValues(const char16_t* name, std::vector<std::u16string>* values); 102 103 // Reads raw data into |data|. If |name| is null or empty, reads the key's 104 // default value, if any. 105 LONG ReadValue(const char16_t* name, 106 void* data, 107 DWORD* dsize, 108 DWORD* dtype) const; 109 110 // Setters: 111 112 // Sets an int32_t value. 113 LONG WriteValue(const char16_t* name, DWORD in_value); 114 115 // Sets a string value. 116 LONG WriteValue(const char16_t* name, const char16_t* in_value); 117 118 // Sets raw data, including type. 119 LONG WriteValue(const char16_t* name, 120 const void* data, 121 DWORD dsize, 122 DWORD dtype); 123 Handle()124 HKEY Handle() const { return key_; } 125 126 private: 127 // Calls RegDeleteKeyEx on supported platforms, alternatively falls back to 128 // RegDeleteKey. 129 static LONG RegDeleteKeyExWrapper(HKEY hKey, 130 const char16_t* lpSubKey, 131 REGSAM samDesired, 132 DWORD Reserved); 133 134 // Recursively deletes a key and all of its subkeys. 135 static LONG RegDelRecurse(HKEY root_key, 136 const std::u16string& name, 137 REGSAM access); 138 139 HKEY key_; // The registry key being iterated. 140 REGSAM wow64access_; 141 142 RegKey(const RegKey&) = delete; 143 RegKey& operator=(const RegKey&) = delete; 144 }; 145 146 // Iterates the entries found in a particular folder on the registry. 147 class RegistryValueIterator { 148 public: 149 // Constructs a Registry Value Iterator with default WOW64 access. 150 RegistryValueIterator(HKEY root_key, const char16_t* folder_key); 151 152 // Constructs a Registry Key Iterator with specific WOW64 access, one of 153 // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0. 154 // Note: |wow64access| should be the same access used to open |root_key| 155 // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE). 156 // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx. 157 RegistryValueIterator(HKEY root_key, 158 const char16_t* folder_key, 159 REGSAM wow64access); 160 161 ~RegistryValueIterator(); 162 163 DWORD ValueCount() const; 164 165 // True while the iterator is valid. 166 bool Valid() const; 167 168 // Advances to the next registry entry. 169 void operator++(); 170 Name()171 const char16_t* Name() const { return name_.c_str(); } Value()172 const char16_t* Value() const { return value_.data(); } 173 // ValueSize() is in bytes. ValueSize()174 DWORD ValueSize() const { return value_size_; } Type()175 DWORD Type() const { return type_; } 176 Index()177 int Index() const { return index_; } 178 179 private: 180 // Reads in the current values. 181 bool Read(); 182 183 void Initialize(HKEY root_key, 184 const char16_t* folder_key, 185 REGSAM wow64access); 186 187 // The registry key being iterated. 188 HKEY key_; 189 190 // Current index of the iteration. 191 int index_; 192 193 // Current values. 194 std::u16string name_; 195 std::vector<char16_t> value_; 196 DWORD value_size_; 197 DWORD type_; 198 199 RegistryValueIterator(const RegistryValueIterator&) = delete; 200 RegistryValueIterator& operator=(const RegistryValueIterator&) = delete; 201 }; 202 203 class RegistryKeyIterator { 204 public: 205 // Constructs a Registry Key Iterator with default WOW64 access. 206 RegistryKeyIterator(HKEY root_key, const char16_t* folder_key); 207 208 // Constructs a Registry Value Iterator with specific WOW64 access, one of 209 // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0. 210 // Note: |wow64access| should be the same access used to open |root_key| 211 // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE). 212 // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx. 213 RegistryKeyIterator(HKEY root_key, 214 const char16_t* folder_key, 215 REGSAM wow64access); 216 217 ~RegistryKeyIterator(); 218 219 DWORD SubkeyCount() const; 220 221 // True while the iterator is valid. 222 bool Valid() const; 223 224 // Advances to the next entry in the folder. 225 void operator++(); 226 Name()227 const char16_t* Name() const { return name_; } 228 Index()229 int Index() const { return index_; } 230 231 private: 232 // Reads in the current values. 233 bool Read(); 234 235 void Initialize(HKEY root_key, 236 const char16_t* folder_key, 237 REGSAM wow64access); 238 239 // The registry key being iterated. 240 HKEY key_; 241 242 // Current index of the iteration. 243 int index_; 244 245 char16_t name_[MAX_PATH]; 246 247 RegistryKeyIterator(const RegistryKeyIterator&) = delete; 248 RegistryKeyIterator& operator=(const RegistryKeyIterator&) = delete; 249 }; 250 251 } // namespace win 252 } // namespace base 253 254 #endif // BASE_WIN_REGISTRY_H_ 255