| Index: chrome/installer/util/set_reg_value_work_item.cc
|
| ===================================================================
|
| --- chrome/installer/util/set_reg_value_work_item.cc (revision 71761)
|
| +++ chrome/installer/util/set_reg_value_work_item.cc (working copy)
|
| @@ -5,6 +5,7 @@
|
| #include "chrome/installer/util/set_reg_value_work_item.h"
|
|
|
| #include "base/logging.h"
|
| +#include "base/string_util.h"
|
| #include "base/win/registry.h"
|
| #include "chrome/installer/util/logging_installer.h"
|
|
|
| @@ -19,14 +20,12 @@
|
| : predefined_root_(predefined_root),
|
| key_path_(key_path),
|
| value_name_(value_name),
|
| - value_data_str_(value_data),
|
| - value_data_dword_(0),
|
| - value_data_qword_(0),
|
| overwrite_(overwrite),
|
| status_(SET_VALUE),
|
| type_(REG_SZ),
|
| - previous_value_dword_(0),
|
| - previous_value_qword_(0) {
|
| + previous_type_(0) {
|
| + const uint8* data = reinterpret_cast<const uint8*>(value_data.c_str());
|
| + value_.assign(data, data + (value_data.length() + 1) * sizeof(wchar_t));
|
| }
|
|
|
| SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
|
| @@ -37,13 +36,12 @@
|
| : predefined_root_(predefined_root),
|
| key_path_(key_path),
|
| value_name_(value_name),
|
| - value_data_dword_(value_data),
|
| - value_data_qword_(0),
|
| overwrite_(overwrite),
|
| status_(SET_VALUE),
|
| type_(REG_DWORD),
|
| - previous_value_dword_(0),
|
| - previous_value_qword_(0) {
|
| + previous_type_(0) {
|
| + const uint8* data = reinterpret_cast<const uint8*>(&value_data);
|
| + value_.assign(data, data + sizeof(value_data));
|
| }
|
|
|
| SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root,
|
| @@ -54,151 +52,94 @@
|
| : predefined_root_(predefined_root),
|
| key_path_(key_path),
|
| value_name_(value_name),
|
| - value_data_dword_(0),
|
| - value_data_qword_(value_data),
|
| overwrite_(overwrite),
|
| status_(SET_VALUE),
|
| type_(REG_QWORD),
|
| - previous_value_dword_(0),
|
| - previous_value_qword_(0) {
|
| + previous_type_(0) {
|
| + const uint8* data = reinterpret_cast<const uint8*>(&value_data);
|
| + value_.assign(data, data + sizeof(value_data));
|
| }
|
|
|
| bool SetRegValueWorkItem::Do() {
|
| - bool success = true;
|
| -
|
| + LONG result = ERROR_SUCCESS;
|
| + base::win::RegKey key;
|
| if (status_ != SET_VALUE) {
|
| // we already did something.
|
| - LOG(ERROR) << "multiple calls to Do()";
|
| - success = false;
|
| + VLOG(1) << "multiple calls to Do()";
|
| + result = ERROR_CANTWRITE;
|
| + return ignore_failure_;
|
| }
|
|
|
| - base::win::RegKey key;
|
| - if (success && !key.Open(predefined_root_, key_path_.c_str(),
|
| - KEY_READ | KEY_SET_VALUE)) {
|
| - LOG(ERROR) << "can not open " << key_path_;
|
| - status_ = VALUE_UNCHANGED;
|
| - success = false;
|
| + status_ = VALUE_UNCHANGED;
|
| + result = key.Open(predefined_root_, key_path_.c_str(),
|
| + KEY_READ | KEY_SET_VALUE);
|
| + if (result != ERROR_SUCCESS) {
|
| + VLOG(1) << "can not open " << key_path_ << " error: " << result;
|
| + return ignore_failure_;
|
| }
|
|
|
| - if (success) {
|
| - if (key.ValueExists(value_name_.c_str())) {
|
| - if (overwrite_) {
|
| - // Read previous value for rollback and write new value
|
| - if (type_ == REG_SZ) {
|
| - std::wstring data;
|
| - if (key.ReadValue(value_name_.c_str(), &data)) {
|
| - previous_value_str_.assign(data);
|
| - }
|
| - success = key.WriteValue(value_name_.c_str(),
|
| - value_data_str_.c_str());
|
| - } else if (type_ == REG_DWORD) {
|
| - DWORD data;
|
| - if (key.ReadValueDW(value_name_.c_str(), &data)) {
|
| - previous_value_dword_ = data;
|
| - }
|
| - success = key.WriteValue(value_name_.c_str(), value_data_dword_);
|
| - } else if (type_ == REG_QWORD) {
|
| - int64 data;
|
| - DWORD data_size = sizeof(data);
|
| - DWORD data_type = NULL;
|
| + DWORD type = 0;
|
| + DWORD size = 0;
|
| + result = key.ReadValue(value_name_.c_str(), NULL, &size, &type);
|
| + // If the value exists but we don't want to overwrite then there's
|
| + // nothing more to do.
|
| + if ((result != ERROR_FILE_NOT_FOUND) && !overwrite_) {
|
| + return true;
|
| + }
|
|
|
| - if (key.ReadValue(value_name_.c_str(), &data, &data_size,
|
| - &data_type)) {
|
| - previous_value_qword_ = data;
|
| - }
|
| - success = key.WriteValue(value_name_.c_str(),
|
| - &value_data_qword_,
|
| - sizeof(value_data_qword_),
|
| - REG_QWORD);
|
| - }
|
| - if (success) {
|
| - VLOG(1) << "overwritten value for " << value_name_;
|
| - status_ = VALUE_OVERWRITTEN;
|
| - } else {
|
| - LOG(ERROR) << "failed to overwrite value for " << value_name_;
|
| - status_ = VALUE_UNCHANGED;
|
| - }
|
| - } else {
|
| - VLOG(1) << value_name_ << " exists. not changed ";
|
| - status_ = VALUE_UNCHANGED;
|
| - }
|
| - } else {
|
| - if (type_ == REG_SZ) {
|
| - success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str());
|
| - } else if (type_ == REG_DWORD) {
|
| - success = key.WriteValue(value_name_.c_str(), value_data_dword_);
|
| - } else if (type_ == REG_QWORD) {
|
| - success = key.WriteValue(value_name_.c_str(),
|
| - &value_data_qword_,
|
| - sizeof(value_data_qword_),
|
| - REG_QWORD);
|
| - } else {
|
| - NOTREACHED() << "Unsupported value type.";
|
| - }
|
| - if (success) {
|
| - VLOG(1) << "created value for " << value_name_;
|
| - status_ = NEW_VALUE_CREATED;
|
| - } else {
|
| - LOG(ERROR) << "failed to create value for " << value_name_;
|
| - status_ = VALUE_UNCHANGED;
|
| - }
|
| + // If there's something to be saved, save it.
|
| + if (result == ERROR_SUCCESS) {
|
| + previous_value_.resize(size);
|
| + result = key.ReadValue(value_name_.c_str(), &previous_value_[0], &size,
|
| + &previous_type_);
|
| + if (result != ERROR_SUCCESS) {
|
| + previous_value_.clear();
|
| + VLOG(1) << "Failed to save original value. Error: " << result;
|
| }
|
| }
|
|
|
| - LOG_IF(ERROR, !success && !log_message_.empty()) << log_message_;
|
| -
|
| - if (ignore_failure_) {
|
| - success = true;
|
| + result = key.WriteValue(value_name_.c_str(), &value_[0],
|
| + static_cast<DWORD>(value_.size()), type_);
|
| + if (result != ERROR_SUCCESS) {
|
| + VLOG(1) << "Failed to write value " << key_path_ << " error: " << result;
|
| + return ignore_failure_;
|
| }
|
|
|
| - return success;
|
| + status_ = previous_type_ ? VALUE_OVERWRITTEN : NEW_VALUE_CREATED;
|
| + return true;
|
| }
|
|
|
| void SetRegValueWorkItem::Rollback() {
|
| - if (!ignore_failure_) {
|
| - if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
|
| - return;
|
| + if (ignore_failure_)
|
| + return;
|
|
|
| - if (status_ == VALUE_UNCHANGED) {
|
| - status_ = VALUE_ROLL_BACK;
|
| - VLOG(1) << "rollback: setting unchanged, nothing to do";
|
| - return;
|
| - }
|
| + if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK)
|
| + return;
|
|
|
| - base::win::RegKey key;
|
| - if (!key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE)) {
|
| - status_ = VALUE_ROLL_BACK;
|
| - VLOG(1) << "rollback: can not open " << key_path_;
|
| - return;
|
| - }
|
| + if (status_ == VALUE_UNCHANGED) {
|
| + status_ = VALUE_ROLL_BACK;
|
| + VLOG(1) << "rollback: setting unchanged, nothing to do";
|
| + return;
|
| + }
|
|
|
| - std::wstring result_str(L" failed");
|
| - if (status_ == NEW_VALUE_CREATED) {
|
| - if (key.DeleteValue(value_name_.c_str()))
|
| - result_str.assign(L" succeeded");
|
| - VLOG(1) << "rollback: deleting " << value_name_ << result_str;
|
| - } else if (status_ == VALUE_OVERWRITTEN) {
|
| - // try restore the previous value
|
| - bool success = true;
|
| - if (type_ == REG_SZ) {
|
| - success = key.WriteValue(value_name_.c_str(),
|
| - previous_value_str_.c_str());
|
| - } else if (type_ == REG_DWORD) {
|
| - success = key.WriteValue(value_name_.c_str(), previous_value_dword_);
|
| - } else if (type_ == REG_QWORD) {
|
| - success = key.WriteValue(value_name_.c_str(),
|
| - &previous_value_qword_,
|
| - sizeof(previous_value_qword_),
|
| - REG_QWORD);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - if (success)
|
| - result_str.assign(L" succeeded");
|
| - VLOG(1) << "rollback: restoring " << value_name_ << result_str;
|
| + base::win::RegKey key;
|
| + LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE);
|
| + if (result != ERROR_SUCCESS) {
|
| + VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result;
|
| + return;
|
| + }
|
|
|
| - status_ = VALUE_ROLL_BACK;
|
| - return;
|
| - }
|
| + if (status_ == NEW_VALUE_CREATED) {
|
| + result = key.DeleteValue(value_name_.c_str());
|
| + VLOG(1) << "rollback: deleting " << value_name_ << " error: " << result;
|
| + } else if (status_ == VALUE_OVERWRITTEN) {
|
| + result = key.WriteValue(value_name_.c_str(), &previous_value_[0],
|
| + static_cast<DWORD>(previous_value_.size()),
|
| + previous_type_);
|
| + VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result;
|
| + } else {
|
| + NOTREACHED();
|
| }
|
| +
|
| + status_ = VALUE_ROLL_BACK;
|
| }
|
|
|