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

Side by Side Diff: chrome/installer/util/delete_reg_value_work_item.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/installer/util/delete_reg_value_work_item.h" 5 #include "chrome/installer/util/delete_reg_value_work_item.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/string_util.h"
8 #include "base/win/registry.h" 9 #include "base/win/registry.h"
9 #include "chrome/installer/util/logging_installer.h" 10 #include "chrome/installer/util/logging_installer.h"
10 11
11 using base::win::RegKey; 12 using base::win::RegKey;
12 13
13 DeleteRegValueWorkItem::DeleteRegValueWorkItem(HKEY predefined_root, 14 DeleteRegValueWorkItem::DeleteRegValueWorkItem(HKEY predefined_root,
14 const std::wstring& key_path, 15 const std::wstring& key_path,
15 const std::wstring& value_name, 16 const std::wstring& value_name)
16 DWORD type)
17 : predefined_root_(predefined_root), 17 : predefined_root_(predefined_root),
18 key_path_(key_path), 18 key_path_(key_path),
19 value_name_(value_name), 19 value_name_(value_name),
20 type_(type), 20 previous_type_(0),
21 status_(DELETE_VALUE), 21 status_(DELETE_VALUE) {
22 old_dw_(0),
23 old_qword_(0) {
24 DCHECK(type_ == REG_QWORD || type_ == REG_DWORD || type == REG_SZ);
25 } 22 }
26 23
27 DeleteRegValueWorkItem::~DeleteRegValueWorkItem() { 24 DeleteRegValueWorkItem::~DeleteRegValueWorkItem() {
28 } 25 }
29 26
30 bool DeleteRegValueWorkItem::Do() { 27 bool DeleteRegValueWorkItem::Do() {
31 if (status_ != DELETE_VALUE) { 28 if (status_ != DELETE_VALUE) {
32 // we already did something. 29 // we already did something.
33 LOG(ERROR) << "multiple calls to Do()"; 30 LOG(ERROR) << "multiple calls to Do()";
34 return false; 31 return false;
35 } 32 }
36 33
37 status_ = VALUE_UNCHANGED; 34 status_ = VALUE_UNCHANGED;
38 35
39 // A big flaw in the RegKey implementation is that all error information 36 RegKey key;
40 // (besides success/failure) is lost in the translation from LSTATUS to bool. 37 DWORD type = 0;
41 // So, we resort to direct API calls here. :-/ 38 DWORD size = 0;
42 HKEY raw_key = NULL; 39 LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_READ);
43 LSTATUS err = RegOpenKeyEx(predefined_root_, key_path_.c_str(), 0, 40 if (result == ERROR_SUCCESS)
44 KEY_READ, &raw_key); 41 result = key.ReadValue(value_name_.c_str(), NULL, &size, &type);
45 if (err != ERROR_SUCCESS) { 42
46 if (err == ERROR_FILE_NOT_FOUND) { 43 if (result == ERROR_FILE_NOT_FOUND) {
47 LOG(INFO) << "(delete value) can not open " << key_path_; 44 LOG(INFO) << "(delete value) Key: " << key_path_ << " or Value: "
48 status_ = VALUE_NOT_FOUND; 45 << value_name_ << " does not exist.";
49 return true; 46 status_ = VALUE_NOT_FOUND;
50 } 47 return true;
51 } else {
52 ::RegCloseKey(raw_key);
53 } 48 }
54 49
55 RegKey key; 50 if (result == ERROR_MORE_DATA) {
grt (UTC plus 2) 2011/01/14 15:53:43 Have you verified this? According to MSDN, you sh
amit 2011/01/15 01:28:11 Done.
56 bool result = false; 51 result = key.ReadValue(value_name_.c_str(),
57 52 WriteInto(&previous_value_, size), &size,
58 // Used in REG_QWORD case only 53 &previous_type_);
59 DWORD value_size = sizeof(old_qword_); 54 VLOG_IF(1, result != ERROR_SUCCESS) << "Failed to save original value. "
60 DWORD type = 0; 55 "Error: " << result;
61
62 if (!key.Open(predefined_root_, key_path_.c_str(), KEY_READ | KEY_WRITE)) {
63 LOG(ERROR) << "can not open " << key_path_;
64 } else if (!key.ValueExists(value_name_.c_str())) {
65 status_ = VALUE_NOT_FOUND;
66 result = true;
67 // Read previous value for rollback and delete
68 } else if (((type_ == REG_SZ && key.ReadValue(value_name_.c_str(),
69 &old_str_)) ||
70 (type_ == REG_DWORD && key.ReadValueDW(value_name_.c_str(),
71 &old_dw_)) ||
72 (type_ == REG_QWORD && key.ReadValue(value_name_.c_str(),
73 &old_qword_,
74 &value_size, &type) &&
75 type == REG_QWORD && value_size == sizeof(old_qword_))) &&
76 (key.DeleteValue(value_name_.c_str()))) {
77 status_ = VALUE_DELETED;
78 result = true;
79 } else {
80 LOG(ERROR) << "failed to read/delete value " << value_name_;
81 } 56 }
82 57
83 return result; 58 result = key.DeleteValue(value_name_.c_str());
59 if (result != ERROR_SUCCESS) {
60 VLOG(1) << "Failed to delete value " << value_name_ << " error: " << result;
61 return false;
62 }
63
64 status_ = VALUE_DELETED;
65 return true;
84 } 66 }
85 67
86 void DeleteRegValueWorkItem::Rollback() { 68 void DeleteRegValueWorkItem::Rollback() {
87 if (status_ == DELETE_VALUE || status_ == VALUE_ROLLED_BACK) 69 if (status_ == DELETE_VALUE || status_ == VALUE_ROLLED_BACK)
88 return; 70 return;
89 if (status_ == VALUE_UNCHANGED || status_ == VALUE_NOT_FOUND) { 71 if (status_ == VALUE_UNCHANGED || status_ == VALUE_NOT_FOUND) {
90 status_ = VALUE_ROLLED_BACK; 72 status_ = VALUE_ROLLED_BACK;
91 VLOG(1) << "rollback: setting unchanged, nothing to do"; 73 VLOG(1) << "rollback: setting unchanged, nothing to do";
92 return; 74 return;
93 } 75 }
94 76
95 // At this point only possible state is VALUE_DELETED. 77 // At this point only possible state is VALUE_DELETED.
96 RegKey key; 78 RegKey key;
97 if (!key.Open(predefined_root_, key_path_.c_str(), KEY_READ | KEY_WRITE)) { 79 LONG result = key.Open(predefined_root_, key_path_.c_str(),
98 LOG(ERROR) << "rollback: can not open " << key_path_; 80 KEY_READ | KEY_WRITE);
99 // try to restore the previous value 81 if (result == ERROR_SUCCESS) {
100 } else if ((type_ == REG_SZ && key.WriteValue(value_name_.c_str(), 82 // try to restore the previous value
101 old_str_.c_str())) || 83 result = key.WriteValue(value_name_.c_str(), previous_value_.c_str(),
grt (UTC plus 2) 2011/01/14 15:53:43 If you use std::string where std::vector<uint8> be
102 (type_ == REG_DWORD && key.WriteValue(value_name_.c_str(), 84 static_cast<DWORD>(previous_value_.size()),
103 old_dw_)) || 85 previous_type_);
104 (type_ == REG_QWORD && key.WriteValue(value_name_.c_str(), 86 VLOG_IF(1, result != ERROR_SUCCESS) << "rollback: restoring "
105 &old_qword_, 87 << value_name_ << " error: " << result;
106 sizeof(old_qword_),
107 REG_QWORD))) {
108 status_ = VALUE_ROLLED_BACK;
109 VLOG(1) << "rollback: restored " << value_name_;
110 } else { 88 } else {
111 LOG(ERROR) << "failed to restore value " << value_name_; 89 VLOG(1) << "can not open " << key_path_ << " error: " << result;
112 } 90 }
113
114 key.Close();
115 return;
116 } 91 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698