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 <oleauto.h> 9 #include <wtypes.h> 10 11 #include "base/strings/string_util.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "base/time/time.h" 14 #include "base/win/registry.h" 15 #include "base/win/scoped_bstr.h" 16 #include "base/win/scoped_comptr.h" 17 #include "base/win/scoped_variant.h" 18 #include "url/gurl.h" 19 20 namespace { 21 22 // Instantiates the registered indexers from the registry |root| + |path| key 23 // and adds them to the |indexers| list. 24 void AddRegisteredIndexers( 25 HKEY root, 26 const wchar_t* path, 27 std::vector< base::win::ScopedComPtr<IChromeHistoryIndexer> >* indexers) { 28 for (base::win::RegistryKeyIterator r_iter(root, path); r_iter.Valid(); 29 ++r_iter) { 30 CLSID clsid; 31 if (FAILED(CLSIDFromString(const_cast<wchar_t*>(r_iter.Name()), &clsid))) 32 continue; 33 base::win::ScopedComPtr<IChromeHistoryIndexer> indexer; 34 if (SUCCEEDED(indexer.CreateInstance(clsid, NULL, CLSCTX_INPROC))) { 35 indexers->push_back(indexer); 36 indexer.Release(); 37 } 38 } 39 } 40 41 } // namespace 42 43 namespace history { 44 45 const wchar_t* const HistoryPublisher::kRegKeyRegisteredIndexersInfo = 46 L"Software\\Google\\Google Chrome\\IndexerPlugins"; 47 48 // static 49 double HistoryPublisher::TimeToUTCVariantTime(const base::Time& time) { 50 double var_time = 0; 51 if (!time.is_null()) { 52 base::Time::Exploded exploded; 53 time.UTCExplode(&exploded); 54 55 // Create the system time struct representing our exploded time. 56 SYSTEMTIME system_time; 57 system_time.wYear = exploded.year; 58 system_time.wMonth = exploded.month; 59 system_time.wDayOfWeek = exploded.day_of_week; 60 system_time.wDay = exploded.day_of_month; 61 system_time.wHour = exploded.hour; 62 system_time.wMinute = exploded.minute; 63 system_time.wSecond = exploded.second; 64 system_time.wMilliseconds = exploded.millisecond; 65 SystemTimeToVariantTime(&system_time, &var_time); 66 } 67 68 return var_time; 69 } 70 71 HistoryPublisher::HistoryPublisher() { 72 } 73 74 HistoryPublisher::~HistoryPublisher() { 75 } 76 77 bool HistoryPublisher::Init() { 78 return ReadRegisteredIndexersFromRegistry(); 79 } 80 81 // Peruse the registry for Indexer to instantiate and store in |indexers_|. 82 // Return true if we found at least one indexer object. We look both in HKCU 83 // and HKLM. 84 bool HistoryPublisher::ReadRegisteredIndexersFromRegistry() { 85 AddRegisteredIndexers(HKEY_CURRENT_USER, 86 kRegKeyRegisteredIndexersInfo, &indexers_); 87 AddRegisteredIndexers(HKEY_LOCAL_MACHINE, 88 kRegKeyRegisteredIndexersInfo, &indexers_); 89 return !indexers_.empty(); 90 } 91 92 void HistoryPublisher::PublishDataToIndexers(const PageData& page_data) 93 const { 94 double var_time = TimeToUTCVariantTime(page_data.time); 95 96 CComSafeArray<unsigned char> thumbnail_arr; 97 if (page_data.thumbnail) { 98 for (size_t i = 0; i < page_data.thumbnail->size(); ++i) 99 thumbnail_arr.Add((*page_data.thumbnail)[i]); 100 } 101 102 // Send data to registered indexers. 103 base::win::ScopedVariant time(var_time, VT_DATE); 104 base::win::ScopedBstr url(ASCIIToWide(page_data.url.spec()).c_str()); 105 base::win::ScopedBstr html(page_data.html); 106 base::win::ScopedBstr title(page_data.title); 107 // Don't send a NULL string through ASCIIToWide. 108 base::win::ScopedBstr format(page_data.thumbnail_format ? 109 ASCIIToWide(page_data.thumbnail_format).c_str() : 110 NULL); 111 base::win::ScopedVariant psa(thumbnail_arr.m_psa); 112 for (size_t i = 0; i < indexers_.size(); ++i) { 113 indexers_[i]->SendPageData(time, url, html, title, format, psa); 114 } 115 } 116 117 } // namespace history 118