16d528ed9Sopenharmony_ci// Copyright (c) 2012 The Chromium Authors. All rights reserved. 26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 36d528ed9Sopenharmony_ci// found in the LICENSE file. 46d528ed9Sopenharmony_ci 56d528ed9Sopenharmony_ci#ifndef BASE_WIN_REGISTRY_H_ 66d528ed9Sopenharmony_ci#define BASE_WIN_REGISTRY_H_ 76d528ed9Sopenharmony_ci 86d528ed9Sopenharmony_ci#include <stdint.h> 96d528ed9Sopenharmony_ci#include <windows.h> 106d528ed9Sopenharmony_ci#include <string> 116d528ed9Sopenharmony_ci#include <vector> 126d528ed9Sopenharmony_ci 136d528ed9Sopenharmony_ci#include "base/win/scoped_handle.h" 146d528ed9Sopenharmony_ci 156d528ed9Sopenharmony_cinamespace base { 166d528ed9Sopenharmony_cinamespace win { 176d528ed9Sopenharmony_ci 186d528ed9Sopenharmony_ci// Utility class to read, write and manipulate the Windows Registry. 196d528ed9Sopenharmony_ci// Registry vocabulary primer: a "key" is like a folder, in which there 206d528ed9Sopenharmony_ci// are "values", which are <name, data> pairs, with an associated data type. 216d528ed9Sopenharmony_ci// 226d528ed9Sopenharmony_ci// Note: 236d528ed9Sopenharmony_ci// * ReadValue family of functions guarantee that the out-parameter 246d528ed9Sopenharmony_ci// is not touched in case of failure. 256d528ed9Sopenharmony_ci// * Functions returning LONG indicate success as ERROR_SUCCESS or an 266d528ed9Sopenharmony_ci// error as a (non-zero) win32 error code. 276d528ed9Sopenharmony_ciclass RegKey { 286d528ed9Sopenharmony_ci public: 296d528ed9Sopenharmony_ci RegKey(); 306d528ed9Sopenharmony_ci explicit RegKey(HKEY key); 316d528ed9Sopenharmony_ci RegKey(HKEY rootkey, const char16_t* subkey, REGSAM access); 326d528ed9Sopenharmony_ci ~RegKey(); 336d528ed9Sopenharmony_ci 346d528ed9Sopenharmony_ci LONG Create(HKEY rootkey, const char16_t* subkey, REGSAM access); 356d528ed9Sopenharmony_ci 366d528ed9Sopenharmony_ci LONG CreateWithDisposition(HKEY rootkey, 376d528ed9Sopenharmony_ci const char16_t* subkey, 386d528ed9Sopenharmony_ci DWORD* disposition, 396d528ed9Sopenharmony_ci REGSAM access); 406d528ed9Sopenharmony_ci 416d528ed9Sopenharmony_ci // Creates a subkey or open it if it already exists. 426d528ed9Sopenharmony_ci LONG CreateKey(const char16_t* name, REGSAM access); 436d528ed9Sopenharmony_ci 446d528ed9Sopenharmony_ci // Opens an existing reg key. 456d528ed9Sopenharmony_ci LONG Open(HKEY rootkey, const char16_t* subkey, REGSAM access); 466d528ed9Sopenharmony_ci 476d528ed9Sopenharmony_ci // Opens an existing reg key, given the relative key name. 486d528ed9Sopenharmony_ci LONG OpenKey(const char16_t* relative_key_name, REGSAM access); 496d528ed9Sopenharmony_ci 506d528ed9Sopenharmony_ci // Closes this reg key. 516d528ed9Sopenharmony_ci void Close(); 526d528ed9Sopenharmony_ci 536d528ed9Sopenharmony_ci // Replaces the handle of the registry key and takes ownership of the handle. 546d528ed9Sopenharmony_ci void Set(HKEY key); 556d528ed9Sopenharmony_ci 566d528ed9Sopenharmony_ci // Transfers ownership away from this object. 576d528ed9Sopenharmony_ci HKEY Take(); 586d528ed9Sopenharmony_ci 596d528ed9Sopenharmony_ci // Returns false if this key does not have the specified value, or if an error 606d528ed9Sopenharmony_ci // occurs while attempting to access it. 616d528ed9Sopenharmony_ci bool HasValue(const char16_t* value_name) const; 626d528ed9Sopenharmony_ci 636d528ed9Sopenharmony_ci // Returns the number of values for this key, or 0 if the number cannot be 646d528ed9Sopenharmony_ci // determined. 656d528ed9Sopenharmony_ci DWORD GetValueCount() const; 666d528ed9Sopenharmony_ci 676d528ed9Sopenharmony_ci // Determines the nth value's name. 686d528ed9Sopenharmony_ci LONG GetValueNameAt(int index, std::u16string* name) const; 696d528ed9Sopenharmony_ci 706d528ed9Sopenharmony_ci // True while the key is valid. 716d528ed9Sopenharmony_ci bool Valid() const { return key_ != NULL; } 726d528ed9Sopenharmony_ci 736d528ed9Sopenharmony_ci // Kills a key and everything that lives below it; please be careful when 746d528ed9Sopenharmony_ci // using it. 756d528ed9Sopenharmony_ci LONG DeleteKey(const char16_t* name); 766d528ed9Sopenharmony_ci 776d528ed9Sopenharmony_ci // Deletes an empty subkey. If the subkey has subkeys or values then this 786d528ed9Sopenharmony_ci // will fail. 796d528ed9Sopenharmony_ci LONG DeleteEmptyKey(const char16_t* name); 806d528ed9Sopenharmony_ci 816d528ed9Sopenharmony_ci // Deletes a single value within the key. 826d528ed9Sopenharmony_ci LONG DeleteValue(const char16_t* name); 836d528ed9Sopenharmony_ci 846d528ed9Sopenharmony_ci // Getters: 856d528ed9Sopenharmony_ci 866d528ed9Sopenharmony_ci // Reads a REG_DWORD (uint32_t) into |out_value|. If |name| is null or empty, 876d528ed9Sopenharmony_ci // reads the key's default value, if any. 886d528ed9Sopenharmony_ci LONG ReadValueDW(const char16_t* name, DWORD* out_value) const; 896d528ed9Sopenharmony_ci 906d528ed9Sopenharmony_ci // Reads a REG_QWORD (int64_t) into |out_value|. If |name| is null or empty, 916d528ed9Sopenharmony_ci // reads the key's default value, if any. 926d528ed9Sopenharmony_ci LONG ReadInt64(const char16_t* name, int64_t* out_value) const; 936d528ed9Sopenharmony_ci 946d528ed9Sopenharmony_ci // Reads a string into |out_value|. If |name| is null or empty, reads 956d528ed9Sopenharmony_ci // the key's default value, if any. 966d528ed9Sopenharmony_ci LONG ReadValue(const char16_t* name, std::u16string* out_value) const; 976d528ed9Sopenharmony_ci 986d528ed9Sopenharmony_ci // Reads a REG_MULTI_SZ registry field into a vector of strings. Clears 996d528ed9Sopenharmony_ci // |values| initially and adds further strings to the list. Returns 1006d528ed9Sopenharmony_ci // ERROR_CANTREAD if type is not REG_MULTI_SZ. 1016d528ed9Sopenharmony_ci LONG ReadValues(const char16_t* name, std::vector<std::u16string>* values); 1026d528ed9Sopenharmony_ci 1036d528ed9Sopenharmony_ci // Reads raw data into |data|. If |name| is null or empty, reads the key's 1046d528ed9Sopenharmony_ci // default value, if any. 1056d528ed9Sopenharmony_ci LONG ReadValue(const char16_t* name, 1066d528ed9Sopenharmony_ci void* data, 1076d528ed9Sopenharmony_ci DWORD* dsize, 1086d528ed9Sopenharmony_ci DWORD* dtype) const; 1096d528ed9Sopenharmony_ci 1106d528ed9Sopenharmony_ci // Setters: 1116d528ed9Sopenharmony_ci 1126d528ed9Sopenharmony_ci // Sets an int32_t value. 1136d528ed9Sopenharmony_ci LONG WriteValue(const char16_t* name, DWORD in_value); 1146d528ed9Sopenharmony_ci 1156d528ed9Sopenharmony_ci // Sets a string value. 1166d528ed9Sopenharmony_ci LONG WriteValue(const char16_t* name, const char16_t* in_value); 1176d528ed9Sopenharmony_ci 1186d528ed9Sopenharmony_ci // Sets raw data, including type. 1196d528ed9Sopenharmony_ci LONG WriteValue(const char16_t* name, 1206d528ed9Sopenharmony_ci const void* data, 1216d528ed9Sopenharmony_ci DWORD dsize, 1226d528ed9Sopenharmony_ci DWORD dtype); 1236d528ed9Sopenharmony_ci 1246d528ed9Sopenharmony_ci HKEY Handle() const { return key_; } 1256d528ed9Sopenharmony_ci 1266d528ed9Sopenharmony_ci private: 1276d528ed9Sopenharmony_ci // Calls RegDeleteKeyEx on supported platforms, alternatively falls back to 1286d528ed9Sopenharmony_ci // RegDeleteKey. 1296d528ed9Sopenharmony_ci static LONG RegDeleteKeyExWrapper(HKEY hKey, 1306d528ed9Sopenharmony_ci const char16_t* lpSubKey, 1316d528ed9Sopenharmony_ci REGSAM samDesired, 1326d528ed9Sopenharmony_ci DWORD Reserved); 1336d528ed9Sopenharmony_ci 1346d528ed9Sopenharmony_ci // Recursively deletes a key and all of its subkeys. 1356d528ed9Sopenharmony_ci static LONG RegDelRecurse(HKEY root_key, 1366d528ed9Sopenharmony_ci const std::u16string& name, 1376d528ed9Sopenharmony_ci REGSAM access); 1386d528ed9Sopenharmony_ci 1396d528ed9Sopenharmony_ci HKEY key_; // The registry key being iterated. 1406d528ed9Sopenharmony_ci REGSAM wow64access_; 1416d528ed9Sopenharmony_ci 1426d528ed9Sopenharmony_ci RegKey(const RegKey&) = delete; 1436d528ed9Sopenharmony_ci RegKey& operator=(const RegKey&) = delete; 1446d528ed9Sopenharmony_ci}; 1456d528ed9Sopenharmony_ci 1466d528ed9Sopenharmony_ci// Iterates the entries found in a particular folder on the registry. 1476d528ed9Sopenharmony_ciclass RegistryValueIterator { 1486d528ed9Sopenharmony_ci public: 1496d528ed9Sopenharmony_ci // Constructs a Registry Value Iterator with default WOW64 access. 1506d528ed9Sopenharmony_ci RegistryValueIterator(HKEY root_key, const char16_t* folder_key); 1516d528ed9Sopenharmony_ci 1526d528ed9Sopenharmony_ci // Constructs a Registry Key Iterator with specific WOW64 access, one of 1536d528ed9Sopenharmony_ci // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0. 1546d528ed9Sopenharmony_ci // Note: |wow64access| should be the same access used to open |root_key| 1556d528ed9Sopenharmony_ci // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE). 1566d528ed9Sopenharmony_ci // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx. 1576d528ed9Sopenharmony_ci RegistryValueIterator(HKEY root_key, 1586d528ed9Sopenharmony_ci const char16_t* folder_key, 1596d528ed9Sopenharmony_ci REGSAM wow64access); 1606d528ed9Sopenharmony_ci 1616d528ed9Sopenharmony_ci ~RegistryValueIterator(); 1626d528ed9Sopenharmony_ci 1636d528ed9Sopenharmony_ci DWORD ValueCount() const; 1646d528ed9Sopenharmony_ci 1656d528ed9Sopenharmony_ci // True while the iterator is valid. 1666d528ed9Sopenharmony_ci bool Valid() const; 1676d528ed9Sopenharmony_ci 1686d528ed9Sopenharmony_ci // Advances to the next registry entry. 1696d528ed9Sopenharmony_ci void operator++(); 1706d528ed9Sopenharmony_ci 1716d528ed9Sopenharmony_ci const char16_t* Name() const { return name_.c_str(); } 1726d528ed9Sopenharmony_ci const char16_t* Value() const { return value_.data(); } 1736d528ed9Sopenharmony_ci // ValueSize() is in bytes. 1746d528ed9Sopenharmony_ci DWORD ValueSize() const { return value_size_; } 1756d528ed9Sopenharmony_ci DWORD Type() const { return type_; } 1766d528ed9Sopenharmony_ci 1776d528ed9Sopenharmony_ci int Index() const { return index_; } 1786d528ed9Sopenharmony_ci 1796d528ed9Sopenharmony_ci private: 1806d528ed9Sopenharmony_ci // Reads in the current values. 1816d528ed9Sopenharmony_ci bool Read(); 1826d528ed9Sopenharmony_ci 1836d528ed9Sopenharmony_ci void Initialize(HKEY root_key, 1846d528ed9Sopenharmony_ci const char16_t* folder_key, 1856d528ed9Sopenharmony_ci REGSAM wow64access); 1866d528ed9Sopenharmony_ci 1876d528ed9Sopenharmony_ci // The registry key being iterated. 1886d528ed9Sopenharmony_ci HKEY key_; 1896d528ed9Sopenharmony_ci 1906d528ed9Sopenharmony_ci // Current index of the iteration. 1916d528ed9Sopenharmony_ci int index_; 1926d528ed9Sopenharmony_ci 1936d528ed9Sopenharmony_ci // Current values. 1946d528ed9Sopenharmony_ci std::u16string name_; 1956d528ed9Sopenharmony_ci std::vector<char16_t> value_; 1966d528ed9Sopenharmony_ci DWORD value_size_; 1976d528ed9Sopenharmony_ci DWORD type_; 1986d528ed9Sopenharmony_ci 1996d528ed9Sopenharmony_ci RegistryValueIterator(const RegistryValueIterator&) = delete; 2006d528ed9Sopenharmony_ci RegistryValueIterator& operator=(const RegistryValueIterator&) = delete; 2016d528ed9Sopenharmony_ci}; 2026d528ed9Sopenharmony_ci 2036d528ed9Sopenharmony_ciclass RegistryKeyIterator { 2046d528ed9Sopenharmony_ci public: 2056d528ed9Sopenharmony_ci // Constructs a Registry Key Iterator with default WOW64 access. 2066d528ed9Sopenharmony_ci RegistryKeyIterator(HKEY root_key, const char16_t* folder_key); 2076d528ed9Sopenharmony_ci 2086d528ed9Sopenharmony_ci // Constructs a Registry Value Iterator with specific WOW64 access, one of 2096d528ed9Sopenharmony_ci // KEY_WOW64_32KEY or KEY_WOW64_64KEY, or 0. 2106d528ed9Sopenharmony_ci // Note: |wow64access| should be the same access used to open |root_key| 2116d528ed9Sopenharmony_ci // previously, or a predefined key (e.g. HKEY_LOCAL_MACHINE). 2126d528ed9Sopenharmony_ci // See http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129.aspx. 2136d528ed9Sopenharmony_ci RegistryKeyIterator(HKEY root_key, 2146d528ed9Sopenharmony_ci const char16_t* folder_key, 2156d528ed9Sopenharmony_ci REGSAM wow64access); 2166d528ed9Sopenharmony_ci 2176d528ed9Sopenharmony_ci ~RegistryKeyIterator(); 2186d528ed9Sopenharmony_ci 2196d528ed9Sopenharmony_ci DWORD SubkeyCount() const; 2206d528ed9Sopenharmony_ci 2216d528ed9Sopenharmony_ci // True while the iterator is valid. 2226d528ed9Sopenharmony_ci bool Valid() const; 2236d528ed9Sopenharmony_ci 2246d528ed9Sopenharmony_ci // Advances to the next entry in the folder. 2256d528ed9Sopenharmony_ci void operator++(); 2266d528ed9Sopenharmony_ci 2276d528ed9Sopenharmony_ci const char16_t* Name() const { return name_; } 2286d528ed9Sopenharmony_ci 2296d528ed9Sopenharmony_ci int Index() const { return index_; } 2306d528ed9Sopenharmony_ci 2316d528ed9Sopenharmony_ci private: 2326d528ed9Sopenharmony_ci // Reads in the current values. 2336d528ed9Sopenharmony_ci bool Read(); 2346d528ed9Sopenharmony_ci 2356d528ed9Sopenharmony_ci void Initialize(HKEY root_key, 2366d528ed9Sopenharmony_ci const char16_t* folder_key, 2376d528ed9Sopenharmony_ci REGSAM wow64access); 2386d528ed9Sopenharmony_ci 2396d528ed9Sopenharmony_ci // The registry key being iterated. 2406d528ed9Sopenharmony_ci HKEY key_; 2416d528ed9Sopenharmony_ci 2426d528ed9Sopenharmony_ci // Current index of the iteration. 2436d528ed9Sopenharmony_ci int index_; 2446d528ed9Sopenharmony_ci 2456d528ed9Sopenharmony_ci char16_t name_[MAX_PATH]; 2466d528ed9Sopenharmony_ci 2476d528ed9Sopenharmony_ci RegistryKeyIterator(const RegistryKeyIterator&) = delete; 2486d528ed9Sopenharmony_ci RegistryKeyIterator& operator=(const RegistryKeyIterator&) = delete; 2496d528ed9Sopenharmony_ci}; 2506d528ed9Sopenharmony_ci 2516d528ed9Sopenharmony_ci} // namespace win 2526d528ed9Sopenharmony_ci} // namespace base 2536d528ed9Sopenharmony_ci 2546d528ed9Sopenharmony_ci#endif // BASE_WIN_REGISTRY_H_ 255