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

Side by Side Diff: chrome/installer/util/set_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/set_reg_value_work_item.h" 5 #include "chrome/installer/util/set_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 SetRegValueWorkItem::~SetRegValueWorkItem() { 12 SetRegValueWorkItem::~SetRegValueWorkItem() {
12 } 13 }
13 14
14 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, 15 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
15 const std::wstring& key_path, 16 const std::wstring& key_path,
16 const std::wstring& value_name, 17 const std::wstring& value_name,
17 const std::wstring& value_data, 18 const std::wstring& value_data,
18 bool overwrite) 19 bool overwrite)
19 : predefined_root_(predefined_root), 20 : predefined_root_(predefined_root),
20 key_path_(key_path), 21 key_path_(key_path),
21 value_name_(value_name), 22 value_name_(value_name),
22 value_data_str_(value_data),
23 value_data_dword_(0),
24 value_data_qword_(0),
25 overwrite_(overwrite), 23 overwrite_(overwrite),
26 status_(SET_VALUE), 24 status_(SET_VALUE),
27 type_(REG_SZ), 25 type_(REG_SZ),
28 previous_value_dword_(0), 26 previous_type_(0) {
29 previous_value_qword_(0) { 27 const uint8* data = reinterpret_cast<const uint8*>(value_data.c_str());
28 value_.assign(data, data + (value_data.length() + 1) * sizeof(wchar_t));
30 } 29 }
31 30
32 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, 31 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
33 const std::wstring& key_path, 32 const std::wstring& key_path,
34 const std::wstring& value_name, 33 const std::wstring& value_name,
35 DWORD value_data, 34 DWORD value_data,
36 bool overwrite) 35 bool overwrite)
37 : predefined_root_(predefined_root), 36 : predefined_root_(predefined_root),
38 key_path_(key_path), 37 key_path_(key_path),
39 value_name_(value_name), 38 value_name_(value_name),
40 value_data_dword_(value_data),
41 value_data_qword_(0),
42 overwrite_(overwrite), 39 overwrite_(overwrite),
43 status_(SET_VALUE), 40 status_(SET_VALUE),
44 type_(REG_DWORD), 41 type_(REG_DWORD),
45 previous_value_dword_(0), 42 previous_type_(0) {
46 previous_value_qword_(0) { 43 const uint8* data = reinterpret_cast<const uint8*>(&value_data);
44 value_.assign(data, data + sizeof(value_data));
47 } 45 }
48 46
49 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, 47 SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
50 const std::wstring& key_path, 48 const std::wstring& key_path,
51 const std::wstring& value_name, 49 const std::wstring& value_name,
52 int64 value_data, 50 int64 value_data,
53 bool overwrite) 51 bool overwrite)
54 : predefined_root_(predefined_root), 52 : predefined_root_(predefined_root),
55 key_path_(key_path), 53 key_path_(key_path),
56 value_name_(value_name), 54 value_name_(value_name),
57 value_data_dword_(0),
58 value_data_qword_(value_data),
59 overwrite_(overwrite), 55 overwrite_(overwrite),
60 status_(SET_VALUE), 56 status_(SET_VALUE),
61 type_(REG_QWORD), 57 type_(REG_QWORD),
62 previous_value_dword_(0), 58 previous_type_(0) {
63 previous_value_qword_(0) { 59 const uint8* data = reinterpret_cast<const uint8*>(&value_data);
60 value_.assign(data, data + sizeof(value_data));
64 } 61 }
65 62
66 bool SetRegValueWorkItem::Do() { 63 bool SetRegValueWorkItem::Do() {
67 bool success = true; 64 LONG result = ERROR_SUCCESS;
68 65 base::win::RegKey key;
69 if (status_ != SET_VALUE) { 66 if (status_ != SET_VALUE) {
70 // we already did something. 67 // we already did something.
71 LOG(ERROR) << "multiple calls to Do()"; 68 VLOG(1) << "multiple calls to Do()";
72 success = false; 69 result = ERROR_CANTWRITE;
70 return ignore_failure_;
71 }
72
73 status_ = VALUE_UNCHANGED;
74 result = key.Open(predefined_root_, key_path_.c_str(),
75 KEY_READ | KEY_SET_VALUE);
76 if (result != ERROR_SUCCESS) {
77 VLOG(1) << "can not open " << key_path_ << " error: " << result;
78 return ignore_failure_;
79 }
80
81 DWORD type = 0;
82 DWORD size = 0;
83 result = key.ReadValue(value_name_.c_str(), NULL, &size, &type);
84 // If the value exists but we don't want to overwrite then there's
85 // nothing more to do.
86 if ((result != ERROR_FILE_NOT_FOUND) && !overwrite_) {
87 return true;
88 }
89
90 // If there's something to be saved, save it.
91 if (result == ERROR_SUCCESS) {
92 previous_value_.resize(size);
93 result = key.ReadValue(value_name_.c_str(), &previous_value_[0], &size,
94 &previous_type_);
95 if (result != ERROR_SUCCESS) {
96 previous_value_.clear();
97 VLOG(1) << "Failed to save original value. Error: " << result;
98 }
99 }
100
101 result = key.WriteValue(value_name_.c_str(), &value_[0],
102 static_cast<DWORD>(value_.size()), type_);
103 if (result != ERROR_SUCCESS) {
104 VLOG(1) << "Failed to write value " << key_path_ << " error: " << result;
105 return ignore_failure_;
106 }
107
108 status_ = previous_type_ ? VALUE_OVERWRITTEN : NEW_VALUE_CREATED;
109 return true;
110 }
111
112 void SetRegValueWorkItem::Rollback() {
113 if (ignore_failure_)
114 return;
115
116 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
117 return;
118
119 if (status_ == VALUE_UNCHANGED) {
120 status_ = VALUE_ROLL_BACK;
121 VLOG(1) << "rollback: setting unchanged, nothing to do";
122 return;
73 } 123 }
74 124
75 base::win::RegKey key; 125 base::win::RegKey key;
76 if (success && !key.Open(predefined_root_, key_path_.c_str(), 126 LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE);
77 KEY_READ | KEY_SET_VALUE)) { 127 if (result != ERROR_SUCCESS) {
78 LOG(ERROR) << "can not open " << key_path_; 128 VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result;
79 status_ = VALUE_UNCHANGED; 129 return;
80 success = false;
81 } 130 }
82 131
83 if (success) { 132 if (status_ == NEW_VALUE_CREATED) {
84 if (key.ValueExists(value_name_.c_str())) { 133 result = key.DeleteValue(value_name_.c_str());
85 if (overwrite_) { 134 VLOG(1) << "rollback: deleting " << value_name_ << " error: " << result;
86 // Read previous value for rollback and write new value 135 } else if (status_ == VALUE_OVERWRITTEN) {
87 if (type_ == REG_SZ) { 136 result = key.WriteValue(value_name_.c_str(), &previous_value_[0],
88 std::wstring data; 137 static_cast<DWORD>(previous_value_.size()),
89 if (key.ReadValue(value_name_.c_str(), &data)) { 138 previous_type_);
90 previous_value_str_.assign(data); 139 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result;
91 } 140 } else {
92 success = key.WriteValue(value_name_.c_str(), 141 NOTREACHED();
93 value_data_str_.c_str());
94 } else if (type_ == REG_DWORD) {
95 DWORD data;
96 if (key.ReadValueDW(value_name_.c_str(), &data)) {
97 previous_value_dword_ = data;
98 }
99 success = key.WriteValue(value_name_.c_str(), value_data_dword_);
100 } else if (type_ == REG_QWORD) {
101 int64 data;
102 DWORD data_size = sizeof(data);
103 DWORD data_type = NULL;
104
105 if (key.ReadValue(value_name_.c_str(), &data, &data_size,
106 &data_type)) {
107 previous_value_qword_ = data;
108 }
109 success = key.WriteValue(value_name_.c_str(),
110 &value_data_qword_,
111 sizeof(value_data_qword_),
112 REG_QWORD);
113 }
114 if (success) {
115 VLOG(1) << "overwritten value for " << value_name_;
116 status_ = VALUE_OVERWRITTEN;
117 } else {
118 LOG(ERROR) << "failed to overwrite value for " << value_name_;
119 status_ = VALUE_UNCHANGED;
120 }
121 } else {
122 VLOG(1) << value_name_ << " exists. not changed ";
123 status_ = VALUE_UNCHANGED;
124 }
125 } else {
126 if (type_ == REG_SZ) {
127 success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str());
128 } else if (type_ == REG_DWORD) {
129 success = key.WriteValue(value_name_.c_str(), value_data_dword_);
130 } else if (type_ == REG_QWORD) {
131 success = key.WriteValue(value_name_.c_str(),
132 &value_data_qword_,
133 sizeof(value_data_qword_),
134 REG_QWORD);
135 } else {
136 NOTREACHED() << "Unsupported value type.";
137 }
138 if (success) {
139 VLOG(1) << "created value for " << value_name_;
140 status_ = NEW_VALUE_CREATED;
141 } else {
142 LOG(ERROR) << "failed to create value for " << value_name_;
143 status_ = VALUE_UNCHANGED;
144 }
145 }
146 } 142 }
147 143
148 LOG_IF(ERROR, !success && !log_message_.empty()) << log_message_; 144 status_ = VALUE_ROLL_BACK;
149
150 if (ignore_failure_) {
151 success = true;
152 }
153
154 return success;
155 } 145 }
156
157 void SetRegValueWorkItem::Rollback() {
158 if (!ignore_failure_) {
159 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
160 return;
161
162 if (status_ == VALUE_UNCHANGED) {
163 status_ = VALUE_ROLL_BACK;
164 VLOG(1) << "rollback: setting unchanged, nothing to do";
165 return;
166 }
167
168 base::win::RegKey key;
169 if (!key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE)) {
170 status_ = VALUE_ROLL_BACK;
171 VLOG(1) << "rollback: can not open " << key_path_;
172 return;
173 }
174
175 std::wstring result_str(L" failed");
176 if (status_ == NEW_VALUE_CREATED) {
177 if (key.DeleteValue(value_name_.c_str()))
178 result_str.assign(L" succeeded");
179 VLOG(1) << "rollback: deleting " << value_name_ << result_str;
180 } else if (status_ == VALUE_OVERWRITTEN) {
181 // try restore the previous value
182 bool success = true;
183 if (type_ == REG_SZ) {
184 success = key.WriteValue(value_name_.c_str(),
185 previous_value_str_.c_str());
186 } else if (type_ == REG_DWORD) {
187 success = key.WriteValue(value_name_.c_str(), previous_value_dword_);
188 } else if (type_ == REG_QWORD) {
189 success = key.WriteValue(value_name_.c_str(),
190 &previous_value_qword_,
191 sizeof(previous_value_qword_),
192 REG_QWORD);
193 } else {
194 NOTREACHED();
195 }
196 if (success)
197 result_str.assign(L" succeeded");
198 VLOG(1) << "rollback: restoring " << value_name_ << result_str;
199
200 status_ = VALUE_ROLL_BACK;
201 return;
202 }
203 }
204 }
OLDNEW
« no previous file with comments | « chrome/installer/util/set_reg_value_work_item.h ('k') | chrome/installer/util/set_reg_value_work_item_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698