This source file includes following definitions.
- cleared_destination_
 
- Do
 
- Rollback
 
#include "chrome/installer/util/copy_reg_key_work_item.h"
#include <shlwapi.h>
#include "base/logging.h"
#include "base/win/registry.h"
using base::win::RegKey;
CopyRegKeyWorkItem::~CopyRegKeyWorkItem() {
}
CopyRegKeyWorkItem::CopyRegKeyWorkItem(HKEY predefined_root,
                                       const std::wstring& source_key_path,
                                       const std::wstring& dest_key_path,
                                       CopyOverWriteOption overwrite_option)
    : predefined_root_(predefined_root),
      source_key_path_(source_key_path),
      dest_key_path_(dest_key_path),
      overwrite_option_(overwrite_option),
      cleared_destination_(false) {
  DCHECK(predefined_root);
  
  
  DCHECK(!source_key_path.empty());
  DCHECK(!dest_key_path.empty());
  DCHECK(overwrite_option == ALWAYS || overwrite_option == IF_NOT_PRESENT);
}
bool CopyRegKeyWorkItem::Do() {
  if (source_key_path_.empty() || dest_key_path_.empty())
    return false;
  
  
  if (overwrite_option_ == IF_NOT_PRESENT &&
      RegKey(predefined_root_, dest_key_path_.c_str(),
             KEY_QUERY_VALUE).Valid()) {
    return true;
  }
  RegistryKeyBackup backup;
  RegKey dest_key;
  
  if (!ignore_failure_) {
    if (!backup.Initialize(predefined_root_, dest_key_path_.c_str())) {
      LOG(ERROR) << "Failed to backup destination for registry key copy.";
      return false;
    }
  }
  
  LONG result = SHDeleteKey(predefined_root_, dest_key_path_.c_str());
  if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
    LOG(ERROR) << "Failed to delete key at " << dest_key_path_ << ", result: "
               << result;
  } else {
    cleared_destination_ = true;
    
    
    backup_.swap(backup);
    
    result = dest_key.Create(predefined_root_, dest_key_path_.c_str(),
                             KEY_WRITE);
    if (result != ERROR_SUCCESS) {
      LOG(ERROR) << "Failed to open destination key at " << dest_key_path_
                 << ", result: " << result;
    } else {
      result = SHCopyKey(predefined_root_, source_key_path_.c_str(),
                         dest_key.Handle(), 0);
      switch (result) {
        case ERROR_FILE_NOT_FOUND:
          
          dest_key.Close();
          SHDeleteKey(predefined_root_, dest_key_path_.c_str());
          
          result = ERROR_SUCCESS;
          
        case ERROR_SUCCESS:
          break;
        default:
          LOG(ERROR) << "Failed to copy key from " << source_key_path_ << " to "
                     << dest_key_path_ << ", result: " << result;
          break;
      }
    }
  }
  return ignore_failure_ ? true : (result == ERROR_SUCCESS);
}
void CopyRegKeyWorkItem::Rollback() {
  if (ignore_failure_)
    return;
  if (cleared_destination_) {
    
    
    LONG result = SHDeleteKey(predefined_root_, dest_key_path_.c_str());
    if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
      LOG(ERROR) << "Failed to delete key at " << dest_key_path_
                 << " in rollback, result: " << result;
    }
    
    
    if (!backup_.WriteTo(predefined_root_, dest_key_path_.c_str()))
      LOG(ERROR) << "Failed to restore key in rollback.";
  }
}