• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/extensions/external_registry_extension_loader_win.h"
6 
7 #include "base/file_path.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "base/version.h"
12 #include "base/win/registry.h"
13 #include "content/browser/browser_thread.h"
14 #include "chrome/browser/extensions/external_extension_provider_impl.h"
15 
16 namespace {
17 
18 // The Registry hive where to look for external extensions.
19 const HKEY kRegRoot = HKEY_LOCAL_MACHINE;
20 
21 // The Registry subkey that contains information about external extensions.
22 const char kRegistryExtensions[] = "Software\\Google\\Chrome\\Extensions";
23 
24 // Registry value of of that key that defines the path to the .crx file.
25 const wchar_t kRegistryExtensionPath[] = L"path";
26 
27 // Registry value of that key that defines the current version of the .crx file.
28 const wchar_t kRegistryExtensionVersion[] = L"version";
29 
30 }  // namespace
31 
StartLoading()32 void ExternalRegistryExtensionLoader::StartLoading() {
33   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
34   BrowserThread::PostTask(
35       BrowserThread::FILE, FROM_HERE,
36       NewRunnableMethod(
37           this,
38           &ExternalRegistryExtensionLoader::LoadOnFileThread));
39 }
40 
LoadOnFileThread()41 void ExternalRegistryExtensionLoader::LoadOnFileThread() {
42   CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
43   scoped_ptr<DictionaryValue> prefs(new DictionaryValue);
44 
45   base::win::RegistryKeyIterator iterator(
46       kRegRoot, ASCIIToWide(kRegistryExtensions).c_str());
47   while (iterator.Valid()) {
48     base::win::RegKey key;
49     std::wstring key_path = ASCIIToWide(kRegistryExtensions);
50     key_path.append(L"\\");
51     key_path.append(iterator.Name());
52     if (key.Open(kRegRoot, key_path.c_str(), KEY_READ)  == ERROR_SUCCESS) {
53       std::wstring extension_path_str;
54       if (key.ReadValue(kRegistryExtensionPath, &extension_path_str)
55           == ERROR_SUCCESS) {
56         FilePath extension_path(extension_path_str);
57         if (!extension_path.IsAbsolute()) {
58           LOG(ERROR) << "Path " << extension_path_str
59                      << " needs to be absolute in key "
60                      << key_path;
61           ++iterator;
62           continue;
63         }
64         std::wstring extension_version;
65         if (key.ReadValue(kRegistryExtensionVersion, &extension_version)
66             == ERROR_SUCCESS) {
67           std::string id = WideToASCII(iterator.Name());
68           StringToLowerASCII(&id);
69 
70           if (!Extension::IdIsValid(id)) {
71             LOG(ERROR) << "Invalid id value " << id
72                        << " for key " << key_path << " .";
73             ++iterator;
74             continue;
75           }
76 
77           scoped_ptr<Version> version;
78           version.reset(Version::GetVersionFromString(
79                             WideToASCII(extension_version)));
80           if (!version.get()) {
81             LOG(ERROR) << "Invalid version value " << extension_version
82                        << " for key " << key_path << " .";
83             ++iterator;
84             continue;
85           }
86 
87           prefs->SetString(
88               id + "." + ExternalExtensionProviderImpl::kExternalVersion,
89               WideToASCII(extension_version));
90           prefs->SetString(
91               id + "." + ExternalExtensionProviderImpl::kExternalCrx,
92               extension_path_str);
93         } else {
94           // TODO(erikkay): find a way to get this into about:extensions
95           LOG(ERROR) << "Missing value " << kRegistryExtensionVersion
96                      << " for key " << key_path << " .";
97         }
98       } else {
99         // TODO(erikkay): find a way to get this into about:extensions
100         LOG(ERROR) << "Missing value " << kRegistryExtensionPath
101                    << " for key " << key_path << " .";
102       }
103     }
104     ++iterator;
105   }
106 
107   prefs_.reset(prefs.release());
108   BrowserThread::PostTask(
109       BrowserThread::UI, FROM_HERE,
110       NewRunnableMethod(
111           this,
112           &ExternalRegistryExtensionLoader::LoadFinished));
113 }
114