OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // All Rights Reserved. | |
5 | 4 |
6 #include "base/registry.h" | 5 #include "base/registry.h" |
7 | 6 |
8 #include <assert.h> | |
9 #include <shlwapi.h> | 7 #include <shlwapi.h> |
10 #include <windows.h> | 8 |
| 9 #include "base/logging.h" |
11 | 10 |
12 #pragma comment(lib, "shlwapi.lib") // for SHDeleteKey | 11 #pragma comment(lib, "shlwapi.lib") // for SHDeleteKey |
13 | 12 |
14 // local types (see the same declarations in the header file) | |
15 #define tchar TCHAR | |
16 #define CTP const tchar* | |
17 #define tstr std::basic_string<tchar> | |
18 | |
19 // | |
20 // RegistryValueIterator | |
21 // | |
22 | |
23 RegistryValueIterator::RegistryValueIterator(HKEY root_key, | 13 RegistryValueIterator::RegistryValueIterator(HKEY root_key, |
24 LPCTSTR folder_key) { | 14 const wchar_t* folder_key) { |
25 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 15 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
26 if (result != ERROR_SUCCESS) { | 16 if (result != ERROR_SUCCESS) { |
27 key_ = NULL; | 17 key_ = NULL; |
28 } else { | 18 } else { |
29 DWORD count = 0; | 19 DWORD count = 0; |
30 result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, | 20 result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, |
31 NULL, NULL, NULL, NULL); | 21 NULL, NULL, NULL, NULL); |
32 | 22 |
33 if (result != ERROR_SUCCESS) { | 23 if (result != ERROR_SUCCESS) { |
34 ::RegCloseKey(key_); | 24 ::RegCloseKey(key_); |
35 key_ = NULL; | 25 key_ = NULL; |
36 } else { | 26 } else { |
37 index_ = count - 1; | 27 index_ = count - 1; |
38 } | 28 } |
39 } | 29 } |
40 | 30 |
41 Read(); | 31 Read(); |
42 } | 32 } |
43 | 33 |
44 RegistryValueIterator::~RegistryValueIterator() { | 34 RegistryValueIterator::~RegistryValueIterator() { |
45 if (key_) | 35 if (key_) |
46 ::RegCloseKey(key_); | 36 ::RegCloseKey(key_); |
47 } | 37 } |
48 | 38 |
49 bool RegistryValueIterator::Valid() const { | 39 bool RegistryValueIterator::Valid() const { |
50 // true while the iterator is valid | |
51 return key_ != NULL && index_ >= 0; | 40 return key_ != NULL && index_ >= 0; |
52 } | 41 } |
53 | 42 |
54 void RegistryValueIterator::operator++() { | 43 void RegistryValueIterator::operator++() { |
55 // advance to the next entry in the folder | |
56 --index_; | 44 --index_; |
57 Read(); | 45 Read(); |
58 } | 46 } |
59 | 47 |
60 bool RegistryValueIterator::Read() { | 48 bool RegistryValueIterator::Read() { |
61 if (Valid()) { | 49 if (Valid()) { |
62 DWORD ncount = sizeof(name_)/sizeof(*name_); | 50 DWORD ncount = arraysize(name_); |
63 value_size_ = sizeof(value_); | 51 value_size_ = sizeof(value_); |
64 LRESULT r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, | 52 LRESULT r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, |
65 reinterpret_cast<BYTE*>(value_), &value_size_); | 53 reinterpret_cast<BYTE*>(value_), &value_size_); |
66 if (ERROR_SUCCESS == r) | 54 if (ERROR_SUCCESS == r) |
67 return true; | 55 return true; |
68 } | 56 } |
69 | 57 |
70 name_[0] = '\0'; | 58 name_[0] = '\0'; |
71 value_[0] = '\0'; | 59 value_[0] = '\0'; |
72 value_size_ = 0; | 60 value_size_ = 0; |
73 return false; | 61 return false; |
74 } | 62 } |
75 | 63 |
76 DWORD RegistryValueIterator::ValueCount() const { | 64 DWORD RegistryValueIterator::ValueCount() const { |
77 | |
78 DWORD count = 0; | 65 DWORD count = 0; |
79 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, | 66 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, |
80 &count, NULL, NULL, NULL, NULL); | 67 &count, NULL, NULL, NULL, NULL); |
81 | 68 |
82 if (result != ERROR_SUCCESS) | 69 if (result != ERROR_SUCCESS) |
83 return 0; | 70 return 0; |
84 | 71 |
85 return count; | 72 return count; |
86 } | 73 } |
87 | 74 |
88 // | |
89 // RegistryKeyIterator | |
90 // | |
91 | |
92 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, | 75 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, |
93 LPCTSTR folder_key) { | 76 const wchar_t* folder_key) { |
94 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 77 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
95 if (result != ERROR_SUCCESS) { | 78 if (result != ERROR_SUCCESS) { |
96 key_ = NULL; | 79 key_ = NULL; |
97 } else { | 80 } else { |
98 DWORD count = 0; | 81 DWORD count = 0; |
99 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 82 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
100 NULL, NULL, NULL, NULL, NULL); | 83 NULL, NULL, NULL, NULL, NULL); |
101 | 84 |
102 if (result != ERROR_SUCCESS) { | 85 if (result != ERROR_SUCCESS) { |
103 ::RegCloseKey(key_); | 86 ::RegCloseKey(key_); |
104 key_ = NULL; | 87 key_ = NULL; |
105 } else { | 88 } else { |
106 index_ = count - 1; | 89 index_ = count - 1; |
107 } | 90 } |
108 } | 91 } |
109 | 92 |
110 Read(); | 93 Read(); |
111 } | 94 } |
112 | 95 |
113 RegistryKeyIterator::~RegistryKeyIterator() { | 96 RegistryKeyIterator::~RegistryKeyIterator() { |
114 if (key_) | 97 if (key_) |
115 ::RegCloseKey(key_); | 98 ::RegCloseKey(key_); |
116 } | 99 } |
117 | 100 |
118 bool RegistryKeyIterator::Valid() const { | 101 bool RegistryKeyIterator::Valid() const { |
119 // true while the iterator is valid | |
120 return key_ != NULL && index_ >= 0; | 102 return key_ != NULL && index_ >= 0; |
121 } | 103 } |
122 | 104 |
123 void RegistryKeyIterator::operator++() { | 105 void RegistryKeyIterator::operator++() { |
124 // advance to the next entry in the folder | |
125 --index_; | 106 --index_; |
126 Read(); | 107 Read(); |
127 } | 108 } |
128 | 109 |
129 bool RegistryKeyIterator::Read() { | 110 bool RegistryKeyIterator::Read() { |
130 if (Valid()) { | 111 if (Valid()) { |
131 DWORD ncount = sizeof(name_)/sizeof(*name_); | 112 DWORD ncount = arraysize(name_); |
132 FILETIME written; | 113 FILETIME written; |
133 LRESULT r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, | 114 LRESULT r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, |
134 NULL, &written); | 115 NULL, &written); |
135 if (ERROR_SUCCESS == r) | 116 if (ERROR_SUCCESS == r) |
136 return true; | 117 return true; |
137 } | 118 } |
138 | 119 |
139 name_[0] = '\0'; | 120 name_[0] = '\0'; |
140 return false; | 121 return false; |
141 } | 122 } |
142 | 123 |
143 DWORD RegistryKeyIterator::SubkeyCount() const { | 124 DWORD RegistryKeyIterator::SubkeyCount() const { |
144 | |
145 DWORD count = 0; | 125 DWORD count = 0; |
146 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 126 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
147 NULL, NULL, NULL, NULL, NULL); | 127 NULL, NULL, NULL, NULL, NULL); |
148 | 128 |
149 if (result != ERROR_SUCCESS) | 129 if (result != ERROR_SUCCESS) |
150 return 0; | 130 return 0; |
151 | 131 |
152 return count; | 132 return count; |
153 } | 133 } |
154 | 134 |
155 // | 135 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) |
156 // RegKey | 136 : key_(NULL), |
157 // | 137 watch_event_(0) { |
158 | |
159 RegKey::RegKey(HKEY rootkey, const tchar* subkey, REGSAM access) | |
160 : key_(NULL), watch_event_(0) { | |
161 if (rootkey) { | 138 if (rootkey) { |
162 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) | 139 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) |
163 this->Create(rootkey, subkey, access); | 140 Create(rootkey, subkey, access); |
164 else | 141 else |
165 this->Open(rootkey, subkey, access); | 142 Open(rootkey, subkey, access); |
166 } else { | 143 } else { |
167 assert(!subkey); | 144 DCHECK(!subkey); |
168 } | 145 } |
169 } | 146 } |
170 | 147 |
171 void RegKey::Close() { | 148 void RegKey::Close() { |
172 StopWatching(); | 149 StopWatching(); |
173 if (key_) { | 150 if (key_) { |
174 ::RegCloseKey(key_); | 151 ::RegCloseKey(key_); |
175 key_ = NULL; | 152 key_ = NULL; |
176 } | 153 } |
177 } | 154 } |
178 | 155 |
179 bool RegKey::Create(HKEY rootkey, const tchar* subkey, REGSAM access) { | 156 bool RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
180 DWORD disposition_value; | 157 DWORD disposition_value; |
181 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); | 158 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); |
182 } | 159 } |
183 | 160 |
184 bool RegKey::CreateWithDisposition(HKEY rootkey, const tchar* subkey, | 161 bool RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, |
185 DWORD* disposition, REGSAM access) { | 162 DWORD* disposition, REGSAM access) { |
186 assert(rootkey && subkey && access && disposition); | 163 DCHECK(rootkey && subkey && access && disposition); |
187 this->Close(); | 164 Close(); |
188 | 165 |
189 LONG const result = RegCreateKeyEx(rootkey, | 166 LONG result = RegCreateKeyEx(rootkey, |
190 subkey, | 167 subkey, |
191 0, | 168 0, |
192 NULL, | 169 NULL, |
193 REG_OPTION_NON_VOLATILE, | 170 REG_OPTION_NON_VOLATILE, |
194 access, | 171 access, |
195 NULL, | 172 NULL, |
196 &key_, | 173 &key_, |
197 disposition ); | 174 disposition); |
198 if (result != ERROR_SUCCESS) { | 175 if (result != ERROR_SUCCESS) { |
199 key_ = NULL; | 176 key_ = NULL; |
200 return false; | 177 return false; |
201 } | 178 } |
202 | 179 |
203 return true; | 180 return true; |
204 } | 181 } |
205 | 182 |
206 bool RegKey::Open(HKEY rootkey, const tchar* subkey, REGSAM access) { | 183 bool RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
207 assert(rootkey && subkey && access); | 184 DCHECK(rootkey && subkey && access); |
208 this->Close(); | 185 Close(); |
209 | 186 |
210 LONG const result = RegOpenKeyEx(rootkey, subkey, 0, | 187 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); |
211 access, &key_ ); | |
212 if (result != ERROR_SUCCESS) { | 188 if (result != ERROR_SUCCESS) { |
213 key_ = NULL; | 189 key_ = NULL; |
214 return false; | 190 return false; |
215 } | 191 } |
216 | |
217 return true; | 192 return true; |
218 } | 193 } |
219 | 194 |
220 bool RegKey::CreateKey(const tchar* name, REGSAM access) { | 195 bool RegKey::CreateKey(const wchar_t* name, REGSAM access) { |
221 assert(name && access); | 196 DCHECK(name && access); |
222 | 197 |
223 HKEY subkey = NULL; | 198 HKEY subkey = NULL; |
224 LONG const result = RegCreateKeyEx(key_, name, 0, NULL, | 199 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, |
225 REG_OPTION_NON_VOLATILE, | 200 access, NULL, &subkey, NULL); |
226 access, NULL, &subkey, NULL); | 201 Close(); |
227 this->Close(); | |
228 | 202 |
229 key_ = subkey; | 203 key_ = subkey; |
230 return (result == ERROR_SUCCESS); | 204 return (result == ERROR_SUCCESS); |
231 } | 205 } |
232 | 206 |
233 bool RegKey::OpenKey(const tchar* name, REGSAM access) { | 207 bool RegKey::OpenKey(const wchar_t* name, REGSAM access) { |
234 assert(name && access); | 208 DCHECK(name && access); |
235 | 209 |
236 HKEY subkey = NULL; | 210 HKEY subkey = NULL; |
237 LONG const result = RegOpenKeyEx(key_, name, 0, access, &subkey); | 211 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); |
238 | 212 |
239 this->Close(); | 213 Close(); |
240 | 214 |
241 key_ = subkey; | 215 key_ = subkey; |
242 return (result == ERROR_SUCCESS); | 216 return (result == ERROR_SUCCESS); |
243 } | 217 } |
244 | 218 |
245 DWORD RegKey::ValueCount() { | 219 DWORD RegKey::ValueCount() { |
246 DWORD count = 0; | 220 DWORD count = 0; |
247 HRESULT const result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, | 221 HRESULT result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, |
248 NULL, &count, NULL, NULL, NULL, NULL); | 222 NULL, &count, NULL, NULL, NULL, NULL); |
249 return (result != ERROR_SUCCESS) ? 0 : count; | 223 return (result != ERROR_SUCCESS) ? 0 : count; |
250 } | 224 } |
251 | 225 |
252 bool RegKey::ReadName(int index, tstr* name) { | 226 bool RegKey::ReadName(int index, std::wstring* name) { |
253 tchar buf[256]; | 227 wchar_t buf[256]; |
254 DWORD bufsize = sizeof(buf)/sizeof(*buf); | 228 DWORD bufsize = arraysize(buf); |
255 LRESULT r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, | 229 LRESULT r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, |
256 NULL, NULL); | 230 NULL, NULL); |
257 if (r != ERROR_SUCCESS) | 231 if (r != ERROR_SUCCESS) |
258 return false; | 232 return false; |
259 if (name) | 233 if (name) |
260 *name = buf; | 234 *name = buf; |
261 return true; | 235 return true; |
262 } | 236 } |
263 | 237 |
264 bool RegKey::ValueExists(const tchar* name) { | 238 bool RegKey::ValueExists(const wchar_t* name) { |
265 if (!key_) return false; | 239 if (!key_) |
266 const HRESULT result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); | 240 return false; |
| 241 HRESULT result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); |
267 return (result == ERROR_SUCCESS); | 242 return (result == ERROR_SUCCESS); |
268 } | 243 } |
269 | 244 |
270 bool RegKey::ReadValue(const tchar* name, void* data, | 245 bool RegKey::ReadValue(const wchar_t* name, void* data, |
271 DWORD* dsize, DWORD* dtype) { | 246 DWORD* dsize, DWORD* dtype) { |
272 if (!key_) return false; | 247 if (!key_) |
273 HRESULT const result = RegQueryValueEx(key_, name, 0, dtype, | 248 return false; |
274 reinterpret_cast<LPBYTE>(data), | 249 HRESULT result = RegQueryValueEx(key_, name, 0, dtype, |
275 dsize); | 250 reinterpret_cast<LPBYTE>(data), dsize); |
276 return (result == ERROR_SUCCESS); | 251 return (result == ERROR_SUCCESS); |
277 } | 252 } |
278 | 253 |
279 bool RegKey::ReadValue(const tchar* name, tstr * value) { | 254 bool RegKey::ReadValue(const wchar_t* name, std::wstring* value) { |
280 assert(value); | 255 DCHECK(value); |
281 static const size_t kMaxStringLength = 1024; // This is after expansion. | 256 const size_t kMaxStringLength = 1024; // This is after expansion. |
282 // Use the one of the other forms of ReadValue if 1024 is too small for you. | 257 // Use the one of the other forms of ReadValue if 1024 is too small for you. |
283 TCHAR raw_value[kMaxStringLength]; | 258 wchar_t raw_value[kMaxStringLength]; |
284 DWORD type = REG_SZ, size = sizeof(raw_value); | 259 DWORD type = REG_SZ, size = sizeof(raw_value); |
285 if (this->ReadValue(name, raw_value, &size, &type)) { | 260 if (ReadValue(name, raw_value, &size, &type)) { |
286 if (type == REG_SZ) { | 261 if (type == REG_SZ) { |
287 *value = raw_value; | 262 *value = raw_value; |
288 } else if (type == REG_EXPAND_SZ) { | 263 } else if (type == REG_EXPAND_SZ) { |
289 TCHAR expanded[kMaxStringLength]; | 264 wchar_t expanded[kMaxStringLength]; |
290 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); | 265 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); |
291 // Success: returns the number of TCHARs copied | 266 // Success: returns the number of wchar_t's copied |
292 // Fail: buffer too small, returns the size required | 267 // Fail: buffer too small, returns the size required |
293 // Fail: other, returns 0 | 268 // Fail: other, returns 0 |
294 if (size == 0 || size > kMaxStringLength) | 269 if (size == 0 || size > kMaxStringLength) |
295 return false; | 270 return false; |
296 *value = expanded; | 271 *value = expanded; |
297 } else { | 272 } else { |
298 // Not a string. Oops. | 273 // Not a string. Oops. |
299 return false; | 274 return false; |
300 } | 275 } |
301 return true; | 276 return true; |
302 } | 277 } |
303 | 278 |
304 return false; | 279 return false; |
305 } | 280 } |
306 | 281 |
307 bool RegKey::ReadValueDW(const tchar* name, DWORD * value) { | 282 bool RegKey::ReadValueDW(const wchar_t* name, DWORD* value) { |
308 assert(value); | 283 DCHECK(value); |
309 DWORD type = REG_DWORD, size = sizeof(DWORD), result = 0; | 284 DWORD type = REG_DWORD; |
310 if (this->ReadValue(name, &result, &size, &type) | 285 DWORD size = sizeof(DWORD); |
311 && (type == REG_DWORD || type == REG_BINARY) | 286 DWORD result = 0; |
312 && size == sizeof(DWORD)) { | 287 if (ReadValue(name, &result, &size, &type) && |
| 288 (type == REG_DWORD || type == REG_BINARY) && |
| 289 size == sizeof(DWORD)) { |
313 *value = result; | 290 *value = result; |
314 return true; | 291 return true; |
315 } | 292 } |
316 | 293 |
317 return false; | 294 return false; |
318 } | 295 } |
319 | 296 |
320 bool RegKey::WriteValue(const tchar* name, | 297 bool RegKey::WriteValue(const wchar_t* name, const void * data, |
321 const void * data, | 298 DWORD dsize, DWORD dtype) { |
322 DWORD dsize, | 299 DCHECK(data); |
323 DWORD dtype) { | 300 |
324 assert(data); | 301 if (!key_) |
325 if (!key_) return false; | 302 return false; |
326 HRESULT const result = RegSetValueEx( | 303 |
| 304 HRESULT result = RegSetValueEx( |
327 key_, | 305 key_, |
328 name, | 306 name, |
329 0, | 307 0, |
330 dtype, | 308 dtype, |
331 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), | 309 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), |
332 dsize); | 310 dsize); |
333 return (result == ERROR_SUCCESS); | 311 return (result == ERROR_SUCCESS); |
334 } | 312 } |
335 | 313 |
336 bool RegKey::WriteValue(const tchar * name, const tchar * value) { | 314 bool RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { |
337 return this->WriteValue(name, value, | 315 return WriteValue(name, value, |
338 static_cast<DWORD>(sizeof(*value) * (_tcslen(value) + 1)), REG_SZ); | 316 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); |
339 } | 317 } |
340 | 318 |
341 bool RegKey::WriteValue(const tchar * name, DWORD value) { | 319 bool RegKey::WriteValue(const wchar_t* name, DWORD value) { |
342 return this->WriteValue(name, &value, | 320 return WriteValue(name, &value, |
343 static_cast<DWORD>(sizeof(value)), REG_DWORD); | 321 static_cast<DWORD>(sizeof(value)), REG_DWORD); |
344 } | 322 } |
345 | 323 |
346 bool RegKey::DeleteKey(const tchar * name) { | 324 bool RegKey::DeleteKey(const wchar_t* name) { |
347 if (!key_) return false; | 325 return (!key_) ? false : (ERROR_SUCCESS == SHDeleteKey(key_, name)); |
348 return (ERROR_SUCCESS == SHDeleteKey(key_, name)); | |
349 } | 326 } |
350 | 327 |
351 | 328 bool RegKey::DeleteValue(const wchar_t* value_name) { |
352 bool RegKey::DeleteValue(const tchar * value_name) { | 329 DCHECK(value_name); |
353 assert(value_name); | 330 HRESULT result = RegDeleteValue(key_, value_name); |
354 HRESULT const result = RegDeleteValue(key_, value_name); | |
355 return (result == ERROR_SUCCESS); | 331 return (result == ERROR_SUCCESS); |
356 } | 332 } |
357 | 333 |
358 bool RegKey::StartWatching() { | 334 bool RegKey::StartWatching() { |
359 if (!watch_event_) | 335 if (!watch_event_) |
360 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); | 336 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); |
361 | 337 |
362 DWORD filter = REG_NOTIFY_CHANGE_NAME | | 338 DWORD filter = REG_NOTIFY_CHANGE_NAME | |
363 REG_NOTIFY_CHANGE_ATTRIBUTES | | 339 REG_NOTIFY_CHANGE_ATTRIBUTES | |
364 REG_NOTIFY_CHANGE_LAST_SET | | 340 REG_NOTIFY_CHANGE_LAST_SET | |
(...skipping 22 matching lines...) Expand all Loading... |
387 | 363 |
388 bool RegKey::HasChanged() { | 364 bool RegKey::HasChanged() { |
389 if (watch_event_) { | 365 if (watch_event_) { |
390 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { | 366 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { |
391 StartWatching(); | 367 StartWatching(); |
392 return true; | 368 return true; |
393 } | 369 } |
394 } | 370 } |
395 return false; | 371 return false; |
396 } | 372 } |
397 | |
398 // Register a COM object with the most usual properties. | |
399 bool RegisterCOMServer(const tchar* guid, | |
400 const tchar* name, | |
401 const tchar* path) { | |
402 RegKey key(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_WRITE); | |
403 key.CreateKey(guid, KEY_WRITE); | |
404 key.WriteValue(NULL, name); | |
405 key.CreateKey(_T("InprocServer32"), KEY_WRITE); | |
406 key.WriteValue(NULL, path); | |
407 key.WriteValue(_T("ThreadingModel"), _T("Apartment")); | |
408 return true; | |
409 } | |
410 | |
411 bool RegisterCOMServer(const tchar* guid, const tchar* name, HINSTANCE module) { | |
412 tchar module_path[MAX_PATH]; | |
413 ::GetModuleFileName(module, module_path, MAX_PATH); | |
414 _tcslwr_s(module_path, MAX_PATH); | |
415 return RegisterCOMServer(guid, name, module_path); | |
416 } | |
417 | |
418 bool UnregisterCOMServer(const tchar* guid) { | |
419 RegKey key(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_WRITE); | |
420 key.DeleteKey(guid); | |
421 return true; | |
422 } | |
OLD | NEW |