1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_WIN_REGISTRY_H_
6#define BASE_WIN_REGISTRY_H_
7#pragma once
8
9#include <windows.h>
10#include <string>
11
12#include "base/base_api.h"
13#include "base/basictypes.h"
14
15namespace base {
16namespace win {
17
18// Utility class to read, write and manipulate the Windows Registry.
19// Registry vocabulary primer: a "key" is like a folder, in which there
20// are "values", which are <name, data> pairs, with an associated data type.
21//
22// Note:
23// ReadValue family of functions guarantee that the return arguments
24// are not touched in case of failure.
25class BASE_API RegKey {
26 public:
27  RegKey();
28  RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access);
29  ~RegKey();
30
31  LONG Create(HKEY rootkey, const wchar_t* subkey, REGSAM access);
32
33  LONG CreateWithDisposition(HKEY rootkey, const wchar_t* subkey,
34                             DWORD* disposition, REGSAM access);
35
36  LONG Open(HKEY rootkey, const wchar_t* subkey, REGSAM access);
37
38  // Creates a subkey or open it if it already exists.
39  LONG CreateKey(const wchar_t* name, REGSAM access);
40
41  // Opens a subkey
42  LONG OpenKey(const wchar_t* name, REGSAM access);
43
44  void Close();
45
46  DWORD ValueCount() const;
47
48  // Determine the nth value's name.
49  LONG ReadName(int index, std::wstring* name) const;
50
51  // True while the key is valid.
52  bool Valid() const { return key_ != NULL; }
53
54  // Kill a key and everything that live below it; please be careful when using
55  // it.
56  LONG DeleteKey(const wchar_t* name);
57
58  // Deletes a single value within the key.
59  LONG DeleteValue(const wchar_t* name);
60
61  bool ValueExists(const wchar_t* name) const;
62
63  LONG ReadValue(const wchar_t* name, void* data, DWORD* dsize,
64                 DWORD* dtype) const;
65  LONG ReadValue(const wchar_t* name, std::wstring* value) const;
66  LONG ReadValueDW(const wchar_t* name, DWORD* value) const;
67  LONG ReadInt64(const wchar_t* name, int64* value) const;
68
69  LONG WriteValue(const wchar_t* name, const void* data, DWORD dsize,
70                  DWORD dtype);
71  LONG WriteValue(const wchar_t* name, const wchar_t* value);
72  LONG WriteValue(const wchar_t* name, DWORD value);
73
74  // Starts watching the key to see if any of its values have changed.
75  // The key must have been opened with the KEY_NOTIFY access privilege.
76  LONG StartWatching();
77
78  // If StartWatching hasn't been called, always returns false.
79  // Otherwise, returns true if anything under the key has changed.
80  // This can't be const because the |watch_event_| may be refreshed.
81  bool HasChanged();
82
83  // Will automatically be called by destructor if not manually called
84  // beforehand.  Returns true if it was watching, false otherwise.
85  LONG StopWatching();
86
87  inline bool IsWatching() const { return watch_event_ != 0; }
88  HANDLE watch_event() const { return watch_event_; }
89  HKEY Handle() const { return key_; }
90
91 private:
92  HKEY key_;  // The registry key being iterated.
93  HANDLE watch_event_;
94
95  DISALLOW_COPY_AND_ASSIGN(RegKey);
96};
97
98// Iterates the entries found in a particular folder on the registry.
99// For this application I happen to know I wont need data size larger
100// than MAX_PATH, but in real life this wouldn't neccessarily be
101// adequate.
102class BASE_API RegistryValueIterator {
103 public:
104  RegistryValueIterator(HKEY root_key, const wchar_t* folder_key);
105
106  ~RegistryValueIterator();
107
108  DWORD ValueCount() const;
109
110  // True while the iterator is valid.
111  bool Valid() const;
112
113  // Advances to the next registry entry.
114  void operator++();
115
116  const wchar_t* Name() const { return name_; }
117  const wchar_t* Value() const { return value_; }
118  DWORD ValueSize() const { return value_size_; }
119  DWORD Type() const { return type_; }
120
121  int Index() const { return index_; }
122
123 private:
124  // Read in the current values.
125  bool Read();
126
127  // The registry key being iterated.
128  HKEY key_;
129
130  // Current index of the iteration.
131  int index_;
132
133  // Current values.
134  wchar_t name_[MAX_PATH];
135  wchar_t value_[MAX_PATH];
136  DWORD value_size_;
137  DWORD type_;
138
139  DISALLOW_COPY_AND_ASSIGN(RegistryValueIterator);
140};
141
142class BASE_API RegistryKeyIterator {
143 public:
144  RegistryKeyIterator(HKEY root_key, const wchar_t* folder_key);
145
146  ~RegistryKeyIterator();
147
148  DWORD SubkeyCount() const;
149
150  // True while the iterator is valid.
151  bool Valid() const;
152
153  // Advances to the next entry in the folder.
154  void operator++();
155
156  const wchar_t* Name() const { return name_; }
157
158  int Index() const { return index_; }
159
160 private:
161  // Read in the current values.
162  bool Read();
163
164  // The registry key being iterated.
165  HKEY key_;
166
167  // Current index of the iteration.
168  int index_;
169
170  wchar_t name_[MAX_PATH];
171
172  DISALLOW_COPY_AND_ASSIGN(RegistryKeyIterator);
173};
174
175}  // namespace win
176}  // namespace base
177
178#endif  // BASE_WIN_REGISTRY_H_
179