|
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 |
|
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 |
|
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 |
|
90 inline bool IsWatching() const { return watch_event_ != 0; } |
|
91 HANDLE watch_event() const { return watch_event_; } |
|
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 |
|
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 |
|
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 |
|
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 |
|
164 CTP Name() const { return name_; } |
|
165 CTP Value() const { return value_; } |
|
166 DWORD ValueSize() const { return value_size_; } |
|
167 DWORD Type() const { return type_; } |
|
168 |
|
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 |
|
199 CTP Name() const { return name_; } |
|
200 |
|
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__ |