Home | History | Annotate | Download | only in base
      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)
    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