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

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

Issue 10785022: Remove IO thread restrictions from registry functions (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 5 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
« no previous file with comments | « no previous file | no next file » | 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"
11 #include "base/threading/thread_restrictions.h" 11 #include "base/threading/thread_restrictions.h"
12 12
13 #pragma comment(lib, "shlwapi.lib") // for SHDeleteKey 13 #pragma comment(lib, "shlwapi.lib") // for SHDeleteKey
14 14
15 namespace base { 15 namespace base {
16 namespace win { 16 namespace win {
17 17
18 // RegKey ---------------------------------------------------------------------- 18 // RegKey ----------------------------------------------------------------------
19 19
20 RegKey::RegKey() 20 RegKey::RegKey()
21 : key_(NULL), 21 : key_(NULL),
22 watch_event_(0) { 22 watch_event_(0) {
23 } 23 }
24 24
25 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) 25 RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access)
26 : key_(NULL), 26 : key_(NULL),
27 watch_event_(0) { 27 watch_event_(0) {
28 base::ThreadRestrictions::AssertIOAllowed();
29 if (rootkey) { 28 if (rootkey) {
30 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) 29 if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
31 Create(rootkey, subkey, access); 30 Create(rootkey, subkey, access);
32 else 31 else
33 Open(rootkey, subkey, access); 32 Open(rootkey, subkey, access);
34 } else { 33 } else {
35 DCHECK(!subkey); 34 DCHECK(!subkey);
36 } 35 }
37 } 36 }
38 37
39 RegKey::~RegKey() { 38 RegKey::~RegKey() {
40 Close(); 39 Close();
41 } 40 }
42 41
43 LONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { 42 LONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
44 DWORD disposition_value; 43 DWORD disposition_value;
45 return CreateWithDisposition(rootkey, subkey, &disposition_value, access); 44 return CreateWithDisposition(rootkey, subkey, &disposition_value, access);
46 } 45 }
47 46
48 LONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, 47 LONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey,
49 DWORD* disposition, REGSAM access) { 48 DWORD* disposition, REGSAM access) {
50 base::ThreadRestrictions::AssertIOAllowed();
51 DCHECK(rootkey && subkey && access && disposition); 49 DCHECK(rootkey && subkey && access && disposition);
52 Close(); 50 Close();
53 51
54 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL, 52 LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL,
55 REG_OPTION_NON_VOLATILE, access, NULL, &key_, 53 REG_OPTION_NON_VOLATILE, access, NULL, &key_,
56 disposition); 54 disposition);
57 return result; 55 return result;
58 } 56 }
59 57
60 LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) { 58 LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) {
61 base::ThreadRestrictions::AssertIOAllowed();
62 DCHECK(name && access); 59 DCHECK(name && access);
63
64 HKEY subkey = NULL; 60 HKEY subkey = NULL;
65 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, 61 LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE,
66 access, NULL, &subkey, NULL); 62 access, NULL, &subkey, NULL);
67 Close(); 63 Close();
68 64
69 key_ = subkey; 65 key_ = subkey;
70 return result; 66 return result;
71 } 67 }
72 68
73 LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { 69 LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
74 base::ThreadRestrictions::AssertIOAllowed();
75 DCHECK(rootkey && subkey && access); 70 DCHECK(rootkey && subkey && access);
76 Close(); 71 Close();
77 72
78 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); 73 LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_);
79 return result; 74 return result;
80 } 75 }
81 76
82 LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) { 77 LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) {
83 base::ThreadRestrictions::AssertIOAllowed();
84 DCHECK(relative_key_name && access); 78 DCHECK(relative_key_name && access);
85
86 HKEY subkey = NULL; 79 HKEY subkey = NULL;
87 LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey); 80 LONG result = RegOpenKeyEx(key_, relative_key_name, 0, access, &subkey);
88 81
89 // We have to close the current opened key before replacing it with the new 82 // We have to close the current opened key before replacing it with the new
90 // one. 83 // one.
91 Close(); 84 Close();
92 85
93 key_ = subkey; 86 key_ = subkey;
94 return result; 87 return result;
95 } 88 }
96 89
97 void RegKey::Close() { 90 void RegKey::Close() {
98 base::ThreadRestrictions::AssertIOAllowed();
99 StopWatching(); 91 StopWatching();
100 if (key_) { 92 if (key_) {
101 ::RegCloseKey(key_); 93 ::RegCloseKey(key_);
102 key_ = NULL; 94 key_ = NULL;
103 } 95 }
104 } 96 }
105 97
106 bool RegKey::HasValue(const wchar_t* name) const { 98 bool RegKey::HasValue(const wchar_t* name) const {
107 base::ThreadRestrictions::AssertIOAllowed();
108 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS; 99 return RegQueryValueEx(key_, name, 0, NULL, NULL, NULL) == ERROR_SUCCESS;
109 } 100 }
110 101
111 DWORD RegKey::GetValueCount() const { 102 DWORD RegKey::GetValueCount() const {
112 base::ThreadRestrictions::AssertIOAllowed();
113 DWORD count = 0; 103 DWORD count = 0;
114 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, 104 LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count,
115 NULL, NULL, NULL, NULL); 105 NULL, NULL, NULL, NULL);
116 return (result == ERROR_SUCCESS) ? count : 0; 106 return (result == ERROR_SUCCESS) ? count : 0;
117 } 107 }
118 108
119 LONG RegKey::GetValueNameAt(int index, std::wstring* name) const { 109 LONG RegKey::GetValueNameAt(int index, std::wstring* name) const {
120 base::ThreadRestrictions::AssertIOAllowed();
121 wchar_t buf[256]; 110 wchar_t buf[256];
122 DWORD bufsize = arraysize(buf); 111 DWORD bufsize = arraysize(buf);
123 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL); 112 LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL);
124 if (r == ERROR_SUCCESS) 113 if (r == ERROR_SUCCESS)
125 *name = buf; 114 *name = buf;
126 115
127 return r; 116 return r;
128 } 117 }
129 118
130 LONG RegKey::DeleteKey(const wchar_t* name) { 119 LONG RegKey::DeleteKey(const wchar_t* name) {
131 base::ThreadRestrictions::AssertIOAllowed();
132 DCHECK(key_); 120 DCHECK(key_);
133 DCHECK(name); 121 DCHECK(name);
134 LONG result = SHDeleteKey(key_, name); 122 LONG result = SHDeleteKey(key_, name);
135 return result; 123 return result;
136 } 124 }
137 125
138 LONG RegKey::DeleteValue(const wchar_t* value_name) { 126 LONG RegKey::DeleteValue(const wchar_t* value_name) {
139 base::ThreadRestrictions::AssertIOAllowed();
140 DCHECK(key_); 127 DCHECK(key_);
141 DCHECK(value_name); 128 DCHECK(value_name);
142 LONG result = RegDeleteValue(key_, value_name); 129 LONG result = RegDeleteValue(key_, value_name);
143 return result; 130 return result;
144 } 131 }
145 132
146 LONG RegKey::ReadValueDW(const wchar_t* name, DWORD* out_value) const { 133 LONG RegKey::ReadValueDW(const wchar_t* name, DWORD* out_value) const {
147 DCHECK(out_value); 134 DCHECK(out_value);
148 DWORD type = REG_DWORD; 135 DWORD type = REG_DWORD;
149 DWORD size = sizeof(DWORD); 136 DWORD size = sizeof(DWORD);
(...skipping 20 matching lines...) Expand all
170 size == sizeof(local_value)) 157 size == sizeof(local_value))
171 *out_value = local_value; 158 *out_value = local_value;
172 else 159 else
173 result = ERROR_CANTREAD; 160 result = ERROR_CANTREAD;
174 } 161 }
175 162
176 return result; 163 return result;
177 } 164 }
178 165
179 LONG RegKey::ReadValue(const wchar_t* name, std::wstring* out_value) const { 166 LONG RegKey::ReadValue(const wchar_t* name, std::wstring* out_value) const {
180 base::ThreadRestrictions::AssertIOAllowed();
181 DCHECK(out_value); 167 DCHECK(out_value);
182 const size_t kMaxStringLength = 1024; // This is after expansion. 168 const size_t kMaxStringLength = 1024; // This is after expansion.
183 // Use the one of the other forms of ReadValue if 1024 is too small for you. 169 // Use the one of the other forms of ReadValue if 1024 is too small for you.
184 wchar_t raw_value[kMaxStringLength]; 170 wchar_t raw_value[kMaxStringLength];
185 DWORD type = REG_SZ, size = sizeof(raw_value); 171 DWORD type = REG_SZ, size = sizeof(raw_value);
186 LONG result = ReadValue(name, raw_value, &size, &type); 172 LONG result = ReadValue(name, raw_value, &size, &type);
187 if (result == ERROR_SUCCESS) { 173 if (result == ERROR_SUCCESS) {
188 if (type == REG_SZ) { 174 if (type == REG_SZ) {
189 *out_value = raw_value; 175 *out_value = raw_value;
190 } else if (type == REG_EXPAND_SZ) { 176 } else if (type == REG_EXPAND_SZ) {
(...skipping 13 matching lines...) Expand all
204 } 190 }
205 } 191 }
206 192
207 return result; 193 return result;
208 } 194 }
209 195
210 LONG RegKey::ReadValue(const wchar_t* name, 196 LONG RegKey::ReadValue(const wchar_t* name,
211 void* data, 197 void* data,
212 DWORD* dsize, 198 DWORD* dsize,
213 DWORD* dtype) const { 199 DWORD* dtype) const {
214 base::ThreadRestrictions::AssertIOAllowed();
215 LONG result = RegQueryValueEx(key_, name, 0, dtype, 200 LONG result = RegQueryValueEx(key_, name, 0, dtype,
216 reinterpret_cast<LPBYTE>(data), dsize); 201 reinterpret_cast<LPBYTE>(data), dsize);
217 return result; 202 return result;
218 } 203 }
219 204
220 LONG RegKey::ReadValues(const wchar_t* name, 205 LONG RegKey::ReadValues(const wchar_t* name,
221 std::vector<std::wstring>* values) { 206 std::vector<std::wstring>* values) {
222 base::ThreadRestrictions::AssertIOAllowed();
223 values->clear(); 207 values->clear();
224 208
225 DWORD type = REG_MULTI_SZ; 209 DWORD type = REG_MULTI_SZ;
226 DWORD size = 0; 210 DWORD size = 0;
227 LONG result = ReadValue(name, NULL, &size, &type); 211 LONG result = ReadValue(name, NULL, &size, &type);
228 if (FAILED(result) || size == 0) 212 if (FAILED(result) || size == 0)
229 return result; 213 return result;
230 214
231 if (type != REG_MULTI_SZ) 215 if (type != REG_MULTI_SZ)
232 return ERROR_CANTREAD; 216 return ERROR_CANTREAD;
(...skipping 23 matching lines...) Expand all
256 240
257 LONG RegKey::WriteValue(const wchar_t * name, const wchar_t* in_value) { 241 LONG RegKey::WriteValue(const wchar_t * name, const wchar_t* in_value) {
258 return WriteValue(name, in_value, 242 return WriteValue(name, in_value,
259 static_cast<DWORD>(sizeof(*in_value) * (wcslen(in_value) + 1)), REG_SZ); 243 static_cast<DWORD>(sizeof(*in_value) * (wcslen(in_value) + 1)), REG_SZ);
260 } 244 }
261 245
262 LONG RegKey::WriteValue(const wchar_t* name, 246 LONG RegKey::WriteValue(const wchar_t* name,
263 const void* data, 247 const void* data,
264 DWORD dsize, 248 DWORD dsize,
265 DWORD dtype) { 249 DWORD dtype) {
266 base::ThreadRestrictions::AssertIOAllowed();
267 DCHECK(data || !dsize); 250 DCHECK(data || !dsize);
268 251
269 LONG result = RegSetValueEx(key_, name, 0, dtype, 252 LONG result = RegSetValueEx(key_, name, 0, dtype,
270 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); 253 reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize);
271 return result; 254 return result;
272 } 255 }
273 256
274 LONG RegKey::StartWatching() { 257 LONG RegKey::StartWatching() {
275 DCHECK(key_); 258 DCHECK(key_);
276 if (!watch_event_) 259 if (!watch_event_)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 watch_event_ = 0; 291 watch_event_ = 0;
309 result = ERROR_SUCCESS; 292 result = ERROR_SUCCESS;
310 } 293 }
311 return result; 294 return result;
312 } 295 }
313 296
314 // RegistryValueIterator ------------------------------------------------------ 297 // RegistryValueIterator ------------------------------------------------------
315 298
316 RegistryValueIterator::RegistryValueIterator(HKEY root_key, 299 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
317 const wchar_t* folder_key) { 300 const wchar_t* folder_key) {
318 base::ThreadRestrictions::AssertIOAllowed();
319
320 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); 301 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_);
321 if (result != ERROR_SUCCESS) { 302 if (result != ERROR_SUCCESS) {
322 key_ = NULL; 303 key_ = NULL;
323 } else { 304 } else {
324 DWORD count = 0; 305 DWORD count = 0;
325 result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, 306 result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count,
326 NULL, NULL, NULL, NULL); 307 NULL, NULL, NULL, NULL);
327 308
328 if (result != ERROR_SUCCESS) { 309 if (result != ERROR_SUCCESS) {
329 ::RegCloseKey(key_); 310 ::RegCloseKey(key_);
330 key_ = NULL; 311 key_ = NULL;
331 } else { 312 } else {
332 index_ = count - 1; 313 index_ = count - 1;
333 } 314 }
334 } 315 }
335 316
336 Read(); 317 Read();
337 } 318 }
338 319
339 RegistryValueIterator::~RegistryValueIterator() { 320 RegistryValueIterator::~RegistryValueIterator() {
340 base::ThreadRestrictions::AssertIOAllowed();
341 if (key_) 321 if (key_)
342 ::RegCloseKey(key_); 322 ::RegCloseKey(key_);
343 } 323 }
344 324
345 DWORD RegistryValueIterator::ValueCount() const { 325 DWORD RegistryValueIterator::ValueCount() const {
346 base::ThreadRestrictions::AssertIOAllowed();
347 DWORD count = 0; 326 DWORD count = 0;
348 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, 327 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL,
349 &count, NULL, NULL, NULL, NULL); 328 &count, NULL, NULL, NULL, NULL);
350 if (result != ERROR_SUCCESS) 329 if (result != ERROR_SUCCESS)
351 return 0; 330 return 0;
352 331
353 return count; 332 return count;
354 } 333 }
355 334
356 bool RegistryValueIterator::Valid() const { 335 bool RegistryValueIterator::Valid() const {
357 return key_ != NULL && index_ >= 0; 336 return key_ != NULL && index_ >= 0;
358 } 337 }
359 338
360 void RegistryValueIterator::operator++() { 339 void RegistryValueIterator::operator++() {
361 --index_; 340 --index_;
362 Read(); 341 Read();
363 } 342 }
364 343
365 bool RegistryValueIterator::Read() { 344 bool RegistryValueIterator::Read() {
366 base::ThreadRestrictions::AssertIOAllowed();
367 if (Valid()) { 345 if (Valid()) {
368 DWORD ncount = arraysize(name_); 346 DWORD ncount = arraysize(name_);
369 value_size_ = sizeof(value_); 347 value_size_ = sizeof(value_);
370 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, 348 LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_,
371 reinterpret_cast<BYTE*>(value_), &value_size_); 349 reinterpret_cast<BYTE*>(value_), &value_size_);
372 if (ERROR_SUCCESS == r) 350 if (ERROR_SUCCESS == r)
373 return true; 351 return true;
374 } 352 }
375 353
376 name_[0] = '\0'; 354 name_[0] = '\0';
377 value_[0] = '\0'; 355 value_[0] = '\0';
378 value_size_ = 0; 356 value_size_ = 0;
379 return false; 357 return false;
380 } 358 }
381 359
382 // RegistryKeyIterator -------------------------------------------------------- 360 // RegistryKeyIterator --------------------------------------------------------
383 361
384 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key, 362 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
385 const wchar_t* folder_key) { 363 const wchar_t* folder_key) {
386 base::ThreadRestrictions::AssertIOAllowed();
387 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); 364 LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_);
388 if (result != ERROR_SUCCESS) { 365 if (result != ERROR_SUCCESS) {
389 key_ = NULL; 366 key_ = NULL;
390 } else { 367 } else {
391 DWORD count = 0; 368 DWORD count = 0;
392 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, 369 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
393 NULL, NULL, NULL, NULL, NULL); 370 NULL, NULL, NULL, NULL, NULL);
394 371
395 if (result != ERROR_SUCCESS) { 372 if (result != ERROR_SUCCESS) {
396 ::RegCloseKey(key_); 373 ::RegCloseKey(key_);
397 key_ = NULL; 374 key_ = NULL;
398 } else { 375 } else {
399 index_ = count - 1; 376 index_ = count - 1;
400 } 377 }
401 } 378 }
402 379
403 Read(); 380 Read();
404 } 381 }
405 382
406 RegistryKeyIterator::~RegistryKeyIterator() { 383 RegistryKeyIterator::~RegistryKeyIterator() {
407 base::ThreadRestrictions::AssertIOAllowed();
408 if (key_) 384 if (key_)
409 ::RegCloseKey(key_); 385 ::RegCloseKey(key_);
410 } 386 }
411 387
412 DWORD RegistryKeyIterator::SubkeyCount() const { 388 DWORD RegistryKeyIterator::SubkeyCount() const {
413 base::ThreadRestrictions::AssertIOAllowed();
414 DWORD count = 0; 389 DWORD count = 0;
415 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, 390 LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
416 NULL, NULL, NULL, NULL, NULL); 391 NULL, NULL, NULL, NULL, NULL);
417 if (result != ERROR_SUCCESS) 392 if (result != ERROR_SUCCESS)
418 return 0; 393 return 0;
419 394
420 return count; 395 return count;
421 } 396 }
422 397
423 bool RegistryKeyIterator::Valid() const { 398 bool RegistryKeyIterator::Valid() const {
424 return key_ != NULL && index_ >= 0; 399 return key_ != NULL && index_ >= 0;
425 } 400 }
426 401
427 void RegistryKeyIterator::operator++() { 402 void RegistryKeyIterator::operator++() {
428 --index_; 403 --index_;
429 Read(); 404 Read();
430 } 405 }
431 406
432 bool RegistryKeyIterator::Read() { 407 bool RegistryKeyIterator::Read() {
433 base::ThreadRestrictions::AssertIOAllowed();
434 if (Valid()) { 408 if (Valid()) {
435 DWORD ncount = arraysize(name_); 409 DWORD ncount = arraysize(name_);
436 FILETIME written; 410 FILETIME written;
437 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, 411 LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL,
438 NULL, &written); 412 NULL, &written);
439 if (ERROR_SUCCESS == r) 413 if (ERROR_SUCCESS == r)
440 return true; 414 return true;
441 } 415 }
442 416
443 name_[0] = '\0'; 417 name_[0] = '\0';
444 return false; 418 return false;
445 } 419 }
446 420
447 } // namespace win 421 } // namespace win
448 } // namespace base 422 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698