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