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

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: Remove XP specific code. 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
« no previous file with comments | « base/win/registry.h ('k') | base/win/registry_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 16 matching lines...) Expand all
27 // a size in wchar_t that can store a truncated wchar_t if necessary. 27 // a size in wchar_t that can store a truncated wchar_t if necessary.
28 inline DWORD to_wchar_size(DWORD byte_size) { 28 inline DWORD to_wchar_size(DWORD byte_size) {
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 // Watches for modifications to a key.
38 class RegKey::Watcher : public ObjectWatcher::Delegate {
39 public:
40 explicit Watcher(RegKey* owner) : owner_(owner) {}
41 ~Watcher() {}
42
43 bool StartWatching(HKEY key, const ChangeCallback& callback);
44
45 // Implementation of ObjectWatcher::Delegate.
46 void OnObjectSignaled(HANDLE object) override {
47 DCHECK(watch_event_.IsValid() && watch_event_.Get() == object);
48 ChangeCallback callback = callback_;
49 callback_.Reset();
50 callback.Run();
51 }
52
53 private:
54 RegKey* owner_;
55 ScopedHandle watch_event_;
56 ObjectWatcher object_watcher_;
57 ChangeCallback callback_;
58 DISALLOW_COPY_AND_ASSIGN(Watcher);
59 };
60
61 bool RegKey::Watcher::StartWatching(HKEY key, const ChangeCallback& callback) {
62 DCHECK(key);
63 DCHECK(callback_.is_null());
64
65 if (!watch_event_.IsValid())
66 watch_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
67
68 if (!watch_event_.IsValid())
69 return false;
70
71 DWORD filter = REG_NOTIFY_CHANGE_NAME |
72 REG_NOTIFY_CHANGE_ATTRIBUTES |
73 REG_NOTIFY_CHANGE_LAST_SET |
74 REG_NOTIFY_CHANGE_SECURITY;
75
76 // Watch the registry key for a change of value.
77 LONG result = RegNotifyChangeKeyValue(key, TRUE, filter, watch_event_.Get(),
78 TRUE);
79 if (result != ERROR_SUCCESS) {
80 watch_event_.Close();
81 return false;
82 }
83
84 callback_ = callback;
85 return object_watcher_.StartWatching(watch_event_.Get(), this);
86 }
87
37 // RegKey ---------------------------------------------------------------------- 88 // RegKey ----------------------------------------------------------------------
38 89
39 RegKey::RegKey() 90 RegKey::RegKey() : key_(NULL), wow64access_(0) {
40 : key_(NULL),
41 watch_event_(0),
42 wow64access_(0) {
43 } 91 }
44 92
45 RegKey::RegKey(HKEY key) 93 RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {
46 : key_(key),
47 watch_event_(0),
48 wow64access_(0) {
49 } 94 }
50 95
51 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) 96 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
52 : key_(NULL), 97 : key_(NULL),
53 watch_event_(0),
54 wow64access_(0) { 98 wow64access_(0) {
55 if (rootkey) { 99 if (rootkey) {
56 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) 100 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
57 Create(rootkey, subkey, access); 101 Create(rootkey, subkey, access);
58 else 102 else
59 Open(rootkey, subkey, access); 103 Open(rootkey, subkey, access);
60 } else { 104 } else {
61 DCHECK(!subkey); 105 DCHECK(!subkey);
62 wow64access_ = access & kWow64AccessMask; 106 wow64access_ = access & kWow64AccessMask;
63 } 107 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // one. 187 // one.
144 if (result == ERROR_SUCCESS) { 188 if (result == ERROR_SUCCESS) {
145 Close(); 189 Close();
146 key_ = subkey; 190 key_ = subkey;
147 wow64access_ = access & kWow64AccessMask; 191 wow64access_ = access & kWow64AccessMask;
148 } 192 }
149 return result; 193 return result;
150 } 194 }
151 195
152 void RegKey::Close() { 196 void RegKey::Close() {
153 StopWatching();
154 if (key_) { 197 if (key_) {
155 ::RegCloseKey(key_); 198 ::RegCloseKey(key_);
156 key_ = NULL; 199 key_ = NULL;
157 wow64access_ = 0; 200 wow64access_ = 0;
158 } 201 }
159 } 202 }
160 203
161 // TODO(wfh): Remove this and other unsafe methods. See http://crbug.com/375400 204 // TODO(wfh): Remove this and other unsafe methods. See http://crbug.com/375400
162 void RegKey::Set(HKEY key) { 205 void RegKey::Set(HKEY key) {
163 if (key_ != key) { 206 if (key_ != key) {
164 Close(); 207 Close();
165 key_ = key; 208 key_ = key;
166 } 209 }
167 } 210 }
168 211
169 HKEY RegKey::Take() { 212 HKEY RegKey::Take() {
170 DCHECK(wow64access_ == 0); 213 DCHECK(wow64access_ == 0);
171 StopWatching();
172 HKEY key = key_; 214 HKEY key = key_;
173 key_ = NULL; 215 key_ = NULL;
174 return key; 216 return key;
175 } 217 }
176 218
177 bool RegKey::HasValue(const wchar_t* name) const { 219 bool RegKey::HasValue(const wchar_t* name) const {
178 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; 220 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
179 } 221 }
180 222
181 DWORD RegKey::GetValueCount() const { 223 DWORD RegKey::GetValueCount() const {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 const void* data, 402 const void* data,
361 DWORD dsize, 403 DWORD dsize,
362 DWORD dtype) { 404 DWORD dtype) {
363 DCHECK(data || !dsize); 405 DCHECK(data || !dsize);
364 406
365 LONG result = RegSetValueEx(key_, name, 0, dtype, 407 LONG result = RegSetValueEx(key_, name, 0, dtype,
366 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); 408 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
367 return result; 409 return result;
368 } 410 }
369 411
370 LONG RegKey::StartWatching() { 412 bool RegKey::StartWatching(const ChangeCallback& callback) {
371 DCHECK(key_); 413 if (!key_watcher_)
372 if (!watch_event_) 414 key_watcher_.reset(new Watcher(this));
373 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
374 415
375 DWORD filter = REG_NOTIFY_CHANGE_NAME | 416 if (!key_watcher_.get()->StartWatching(key_, callback))
376 REG_NOTIFY_CHANGE_ATTRIBUTES | 417 return false;
377 REG_NOTIFY_CHANGE_LAST_SET |
378 REG_NOTIFY_CHANGE_SECURITY;
379 418
380 // Watch the registry key for a change of value. 419 return true;
381 LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE);
382 if (result != ERROR_SUCCESS) {
383 CloseHandle(watch_event_);
384 watch_event_ = 0;
385 }
386
387 return result;
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 } 420 }
409 421
410 // static 422 // static
411 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey, 423 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey,
412 const wchar_t* lpSubKey, 424 const wchar_t* lpSubKey,
413 REGSAM samDesired, 425 REGSAM samDesired,
414 DWORD Reserved) { 426 DWORD Reserved) {
415 typedef LSTATUS(WINAPI* RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD); 427 typedef LSTATUS(WINAPI* RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD);
416 428
417 RegDeleteKeyExPtr reg_delete_key_ex_func = 429 RegDeleteKeyExPtr reg_delete_key_ex_func =
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 } else { 671 } else {
660 index_ = count - 1; 672 index_ = count - 1;
661 } 673 }
662 } 674 }
663 675
664 Read(); 676 Read();
665 } 677 }
666 678
667 } // namespace win 679 } // namespace win
668 } // namespace base 680 } // namespace base
OLDNEW
« no previous file with comments | « 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