Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: base/win/registry.cc

Issue 6090006: Regkey functions return error code instead of bool (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 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 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 void RegistryValueIterator::operator++() { 50 void RegistryValueIterator::operator++() {
51 --index_; 51 --index_;
52 Read(); 52 Read();
53 } 53 }
54 54
55 bool RegistryValueIterator::Read() { 55 bool RegistryValueIterator::Read() {
56 base::ThreadRestrictions::AssertIOAllowed(); 56 base::ThreadRestrictions::AssertIOAllowed();
57 if (Valid()) { 57 if (Valid()) {
58 DWORD ncount = arraysize(name_); 58 DWORD ncount = arraysize(name_);
59 value_size_ = sizeof(value_); 59 value_size_ = sizeof(value_);
60 LRESULT r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, 60 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_,
61 reinterpret_cast<BYTE*>(value_), &value_size_); 61 reinterpret_cast<BYTE*>(value_), &value_size_);
62 if (ERROR_SUCCESS == r) 62 if (ERROR_SUCCESS == r)
63 return true; 63 return true;
64 } 64 }
65 65
66 name_[0] = '\0'; 66 name_[0] = '\0';
67 value_[0] = '\0'; 67 value_[0] = '\0';
68 value_size_ = 0; 68 value_size_ = 0;
69 return false; 69 return false;
70 } 70 }
71 71
72 DWORD RegistryValueIterator::ValueCount() const { 72 DWORD RegistryValueIterator::ValueCount() const {
73 base::ThreadRestrictions::AssertIOAllowed(); 73 base::ThreadRestrictions::AssertIOAllowed();
74 DWORD count = 0; 74 DWORD count = 0;
75 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, 75 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL,
76 &count, NULL, NULL, NULL, NULL); 76 &count, NULL, NULL, NULL, NULL);
77 77
78 if (result != ERROR_SUCCESS) 78 if (result != ERROR_SUCCESS)
79 return 0; 79 return 0;
80 80
81 return count; 81 return count;
82 } 82 }
83 83
84 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, 84 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
85 const wchar_t* folder_key) { 85 const wchar_t* folder_key) {
86 base::ThreadRestrictions::AssertIOAllowed(); 86 base::ThreadRestrictions::AssertIOAllowed();
87 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); 87 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_);
88 if (result != ERROR_SUCCESS) { 88 if (result != ERROR_SUCCESS) {
89 key_ = NULL; 89 key_ = NULL;
90 } else { 90 } else {
91 DWORD count = 0; 91 DWORD count = 0;
92 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, 92 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
93 NULL, NULL, NULL, NULL, NULL); 93 NULL, NULL, NULL, NULL, NULL);
94 94
95 if (result != ERROR_SUCCESS) { 95 if (result != ERROR_SUCCESS) {
96 ::RegCloseKey(key_); 96 ::RegCloseKey(key_);
97 key_ = NULL; 97 key_ = NULL;
98 } else { 98 } else {
99 index_ = count - 1; 99 index_ = count - 1;
100 } 100 }
101 } 101 }
102 102
103 Read(); 103 Read();
(...skipping 12 matching lines...) Expand all
116 void RegistryKeyIterator::operator++() { 116 void RegistryKeyIterator::operator++() {
117 --index_; 117 --index_;
118 Read(); 118 Read();
119 } 119 }
120 120
121 bool RegistryKeyIterator::Read() { 121 bool RegistryKeyIterator::Read() {
122 base::ThreadRestrictions::AssertIOAllowed(); 122 base::ThreadRestrictions::AssertIOAllowed();
123 if (Valid()) { 123 if (Valid()) {
124 DWORD ncount = arraysize(name_); 124 DWORD ncount = arraysize(name_);
125 FILETIME written; 125 FILETIME written;
126 LRESULT r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, 126 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL,
127 NULL, &written); 127 NULL, &written);
128 if (ERROR_SUCCESS == r) 128 if (ERROR_SUCCESS == r)
129 return true; 129 return true;
130 } 130 }
131 131
132 name_[0] = '\0'; 132 name_[0] = '\0';
133 return false; 133 return false;
134 } 134 }
135 135
136 DWORD RegistryKeyIterator::SubkeyCount() const { 136 DWORD RegistryKeyIterator::SubkeyCount() const {
137 base::ThreadRestrictions::AssertIOAllowed(); 137 base::ThreadRestrictions::AssertIOAllowed();
138 DWORD count = 0; 138 DWORD count = 0;
139 HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, 139 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
140 NULL, NULL, NULL, NULL, NULL); 140 NULL, NULL, NULL, NULL, NULL);
141 141
142 if (result != ERROR_SUCCESS) 142 if (result != ERROR_SUCCESS)
143 return 0; 143 return 0;
144 144
145 return count; 145 return count;
146 } 146 }
147 147
148 RegKey::RegKey() 148 RegKey::RegKey()
149 : key_(NULL), 149 : key_(NULL),
150 watch_event_(0) { 150 watch_event_(0) {
(...skipping 19 matching lines...) Expand all
170 170
171 void RegKey::Close() { 171 void RegKey::Close() {
172 base::ThreadRestrictions::AssertIOAllowed(); 172 base::ThreadRestrictions::AssertIOAllowed();
173 StopWatching(); 173 StopWatching();
174 if (key_) { 174 if (key_) {
175 ::RegCloseKey(key_); 175 ::RegCloseKey(key_);
176 key_ = NULL; 176 key_ = NULL;
177 } 177 }
178 } 178 }
179 179
180 bool RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { 180 GONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
181 DWORD disposition_value; 181 DWORD disposition_value;
182 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); 182 return CreateWithDisposition(rootkey, subkey, &disposition_value, access);
183 } 183 }
184 184
185 bool RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, 185 GONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey,
186 DWORD* disposition, REGSAM access) { 186 DWORD* disposition, REGSAM access) {
187 base::ThreadRestrictions::AssertIOAllowed(); 187 base::ThreadRestrictions::AssertIOAllowed();
188 DCHECK(rootkey && subkey && access && disposition); 188 DCHECK(rootkey && subkey && access && disposition);
189 Close(); 189 Close();
190 190
191 LONG result = RegCreateKeyEx(rootkey, 191 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL,
192 subkey, 192 REG_OPTION_NON_VOLATILE, access, NULL, &key_,
193 0,
194 NULL,
195 REG_OPTION_NON_VOLATILE,
196 access,
197 NULL,
198 &key_,
199 disposition); 193 disposition);
200 if (result != ERROR_SUCCESS) { 194 return result;
201 key_ = NULL;
202 return false;
203 }
204
205 return true;
206 } 195 }
207 196
208 bool RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { 197 GONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
209 base::ThreadRestrictions::AssertIOAllowed(); 198 base::ThreadRestrictions::AssertIOAllowed();
210 DCHECK(rootkey && subkey && access); 199 DCHECK(rootkey && subkey && access);
211 Close(); 200 Close();
212 201
213 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); 202 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_);
214 if (result != ERROR_SUCCESS) { 203 return result;
215 key_ = NULL;
216 return false;
217 }
218 return true;
219 } 204 }
220 205
221 bool RegKey::CreateKey(const wchar_t* name, REGSAM access) { 206 GONG RegKey::CreateKey(const wchar_t* name, REGSAM access) {
222 base::ThreadRestrictions::AssertIOAllowed(); 207 base::ThreadRestrictions::AssertIOAllowed();
223 DCHECK(name && access); 208 DCHECK(name && access);
224 209
225 HKEY subkey = NULL; 210 HKEY subkey = NULL;
226 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, 211 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE,
227 access, NULL, &subkey, NULL); 212 access, NULL, &subkey, NULL);
228 Close(); 213 Close();
229 214
230 key_ = subkey; 215 key_ = subkey;
231 return (result == ERROR_SUCCESS); 216 return result;
232 } 217 }
233 218
234 bool RegKey::OpenKey(const wchar_t* name, REGSAM access) { 219 GONG RegKey::OpenKey(const wchar_t* name, REGSAM access) {
235 base::ThreadRestrictions::AssertIOAllowed(); 220 base::ThreadRestrictions::AssertIOAllowed();
236 DCHECK(name && access); 221 DCHECK(name && access);
237 222
238 HKEY subkey = NULL; 223 HKEY subkey = NULL;
239 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); 224 LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey);
240 225
241 Close(); 226 Close();
242 227
243 key_ = subkey; 228 key_ = subkey;
244 return (result == ERROR_SUCCESS); 229 return result;
245 } 230 }
246 231
247 DWORD RegKey::ValueCount() const { 232 DWORD RegKey::ValueCount() const {
248 base::ThreadRestrictions::AssertIOAllowed(); 233 base::ThreadRestrictions::AssertIOAllowed();
249 DWORD count = 0; 234 DWORD count = 0;
250 HRESULT result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, 235 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count,
251 NULL, &count, NULL, NULL, NULL, NULL); 236 NULL, NULL, NULL, NULL);
252 return (result != ERROR_SUCCESS) ? 0 : count; 237 return (result != ERROR_SUCCESS) ? 0 : count;
253 } 238 }
254 239
255 bool RegKey::ReadName(int index, std::wstring* name) const { 240 GONG RegKey::ReadName(int index, std::wstring* name) const {
256 base::ThreadRestrictions::AssertIOAllowed(); 241 base::ThreadRestrictions::AssertIOAllowed();
257 wchar_t buf[256]; 242 wchar_t buf[256];
258 DWORD bufsize = arraysize(buf); 243 DWORD bufsize = arraysize(buf);
259 LRESULT r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, 244 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL);
260 NULL, NULL); 245 if (r == ERROR_SUCCESS)
261 if (r != ERROR_SUCCESS)
262 return false;
263 if (name)
264 *name = buf; 246 *name = buf;
265 return true; 247
248 return r;
266 } 249 }
267 250
268 bool RegKey::ValueExists(const wchar_t* name) { 251 bool RegKey::ValueExists(const wchar_t* name) const {
269 base::ThreadRestrictions::AssertIOAllowed(); 252 base::ThreadRestrictions::AssertIOAllowed();
270 if (!key_) 253 DCHECK(key_);
271 return false; 254 LONG result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL);
272 HRESULT result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); 255 return result == ERROR_SUCCESS;
273 return (result == ERROR_SUCCESS);
274 } 256 }
275 257
276 bool RegKey::ReadValue(const wchar_t* name, void* data, 258 GONG RegKey::ReadValue(const wchar_t* name, void* data, DWORD* dsize,
277 DWORD* dsize, DWORD* dtype) const { 259 DWORD* dtype) const {
278 base::ThreadRestrictions::AssertIOAllowed(); 260 base::ThreadRestrictions::AssertIOAllowed();
279 if (!key_) 261 DCHECK(key_);
280 return false; 262 LONG result = RegQueryValueEx(key_, name, 0, dtype,
281 HRESULT result = RegQueryValueEx(key_, name, 0, dtype, 263 reinterpret_cast<LPBYTE>(data), dsize);
282 reinterpret_cast<LPBYTE>(data), dsize); 264 return result;
283 return (result == ERROR_SUCCESS);
284 } 265 }
285 266
286 bool RegKey::ReadValue(const wchar_t* name, std::wstring* value) const { 267 GONG RegKey::ReadValue(const wchar_t* name, std::wstring* value) const {
287 base::ThreadRestrictions::AssertIOAllowed(); 268 base::ThreadRestrictions::AssertIOAllowed();
288 DCHECK(value); 269 DCHECK(value);
289 const size_t kMaxStringLength = 1024; // This is after expansion. 270 const size_t kMaxStringLength = 1024; // This is after expansion.
290 // Use the one of the other forms of ReadValue if 1024 is too small for you. 271 // Use the one of the other forms of ReadValue if 1024 is too small for you.
291 wchar_t raw_value[kMaxStringLength]; 272 wchar_t raw_value[kMaxStringLength];
292 DWORD type = REG_SZ, size = sizeof(raw_value); 273 DWORD type = REG_SZ, size = sizeof(raw_value);
293 if (ReadValue(name, raw_value, &size, &type)) { 274 LONG result = ReadValue(name, raw_value, &size, &type);
275 if (result == ERROR_SUCCESS) {
294 if (type == REG_SZ) { 276 if (type == REG_SZ) {
295 *value = raw_value; 277 *value = raw_value;
296 } else if (type == REG_EXPAND_SZ) { 278 } else if (type == REG_EXPAND_SZ) {
297 wchar_t expanded[kMaxStringLength]; 279 wchar_t expanded[kMaxStringLength];
298 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); 280 size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength);
299 // Success: returns the number of wchar_t's copied 281 // Success: returns the number of wchar_t's copied
300 // Fail: buffer too small, returns the size required 282 // Fail: buffer too small, returns the size required
301 // Fail: other, returns 0 283 // Fail: other, returns 0
302 if (size == 0 || size > kMaxStringLength) 284 if (size == 0 || size > kMaxStringLength) {
303 return false; 285 result = ERROR_MORE_DATA;
304 *value = expanded; 286 } else {
287 *value = expanded;
288 }
305 } else { 289 } else {
306 // Not a string. Oops. 290 // Not a string. Oops.
307 return false; 291 result = ERROR_CANTREAD;
308 } 292 }
309 return true;
310 } 293 }
311 294
312 return false; 295 return result;
313 } 296 }
314 297
315 bool RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const { 298 GONG RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const {
316 DCHECK(value); 299 DCHECK(value);
317 DWORD type = REG_DWORD; 300 DWORD type = REG_DWORD;
318 DWORD size = sizeof(DWORD); 301 DWORD size = sizeof(DWORD);
319 DWORD result = 0; 302 DWORD local_value = 0;
320 if (ReadValue(name, &result, &size, &type) && 303 LONG result = ReadValue(name, &local_value, &size, &type);
321 (type == REG_DWORD || type == REG_BINARY) && 304 if (result == ERROR_SUCCESS) {
322 size == sizeof(DWORD)) { 305 if ((type == REG_DWORD || type == REG_BINARY) && size == sizeof(DWORD)) {
323 *value = result; 306 *value = local_value;
324 return true; 307 } else {
308 result = ERROR_CANTREAD;
309 }
325 } 310 }
326 311
327 return false; 312 return result;
328 } 313 }
329 314
330 bool RegKey::WriteValue(const wchar_t* name, const void * data, 315 GONG RegKey::ReadValueQW(const wchar_t* name, int64* value) const {
316 DCHECK(value);
317 DWORD type = REG_QWORD;
318 int64 local_value = 0;
319 DWORD size = sizeof(local_value);
320 LONG result = ReadValue(name, &local_value, &size, &type);
321 if (result == ERROR_SUCCESS) {
322 if ((type == REG_QWORD || type == REG_BINARY) &&
323 size == sizeof(local_value)) {
324 *value = local_value;
325 } else {
326 result = ERROR_CANTREAD;
327 }
328 }
329
330 return result;
331 }
332
333 GONG RegKey::WriteValue(const wchar_t* name, const void * data,
331 DWORD dsize, DWORD dtype) { 334 DWORD dsize, DWORD dtype) {
332 base::ThreadRestrictions::AssertIOAllowed(); 335 base::ThreadRestrictions::AssertIOAllowed();
333 DCHECK(data); 336 DCHECK(data);
337 DCHECK(key_);
334 338
335 if (!key_) 339 LONG result = RegSetValueEx(key_, name, 0, dtype,
336 return false; 340 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
337 341 return result;
338 HRESULT result = RegSetValueEx(
339 key_,
340 name,
341 0,
342 dtype,
343 reinterpret_cast<LPBYTE>(const_cast<void*>(data)),
344 dsize);
345 return (result == ERROR_SUCCESS);
346 } 342 }
347 343
348 bool RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { 344 GONG RegKey::WriteValue(const wchar_t * name, const wchar_t* value) {
349 return WriteValue(name, value, 345 return WriteValue(name, value,
350 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); 346 static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ);
351 } 347 }
352 348
353 bool RegKey::WriteValue(const wchar_t* name, DWORD value) { 349 GONG RegKey::WriteValue(const wchar_t* name, DWORD value) {
354 return WriteValue(name, &value, 350 return WriteValue(name, &value, static_cast<DWORD>(sizeof(value)), REG_DWORD);
355 static_cast<DWORD>(sizeof(value)), REG_DWORD);
356 } 351 }
357 352
358 bool RegKey::DeleteKey(const wchar_t* name) { 353 GONG RegKey::DeleteKey(const wchar_t* name) {
359 base::ThreadRestrictions::AssertIOAllowed(); 354 base::ThreadRestrictions::AssertIOAllowed();
360 if (!key_) 355 DCHECK(key_);
361 return false; 356 DCHECK(name);
362 LSTATUS ret = SHDeleteKey(key_, name); 357 LONG result = SHDeleteKey(key_, name);
363 if (ERROR_SUCCESS != ret) 358 return result;
364 SetLastError(ret);
365 return ERROR_SUCCESS == ret;
366 } 359 }
367 360
368 bool RegKey::DeleteValue(const wchar_t* value_name) { 361 GONG RegKey::DeleteValue(const wchar_t* value_name) {
369 base::ThreadRestrictions::AssertIOAllowed(); 362 base::ThreadRestrictions::AssertIOAllowed();
363 DCHECK(key_);
370 DCHECK(value_name); 364 DCHECK(value_name);
371 HRESULT result = RegDeleteValue(key_, value_name); 365 LONG result = RegDeleteValue(key_, value_name);
372 return (result == ERROR_SUCCESS); 366 return result;
373 } 367 }
374 368
375 bool RegKey::StartWatching() { 369 GONG RegKey::StartWatching() {
370 DCHECK(key_);
376 if (!watch_event_) 371 if (!watch_event_)
377 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); 372 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
378 373
379 DWORD filter = REG_NOTIFY_CHANGE_NAME | 374 DWORD filter = REG_NOTIFY_CHANGE_NAME |
380 REG_NOTIFY_CHANGE_ATTRIBUTES | 375 REG_NOTIFY_CHANGE_ATTRIBUTES |
381 REG_NOTIFY_CHANGE_LAST_SET | 376 REG_NOTIFY_CHANGE_LAST_SET |
382 REG_NOTIFY_CHANGE_SECURITY; 377 REG_NOTIFY_CHANGE_SECURITY;
383 378
384 // Watch the registry key for a change of value. 379 // Watch the registry key for a change of value.
385 HRESULT result = RegNotifyChangeKeyValue(key_, TRUE, filter, 380 LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE);
386 watch_event_, TRUE); 381 if (result != ERROR_SUCCESS) {
387 if (SUCCEEDED(result)) {
388 return true;
389 } else {
390 CloseHandle(watch_event_); 382 CloseHandle(watch_event_);
391 watch_event_ = 0; 383 watch_event_ = 0;
392 return false;
393 } 384 }
385
386 return result;
394 } 387 }
395 388
396 bool RegKey::StopWatching() { 389 GONG RegKey::StopWatching() {
390 LONG result = ERROR_INVALID_HANDLE;
397 if (watch_event_) { 391 if (watch_event_) {
398 CloseHandle(watch_event_); 392 CloseHandle(watch_event_);
399 watch_event_ = 0; 393 watch_event_ = 0;
400 return true; 394 result = ERROR_SUCCESS;
401 } 395 }
402 return false; 396 return result;
403 } 397 }
404 398
405 bool RegKey::HasChanged() { 399 bool RegKey::HasChanged() {
406 if (watch_event_) { 400 if (watch_event_) {
407 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { 401 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) {
408 StartWatching(); 402 StartWatching();
409 return true; 403 return true;
410 } 404 }
411 } 405 }
412 return false; 406 return false;
413 } 407 }
414 408
415 } // namespace win 409 } // namespace win
416 } // namespace base 410 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698