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

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

Issue 10832210: Delete the installation folder after deleting its contents. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review 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 | no next file » | 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 FilePath grandparent_dir(parent_dir.DirName()); 311 FilePath grandparent_dir(parent_dir.DirName());
312 ret = ScheduleFileSystemEntityForDeletion(grandparent_dir.value().c_str()); 312 ret = ScheduleFileSystemEntityForDeletion(grandparent_dir.value().c_str());
313 if (!ret) { 313 if (!ret) {
314 LOG(ERROR) << "Failed to schedule grandparent dir for deletion: " 314 LOG(ERROR) << "Failed to schedule grandparent dir for deletion: "
315 << grandparent_dir.value(); 315 << grandparent_dir.value();
316 } 316 }
317 } 317 }
318 return ret; 318 return ret;
319 } 319 }
320 320
321 // Deletes empty parent & empty grandparent dir of given path. 321 // Deletes the given directory if it is empty. Returns true if the directory is
322 bool DeleteEmptyParentDir(const FilePath& path) { 322 // deleted. *error is set to true iff the attempt to delete the file fails.
323 bool ret = true; 323 bool DeleteEmptyDir(const FilePath& path, bool* error) {
gab 2012/08/09 16:07:22 I'm not a fan of the bool return and bool* error p
erikwright (departed) 2012/08/13 14:53:22 Done.
324 FilePath parent_dir = path.DirName(); 324 *error = false;
325 if (!parent_dir.empty() && file_util::IsDirectoryEmpty(parent_dir)) {
326 if (!file_util::Delete(parent_dir, true)) {
327 ret = false;
328 LOG(ERROR) << "Failed to delete folder: " << parent_dir.value();
329 }
330 325
331 parent_dir = parent_dir.DirName(); 326 if (path.empty())
332 if (!parent_dir.empty() && file_util::IsDirectoryEmpty(parent_dir)) { 327 return false;
333 if (!file_util::Delete(parent_dir, true)) { 328
334 ret = false; 329 if (!file_util::IsDirectoryEmpty(path))
gab 2012/08/09 16:07:22 Group this condition with path.empty() above since
erikwright (departed) 2012/08/13 14:53:22 N/A.
335 LOG(ERROR) << "Failed to delete folder: " << parent_dir.value(); 330 return false;
336 } 331
337 } 332 if (file_util::Delete(path, true))
338 } 333 return true;
339 return ret; 334
335 *error = true;
336 LOG(ERROR) << "Failed to delete folder: " << path.value();
337 return false;
340 } 338 }
341 339
342 void GetLocalStateFolders(const Product& product, 340 void GetLocalStateFolders(const Product& product,
343 std::vector<FilePath>* paths) { 341 std::vector<FilePath>* paths) {
344 // Obtain the location of the user profile data. 342 // Obtain the location of the user profile data.
345 product.GetUserDataPaths(paths); 343 product.GetUserDataPaths(paths);
346 LOG_IF(ERROR, paths->empty()) 344 LOG_IF(ERROR, paths->empty())
347 << "Could not retrieve user's profile directory."; 345 << "Could not retrieve user's profile directory.";
348 } 346 }
349 347
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 result = DELETE_REQUIRES_REBOOT; 389 result = DELETE_REQUIRES_REBOOT;
392 } else { 390 } else {
393 result = DELETE_FAILED; 391 result = DELETE_FAILED;
394 } 392 }
395 } 393 }
396 } 394 }
397 395
398 if (result == DELETE_REQUIRES_REBOOT) { 396 if (result == DELETE_REQUIRES_REBOOT) {
399 ScheduleParentAndGrandparentForDeletion(local_state_folders[0]); 397 ScheduleParentAndGrandparentForDeletion(local_state_folders[0]);
400 } else { 398 } else {
401 DeleteEmptyParentDir(local_state_folders[0]); 399 bool error = false;
400 if (DeleteEmptyDir(local_state_folders[0].DirName(), &error))
401 DeleteEmptyDir(local_state_folders[0].DirName().DirName(), &error);
402 } 402 }
403 403
404 return result; 404 return result;
405 } 405 }
406 406
407 bool MoveSetupOutOfInstallFolder(const InstallerState& installer_state, 407 bool MoveSetupOutOfInstallFolder(const InstallerState& installer_state,
408 const FilePath& setup_path, 408 const FilePath& setup_path,
409 const Version& installed_version) { 409 const Version& installed_version) {
410 bool ret = false; 410 bool ret = false;
411 FilePath setup_exe(installer_state.GetInstallerDirectory(installed_version) 411 FilePath setup_exe(installer_state.GetInstallerDirectory(installed_version)
(...skipping 27 matching lines...) Expand all
439 439
440 DeleteInstallTempDir(target_path); 440 DeleteInstallTempDir(target_path);
441 441
442 DeleteResult result = DELETE_SUCCEEDED; 442 DeleteResult result = DELETE_SUCCEEDED;
443 443
444 FilePath app_host_exe(target_path.Append(installer::kChromeAppHostExe)); 444 FilePath app_host_exe(target_path.Append(installer::kChromeAppHostExe));
445 if (!file_util::Delete(app_host_exe, false)) { 445 if (!file_util::Delete(app_host_exe, false)) {
446 result = DELETE_FAILED; 446 result = DELETE_FAILED;
447 LOG(ERROR) << "Failed to delete path: " << app_host_exe.value(); 447 LOG(ERROR) << "Failed to delete path: " << app_host_exe.value();
448 } else { 448 } else {
449 DeleteEmptyParentDir(target_path); 449 bool error = false;
450 if (DeleteEmptyDir(target_path, &error)) {
451 // Now check and delete if the parent directories are empty
452 // For example Google\Chrome or Chromium
453 if (DeleteEmptyDir(target_path.DirName(), &error))
454 DeleteEmptyDir(target_path.DirName().DirName(), &error);
455 }
456 if (error)
457 result = DELETE_FAILED;
450 } 458 }
451 459
452 return result; 460 return result;
453 } 461 }
454 462
455 DeleteResult DeleteChromeFilesAndFolders(const InstallerState& installer_state, 463 DeleteResult DeleteChromeFilesAndFolders(const InstallerState& installer_state,
456 const Version& installed_version) { 464 const Version& installed_version) {
457 const FilePath& target_path = installer_state.target_path(); 465 const FilePath& target_path = installer_state.target_path();
458 if (target_path.empty()) { 466 if (target_path.empty()) {
459 LOG(ERROR) << "DeleteChromeFilesAndFolders: no installation destination " 467 LOG(ERROR) << "DeleteChromeFilesAndFolders: no installation destination "
(...skipping 11 matching lines...) Expand all
471 false, 479 false,
472 static_cast<FileEnumerator::FileType>(FileEnumerator::FILES | 480 static_cast<FileEnumerator::FileType>(FileEnumerator::FILES |
473 FileEnumerator::DIRECTORIES)); 481 FileEnumerator::DIRECTORIES));
474 while (true) { 482 while (true) {
475 FilePath to_delete(file_enumerator.Next()); 483 FilePath to_delete(file_enumerator.Next());
476 if (to_delete.empty()) 484 if (to_delete.empty())
477 break; 485 break;
478 if (to_delete.BaseName().value() == installer::kChromeAppHostExe) 486 if (to_delete.BaseName().value() == installer::kChromeAppHostExe)
479 continue; 487 continue;
480 488
481 VLOG(1) << "Deleting install path " << target_path.value(); 489 VLOG(1) << "Deleting install path " << to_delete.value();
482 if (!file_util::Delete(to_delete, true)) { 490 if (!file_util::Delete(to_delete, true)) {
483 LOG(ERROR) << "Failed to delete path (1st try): " << to_delete.value(); 491 LOG(ERROR) << "Failed to delete path (1st try): " << to_delete.value();
484 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { 492 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
485 // We don't try killing Chrome processes for Chrome Frame builds since 493 // We don't try killing Chrome processes for Chrome Frame builds since
486 // that is unlikely to help. Instead, schedule files for deletion and 494 // that is unlikely to help. Instead, schedule files for deletion and
487 // return a value that will trigger a reboot prompt. 495 // return a value that will trigger a reboot prompt.
488 FileEnumerator::FindInfo find_info; 496 FileEnumerator::FindInfo find_info;
489 file_enumerator.GetFindInfo(&find_info); 497 file_enumerator.GetFindInfo(&find_info);
490 if (FileEnumerator::IsDirectory(find_info)) 498 if (FileEnumerator::IsDirectory(find_info))
491 ScheduleDirectoryForDeletion(to_delete.value().c_str()); 499 ScheduleDirectoryForDeletion(to_delete.value().c_str());
492 else 500 else
493 ScheduleFileSystemEntityForDeletion(to_delete.value().c_str()); 501 ScheduleFileSystemEntityForDeletion(to_delete.value().c_str());
494 result = DELETE_REQUIRES_REBOOT; 502 result = DELETE_REQUIRES_REBOOT;
495 } else { 503 } else {
496 // Try closing any running Chrome processes and deleting files once 504 // Try closing any running Chrome processes and deleting files once
497 // again. 505 // again.
498 CloseAllChromeProcesses(); 506 CloseAllChromeProcesses();
499 if (!file_util::Delete(to_delete, true)) { 507 if (!file_util::Delete(to_delete, true)) {
500 LOG(ERROR) << "Failed to delete path (2nd try): " 508 LOG(ERROR) << "Failed to delete path (2nd try): "
501 << to_delete.value(); 509 << to_delete.value();
502 result = DELETE_FAILED; 510 result = DELETE_FAILED;
503 break; 511 break;
504 } 512 }
505 } 513 }
506 } 514 }
507 } 515 }
508 516
509 if (result == DELETE_REQUIRES_REBOOT) { 517 if (result == DELETE_REQUIRES_REBOOT) {
518 // Delete the Application directory at reboot if empty.
519 ScheduleFileSystemEntityForDeletion(target_path.value().c_str());
520
510 // If we need a reboot to continue, schedule the parent directories for 521 // If we need a reboot to continue, schedule the parent directories for
511 // deletion unconditionally. If they are not empty, the session manager 522 // deletion unconditionally. If they are not empty, the session manager
512 // will not delete them on reboot. 523 // will not delete them on reboot.
513 ScheduleParentAndGrandparentForDeletion(target_path); 524 ScheduleParentAndGrandparentForDeletion(target_path);
514 } else { 525 } else {
515 // Now check and delete if the parent directories are empty 526 bool error = false;
516 // For example Google\Chrome or Chromium 527 if (DeleteEmptyDir(target_path, &error)) {
517 DeleteEmptyParentDir(target_path); 528 // Now check and delete if the parent directories are empty
529 // For example Google\Chrome or Chromium
530 if (DeleteEmptyDir(target_path.DirName(), &error))
531 DeleteEmptyDir(target_path.DirName().DirName(), &error);
532 }
533 if (error)
534 result = DELETE_FAILED;
518 } 535 }
519 return result; 536 return result;
520 } 537 }
521 538
522 // This method checks if Chrome is currently running or if the user has 539 // This method checks if Chrome is currently running or if the user has
523 // cancelled the uninstall operation by clicking Cancel on the confirmation 540 // cancelled the uninstall operation by clicking Cancel on the confirmation
524 // box that Chrome pops up. 541 // box that Chrome pops up.
525 InstallStatus IsChromeActiveOrUserCancelled( 542 InstallStatus IsChromeActiveOrUserCancelled(
526 const InstallerState& installer_state, 543 const InstallerState& installer_state,
527 const Product& product) { 544 const Product& product) {
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1178
1162 // Try and delete the preserved local state once the post-install 1179 // Try and delete the preserved local state once the post-install
1163 // operations are complete. 1180 // operations are complete.
1164 if (!backup_state_file.empty()) 1181 if (!backup_state_file.empty())
1165 file_util::Delete(backup_state_file, false); 1182 file_util::Delete(backup_state_file, false);
1166 1183
1167 return ret; 1184 return ret;
1168 } 1185 }
1169 1186
1170 } // namespace installer 1187 } // namespace installer
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698