1 // Copyright (c) 2010 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.
5 #ifndef CHROME_FRAME_BUGGY_BHO_HANDLING_H_
6 #define CHROME_FRAME_BUGGY_BHO_HANDLING_H_
14 #include "base/threading/thread_local.h"
15 #include "base/win/scoped_comptr.h"
19 // Method prototype for IDispatch::Invoke.
20 typedef HRESULT (__stdcall
* InvokeFunc
)(IDispatch
* me
, DISPID dispid
,
21 REFIID riid
, LCID lcid
, WORD flags
,
22 DISPPARAMS
* params
, VARIANT
* result
,
23 EXCEPINFO
* ei
, UINT
* err
);
25 // Construct a per thread instance of this class before firing web browser
26 // events that can be sent to buggy BHOs. This class will intercept those
27 // BHOs (see list in cc file) and ignore notifications to those components
28 // as long as ChromeFrame is the active view.
31 // This method traverses the list of DWebBrowserEvents and DWebBrowserEvents2
32 // subscribers and checks if any of the sinks belong to a list of
33 // known-to-be-buggy BHOs.
34 // For each of those, a patch will be applied that temporarily ignores certain
36 HRESULT
PatchBuggyBHOs(IWebBrowser2
* browser
);
38 // Returns the instance of the BuggyBhoTls object for the current thread.
39 static BuggyBhoTls
* GetInstance();
41 // Destroys the BuggyBhoTls instance foe the current thread.
42 static void DestroyInstance();
44 void set_web_browser(IWebBrowser2
* web_browser2
) {
45 web_browser2_
= web_browser2
;
51 // internal implementation:
53 // Called when a buggy instance is found to be subscribing to browser events.
54 void AddBuggyObject(IDispatch
* obj
);
56 // Called from our patch to check if calls for this object should be ignored.
57 // The reason we do this check is because there might be more than one browser
58 // object running on the same thread (e.g. IE6) with one running CF and the
59 // other MSHTML. We don't want to drop events being fired by MSHTML, only
60 // events fired by CF since these BHOs should handle MSHTML correctly.
61 bool ShouldSkipInvoke(IDispatch
* obj
) const;
63 // Static, protected member methods
65 // Patches a subscriber if it belongs to a buggy dll.
66 bool PatchIfBuggy(IUnknown
* unk
, const IID
& diid
);
68 // Patches the IDispatch::Invoke method.
69 static HRESULT
PatchInvokeMethod(PROC
* invoke
);
71 // This is our substitute function that is called instead of the buggy DLLs.
72 // Here we call IsBuggyObject to check if we should ignore invokes or allow
73 // them to go through.
74 static STDMETHODIMP
BuggyBhoInvoke(InvokeFunc original
, IDispatch
* me
,
75 DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
, DISPPARAMS
* params
,
76 VARIANT
* result
, EXCEPINFO
* ei
, UINT
* err
);
79 // List of buggy subscribers.
80 std::vector
<IDispatch
*> bad_objects_
;
81 // Where we store the current thread's instance.
82 static base::ThreadLocalPointer
<BuggyBhoTls
> s_bad_object_tls_
;
83 // The IWebBrowser2 instance for this thread.
84 base::win::ScopedComPtr
<IWebBrowser2
> web_browser2_
;
85 // Set to true when we are done patching the event sinks of buggy bho's.
89 } // end namespace buggy_bho
91 #endif // CHROME_FRAME_BUGGY_BHO_HANDLING_H_