• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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