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

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

Issue 7890069: Added CopyRegKeyWorkItem in support of IE low rights policy fixes. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Ready for review Created 9 years, 3 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/registry_key_backup.cc
diff --git a/chrome/installer/util/delete_reg_key_work_item.cc b/chrome/installer/util/registry_key_backup.cc
similarity index 56%
copy from chrome/installer/util/delete_reg_key_work_item.cc
copy to chrome/installer/util/registry_key_backup.cc
index b044f447c47d015beebd4d00aeaa29549bfd0d59..f2aef3cae25274924b38c187f159d2fafaba81c9 100644
--- a/chrome/installer/util/delete_reg_key_work_item.cc
+++ b/chrome/installer/util/registry_key_backup.cc
@@ -1,19 +1,15 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/installer/util/delete_reg_key_work_item.h"
+#include "chrome/installer/util/registry_key_backup.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;
@@ -21,77 +17,61 @@ namespace {
const REGSAM kKeyReadNoNotify = (KEY_READ) & ~(KEY_NOTIFY);
}
erikwright (departed) 2011/09/15 18:38:57 } // namespace
grt (UTC plus 2) 2011/09/16 17:45:45 Done.
-// 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 {
+// A container for a registry value.
+class RegistryKeyBackup::RegistryValueBackup {
public:
- RegKeyBackup();
- bool Initialize(const RegKey& key);
- bool WriteTo(RegKey* key) const;
+ RegistryValueBackup();
+ ~RegistryValueBackup();
+ 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:
- // 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()); }
+ std::wstring name_;
+ std::vector<uint8> data_;
+ DWORD type_;
- 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);
+ DISALLOW_COPY_AND_ASSIGN(RegistryValueBackup);
};
-DeleteRegKeyWorkItem::RegKeyBackup::RegValueBackup::RegValueBackup()
+RegistryKeyBackup::RegistryValueBackup::RegistryValueBackup()
: type_(REG_NONE) {
}
-void DeleteRegKeyWorkItem::RegKeyBackup::RegValueBackup::Initialize(
+RegistryKeyBackup::RegistryValueBackup::~RegistryValueBackup()
erikwright (departed) 2011/09/15 18:38:57 Why are you required to explicitly define a destru
grt (UTC plus 2) 2011/09/16 17:45:45 Since the class has non-POD data members, the dtor
+{
+}
+
+void RegistryKeyBackup::RegistryValueBackup::Initialize(
const wchar_t* name_buffer,
DWORD name_size,
- DWORD type, const uint8* data,
+ 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()
+RegistryKeyBackup::RegistryKeyBackup()
: num_values_(0),
num_subkeys_(0) {
}
+RegistryKeyBackup::~RegistryKeyBackup()
+{
+}
+
// 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;
+bool RegistryKeyBackup::Initialize(const RegKey& key) {
+ scoped_array<RegistryValueBackup> values;
scoped_array<std::wstring> subkey_names;
- scoped_array<RegKeyBackup> subkeys;
+ scoped_array<RegistryKeyBackup> subkeys;
DWORD num_subkeys = 0;
DWORD max_subkey_name_len = 0;
@@ -117,7 +97,7 @@ bool DeleteRegKeyWorkItem::RegKeyBackup::Initialize(const RegKey& key) {
// Backup the values.
if (num_values != 0) {
- values.reset(new RegValueBackup[num_values]);
+ values.reset(new RegistryValueBackup[num_values]);
scoped_array<uint8> value_buffer(new uint8[max_value_len]);
DWORD name_size = 0;
DWORD value_type = REG_NONE;
@@ -140,14 +120,16 @@ bool DeleteRegKeyWorkItem::RegKeyBackup::Initialize(const RegKey& key) {
case ERROR_MORE_DATA:
if (value_size > max_value_len) {
max_value_len = value_size;
+ value_buffer.reset(); // Release to heap before new allocation.
value_buffer.reset(new uint8[max_value_len]);
} else {
- DCHECK(max_name_len - 1 < name_size);
+ DCHECK_LT(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(); // Release to heap before new allocation.
name_buffer.reset(new wchar_t[max_name_len]);
}
break;
@@ -166,7 +148,7 @@ bool DeleteRegKeyWorkItem::RegKeyBackup::Initialize(const RegKey& key) {
// Backup the subkeys.
if (num_subkeys != 0) {
subkey_names.reset(new std::wstring[num_subkeys]);
- subkeys.reset(new RegKeyBackup[num_subkeys]);
+ subkeys.reset(new RegistryKeyBackup[num_subkeys]);
DWORD name_size = 0;
// Get the names of them.
@@ -228,12 +210,14 @@ bool DeleteRegKeyWorkItem::RegKeyBackup::Initialize(const RegKey& key) {
}
// Writes the values and subkeys of this object into |key|.
-bool DeleteRegKeyWorkItem::RegKeyBackup::WriteTo(RegKey* key) const {
+bool RegistryKeyBackup::WriteTo(RegKey* key) const {
+ DCHECK(key);
+
LONG result = ERROR_SUCCESS;
// Write the values.
- for (int i = 0; i < num_values_; ++i) {
- const RegValueBackup& value = values_[i];
+ for (DWORD i = 0; i < num_values_; ++i) {
+ const RegistryValueBackup& value = values_[i];
result = RegSetValueEx(key->Handle(), value.name(), 0, value.type(),
value.data(), value.data_len());
if (result != ERROR_SUCCESS) {
@@ -245,7 +229,7 @@ bool DeleteRegKeyWorkItem::RegKeyBackup::WriteTo(RegKey* key) const {
// Write the subkeys.
RegKey subkey;
- for (int i = 0; i < num_subkeys_; ++i) {
+ for (DWORD i = 0; i < num_subkeys_; ++i) {
const std::wstring& name = subkey_names_[i];
result = subkey.Create(key->Handle(), name.c_str(), KEY_WRITE);
@@ -263,76 +247,3 @@ bool DeleteRegKeyWorkItem::RegKeyBackup::WriteTo(RegKey* key) const {
return true;
}
-
-DeleteRegKeyWorkItem::~DeleteRegKeyWorkItem() {
-}
-
-DeleteRegKeyWorkItem::DeleteRegKeyWorkItem(HKEY predefined_root,
- const std::wstring& path)
- : predefined_root_(predefined_root),
- path_(path) {
- // 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;
-
- // 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_;
- }
- }
-
- // Delete the key.
- LONG result = SHDeleteKey(predefined_root_, path_.c_str());
- if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
- LOG(ERROR) << "Failed to delete key at " << path_ << ", result: "
- << result;
- return ignore_failure_;
- }
-
- // We've succeeded, so remember any backup we may have made.
- backup_.swap(backup);
-
- return true;
-}
-
-void DeleteRegKeyWorkItem::Rollback() {
- if (ignore_failure_ || backup_.get() == NULL)
- return;
-
- // Delete anything in the key before restoring the backup in case someone else
- // put new data in the key after Do().
- LONG result = SHDeleteKey(predefined_root_, path_.c_str());
- if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
- LOG(ERROR) << "Failed to delete key at " << path_ << " in rollback, "
- "result: " << result;
- }
-
- // 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;
- }
-}

Powered by Google App Engine
This is Rietveld 408576698