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