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

Unified Diff: chrome/installer/util/delete_reg_key_work_item.cc

Issue 8176008: Merge 101684 - Added CopyRegKeyWorkItem in support of IE low rights policy fixes. (Closed) Base URL: svn://svn.chromium.org/chrome/branches/835/src/
Patch Set: Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: chrome/installer/util/delete_reg_key_work_item.cc
===================================================================
--- chrome/installer/util/delete_reg_key_work_item.cc (revision 104337)
+++ chrome/installer/util/delete_reg_key_work_item.cc (working copy)
@@ -5,265 +5,12 @@
#include "chrome/installer/util/delete_reg_key_work_item.h"
#include <shlwapi.h>
-#include <algorithm>
-#include <limits>
-#include <vector>
#include "base/logging.h"
-#include "base/rand_util.h"
-#include "base/stringprintf.h"
#include "base/win/registry.h"
-#include "chrome/installer/util/logging_installer.h"
using base::win::RegKey;
-namespace {
-const REGSAM kKeyReadNoNotify = (KEY_READ) & ~(KEY_NOTIFY);
-}
-
-// A container for a registry key, its values, and its subkeys. We don't use
-// more obvious methods for various reasons:
-// - RegCopyTree isn't supported pre-Vista, so we'd have to do something
-// different for XP anyway.
-// - SHCopyKey can't copy subkeys into a volatile destination, so we'd have to
-// worry about polluting the registry.
-// We don't persist security attributes since we only delete keys that we own,
-// and we don't set custom attributes on them anyway.
-class DeleteRegKeyWorkItem::RegKeyBackup {
- public:
- RegKeyBackup();
- bool Initialize(const RegKey& key);
- bool WriteTo(RegKey* key) const;
-
- private:
- // A container for a registry value.
- class RegValueBackup {
- public:
- RegValueBackup();
- void Initialize(const wchar_t* name_buffer, DWORD name_size,
- DWORD type, const uint8* data, DWORD data_size);
- const std::wstring& name_str() const { return name_; }
- const wchar_t* name() const { return name_.empty() ? NULL : name_.c_str(); }
- DWORD type() const { return type_; }
- const uint8* data() const { return data_.empty() ? NULL : &data_[0]; }
- DWORD data_len() const { return static_cast<DWORD>(data_.size()); }
-
- private:
- std::wstring name_;
- std::vector<uint8> data_;
- DWORD type_;
-
- DISALLOW_COPY_AND_ASSIGN(RegValueBackup);
- };
-
- scoped_array<RegValueBackup> values_;
- scoped_array<std::wstring> subkey_names_;
- scoped_array<RegKeyBackup> subkeys_;
- ptrdiff_t num_values_;
- ptrdiff_t num_subkeys_;
-
- DISALLOW_COPY_AND_ASSIGN(RegKeyBackup);
-};
-
-DeleteRegKeyWorkItem::RegKeyBackup::RegValueBackup::RegValueBackup()
- : type_(REG_NONE) {
-}
-
-void DeleteRegKeyWorkItem::RegKeyBackup::RegValueBackup::Initialize(
- const wchar_t* name_buffer,
- DWORD name_size,
- DWORD type, const uint8* data,
- DWORD data_size) {
- name_.assign(name_buffer, name_size);
- type_ = type;
- data_.assign(data, data + data_size);
-}
-
-DeleteRegKeyWorkItem::RegKeyBackup::RegKeyBackup()
- : num_values_(0),
- num_subkeys_(0) {
-}
-
-// Initializes this object by reading the values and subkeys of |key|.
-// Security descriptors are not backed up.
-bool DeleteRegKeyWorkItem::RegKeyBackup::Initialize(const RegKey& key) {
- DCHECK(key.Valid());
-
- scoped_array<RegValueBackup> values;
- scoped_array<std::wstring> subkey_names;
- scoped_array<RegKeyBackup> subkeys;
-
- DWORD num_subkeys = 0;
- DWORD max_subkey_name_len = 0;
- DWORD num_values = 0;
- DWORD max_value_name_len = 0;
- DWORD max_value_len = 0;
- LONG result = RegQueryInfoKey(key.Handle(), NULL, NULL, NULL,
- &num_subkeys, &max_subkey_name_len, NULL,
- &num_values, &max_value_name_len,
- &max_value_len, NULL, NULL);
- if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed getting info of key to backup, result: " << result;
- return false;
- }
- if (max_subkey_name_len >= std::numeric_limits<DWORD>::max() - 1 ||
- max_value_name_len >= std::numeric_limits<DWORD>::max() - 1) {
- LOG(ERROR)
- << "Failed backing up key; subkeys and/or names are out of range.";
- return false;
- }
- DWORD max_name_len = std::max(max_subkey_name_len, max_value_name_len) + 1;
- scoped_array<wchar_t> name_buffer(new wchar_t[max_name_len]);
-
- // Backup the values.
- if (num_values != 0) {
- values.reset(new RegValueBackup[num_values]);
- scoped_array<uint8> value_buffer(new uint8[max_value_len]);
- DWORD name_size = 0;
- DWORD value_type = REG_NONE;
- DWORD value_size = 0;
-
- for (DWORD i = 0; i < num_values; ) {
- name_size = max_name_len;
- value_size = max_value_len;
- result = RegEnumValue(key.Handle(), i, name_buffer.get(), &name_size,
- NULL, &value_type, value_buffer.get(), &value_size);
- switch (result) {
- case ERROR_NO_MORE_ITEMS:
- num_values = i;
- break;
- case ERROR_SUCCESS:
- values[i].Initialize(name_buffer.get(), name_size, value_type,
- value_buffer.get(), value_size);
- ++i;
- break;
- case ERROR_MORE_DATA:
- if (value_size > max_value_len) {
- max_value_len = value_size;
- value_buffer.reset(new uint8[max_value_len]);
- } else {
- DCHECK(max_name_len - 1 < name_size);
- if (name_size >= std::numeric_limits<DWORD>::max() - 1) {
- LOG(ERROR) << "Failed backing up key; value name out of range.";
- return false;
- }
- max_name_len = name_size + 1;
- name_buffer.reset(new wchar_t[max_name_len]);
- }
- break;
- default:
- LOG(ERROR) << "Failed backing up value " << i << ", result: "
- << result;
- return false;
- }
- }
- DLOG_IF(WARNING, RegEnumValue(key.Handle(), num_values, name_buffer.get(),
- &name_size, NULL, &value_type, NULL,
- NULL) != ERROR_NO_MORE_ITEMS)
- << "Concurrent modifications to registry key during backup operation.";
- }
-
- // Backup the subkeys.
- if (num_subkeys != 0) {
- subkey_names.reset(new std::wstring[num_subkeys]);
- subkeys.reset(new RegKeyBackup[num_subkeys]);
- DWORD name_size = 0;
-
- // Get the names of them.
- for (DWORD i = 0; i < num_subkeys; ) {
- name_size = max_name_len;
- result = RegEnumKeyEx(key.Handle(), i, name_buffer.get(), &name_size,
- NULL, NULL, NULL, NULL);
- switch (result) {
- case ERROR_NO_MORE_ITEMS:
- num_subkeys = i;
- break;
- case ERROR_SUCCESS:
- subkey_names[i].assign(name_buffer.get(), name_size);
- ++i;
- break;
- case ERROR_MORE_DATA:
- if (name_size >= std::numeric_limits<DWORD>::max() - 1) {
- LOG(ERROR) << "Failed backing up key; subkey name out of range.";
- return false;
- }
- max_name_len = name_size + 1;
- name_buffer.reset(new wchar_t[max_name_len]);
- break;
- default:
- LOG(ERROR) << "Failed getting name of subkey " << i
- << " for backup, result: " << result;
- return false;
- }
- }
- DLOG_IF(WARNING,
- RegEnumKeyEx(key.Handle(), num_subkeys, NULL, &name_size, NULL,
- NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
- << "Concurrent modifications to registry key during backup operation.";
-
- // Get their values.
- RegKey subkey;
- for (DWORD i = 0; i < num_subkeys; ++i) {
- result = subkey.Open(key.Handle(), subkey_names[i].c_str(),
- kKeyReadNoNotify);
- if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed opening subkey \"" << subkey_names[i]
- << "\" for backup, result: " << result;
- return false;
- }
- if (!subkeys[i].Initialize(subkey)) {
- LOG(ERROR) << "Failed backing up subkey \"" << subkey_names[i] << "\"";
- return false;
- }
- }
- }
-
- values_.swap(values);
- subkey_names_.swap(subkey_names);
- subkeys_.swap(subkeys);
- num_values_ = num_values;
- num_subkeys_ = num_subkeys;
-
- return true;
-}
-
-// Writes the values and subkeys of this object into |key|.
-bool DeleteRegKeyWorkItem::RegKeyBackup::WriteTo(RegKey* key) const {
- LONG result = ERROR_SUCCESS;
-
- // Write the values.
- for (int i = 0; i < num_values_; ++i) {
- const RegValueBackup& value = values_[i];
- result = RegSetValueEx(key->Handle(), value.name(), 0, value.type(),
- value.data(), value.data_len());
- if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed writing value \"" << value.name_str()
- << "\", result: " << result;
- return false;
- }
- }
-
- // Write the subkeys.
- RegKey subkey;
- for (int i = 0; i < num_subkeys_; ++i) {
- const std::wstring& name = subkey_names_[i];
-
- result = subkey.Create(key->Handle(), name.c_str(), KEY_WRITE);
- if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed creating subkey \"" << name << "\", result: "
- << result;
- return false;
- }
- if (!subkeys_[i].WriteTo(&subkey)) {
- LOG(ERROR) << "Failed writing subkey \"" << name << "\", result: "
- << result;
- return false;
- }
- }
-
- return true;
-}
-
DeleteRegKeyWorkItem::~DeleteRegKeyWorkItem() {
}
@@ -271,30 +18,22 @@
const std::wstring& path)
: predefined_root_(predefined_root),
path_(path) {
+ DCHECK(predefined_root);
// It's a safe bet that we don't want to delete one of the root trees.
DCHECK(!path.empty());
}
bool DeleteRegKeyWorkItem::Do() {
- scoped_ptr<RegKeyBackup> backup;
+ if (path_.empty())
+ return false;
+ RegistryKeyBackup backup;
+
// Only try to make a backup if we're not configured to ignore failures.
if (!ignore_failure_) {
- RegKey original_key;
-
- // Does the key exist?
- LONG result = original_key.Open(predefined_root_, path_.c_str(),
- kKeyReadNoNotify);
- if (result == ERROR_SUCCESS) {
- backup.reset(new RegKeyBackup());
- if (!backup->Initialize(original_key)) {
- LOG(ERROR) << "Failed to backup key at " << path_;
- return ignore_failure_;
- }
- } else if (result != ERROR_FILE_NOT_FOUND) {
- LOG(ERROR) << "Failed to open key at " << path_
- << " to create backup, result: " << result;
- return ignore_failure_;
+ if (!backup.Initialize(predefined_root_, path_.c_str())) {
+ LOG(ERROR) << "Failed to backup destination for registry key copy.";
+ return false;
}
}
@@ -313,7 +52,7 @@
}
void DeleteRegKeyWorkItem::Rollback() {
- if (ignore_failure_ || backup_.get() == NULL)
+ if (ignore_failure_)
return;
// Delete anything in the key before restoring the backup in case someone else
@@ -326,13 +65,6 @@
// Restore the old contents. The restoration takes on its default security
// attributes; any custom attributes are lost.
- RegKey original_key;
- result = original_key.Create(predefined_root_, path_.c_str(), KEY_WRITE);
- if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed to create original key at " << path_
- << " in rollback, result: " << result;
- } else {
- if (!backup_->WriteTo(&original_key))
- LOG(ERROR) << "Failed to restore key in rollback, result: " << result;
- }
+ if (!backup_.WriteTo(predefined_root_, path_.c_str()))
+ LOG(ERROR) << "Failed to restore key in rollback.";
}
« no previous file with comments | « chrome/installer/util/delete_reg_key_work_item.h ('k') | chrome/installer/util/delete_reg_key_work_item_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698