OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file defines the methods useful for uninstalling Chrome. | 5 // This file defines the methods useful for uninstalling Chrome. |
6 | 6 |
7 #include "chrome/installer/setup/uninstall.h" | 7 #include "chrome/installer/setup/uninstall.h" |
8 | 8 |
9 #include <windows.h> | 9 #include <windows.h> |
10 | 10 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 bool* remove_setup, | 208 bool* remove_setup, |
209 bool* remove_archive) { | 209 bool* remove_archive) { |
210 *remove_setup = true; | 210 *remove_setup = true; |
211 *remove_archive = true; | 211 *remove_archive = true; |
212 | 212 |
213 // If any multi-install product is left (other than App Host) we must leave | 213 // If any multi-install product is left (other than App Host) we must leave |
214 // the installer and archive. For the App Host, we only leave the installer. | 214 // the installer and archive. For the App Host, we only leave the installer. |
215 if (!installer_state.is_multi_install()) { | 215 if (!installer_state.is_multi_install()) { |
216 VLOG(1) << "Removing all installer files for a non-multi installation."; | 216 VLOG(1) << "Removing all installer files for a non-multi installation."; |
217 } else { | 217 } else { |
| 218 // Loop through all known products... |
218 for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { | 219 for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { |
219 BrowserDistribution::Type dist_type = | 220 BrowserDistribution::Type dist_type = |
220 static_cast<BrowserDistribution::Type>(i); | 221 static_cast<BrowserDistribution::Type>(i); |
221 const installer::ProductState* product_state = | 222 const installer::ProductState* product_state = |
222 original_state.GetProductState( | 223 original_state.GetProductState( |
223 installer_state.system_install(), dist_type); | 224 installer_state.system_install(), dist_type); |
| 225 // If the product is installed, in multi mode, and is not part of the |
| 226 // active uninstallation... |
224 if (product_state && product_state->is_multi_install() && | 227 if (product_state && product_state->is_multi_install() && |
225 !installer_state.FindProduct(dist_type)) { | 228 !installer_state.FindProduct(dist_type)) { |
226 // setup.exe will not be removed as there is a remaining multi-install | 229 // setup.exe will not be removed as there is a remaining multi-install |
227 // product. | 230 // product. |
228 *remove_setup = false; | 231 *remove_setup = false; |
229 // As a special case, we can still remove the actual archive if the | 232 // As a special case, we can still remove the actual archive if the |
230 // only remaining product is the App Host. | 233 // only remaining product is the App Host. |
231 if (dist_type != BrowserDistribution::CHROME_APP_HOST) { | 234 if (dist_type != BrowserDistribution::CHROME_APP_HOST) { |
232 VLOG(1) << "Keeping all installer files due to a remaining " | 235 VLOG(1) << "Keeping all installer files due to a remaining " |
233 << "multi-install product."; | 236 << "multi-install product."; |
234 *remove_archive = false; | 237 *remove_archive = false; |
235 return; | 238 return; |
236 } | 239 } |
237 VLOG(1) << "Keeping setup.exe due to a remaining " | 240 VLOG(1) << "Keeping setup.exe due to a remaining " |
238 << "app-host installation."; | 241 << "app-host installation."; |
239 } | 242 } |
240 } | 243 } |
241 VLOG(1) << "Removing the installer archive."; | 244 VLOG(1) << "Removing the installer archive."; |
242 if (remove_setup) | 245 if (remove_setup) |
243 VLOG(1) << "Removing setup.exe."; | 246 VLOG(1) << "Removing setup.exe."; |
244 } | 247 } |
245 } | 248 } |
246 | 249 |
247 // Removes all files from the installer directory, leaving setup.exe iff | 250 // Removes all files from the installer directory, leaving setup.exe iff |
248 // |remove_setup| is false. | 251 // |remove_setup| is false. |
249 // Returns false in case of an error. | 252 // Returns false in case of an error. |
250 bool RemoveInstallerFiles(const FilePath& install_directory, | 253 bool RemoveInstallerFiles(const FilePath& installer_directory, |
251 bool remove_setup) { | 254 bool remove_setup) { |
252 using file_util::FileEnumerator; | 255 using file_util::FileEnumerator; |
253 FileEnumerator file_enumerator( | 256 FileEnumerator file_enumerator( |
254 install_directory, | 257 installer_directory, |
255 false, | 258 false, |
256 FileEnumerator::FILES | FileEnumerator::DIRECTORIES); | 259 FileEnumerator::FILES | FileEnumerator::DIRECTORIES); |
257 bool success = true; | 260 bool success = true; |
258 | 261 |
259 FilePath setup_exe_base_name(installer::kSetupExe); | 262 FilePath setup_exe_base_name(installer::kSetupExe); |
260 | 263 |
261 while (true) { | 264 while (true) { |
262 FilePath to_delete(file_enumerator.Next()); | 265 FilePath to_delete(file_enumerator.Next()); |
263 if (to_delete.empty()) | 266 if (to_delete.empty()) |
264 break; | 267 break; |
265 if (!remove_setup && to_delete.BaseName() == setup_exe_base_name) | 268 if (!remove_setup && to_delete.BaseName() == setup_exe_base_name) |
266 continue; | 269 continue; |
267 | 270 |
268 VLOG(1) << "Deleting install path " << to_delete.value(); | 271 VLOG(1) << "Deleting installer path " << to_delete.value(); |
269 if (!file_util::Delete(to_delete, true)) { | 272 if (!file_util::Delete(to_delete, true)) { |
270 LOG(ERROR) << "Failed to delete path: " << to_delete.value(); | 273 LOG(ERROR) << "Failed to delete path: " << to_delete.value(); |
271 success = false; | 274 success = false; |
272 } | 275 } |
273 } | 276 } |
274 | 277 |
275 return success; | 278 return success; |
276 } | 279 } |
277 | 280 |
278 } // namespace | 281 } // namespace |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 FilePath app_host_exe(target_path.Append(installer::kChromeAppHostExe)); | 537 FilePath app_host_exe(target_path.Append(installer::kChromeAppHostExe)); |
535 if (!file_util::Delete(app_host_exe, false)) { | 538 if (!file_util::Delete(app_host_exe, false)) { |
536 result = DELETE_FAILED; | 539 result = DELETE_FAILED; |
537 LOG(ERROR) << "Failed to delete path: " << app_host_exe.value(); | 540 LOG(ERROR) << "Failed to delete path: " << app_host_exe.value(); |
538 } | 541 } |
539 | 542 |
540 return result; | 543 return result; |
541 } | 544 } |
542 | 545 |
543 DeleteResult DeleteChromeFilesAndFolders(const InstallerState& installer_state, | 546 DeleteResult DeleteChromeFilesAndFolders(const InstallerState& installer_state, |
544 const FilePath& installer_path) { | 547 const FilePath& setup_exe) { |
545 const FilePath& target_path = installer_state.target_path(); | 548 const FilePath& target_path = installer_state.target_path(); |
546 if (target_path.empty()) { | 549 if (target_path.empty()) { |
547 LOG(ERROR) << "DeleteChromeFilesAndFolders: no installation destination " | 550 LOG(ERROR) << "DeleteChromeFilesAndFolders: no installation destination " |
548 << "path."; | 551 << "path."; |
549 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. | 552 return DELETE_FAILED; // Nothing else we can do to uninstall, so we return. |
550 } | 553 } |
551 | 554 |
552 DeleteInstallTempDir(target_path); | 555 DeleteInstallTempDir(target_path); |
553 | 556 |
554 DeleteResult result = DELETE_SUCCEEDED; | 557 DeleteResult result = DELETE_SUCCEEDED; |
555 | 558 |
556 FilePath installer_directory; | 559 FilePath installer_directory; |
557 if (target_path.IsParent(installer_path)) | 560 if (target_path.IsParent(setup_exe)) |
558 installer_directory = installer_path.DirName(); | 561 installer_directory = setup_exe.DirName(); |
559 | 562 |
560 // Enumerate all the files in target_path recursively (breadth-first). | 563 // Enumerate all the files in target_path recursively (breadth-first). |
561 // We delete a file or folder unless it is a parent/child of the installer | 564 // We delete a file or folder unless it is a parent/child of the installer |
562 // directory. For parents of the installer directory, we will later recurse | 565 // directory. For parents of the installer directory, we will later recurse |
563 // and delete all the children (that are not also parents/children of the | 566 // and delete all the children (that are not also parents/children of the |
564 // installer directory). | 567 // installer directory). |
565 using file_util::FileEnumerator; | 568 using file_util::FileEnumerator; |
566 FileEnumerator file_enumerator( | 569 FileEnumerator file_enumerator( |
567 target_path, true, FileEnumerator::FILES | FileEnumerator::DIRECTORIES); | 570 target_path, true, FileEnumerator::FILES | FileEnumerator::DIRECTORIES); |
568 while (true) { | 571 while (true) { |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 // (aka non-multi) installation or we are the Chrome Binaries. | 1300 // (aka non-multi) installation or we are the Chrome Binaries. |
1298 | 1301 |
1299 std::vector<FilePath> local_state_folders; | 1302 std::vector<FilePath> local_state_folders; |
1300 GetLocalStateFolders(product, &local_state_folders); | 1303 GetLocalStateFolders(product, &local_state_folders); |
1301 FilePath backup_state_file(BackupLocalStateFile(local_state_folders)); | 1304 FilePath backup_state_file(BackupLocalStateFile(local_state_folders)); |
1302 | 1305 |
1303 if (product.is_chrome_app_host()) { | 1306 if (product.is_chrome_app_host()) { |
1304 DeleteAppHostFilesAndFolders(installer_state, product_state->version()); | 1307 DeleteAppHostFilesAndFolders(installer_state, product_state->version()); |
1305 } else if (!installer_state.is_multi_install() || | 1308 } else if (!installer_state.is_multi_install() || |
1306 product.is_chrome_binaries()) { | 1309 product.is_chrome_binaries()) { |
| 1310 FilePath setup_exe(cmd_line.GetProgram()); |
| 1311 file_util::AbsolutePath(&setup_exe); |
1307 DeleteResult delete_result = DeleteChromeFilesAndFolders( | 1312 DeleteResult delete_result = DeleteChromeFilesAndFolders( |
1308 installer_state, cmd_line.GetProgram()); | 1313 installer_state, setup_exe); |
1309 if (delete_result == DELETE_FAILED) { | 1314 if (delete_result == DELETE_FAILED) { |
1310 ret = installer::UNINSTALL_FAILED; | 1315 ret = installer::UNINSTALL_FAILED; |
1311 } else if (delete_result == DELETE_REQUIRES_REBOOT) { | 1316 } else if (delete_result == DELETE_REQUIRES_REBOOT) { |
1312 ret = installer::UNINSTALL_REQUIRES_REBOOT; | 1317 ret = installer::UNINSTALL_REQUIRES_REBOOT; |
1313 } | 1318 } |
1314 } | 1319 } |
1315 | 1320 |
1316 if (delete_profile) | 1321 if (delete_profile) |
1317 DeleteLocalState(local_state_folders, product.is_chrome_frame()); | 1322 DeleteLocalState(local_state_folders, product.is_chrome_frame()); |
1318 | 1323 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 // deletion unconditionally. If they are not empty, the session manager | 1414 // deletion unconditionally. If they are not empty, the session manager |
1410 // will not delete them on reboot. | 1415 // will not delete them on reboot. |
1411 ScheduleParentAndGrandparentForDeletion(target_path); | 1416 ScheduleParentAndGrandparentForDeletion(target_path); |
1412 } else if (DeleteApplicationProductAndVendorDirectories(target_path) == | 1417 } else if (DeleteApplicationProductAndVendorDirectories(target_path) == |
1413 installer::DELETE_FAILED) { | 1418 installer::DELETE_FAILED) { |
1414 *uninstall_status = installer::UNINSTALL_FAILED; | 1419 *uninstall_status = installer::UNINSTALL_FAILED; |
1415 } | 1420 } |
1416 } | 1421 } |
1417 | 1422 |
1418 } // namespace installer | 1423 } // namespace installer |
OLD | NEW |