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

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

Issue 10826144: Delete both regular and Metro user data dirs on uninstall. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: factored in gab's comments Created 8 years, 4 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
« no previous file with comments | « no previous file | chrome/installer/util/auto_launch_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 if (!parent_dir.empty() && file_util::IsDirectoryEmpty(parent_dir)) { 332 if (!parent_dir.empty() && file_util::IsDirectoryEmpty(parent_dir)) {
333 if (!file_util::Delete(parent_dir, true)) { 333 if (!file_util::Delete(parent_dir, true)) {
334 ret = false; 334 ret = false;
335 LOG(ERROR) << "Failed to delete folder: " << parent_dir.value(); 335 LOG(ERROR) << "Failed to delete folder: " << parent_dir.value();
336 } 336 }
337 } 337 }
338 } 338 }
339 return ret; 339 return ret;
340 } 340 }
341 341
342 FilePath GetLocalStateFolder(const Product& product) { 342 void GetLocalStateFolders(const Product& product,
343 std::vector<FilePath>* paths) {
343 // Obtain the location of the user profile data. 344 // Obtain the location of the user profile data.
344 FilePath local_state_folder = product.GetUserDataPath(); 345 product.GetUserDataPaths(paths);
345 LOG_IF(ERROR, local_state_folder.empty()) 346 LOG_IF(ERROR, paths->empty())
346 << "Could not retrieve user's profile directory."; 347 << "Could not retrieve user's profile directory.";
347
348 return local_state_folder;
349 } 348 }
350 349
351 // Creates a copy of the local state file and returns a path to the copy. 350 // Creates a copy of the local state file and returns a path to the copy.
352 FilePath BackupLocalStateFile(const FilePath& local_state_folder) { 351 FilePath BackupLocalStateFile(
352 const std::vector<FilePath>& local_state_folders) {
353 FilePath backup; 353 FilePath backup;
354 FilePath state_file(local_state_folder.Append(chrome::kLocalStateFilename)); 354
355 if (!file_util::CreateTemporaryFile(&backup)) { 355 // Copy the first local state file that is found.
356 LOG(ERROR) << "Failed to create temporary file for Local State."; 356 for (size_t i = 0; i < local_state_folders.size(); ++i) {
357 } else { 357 const FilePath& local_state_folder = local_state_folders[i];
358 file_util::CopyFile(state_file, backup); 358 FilePath state_file(local_state_folder.Append(chrome::kLocalStateFilename));
359 if (!file_util::PathExists(state_file))
360 continue;
361 if (!file_util::CreateTemporaryFile(&backup))
362 LOG(ERROR) << "Failed to create temporary file for Local State.";
363 else
364 file_util::CopyFile(state_file, backup);
365 break;
359 } 366 }
360 return backup; 367 return backup;
361 } 368 }
362 369
363 enum DeleteResult { 370 enum DeleteResult {
364 DELETE_SUCCEEDED, 371 DELETE_SUCCEEDED,
365 DELETE_FAILED, 372 DELETE_FAILED,
366 DELETE_REQUIRES_REBOOT, 373 DELETE_REQUIRES_REBOOT,
367 }; 374 };
368 375
369 // Copies the local state to the temp folder and then deletes it. 376 // Deletes all user data directories for a product.
370 // The path to the copy is returned via the local_state_copy parameter. 377 DeleteResult DeleteLocalState(const std::vector<FilePath>& local_state_folders,
371 DeleteResult DeleteLocalState(const Product& product) { 378 bool schedule_on_failure) {
372 FilePath user_local_state(GetLocalStateFolder(product)); 379 if (local_state_folders.empty())
373 if (user_local_state.empty())
374 return DELETE_SUCCEEDED; 380 return DELETE_SUCCEEDED;
375 381
376 DeleteResult result = DELETE_SUCCEEDED; 382 DeleteResult result = DELETE_SUCCEEDED;
377 VLOG(1) << "Deleting user profile " << user_local_state.value(); 383 for (size_t i = 0; i < local_state_folders.size(); ++i) {
378 if (!file_util::Delete(user_local_state, true)) { 384 const FilePath& user_local_state = local_state_folders[i];
379 LOG(ERROR) << "Failed to delete user profile dir: " 385 VLOG(1) << "Deleting user profile " << user_local_state.value();
380 << user_local_state.value(); 386 if (!file_util::Delete(user_local_state, true)) {
381 if (product.is_chrome_frame()) { 387 LOG(ERROR) << "Failed to delete user profile dir: "
382 ScheduleDirectoryForDeletion(user_local_state.value().c_str()); 388 << user_local_state.value();
383 result = DELETE_REQUIRES_REBOOT; 389 if (schedule_on_failure) {
384 } else { 390 ScheduleDirectoryForDeletion(user_local_state.value().c_str());
385 result = DELETE_FAILED; 391 result = DELETE_REQUIRES_REBOOT;
392 } else {
393 result = DELETE_FAILED;
394 }
386 } 395 }
387 } 396 }
388 397
389 if (result == DELETE_REQUIRES_REBOOT) { 398 if (result == DELETE_REQUIRES_REBOOT) {
390 ScheduleParentAndGrandparentForDeletion(user_local_state); 399 ScheduleParentAndGrandparentForDeletion(local_state_folders[0]);
391 } else { 400 } else {
392 DeleteEmptyParentDir(user_local_state); 401 DeleteEmptyParentDir(local_state_folders[0]);
393 } 402 }
394 403
395 return result; 404 return result;
396 } 405 }
397 406
398 bool MoveSetupOutOfInstallFolder(const InstallerState& installer_state, 407 bool MoveSetupOutOfInstallFolder(const InstallerState& installer_state,
399 const FilePath& setup_path, 408 const FilePath& setup_path,
400 const Version& installed_version) { 409 const Version& installed_version) {
401 bool ret = false; 410 bool ret = false;
402 FilePath setup_exe(installer_state.GetInstallerDirectory(installed_version) 411 FilePath setup_exe(installer_state.GetInstallerDirectory(installed_version)
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 1103
1095 // Finally delete all the files from Chrome folder after moving setup.exe 1104 // Finally delete all the files from Chrome folder after moving setup.exe
1096 // and the user's Local State to a temp location. 1105 // and the user's Local State to a temp location.
1097 bool delete_profile = ShouldDeleteProfile(installer_state, cmd_line, status, 1106 bool delete_profile = ShouldDeleteProfile(installer_state, cmd_line, status,
1098 product); 1107 product);
1099 ret = installer::UNINSTALL_SUCCESSFUL; 1108 ret = installer::UNINSTALL_SUCCESSFUL;
1100 1109
1101 // When deleting files, we must make sure that we're either a "single" 1110 // When deleting files, we must make sure that we're either a "single"
1102 // (aka non-multi) installation or we are the Chrome Binaries. 1111 // (aka non-multi) installation or we are the Chrome Binaries.
1103 1112
1104 FilePath backup_state_file( 1113 std::vector<FilePath> local_state_folders;
1105 BackupLocalStateFile(GetLocalStateFolder(product))); 1114 GetLocalStateFolders(product, &local_state_folders);
1115 FilePath backup_state_file(BackupLocalStateFile(local_state_folders));
1106 1116
1107 DeleteResult delete_result = DELETE_SUCCEEDED; 1117 DeleteResult delete_result = DELETE_SUCCEEDED;
1108 1118
1109 if (product.is_chrome_app_host()) { 1119 if (product.is_chrome_app_host()) {
1110 DeleteAppHostFilesAndFolders(installer_state, product_state->version()); 1120 DeleteAppHostFilesAndFolders(installer_state, product_state->version());
1111 } else if (!installer_state.is_multi_install() || 1121 } else if (!installer_state.is_multi_install() ||
1112 product.is_chrome_binaries()) { 1122 product.is_chrome_binaries()) {
1113 1123
1114 // In order to be able to remove the folder in which we're running, we 1124 // In order to be able to remove the folder in which we're running, we
1115 // need to move setup.exe out of the install folder. 1125 // need to move setup.exe out of the install folder.
1116 // TODO(tommi): What if the temp folder is on a different volume? 1126 // TODO(tommi): What if the temp folder is on a different volume?
1117 MoveSetupOutOfInstallFolder(installer_state, setup_path, 1127 MoveSetupOutOfInstallFolder(installer_state, setup_path,
1118 product_state->version()); 1128 product_state->version());
1119 delete_result = DeleteChromeFilesAndFolders(installer_state, 1129 delete_result = DeleteChromeFilesAndFolders(installer_state,
1120 product_state->version()); 1130 product_state->version());
1121 } 1131 }
1122 1132
1123 if (delete_profile) 1133 if (delete_profile)
1124 DeleteLocalState(product); 1134 DeleteLocalState(local_state_folders, product.is_chrome_frame());
1125 1135
1126 if (delete_result == DELETE_FAILED) { 1136 if (delete_result == DELETE_FAILED) {
1127 ret = installer::UNINSTALL_FAILED; 1137 ret = installer::UNINSTALL_FAILED;
1128 } else if (delete_result == DELETE_REQUIRES_REBOOT) { 1138 } else if (delete_result == DELETE_REQUIRES_REBOOT) {
1129 ret = installer::UNINSTALL_REQUIRES_REBOOT; 1139 ret = installer::UNINSTALL_REQUIRES_REBOOT;
1130 } 1140 }
1131 1141
1132 if (!force_uninstall) { 1142 if (!force_uninstall) {
1133 VLOG(1) << "Uninstallation complete. Launching post-uninstall operations."; 1143 VLOG(1) << "Uninstallation complete. Launching post-uninstall operations.";
1134 browser_dist->DoPostUninstallOperations(product_state->version(), 1144 browser_dist->DoPostUninstallOperations(product_state->version(),
1135 backup_state_file, distribution_data); 1145 backup_state_file, distribution_data);
1136 } 1146 }
1137 1147
1138 // Try and delete the preserved local state once the post-install 1148 // Try and delete the preserved local state once the post-install
1139 // operations are complete. 1149 // operations are complete.
1140 if (!backup_state_file.empty()) 1150 if (!backup_state_file.empty())
1141 file_util::Delete(backup_state_file, false); 1151 file_util::Delete(backup_state_file, false);
1142 1152
1143 return ret; 1153 return ret;
1144 } 1154 }
1145 1155
1146 } // namespace installer 1156 } // namespace installer
OLDNEW
« no previous file with comments | « no previous file | chrome/installer/util/auto_launch_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698