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 <windows.h> 9 #include <string> 10 #include <vector> 11 12 #include "base/base_export.h" 13 #include "base/basictypes.h" 14 #include "base/stl_util.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 return arguments 25 // are not touched in case of failure. 26 class BASE_EXPORT RegKey { 27 public: 28 RegKey(); 29 explicit RegKey(HKEY key); 30 RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access); 31 ~RegKey(); 32 33 LONG Create(HKEY rootkey, const wchar_t* subkey, REGSAM access); 34 35 LONG CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, 36 DWORD* disposition, REGSAM access); 37 38 // Creates a subkey or open it if it already exists. 39 LONG CreateKey(const wchar_t* name, REGSAM access); 40 41 // Opens an existing reg key. 42 LONG Open(HKEY rootkey, const wchar_t* subkey, REGSAM access); 43 44 // Opens an existing reg key, given the relative key name. 45 LONG OpenKey(const wchar_t* relative_key_name, REGSAM access); 46 47 // Closes this reg key. 48 void Close(); 49 50 // Replaces the handle of the registry key and takes ownership of the handle. 51 void Set(HKEY key); 52 53 // Transfers ownership away from this object. 54 HKEY Take(); 55 56 // Returns false if this key does not have the specified value, or if an error 57 // occurrs while attempting to access it. 58 bool HasValue(const wchar_t* value_name) const; 59 60 // Returns the number of values for this key, or 0 if the number cannot be 61 // determined. 62 DWORD GetValueCount() const; 63 64 // Determine the nth value's name. 65 LONG GetValueNameAt(int index, std::wstring* name) const; 66 67 // True while the key is valid. 68 bool Valid() const { return key_ != NULL; } 69 70 // Kill a key and everything that live below it; please be careful when using 71 // it. 72 LONG DeleteKey(const wchar_t* name); 73 74 // Deletes an empty subkey. If the subkey has subkeys or values then this 75 // will fail. 76 LONG DeleteEmptyKey(const wchar_t* name); 77 78 // Deletes a single value within the key. 79 LONG DeleteValue(const wchar_t* name); 80 81 // Getters: 82 83 // Returns an int32 value. If |name| is NULL or empty, returns the default 84 // value, if any. 85 LONG ReadValueDW(const wchar_t* name, DWORD* out_value) const; 86 87 // Returns an int64 value. If |name| is NULL or empty, returns the default 88 // value, if any. 89 LONG ReadInt64(const wchar_t* name, int64* out_value) const; 90 91 // Returns a string value. If |name| is NULL or empty, returns the default 92 // value, if any. 93 LONG ReadValue(const wchar_t* name, std::wstring* out_value) const; 94 95 // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears 96 // |values| initially and adds further strings to the list. Returns 97 // ERROR_CANTREAD if type is not REG_MULTI_SZ. 98 LONG ReadValues(const wchar_t* name, std::vector<std::wstring>* values); 99 100 // Returns raw data. If |name| is NULL or empty, returns the default 101 // value, if any. 102 LONG ReadValue(const wchar_t* name, 103 void* data, 104 DWORD* dsize, 105 DWORD* dtype) const; 106 107 // Setters: 108 109 // Sets an int32 value. 110 LONG WriteValue(const wchar_t* name, DWORD in_value); 111 112 // Sets a string value. 113 LONG WriteValue(const wchar_t* name, const wchar_t* in_value); 114 115 // Sets raw data, including type. 116 LONG WriteValue(const wchar_t* name, 117 const void* data, 118 DWORD dsize, 119 DWORD dtype); 120 121 // Starts watching the key to see if any of its values have changed. 122 // The key must have been opened with the KEY_NOTIFY access privilege. 123 LONG StartWatching(); 124 125 // If StartWatching hasn't been called, always returns false. 126 // Otherwise, returns true if anything under the key has changed. 127 // This can't be const because the |watch_event_| may be refreshed. 128 bool HasChanged(); 129 130 // Will automatically be called by destructor if not manually called 131 // beforehand. Returns true if it was watching, false otherwise. 132 LONG StopWatching(); 133 134 inline bool IsWatching() const { return watch_event_ != 0; } 135 HANDLE watch_event() const { return watch_event_; } 136 HKEY Handle() const { return key_; } 137 138 private: 139 // Calls RegDeleteKeyEx on supported platforms, alternatively falls back to 140 // RegDeleteKey. 141 static LONG RegDeleteKeyExWrapper(HKEY hKey, 142 const wchar_t* lpSubKey, 143 REGSAM samDesired, 144 DWORD Reserved); 145 146 // Recursively deletes a key and all of its subkeys. 147 static LONG RegDelRecurse(HKEY root_key, 148 const std::wstring& name, 149 REGSAM access); 150 HKEY key_; // The registry key being iterated. 151 HANDLE watch_event_; 152 REGSAM wow64access_; 153 154 DISALLOW_COPY_AND_ASSIGN(RegKey); 155 }; 156 157 // Iterates the entries found in a particular folder on the registry. 158 class BASE_EXPORT RegistryValueIterator { 159 public: 160 RegistryValueIterator(HKEY root_key, const wchar_t* folder_key); 161 162 ~RegistryValueIterator(); 163 164 DWORD ValueCount() const; 165 166 // True while the iterator is valid. 167 bool Valid() const; 168 169 // Advances to the next registry entry. 170 void operator++(); 171 172 const wchar_t* Name() const { return name_.c_str(); } 173 const wchar_t* Value() const { return vector_as_array(&value_); } 174 // ValueSize() is in bytes. 175 DWORD ValueSize() const { return value_size_; } 176 DWORD Type() const { return type_; } 177 178 int Index() const { return index_; } 179 180 private: 181 // Read in the current values. 182 bool Read(); 183 184 // The registry key being iterated. 185 HKEY key_; 186 187 // Current index of the iteration. 188 int index_; 189 190 // Current values. 191 std::wstring name_; 192 std::vector<wchar_t> value_; 193 DWORD value_size_; 194 DWORD type_; 195 196 DISALLOW_COPY_AND_ASSIGN(RegistryValueIterator); 197 }; 198 199 class BASE_EXPORT RegistryKeyIterator { 200 public: 201 RegistryKeyIterator(HKEY root_key, const wchar_t* folder_key); 202 203 ~RegistryKeyIterator(); 204 205 DWORD SubkeyCount() const; 206 207 // True while the iterator is valid. 208 bool Valid() const; 209 210 // Advances to the next entry in the folder. 211 void operator++(); 212 213 const wchar_t* Name() const { return name_; } 214 215 int Index() const { return index_; } 216 217 private: 218 // Read in the current values. 219 bool Read(); 220 221 // The registry key being iterated. 222 HKEY key_; 223 224 // Current index of the iteration. 225 int index_; 226 227 wchar_t name_[MAX_PATH]; 228 229 DISALLOW_COPY_AND_ASSIGN(RegistryKeyIterator); 230 }; 231 232 } // namespace win 233 } // namespace base 234 235 #endif // BASE_WIN_REGISTRY_H_ 236