1 // Copyright (c) 2006-2008 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 // All Rights Reserved.
5
6 #ifndef BASE_REGISTRY_H__
7 #define BASE_REGISTRY_H__
8
9 #include <windows.h>
10 #include <tchar.h>
11 #include <shlwapi.h>
12 #include <string>
13
14 // The shared file uses a bunch of header files that define types that we don't.
15 // To avoid changing much code from the standard version, and also to avoid
16 // polluting our namespace with extra types we don't want, we define these types
17 // here with the preprocessor and undefine them at the end of the file.
18 #define tchar TCHAR
19 #define CTP const tchar*
20 #define tstr std::basic_string<tchar>
21
22 // RegKey
23 // Utility class to read from and manipulate the registry.
24 // Registry vocabulary primer: a "key" is like a folder, in which there
25 // are "values", which are <name,data> pairs, with an associated data type.
26
27 class RegKey {
28 public:
29 RegKey(HKEY rootkey = NULL, CTP subkey = NULL, REGSAM access = KEY_READ);
30 // start there
31
~RegKey()32 ~RegKey() { this->Close(); }
33
34 bool Create(HKEY rootkey, CTP subkey, REGSAM access = KEY_READ);
35
36 bool CreateWithDisposition(HKEY rootkey, CTP subkey, DWORD* disposition,
37 REGSAM access = KEY_READ);
38
39 bool Open(HKEY rootkey, CTP subkey, REGSAM access = KEY_READ);
40
41 // Create a subkey (or open if exists)
42 bool CreateKey(CTP name, REGSAM access);
43
44 // Open a subkey
45 bool OpenKey(CTP name, REGSAM access);
46
47 // all done, eh?
48 void Close();
49
50 DWORD ValueCount(); // Count of the number of value extant
51
52 bool ReadName(int index, tstr* name); // Determine the Nth value's name
53
54 // True while the key is valid
Valid()55 bool Valid() const { return NULL != key_; }
56
57 // Kill key and everything that liveth below it; please be careful out there
58 bool DeleteKey(CTP name);
59
60 // Delete a single value within the key
61 bool DeleteValue(CTP name);
62
63 bool ValueExists(CTP name);
64 bool ReadValue(CTP name, void * data, DWORD * dsize, DWORD * dtype = NULL);
65 bool ReadValue(CTP name, tstr * value);
66 bool ReadValueDW(CTP name, DWORD * value); // Named to differ from tstr*
67
68 bool WriteValue(CTP name, const void * data, DWORD dsize,
69 DWORD dtype = REG_BINARY);
70 bool WriteValue(CTP name, CTP value);
71 bool WriteValue(CTP name, DWORD value);
72
73 // StartWatching()
74 // Start watching the key to see if any of its values have changed.
75 // The key must have been opened with the KEY_NOTIFY access
76 // privelege.
77 bool StartWatching();
78
79 // HasChanged()
80 // If StartWatching hasn't been called, always returns false.
81 // Otherwise, returns true if anything under the key has changed.
82 // This can't be const because the watch_event_ may be refreshed.
83 bool HasChanged();
84
85 // StopWatching()
86 // Will automatically be called by destructor if not manually called
87 // beforehand. Returns true if it was watching, false otherwise.
88 bool StopWatching();
89
IsWatching()90 inline bool IsWatching() const { return watch_event_ != 0; }
watch_event()91 HANDLE watch_event() const { return watch_event_; }
Handle()92 HKEY Handle() const { return key_; }
93
94 private:
95 HKEY key_; // the registry key being iterated
96 HANDLE watch_event_;
97 };
98
99
100 // Standalone registry functions -- sorta deprecated, they now map to
101 // using RegKey
102
103
104 // Add a raw data to the registry -- you can pass NULL for the data if
105 // you just want to create a key
106 inline bool AddToRegistry(HKEY root_key, CTP key, CTP value_name,
107 void const * data, DWORD dsize,
108 DWORD dtype = REG_BINARY) {
109 return RegKey(root_key, key, KEY_WRITE).WriteValue(value_name, data, dsize,
110 dtype);
111 }
112
113 // Convenience routine to add a string value to the registry
AddToRegistry(HKEY root_key,CTP key,CTP value_name,CTP value)114 inline bool AddToRegistry(HKEY root_key, CTP key, CTP value_name, CTP value) {
115 return AddToRegistry(root_key, key, value_name, value,
116 sizeof(*value) * (lstrlen(value) + 1), REG_SZ);
117 }
118
119 // Read raw data from the registry -- pass something as the dtype
120 // parameter if you care to learn what type the value was stored as
121 inline bool ReadFromRegistry(HKEY root_key, CTP key, CTP value_name,
122 void* data, DWORD* dsize, DWORD* dtype = NULL) {
123 return RegKey(root_key, key).ReadValue(value_name, data, dsize, dtype);
124 }
125
126
127 // Delete a value or a key from the registry
DeleteFromRegistry(HKEY root_key,CTP subkey,CTP value_name)128 inline bool DeleteFromRegistry(HKEY root_key, CTP subkey, CTP value_name) {
129 if (value_name)
130 return ERROR_SUCCESS == ::SHDeleteValue(root_key, subkey, value_name);
131 else
132 return ERROR_SUCCESS == ::SHDeleteKey(root_key, subkey);
133 }
134
135
136
137 // delete a key and all subkeys from the registry
DeleteKeyFromRegistry(HKEY root_key,CTP key_path,CTP key_name)138 inline bool DeleteKeyFromRegistry(HKEY root_key, CTP key_path, CTP key_name) {
139 RegKey key;
140 return key.Open(root_key, key_path, KEY_WRITE)
141 && key.DeleteKey(key_name);
142 }
143
144
145 // Iterates the entries found in a particular folder on the registry.
146 // For this application I happen to know I wont need data size larger
147 // than MAX_PATH, but in real life this wouldn't neccessarily be
148 // adequate.
149 class RegistryValueIterator {
150 public:
151 // Specify a key in construction
152 RegistryValueIterator(HKEY root_key, LPCTSTR folder_key);
153
154 ~RegistryValueIterator();
155
156 DWORD ValueCount() const; // count of the number of subkeys extant
157
158 bool Valid() const; // true while the iterator is valid
159
160 void operator++(); // advance to the next entry in the folder
161
162 // The pointers returned by these functions are statics owned by the
163 // Name and Value functions
Name()164 CTP Name() const { return name_; }
Value()165 CTP Value() const { return value_; }
ValueSize()166 DWORD ValueSize() const { return value_size_; }
Type()167 DWORD Type() const { return type_; }
168
Index()169 int Index() const { return index_; }
170
171 private:
172 bool Read(); // read in the current values
173
174 HKEY key_; // the registry key being iterated
175 int index_; // current index of the iteration
176
177 // Current values
178 TCHAR name_[MAX_PATH];
179 TCHAR value_[MAX_PATH];
180 DWORD value_size_;
181 DWORD type_;
182 };
183
184
185 class RegistryKeyIterator {
186 public:
187 // Specify a parent key in construction
188 RegistryKeyIterator(HKEY root_key, LPCTSTR folder_key);
189
190 ~RegistryKeyIterator();
191
192 DWORD SubkeyCount() const; // count of the number of subkeys extant
193
194 bool Valid() const; // true while the iterator is valid
195
196 void operator++(); // advance to the next entry in the folder
197
198 // The pointer returned by Name() is a static owned by the function
Name()199 CTP Name() const { return name_; }
200
Index()201 int Index() const { return index_; }
202
203 private:
204 bool Read(); // read in the current values
205
206 HKEY key_; // the registry key being iterated
207 int index_; // current index of the iteration
208
209 // Current values
210 TCHAR name_[MAX_PATH];
211 };
212
213
214 // Register a COM object with the most usual properties.
215 bool RegisterCOMServer(const tchar* guid, const tchar* name,
216 const tchar* modulepath);
217 bool RegisterCOMServer(const tchar* guid, const tchar* name, HINSTANCE module);
218 bool UnregisterCOMServer(const tchar* guid);
219
220 // undo the local types defined above
221 #undef tchar
222 #undef CTP
223 #undef tstr
224
225 #endif // BASE_REGISTRY_H__
226