1/*
2 *  Copyright 2003 The WebRTC Project Authors. All rights reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11// Registry configuration wrappers class
12//
13// Offers static functions for convenient
14// fast access for individual values
15//
16// Also provides a wrapper class for efficient
17// batch operations on values of a given registry key.
18//
19
20#ifndef WEBRTC_BASE_WIN32REGKEY_H_
21#define WEBRTC_BASE_WIN32REGKEY_H_
22
23#include <string>
24#include <vector>
25
26#include "webrtc/base/basictypes.h"
27#include "webrtc/base/win32.h"
28
29namespace rtc {
30
31// maximum sizes registry key and value names
32const int kMaxKeyNameChars = 255 + 1;
33const int kMaxValueNameChars = 16383 + 1;
34
35class RegKey {
36 public:
37  // constructor
38  RegKey();
39
40  // destructor
41  ~RegKey();
42
43  // create a reg key
44  HRESULT Create(HKEY parent_key, const wchar_t* key_name);
45
46  HRESULT Create(HKEY parent_key,
47                 const wchar_t* key_name,
48                 wchar_t* reg_class,
49                 DWORD options,
50                 REGSAM sam_desired,
51                 LPSECURITY_ATTRIBUTES lp_sec_attr,
52                 LPDWORD lp_disposition);
53
54  // open an existing reg key
55  HRESULT Open(HKEY parent_key, const wchar_t* key_name);
56
57  HRESULT Open(HKEY parent_key, const wchar_t* key_name, REGSAM sam_desired);
58
59  // close this reg key
60  HRESULT Close();
61
62  // check if the key has a specified value
63  bool HasValue(const wchar_t* value_name) const;
64
65  // get the number of values for this key
66  uint32 GetValueCount();
67
68  // Called to get the value name for the given value name index
69  // Use GetValueCount() to get the total value_name count for this key
70  // Returns failure if no key at the specified index
71  // If you modify the key while enumerating, the indexes will be out of order.
72  // Since the index order is not guaranteed, you need to reset your counting
73  // loop.
74  // 'type' refers to REG_DWORD, REG_QWORD, etc..
75  // 'type' can be NULL if not interested in the value type
76  HRESULT GetValueNameAt(int index, std::wstring* value_name, DWORD* type);
77
78  // check if the current key has the specified subkey
79  bool HasSubkey(const wchar_t* key_name) const;
80
81  // get the number of subkeys for this key
82  uint32 GetSubkeyCount();
83
84  // Called to get the key name for the given key index
85  // Use GetSubkeyCount() to get the total count for this key
86  // Returns failure if no key at the specified index
87  // If you modify the key while enumerating, the indexes will be out of order.
88  // Since the index order is not guaranteed, you need to reset your counting
89  // loop.
90  HRESULT GetSubkeyNameAt(int index, std::wstring* key_name);
91
92  // SETTERS
93
94  // set an int32 value - use when reading multiple values from a key
95  HRESULT SetValue(const wchar_t* value_name, DWORD value) const;
96
97  // set an int64 value
98  HRESULT SetValue(const wchar_t* value_name, DWORD64 value) const;
99
100  // set a string value
101  HRESULT SetValue(const wchar_t* value_name, const wchar_t* value) const;
102
103  // set binary data
104  HRESULT SetValue(const wchar_t* value_name,
105                   const uint8* value,
106                   DWORD byte_count) const;
107
108  // set raw data, including type
109  HRESULT SetValue(const wchar_t* value_name,
110                   const uint8* value,
111                   DWORD byte_count,
112                   DWORD type) const;
113
114  // GETTERS
115
116  // get an int32 value
117  HRESULT GetValue(const wchar_t* value_name, DWORD* value) const;
118
119  // get an int64 value
120  HRESULT GetValue(const wchar_t* value_name, DWORD64* value) const;
121
122  // get a string value - the caller must free the return buffer
123  HRESULT GetValue(const wchar_t* value_name, wchar_t** value) const;
124
125  // get a string value
126  HRESULT GetValue(const wchar_t* value_name, std::wstring* value) const;
127
128  // get a std::vector<std::wstring> value from REG_MULTI_SZ type
129  HRESULT GetValue(const wchar_t* value_name,
130                   std::vector<std::wstring>* value) const;
131
132  // get binary data - the caller must free the return buffer
133  HRESULT GetValue(const wchar_t* value_name,
134                   uint8** value,
135                   DWORD* byte_count) const;
136
137  // get raw data, including type - the caller must free the return buffer
138  HRESULT GetValue(const wchar_t* value_name,
139                   uint8** value,
140                   DWORD* byte_count,
141                   DWORD* type) const;
142
143  // STATIC VERSIONS
144
145  // flush
146  static HRESULT FlushKey(const wchar_t* full_key_name);
147
148  // check if a key exists
149  static bool HasKey(const wchar_t* full_key_name);
150
151  // check if the key has a specified value
152  static bool HasValue(const wchar_t* full_key_name, const wchar_t* value_name);
153
154  // SETTERS
155
156  // STATIC int32 set
157  static HRESULT SetValue(const wchar_t* full_key_name,
158                          const wchar_t* value_name,
159                          DWORD value);
160
161  // STATIC int64 set
162  static HRESULT SetValue(const wchar_t* full_key_name,
163                          const wchar_t* value_name,
164                          DWORD64 value);
165
166  // STATIC float set
167  static HRESULT SetValue(const wchar_t* full_key_name,
168                          const wchar_t* value_name,
169                          float value);
170
171  // STATIC double set
172  static HRESULT SetValue(const wchar_t* full_key_name,
173                          const wchar_t* value_name,
174                          double value);
175
176  // STATIC string set
177  static HRESULT SetValue(const wchar_t* full_key_name,
178                          const wchar_t* value_name,
179                          const wchar_t* value);
180
181  // STATIC binary data set
182  static HRESULT SetValue(const wchar_t* full_key_name,
183                          const wchar_t* value_name,
184                          const uint8* value,
185                          DWORD byte_count);
186
187  // STATIC multi-string set
188  static HRESULT SetValueMultiSZ(const wchar_t* full_key_name,
189                                 const TCHAR* value_name,
190                                 const uint8* value,
191                                 DWORD byte_count);
192
193  // GETTERS
194
195  // STATIC int32 get
196  static HRESULT GetValue(const wchar_t* full_key_name,
197                          const wchar_t* value_name,
198                          DWORD* value);
199
200  // STATIC int64 get
201  //
202  // Note: if you are using time64 you should
203  // likely use GetLimitedTimeValue (util.h) instead of this method.
204  static HRESULT GetValue(const wchar_t* full_key_name,
205                          const wchar_t* value_name,
206                          DWORD64* value);
207
208  // STATIC float get
209  static HRESULT GetValue(const wchar_t* full_key_name,
210                          const wchar_t* value_name,
211                          float* value);
212
213  // STATIC double get
214  static HRESULT GetValue(const wchar_t* full_key_name,
215                          const wchar_t* value_name,
216                          double* value);
217
218  // STATIC string get
219  // Note: the caller must free the return buffer for wchar_t* version
220  static HRESULT GetValue(const wchar_t* full_key_name,
221                          const wchar_t* value_name,
222                          wchar_t** value);
223  static HRESULT GetValue(const wchar_t* full_key_name,
224                          const wchar_t* value_name,
225                          std::wstring* value);
226
227  // STATIC REG_MULTI_SZ get
228  static HRESULT GetValue(const wchar_t* full_key_name,
229                          const wchar_t* value_name,
230                          std::vector<std::wstring>* value);
231
232  // STATIC get binary data - the caller must free the return buffer
233  static HRESULT GetValue(const wchar_t* full_key_name,
234                          const wchar_t* value_name,
235                          uint8** value,
236                          DWORD* byte_count);
237
238  // Get type of a registry value
239  static HRESULT GetValueType(const wchar_t* full_key_name,
240                              const wchar_t* value_name,
241                              DWORD* value_type);
242
243  // delete a subkey of the current key (with no subkeys)
244  HRESULT DeleteSubKey(const wchar_t* key_name);
245
246  // recursively delete a sub key of the current key (and all its subkeys)
247  HRESULT RecurseDeleteSubKey(const wchar_t* key_name);
248
249  // STATIC version of delete key - handles nested keys also
250  // delete a key and all its sub-keys recursively
251  // Returns S_FALSE if key didn't exist, S_OK if deletion was successful,
252  // and failure otherwise.
253  static HRESULT DeleteKey(const wchar_t* full_key_name);
254
255  // STATIC version of delete key
256  // delete a key recursively or non-recursively
257  // Returns S_FALSE if key didn't exist, S_OK if deletion was successful,
258  // and failure otherwise.
259  static HRESULT DeleteKey(const wchar_t* full_key_name, bool recursive);
260
261  // delete the specified value
262  HRESULT DeleteValue(const wchar_t* value_name);
263
264  // STATIC version of delete value
265  // Returns S_FALSE if key didn't exist, S_OK if deletion was successful,
266  // and failure otherwise.
267  static HRESULT DeleteValue(const wchar_t* full_key_name,
268                             const wchar_t* value_name);
269
270  // Peek inside (use a RegKey as a smart wrapper around a registry handle)
271  HKEY key() { return h_key_; }
272
273  // helper function to get the HKEY and the root key from a string
274  // modifies the argument in place and returns the key name
275  // e.g. HKLM\\Software\\Google\... returns HKLM, "Software\\Google\..."
276  // Necessary for the static versions that use the full name of the reg key
277  static HKEY GetRootKeyInfo(std::wstring* full_key_name);
278
279  // Returns true if this key name is 'safe' for deletion (doesn't specify a key
280  // root)
281  static bool SafeKeyNameForDeletion(const wchar_t* key_name);
282
283  // save the key and all of its subkeys and values to a file
284  static HRESULT Save(const wchar_t* full_key_name, const wchar_t* file_name);
285
286  // restore the key and all of its subkeys and values which are saved into a
287  // file
288  static HRESULT Restore(const wchar_t* full_key_name,
289                         const wchar_t* file_name);
290
291  // Is the key empty: having no sub-keys and values
292  static bool IsKeyEmpty(const wchar_t* full_key_name);
293
294 private:
295
296  // helper function to get any value from the registry
297  // used when the size of the data is unknown
298  HRESULT GetValueHelper(const wchar_t* value_name,
299                         DWORD* type, uint8** value,
300                         DWORD* byte_count) const;
301
302  // helper function to get the parent key name and the subkey from a string
303  // modifies the argument in place and returns the key name
304  // Necessary for the static versions that use the full name of the reg key
305  static std::wstring GetParentKeyInfo(std::wstring* key_name);
306
307  // common SET Helper for the static case
308  static HRESULT SetValueStaticHelper(const wchar_t* full_key_name,
309                                      const wchar_t* value_name,
310                                      DWORD type,
311                                      LPVOID value,
312                                      DWORD byte_count = 0);
313
314  // common GET Helper for the static case
315  static HRESULT GetValueStaticHelper(const wchar_t* full_key_name,
316                                      const wchar_t* value_name,
317                                      DWORD type,
318                                      LPVOID value,
319                                      DWORD* byte_count = NULL);
320
321  // convert REG_MULTI_SZ bytes to string array
322  static HRESULT MultiSZBytesToStringArray(const uint8* buffer,
323                                           DWORD byte_count,
324                                           std::vector<std::wstring>* value);
325
326  // the HKEY for the current key
327  HKEY h_key_;
328
329  // for unittest
330  friend void RegKeyHelperFunctionsTest();
331
332  DISALLOW_EVIL_CONSTRUCTORS(RegKey);
333};
334
335}  // namespace rtc
336
337#endif  // WEBRTC_BASE_WIN32REGKEY_H_
338