| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_WIN_REGISTRY_H_ | 
 | #define BASE_WIN_REGISTRY_H_ | 
 |  | 
 | #include <stdint.h> | 
 | #include <string> | 
 | #include <vector> | 
 | #include <windows.h> | 
 |  | 
 | #include "base/macros.h" | 
 | #include "base/win/scoped_handle.h" | 
 |  | 
 | namespace base { | 
 | namespace win { | 
 |  | 
 | // Utility class to read, write and manipulate the Windows Registry. | 
 | // Registry vocabulary primer: a "key" is like a folder, in which there | 
 | // are "values", which are <name, data> pairs, with an associated data type. | 
 | // | 
 | // Note: | 
 | //  * ReadValue family of functions guarantee that the out-parameter | 
 | //    is not touched in case of failure. | 
 | //  * Functions returning LONG indicate success as ERROR_SUCCESS or an | 
 | //    error as a (non-zero) win32 error code. | 
 | class RegKey { | 
 |  public: | 
 |   RegKey(); | 
 |   explicit RegKey(HKEY key); | 
 |   RegKey(HKEY rootkey, const char16_t* subkey, REGSAM access); | 
 |   ~RegKey(); | 
 |  | 
 |   LONG Create(HKEY rootkey, const char16_t* subkey, REGSAM access); | 
 |  | 
 |   LONG CreateWithDisposition(HKEY rootkey, | 
 |                              const char16_t* subkey, | 
 |                              DWORD* disposition, | 
 |                              REGSAM access); | 
 |  | 
 |   // Creates a subkey or open it if it already exists. | 
 |   LONG CreateKey(const char16_t* name, REGSAM access); | 
 |  | 
 |   // Opens an existing reg key. | 
 |   LONG Open(HKEY rootkey, const char16_t* subkey, REGSAM access); | 
 |  | 
 |   // Opens an existing reg key, given the relative key name. | 
 |   LONG OpenKey(const char16_t* relative_key_name, REGSAM access); | 
 |  | 
 |   // Closes this reg key. | 
 |   void Close(); | 
 |  | 
 |   // Replaces the handle of the registry key and takes ownership of the handle. | 
 |   void Set(HKEY key); | 
 |  | 
 |   // Transfers ownership away from this object. | 
 |   HKEY Take(); | 
 |  | 
 |   // Returns false if this key does not have the specified value, or if an error | 
 |   // occurrs while attempting to access it. | 
 |   bool HasValue(const char16_t* value_name) const; | 
 |  | 
 |   // Returns the number of values for this key, or 0 if the number cannot be | 
 |   // determined. | 
 |   DWORD GetValueCount() const; | 
 |  | 
 |   // Determines the nth value's name. | 
 |   LONG GetValueNameAt(int index, std::u16string* name) const; | 
 |  | 
 |   // True while the key is valid. | 
 |   bool Valid() const { return key_ != NULL; } | 
 |  | 
 |   // Kills a key and everything that lives below it; please be careful when | 
 |   // using it. | 
 |   LONG DeleteKey(const char16_t* name); | 
 |  | 
 |   // Deletes an empty subkey.  If the subkey has subkeys or values then this | 
 |   // will fail. | 
 |   LONG DeleteEmptyKey(const char16_t* name); | 
 |  | 
 |   // Deletes a single value within the key. | 
 |   LONG DeleteValue(const char16_t* name); | 
 |  | 
 |   // Getters: | 
 |  | 
 |   // Reads a REG_DWORD (uint32_t) into |out_value|. If |name| is null or empty, | 
 |   // reads the key's default value, if any. | 
 |   LONG ReadValueDW(const char16_t* name, DWORD* out_value) const; | 
 |  | 
 |   // Reads a REG_QWORD (int64_t) into |out_value|. If |name| is null or empty, | 
 |   // reads the key's default value, if any. | 
 |   LONG ReadInt64(const char16_t* name, int64_t* out_value) const; | 
 |  | 
 |   // Reads a string into |out_value|. If |name| is null or empty, reads | 
 |   // the key's default value, if any. | 
 |   LONG ReadValue(const char16_t* name, std::u16string* out_value) const; | 
 |  | 
 |   // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears | 
 |   // |values| initially and adds further strings to the list. Returns | 
 |   // ERROR_CANTREAD if type is not REG_MULTI_SZ. | 
 |   LONG ReadValues(const char16_t* name, std::vector<std::u16string>* values); | 
 |  | 
 |   // Reads raw data into |data|. If |name| is null or empty, reads the key's | 
 |   // default value, if any. | 
 |   LONG ReadValue(const char16_t* name, | 
 |                  void* data, | 
 |                  DWORD* dsize, | 
 |                  DWORD* dtype) const; | 
 |  | 
 |   // Setters: | 
 |  | 
 |   // Sets an int32_t value. | 
 |   LONG WriteValue(const char16_t* name, DWORD in_value); | 
 |  | 
 |   // Sets a string value. | 
 |   LONG WriteValue(const char16_t* name, const char16_t* in_value); | 
 |  | 
 |   // Sets raw data, including type. | 
 |   LONG WriteValue(const char16_t* name, | 
 |                   const void* data, | 
 |                   DWORD dsize, | 
 |                   DWORD dtype); | 
 |  | 
 |   HKEY Handle() const { return key_; } | 
 |  | 
 |  private: | 
 |   // Calls RegDeleteKeyEx on supported platforms, alternatively falls back to | 
 |   // RegDeleteKey. | 
 |   static LONG RegDeleteKeyExWrapper(HKEY hKey, | 
 |                                     const char16_t* lpSubKey, | 
 |                                     REGSAM samDesired, | 
 |                                     DWORD Reserved); | 
 |  | 
 |   // Recursively deletes a key and all of its subkeys. | 
 |   static LONG RegDelRecurse(HKEY root_key, | 
 |                             const std::u16string& name, | 
 |                             REGSAM access); | 
 |  | 
 |   HKEY key_;  // The registry key being iterated. | 
 |   REGSAM wow64access_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(RegKey); | 
 | }; | 
 |  | 
 | // Iterates the entries found in a particular folder on the registry. | 
 | class RegistryValueIterator { | 
 |  public: | 
 |   // Constructs a Registry Value Iterator with default WOW64 access. | 
 |   RegistryValueIterator(HKEY root_key, const char16_t* folder_key); | 
 |  | 
 |   // Constructs a Registry Key Iterator with specific WOW64 access, one of | 
 |   // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0. | 
 |   // Note: |wow64access| should be the same access used to open |root_key| | 
 |   // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE). | 
 |   // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx. | 
 |   RegistryValueIterator(HKEY root_key, | 
 |                         const char16_t* folder_key, | 
 |                         REGSAM wow64access); | 
 |  | 
 |   ~RegistryValueIterator(); | 
 |  | 
 |   DWORD ValueCount() const; | 
 |  | 
 |   // True while the iterator is valid. | 
 |   bool Valid() const; | 
 |  | 
 |   // Advances to the next registry entry. | 
 |   void operator++(); | 
 |  | 
 |   const char16_t* Name() const { return name_.c_str(); } | 
 |   const char16_t* Value() const { return value_.data(); } | 
 |   // ValueSize() is in bytes. | 
 |   DWORD ValueSize() const { return value_size_; } | 
 |   DWORD Type() const { return type_; } | 
 |  | 
 |   int Index() const { return index_; } | 
 |  | 
 |  private: | 
 |   // Reads in the current values. | 
 |   bool Read(); | 
 |  | 
 |   void Initialize(HKEY root_key, | 
 |                   const char16_t* folder_key, | 
 |                   REGSAM wow64access); | 
 |  | 
 |   // The registry key being iterated. | 
 |   HKEY key_; | 
 |  | 
 |   // Current index of the iteration. | 
 |   int index_; | 
 |  | 
 |   // Current values. | 
 |   std::u16string name_; | 
 |   std::vector<char16_t> value_; | 
 |   DWORD value_size_; | 
 |   DWORD type_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(RegistryValueIterator); | 
 | }; | 
 |  | 
 | class RegistryKeyIterator { | 
 |  public: | 
 |   // Constructs a Registry Key Iterator with default WOW64 access. | 
 |   RegistryKeyIterator(HKEY root_key, const char16_t* folder_key); | 
 |  | 
 |   // Constructs a Registry Value Iterator with specific WOW64 access, one of | 
 |   // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0. | 
 |   // Note: |wow64access| should be the same access used to open |root_key| | 
 |   // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE). | 
 |   // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx. | 
 |   RegistryKeyIterator(HKEY root_key, | 
 |                       const char16_t* folder_key, | 
 |                       REGSAM wow64access); | 
 |  | 
 |   ~RegistryKeyIterator(); | 
 |  | 
 |   DWORD SubkeyCount() const; | 
 |  | 
 |   // True while the iterator is valid. | 
 |   bool Valid() const; | 
 |  | 
 |   // Advances to the next entry in the folder. | 
 |   void operator++(); | 
 |  | 
 |   const char16_t* Name() const { return name_; } | 
 |  | 
 |   int Index() const { return index_; } | 
 |  | 
 |  private: | 
 |   // Reads in the current values. | 
 |   bool Read(); | 
 |  | 
 |   void Initialize(HKEY root_key, | 
 |                   const char16_t* folder_key, | 
 |                   REGSAM wow64access); | 
 |  | 
 |   // The registry key being iterated. | 
 |   HKEY key_; | 
 |  | 
 |   // Current index of the iteration. | 
 |   int index_; | 
 |  | 
 |   char16_t name_[MAX_PATH]; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(RegistryKeyIterator); | 
 | }; | 
 |  | 
 | }  // namespace win | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_WIN_REGISTRY_H_ |