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

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

Issue 652903005: Revert of Remove raw handles from base::win::RegKey (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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. 37 // RegKey ----------------------------------------------------------------------
38 class RegKey::Watcher : public ObjectWatcher::Delegate {
39 public:
40 explicit Watcher(RegKey* owner) : owner_(owner) {}
41 ~Watcher() {}
42 38
43 bool StartWatching(HKEY key, const ChangeCallback& callback); 39 RegKey::RegKey()
44 40 : key_(NULL),
45 // Implementation of ObjectWatcher::Delegate. 41 watch_event_(0),
46 void OnObjectSignaled(HANDLE object) override { 42 wow64access_(0) {
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 if (GetVersion() < VERSION_VISTA) {
65 // It is an error to register multiple times before Vista.
66 if (watch_event_.IsValid()) {
67 callback_ = callback;
68 return true;
69 }
70 }
71
72 if (!watch_event_.IsValid())
73 watch_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
74
75 if (!watch_event_.IsValid())
76 return false;
77
78 DWORD filter = REG_NOTIFY_CHANGE_NAME |
79 REG_NOTIFY_CHANGE_ATTRIBUTES |
80 REG_NOTIFY_CHANGE_LAST_SET |
81 REG_NOTIFY_CHANGE_SECURITY;
82
83 // Watch the registry key for a change of value.
84 LONG result = RegNotifyChangeKeyValue(key, TRUE, filter, watch_event_.Get(),
85 TRUE);
86 if (result != ERROR_SUCCESS) {
87 watch_event_.Close();
88 return false;
89 }
90
91 callback_ = callback;
92 return object_watcher_.StartWatching(watch_event_.Get(), this);
93 } 43 }
94 44
95 // RegKey ---------------------------------------------------------------------- 45 RegKey::RegKey(HKEY key)
96 46 : key_(key),
97 RegKey::RegKey() : key_(NULL), wow64access_(0) { 47 watch_event_(0),
98 } 48 wow64access_(0) {
99
100 RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) {
101 } 49 }
102 50
103 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) 51 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
104 : key_(NULL), 52 : key_(NULL),
53 watch_event_(0),
105 wow64access_(0) { 54 wow64access_(0) {
106 if (rootkey) { 55 if (rootkey) {
107 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) 56 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
108 Create(rootkey, subkey, access); 57 Create(rootkey, subkey, access);
109 else 58 else
110 Open(rootkey, subkey, access); 59 Open(rootkey, subkey, access);
111 } else { 60 } else {
112 DCHECK(!subkey); 61 DCHECK(!subkey);
113 wow64access_ = access & kWow64AccessMask; 62 wow64access_ = access & kWow64AccessMask;
114 } 63 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // one. 143 // one.
195 if (result == ERROR_SUCCESS) { 144 if (result == ERROR_SUCCESS) {
196 Close(); 145 Close();
197 key_ = subkey; 146 key_ = subkey;
198 wow64access_ = access & kWow64AccessMask; 147 wow64access_ = access & kWow64AccessMask;
199 } 148 }
200 return result; 149 return result;
201 } 150 }
202 151
203 void RegKey::Close() { 152 void RegKey::Close() {
153 StopWatching();
204 if (key_) { 154 if (key_) {
205 ::RegCloseKey(key_); 155 ::RegCloseKey(key_);
206 key_ = NULL; 156 key_ = NULL;
207 wow64access_ = 0; 157 wow64access_ = 0;
208 } 158 }
209 } 159 }
210 160
211 // TODO(wfh): Remove this and other unsafe methods. See http://crbug.com/375400 161 // TODO(wfh): Remove this and other unsafe methods. See http://crbug.com/375400
212 void RegKey::Set(HKEY key) { 162 void RegKey::Set(HKEY key) {
213 if (key_ != key) { 163 if (key_ != key) {
214 Close(); 164 Close();
215 key_ = key; 165 key_ = key;
216 } 166 }
217 } 167 }
218 168
219 HKEY RegKey::Take() { 169 HKEY RegKey::Take() {
220 DCHECK(wow64access_ == 0); 170 DCHECK(wow64access_ == 0);
171 StopWatching();
221 HKEY key = key_; 172 HKEY key = key_;
222 key_ = NULL; 173 key_ = NULL;
223 return key; 174 return key;
224 } 175 }
225 176
226 bool RegKey::HasValue(const wchar_t* name) const { 177 bool RegKey::HasValue(const wchar_t* name) const {
227 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; 178 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
228 } 179 }
229 180
230 DWORD RegKey::GetValueCount() const { 181 DWORD RegKey::GetValueCount() const {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 const void* data, 360 const void* data,
410 DWORD dsize, 361 DWORD dsize,
411 DWORD dtype) { 362 DWORD dtype) {
412 DCHECK(data || !dsize); 363 DCHECK(data || !dsize);
413 364
414 LONG result = RegSetValueEx(key_, name, 0, dtype, 365 LONG result = RegSetValueEx(key_, name, 0, dtype,
415 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); 366 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
416 return result; 367 return result;
417 } 368 }
418 369
419 bool RegKey::StartWatching(const ChangeCallback& callback) { 370 LONG RegKey::StartWatching() {
420 if (!key_watcher_) 371 DCHECK(key_);
421 key_watcher_.reset(new Watcher(this)); 372 if (!watch_event_)
373 watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
422 374
423 if (!key_watcher_.get()->StartWatching(key_, callback)) 375 DWORD filter = REG_NOTIFY_CHANGE_NAME |
424 return false; 376 REG_NOTIFY_CHANGE_ATTRIBUTES |
377 REG_NOTIFY_CHANGE_LAST_SET |
378 REG_NOTIFY_CHANGE_SECURITY;
425 379
426 return true; 380 // Watch the registry key for a change of value.
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;
427 } 408 }
428 409
429 // static 410 // static
430 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey, 411 LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey,
431 const wchar_t* lpSubKey, 412 const wchar_t* lpSubKey,
432 REGSAM samDesired, 413 REGSAM samDesired,
433 DWORD Reserved) { 414 DWORD Reserved) {
434 typedef LSTATUS(WINAPI* RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD); 415 typedef LSTATUS(WINAPI* RegDeleteKeyExPtr)(HKEY, LPCWSTR, REGSAM, DWORD);
435 416
436 RegDeleteKeyExPtr reg_delete_key_ex_func = 417 RegDeleteKeyExPtr reg_delete_key_ex_func =
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 } else { 659 } else {
679 index_ = count - 1; 660 index_ = count - 1;
680 } 661 }
681 } 662 }
682 663
683 Read(); 664 Read();
684 } 665 }
685 666
686 } // namespace win 667 } // namespace win
687 } // namespace base 668 } // 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