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

Side by Side Diff: chrome/installer/setup/install.cc

Issue 6288009: More installer refactoring in the interest of fixing some bugs and cleaning t... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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/setup/install.h" 5 #include "chrome/installer/setup/install.h"
6 6
7 #include <shlobj.h> 7 #include <shlobj.h>
8 #include <time.h> 8 #include <time.h>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/file_path.h" 12 #include "base/file_path.h"
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/path_service.h" 15 #include "base/path_service.h"
16 #include "base/scoped_ptr.h" 16 #include "base/scoped_ptr.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "base/win/registry.h"
20 #include "chrome/installer/setup/setup_constants.h" 19 #include "chrome/installer/setup/setup_constants.h"
21 #include "chrome/installer/setup/install_worker.h" 20 #include "chrome/installer/setup/install_worker.h"
22 #include "chrome/installer/util/browser_distribution.h" 21 #include "chrome/installer/util/browser_distribution.h"
23 #include "chrome/installer/util/channel_info.h"
24 #include "chrome/installer/util/chrome_frame_distribution.h"
25 #include "chrome/installer/util/conditional_work_item_list.h"
26 #include "chrome/installer/util/create_reg_key_work_item.h" 22 #include "chrome/installer/util/create_reg_key_work_item.h"
27 #include "chrome/installer/util/delete_after_reboot_helper.h" 23 #include "chrome/installer/util/delete_after_reboot_helper.h"
28 #include "chrome/installer/util/google_update_constants.h" 24 #include "chrome/installer/util/google_update_constants.h"
29 #include "chrome/installer/util/helper.h" 25 #include "chrome/installer/util/helper.h"
30 #include "chrome/installer/util/install_util.h" 26 #include "chrome/installer/util/install_util.h"
31 #include "chrome/installer/util/installation_state.h" 27 #include "chrome/installer/util/installation_state.h"
32 #include "chrome/installer/util/installer_state.h" 28 #include "chrome/installer/util/installer_state.h"
33 #include "chrome/installer/util/master_preferences.h" 29 #include "chrome/installer/util/master_preferences.h"
34 #include "chrome/installer/util/master_preferences_constants.h" 30 #include "chrome/installer/util/master_preferences_constants.h"
35 #include "chrome/installer/util/package.h"
36 #include "chrome/installer/util/package_properties.h"
37 #include "chrome/installer/util/product.h" 31 #include "chrome/installer/util/product.h"
38 #include "chrome/installer/util/set_reg_value_work_item.h" 32 #include "chrome/installer/util/set_reg_value_work_item.h"
39 #include "chrome/installer/util/shell_util.h" 33 #include "chrome/installer/util/shell_util.h"
40 #include "chrome/installer/util/util_constants.h" 34 #include "chrome/installer/util/util_constants.h"
41 #include "chrome/installer/util/work_item_list.h" 35 #include "chrome/installer/util/work_item_list.h"
42 36
43 // Build-time generated include file. 37 // Build-time generated include file.
44 #include "installer_util_strings.h" // NOLINT 38 #include "installer_util_strings.h" // NOLINT
45 #include "registered_dlls.h" // NOLINT 39 #include "registered_dlls.h" // NOLINT
46 40
47 using base::win::RegKey;
48 using installer::ChannelInfo;
49 using installer::InstallerState; 41 using installer::InstallerState;
50 using installer::InstallationState; 42 using installer::InstallationState;
51 using installer::MasterPreferences;
52 using installer::Products;
53 using installer::Product; 43 using installer::Product;
54 using installer::Package;
55 using installer::PackageProperties;
56 44
57 namespace { 45 namespace {
58 46
59 void AddChromeToMediaPlayerList() { 47 void AddChromeToMediaPlayerList() {
60 std::wstring reg_path(installer::kMediaPlayerRegPath); 48 std::wstring reg_path(installer::kMediaPlayerRegPath);
61 // registry paths can also be appended like file system path 49 // registry paths can also be appended like file system path
62 file_util::AppendToPath(&reg_path, installer::kChromeExe); 50 file_util::AppendToPath(&reg_path, installer::kChromeExe);
63 VLOG(1) << "Adding Chrome to Media player list at " << reg_path; 51 VLOG(1) << "Adding Chrome to Media player list at " << reg_path;
64 scoped_ptr<WorkItem> work_item(WorkItem::CreateCreateRegKeyWorkItem( 52 scoped_ptr<WorkItem> work_item(WorkItem::CreateCreateRegKeyWorkItem(
65 HKEY_LOCAL_MACHINE, reg_path)); 53 HKEY_LOCAL_MACHINE, reg_path));
66 54
67 // if the operation fails we log the error but still continue 55 // if the operation fails we log the error but still continue
68 if (!work_item.get()->Do()) 56 if (!work_item.get()->Do())
69 LOG(ERROR) << "Could not add Chrome to media player inclusion list."; 57 LOG(ERROR) << "Could not add Chrome to media player inclusion list.";
70 } 58 }
71 59
72 void AddInstallerCopyTasks(const FilePath& setup_path, 60 void AddInstallerCopyTasks(const InstallerState& installer_state,
61 const FilePath& setup_path,
73 const FilePath& archive_path, 62 const FilePath& archive_path,
74 const FilePath& temp_path, 63 const FilePath& temp_path,
75 const Version& new_version, 64 const Version& new_version,
76 WorkItemList* install_list, 65 WorkItemList* install_list) {
77 const Package& package) {
78 DCHECK(install_list); 66 DCHECK(install_list);
79 FilePath installer_dir(package.GetInstallerDirectory(new_version)); 67 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version));
80 install_list->AddCreateDirWorkItem(installer_dir); 68 install_list->AddCreateDirWorkItem(installer_dir);
81 69
82 FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); 70 FilePath exe_dst(installer_dir.Append(setup_path.BaseName()));
83 FilePath archive_dst(installer_dir.Append(archive_path.BaseName())); 71 FilePath archive_dst(installer_dir.Append(archive_path.BaseName()));
84 72
85 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), 73 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(),
86 temp_path.value(), WorkItem::ALWAYS); 74 temp_path.value(), WorkItem::ALWAYS);
87 if (package.system_level()) { 75 if (installer_state.system_install()) {
88 install_list->AddCopyTreeWorkItem(archive_path.value(), archive_dst.value(), 76 install_list->AddCopyTreeWorkItem(archive_path.value(), archive_dst.value(),
89 temp_path.value(), WorkItem::ALWAYS); 77 temp_path.value(), WorkItem::ALWAYS);
90 } else { 78 } else {
91 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(), 79 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(),
92 temp_path.value()); 80 temp_path.value());
93 } 81 }
94 } 82 }
95 83
96 // Adds work items that make registry adjustments for Google Update. When a
97 // product is installed (including overinstall), Google Update will write the
98 // channel ("ap") value into either Chrome or Chrome Frame's ClientState key.
99 // In the multi-install case, this value is used as the basis upon which the
100 // package's channel value is built (by adding the ordered list of installed
101 // products and their options).
102 void AddGoogleUpdateWorkItems(const InstallationState& original_state,
103 const InstallerState& installer_state,
104 const Package& package,
105 WorkItemList* install_list) {
106 // Is a multi-install product being installed or over-installed?
107 if (installer_state.operation() != InstallerState::MULTI_INSTALL)
108 return;
109
110 const HKEY reg_root = package.system_level() ? HKEY_LOCAL_MACHINE :
111 HKEY_CURRENT_USER;
112 const std::wstring key_path = installer_state.state_key();
113 ChannelInfo channel_info;
114
115 // Update the "ap" value for the product being installed/updated.
116 // It is completely acceptable for there to be no "ap" value or even no
117 // ClientState key. Note that we check the registry rather than
118 // original_state since on a fresh install the "ap" value will be present
119 // sans "pv" value.
120 channel_info.Initialize(RegKey(reg_root, key_path.c_str(), KEY_QUERY_VALUE));
121
122 // This is a multi-install product.
123 bool modified = channel_info.SetMultiInstall(true);
124
125 // Add the appropriate modifiers for all products and their options.
126 Products::const_iterator scan = package.products().begin();
127 const Products::const_iterator end = package.products().end();
128 for (; scan != end; ++scan) {
129 modified |= scan->get()->distribution()->SetChannelFlags(true,
130 &channel_info);
131 }
132
133 // Write the results if needed.
134 if (modified) {
135 install_list->AddSetRegValueWorkItem(reg_root, key_path,
136 google_update::kRegApField,
137 channel_info.value(), true);
138 }
139
140 // Synchronize the other products and the package with this one.
141 std::wstring other_key;
142 std::vector<std::wstring> keys;
143
144 keys.reserve(package.products().size());
145 other_key = package.properties()->GetStateKey();
146 if (other_key != key_path)
147 keys.push_back(other_key);
148 scan = package.products().begin();
149 for (; scan != end; ++scan) {
150 other_key = scan->get()->distribution()->GetStateKey();
151 if (other_key != key_path)
152 keys.push_back(other_key);
153 }
154
155 RegKey key;
156 ChannelInfo other_info;
157 std::vector<std::wstring>::const_iterator kscan = keys.begin();
158 std::vector<std::wstring>::const_iterator kend = keys.end();
159 for (; kscan != kend; ++kscan) {
160 // Handle the case where the ClientState key doesn't exist by creating it.
161 // This takes care of the multi-installer's package key, which is not
162 // created by Google Update for us.
163 if (key.Open(reg_root, kscan->c_str(), KEY_QUERY_VALUE) != ERROR_SUCCESS ||
164 !other_info.Initialize(key)) {
165 other_info.set_value(std::wstring());
166 }
167 if (!other_info.Equals(channel_info)) {
168 if (!key.Valid())
169 install_list->AddCreateRegKeyWorkItem(reg_root, *kscan);
170 install_list->AddSetRegValueWorkItem(reg_root, *kscan,
171 google_update::kRegApField,
172 channel_info.value(), true);
173 }
174 }
175 // TODO(grt): check for other keys/values we should put in the package's
176 // ClientState and/or Clients key.
177 }
178
179 // This is called when an MSI installation is run. It may be that a user is
180 // attempting to install the MSI on top of a non-MSI managed installation.
181 // If so, try and remove any existing uninstallation shortcuts, as we want the
182 // uninstall to be managed entirely by the MSI machinery (accessible via the
183 // Add/Remove programs dialog).
184 void AddDeleteUninstallShortcutsForMSIWorkItems(const Product& product,
185 WorkItemList* work_item_list) {
186 DCHECK(product.IsMsi()) << "This must only be called for MSI installations!";
187
188 // First attempt to delete the old installation's ARP dialog entry.
189 HKEY reg_root = product.system_level() ? HKEY_LOCAL_MACHINE :
190 HKEY_CURRENT_USER;
191 base::win::RegKey root_key(reg_root, L"", KEY_ALL_ACCESS);
192 std::wstring uninstall_reg(product.distribution()->GetUninstallRegPath());
193
194 WorkItem* delete_reg_key = work_item_list->AddDeleteRegKeyWorkItem(
195 reg_root, uninstall_reg);
196 delete_reg_key->set_ignore_failure(true);
197
198 // Then attempt to delete the old installation's start menu shortcut.
199 FilePath uninstall_link;
200 if (product.system_level()) {
201 PathService::Get(base::DIR_COMMON_START_MENU, &uninstall_link);
202 } else {
203 PathService::Get(base::DIR_START_MENU, &uninstall_link);
204 }
205
206 if (uninstall_link.empty()) {
207 LOG(ERROR) << "Failed to get location for shortcut.";
208 } else {
209 uninstall_link = uninstall_link.Append(
210 product.distribution()->GetAppShortCutName());
211 uninstall_link = uninstall_link.Append(
212 product.distribution()->GetUninstallLinkName() + L".lnk");
213 VLOG(1) << "Deleting old uninstall shortcut (if present): "
214 << uninstall_link.value();
215 WorkItem* delete_link = work_item_list->AddDeleteTreeWorkItem(
216 uninstall_link);
217 delete_link->set_ignore_failure(true);
218 delete_link->set_log_message(
219 "Failed to delete old uninstall shortcut.");
220 }
221 }
222
223 // Copy master preferences file provided to installer, in the same folder 84 // Copy master preferences file provided to installer, in the same folder
224 // as chrome.exe so Chrome first run can find it. This function will be called 85 // as chrome.exe so Chrome first run can find it. This function will be called
225 // only on the first install of Chrome. 86 // only on the first install of Chrome.
226 void CopyPreferenceFileForFirstRun(const Package& package, 87 void CopyPreferenceFileForFirstRun(const InstallerState& installer_state,
227 const FilePath& prefs_source_path) { 88 const FilePath& prefs_source_path) {
228 FilePath prefs_dest_path(package.path().AppendASCII( 89 FilePath prefs_dest_path(installer_state.target_path().AppendASCII(
229 installer::kDefaultMasterPrefs)); 90 installer::kDefaultMasterPrefs));
230 if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) { 91 if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) {
231 VLOG(1) << "Failed to copy master preferences from:" 92 VLOG(1) << "Failed to copy master preferences from:"
232 << prefs_source_path.value() << " gle: " << ::GetLastError(); 93 << prefs_source_path.value() << " gle: " << ::GetLastError();
233 } 94 }
234 } 95 }
235 96
236 // This method creates Chrome shortcuts in Start->Programs for all users or 97 // This method creates Chrome shortcuts in Start->Programs for all users or
237 // only for current user depending on whether it is system wide install or 98 // only for current user depending on whether it is system wide install or
238 // user only install. 99 // user only install.
239 // 100 //
240 // If first_install is true, it creates shortcuts for launching and 101 // If first_install is true, it creates shortcuts for launching and
241 // uninstalling chrome. 102 // uninstalling chrome.
242 // If first_install is false, the function only updates the shortcut for 103 // If first_install is false, the function only updates the shortcut for
243 // uninstalling chrome. According to 104 // uninstalling chrome. According to
244 // http://blogs.msdn.com/oldnewthing/archive/2005/11/24/496690.aspx, 105 // http://blogs.msdn.com/oldnewthing/archive/2005/11/24/496690.aspx,
245 // updating uninstall shortcut should not trigger Windows "new application 106 // updating uninstall shortcut should not trigger Windows "new application
246 // installed" notification. 107 // installed" notification.
247 // 108 //
248 // If the shortcuts do not exist, the function does not recreate them during 109 // If the shortcuts do not exist, the function does not recreate them during
249 // update. 110 // update.
250 bool CreateOrUpdateChromeShortcuts(const FilePath& setup_path, 111 bool CreateOrUpdateChromeShortcuts(const InstallerState& installer_state,
112 const FilePath& setup_path,
251 const Version& new_version, 113 const Version& new_version,
252 installer::InstallStatus install_status, 114 installer::InstallStatus install_status,
253 const Product& product, 115 const Product& product,
254 bool create_all_shortcut, 116 bool create_all_shortcut,
255 bool alt_shortcut) { 117 bool alt_shortcut) {
256 // TODO(tommi): Change this function to use WorkItemList. 118 // TODO(tommi): Change this function to use WorkItemList.
257 DCHECK(product.is_chrome()); 119 DCHECK(product.is_chrome());
258 120
259 FilePath shortcut_path; 121 FilePath shortcut_path;
260 int dir_enum = product.system_level() ? 122 int dir_enum = installer_state.system_install() ?
261 base::DIR_COMMON_START_MENU : base::DIR_START_MENU; 123 base::DIR_COMMON_START_MENU : base::DIR_START_MENU;
262 if (!PathService::Get(dir_enum, &shortcut_path)) { 124 if (!PathService::Get(dir_enum, &shortcut_path)) {
263 LOG(ERROR) << "Failed to get location for shortcut."; 125 LOG(ERROR) << "Failed to get location for shortcut.";
264 return false; 126 return false;
265 } 127 }
266 128
267 BrowserDistribution* browser_dist = product.distribution(); 129 BrowserDistribution* browser_dist = product.distribution();
268 130
269 // The location of Start->Programs->Google Chrome folder 131 // The location of Start->Programs->Google Chrome folder
270 const std::wstring product_name(browser_dist->GetAppShortCutName()); 132 const std::wstring product_name(browser_dist->GetAppShortCutName());
271 const std::wstring product_desc(browser_dist->GetAppDescription()); 133 const std::wstring product_desc(browser_dist->GetAppDescription());
272 shortcut_path = shortcut_path.Append(product_name); 134 shortcut_path = shortcut_path.Append(product_name);
273 135
274 // Create/update Chrome link (points to chrome.exe) & Uninstall Chrome link 136 // Create/update Chrome link (points to chrome.exe) & Uninstall Chrome link
275 // (which points to setup.exe) under this folder only if: 137 // (which points to setup.exe) under this folder only if:
276 // - This is a new install or install repair 138 // - This is a new install or install repair
277 // OR 139 // OR
278 // - The shortcut already exists in case of updates (user may have deleted 140 // - The shortcut already exists in case of updates (user may have deleted
279 // shortcuts since our install. So on updates we only update if shortcut 141 // shortcuts since our install. So on updates we only update if shortcut
280 // already exists) 142 // already exists)
281 bool ret = true; 143 bool ret = true;
282 FilePath chrome_link(shortcut_path); // Chrome link (launches Chrome) 144 FilePath chrome_link(shortcut_path); // Chrome link (launches Chrome)
283 chrome_link = chrome_link.Append(product_name + L".lnk"); 145 chrome_link = chrome_link.Append(product_name + L".lnk");
284 // Chrome link target 146 // Chrome link target
285 FilePath chrome_exe( 147 FilePath chrome_exe(
286 product.package().path().Append(installer::kChromeExe)); 148 installer_state.target_path().Append(installer::kChromeExe));
287 149
288 if ((install_status == installer::FIRST_INSTALL_SUCCESS) || 150 if ((install_status == installer::FIRST_INSTALL_SUCCESS) ||
289 (install_status == installer::INSTALL_REPAIRED)) { 151 (install_status == installer::INSTALL_REPAIRED)) {
290 if (!file_util::PathExists(shortcut_path)) 152 if (!file_util::PathExists(shortcut_path))
291 file_util::CreateDirectoryW(shortcut_path); 153 file_util::CreateDirectoryW(shortcut_path);
292 154
293 VLOG(1) << "Creating shortcut to " << chrome_exe.value() << " at " 155 VLOG(1) << "Creating shortcut to " << chrome_exe.value() << " at "
294 << chrome_link.value(); 156 << chrome_link.value();
295 ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(), 157 ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(),
296 chrome_link.value(), product_desc, true); 158 chrome_link.value(), product_desc, true);
297 } else if (file_util::PathExists(chrome_link)) { 159 } else if (file_util::PathExists(chrome_link)) {
298 VLOG(1) << "Updating shortcut at " << chrome_link.value() 160 VLOG(1) << "Updating shortcut at " << chrome_link.value()
299 << " to point to " << chrome_exe.value(); 161 << " to point to " << chrome_exe.value();
300 ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(), 162 ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(),
301 chrome_link.value(), product_desc, false); 163 chrome_link.value(), product_desc, false);
302 } else { 164 } else {
303 VLOG(1) 165 VLOG(1)
304 << "not first or repaired install, link file doesn't exist. status: " 166 << "not first or repaired install, link file doesn't exist. status: "
305 << install_status; 167 << install_status;
306 } 168 }
307 169
308 // Create/update uninstall link if we are not an MSI install. MSI 170 // Create/update uninstall link if we are not an MSI install. MSI
309 // installations are, for the time being, managed only through the 171 // installations are, for the time being, managed only through the
310 // Add/Remove Programs dialog. 172 // Add/Remove Programs dialog.
311 // TODO(robertshield): We could add a shortcut to msiexec /X {GUID} here. 173 // TODO(robertshield): We could add a shortcut to msiexec /X {GUID} here.
312 if (ret && !product.IsMsi()) { 174 if (ret && !installer_state.msi()) {
313 FilePath uninstall_link(shortcut_path); // Uninstall Chrome link 175 FilePath uninstall_link(shortcut_path); // Uninstall Chrome link
314 uninstall_link = uninstall_link.Append( 176 uninstall_link = uninstall_link.Append(
315 browser_dist->GetUninstallLinkName() + L".lnk"); 177 browser_dist->GetUninstallLinkName() + L".lnk");
316 if ((install_status == installer::FIRST_INSTALL_SUCCESS) || 178 if ((install_status == installer::FIRST_INSTALL_SUCCESS) ||
317 (install_status == installer::INSTALL_REPAIRED) || 179 (install_status == installer::INSTALL_REPAIRED) ||
318 (file_util::PathExists(uninstall_link))) { 180 (file_util::PathExists(uninstall_link))) {
319 if (!file_util::PathExists(shortcut_path)) 181 if (!file_util::PathExists(shortcut_path))
320 file_util::CreateDirectory(shortcut_path); 182 file_util::CreateDirectory(shortcut_path);
321 183
322 FilePath setup_exe( 184 FilePath setup_exe(installer_state.GetInstallerDirectory(new_version)
323 product.package().GetInstallerDirectory(new_version) 185 .Append(setup_path.BaseName()));
324 .Append(setup_path.BaseName()));
325 186
326 CommandLine arguments(CommandLine::NO_PROGRAM); 187 CommandLine arguments(CommandLine::NO_PROGRAM);
327 AppendUninstallCommandLineFlags(&arguments, product); 188 AppendUninstallCommandLineFlags(installer_state, product, &arguments);
328 VLOG(1) << "Creating/updating uninstall link at " 189 VLOG(1) << "Creating/updating uninstall link at "
329 << uninstall_link.value(); 190 << uninstall_link.value();
330 ret = file_util::CreateShortcutLink(setup_exe.value().c_str(), 191 ret = file_util::CreateShortcutLink(setup_exe.value().c_str(),
331 uninstall_link.value().c_str(), 192 uninstall_link.value().c_str(),
332 NULL, 193 NULL,
333 arguments.command_line_string().c_str(), 194 arguments.command_line_string().c_str(),
334 NULL, 195 NULL,
335 setup_exe.value().c_str(), 196 setup_exe.value().c_str(),
336 0, 197 0,
337 NULL); 198 NULL);
338 } 199 }
339 } 200 }
340 201
341 // Update Desktop and Quick Launch shortcuts. If --create-new-shortcuts 202 // Update Desktop and Quick Launch shortcuts. If --create-new-shortcuts
342 // is specified we want to create them, otherwise we update them only if 203 // is specified we want to create them, otherwise we update them only if
343 // they exist. 204 // they exist.
344 if (ret) { 205 if (ret) {
345 if (product.system_level()) { 206 if (installer_state.system_install()) {
346 ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(), 207 ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(),
347 chrome_exe.value(), product_desc, ShellUtil::SYSTEM_LEVEL, 208 chrome_exe.value(), product_desc, ShellUtil::SYSTEM_LEVEL,
348 alt_shortcut, create_all_shortcut); 209 alt_shortcut, create_all_shortcut);
349 if (ret) { 210 if (ret) {
350 ret = ShellUtil::CreateChromeQuickLaunchShortcut( 211 ret = ShellUtil::CreateChromeQuickLaunchShortcut(
351 product.distribution(), chrome_exe.value(), 212 product.distribution(), chrome_exe.value(),
352 ShellUtil::CURRENT_USER | ShellUtil::SYSTEM_LEVEL, 213 ShellUtil::CURRENT_USER | ShellUtil::SYSTEM_LEVEL,
353 create_all_shortcut); 214 create_all_shortcut);
354 } 215 }
355 } else { 216 } else {
356 ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(), 217 ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(),
357 chrome_exe.value(), product_desc, ShellUtil::CURRENT_USER, 218 chrome_exe.value(), product_desc, ShellUtil::CURRENT_USER,
358 alt_shortcut, create_all_shortcut); 219 alt_shortcut, create_all_shortcut);
359 if (ret) { 220 if (ret) {
360 ret = ShellUtil::CreateChromeQuickLaunchShortcut( 221 ret = ShellUtil::CreateChromeQuickLaunchShortcut(
361 product.distribution(), chrome_exe.value(), ShellUtil::CURRENT_USER, 222 product.distribution(), chrome_exe.value(), ShellUtil::CURRENT_USER,
362 create_all_shortcut); 223 create_all_shortcut);
363 } 224 }
364 } 225 }
365 } 226 }
366 227
367 return ret; 228 return ret;
368 } 229 }
369 230
370 231 void RegisterChromeOnMachine(const InstallerState& installer_state,
371 void RegisterChromeOnMachine(const Product& product, 232 const Product& product,
372 bool make_chrome_default) { 233 bool make_chrome_default) {
373 DCHECK(product.is_chrome()); 234 DCHECK(product.is_chrome());
374 235
375 // Try to add Chrome to Media Player shim inclusion list. We don't do any 236 // Try to add Chrome to Media Player shim inclusion list. We don't do any
376 // error checking here because this operation will fail if user doesn't 237 // error checking here because this operation will fail if user doesn't
377 // have admin rights and we want to ignore the error. 238 // have admin rights and we want to ignore the error.
378 AddChromeToMediaPlayerList(); 239 AddChromeToMediaPlayerList();
379 240
380 // Is --make-chrome-default option is given we make Chrome default browser 241 // Is --make-chrome-default option is given we make Chrome default browser
381 // otherwise we only register it on the machine as a valid browser. 242 // otherwise we only register it on the machine as a valid browser.
382 FilePath chrome_exe( 243 FilePath chrome_exe(
383 product.package().path().Append(installer::kChromeExe)); 244 installer_state.target_path().Append(installer::kChromeExe));
384 VLOG(1) << "Registering Chrome as browser: " << chrome_exe.value(); 245 VLOG(1) << "Registering Chrome as browser: " << chrome_exe.value();
385 if (make_chrome_default) { 246 if (make_chrome_default) {
386 int level = ShellUtil::CURRENT_USER; 247 int level = ShellUtil::CURRENT_USER;
387 if (product.system_level()) 248 if (installer_state.system_install())
388 level = level | ShellUtil::SYSTEM_LEVEL; 249 level = level | ShellUtil::SYSTEM_LEVEL;
389 ShellUtil::MakeChromeDefault(product.distribution(), level, 250 ShellUtil::MakeChromeDefault(product.distribution(), level,
390 chrome_exe.value(), true); 251 chrome_exe.value(), true);
391 } else { 252 } else {
392 ShellUtil::RegisterChromeBrowser(product.distribution(), chrome_exe.value(), 253 ShellUtil::RegisterChromeBrowser(product.distribution(), chrome_exe.value(),
393 L"", false); 254 L"", false);
394 } 255 }
395 } 256 }
396 257
397 // This function installs a new version of Chrome to the specified location. 258 // This function installs a new version of Chrome to the specified location.
(...skipping 12 matching lines...) Expand all
410 // This function makes best effort to do installation in a transactional 271 // This function makes best effort to do installation in a transactional
411 // manner. If failed it tries to rollback all changes on the file system 272 // manner. If failed it tries to rollback all changes on the file system
412 // and registry. For example, if package exists before calling the 273 // and registry. For example, if package exists before calling the
413 // function, it rolls back all new file and directory changes under 274 // function, it rolls back all new file and directory changes under
414 // package. If package does not exist before calling the function 275 // package. If package does not exist before calling the function
415 // (typical new install), the function creates package during install 276 // (typical new install), the function creates package during install
416 // and removes the whole directory during rollback. 277 // and removes the whole directory during rollback.
417 installer::InstallStatus InstallNewVersion( 278 installer::InstallStatus InstallNewVersion(
418 const InstallationState& original_state, 279 const InstallationState& original_state,
419 const InstallerState& installer_state, 280 const InstallerState& installer_state,
420 bool multi_install,
421 const FilePath& setup_path, 281 const FilePath& setup_path,
422 const FilePath& archive_path, 282 const FilePath& archive_path,
423 const FilePath& src_path, 283 const FilePath& src_path,
424 const FilePath& temp_dir, 284 const FilePath& temp_dir,
425 const Version& new_version, 285 const Version& new_version,
426 scoped_ptr<Version>* current_version, 286 scoped_ptr<Version>* current_version) {
427 const Package& package) {
428 DCHECK(current_version); 287 DCHECK(current_version);
429 288
430 current_version->reset(package.GetCurrentVersion()); 289 current_version->reset(installer_state.GetCurrentVersion(original_state));
431 scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList()); 290 scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList());
432 291
433 AddInstallWorkItems(original_state, 292 AddInstallWorkItems(original_state,
434 installer_state, 293 installer_state,
435 multi_install,
436 setup_path, 294 setup_path,
437 archive_path, 295 archive_path,
438 src_path, 296 src_path,
439 temp_dir, 297 temp_dir,
440 new_version, 298 new_version,
441 current_version, 299 current_version,
442 package,
443 install_list.get()); 300 install_list.get());
444 301
445 FilePath new_chrome_exe( 302 FilePath new_chrome_exe(
446 package.path().Append(installer::kChromeNewExe)); 303 installer_state.target_path().Append(installer::kChromeNewExe));
447 304
448 if (!install_list->Do()) { 305 if (!install_list->Do()) {
449 installer::InstallStatus result = 306 installer::InstallStatus result =
450 file_util::PathExists(new_chrome_exe) && current_version->get() && 307 file_util::PathExists(new_chrome_exe) && current_version->get() &&
451 new_version.Equals(*current_version->get()) ? 308 new_version.Equals(*current_version->get()) ?
452 installer::SAME_VERSION_REPAIR_FAILED : 309 installer::SAME_VERSION_REPAIR_FAILED :
453 installer::INSTALL_FAILED; 310 installer::INSTALL_FAILED;
454 LOG(ERROR) << "Install failed, rolling back... result: " << result; 311 LOG(ERROR) << "Install failed, rolling back... result: " << result;
455 install_list->Rollback(); 312 install_list->Rollback();
456 LOG(ERROR) << "Rollback complete. "; 313 LOG(ERROR) << "Rollback complete. ";
(...skipping 24 matching lines...) Expand all
481 << ", new version: " << new_version.GetString() 338 << ", new version: " << new_version.GetString()
482 << ", old version: " << (*current_version)->GetString(); 339 << ", old version: " << (*current_version)->GetString();
483 340
484 return installer::INSTALL_FAILED; 341 return installer::INSTALL_FAILED;
485 } 342 }
486 343
487 } // end namespace 344 } // end namespace
488 345
489 namespace installer { 346 namespace installer {
490 347
491 installer::InstallStatus InstallOrUpdateProduct( 348 InstallStatus InstallOrUpdateProduct(
492 const InstallationState& original_state, 349 const InstallationState& original_state,
493 const InstallerState& installer_state, 350 const InstallerState& installer_state,
494 const FilePath& setup_path, const FilePath& archive_path, 351 const FilePath& setup_path, const FilePath& archive_path,
495 const FilePath& install_temp_path, const FilePath& prefs_path, 352 const FilePath& install_temp_path, const FilePath& prefs_path,
496 const installer::MasterPreferences& prefs, const Version& new_version, 353 const MasterPreferences& prefs, const Version& new_version) {
robertshield 2011/01/20 22:06:06 could we put each of these parameters on a separat
grt (UTC plus 2) 2011/01/21 05:27:51 Done.
497 const Package& install) {
498 FilePath src_path(install_temp_path); 354 FilePath src_path(install_temp_path);
499 src_path = src_path.Append(kInstallSourceDir).Append(kInstallSourceChromeDir); 355 src_path = src_path.Append(kInstallSourceDir).Append(kInstallSourceChromeDir);
500 356
501 // TODO(robertshield): Removing the pending on-reboot moves should be done 357 // TODO(robertshield): Removing the pending on-reboot moves should be done
502 // elsewhere. 358 // elsewhere.
503 const Products& products = install.products(); 359 const Products& products = installer_state.products();
504 DCHECK(products.size()); 360 DCHECK(products.size());
505 if (FindProduct(products, BrowserDistribution::CHROME_FRAME)) { 361 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
506 // Make sure that we don't end up deleting installed files on next reboot. 362 // Make sure that we don't end up deleting installed files on next reboot.
507 if (!RemoveFromMovesPendingReboot(install.path().value().c_str())) { 363 if (!RemoveFromMovesPendingReboot(
364 installer_state.target_path().value().c_str())) {
508 LOG(ERROR) << "Error accessing pending moves value."; 365 LOG(ERROR) << "Error accessing pending moves value.";
509 } 366 }
510 } 367 }
511 368
512 scoped_ptr<Version> existing_version; 369 scoped_ptr<Version> existing_version;
513 installer::InstallStatus result = InstallNewVersion(original_state, 370 InstallStatus result = InstallNewVersion(original_state, installer_state,
514 installer_state, prefs.is_multi_install(), setup_path, archive_path, 371 setup_path, archive_path, src_path, install_temp_path, new_version,
515 src_path, install_temp_path, new_version, &existing_version, install); 372 &existing_version);
516 373
517 // TODO(robertshield): Everything below this line should instead be captured 374 // TODO(robertshield): Everything below this line should instead be captured
518 // by WorkItems. 375 // by WorkItems.
519 if (!InstallUtil::GetInstallReturnCode(result)) { 376 if (!InstallUtil::GetInstallReturnCode(result)) {
520 if (result == installer::FIRST_INSTALL_SUCCESS && !prefs_path.empty()) 377 if (result == FIRST_INSTALL_SUCCESS && !prefs_path.empty())
521 CopyPreferenceFileForFirstRun(install, prefs_path); 378 CopyPreferenceFileForFirstRun(installer_state, prefs_path);
522 379
523 bool do_not_create_shortcuts = false; 380 bool do_not_create_shortcuts = false;
524 prefs.GetBool(installer::master_preferences::kDoNotCreateShortcuts, 381 prefs.GetBool(master_preferences::kDoNotCreateShortcuts,
525 &do_not_create_shortcuts); 382 &do_not_create_shortcuts);
526 383
527 // Currently this only creates shortcuts for Chrome, but for other products 384 // Currently this only creates shortcuts for Chrome, but for other products
528 // we might want to create shortcuts. 385 // we might want to create shortcuts.
529 const Product* chrome_install = 386 const Product* chrome_install =
530 FindProduct(install.products(), BrowserDistribution::CHROME_BROWSER); 387 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER);
531 if (chrome_install && !do_not_create_shortcuts) { 388 if (chrome_install && !do_not_create_shortcuts) {
532 bool create_all_shortcut = false; 389 bool create_all_shortcut = false;
533 prefs.GetBool(installer::master_preferences::kCreateAllShortcuts, 390 prefs.GetBool(master_preferences::kCreateAllShortcuts,
534 &create_all_shortcut); 391 &create_all_shortcut);
535 bool alt_shortcut = false; 392 bool alt_shortcut = false;
536 prefs.GetBool(installer::master_preferences::kAltShortcutText, 393 prefs.GetBool(master_preferences::kAltShortcutText, &alt_shortcut);
537 &alt_shortcut); 394 if (!CreateOrUpdateChromeShortcuts(installer_state, setup_path,
538 if (!CreateOrUpdateChromeShortcuts(setup_path, new_version, result, 395 new_version, result, *chrome_install,
539 *chrome_install, create_all_shortcut, 396 create_all_shortcut, alt_shortcut)) {
540 alt_shortcut)) {
541 PLOG(WARNING) << "Failed to create/update start menu shortcut."; 397 PLOG(WARNING) << "Failed to create/update start menu shortcut.";
542 } 398 }
543 399
544 bool make_chrome_default = false; 400 bool make_chrome_default = false;
545 prefs.GetBool(installer::master_preferences::kMakeChromeDefault, 401 prefs.GetBool(master_preferences::kMakeChromeDefault,
546 &make_chrome_default); 402 &make_chrome_default);
547 403
548 // If this is not the user's first Chrome install, but they have chosen 404 // If this is not the user's first Chrome install, but they have chosen
549 // Chrome to become their default browser on the download page, we must 405 // Chrome to become their default browser on the download page, we must
550 // force it here because the master_preferences file will not get copied 406 // force it here because the master_preferences file will not get copied
551 // into the build. 407 // into the build.
552 bool force_chrome_default_for_user = false; 408 bool force_chrome_default_for_user = false;
553 if (result == installer::NEW_VERSION_UPDATED || 409 if (result == NEW_VERSION_UPDATED ||
554 result == installer::INSTALL_REPAIRED) { 410 result == INSTALL_REPAIRED) {
555 prefs.GetBool( 411 prefs.GetBool(master_preferences::kMakeChromeDefaultForUser,
556 installer::master_preferences::kMakeChromeDefaultForUser, 412 &force_chrome_default_for_user);
557 &force_chrome_default_for_user);
558 } 413 }
559 414
560 RegisterChromeOnMachine(*chrome_install, 415 RegisterChromeOnMachine(installer_state, *chrome_install,
561 make_chrome_default || force_chrome_default_for_user); 416 make_chrome_default || force_chrome_default_for_user);
562 } 417 }
563 418
564 install.RemoveOldVersionDirectories(existing_version.get() ? 419 installer_state.RemoveOldVersionDirectories(existing_version.get() ?
565 *existing_version.get() : new_version); 420 *existing_version.get() : new_version);
566 } 421 }
567 422
568 return result; 423 return result;
569 } 424 }
570 425
571 } // namespace installer 426 } // namespace installer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698