13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/importer/ie_importer.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <ole2.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <intshcut.h>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <pstore.h>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <shlobj.h>
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <urlhist.h>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "app/win/scoped_co_mem.h"
193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "app/win/scoped_com_initializer.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/registry.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/win/scoped_comptr.h"
283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/win/scoped_handle.h"
29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/windows_version.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/importer/importer_bridge.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/importer/importer_data_types.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/ie7_password.h"
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/template_url.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_model.h"
35513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/time_format.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/password_form.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A struct that hosts the information of AutoComplete data in PStore.
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstruct AutoCompleteInfo {
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::wstring key;
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<std::wstring> data;
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool is_url;
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Gets the creation time of the given file or directory.
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbase::Time GetFileCreationTime(const std::wstring& file) {
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::Time creation_time;
553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  base::win::ScopedHandle file_handle(
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CreateFile(file.c_str(), GENERIC_READ,
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NULL, OPEN_EXISTING,
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL));
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FILETIME creation_filetime;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetFileTime(file_handle, &creation_filetime, NULL, NULL))
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    creation_time = base::Time::FromFileTime(creation_filetime);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return creation_time;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// {E161255A-37C3-11D2-BCAA-00C04fD929DB}
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst GUID IEImporter::kPStoreAutocompleteGUID = {
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xe161255a, 0x37c3, 0x11d2,
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0xbc, 0xaa, 0x00, 0xc0, 0x4f, 0xd9, 0x29, 0xdb }
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// {A79029D6-753E-4e27-B807-3D46AB1545DF}
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst GUID IEImporter::kUnittestGUID = {
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xa79029d6, 0x753e, 0x4e27,
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { 0xb8, 0x7, 0x3d, 0x46, 0xab, 0x15, 0x45, 0xdf }
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIEImporter::IEImporter() {
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid IEImporter::StartImport(const importer::SourceProfile& source_profile,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             uint16 items,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             ImporterBridge* bridge) {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bridge_ = bridge;
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  source_path_ = source_profile.source_path;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bridge_->NotifyStarted();
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Some IE settings (such as Protected Storage) are obtained via COM APIs.
923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  app::win::ScopedCOMInitializer com_initializer;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((items & importer::HOME_PAGE) && !cancelled())
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ImportHomepage();  // Doesn't have a UI item.
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The order here is important!
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((items & importer::HISTORY) && !cancelled()) {
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemStarted(importer::HISTORY);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ImportHistory();
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemEnded(importer::HISTORY);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((items & importer::FAVORITES) && !cancelled()) {
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemStarted(importer::FAVORITES);
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ImportFavorites();
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemEnded(importer::FAVORITES);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((items & importer::SEARCH_ENGINES) && !cancelled()) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemStarted(importer::SEARCH_ENGINES);
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ImportSearchEngines();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemEnded(importer::SEARCH_ENGINES);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((items & importer::PASSWORDS) && !cancelled()) {
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemStarted(importer::PASSWORDS);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Always import IE6 passwords.
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ImportPasswordsIE6();
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (CurrentIEVersion() >= 7)
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ImportPasswordsIE7();
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->NotifyItemEnded(importer::PASSWORDS);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bridge_->NotifyEnded();
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIEImporter::~IEImporter() {
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid IEImporter::ImportFavorites() {
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring path;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FavoritesInfo info;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!GetFavoritesInfo(&info))
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkVector bookmarks;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ParseFavoritesFolder(info, &bookmarks);
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!bookmarks.empty() && !cancelled()) {
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const string16& first_folder_name =
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_BOOKMARK_GROUP_FROM_IE);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int options = 0;
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (import_to_bookmark_bar())
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      options = ProfileWriter::IMPORT_TO_BOOKMARK_BAR;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->AddBookmarkEntries(bookmarks, first_folder_name, options);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid IEImporter::ImportHistory() {
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string kSchemes[] = {chrome::kHttpScheme,
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  chrome::kHttpsScheme,
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  chrome::kFtpScheme,
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  chrome::kFileScheme};
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int total_schemes = arraysize(kSchemes);
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IUrlHistoryStg2> url_history_stg2;
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  HRESULT result;
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result = url_history_stg2.CreateInstance(CLSID_CUrlHistory, NULL,
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           CLSCTX_INPROC_SERVER);
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (FAILED(result))
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IEnumSTATURL> enum_url;
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (SUCCEEDED(result = url_history_stg2->EnumUrls(enum_url.Receive()))) {
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::vector<history::URLRow> rows;
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    STATURL stat_url;
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULONG fetched;
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    while (!cancelled() &&
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           (result = enum_url->Next(1, &stat_url, &fetched)) == S_OK) {
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::wstring url_string;
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::wstring title_string;
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (stat_url.pwcsUrl) {
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        url_string = stat_url.pwcsUrl;
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        CoTaskMemFree(stat_url.pwcsUrl);
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (stat_url.pwcsTitle) {
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        title_string = stat_url.pwcsTitle;
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        CoTaskMemFree(stat_url.pwcsTitle);
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GURL url(url_string);
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Skips the URLs that are invalid or have other schemes.
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!url.is_valid() ||
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          (std::find(kSchemes, kSchemes + total_schemes, url.scheme()) ==
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           kSchemes + total_schemes))
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        continue;
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      history::URLRow row(url);
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      row.set_title(title_string);
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      row.set_last_visit(base::Time::FromFileTime(stat_url.ftLastVisited));
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (stat_url.dwFlags == STATURL_QUERYFLAG_TOPLEVEL) {
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        row.set_visit_count(1);
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        row.set_hidden(false);
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        row.set_hidden(true);
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      rows.push_back(row);
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!rows.empty() && !cancelled()) {
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      bridge_->SetHistoryItems(rows, history::SOURCE_IE_IMPORTED);
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid IEImporter::ImportPasswordsIE6() {
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GUID AutocompleteGUID = kPStoreAutocompleteGUID;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!source_path_.empty()) {
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We supply a fake GUID for testting.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AutocompleteGUID = kUnittestGUID;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The PStoreCreateInstance function retrieves an interface pointer
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to a storage provider. But this function has no associated import
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // library or header file, we must call it using the LoadLibrary()
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and GetProcAddress() functions.
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef HRESULT (WINAPI *PStoreCreateFunc)(IPStore**, DWORD, DWORD, DWORD);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HMODULE pstorec_dll = LoadLibrary(L"pstorec.dll");
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!pstorec_dll)
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PStoreCreateFunc PStoreCreateInstance =
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (PStoreCreateFunc)GetProcAddress(pstorec_dll, "PStoreCreateInstance");
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!PStoreCreateInstance) {
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FreeLibrary(pstorec_dll);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IPStore, &IID_IPStore> pstore;
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HRESULT result = PStoreCreateInstance(pstore.Receive(), 0, 0, 0);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result != S_OK) {
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FreeLibrary(pstorec_dll);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<AutoCompleteInfo> ac_list;
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Enumerates AutoComplete items in the protected database.
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IEnumPStoreItems, &IID_IEnumPStoreItems> item;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  result = pstore->EnumItems(0, &AutocompleteGUID,
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             &AutocompleteGUID, 0, item.Receive());
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result != PST_E_OK) {
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pstore.Release();
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FreeLibrary(pstorec_dll);
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  wchar_t* item_name;
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (!cancelled() && SUCCEEDED(item->Next(1, &item_name, 0))) {
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DWORD length = 0;
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned char* buffer = NULL;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result = pstore->ReadItem(0, &AutocompleteGUID, &AutocompleteGUID,
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              item_name, &length, &buffer, NULL, 0);
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (SUCCEEDED(result)) {
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AutoCompleteInfo ac;
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ac.key = item_name;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::wstring data;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      data.insert(0, reinterpret_cast<wchar_t*>(buffer),
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                  length / sizeof(wchar_t));
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // The key name is always ended with ":StringData".
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const wchar_t kDataSuffix[] = L":StringData";
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      size_t i = ac.key.rfind(kDataSuffix);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (i != std::wstring::npos && ac.key.substr(i) == kDataSuffix) {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ac.key.erase(i);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ac.is_url = (ac.key.find(L"://") != std::wstring::npos);
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ac_list.push_back(ac);
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        base::SplitString(data, L'\0', &ac_list[ac_list.size() - 1].data);
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CoTaskMemFree(buffer);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CoTaskMemFree(item_name);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Releases them before unload the dll.
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  item.Release();
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pstore.Release();
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FreeLibrary(pstorec_dll);
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t i;
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (i = 0; i < ac_list.size(); i++) {
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!ac_list[i].is_url || ac_list[i].data.size() < 2)
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url(ac_list[i].key.c_str());
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!(LowerCaseEqualsASCII(url.scheme(), chrome::kHttpScheme) ||
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        LowerCaseEqualsASCII(url.scheme(), chrome::kHttpsScheme))) {
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    webkit_glue::PasswordForm form;
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL::Replacements rp;
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rp.ClearUsername();
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rp.ClearPassword();
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rp.ClearQuery();
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rp.ClearRef();
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    form.origin = url.ReplaceComponents(rp);
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    form.username_value = ac_list[i].data[0];
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    form.password_value = ac_list[i].data[1];
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    form.signon_realm = url.GetOrigin().spec();
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This is not precise, because a scheme of https does not imply a valid
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // certificate was presented; however we assign it this way so that if we
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // import a password from IE whose scheme is https, we give it the benefit
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // of the doubt and DONT auto-fill it unless the form appears under
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // valid SSL conditions.
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    form.ssl_valid = url.SchemeIsSecure();
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Goes through the list to find out the username field
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // of the web page.
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t list_it, item_it;
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (list_it = 0; list_it < ac_list.size(); ++list_it) {
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (ac_list[list_it].is_url)
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (item_it = 0; item_it < ac_list[list_it].data.size(); ++item_it)
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (ac_list[list_it].data[item_it] == form.username_value) {
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          form.username_element = ac_list[list_it].key;
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          break;
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bridge_->SetPasswordForm(form);
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid IEImporter::ImportPasswordsIE7() {
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!source_path_.empty()) {
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We have been called from the unit tests. Don't import real passwords.
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const wchar_t* kStorage2Path =
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"Software\\Microsoft\\Internet Explorer\\IntelliForms\\Storage2";
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::win::RegKey key(HKEY_CURRENT_USER, kStorage2Path, KEY_READ);
333513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::win::RegistryValueIterator reg_iterator(HKEY_CURRENT_USER,
334513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                                kStorage2Path);
33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  IE7PasswordInfo password_info;
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (reg_iterator.Valid() && !cancelled()) {
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Get the size of the encrypted data.
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DWORD value_len = 0;
33972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    key.ReadValue(reg_iterator.Name(), NULL, &value_len, NULL);
34072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (value_len) {
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Query the encrypted data.
34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      password_info.encrypted_data.resize(value_len);
34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (key.ReadValue(reg_iterator.Name(),
34472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        &password_info.encrypted_data.front(),
34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        &value_len, NULL) == ERROR_SUCCESS) {
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        password_info.url_hash = reg_iterator.Name();
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        password_info.date_created = base::Time::Now();
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        bridge_->AddIE7PasswordInfo(password_info);
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ++reg_iterator;
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid IEImporter::ImportSearchEngines() {
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On IE, search engines are stored in the registry, under:
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Software\Microsoft\Internet Explorer\SearchScopes
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Each key represents a search engine. The URL value contains the URL and
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the DisplayName the name.
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The default key's name is contained under DefaultScope.
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const wchar_t* kSearchScopePath =
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"Software\\Microsoft\\Internet Explorer\\SearchScopes";
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::win::RegKey key(HKEY_CURRENT_USER, kSearchScopePath, KEY_READ);
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring default_search_engine_name;
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const TemplateURL* default_search_engine = NULL;
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<std::string, TemplateURL*> search_engines_map;
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  key.ReadValue(L"DefaultScope", &default_search_engine_name);
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base::win::RegistryKeyIterator key_iterator(HKEY_CURRENT_USER,
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                              kSearchScopePath);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (key_iterator.Valid()) {
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::wstring sub_key_name = kSearchScopePath;
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    sub_key_name.append(L"\\").append(key_iterator.Name());
376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::win::RegKey sub_key(HKEY_CURRENT_USER, sub_key_name.c_str(),
377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              KEY_READ);
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::wstring wide_url;
37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if ((sub_key.ReadValue(L"URL", &wide_url) != ERROR_SUCCESS) ||
38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        wide_url.empty()) {
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      VLOG(1) << "No URL for IE search engine at " << key_iterator.Name();
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++key_iterator;
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // For the name, we try the default value first (as Live Search uses a
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // non displayable name in DisplayName, and the readable name under the
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // default value).
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::wstring name;
38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if ((sub_key.ReadValue(NULL, &name) != ERROR_SUCCESS) || name.empty()) {
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Try the displayable name.
39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if ((sub_key.ReadValue(L"DisplayName", &name) != ERROR_SUCCESS) ||
39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          name.empty()) {
393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        VLOG(1) << "No name for IE search engine at " << key_iterator.Name();
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ++key_iterator;
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string url(WideToUTF8(wide_url));
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::map<std::string, TemplateURL*>::iterator t_iter =
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        search_engines_map.find(url);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TemplateURL* template_url =
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (t_iter != search_engines_map.end()) ? t_iter->second : NULL;
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!template_url) {
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // First time we see that URL.
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      template_url = new TemplateURL();
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      template_url->set_short_name(name);
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      template_url->SetURL(url, 0, 0);
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Give this a keyword to facilitate tab-to-search, if possible.
410513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GURL gurl = GURL(url);
411513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      template_url->set_keyword(TemplateURLModel::GenerateKeyword(gurl,
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                                  false));
413513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      template_url->set_logo_id(
414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          TemplateURLPrepopulateData::GetSearchEngineLogo(gurl));
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      template_url->set_show_in_default_list(true);
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      search_engines_map[url] = template_url;
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (template_url && key_iterator.Name() == default_search_engine_name) {
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(!default_search_engine);
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default_search_engine = template_url;
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ++key_iterator;
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ProfileWriter::AddKeywords() requires a vector and we have a map.
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<std::string, TemplateURL*>::iterator t_iter;
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<TemplateURL*> search_engines;
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int default_search_engine_index = -1;
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (t_iter = search_engines_map.begin(); t_iter != search_engines_map.end();
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++t_iter) {
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    search_engines.push_back(t_iter->second);
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (default_search_engine == t_iter->second) {
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default_search_engine_index =
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          static_cast<int>(search_engines.size()) - 1;
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bridge_->SetKeywords(search_engines, default_search_engine_index, true);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid IEImporter::ImportHomepage() {
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const wchar_t* kIESettingsMain =
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"Software\\Microsoft\\Internet Explorer\\Main";
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const wchar_t* kIEHomepage = L"Start Page";
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const wchar_t* kIEDefaultHomepage = L"Default_Page_URL";
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
446513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::win::RegKey key(HKEY_CURRENT_USER, kIESettingsMain, KEY_READ);
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring homepage_url;
44872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (key.ReadValue(kIEHomepage, &homepage_url) != ERROR_SUCCESS ||
44972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      homepage_url.empty())
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL homepage = GURL(homepage_url);
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!homepage.is_valid())
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check to see if this is the default website and skip import.
457513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  base::win::RegKey keyDefault(HKEY_LOCAL_MACHINE, kIESettingsMain, KEY_READ);
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring default_homepage_url;
45972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LONG result = keyDefault.ReadValue(kIEDefaultHomepage, &default_homepage_url);
46072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (result == ERROR_SUCCESS && !default_homepage_url.empty()) {
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (homepage.spec() == GURL(default_homepage_url).spec())
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bridge_->AddHomePage(homepage);
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::wstring IEImporter::ResolveInternetShortcut(const std::wstring& file) {
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  app::win::ScopedCoMem<wchar_t> url;
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IUniformResourceLocator> url_locator;
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  HRESULT result = url_locator.CreateInstance(CLSID_InternetShortcut, NULL,
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                              CLSCTX_INPROC_SERVER);
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (FAILED(result))
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return std::wstring();
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::win::ScopedComPtr<IPersistFile> persist_file;
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result = persist_file.QueryFrom(url_locator);
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (FAILED(result))
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return std::wstring();
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Loads the Internet Shortcut from persistent storage.
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result = persist_file->Load(file.c_str(), STGM_READ);
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (FAILED(result))
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return std::wstring();
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  result = url_locator->GetURL(&url);
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // GetURL can return S_FALSE (FAILED(S_FALSE) is false) when url == NULL.
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (FAILED(result) || (url == NULL))
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return std::wstring();
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return std::wstring(url);
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool IEImporter::GetFavoritesInfo(IEImporter::FavoritesInfo* info) {
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!source_path_.empty()) {
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Source path exists during testing.
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->path = source_path_;
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    info->path = info->path.AppendASCII("Favorites");
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->links_folder = L"Links";
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // IE stores the favorites in the Favorites under user profile's folder.
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  wchar_t buffer[MAX_PATH];
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (FAILED(SHGetFolderPath(NULL, CSIDL_FAVORITES, NULL,
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             SHGFP_TYPE_CURRENT, buffer)))
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  info->path = FilePath(buffer);
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There is a Links folder under Favorites folder in Windows Vista, but it
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is not recording in Vista's registry. So in Vista, we assume the Links
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // folder is under Favorites folder since it looks like there is not name
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // different in every language version of Windows Vista.
514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (base::win::GetVersion() < base::win::VERSION_VISTA) {
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The Link folder name is stored in the registry.
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DWORD buffer_length = sizeof(buffer);
517513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::win::RegKey reg_key(HKEY_CURRENT_USER,
518513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        L"Software\\Microsoft\\Internet Explorer\\Toolbar", KEY_READ);
51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (reg_key.ReadValue(L"LinksFolderName", buffer,
52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          &buffer_length, NULL) != ERROR_SUCCESS)
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->links_folder = buffer;
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info->links_folder = L"Links";
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid IEImporter::ParseFavoritesFolder(const FavoritesInfo& info,
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      BookmarkVector* bookmarks) {
5323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  std::wstring ie_folder =
5333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_BOOKMARK_GROUP_FROM_IE));
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkVector toolbar_bookmarks;
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath file;
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<FilePath::StringType> file_list;
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath favorites_path(info.path);
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Favorites path length.  Make sure it doesn't include the trailing \.
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t favorites_path_len =
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      favorites_path.StripTrailingSeparators().value().size();
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::FileEnumerator file_enumerator(
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      favorites_path, true, file_util::FileEnumerator::FILES);
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (!(file = file_enumerator.Next()).value().empty() && !cancelled())
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_list.push_back(file.value());
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Keep the bookmarks in alphabetical order.
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::sort(file_list.begin(), file_list.end());
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<FilePath::StringType>::iterator it = file_list.begin();
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != file_list.end(); ++it) {
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath shortcut(*it);
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!LowerCaseEqualsASCII(shortcut.Extension(), ".url"))
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Skip the bookmark with invalid URL.
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url = GURL(ResolveInternetShortcut(*it));
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!url.is_valid())
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make the relative path from the Favorites folder, without the basename.
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // ex. Suppose that the Favorites folder is C:\Users\Foo\Favorites.
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //   C:\Users\Foo\Favorites\Foo.url -> ""
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //   C:\Users\Foo\Favorites\Links\Bar\Baz.url -> "Links\Bar"
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath::StringType relative_string =
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        shortcut.DirName().value().substr(favorites_path_len);
566dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!relative_string.empty() && FilePath::IsSeparator(relative_string[0]))
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      relative_string = relative_string.substr(1);
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath relative_path(relative_string);
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProfileWriter::BookmarkEntry entry;
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Remove the dot, the file extension, and the directory path.
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry.title = shortcut.RemoveExtension().BaseName().value();
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry.url = url;
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entry.creation_time = GetFileCreationTime(*it);
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!relative_path.empty())
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      relative_path.GetComponents(&entry.path);
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Flatten the bookmarks in Link folder onto bookmark toolbar. Otherwise,
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // put it into "Other bookmarks".
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (import_to_bookmark_bar() &&
581dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (!entry.path.empty() && entry.path[0] == info.links_folder)) {
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry.in_toolbar = true;
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry.path.erase(entry.path.begin());
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      toolbar_bookmarks.push_back(entry);
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We put the bookmarks in a "Imported From IE"
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // folder, so that we don't mess up the "Other bookmarks".
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!import_to_bookmark_bar())
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        entry.path.insert(entry.path.begin(), ie_folder);
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      bookmarks->push_back(entry);
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bookmarks->insert(bookmarks->begin(), toolbar_bookmarks.begin(),
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    toolbar_bookmarks.end());
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint IEImporter::CurrentIEVersion() const {
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static int version = -1;
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (version < 0) {
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wchar_t buffer[128];
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DWORD buffer_length = sizeof(buffer);
602513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::win::RegKey reg_key(HKEY_LOCAL_MACHINE,
603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        L"Software\\Microsoft\\Internet Explorer", KEY_READ);
60472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    LONG result = reg_key.ReadValue(L"Version", buffer, &buffer_length, NULL);
60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    version = ((result == ERROR_SUCCESS)? _wtoi(buffer) : 0);
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return version;
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
609