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