password_store_win.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_win.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_manager.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/webdata/web_data_service.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "components/webdata/encryptor/ie7_password_win.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using autofill::PasswordForm; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handles requests to WebDataService. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PasswordStoreWin::DBHandler : public WebDataServiceConsumer { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBHandler(WebDataService* web_data_service, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreWin* password_store) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : web_data_service_(web_data_service), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) password_store_(password_store) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DBHandler(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Requests the IE7 login for |form|. This is async. |callback_runner| will be 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // run when complete. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetIE7Login( 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordForm& form, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordStoreWin::ConsumerCallbackRunner& callback_runner); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct RequestInfo { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestInfo() {} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestInfo(PasswordForm* request_form, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordStoreWin::ConsumerCallbackRunner& runner) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : form(request_form), 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_runner(runner) {} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PasswordForm* form; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PasswordStoreWin::ConsumerCallbackRunner callback_runner; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Holds info associated with in-flight GetIE7Login requests. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<WebDataService::Handle, RequestInfo> PendingRequestMap; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets logins from IE7 if no others are found. Also copies them into 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome's WebDatabase so we don't need to look next time. 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::vector<autofill::PasswordForm*> GetIE7Results( 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const WDTypedResult* result, 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const PasswordForm& form); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebDataServiceConsumer implementation. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnWebDataServiceRequestDone( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebDataService::Handle handle, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WDTypedResult* result) OVERRIDE; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebDataService> web_data_service_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This creates a cycle between us and PasswordStore. The cycle is broken 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from PasswordStoreWin::Shutdown, which deletes us. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PasswordStoreWin> password_store_; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingRequestMap pending_requests_; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DBHandler); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStoreWin::DBHandler::~DBHandler() { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingRequestMap::const_iterator i = pending_requests_.begin(); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i != pending_requests_.end(); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++i) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_data_service_->CancelRequest(i->first); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete i->second.form; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PasswordStoreWin::DBHandler::GetIE7Login( 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordForm& form, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordStoreWin::ConsumerCallbackRunner& callback_runner) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IE7PasswordInfo info; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.url_hash = ie7_password::GetUrlHash(UTF8ToWide(form.origin.spec())); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebDataService::Handle handle = web_data_service_->GetIE7Login(info, this); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_requests_[handle] = 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RequestInfo(new PasswordForm(form), callback_runner); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::vector<PasswordForm*> PasswordStoreWin::DBHandler::GetIE7Results( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WDTypedResult *result, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PasswordForm& form) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::vector<PasswordForm*> matching_forms; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WDResult<IE7PasswordInfo>* r = 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const WDResult<IE7PasswordInfo>*>(result); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IE7PasswordInfo info = r->GetValue(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info.encrypted_data.empty()) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We got a result. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the entry. If it's good we will add it to the real saved password 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // table. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_data_service_->RemoveIE7Login(info); 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::vector<ie7_password::DecryptedCredentials> credentials; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring url = ASCIIToWide(form.origin.spec()); 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (ie7_password::DecryptPasswords(url, 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) info.encrypted_data, 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &credentials)) { 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < credentials.size(); ++i) { 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PasswordForm* autofill = new PasswordForm(form); 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) autofill->username_value = credentials[i].username; 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) autofill->password_value = credentials[i].password; 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) autofill->preferred = true; 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) autofill->ssl_valid = form.origin.SchemeIsSecure(); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) autofill->date_created = info.date_created; 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) matching_forms.push_back(autofill); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Add this PasswordForm to the saved password table. We're on the DB 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // thread already, so we use AddLoginImpl. 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) password_store_->AddLoginImpl(*autofill); 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return matching_forms; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::DBHandler::OnWebDataServiceRequestDone( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebDataService::Handle handle, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WDTypedResult* result) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PendingRequestMap::iterator i = pending_requests_.find(handle); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(i != pending_requests_.end()); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PasswordForm> form(i->second.form); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PasswordStoreWin::ConsumerCallbackRunner callback_runner( 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i->second.callback_runner); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.erase(i); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result) { 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The WDS returns NULL if it is shutting down. Run callback with empty 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // result. 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback_runner.Run(std::vector<autofill::PasswordForm*>()); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(PASSWORD_IE7_RESULT, result->GetType()); 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::vector<autofill::PasswordForm*> matched_forms = 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetIE7Results(result, *form); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_runner.Run(matched_forms); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStoreWin::PasswordStoreWin(LoginDatabase* login_database, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebDataService* web_data_service) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : PasswordStoreDefault(login_database, profile) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_handler_.reset(new DBHandler(web_data_service, this)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PasswordStoreWin::~PasswordStoreWin() { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::ShutdownOnDBThread() { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_handler_.reset(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PasswordStoreWin::ShutdownOnUIThread() { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DB, FROM_HERE, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PasswordStoreWin::ShutdownOnDBThread, this)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreDefault::ShutdownOnUIThread(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PasswordStoreWin::GetIE7LoginIfNecessary( 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordForm& form, 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ConsumerCallbackRunner& callback_runner, 18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::vector<autofill::PasswordForm*>& matched_forms) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (matched_forms.empty() && db_handler_.get()) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) db_handler_->GetIE7Login(form, callback_runner); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No need to get IE7 login. 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_runner.Run(matched_forms); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PasswordStoreWin::GetLoginsImpl( 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PasswordForm& form, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ConsumerCallbackRunner& callback_runner) { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConsumerCallbackRunner get_ie7_login = 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PasswordStoreWin::GetIE7LoginIfNecessary, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, form, callback_runner); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PasswordStoreDefault::GetLoginsImpl(form, get_ie7_login); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 205