michael@0: // Copyright (c) 2012 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef BASE_WIN_REGISTRY_H_ michael@0: #define BASE_WIN_REGISTRY_H_ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "base/base_export.h" michael@0: #include "base/basictypes.h" michael@0: #include "base/stl_util.h" michael@0: michael@0: namespace base { michael@0: namespace win { michael@0: michael@0: // Utility class to read, write and manipulate the Windows Registry. michael@0: // Registry vocabulary primer: a "key" is like a folder, in which there michael@0: // are "values", which are pairs, with an associated data type. michael@0: // michael@0: // Note: michael@0: // ReadValue family of functions guarantee that the return arguments michael@0: // are not touched in case of failure. michael@0: class BASE_EXPORT RegKey { michael@0: public: michael@0: RegKey(); michael@0: explicit RegKey(HKEY key); michael@0: RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access); michael@0: ~RegKey(); michael@0: michael@0: LONG Create(HKEY rootkey, const wchar_t* subkey, REGSAM access); michael@0: michael@0: LONG CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, michael@0: DWORD* disposition, REGSAM access); michael@0: michael@0: // Creates a subkey or open it if it already exists. michael@0: LONG CreateKey(const wchar_t* name, REGSAM access); michael@0: michael@0: // Opens an existing reg key. michael@0: LONG Open(HKEY rootkey, const wchar_t* subkey, REGSAM access); michael@0: michael@0: // Opens an existing reg key, given the relative key name. michael@0: LONG OpenKey(const wchar_t* relative_key_name, REGSAM access); michael@0: michael@0: // Closes this reg key. michael@0: void Close(); michael@0: michael@0: // Replaces the handle of the registry key and takes ownership of the handle. michael@0: void Set(HKEY key); michael@0: michael@0: // Transfers ownership away from this object. michael@0: HKEY Take(); michael@0: michael@0: // Returns false if this key does not have the specified value, of if an error michael@0: // occurrs while attempting to access it. michael@0: bool HasValue(const wchar_t* value_name) const; michael@0: michael@0: // Returns the number of values for this key, of 0 if the number cannot be michael@0: // determined. michael@0: DWORD GetValueCount() const; michael@0: michael@0: // Determine the nth value's name. michael@0: LONG GetValueNameAt(int index, std::wstring* name) const; michael@0: michael@0: // True while the key is valid. michael@0: bool Valid() const { return key_ != NULL; } michael@0: michael@0: // Kill a key and everything that live below it; please be careful when using michael@0: // it. michael@0: LONG DeleteKey(const wchar_t* name); michael@0: michael@0: // Deletes a single value within the key. michael@0: LONG DeleteValue(const wchar_t* name); michael@0: michael@0: // Getters: michael@0: michael@0: // Returns an int32 value. If |name| is NULL or empty, returns the default michael@0: // value, if any. michael@0: LONG ReadValueDW(const wchar_t* name, DWORD* out_value) const; michael@0: michael@0: // Returns an int64 value. If |name| is NULL or empty, returns the default michael@0: // value, if any. michael@0: LONG ReadInt64(const wchar_t* name, int64* out_value) const; michael@0: michael@0: // Returns a string value. If |name| is NULL or empty, returns the default michael@0: // value, if any. michael@0: LONG ReadValue(const wchar_t* name, std::wstring* out_value) const; michael@0: michael@0: // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears michael@0: // |values| initially and adds further strings to the list. Returns michael@0: // ERROR_CANTREAD if type is not REG_MULTI_SZ. michael@0: LONG ReadValues(const wchar_t* name, std::vector* values); michael@0: michael@0: // Returns raw data. If |name| is NULL or empty, returns the default michael@0: // value, if any. michael@0: LONG ReadValue(const wchar_t* name, michael@0: void* data, michael@0: DWORD* dsize, michael@0: DWORD* dtype) const; michael@0: michael@0: // Setters: michael@0: michael@0: // Sets an int32 value. michael@0: LONG WriteValue(const wchar_t* name, DWORD in_value); michael@0: michael@0: // Sets a string value. michael@0: LONG WriteValue(const wchar_t* name, const wchar_t* in_value); michael@0: michael@0: // Sets raw data, including type. michael@0: LONG WriteValue(const wchar_t* name, michael@0: const void* data, michael@0: DWORD dsize, michael@0: DWORD dtype); michael@0: michael@0: // Starts watching the key to see if any of its values have changed. michael@0: // The key must have been opened with the KEY_NOTIFY access privilege. michael@0: LONG StartWatching(); michael@0: michael@0: // If StartWatching hasn't been called, always returns false. michael@0: // Otherwise, returns true if anything under the key has changed. michael@0: // This can't be const because the |watch_event_| may be refreshed. michael@0: bool HasChanged(); michael@0: michael@0: // Will automatically be called by destructor if not manually called michael@0: // beforehand. Returns true if it was watching, false otherwise. michael@0: LONG StopWatching(); michael@0: michael@0: inline bool IsWatching() const { return watch_event_ != 0; } michael@0: HANDLE watch_event() const { return watch_event_; } michael@0: HKEY Handle() const { return key_; } michael@0: michael@0: private: michael@0: HKEY key_; // The registry key being iterated. michael@0: HANDLE watch_event_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(RegKey); michael@0: }; michael@0: michael@0: // Iterates the entries found in a particular folder on the registry. michael@0: class BASE_EXPORT RegistryValueIterator { michael@0: public: michael@0: RegistryValueIterator(HKEY root_key, const wchar_t* folder_key); michael@0: michael@0: ~RegistryValueIterator(); michael@0: michael@0: DWORD ValueCount() const; michael@0: michael@0: // True while the iterator is valid. michael@0: bool Valid() const; michael@0: michael@0: // Advances to the next registry entry. michael@0: void operator++(); michael@0: michael@0: const wchar_t* Name() const { return name_.c_str(); } michael@0: const wchar_t* Value() const { return vector_as_array(&value_); } michael@0: // ValueSize() is in bytes. michael@0: DWORD ValueSize() const { return value_size_; } michael@0: DWORD Type() const { return type_; } michael@0: michael@0: int Index() const { return index_; } michael@0: michael@0: private: michael@0: // Read in the current values. michael@0: bool Read(); michael@0: michael@0: // The registry key being iterated. michael@0: HKEY key_; michael@0: michael@0: // Current index of the iteration. michael@0: int index_; michael@0: michael@0: // Current values. michael@0: std::wstring name_; michael@0: std::vector value_; michael@0: DWORD value_size_; michael@0: DWORD type_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(RegistryValueIterator); michael@0: }; michael@0: michael@0: class BASE_EXPORT RegistryKeyIterator { michael@0: public: michael@0: RegistryKeyIterator(HKEY root_key, const wchar_t* folder_key); michael@0: michael@0: ~RegistryKeyIterator(); michael@0: michael@0: DWORD SubkeyCount() const; michael@0: michael@0: // True while the iterator is valid. michael@0: bool Valid() const; michael@0: michael@0: // Advances to the next entry in the folder. michael@0: void operator++(); michael@0: michael@0: const wchar_t* Name() const { return name_; } michael@0: michael@0: int Index() const { return index_; } michael@0: michael@0: private: michael@0: // Read in the current values. michael@0: bool Read(); michael@0: michael@0: // The registry key being iterated. michael@0: HKEY key_; michael@0: michael@0: // Current index of the iteration. michael@0: int index_; michael@0: michael@0: wchar_t name_[MAX_PATH]; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(RegistryKeyIterator); michael@0: }; michael@0: michael@0: } // namespace win michael@0: } // namespace base michael@0: michael@0: #endif // BASE_WIN_REGISTRY_H_