| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/files/file_util.h" | 
 | #include "base/logging.h" | 
 | #include "chrome/installer/util/create_dir_work_item.h" | 
 | #include "chrome/installer/util/logging_installer.h" | 
 |  | 
 | CreateDirWorkItem::~CreateDirWorkItem() { | 
 | } | 
 |  | 
 | CreateDirWorkItem::CreateDirWorkItem(const base::FilePath& path) | 
 |     : path_(path), | 
 |       rollback_needed_(false) { | 
 | } | 
 |  | 
 | void CreateDirWorkItem::GetTopDirToCreate() { | 
 |   if (base::PathExists(path_)) { | 
 |     top_path_ = base::FilePath(); | 
 |     return; | 
 |   } | 
 |  | 
 |   base::FilePath parent_dir(path_); | 
 |   do { | 
 |     top_path_ = parent_dir; | 
 |     parent_dir = parent_dir.DirName(); | 
 |   } while ((parent_dir != top_path_) && !base::PathExists(parent_dir)); | 
 |   return; | 
 | } | 
 |  | 
 | bool CreateDirWorkItem::Do() { | 
 |   VLOG(1) << "creating directory " << path_.value(); | 
 |   GetTopDirToCreate(); | 
 |   if (top_path_.empty()) | 
 |     return true; | 
 |  | 
 |   VLOG(1) << "top directory that needs to be created: " << top_path_.value(); | 
 |   bool result = base::CreateDirectory(path_); | 
 |   VLOG(1) << "directory creation result: " << result; | 
 |  | 
 |   rollback_needed_ = true; | 
 |  | 
 |   return result; | 
 | } | 
 |  | 
 | void CreateDirWorkItem::Rollback() { | 
 |   if (!rollback_needed_) | 
 |     return; | 
 |  | 
 |   // Delete all the directories we created to rollback. | 
 |   // Note we can not recusively delete top_path_ since we don't want to | 
 |   // delete non-empty directory. (We may have created a shared directory). | 
 |   // Instead we walk through path_ to top_path_ and delete directories | 
 |   // along the way. | 
 |   base::FilePath path_to_delete(path_); | 
 |  | 
 |   while (1) { | 
 |     if (base::PathExists(path_to_delete)) { | 
 |       if (!RemoveDirectory(path_to_delete.value().c_str())) | 
 |         break; | 
 |     } | 
 |     if (path_to_delete == top_path_) | 
 |       break; | 
 |     path_to_delete = path_to_delete.DirName(); | 
 |   } | 
 |  | 
 |   return; | 
 | } |