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 
29 namespace rtc {
30 
31 // maximum sizes registry key and value names
32 const int kMaxKeyNameChars = 255 + 1;
33 const int kMaxValueNameChars = 16383 + 1;
34 
35 class 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)
key()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