diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-07 18:30:08 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-07 18:30:08 +0000 |
commit | 4c01d63e2eb3402666b679d5a797c8e5ca66ce79 (patch) | |
tree | 8990649609ae15097f75b77c1ae22f3817aa823f | |
parent | 43807e2f8ecee21ff873d68f0fb58a3ff06caaf2 (diff) | |
download | chromium_src-4c01d63e2eb3402666b679d5a797c8e5ca66ce79.zip chromium_src-4c01d63e2eb3402666b679d5a797c8e5ca66ce79.tar.gz chromium_src-4c01d63e2eb3402666b679d5a797c8e5ca66ce79.tar.bz2 |
Prevent double loading of the Chrome Frame BHO when using the user-level injection technique.
BUG=53127
TEST=With two chrome_frame_helper.exe processes running, only a single BHO instance is created and SetSite is only called on the BHO once.
Review URL: http://codereview.chromium.org/3338011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58723 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/bho_loader.cc | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/chrome_frame/bho_loader.cc b/chrome_frame/bho_loader.cc index fb8f71d..d0d94ff 100644 --- a/chrome_frame/bho_loader.cc +++ b/chrome_frame/bho_loader.cc @@ -35,6 +35,10 @@ void BHOLoader::OnHookEvent(DWORD event, HWND window) { // 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)) { + // Check that the window was created on the current thread. + DWORD thread_id = GetWindowThreadProcessId(window, NULL); + _ASSERTE(thread_id == GetCurrentThreadId()); + HWND parent_window = GetParent(window); // Step 3: // Parent window of status bar window is the web browser window. Try to @@ -43,35 +47,39 @@ void BHOLoader::OnHookEvent(DWORD event, HWND window) { 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); + // Figure out if we're already in the property map. + 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); - 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)); + CComVariant existing_bho; + HRESULT hr = browser->GetProperty(bho_clsid_as_string_bstr, + &existing_bho); - CComBSTR bho_clsid_as_string_bstr(bho_clsid_as_string); - CComVariant object_variant(bho_object); + if (existing_bho.vt != VT_DISPATCH || existing_bho.pdispVal == NULL) { + // Step 4: + // We have the IWebBrowser2 interface. Now create the BHO instance + CComPtr<IObjectWithSite> bho_object; + hr = bho_object.CoCreateInstance(CLSID_ChromeFrameBHO, + NULL, + CLSCTX_INPROC_SERVER); - browser->PutProperty(bho_clsid_as_string_bstr, object_variant); + _ASSERTE(bho_object); + if (SUCCEEDED(hr) && bho_object) { + // Step 5: + // Initialize the BHO by calling SetSite and passing it IWebBrowser2 + hr = bho_object->SetSite(browser); + _ASSERTE(bho_object); + if (SUCCEEDED(hr)) { + // 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. + CComVariant object_variant(bho_object); + browser->PutProperty(bho_clsid_as_string_bstr, object_variant); + } } } } |