• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/history/history_publisher.h"
6 
7 #include <atlsafe.h>
8 #include <objbase.h>
9 #include <oleauto.h>
10 #include <wtypes.h>
11 
12 #include "base/string_util.h"
13 #include "base/time.h"
14 #include "base/utf_string_conversions.h"
15 #include "base/win/registry.h"
16 #include "base/win/scoped_bstr.h"
17 #include "base/win/scoped_comptr.h"
18 #include "base/win/scoped_variant.h"
19 #include "googleurl/src/gurl.h"
20 
21 namespace {
22 
23 // Instantiates a IChromeHistoryIndexer COM object. Takes a COM class id
24 // in |name| and returns the object in |indexer|. Returns false if the
25 // operation fails.
CoCreateIndexerFromName(const wchar_t * name,IChromeHistoryIndexer ** indexer)26 bool CoCreateIndexerFromName(const wchar_t* name,
27                              IChromeHistoryIndexer** indexer) {
28   CLSID clsid;
29   HRESULT hr = CLSIDFromString(const_cast<wchar_t*>(name), &clsid);
30   if (FAILED(hr))
31     return false;
32   hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC,
33                         __uuidof(IChromeHistoryIndexer),
34                         reinterpret_cast<void**>(indexer));
35   if (FAILED(hr))
36     return false;
37   return true;
38 }
39 
40 // Instantiates the registered indexers from the registry |root| + |path| key
41 // and adds them to the |indexers| list.
AddRegisteredIndexers(HKEY root,const wchar_t * path,std::vector<base::win::ScopedComPtr<IChromeHistoryIndexer>> * indexers)42 void AddRegisteredIndexers(HKEY root, const wchar_t* path,
43     std::vector< base::win::ScopedComPtr<IChromeHistoryIndexer> >* indexers) {
44   IChromeHistoryIndexer* indexer;
45   base::win::RegistryKeyIterator r_iter(root, path);
46   while (r_iter.Valid()) {
47     if (CoCreateIndexerFromName(r_iter.Name(), &indexer)) {
48       indexers->push_back(
49           base::win::ScopedComPtr<IChromeHistoryIndexer>(indexer));
50       indexer->Release();
51     }
52     ++r_iter;
53   }
54 }
55 
56 }  // namespace
57 
58 namespace history {
59 
60 const wchar_t* const HistoryPublisher::kRegKeyRegisteredIndexersInfo =
61     L"Software\\Google\\Google Chrome\\IndexerPlugins";
62 
63 // static
TimeToUTCVariantTime(const base::Time & time)64 double HistoryPublisher::TimeToUTCVariantTime(const base::Time& time) {
65   double var_time = 0;
66   if (!time.is_null()) {
67     base::Time::Exploded exploded;
68     time.UTCExplode(&exploded);
69 
70     // Create the system time struct representing our exploded time.
71     SYSTEMTIME system_time;
72     system_time.wYear = exploded.year;
73     system_time.wMonth = exploded.month;
74     system_time.wDayOfWeek = exploded.day_of_week;
75     system_time.wDay = exploded.day_of_month;
76     system_time.wHour = exploded.hour;
77     system_time.wMinute = exploded.minute;
78     system_time.wSecond = exploded.second;
79     system_time.wMilliseconds = exploded.millisecond;
80     SystemTimeToVariantTime(&system_time, &var_time);
81   }
82 
83   return var_time;
84 }
85 
HistoryPublisher()86 HistoryPublisher::HistoryPublisher() {
87   CoInitialize(NULL);
88 }
89 
~HistoryPublisher()90 HistoryPublisher::~HistoryPublisher() {
91   CoUninitialize();
92 }
93 
Init()94 bool HistoryPublisher::Init() {
95   return ReadRegisteredIndexersFromRegistry();
96 }
97 
98 // Peruse the registry for Indexer to instantiate and store in |indexers_|.
99 // Return true if we found at least one indexer object. We look both in HKCU
100 // and HKLM.
ReadRegisteredIndexersFromRegistry()101 bool HistoryPublisher::ReadRegisteredIndexersFromRegistry() {
102   AddRegisteredIndexers(HKEY_CURRENT_USER,
103                         kRegKeyRegisteredIndexersInfo, &indexers_);
104   AddRegisteredIndexers(HKEY_LOCAL_MACHINE,
105                         kRegKeyRegisteredIndexersInfo, &indexers_);
106   return !indexers_.empty();
107 }
108 
PublishDataToIndexers(const PageData & page_data) const109 void HistoryPublisher::PublishDataToIndexers(const PageData& page_data)
110     const {
111   double var_time = TimeToUTCVariantTime(page_data.time);
112 
113   CComSafeArray<unsigned char> thumbnail_arr;
114   if (page_data.thumbnail) {
115     for (size_t i = 0; i < page_data.thumbnail->size(); ++i)
116       thumbnail_arr.Add((*page_data.thumbnail)[i]);
117   }
118 
119   // Send data to registered indexers.
120   base::win::ScopedVariant time(var_time, VT_DATE);
121   base::win::ScopedBstr url(ASCIIToWide(page_data.url.spec()).c_str());
122   base::win::ScopedBstr html(page_data.html);
123   base::win::ScopedBstr title(page_data.title);
124   // Don't send a NULL string through ASCIIToWide.
125   base::win::ScopedBstr format(page_data.thumbnail_format ?
126       ASCIIToWide(page_data.thumbnail_format).c_str() :
127       NULL);
128   base::win::ScopedVariant psa(thumbnail_arr.m_psa);
129   for (size_t i = 0; i < indexers_.size(); ++i) {
130     indexers_[i]->SendPageData(time, url, html, title, format, psa);
131   }
132 }
133 
DeleteUserHistoryBetween(const base::Time & begin_time,const base::Time & end_time) const134 void HistoryPublisher::DeleteUserHistoryBetween(const base::Time& begin_time,
135                                                 const base::Time& end_time)
136     const {
137   base::win::ScopedVariant var_begin_time(TimeToUTCVariantTime(begin_time),
138                                           VT_DATE);
139   base::win::ScopedVariant var_end_time(TimeToUTCVariantTime(end_time),
140                                         VT_DATE);
141   for (size_t i = 0; i < indexers_.size(); ++i) {
142     indexers_[i]->DeleteUserHistoryBetween(var_begin_time, var_end_time);
143   }
144 }
145 
146 }  // namespace history
147