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