1 /* 2 * libjingle 3 * Copyright 2003-2007, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 // Registry configuration wrappers class 29 // 30 // Offers static functions for convenient 31 // fast access for individual values 32 // 33 // Also provides a wrapper class for efficient 34 // batch operations on values of a given registry key. 35 // 36 37 #ifndef TALK_BASE_WIN32REGKEY_H_ 38 #define TALK_BASE_WIN32REGKEY_H_ 39 40 #include <string> 41 #include <vector> 42 43 #include "talk/base/basictypes.h" 44 #include "talk/base/win32.h" 45 46 namespace talk_base { 47 48 // maximum sizes registry key and value names 49 const int kMaxKeyNameChars = 255 + 1; 50 const int kMaxValueNameChars = 16383 + 1; 51 52 class RegKey { 53 public: 54 // constructor 55 RegKey(); 56 57 // destructor 58 ~RegKey(); 59 60 // create a reg key 61 HRESULT Create(HKEY parent_key, const wchar_t* key_name); 62 63 HRESULT Create(HKEY parent_key, 64 const wchar_t* key_name, 65 wchar_t* reg_class, 66 DWORD options, 67 REGSAM sam_desired, 68 LPSECURITY_ATTRIBUTES lp_sec_attr, 69 LPDWORD lp_disposition); 70 71 // open an existing reg key 72 HRESULT Open(HKEY parent_key, const wchar_t* key_name); 73 74 HRESULT Open(HKEY parent_key, const wchar_t* key_name, REGSAM sam_desired); 75 76 // close this reg key 77 HRESULT Close(); 78 79 // check if the key has a specified value 80 bool HasValue(const wchar_t* value_name) const; 81 82 // get the number of values for this key 83 uint32 GetValueCount(); 84 85 // Called to get the value name for the given value name index 86 // Use GetValueCount() to get the total value_name 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 // 'type' refers to REG_DWORD, REG_QWORD, etc.. 92 // 'type' can be NULL if not interested in the value type 93 HRESULT GetValueNameAt(int index, std::wstring* value_name, DWORD* type); 94 95 // check if the current key has the specified subkey 96 bool HasSubkey(const wchar_t* key_name) const; 97 98 // get the number of subkeys for this key 99 uint32 GetSubkeyCount(); 100 101 // Called to get the key name for the given key index 102 // Use GetSubkeyCount() to get the total count for this key 103 // Returns failure if no key at the specified index 104 // If you modify the key while enumerating, the indexes will be out of order. 105 // Since the index order is not guaranteed, you need to reset your counting 106 // loop. 107 HRESULT GetSubkeyNameAt(int index, std::wstring* key_name); 108 109 // SETTERS 110 111 // set an int32 value - use when reading multiple values from a key 112 HRESULT SetValue(const wchar_t* value_name, DWORD value) const; 113 114 // set an int64 value 115 HRESULT SetValue(const wchar_t* value_name, DWORD64 value) const; 116 117 // set a string value 118 HRESULT SetValue(const wchar_t* value_name, const wchar_t* value) const; 119 120 // set binary data 121 HRESULT SetValue(const wchar_t* value_name, 122 const uint8* value, 123 DWORD byte_count) const; 124 125 // set raw data, including type 126 HRESULT SetValue(const wchar_t* value_name, 127 const uint8* value, 128 DWORD byte_count, 129 DWORD type) const; 130 131 // GETTERS 132 133 // get an int32 value 134 HRESULT GetValue(const wchar_t* value_name, DWORD* value) const; 135 136 // get an int64 value 137 HRESULT GetValue(const wchar_t* value_name, DWORD64* value) const; 138 139 // get a string value - the caller must free the return buffer 140 HRESULT GetValue(const wchar_t* value_name, wchar_t** value) const; 141 142 // get a string value 143 HRESULT GetValue(const wchar_t* value_name, std::wstring* value) const; 144 145 // get a std::vector<std::wstring> value from REG_MULTI_SZ type 146 HRESULT GetValue(const wchar_t* value_name, 147 std::vector<std::wstring>* value) const; 148 149 // get binary data - the caller must free the return buffer 150 HRESULT GetValue(const wchar_t* value_name, 151 uint8** value, 152 DWORD* byte_count) const; 153 154 // get raw data, including type - the caller must free the return buffer 155 HRESULT GetValue(const wchar_t* value_name, 156 uint8** value, 157 DWORD* byte_count, 158 DWORD* type) const; 159 160 // STATIC VERSIONS 161 162 // flush 163 static HRESULT FlushKey(const wchar_t* full_key_name); 164 165 // check if a key exists 166 static bool HasKey(const wchar_t* full_key_name); 167 168 // check if the key has a specified value 169 static bool HasValue(const wchar_t* full_key_name, const wchar_t* value_name); 170 171 // SETTERS 172 173 // STATIC int32 set 174 static HRESULT SetValue(const wchar_t* full_key_name, 175 const wchar_t* value_name, 176 DWORD value); 177 178 // STATIC int64 set 179 static HRESULT SetValue(const wchar_t* full_key_name, 180 const wchar_t* value_name, 181 DWORD64 value); 182 183 // STATIC float set 184 static HRESULT SetValue(const wchar_t* full_key_name, 185 const wchar_t* value_name, 186 float value); 187 188 // STATIC double set 189 static HRESULT SetValue(const wchar_t* full_key_name, 190 const wchar_t* value_name, 191 double value); 192 193 // STATIC string set 194 static HRESULT SetValue(const wchar_t* full_key_name, 195 const wchar_t* value_name, 196 const wchar_t* value); 197 198 // STATIC binary data set 199 static HRESULT SetValue(const wchar_t* full_key_name, 200 const wchar_t* value_name, 201 const uint8* value, 202 DWORD byte_count); 203 204 // STATIC multi-string set 205 static HRESULT SetValueMultiSZ(const wchar_t* full_key_name, 206 const TCHAR* value_name, 207 const uint8* value, 208 DWORD byte_count); 209 210 // GETTERS 211 212 // STATIC int32 get 213 static HRESULT GetValue(const wchar_t* full_key_name, 214 const wchar_t* value_name, 215 DWORD* value); 216 217 // STATIC int64 get 218 // 219 // Note: if you are using time64 you should 220 // likely use GetLimitedTimeValue (util.h) instead of this method. 221 static HRESULT GetValue(const wchar_t* full_key_name, 222 const wchar_t* value_name, 223 DWORD64* value); 224 225 // STATIC float get 226 static HRESULT GetValue(const wchar_t* full_key_name, 227 const wchar_t* value_name, 228 float* value); 229 230 // STATIC double get 231 static HRESULT GetValue(const wchar_t* full_key_name, 232 const wchar_t* value_name, 233 double* value); 234 235 // STATIC string get 236 // Note: the caller must free the return buffer for wchar_t* version 237 static HRESULT GetValue(const wchar_t* full_key_name, 238 const wchar_t* value_name, 239 wchar_t** value); 240 static HRESULT GetValue(const wchar_t* full_key_name, 241 const wchar_t* value_name, 242 std::wstring* value); 243 244 // STATIC REG_MULTI_SZ get 245 static HRESULT GetValue(const wchar_t* full_key_name, 246 const wchar_t* value_name, 247 std::vector<std::wstring>* value); 248 249 // STATIC get binary data - the caller must free the return buffer 250 static HRESULT GetValue(const wchar_t* full_key_name, 251 const wchar_t* value_name, 252 uint8** value, 253 DWORD* byte_count); 254 255 // Get type of a registry value 256 static HRESULT GetValueType(const wchar_t* full_key_name, 257 const wchar_t* value_name, 258 DWORD* value_type); 259 260 // delete a subkey of the current key (with no subkeys) 261 HRESULT DeleteSubKey(const wchar_t* key_name); 262 263 // recursively delete a sub key of the current key (and all its subkeys) 264 HRESULT RecurseDeleteSubKey(const wchar_t* key_name); 265 266 // STATIC version of delete key - handles nested keys also 267 // delete a key and all its sub-keys recursively 268 // Returns S_FALSE if key didn't exist, S_OK if deletion was successful, 269 // and failure otherwise. 270 static HRESULT DeleteKey(const wchar_t* full_key_name); 271 272 // STATIC version of delete key 273 // delete a key recursively or non-recursively 274 // Returns S_FALSE if key didn't exist, S_OK if deletion was successful, 275 // and failure otherwise. 276 static HRESULT DeleteKey(const wchar_t* full_key_name, bool recursive); 277 278 // delete the specified value 279 HRESULT DeleteValue(const wchar_t* value_name); 280 281 // STATIC version of delete value 282 // Returns S_FALSE if key didn't exist, S_OK if deletion was successful, 283 // and failure otherwise. 284 static HRESULT DeleteValue(const wchar_t* full_key_name, 285 const wchar_t* value_name); 286 287 // Peek inside (use a RegKey as a smart wrapper around a registry handle) 288 HKEY key() { return h_key_; } 289 290 // helper function to get the HKEY and the root key from a string 291 // modifies the argument in place and returns the key name 292 // e.g. HKLM\\Software\\Google\... returns HKLM, "Software\\Google\..." 293 // Necessary for the static versions that use the full name of the reg key 294 static HKEY GetRootKeyInfo(std::wstring* full_key_name); 295 296 // Returns true if this key name is 'safe' for deletion (doesn't specify a key 297 // root) 298 static bool SafeKeyNameForDeletion(const wchar_t* key_name); 299 300 // save the key and all of its subkeys and values to a file 301 static HRESULT Save(const wchar_t* full_key_name, const wchar_t* file_name); 302 303 // restore the key and all of its subkeys and values which are saved into a 304 // file 305 static HRESULT Restore(const wchar_t* full_key_name, 306 const wchar_t* file_name); 307 308 // Is the key empty: having no sub-keys and values 309 static bool IsKeyEmpty(const wchar_t* full_key_name); 310 311 private: 312 313 // helper function to get any value from the registry 314 // used when the size of the data is unknown 315 HRESULT GetValueHelper(const wchar_t* value_name, 316 DWORD* type, uint8** value, 317 DWORD* byte_count) const; 318 319 // helper function to get the parent key name and the subkey from a string 320 // modifies the argument in place and returns the key name 321 // Necessary for the static versions that use the full name of the reg key 322 static std::wstring GetParentKeyInfo(std::wstring* key_name); 323 324 // common SET Helper for the static case 325 static HRESULT SetValueStaticHelper(const wchar_t* full_key_name, 326 const wchar_t* value_name, 327 DWORD type, 328 LPVOID value, 329 DWORD byte_count = 0); 330 331 // common GET Helper for the static case 332 static HRESULT GetValueStaticHelper(const wchar_t* full_key_name, 333 const wchar_t* value_name, 334 DWORD type, 335 LPVOID value, 336 DWORD* byte_count = NULL); 337 338 // convert REG_MULTI_SZ bytes to string array 339 static HRESULT MultiSZBytesToStringArray(const uint8* buffer, 340 DWORD byte_count, 341 std::vector<std::wstring>* value); 342 343 // the HKEY for the current key 344 HKEY h_key_; 345 346 // for unittest 347 friend void RegKeyHelperFunctionsTest(); 348 349 DISALLOW_EVIL_CONSTRUCTORS(RegKey); 350 }; 351 352 } // namespace talk_base 353 354 #endif // TALK_BASE_WIN32REGKEY_H_ 355