OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 | 4 |
5 #include "base/win/registry.h" | 5 #include "base/win/registry.h" |
6 | 6 |
7 #include <shlwapi.h> | 7 #include <shlwapi.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 Open(rootkey, subkey, access); | 32 Open(rootkey, subkey, access); |
33 } else { | 33 } else { |
34 DCHECK(!subkey); | 34 DCHECK(!subkey); |
35 } | 35 } |
36 } | 36 } |
37 | 37 |
38 RegKey::~RegKey() { | 38 RegKey::~RegKey() { |
39 Close(); | 39 Close(); |
40 } | 40 } |
41 | 41 |
42 bool RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { | 42 GONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
43 DWORD disposition_value; | 43 DWORD disposition_value; |
44 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); | 44 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); |
45 } | 45 } |
46 | 46 |
47 bool RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, | 47 GONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, |
48 DWORD* disposition, REGSAM access) { | 48 DWORD* disposition, REGSAM access) { |
49 base::ThreadRestrictions::AssertIOAllowed(); | 49 base::ThreadRestrictions::AssertIOAllowed(); |
50 DCHECK(rootkey && subkey && access && disposition); | 50 DCHECK(rootkey && subkey && access && disposition); |
51 Close(); | 51 Close(); |
52 | 52 |
53 LONG result = RegCreateKeyEx(rootkey, | 53 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL, |
54 subkey, | 54 REG_OPTION_NON_VOLATILE, access, NULL, &key_, |
55 0, | |
56 NULL, | |
57 REG_OPTION_NON_VOLATILE, | |
58 access, | |
59 NULL, | |
60 &key_, | |
61 disposition); | 55 disposition); |
62 if (result != ERROR_SUCCESS) { | 56 return result; |
63 key_ = NULL; | |
64 return false; | |
65 } | |
66 | |
67 return true; | |
68 } | 57 } |
69 | 58 |
70 bool RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { | 59 GONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { |
71 base::ThreadRestrictions::AssertIOAllowed(); | 60 base::ThreadRestrictions::AssertIOAllowed(); |
72 DCHECK(rootkey && subkey && access); | 61 DCHECK(rootkey && subkey && access); |
73 Close(); | 62 Close(); |
74 | 63 |
75 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); | 64 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); |
76 if (result != ERROR_SUCCESS) { | 65 return result; |
77 key_ = NULL; | |
78 return false; | |
79 } | |
80 return true; | |
81 } | 66 } |
82 | 67 |
83 bool RegKey::CreateKey(const wchar_t* name, REGSAM access) { | 68 GONG RegKey::CreateKey(const wchar_t* name, REGSAM access) { |
84 base::ThreadRestrictions::AssertIOAllowed(); | 69 base::ThreadRestrictions::AssertIOAllowed(); |
85 DCHECK(name && access); | 70 DCHECK(name && access); |
86 | 71 |
87 HKEY subkey = NULL; | 72 HKEY subkey = NULL; |
88 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, | 73 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, |
89 access, NULL, &subkey, NULL); | 74 access, NULL, &subkey, NULL); |
90 Close(); | 75 Close(); |
91 | 76 |
92 key_ = subkey; | 77 key_ = subkey; |
93 return (result == ERROR_SUCCESS); | 78 return result; |
94 } | 79 } |
95 | 80 |
96 bool RegKey::OpenKey(const wchar_t* name, REGSAM access) { | 81 GONG RegKey::OpenKey(const wchar_t* name, REGSAM access) { |
97 base::ThreadRestrictions::AssertIOAllowed(); | 82 base::ThreadRestrictions::AssertIOAllowed(); |
98 DCHECK(name && access); | 83 DCHECK(name && access); |
99 | 84 |
100 HKEY subkey = NULL; | 85 HKEY subkey = NULL; |
101 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); | 86 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); |
102 | 87 |
103 Close(); | 88 Close(); |
104 | 89 |
105 key_ = subkey; | 90 key_ = subkey; |
106 return (result == ERROR_SUCCESS); | 91 return result; |
107 } | 92 } |
108 | 93 |
109 void RegKey::Close() { | 94 void RegKey::Close() { |
110 base::ThreadRestrictions::AssertIOAllowed(); | 95 base::ThreadRestrictions::AssertIOAllowed(); |
111 StopWatching(); | 96 StopWatching(); |
112 if (key_) { | 97 if (key_) { |
113 ::RegCloseKey(key_); | 98 ::RegCloseKey(key_); |
114 key_ = NULL; | 99 key_ = NULL; |
115 } | 100 } |
116 } | 101 } |
117 | 102 |
118 DWORD RegKey::ValueCount() const { | 103 DWORD RegKey::ValueCount() const { |
119 base::ThreadRestrictions::AssertIOAllowed(); | 104 base::ThreadRestrictions::AssertIOAllowed(); |
120 DWORD count = 0; | 105 DWORD count = 0; |
121 HRESULT result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, | 106 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, |
122 NULL, &count, NULL, NULL, NULL, NULL); | 107 NULL, NULL, NULL, NULL); |
123 return (result != ERROR_SUCCESS) ? 0 : count; | 108 return (result != ERROR_SUCCESS) ? 0 : count; |
124 } | 109 } |
125 | 110 |
126 bool RegKey::ReadName(int index, std::wstring* name) const { | 111 GONG RegKey::ReadName(int index, std::wstring* name) const { |
127 base::ThreadRestrictions::AssertIOAllowed(); | 112 base::ThreadRestrictions::AssertIOAllowed(); |
128 wchar_t buf[256]; | 113 wchar_t buf[256]; |
129 DWORD bufsize = arraysize(buf); | 114 DWORD bufsize = arraysize(buf); |
130 LRESULT r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, | 115 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL); |
131 NULL, NULL); | 116 if (r == ERROR_SUCCESS) |
132 if (r != ERROR_SUCCESS) | |
133 return false; | |
134 if (name) | |
135 *name = buf; | 117 *name = buf; |
136 return true; | 118 |
| 119 return r; |
137 } | 120 } |
138 | 121 |
139 bool RegKey::DeleteKey(const wchar_t* name) { | 122 GONG RegKey::DeleteKey(const wchar_t* name) { |
140 base::ThreadRestrictions::AssertIOAllowed(); | 123 base::ThreadRestrictions::AssertIOAllowed(); |
141 if (!key_) | 124 DCHECK(key_); |
142 return false; | 125 DCHECK(name); |
143 LSTATUS ret = SHDeleteKey(key_, name); | 126 LONG result = SHDeleteKey(key_, name); |
144 if (ERROR_SUCCESS != ret) | 127 return result; |
145 SetLastError(ret); | |
146 return ERROR_SUCCESS == ret; | |
147 } | 128 } |
148 | 129 |
149 bool RegKey::DeleteValue(const wchar_t* value_name) { | 130 GONG RegKey::DeleteValue(const wchar_t* value_name) { |
150 base::ThreadRestrictions::AssertIOAllowed(); | 131 base::ThreadRestrictions::AssertIOAllowed(); |
| 132 DCHECK(key_); |
151 DCHECK(value_name); | 133 DCHECK(value_name); |
152 HRESULT result = RegDeleteValue(key_, value_name); | 134 LONG result = RegDeleteValue(key_, value_name); |
153 return (result == ERROR_SUCCESS); | 135 return result; |
154 } | 136 } |
155 | 137 |
156 bool RegKey::ValueExists(const wchar_t* name) { | 138 bool RegKey::ValueExists(const wchar_t* name) const { |
157 base::ThreadRestrictions::AssertIOAllowed(); | 139 base::ThreadRestrictions::AssertIOAllowed(); |
158 if (!key_) | 140 LONG result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); |
159 return false; | 141 return result == ERROR_SUCCESS; |
160 HRESULT result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); | |
161 return (result == ERROR_SUCCESS); | |
162 } | 142 } |
163 | 143 |
164 bool RegKey::ReadValue(const wchar_t* name, void* data, | 144 GONG RegKey::ReadValue(const wchar_t* name, void* data, DWORD* dsize, |
165 DWORD* dsize, DWORD* dtype) const { | 145 DWORD* dtype) const { |
166 base::ThreadRestrictions::AssertIOAllowed(); | 146 base::ThreadRestrictions::AssertIOAllowed(); |
167 if (!key_) | 147 LONG result = RegQueryValueEx(key_, name, 0, dtype, |
168 return false; | 148 reinterpret_cast<LPBYTE>(data), dsize); |
169 HRESULT result = RegQueryValueEx(key_, name, 0, dtype, | 149 return result; |
170 reinterpret_cast<LPBYTE>(data), dsize); | |
171 return (result == ERROR_SUCCESS); | |
172 } | 150 } |
173 | 151 |
174 bool RegKey::ReadValue(const wchar_t* name, std::wstring* value) const { | 152 GONG RegKey::ReadValue(const wchar_t* name, std::wstring* value) const { |
175 base::ThreadRestrictions::AssertIOAllowed(); | 153 base::ThreadRestrictions::AssertIOAllowed(); |
176 DCHECK(value); | 154 DCHECK(value); |
177 const size_t kMaxStringLength = 1024; // This is after expansion. | 155 const size_t kMaxStringLength = 1024; // This is after expansion. |
178 // Use the one of the other forms of ReadValue if 1024 is too small for you. | 156 // Use the one of the other forms of ReadValue if 1024 is too small for you. |
179 wchar_t raw_value[kMaxStringLength]; | 157 wchar_t raw_value[kMaxStringLength]; |
180 DWORD type = REG_SZ, size = sizeof(raw_value); | 158 DWORD type = REG_SZ, size = sizeof(raw_value); |
181 if (ReadValue(name, raw_value, &size, &type)) { | 159 LONG result = ReadValue(name, raw_value, &size, &type); |
| 160 if (result == ERROR_SUCCESS) { |
182 if (type == REG_SZ) { | 161 if (type == REG_SZ) { |
183 *value = raw_value; | 162 *value = raw_value; |
184 } else if (type == REG_EXPAND_SZ) { | 163 } else if (type == REG_EXPAND_SZ) { |
185 wchar_t expanded[kMaxStringLength]; | 164 wchar_t expanded[kMaxStringLength]; |
186 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); | 165 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); |
187 // Success: returns the number of wchar_t's copied | 166 // Success: returns the number of wchar_t's copied |
188 // Fail: buffer too small, returns the size required | 167 // Fail: buffer too small, returns the size required |
189 // Fail: other, returns 0 | 168 // Fail: other, returns 0 |
190 if (size == 0 || size > kMaxStringLength) | 169 if (size == 0 || size > kMaxStringLength) { |
191 return false; | 170 result = ERROR_MORE_DATA; |
192 *value = expanded; | 171 } else { |
| 172 *value = expanded; |
| 173 } |
193 } else { | 174 } else { |
194 // Not a string. Oops. | 175 // Not a string. Oops. |
195 return false; | 176 result = ERROR_CANTREAD; |
196 } | 177 } |
197 return true; | |
198 } | 178 } |
199 | 179 |
200 return false; | 180 return result; |
201 } | 181 } |
202 | 182 |
203 bool RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const { | 183 GONG RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const { |
204 DCHECK(value); | 184 DCHECK(value); |
205 DWORD type = REG_DWORD; | 185 DWORD type = REG_DWORD; |
206 DWORD size = sizeof(DWORD); | 186 DWORD size = sizeof(DWORD); |
207 DWORD result = 0; | 187 DWORD local_value = 0; |
208 if (ReadValue(name, &result, &size, &type) && | 188 LONG result = ReadValue(name, &local_value, &size, &type); |
209 (type == REG_DWORD || type == REG_BINARY) && | 189 if (result == ERROR_SUCCESS) { |
210 size == sizeof(DWORD)) { | 190 if ((type == REG_DWORD || type == REG_BINARY) && size == sizeof(DWORD)) { |
211 *value = result; | 191 *value = local_value; |
212 return true; | 192 } else { |
| 193 result = ERROR_CANTREAD; |
| 194 } |
213 } | 195 } |
214 | 196 |
215 return false; | 197 return result; |
216 } | 198 } |
217 | 199 |
218 bool RegKey::WriteValue(const wchar_t* name, const void * data, | 200 GONG RegKey::ReadInt64(const wchar_t* name, int64* value) const { |
| 201 DCHECK(value); |
| 202 DWORD type = REG_QWORD; |
| 203 int64 local_value = 0; |
| 204 DWORD size = sizeof(local_value); |
| 205 LONG result = ReadValue(name, &local_value, &size, &type); |
| 206 if (result == ERROR_SUCCESS) { |
| 207 if ((type == REG_QWORD || type == REG_BINARY) && |
| 208 size == sizeof(local_value)) { |
| 209 *value = local_value; |
| 210 } else { |
| 211 result = ERROR_CANTREAD; |
| 212 } |
| 213 } |
| 214 |
| 215 return result; |
| 216 } |
| 217 |
| 218 GONG RegKey::WriteValue(const wchar_t* name, const void * data, |
219 DWORD dsize, DWORD dtype) { | 219 DWORD dsize, DWORD dtype) { |
220 base::ThreadRestrictions::AssertIOAllowed(); | 220 base::ThreadRestrictions::AssertIOAllowed(); |
221 DCHECK(data); | 221 DCHECK(data); |
| 222 DCHECK(key_); |
222 | 223 |
223 if (!key_) | 224 LONG result = RegSetValueEx(key_, name, 0, dtype, |
224 return false; | 225 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); |
225 | 226 return result; |
226 HRESULT result = RegSetValueEx( | |
227 key_, | |
228 name, | |
229 0, | |
230 dtype, | |
231 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), | |
232 dsize); | |
233 return (result == ERROR_SUCCESS); | |
234 } | 227 } |
235 | 228 |
236 bool RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { | 229 GONG RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { |
237 return WriteValue(name, value, | 230 return WriteValue(name, value, |
238 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); | 231 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); |
239 } | 232 } |
240 | 233 |
241 bool RegKey::WriteValue(const wchar_t* name, DWORD value) { | 234 GONG RegKey::WriteValue(const wchar_t* name, DWORD value) { |
242 return WriteValue(name, &value, | 235 return WriteValue(name, &value, static_cast<DWORD>(sizeof(value)), REG_DWORD); |
243 static_cast<DWORD>(sizeof(value)), REG_DWORD); | |
244 } | 236 } |
245 | 237 |
246 bool RegKey::StartWatching() { | 238 GONG RegKey::StartWatching() { |
| 239 DCHECK(key_); |
247 if (!watch_event_) | 240 if (!watch_event_) |
248 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); | 241 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); |
249 | 242 |
250 DWORD filter = REG_NOTIFY_CHANGE_NAME | | 243 DWORD filter = REG_NOTIFY_CHANGE_NAME | |
251 REG_NOTIFY_CHANGE_ATTRIBUTES | | 244 REG_NOTIFY_CHANGE_ATTRIBUTES | |
252 REG_NOTIFY_CHANGE_LAST_SET | | 245 REG_NOTIFY_CHANGE_LAST_SET | |
253 REG_NOTIFY_CHANGE_SECURITY; | 246 REG_NOTIFY_CHANGE_SECURITY; |
254 | 247 |
255 // Watch the registry key for a change of value. | 248 // Watch the registry key for a change of value. |
256 HRESULT result = RegNotifyChangeKeyValue(key_, TRUE, filter, | 249 LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE); |
257 watch_event_, TRUE); | 250 if (result != ERROR_SUCCESS) { |
258 if (SUCCEEDED(result)) { | |
259 return true; | |
260 } else { | |
261 CloseHandle(watch_event_); | 251 CloseHandle(watch_event_); |
262 watch_event_ = 0; | 252 watch_event_ = 0; |
263 return false; | |
264 } | 253 } |
| 254 |
| 255 return result; |
265 } | 256 } |
266 | 257 |
267 bool RegKey::HasChanged() { | 258 bool RegKey::HasChanged() { |
268 if (watch_event_) { | 259 if (watch_event_) { |
269 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { | 260 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { |
270 StartWatching(); | 261 StartWatching(); |
271 return true; | 262 return true; |
272 } | 263 } |
273 } | 264 } |
274 return false; | 265 return false; |
275 } | 266 } |
276 | 267 |
277 bool RegKey::StopWatching() { | 268 GONG RegKey::StopWatching() { |
| 269 LONG result = ERROR_INVALID_HANDLE; |
278 if (watch_event_) { | 270 if (watch_event_) { |
279 CloseHandle(watch_event_); | 271 CloseHandle(watch_event_); |
280 watch_event_ = 0; | 272 watch_event_ = 0; |
281 return true; | 273 result = ERROR_SUCCESS; |
282 } | 274 } |
283 return false; | 275 return result; |
284 } | 276 } |
285 | 277 |
286 // RegistryValueIterator ------------------------------------------------------ | 278 // RegistryValueIterator ------------------------------------------------------ |
287 | 279 |
288 RegistryValueIterator::RegistryValueIterator(HKEY root_key, | 280 RegistryValueIterator::RegistryValueIterator(HKEY root_key, |
289 const wchar_t* folder_key) { | 281 const wchar_t* folder_key) { |
290 base::ThreadRestrictions::AssertIOAllowed(); | 282 base::ThreadRestrictions::AssertIOAllowed(); |
291 | 283 |
292 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 284 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
293 if (result != ERROR_SUCCESS) { | 285 if (result != ERROR_SUCCESS) { |
(...skipping 16 matching lines...) Expand all Loading... |
310 | 302 |
311 RegistryValueIterator::~RegistryValueIterator() { | 303 RegistryValueIterator::~RegistryValueIterator() { |
312 base::ThreadRestrictions::AssertIOAllowed(); | 304 base::ThreadRestrictions::AssertIOAllowed(); |
313 if (key_) | 305 if (key_) |
314 ::RegCloseKey(key_); | 306 ::RegCloseKey(key_); |
315 } | 307 } |
316 | 308 |
317 DWORD RegistryValueIterator::ValueCount() const { | 309 DWORD RegistryValueIterator::ValueCount() const { |
318 base::ThreadRestrictions::AssertIOAllowed(); | 310 base::ThreadRestrictions::AssertIOAllowed(); |
319 DWORD count = 0; | 311 DWORD count = 0; |
320 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, | 312 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, |
321 &count, NULL, NULL, NULL, NULL); | 313 &count, NULL, NULL, NULL, NULL); |
322 | |
323 if (result != ERROR_SUCCESS) | 314 if (result != ERROR_SUCCESS) |
324 return 0; | 315 return 0; |
325 | 316 |
326 return count; | 317 return count; |
327 } | 318 } |
328 | 319 |
329 bool RegistryValueIterator::Valid() const { | 320 bool RegistryValueIterator::Valid() const { |
330 return key_ != NULL && index_ >= 0; | 321 return key_ != NULL && index_ >= 0; |
331 } | 322 } |
332 | 323 |
333 void RegistryValueIterator::operator++() { | 324 void RegistryValueIterator::operator++() { |
334 --index_; | 325 --index_; |
335 Read(); | 326 Read(); |
336 } | 327 } |
337 | 328 |
338 bool RegistryValueIterator::Read() { | 329 bool RegistryValueIterator::Read() { |
339 base::ThreadRestrictions::AssertIOAllowed(); | 330 base::ThreadRestrictions::AssertIOAllowed(); |
340 if (Valid()) { | 331 if (Valid()) { |
341 DWORD ncount = arraysize(name_); | 332 DWORD ncount = arraysize(name_); |
342 value_size_ = sizeof(value_); | 333 value_size_ = sizeof(value_); |
343 LRESULT r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, | 334 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, |
344 reinterpret_cast<BYTE*>(value_), &value_size_); | 335 reinterpret_cast<BYTE*>(value_), &value_size_); |
345 if (ERROR_SUCCESS == r) | 336 if (ERROR_SUCCESS == r) |
346 return true; | 337 return true; |
347 } | 338 } |
348 | 339 |
349 name_[0] = '\0'; | 340 name_[0] = '\0'; |
350 value_[0] = '\0'; | 341 value_[0] = '\0'; |
351 value_size_ = 0; | 342 value_size_ = 0; |
352 return false; | 343 return false; |
353 } | 344 } |
354 | 345 |
355 // RegistryKeyIterator -------------------------------------------------------- | 346 // RegistryKeyIterator -------------------------------------------------------- |
356 | 347 |
357 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, | 348 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, |
358 const wchar_t* folder_key) { | 349 const wchar_t* folder_key) { |
359 base::ThreadRestrictions::AssertIOAllowed(); | 350 base::ThreadRestrictions::AssertIOAllowed(); |
360 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); | 351 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); |
361 if (result != ERROR_SUCCESS) { | 352 if (result != ERROR_SUCCESS) { |
362 key_ = NULL; | 353 key_ = NULL; |
363 } else { | 354 } else { |
364 DWORD count = 0; | 355 DWORD count = 0; |
365 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 356 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
366 NULL, NULL, NULL, NULL, NULL); | 357 NULL, NULL, NULL, NULL, NULL); |
367 | 358 |
368 if (result != ERROR_SUCCESS) { | 359 if (result != ERROR_SUCCESS) { |
369 ::RegCloseKey(key_); | 360 ::RegCloseKey(key_); |
370 key_ = NULL; | 361 key_ = NULL; |
371 } else { | 362 } else { |
372 index_ = count - 1; | 363 index_ = count - 1; |
373 } | 364 } |
374 } | 365 } |
375 | 366 |
376 Read(); | 367 Read(); |
377 } | 368 } |
378 | 369 |
379 RegistryKeyIterator::~RegistryKeyIterator() { | 370 RegistryKeyIterator::~RegistryKeyIterator() { |
380 base::ThreadRestrictions::AssertIOAllowed(); | 371 base::ThreadRestrictions::AssertIOAllowed(); |
381 if (key_) | 372 if (key_) |
382 ::RegCloseKey(key_); | 373 ::RegCloseKey(key_); |
383 } | 374 } |
384 | 375 |
385 DWORD RegistryKeyIterator::SubkeyCount() const { | 376 DWORD RegistryKeyIterator::SubkeyCount() const { |
386 base::ThreadRestrictions::AssertIOAllowed(); | 377 base::ThreadRestrictions::AssertIOAllowed(); |
387 DWORD count = 0; | 378 DWORD count = 0; |
388 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, | 379 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, |
389 NULL, NULL, NULL, NULL, NULL); | 380 NULL, NULL, NULL, NULL, NULL); |
390 | |
391 if (result != ERROR_SUCCESS) | 381 if (result != ERROR_SUCCESS) |
392 return 0; | 382 return 0; |
393 | 383 |
394 return count; | 384 return count; |
395 } | 385 } |
396 | 386 |
397 bool RegistryKeyIterator::Valid() const { | 387 bool RegistryKeyIterator::Valid() const { |
398 return key_ != NULL && index_ >= 0; | 388 return key_ != NULL && index_ >= 0; |
399 } | 389 } |
400 | 390 |
401 void RegistryKeyIterator::operator++() { | 391 void RegistryKeyIterator::operator++() { |
402 --index_; | 392 --index_; |
403 Read(); | 393 Read(); |
404 } | 394 } |
405 | 395 |
406 bool RegistryKeyIterator::Read() { | 396 bool RegistryKeyIterator::Read() { |
407 base::ThreadRestrictions::AssertIOAllowed(); | 397 base::ThreadRestrictions::AssertIOAllowed(); |
408 if (Valid()) { | 398 if (Valid()) { |
409 DWORD ncount = arraysize(name_); | 399 DWORD ncount = arraysize(name_); |
410 FILETIME written; | 400 FILETIME written; |
411 LRESULT r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, | 401 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, |
412 NULL, &written); | 402 NULL, &written); |
413 if (ERROR_SUCCESS == r) | 403 if (ERROR_SUCCESS == r) |
414 return true; | 404 return true; |
415 } | 405 } |
416 | 406 |
417 name_[0] = '\0'; | 407 name_[0] = '\0'; |
418 return false; | 408 return false; |
419 } | 409 } |
420 | 410 |
421 } // namespace win | 411 } // namespace win |
422 } // namespace base | 412 } // namespace base |
OLD | NEW |