OLD | NEW |
---|---|
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/chrome_frame_ready_mode.h" | 5 #include "chrome/installer/setup/chrome_frame_ready_mode.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/ref_counted.h" | 10 #include "base/ref_counted.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/time.h" | 12 #include "base/time.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "base/win/registry.h" | 14 #include "base/win/registry.h" |
15 #include "chrome/installer/setup/install.h" | 15 #include "chrome/installer/setup/install.h" |
16 #include "chrome/installer/setup/install_worker.h" | 16 #include "chrome/installer/setup/install_worker.h" |
17 #include "chrome/installer/util/browser_distribution.h" | 17 #include "chrome/installer/util/browser_distribution.h" |
18 #include "chrome/installer/util/google_update_constants.h" | 18 #include "chrome/installer/util/google_update_constants.h" |
19 #include "chrome/installer/util/helper.h" | 19 #include "chrome/installer/util/helper.h" |
20 #include "chrome/installer/util/install_util.h" | 20 #include "chrome/installer/util/install_util.h" |
21 #include "chrome/installer/util/installation_state.h" | 21 #include "chrome/installer/util/installation_state.h" |
22 #include "chrome/installer/util/installer_state.h" | 22 #include "chrome/installer/util/installer_state.h" |
23 #include "chrome/installer/util/master_preferences.h" | 23 #include "chrome/installer/util/master_preferences.h" |
24 #include "chrome/installer/util/master_preferences_constants.h" | 24 #include "chrome/installer/util/master_preferences_constants.h" |
25 #include "chrome/installer/util/package.h" | |
26 #include "chrome/installer/util/package_properties.h" | |
27 #include "chrome/installer/util/product.h" | 25 #include "chrome/installer/util/product.h" |
28 #include "chrome/installer/util/util_constants.h" | 26 #include "chrome/installer/util/util_constants.h" |
29 #include "chrome/installer/util/work_item.h" | 27 #include "chrome/installer/util/work_item.h" |
30 #include "chrome/installer/util/work_item_list.h" | 28 #include "chrome/installer/util/work_item_list.h" |
31 | 29 |
32 namespace installer { | 30 namespace installer { |
33 | 31 |
34 InstallStatus ChromeFrameReadyModeOptIn(const InstallerState& installer_state, | 32 // If Chrome is not multi-installed at the appropriate level, error. |
35 const CommandLine& cmd_line) { | 33 // If Chrome Frame is already multi-installed at the appropriate level, noop. |
34 // If Chrome Frame is single-installed at the appropriate level, error. | |
35 // Add uninstall for Chrome Frame. | |
36 // Update uninstall for Chrome. | |
37 // Update ChannelInfo for all multi-installed products. | |
38 // Remove ready-mode. | |
39 InstallStatus ChromeFrameReadyModeOptIn( | |
40 const InstallationState& machine_state, | |
41 InstallerState* installer_state) { | |
36 VLOG(1) << "Opting into Chrome Frame"; | 42 VLOG(1) << "Opting into Chrome Frame"; |
37 InstallStatus status = INSTALL_REPAIRED; | 43 InstallStatus status = INSTALL_REPAIRED; |
38 | 44 |
39 const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); | 45 // Make sure Chrome and Chrome Frame are both multi-installed. |
40 bool system_install = false; | 46 const ProductState* chrome_state = |
41 prefs.GetBool(master_preferences::kSystemLevel, &system_install); | 47 machine_state.GetProductState(installer_state->system_install(), |
42 BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( | 48 BrowserDistribution::CHROME_BROWSER); |
43 BrowserDistribution::CHROME_FRAME, prefs); | 49 const ProductState* cf_state = |
44 DCHECK(cf->ShouldCreateUninstallEntry()) | 50 machine_state.GetProductState(installer_state->system_install(), |
45 << "Opting into CF should create an uninstall entry"; | 51 BrowserDistribution::CHROME_FRAME); |
46 BrowserDistribution* chrome = BrowserDistribution::GetSpecificDistribution( | 52 if (chrome_state == NULL) { |
47 BrowserDistribution::CHROME_BROWSER, prefs); | 53 LOG(ERROR) << "Chrome Frame opt-in requires multi-install of Chrome."; |
54 return CHROME_NOT_INSTALLED; | |
55 } | |
56 if (!chrome_state->multi_install()) { | |
57 LOG(ERROR) << "Chrome Frame opt-in requires multi-install of Chrome."; | |
58 return NON_MULTI_INSTALLATION_EXISTS; | |
59 } | |
60 if (cf_state == NULL) { | |
61 LOG(ERROR) << "Chrome Frame opt-in requires multi-install of Chrome Frame."; | |
62 return CHROME_NOT_INSTALLED; | |
63 } | |
64 if (!cf_state->multi_install()) { | |
65 LOG(ERROR) << "Chrome Frame opt-in requires multi-install of Chrome Frame."; | |
66 return NON_MULTI_INSTALLATION_EXISTS; | |
67 } | |
48 | 68 |
49 ActivePackageProperties package_properties; | 69 // Forget about anything product-related divined from the command line. |
70 installer_state->ResetProducts(); | |
robertshield
2011/01/20 22:06:06
Why not build a new installer_state here? Modifyin
grt (UTC plus 2)
2011/01/21 05:27:51
Done.
| |
50 | 71 |
51 // Remove ChromeFrameReadyMode, update Chrome's uninstallation commands to | 72 // Add the two products we're going to operate on. |
erikwright (departed)
2011/01/20 15:16:40
Consider using either reference or pointer for bot
grt (UTC plus 2)
2011/01/21 05:27:51
Done.
| |
52 // only uninstall Chrome, and add an entry to the Add/Remove Programs | 73 const Product& chrome = |
53 // dialog for GCF. | 74 *installer_state->AddProductFromState(BrowserDistribution::CHROME_BROWSER, |
75 *chrome_state); | |
76 Product* cf = | |
77 installer_state->AddProductFromState(BrowserDistribution::CHROME_FRAME, | |
78 *cf_state); | |
54 | 79 |
55 FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); | 80 // Turn off ready-mode on Chrome Frame, thereby making it fully installed. |
56 if (path.empty()) { | 81 if (!cf->SetOption(kOptionReadyMode, false)) |
erikwright (departed)
2011/01/20 15:16:40
Braces.
grt (UTC plus 2)
2011/01/21 05:27:51
Done.
| |
57 LOG(ERROR) << "Conflicting installations"; | 82 LOG(WARNING) |
58 status = NON_MULTI_INSTALLATION_EXISTS; | 83 << "Chrome Frame is already fully installed; opting-in nonetheless."; |
59 } else { | |
60 InstallationState original_state; | |
61 original_state.Initialize(prefs); | |
62 | 84 |
63 scoped_refptr<Package> package(new Package(prefs.is_multi_install(), | 85 // Update Chrome's uninstallation commands to only uninstall Chrome, and add |
64 system_install, path, &package_properties)); | 86 // an entry to the Add/Remove Programs dialog for GCF. |
65 scoped_refptr<Product> cf_product(new Product(cf, package)); | 87 DCHECK(cf->ShouldCreateUninstallEntry() || installer_state->msi()); |
66 DCHECK(cf_product->ShouldCreateUninstallEntry() || cf_product->IsMsi()); | |
67 scoped_refptr<Product> chrome_product(new Product(chrome, package)); | |
68 const ProductState* product_state = | |
69 original_state.GetProductState(system_install, cf->GetType()); | |
70 if (product_state == NULL) { | |
71 LOG(ERROR) << "No Chrome Frame installation found for opt-in."; | |
72 return CHROME_NOT_INSTALLED; | |
73 } | |
74 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); | |
75 | 88 |
76 // This creates the uninstallation entry for GCF. | 89 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); |
77 AddUninstallShortcutWorkItems(cmd_line.GetProgram(), | |
78 product_state->version(), item_list.get(), *cf_product.get()); | |
79 // This updates the Chrome uninstallation entries. | |
80 AddUninstallShortcutWorkItems(cmd_line.GetProgram(), | |
81 product_state->version(), item_list.get(), *chrome_product.get()); | |
82 | 90 |
83 // Add a work item to delete the ChromeFrameReadyMode registry value. | 91 // This creates the uninstallation entry for GCF. |
84 HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 92 AddUninstallShortcutWorkItems(*installer_state, cf_state->GetSetupPath(), |
85 item_list->AddDeleteRegValueWorkItem(root, package_properties.GetStateKey(), | 93 cf_state->version(), item_list.get(), *cf); |
86 kChromeFrameReadyModeField); | 94 // This updates the Chrome uninstallation entries. |
95 AddUninstallShortcutWorkItems(*installer_state, chrome_state->GetSetupPath(), | |
96 chrome_state->version(), item_list.get(), chrome); | |
87 | 97 |
88 // Delete the command elevation registry keys | 98 // Add a work item to delete the ChromeFrameReadyMode registry value. |
89 std::wstring version_key(cf->GetVersionKey()); | 99 HKEY root = installer_state->root_key(); |
90 item_list->AddDeleteRegValueWorkItem( | 100 item_list->AddDeleteRegValueWorkItem(root, |
91 root, version_key, google_update::kRegCFTempOptOutCmdField); | 101 installer_state->multi_package_binaries_distribution()->GetStateKey(), |
92 item_list->AddDeleteRegValueWorkItem( | 102 kChromeFrameReadyModeField); |
93 root, version_key, google_update::kRegCFEndTempOptOutCmdField); | |
94 item_list->AddDeleteRegValueWorkItem(root, version_key, | |
95 google_update::kRegCFOptOutCmdField); | |
96 item_list->AddDeleteRegValueWorkItem(root, version_key, | |
97 google_update::kRegCFOptInCmdField); | |
98 | 103 |
99 if (!item_list->Do()) { | 104 // Update the Google Update channel ("ap") value. |
100 LOG(ERROR) << "Failed to opt into GCF"; | 105 AddGoogleUpdateWorkItems(*installer_state, item_list.get()); |
101 item_list->Rollback(); | 106 |
102 status = READY_MODE_OPT_IN_FAILED; | 107 // Delete the command elevation registry keys |
103 } | 108 std::wstring version_key(cf->distribution()->GetVersionKey()); |
109 item_list->AddDeleteRegValueWorkItem( | |
110 root, version_key, google_update::kRegCFTempOptOutCmdField); | |
111 item_list->AddDeleteRegValueWorkItem( | |
112 root, version_key, google_update::kRegCFEndTempOptOutCmdField); | |
113 item_list->AddDeleteRegValueWorkItem(root, version_key, | |
114 google_update::kRegCFOptOutCmdField); | |
115 item_list->AddDeleteRegValueWorkItem(root, version_key, | |
116 google_update::kRegCFOptInCmdField); | |
117 | |
118 if (!item_list->Do()) { | |
119 LOG(ERROR) << "Failed to opt into GCF"; | |
120 item_list->Rollback(); | |
121 status = READY_MODE_OPT_IN_FAILED; | |
104 } | 122 } |
105 | 123 |
106 return status; | 124 return status; |
107 } | 125 } |
108 | 126 |
109 const wchar_t kPostPlatformUAKey[] = | 127 const wchar_t kPostPlatformUAKey[] = |
110 L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\" | 128 L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\" |
111 L"User Agent\\Post Platform"; | 129 L"User Agent\\Post Platform"; |
112 const wchar_t kChromeFramePrefix[] = L"chromeframe/"; | 130 const wchar_t kChromeFramePrefix[] = L"chromeframe/"; |
113 | 131 |
114 InstallStatus ChromeFrameReadyModeTempOptOut(const CommandLine& cmd_line) { | 132 InstallStatus ChromeFrameReadyModeTempOptOut( |
133 const InstallationState& machine_state, | |
134 const InstallerState& installer_state) { | |
115 VLOG(1) << "Temporarily opting out of Chrome Frame"; | 135 VLOG(1) << "Temporarily opting out of Chrome Frame"; |
116 InstallStatus status = INSTALL_REPAIRED; | 136 InstallStatus status = INSTALL_REPAIRED; |
117 | 137 |
118 const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); | 138 // Make sure Chrome Frame is multi-installed. |
119 bool system_install = false; | 139 const ProductState* cf_state = |
120 prefs.GetBool(master_preferences::kSystemLevel, &system_install); | 140 machine_state.GetProductState(installer_state.system_install(), |
121 BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( | 141 BrowserDistribution::CHROME_FRAME); |
122 BrowserDistribution::CHROME_FRAME, prefs); | 142 if (cf_state == NULL) { |
143 LOG(ERROR) | |
144 << "Chrome Frame temp opt-out requires multi-install of Chrome Frame."; | |
145 return CHROME_NOT_INSTALLED; | |
146 } | |
147 if (!cf_state->multi_install()) { | |
148 LOG(ERROR) | |
149 << "Chrome Frame temp opt-out requires multi-install of Chrome Frame."; | |
150 return NON_MULTI_INSTALLATION_EXISTS; | |
151 } | |
123 | 152 |
124 installer::ActivePackageProperties package_properties; | 153 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); |
125 | 154 |
126 // Remove the ChromeFrame user agent string from the registry, modify the | 155 HKEY root = installer_state.root_key(); |
127 // ReadyMode state flag. | |
128 FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); | |
129 if (path.empty()) { | |
130 LOG(ERROR) << "Conflicting installations"; | |
131 status = NON_MULTI_INSTALLATION_EXISTS; | |
132 } else { | |
133 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); | |
134 | 156 |
135 HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 157 // Add a work item to delete the ChromeFrame user agent registry value. |
158 base::win::RegistryValueIterator values(root, kPostPlatformUAKey); | |
159 while (values.Valid()) { | |
160 const wchar_t* name = values.Name(); | |
161 if (StartsWith(name, kChromeFramePrefix, true)) { | |
162 item_list->AddDeleteRegValueWorkItem(root, kPostPlatformUAKey, name); | |
163 } | |
164 ++values; | |
165 } | |
136 | 166 |
137 // Add a work item to delete the ChromeFrame user agent registry value. | 167 // Add a work item to update the Ready Mode state flag |
138 base::win::RegistryValueIterator values(root, kPostPlatformUAKey); | 168 int64 timestamp = base::Time::Now().ToInternalValue(); |
139 while (values.Valid()) { | 169 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( |
140 const wchar_t* name = values.Name(); | 170 BrowserDistribution::CHROME_BINARIES); |
141 if (StartsWith(name, kChromeFramePrefix, true)) { | 171 item_list->AddSetRegValueWorkItem(root, dist->GetStateKey(), |
142 item_list->AddDeleteRegValueWorkItem(root, kPostPlatformUAKey, name); | 172 kChromeFrameReadyModeField, timestamp, |
143 } | 173 true); |
144 ++values; | |
145 } | |
146 | 174 |
147 // Add a work item to update the Ready Mode state flag | 175 if (!item_list->Do()) { |
148 int64 timestamp = base::Time::Now().ToInternalValue(); | 176 LOG(ERROR) << "Failed to temporarily opt out of GCF"; |
149 item_list->AddSetRegValueWorkItem(root, package_properties.GetStateKey(), | 177 item_list->Rollback(); |
150 kChromeFrameReadyModeField, timestamp, | 178 status = READY_MODE_TEMP_OPT_OUT_FAILED; |
151 true); | |
152 | |
153 if (!item_list->Do()) { | |
154 LOG(ERROR) << "Failed to temporarily opt out of GCF"; | |
155 item_list->Rollback(); | |
156 status = READY_MODE_TEMP_OPT_OUT_FAILED; | |
157 } | |
158 } | 179 } |
159 | 180 |
160 return status; | 181 return status; |
161 } | 182 } |
162 | 183 |
163 InstallStatus ChromeFrameReadyModeEndTempOptOut(const CommandLine& cmd_line) { | 184 InstallStatus ChromeFrameReadyModeEndTempOptOut( |
185 const InstallationState& machine_state, | |
186 const InstallerState& installer_state) { | |
164 VLOG(1) << "Ending temporary opt-out of Chrome Frame"; | 187 VLOG(1) << "Ending temporary opt-out of Chrome Frame"; |
165 InstallStatus status = INSTALL_REPAIRED; | 188 InstallStatus status = INSTALL_REPAIRED; |
166 | 189 |
167 const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); | 190 // Make sure Chrome Frame is multi-installed. |
168 bool system_install = false; | 191 const ProductState* cf_state = |
169 prefs.GetBool(master_preferences::kSystemLevel, &system_install); | 192 machine_state.GetProductState(installer_state.system_install(), |
170 BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( | 193 BrowserDistribution::CHROME_FRAME); |
171 BrowserDistribution::CHROME_FRAME, prefs); | 194 if (cf_state == NULL) { |
172 | 195 LOG(ERROR) |
173 installer::ActivePackageProperties package_properties; | 196 << "Chrome Frame temp opt-out requires multi-install of Chrome Frame."; |
197 return CHROME_NOT_INSTALLED; | |
198 } | |
199 if (!cf_state->multi_install()) { | |
200 LOG(ERROR) | |
201 << "Chrome Frame temp opt-out requires multi-install of Chrome Frame."; | |
202 return NON_MULTI_INSTALLATION_EXISTS; | |
203 } | |
174 | 204 |
175 // Replace the ChromeFrame user agent string in the registry, modify the | 205 // Replace the ChromeFrame user agent string in the registry, modify the |
176 // ReadyMode state flag. | 206 // ReadyMode state flag. |
177 FilePath path(GetChromeFrameInstallPath(true, system_install, cf)); | 207 const Version& installed_version = cf_state->version(); |
178 scoped_ptr<Version> installed_version( | |
179 InstallUtil::GetChromeVersion(cf, system_install)); | |
180 | 208 |
181 if (path.empty()) { | 209 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); |
182 LOG(ERROR) << "Conflicting installations"; | 210 |
183 status = NON_MULTI_INSTALLATION_EXISTS; | 211 HKEY root = installer_state.root_key(); |
184 } else if (installed_version == NULL) { | 212 |
185 LOG(ERROR) << "Failed to query installed version of Chrome Frame"; | 213 std::wstring chrome_frame_ua_value_name = kChromeFramePrefix; |
214 chrome_frame_ua_value_name += ASCIIToWide(installed_version.GetString()); | |
215 | |
216 // Store the Chrome Frame user agent string | |
217 item_list->AddSetRegValueWorkItem(root, kPostPlatformUAKey, | |
218 chrome_frame_ua_value_name, L"", true); | |
219 // Add a work item to update the Ready Mode state flag | |
220 BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( | |
221 BrowserDistribution::CHROME_BINARIES); | |
222 item_list->AddSetRegValueWorkItem(root, dist->GetStateKey(), | |
223 kChromeFrameReadyModeField, | |
224 static_cast<int64>(1), true); | |
225 | |
226 if (!item_list->Do()) { | |
227 LOG(ERROR) << "Failed to end temporary opt out of GCF"; | |
228 item_list->Rollback(); | |
186 status = READY_MODE_END_TEMP_OPT_OUT_FAILED; | 229 status = READY_MODE_END_TEMP_OPT_OUT_FAILED; |
187 } else { | |
188 scoped_ptr<WorkItemList> item_list(WorkItem::CreateWorkItemList()); | |
189 | |
190 HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
191 | |
192 std::wstring chrome_frame_ua_value_name = kChromeFramePrefix; | |
193 chrome_frame_ua_value_name += ASCIIToWide(installed_version->GetString()); | |
194 | |
195 // Store the Chrome Frame user agent string | |
196 item_list->AddSetRegValueWorkItem(root, kPostPlatformUAKey, | |
197 chrome_frame_ua_value_name, L"", true); | |
198 // Add a work item to update the Ready Mode state flag | |
199 item_list->AddSetRegValueWorkItem(root, package_properties.GetStateKey(), | |
200 kChromeFrameReadyModeField, | |
201 static_cast<int64>(1), true); | |
202 | |
203 if (!item_list->Do()) { | |
204 LOG(ERROR) << "Failed to end temporary opt out of GCF"; | |
205 item_list->Rollback(); | |
206 status = READY_MODE_END_TEMP_OPT_OUT_FAILED; | |
207 } | |
208 } | 230 } |
209 | 231 |
210 return status; | 232 return status; |
211 } | 233 } |
212 | 234 |
213 } // namespace installer | 235 } // namespace installer |
OLD | NEW |