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