Index: chrome/installer/util/set_reg_value_work_item.cc |
diff --git a/chrome/installer/util/set_reg_value_work_item.cc b/chrome/installer/util/set_reg_value_work_item.cc |
index 596fe7c8895ecd81944ddf262f16f4386b63a92c..8b0860aefa8cd51c6c6a9e93ce46f4d556b0b8b7 100644 |
--- a/chrome/installer/util/set_reg_value_work_item.cc |
+++ b/chrome/installer/util/set_reg_value_work_item.cc |
@@ -9,6 +9,40 @@ |
#include "base/win/registry.h" |
#include "chrome/installer/util/logging_installer.h" |
+namespace { |
+ |
+// Transforms |str_value| into the byte-by-byte representation of its underlying |
+// string, stores the result in |binary_data|. |
+void StringToBinaryData(const std::wstring& str_value, |
+ std::vector<uint8>* binary_data) { |
+ DCHECK(binary_data); |
+ const uint8* data = reinterpret_cast<const uint8*>(str_value.c_str()); |
+ binary_data->assign(data, data + (str_value.length() + 1) * sizeof(wchar_t)); |
+} |
+ |
+// Transforms |binary_data| into its wstring representation (assuming |
+// |binary_data| is a sequence of wchar_t's). |
+void BinaryDataToString(const std::vector<uint8>& binary_data, |
+ std::wstring* str_value) { |
+ DCHECK(str_value); |
+ if (binary_data.size() < sizeof(wchar_t)) { |
+ str_value->clear(); |
+ return; |
+ } |
+ |
+ str_value->assign(reinterpret_cast<const wchar_t*>(&binary_data[0]), |
+ binary_data.size() / sizeof(wchar_t)); |
+ |
+ // Trim off a trailing string terminator, if present. |
+ if (!str_value->empty()) { |
+ auto iter = str_value->end(); |
+ if (*--iter == L'\0') |
+ str_value->erase(iter); |
+ } |
+} |
+ |
+} // namespace |
+ |
SetRegValueWorkItem::~SetRegValueWorkItem() { |
} |
@@ -29,8 +63,7 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, |
DCHECK(wow64_access == 0 || |
wow64_access == KEY_WOW64_32KEY || |
wow64_access == KEY_WOW64_64KEY); |
- const uint8* data = reinterpret_cast<const uint8*>(value_data.c_str()); |
- value_.assign(data, data + (value_data.length() + 1) * sizeof(wchar_t)); |
+ StringToBinaryData(value_data, &value_); |
} |
SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, |
@@ -75,6 +108,27 @@ SetRegValueWorkItem::SetRegValueWorkItem(HKEY predefined_root, |
value_.assign(data, data + sizeof(value_data)); |
} |
+SetRegValueWorkItem::SetRegValueWorkItem( |
+ HKEY predefined_root, |
+ const std::wstring& key_path, |
+ REGSAM wow64_access, |
+ const std::wstring& value_name, |
+ const GetValueFromExistingCallback& get_value_callback) |
+ : predefined_root_(predefined_root), |
+ key_path_(key_path), |
+ value_name_(value_name), |
+ get_value_callback_(get_value_callback), |
+ overwrite_(true), |
+ wow64_access_(wow64_access), |
+ status_(SET_VALUE), |
+ type_(REG_SZ), |
+ previous_type_(0) { |
+ DCHECK(wow64_access == 0 || |
+ wow64_access == KEY_WOW64_32KEY || |
+ wow64_access == KEY_WOW64_64KEY); |
+ // Nothing to do, |get_value_callback| will fill |value_| later. |
+} |
+ |
bool SetRegValueWorkItem::Do() { |
LONG result = ERROR_SUCCESS; |
base::win::RegKey key; |
@@ -118,6 +172,21 @@ bool SetRegValueWorkItem::Do() { |
} |
} |
+ if (!get_value_callback_.is_null()) { |
+ // Although this could be made more generic, for now this assumes the |
+ // |type_| of |value_| is REG_SZ. |
+ DCHECK_EQ(static_cast<DWORD>(REG_SZ), type_); |
+ |
+ // Fill |previous_value_str| with the wstring representation of the binary |
+ // data in |previous_value_| as long as it's of type REG_SZ (leave it empty |
+ // otherwise). |
+ std::wstring previous_value_str; |
+ if (previous_type_ == REG_SZ) |
+ BinaryDataToString(previous_value_, &previous_value_str); |
+ |
+ StringToBinaryData(get_value_callback_.Run(previous_value_str), &value_); |
+ } |
+ |
result = key.WriteValue(value_name_.c_str(), &value_[0], |
static_cast<DWORD>(value_.size()), type_); |
if (result != ERROR_SUCCESS) { |