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/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)
    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