• 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 <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