diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-30 15:34:11 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-30 15:34:11 +0000 |
commit | 9ceda77323dcc335680d3cb47b0b76e2821199ad (patch) | |
tree | f5280e2a394d7d66a035b57d2c6b835bcbd7057b /chrome_frame/bho_loader.cc | |
parent | cf993864f9e684fb2e58f5b89d669ae680feefd9 (diff) | |
download | chromium_src-9ceda77323dcc335680d3cb47b0b76e2821199ad.zip chromium_src-9ceda77323dcc335680d3cb47b0b76e2821199ad.tar.gz chromium_src-9ceda77323dcc335680d3cb47b0b76e2821199ad.tar.bz2 |
Add a helper process to Chrome Frame to allow for non-administrative installs. The helper process registers a hook dll that performs the necessary BHO injection instead of registering it in HKLM.
BUG=53127
TEST=Non-admin CF installs work.
Review URL: http://codereview.chromium.org/3158036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57860 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/bho_loader.cc')
-rw-r--r-- | chrome_frame/bho_loader.cc | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/chrome_frame/bho_loader.cc b/chrome_frame/bho_loader.cc new file mode 100644 index 0000000..fb8f71d --- /dev/null +++ b/chrome_frame/bho_loader.cc @@ -0,0 +1,93 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome_frame/bho_loader.h" + +#include <atlbase.h> +#include <atlcomcli.h> +#include <exdisp.h> + +#include "chrome_frame/chrome_frame_helper_util.h" +#include "chrome_frame/event_hooker.h" +#include "chrome_tab.h" // NOLINT + + +// Describes the window class we look for. +const wchar_t kStatusBarWindowClass[] = L"msctls_statusbar32"; + +BHOLoader::BHOLoader() : hooker_(new EventHooker()) { +} + +BHOLoader::~BHOLoader() { + if (hooker_) { + delete hooker_; + hooker_ = NULL; + } +} + +void BHOLoader::OnHookEvent(DWORD event, HWND window) { + // Step 1: Make sure that we are in a process named iexplore.exe. + if (IsNamedProcess(L"iexplore.exe")) { + // Step 2: Check to see if the window is of the right class. + // IE loads BHOs in the WM_CREATE handler of the tab window approximately + // after it creates the status bar window. To be as close to IE as possible + // in our simulation on BHO loading, we watch for the status bar to be + // created and do our simulated BHO loading at that time. + if (IsWindowOfClass(window, kStatusBarWindowClass)) { + HWND parent_window = GetParent(window); + // Step 3: + // Parent window of status bar window is the web browser window. Try to + // get its IWebBrowser2 interface + CComPtr<IWebBrowser2> browser; + UtilGetWebBrowserObjectFromWindow(parent_window, __uuidof(browser), + reinterpret_cast<void**>(&browser)); + if (browser) { + // TODO(robertshield): We may need to find a way to prevent doing this + // twice. A marker of some kind would do. Ask during review for good + // suggestions. + + // Step 4: + // We have the IWebBrowser2 interface. Now create the BHO instance + CComPtr<IObjectWithSite> bho_object; + HRESULT error_code = bho_object.CoCreateInstance(CLSID_ChromeFrameBHO, + NULL, + CLSCTX_INPROC_SERVER); + + if (SUCCEEDED(error_code) && bho_object) { + // Step 5: + // Initialize the BHO by calling SetSite and passing it IWebBrowser2 + error_code = bho_object->SetSite(browser); + if (SUCCEEDED(error_code)) { + // Step 6: + // Now add the BHO to the collection of automation objects. This + // will ensure that BHO will be accessible from the web pages as + // any other BHO. Importantly, it will make sure that our BHO + // will be cleaned up at the right time along with other BHOs. + wchar_t bho_clsid_as_string[MAX_PATH] = {0}; + StringFromGUID2(CLSID_ChromeFrameBHO, bho_clsid_as_string, + ARRAYSIZE(bho_clsid_as_string)); + + CComBSTR bho_clsid_as_string_bstr(bho_clsid_as_string); + CComVariant object_variant(bho_object); + + browser->PutProperty(bho_clsid_as_string_bstr, object_variant); + } + } + } + } + } +} + +bool BHOLoader::StartHook() { + return hooker_->StartHook(); +} + +void BHOLoader::StopHook() { + hooker_->StopHook(); +} + +BHOLoader* BHOLoader::GetInstance() { + static BHOLoader loader; + return &loader; +} |