| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/win/registry.h" | 8 #include "base/win/registry.h" |
| 9 #include "chrome/installer/util/logging_installer.h" | 9 #include "chrome/installer/util/logging_installer.h" |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 key_path_(key_path), | 36 key_path_(key_path), |
| 37 value_name_(value_name), | 37 value_name_(value_name), |
| 38 value_data_dword_(value_data), | 38 value_data_dword_(value_data), |
| 39 overwrite_(overwrite), | 39 overwrite_(overwrite), |
| 40 status_(SET_VALUE), | 40 status_(SET_VALUE), |
| 41 is_str_type_(false), | 41 is_str_type_(false), |
| 42 previous_value_dword_(0) { | 42 previous_value_dword_(0) { |
| 43 } | 43 } |
| 44 | 44 |
| 45 bool SetRegValueWorkItem::Do() { | 45 bool SetRegValueWorkItem::Do() { |
| 46 bool success = true; | 46 LONG result = ERROR_SUCCESS; |
| 47 | 47 base::win::RegKey key; |
| 48 if (status_ != SET_VALUE) { | 48 if (status_ != SET_VALUE) { |
| 49 // we already did something. | 49 // we already did something. |
| 50 LOG(ERROR) << "multiple calls to Do()"; | 50 LOG(ERROR) << "multiple calls to Do()"; |
| 51 success = false; | 51 result = ERROR_CANTWRITE; |
| 52 } else { |
| 53 result = key.Open(predefined_root_, key_path_.c_str(), |
| 54 KEY_READ | KEY_SET_VALUE); |
| 55 if (result != ERROR_SUCCESS) { |
| 56 LOG(ERROR) << "can not open " << key_path_ << " error: " << result; |
| 57 status_ = VALUE_UNCHANGED; |
| 58 } |
| 52 } | 59 } |
| 53 | 60 |
| 54 base::win::RegKey key; | 61 if (result == ERROR_SUCCESS) { |
| 55 if (success && !key.Open(predefined_root_, key_path_.c_str(), | |
| 56 KEY_READ | KEY_SET_VALUE)) { | |
| 57 LOG(ERROR) << "can not open " << key_path_; | |
| 58 status_ = VALUE_UNCHANGED; | |
| 59 success = false; | |
| 60 } | |
| 61 | |
| 62 if (success) { | |
| 63 if (key.ValueExists(value_name_.c_str())) { | 62 if (key.ValueExists(value_name_.c_str())) { |
| 64 if (overwrite_) { | 63 if (overwrite_) { |
| 65 // Read previous value for rollback and write new value | 64 // Read previous value for rollback and write new value |
| 66 if (is_str_type_) { | 65 if (is_str_type_) { |
| 67 std::wstring data; | 66 key.ReadValue(value_name_.c_str(), &previous_value_str_); |
| 68 if (key.ReadValue(value_name_.c_str(), &data)) { | 67 result = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); |
| 69 previous_value_str_.assign(data); | 68 } else { |
| 69 key.ReadValueDW(value_name_.c_str(), &previous_value_dword_); |
| 70 result = key.WriteValue(value_name_.c_str(), value_data_dword_); |
| 71 } |
| 72 if (result == ERROR_SUCCESS) { |
| 73 VLOG(1) << "overwritten value for " << value_name_; |
| 74 status_ = VALUE_OVERWRITTEN; |
| 75 } else { |
| 76 LOG(ERROR) << "failed to overwrite value for " << value_name_; |
| 77 status_ = VALUE_UNCHANGED; |
| 70 } | 78 } |
| 71 success = key.WriteValue(value_name_.c_str(), | |
| 72 value_data_str_.c_str()); | |
| 73 } else { | |
| 74 DWORD data; | |
| 75 if (key.ReadValueDW(value_name_.c_str(), &data)) { | |
| 76 previous_value_dword_ = data; | |
| 77 } | |
| 78 success = key.WriteValue(value_name_.c_str(), value_data_dword_); | |
| 79 } | |
| 80 if (success) { | |
| 81 VLOG(1) << "overwritten value for " << value_name_; | |
| 82 status_ = VALUE_OVERWRITTEN; | |
| 83 } else { | |
| 84 LOG(ERROR) << "failed to overwrite value for " << value_name_; | |
| 85 status_ = VALUE_UNCHANGED; | |
| 86 } | |
| 87 } else { | 79 } else { |
| 80 // value exists and cannot be overwriten |
| 88 VLOG(1) << value_name_ << " exists. not changed "; | 81 VLOG(1) << value_name_ << " exists. not changed "; |
| 89 status_ = VALUE_UNCHANGED; | 82 status_ = VALUE_UNCHANGED; |
| 90 } | 83 } |
| 91 } else { | 84 } else { |
| 85 // Value does not exist, simply write a new value |
| 92 if (is_str_type_) { | 86 if (is_str_type_) { |
| 93 success = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); | 87 result = key.WriteValue(value_name_.c_str(), value_data_str_.c_str()); |
| 94 } else { | 88 } else { |
| 95 success = key.WriteValue(value_name_.c_str(), value_data_dword_); | 89 result = key.WriteValue(value_name_.c_str(), value_data_dword_); |
| 96 } | 90 } |
| 97 if (success) { | 91 if (result == ERROR_SUCCESS) { |
| 98 VLOG(1) << "created value for " << value_name_; | 92 VLOG(1) << "created value for " << value_name_; |
| 99 status_ = NEW_VALUE_CREATED; | 93 status_ = NEW_VALUE_CREATED; |
| 100 } else { | 94 } else { |
| 101 LOG(ERROR) << "failed to create value for " << value_name_; | 95 LOG(ERROR) << "failed to create value for " << value_name_ |
| 96 << " error: " << result; |
| 102 status_ = VALUE_UNCHANGED; | 97 status_ = VALUE_UNCHANGED; |
| 103 } | 98 } |
| 104 } | 99 } |
| 105 } | 100 } |
| 106 | 101 |
| 107 LOG_IF(ERROR, !success && !log_message_.empty()) << log_message_; | |
| 108 | |
| 109 if (ignore_failure_) { | 102 if (ignore_failure_) { |
| 110 success = true; | 103 result = ERROR_SUCCESS; |
| 111 } | 104 } |
| 112 | 105 |
| 113 return success; | 106 return result == ERROR_SUCCESS; |
| 114 } | 107 } |
| 115 | 108 |
| 116 void SetRegValueWorkItem::Rollback() { | 109 void SetRegValueWorkItem::Rollback() { |
| 117 if (!ignore_failure_) { | 110 if (ignore_failure_) |
| 118 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK) | 111 return; |
| 119 return; | |
| 120 | 112 |
| 121 if (status_ == VALUE_UNCHANGED) { | 113 if (status_ == SET_VALUE || status_ == VALUE_ROLL_BACK) |
| 122 status_ = VALUE_ROLL_BACK; | 114 return; |
| 123 VLOG(1) << "rollback: setting unchanged, nothing to do"; | |
| 124 return; | |
| 125 } | |
| 126 | 115 |
| 127 base::win::RegKey key; | 116 if (status_ == VALUE_UNCHANGED) { |
| 128 if (!key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE)) { | |
| 129 status_ = VALUE_ROLL_BACK; | |
| 130 VLOG(1) << "rollback: can not open " << key_path_; | |
| 131 return; | |
| 132 } | |
| 133 | |
| 134 std::wstring result_str(L" failed"); | |
| 135 if (status_ == NEW_VALUE_CREATED) { | |
| 136 if (key.DeleteValue(value_name_.c_str())) | |
| 137 result_str.assign(L" succeeded"); | |
| 138 VLOG(1) << "rollback: deleting " << value_name_ << result_str; | |
| 139 } else if (status_ == VALUE_OVERWRITTEN) { | |
| 140 // try restore the previous value | |
| 141 bool success = true; | |
| 142 if (is_str_type_) { | |
| 143 success = key.WriteValue(value_name_.c_str(), | |
| 144 previous_value_str_.c_str()); | |
| 145 } else { | |
| 146 success = key.WriteValue(value_name_.c_str(), previous_value_dword_); | |
| 147 } | |
| 148 if (success) | |
| 149 result_str.assign(L" succeeded"); | |
| 150 VLOG(1) << "rollback: restoring " << value_name_ << result_str; | |
| 151 } else { | |
| 152 NOTREACHED(); | |
| 153 } | |
| 154 | |
| 155 status_ = VALUE_ROLL_BACK; | 117 status_ = VALUE_ROLL_BACK; |
| 118 VLOG(1) << "rollback: setting unchanged, nothing to do"; |
| 156 return; | 119 return; |
| 157 } | 120 } |
| 121 |
| 122 base::win::RegKey key; |
| 123 LONG result = key.Open(predefined_root_, key_path_.c_str(), KEY_SET_VALUE); |
| 124 if (result != ERROR_SUCCESS) { |
| 125 status_ = VALUE_ROLL_BACK; |
| 126 VLOG(1) << "rollback: can not open " << key_path_ << " error: " << result; |
| 127 return; |
| 128 } |
| 129 |
| 130 if (status_ == NEW_VALUE_CREATED) { |
| 131 result = key.DeleteValue(value_name_.c_str()); |
| 132 VLOG(1) << "rollback: deleting " << value_name_ << " error: " << result; |
| 133 } else if (status_ == VALUE_OVERWRITTEN) { |
| 134 // try restore the previous value |
| 135 if (is_str_type_) { |
| 136 result = key.WriteValue(value_name_.c_str(), previous_value_str_.c_str()); |
| 137 } else { |
| 138 result = key.WriteValue(value_name_.c_str(), previous_value_dword_); |
| 139 } |
| 140 VLOG(1) << "rollback: restoring " << value_name_ << " error: " << result; |
| 141 } else { |
| 142 NOTREACHED(); |
| 143 } |
| 144 |
| 145 status_ = VALUE_ROLL_BACK; |
| 158 } | 146 } |
| OLD | NEW |