This source file includes following definitions.
- CanOpenFileForReading
- StartLoading
- LoadOnFileThread
#include "chrome/browser/extensions/external_registry_loader_win.h"
#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_handle.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "base/version.h"
#include "base/win/registry.h"
#include "chrome/browser/extensions/external_provider_impl.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/extension.h"
using content::BrowserThread;
namespace {
const char kRegistryExtensions[] = "Software\\Google\\Chrome\\Extensions";
const wchar_t kRegistryExtensionInstallParam[] = L"install_parameter";
const wchar_t kRegistryExtensionPath[] = L"path";
const wchar_t kRegistryExtensionVersion[] = L"version";
const wchar_t kRegistryExtensionUpdateUrl[] = L"update_url";
bool CanOpenFileForReading(const base::FilePath& path) {
ScopedStdioHandle file_handle(base::OpenFile(path, "rb"));
return file_handle.get() != NULL;
}
}
namespace extensions {
void ExternalRegistryLoader::StartLoading() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&ExternalRegistryLoader::LoadOnFileThread, this));
}
void ExternalRegistryLoader::LoadOnFileThread() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
base::TimeTicks start_time = base::TimeTicks::Now();
scoped_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
std::set<base::string16> keys;
base::win::RegistryKeyIterator iterator_machine_key(
HKEY_LOCAL_MACHINE, base::ASCIIToWide(kRegistryExtensions).c_str());
for (; iterator_machine_key.Valid(); ++iterator_machine_key)
keys.insert(iterator_machine_key.Name());
base::win::RegistryKeyIterator iterator_user_key(
HKEY_CURRENT_USER, base::ASCIIToWide(kRegistryExtensions).c_str());
for (; iterator_user_key.Valid(); ++iterator_user_key)
keys.insert(iterator_user_key.Name());
for (std::set<base::string16>::const_iterator it = keys.begin();
it != keys.end(); ++it) {
base::win::RegKey key;
base::string16 key_path = base::ASCIIToWide(kRegistryExtensions);
key_path.append(L"\\");
key_path.append(*it);
if (key.Open(HKEY_LOCAL_MACHINE,
key_path.c_str(), KEY_READ) != ERROR_SUCCESS) {
if (key.Open(HKEY_CURRENT_USER,
key_path.c_str(), KEY_READ) != ERROR_SUCCESS) {
LOG(ERROR) << "Unable to read registry key at path (HKLM & HKCU): "
<< key_path << ".";
continue;
}
}
std::string id = base::UTF16ToASCII(*it);
StringToLowerASCII(&id);
if (!Extension::IdIsValid(id)) {
LOG(ERROR) << "Invalid id value " << id
<< " for key " << key_path << ".";
continue;
}
base::string16 extension_dist_id;
if (key.ReadValue(kRegistryExtensionInstallParam, &extension_dist_id) ==
ERROR_SUCCESS) {
prefs->SetString(id + "." + ExternalProviderImpl::kInstallParam,
base::UTF16ToASCII(extension_dist_id));
}
base::string16 extension_update_url;
if (key.ReadValue(kRegistryExtensionUpdateUrl, &extension_update_url)
== ERROR_SUCCESS) {
prefs->SetString(
id + "." + ExternalProviderImpl::kExternalUpdateUrl,
base::UTF16ToASCII(extension_update_url));
continue;
}
base::string16 extension_path_str;
if (key.ReadValue(kRegistryExtensionPath, &extension_path_str)
!= ERROR_SUCCESS) {
LOG(ERROR) << "Missing value " << kRegistryExtensionPath
<< " for key " << key_path << ".";
continue;
}
base::FilePath extension_path(extension_path_str);
if (!extension_path.IsAbsolute()) {
LOG(ERROR) << "File path " << extension_path_str
<< " needs to be absolute in key "
<< key_path;
continue;
}
if (!base::PathExists(extension_path)) {
LOG(ERROR) << "File " << extension_path_str
<< " for key " << key_path
<< " does not exist or is not readable.";
continue;
}
if (!CanOpenFileForReading(extension_path)) {
LOG(ERROR) << "File " << extension_path_str
<< " for key " << key_path << " can not be read. "
<< "Check that users who should have the extension "
<< "installed have permission to read it.";
continue;
}
base::string16 extension_version;
if (key.ReadValue(kRegistryExtensionVersion, &extension_version)
!= ERROR_SUCCESS) {
LOG(ERROR) << "Missing value " << kRegistryExtensionVersion
<< " for key " << key_path << ".";
continue;
}
Version version(base::UTF16ToASCII(extension_version));
if (!version.IsValid()) {
LOG(ERROR) << "Invalid version value " << extension_version
<< " for key " << key_path << ".";
continue;
}
prefs->SetString(
id + "." + ExternalProviderImpl::kExternalVersion,
base::UTF16ToASCII(extension_version));
prefs->SetString(
id + "." + ExternalProviderImpl::kExternalCrx,
extension_path_str);
}
prefs_.reset(prefs.release());
HISTOGRAM_TIMES("Extensions.ExternalRegistryLoaderWin",
base::TimeTicks::Now() - start_time);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&ExternalRegistryLoader::LoadFinished, this));
}
}