This source file includes following definitions.
- UpOneDirectoryOrEmpty
- key_created_
- Do
- Rollback
- InitKeyList
#include <shlwapi.h>
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/win/registry.h"
#include "chrome/installer/util/create_reg_key_work_item.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/logging_installer.h"
using base::win::RegKey;
namespace {
void UpOneDirectoryOrEmpty(std::wstring* dir) {
base::FilePath path = base::FilePath(*dir);
base::FilePath directory = path.DirName();
if (directory == path || directory.value() ==
base::FilePath::kCurrentDirectory)
dir->clear();
else
*dir = directory.value();
}
}
CreateRegKeyWorkItem::~CreateRegKeyWorkItem() {
}
CreateRegKeyWorkItem::CreateRegKeyWorkItem(HKEY predefined_root,
const std::wstring& path)
: predefined_root_(predefined_root),
path_(path),
key_created_(false) {
}
bool CreateRegKeyWorkItem::Do() {
if (!InitKeyList()) {
VLOG(1) << "no key to create";
return true;
}
RegKey key;
std::wstring key_path;
for (size_t i = key_list_.size(); i > 0; i--) {
DWORD disposition;
key_path.assign(key_list_[i - 1]);
if (key.CreateWithDisposition(predefined_root_, key_path.c_str(),
&disposition, KEY_READ) == ERROR_SUCCESS) {
if (disposition == REG_OPENED_EXISTING_KEY) {
if (key_created_) {
LOG(ERROR) << key_path << " exists, this is not expected.";
return false;
}
key_list_.pop_back();
} else if (disposition == REG_CREATED_NEW_KEY) {
VLOG(1) << "created " << key_path;
key_created_ = true;
} else {
LOG(ERROR) << "unkown disposition";
return false;
}
} else {
LOG(ERROR) << "Failed to create " << key_path;
return false;
}
}
return true;
}
void CreateRegKeyWorkItem::Rollback() {
if (!key_created_)
return;
std::wstring key_path;
std::vector<std::wstring>::iterator itr;
for (itr = key_list_.begin(); itr != key_list_.end(); ++itr) {
key_path.assign(*itr);
if (SHDeleteEmptyKey(predefined_root_, key_path.c_str()) ==
ERROR_SUCCESS) {
VLOG(1) << "rollback: delete " << key_path;
} else {
VLOG(1) << "rollback: can not delete " << key_path;
}
}
key_created_ = false;
key_list_.clear();
return;
}
bool CreateRegKeyWorkItem::InitKeyList() {
if (path_.empty())
return false;
std::wstring key_path(path_);
do {
key_list_.push_back(key_path);
UpOneDirectoryOrEmpty(&key_path);
} while (!key_path.empty());
return true;
}