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

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

Issue 632833002: Remove raw handles from base::win::RegKey (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix stale logic Created 6 years, 2 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <algorithm> 8 #include <algorithm>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 18 matching lines...) Expand all
29 return (byte_size + sizeof(wchar_t) - 1) / sizeof(wchar_t); 29 return (byte_size + sizeof(wchar_t) - 1) / sizeof(wchar_t);
30 } 30 }
31 31
32 // Mask to pull WOW64 access flags out of REGSAM access. 32 // Mask to pull WOW64 access flags out of REGSAM access.
33 const REGSAM kWow64AccessMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY; 33 const REGSAM kWow64AccessMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY;
34 34
35 } // namespace 35 } // namespace
36 36
37 // RegKey ---------------------------------------------------------------------- 37 // RegKey ----------------------------------------------------------------------
38 38
39 RegKey::RegKey() 39 RegKey::RegKey() : key_(NULL), wow64access_(0) {
40 : key_(NULL),
41 watch_event_(0),
42 wow64access_(0) {
43 } 40 }
44 41
45 RegKey::RegKey(HKEY key) 42 RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {
46 : key_(key),
47 watch_event_(0),
48 wow64access_(0) {
49 } 43 }
50 44
51 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) 45 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
52 : key_(NULL), 46 : key_(NULL),
53 watch_event_(0),
54 wow64access_(0) { 47 wow64access_(0) {
55 if (rootkey) { 48 if (rootkey) {
56 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) 49 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
57 Create(rootkey, subkey, access); 50 Create(rootkey, subkey, access);
58 else 51 else
59 Open(rootkey, subkey, access); 52 Open(rootkey, subkey, access);
60 } else { 53 } else {
61 DCHECK(!subkey); 54 DCHECK(!subkey);
62 wow64access_ = access & kWow64AccessMask; 55 wow64access_ = access & kWow64AccessMask;
63 } 56 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // one. 136 // one.
144 if (result == ERROR_SUCCESS) { 137 if (result == ERROR_SUCCESS) {
145 Close(); 138 Close();
146 key_ = subkey; 139 key_ = subkey;
147 wow64access_ = access & kWow64AccessMask; 140 wow64access_ = access & kWow64AccessMask;
148 } 141 }
149 return result; 142 return result;
150 } 143 }
151 144
152 void RegKey::Close() { 145 void RegKey::Close() {
153 StopWatching();
154 if (key_) { 146 if (key_) {
155 ::RegCloseKey(key_); 147 ::RegCloseKey(key_);
156 key_ = NULL; 148 key_ = NULL;
157 wow64access_ = 0; 149 wow64access_ = 0;
158 } 150 }
159 } 151 }
160 152
161 // TODO(wfh): Remove this and other unsafe methods. See http://crbug.com/375400 153 // TODO(wfh): Remove this and other unsafe methods. See http://crbug.com/375400
162 void RegKey::Set(HKEY key) { 154 void RegKey::Set(HKEY key) {
163 if (key_ != key) { 155 if (key_ != key) {
164 Close(); 156 Close();
165 key_ = key; 157 key_ = key;
166 } 158 }
167 } 159 }
168 160
169 HKEY RegKey::Take() { 161 HKEY RegKey::Take() {
170 DCHECK(wow64access_ == 0); 162 DCHECK(wow64access_ == 0);
171 StopWatching();
172 HKEY key = key_; 163 HKEY key = key_;
173 key_ = NULL; 164 key_ = NULL;
174 return key; 165 return key;
175 } 166 }
176 167
177 bool RegKey::HasValue(const wchar_t* name) const { 168 bool RegKey::HasValue(const wchar_t* name) const {
178 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; 169 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
179 } 170 }
180 171
181 DWORD RegKey::GetValueCount() const { 172 DWORD RegKey::GetValueCount() const {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 const void* data, 351 const void* data,
361 DWORD dsize, 352 DWORD dsize,
362 DWORD dtype) { 353 DWORD dtype) {
363 DCHECK(data || !dsize); 354 DCHECK(data || !dsize);
364 355
365 LONG result = RegSetValueEx(key_, name, 0, dtype, 356 LONG result = RegSetValueEx(key_, name, 0, dtype,
366 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); 357 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
367 return result; 358 return result;
368 } 359 }
369 360
370 LONG RegKey::StartWatching() { 361 bool RegKey::StartWatching(const ChangeCallback& callback) {
362 DCHECK(callback_.is_null());
363 if (!StartWatchingInternal())
364 return false;
365
366 DCHECK(watch_event_.IsValid());
367 if (!object_watcher_.StartWatching(watch_event_.Get(), this))
368 return false;
369
370 callback_ = callback;
371 return true;
372 }
373
374 bool RegKey::StartWatchingInternal() {
371 DCHECK(key_); 375 DCHECK(key_);
372 if (!watch_event_) 376 if (GetVersion() < VERSION_VISTA) {
373 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); 377 // It is an error to register multiple times before Vista.
378 if (watch_event_.IsValid())
379 return true;
380 }
381
382 if (!watch_event_.IsValid())
383 watch_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
384
385 if (!watch_event_.IsValid())
386 return false;
374 387
375 DWORD filter = REG_NOTIFY_CHANGE_NAME | 388 DWORD filter = REG_NOTIFY_CHANGE_NAME |
376 REG_NOTIFY_CHANGE_ATTRIBUTES | 389 REG_NOTIFY_CHANGE_ATTRIBUTES |
377 REG_NOTIFY_CHANGE_LAST_SET | 390 REG_NOTIFY_CHANGE_LAST_SET |
378 REG_NOTIFY_CHANGE_SECURITY; 391 REG_NOTIFY_CHANGE_SECURITY;
379 392
380 // Watch the registry key for a change of value. 393 // Watch the registry key for a change of value.
381 LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE); 394 LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_.Get(),
395 TRUE);
382 if (result != ERROR_SUCCESS) { 396 if (result != ERROR_SUCCESS) {
383 CloseHandle(watch_event_); 397 watch_event_.Close();
384 watch_event_ = 0; 398 return false;
385 } 399 }
386 400
387 return result; 401 return true;
388 }
389
390 bool RegKey::HasChanged() {
391 if (watch_event_) {
392 if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) {
393 StartWatching();
394 return true;
395 }
396 }
397 return false;
398 }
399
400 LONG RegKey::StopWatching() {
401 LONG result = ERROR_INVALID_HANDLE;
402 if (watch_event_) {
403 CloseHandle(watch_event_);
404 watch_event_ = 0;
405 result = ERROR_SUCCESS;
406 }
407 return result;
408 } 402 }
409 403
410 // static 404 // static
411 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey, 405 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey,
412 const wchar_t* lpSubKey, 406 const wchar_t* lpSubKey,
413 REGSAM samDesired, 407 REGSAM samDesired,
414 DWORD Reserved) { 408 DWORD Reserved) {
415 typedef LSTATUS(WINAPI* RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD); 409 typedef LSTATUS(WINAPI* RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD);
416 410
417 RegDeleteKeyExPtr reg_delete_key_ex_func = 411 RegDeleteKeyExPtr reg_delete_key_ex_func =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } 471 }
478 472
479 RegCloseKey(target_key); 473 RegCloseKey(target_key);
480 474
481 // Try again to delete the key. 475 // Try again to delete the key.
482 result = RegDeleteKeyExWrapper(root_key, name.c_str(), access, 0); 476 result = RegDeleteKeyExWrapper(root_key, name.c_str(), access, 0);
483 477
484 return result; 478 return result;
485 } 479 }
486 480
481 void RegKey::OnObjectSignaled(HANDLE object) {
482 DCHECK(watch_event_.IsValid() && watch_event_.Get() == object);
483 ChangeCallback callback = callback_;
484 callback_.Reset();
485 callback.Run();
486 }
487
487 // RegistryValueIterator ------------------------------------------------------ 488 // RegistryValueIterator ------------------------------------------------------
488 489
489 RegistryValueIterator::RegistryValueIterator(HKEY root_key, 490 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
490 const wchar_t* folder_key) 491 const wchar_t* folder_key)
491 : name_(MAX_PATH, L'\0'), 492 : name_(MAX_PATH, L'\0'),
492 value_(MAX_PATH, L'\0') { 493 value_(MAX_PATH, L'\0') {
493 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); 494 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_);
494 if (result != ERROR_SUCCESS) { 495 if (result != ERROR_SUCCESS) {
495 key_ = NULL; 496 key_ = NULL;
496 } else { 497 } else {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 if (ERROR_SUCCESS == r) 630 if (ERROR_SUCCESS == r)
630 return true; 631 return true;
631 } 632 }
632 633
633 name_[0] = '\0'; 634 name_[0] = '\0';
634 return false; 635 return false;
635 } 636 }
636 637
637 } // namespace win 638 } // namespace win
638 } // namespace base 639 } // namespace base
OLDNEW
« base/win/registry.h ('K') | « base/win/registry.h ('k') | base/win/registry_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698