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

Side by Side Diff: chrome/installer/util/copy_reg_key_work_item.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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/installer/util/copy_reg_key_work_item.h"
6
7 #include <shlwapi.h>
8
9 #include "base/logging.h"
10 #include "base/stringprintf.h"
11 #include "base/win/registry.h"
12 #include "chrome/installer/util/registry_key_backup.h"
13
14 using base::win::RegKey;
15
16 namespace {
17 const REGSAM kKeyReadNoNotify = (KEY_READ) & ~(KEY_NOTIFY);
18 }
erikwright (departed) 2011/09/15 18:38:57 } // namespace http://google-styleguide.googleco
grt (UTC plus 2) 2011/09/16 17:45:45 Done.
19
20 CopyRegKeyWorkItem::~CopyRegKeyWorkItem() {
21 }
22
23 CopyRegKeyWorkItem::CopyRegKeyWorkItem(HKEY predefined_root,
24 const std::wstring& source_key_path,
25 const std::wstring& dest_key_path)
26 : predefined_root_(predefined_root),
27 source_key_path_(source_key_path),
28 dest_key_path_(dest_key_path) {
29 // It's a safe bet that we don't want to copy or overwrite one of the root
30 // trees.
31 DCHECK(!source_key_path.empty());
32 DCHECK(!dest_key_path.empty());
33 }
34
35 bool CopyRegKeyWorkItem::Do() {
36 scoped_ptr<RegistryKeyBackup> backup;
37 RegKey dest_key;
38
39 // Only try to make a backup if we're not configured to ignore failures.
40 if (!ignore_failure_) {
41 // Does the key exist?
42 LONG result = dest_key.Open(predefined_root_, dest_key_path_.c_str(),
erikwright (departed) 2011/09/15 18:38:57 Any chance you can make this a little DRYer? http
grt (UTC plus 2) 2011/09/16 17:45:45 That code was so damn sweet I had to do it twice,
43 kKeyReadNoNotify);
44 if (result == ERROR_SUCCESS) {
45 backup.reset(new RegistryKeyBackup());
46 if (!backup->Initialize(dest_key)) {
47 LOG(ERROR) << "Failed to backup key at " << dest_key_path_;
48 return ignore_failure_;
49 }
50 } else if (result != ERROR_FILE_NOT_FOUND) {
51 LOG(ERROR) << "Failed to open key at " << dest_key_path_
52 << " to create backup, result: " << result;
53 return ignore_failure_;
54 }
55 dest_key.Close();
56 }
57
58 // Delete the destination before attempting to copy.
59 LONG result = SHDeleteKey(predefined_root_, dest_key_path_.c_str());
erikwright (departed) 2011/09/15 18:38:57 Should you not, immediately after this delete succ
grt (UTC plus 2) 2011/09/16 17:45:45 Good catch. Yes, the list will rollback the faile
60 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
61 LOG(ERROR) << "Failed to delete key at " << dest_key_path_ << ", result: "
62 << result;
63 } else {
64 // Make the copy.
65 result = dest_key.Create(predefined_root_, dest_key_path_.c_str(),
66 KEY_WRITE);
67 if (result != ERROR_SUCCESS) {
68 LOG(ERROR) << "Failed to open destination key at " << dest_key_path_
69 << ", result: " << result;
70 } else {
71 result = SHCopyKey(predefined_root_, source_key_path_.c_str(),
72 dest_key.Handle(), 0);
73 switch (result) {
74 case ERROR_FILE_NOT_FOUND:
75 // The source didn't exist, so neither should the destination.
76 dest_key.Close();
77 SHDeleteKey(predefined_root_, dest_key_path_.c_str());
78 // Handle like a success.
79 result = ERROR_SUCCESS;
80 // -- FALL THROUGH TO SUCCESS CASE --
81 case ERROR_SUCCESS:
82 // We've succeeded, so remember any backup we may have made.
83 backup_.swap(backup);
84 break;
85 default:
86 LOG(ERROR) << "Failed to copy key from " << source_key_path_ << " to "
87 << dest_key_path_ << ", result: " << result;
88 break;
89 }
90 }
91 }
92
93 return ignore_failure_ ? true : (result == ERROR_SUCCESS);
94 }
95
96 void CopyRegKeyWorkItem::Rollback() {
97 if (ignore_failure_)
erikwright (departed) 2011/09/15 18:38:57 Is it really up to each task to do this?
grt (UTC plus 2) 2011/09/16 17:45:45 Sadly, yes. Overhauling WorkItemList is outside o
98 return;
99
100 // Delete anything in the key before restoring the backup in case someone else
101 // put new data in the key after Do().
102 LONG result = SHDeleteKey(predefined_root_, dest_key_path_.c_str());
103 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
104 LOG(ERROR) << "Failed to delete key at " << dest_key_path_
105 << " in rollback, result: " << result;
erikwright (departed) 2011/09/15 18:38:57 Is it intentional that we continue with the attemp
grt (UTC plus 2) 2011/09/16 17:45:45 Yeah, I think it's consistent to go ahead and rest
106 }
107
108 // Restore the old contents. The restoration takes on its default security
erikwright (departed) 2011/09/15 18:38:57 This is also a nearly line-for-line duplicate of d
grt (UTC plus 2) 2011/09/16 17:45:45 Done.
109 // attributes; any custom attributes are lost.
110 if (backup_.get() != NULL) {
111 RegKey dest_key;
112 result = dest_key.Create(predefined_root_, dest_key_path_.c_str(),
113 KEY_WRITE);
114 if (result != ERROR_SUCCESS) {
115 LOG(ERROR) << "Failed to create destination key at " << dest_key_path_
116 << " in rollback, result: " << result;
117 } else {
118 if (!backup_->WriteTo(&dest_key))
119 LOG(ERROR) << "Failed to restore key in rollback.";
120 }
121 }
122 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698