[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 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. |
| 4 | |
| 5 | #ifndef CHROME_FRAME_BUGGY_BHO_HANDLING_H_ |
| 6 | #define CHROME_FRAME_BUGGY_BHO_HANDLING_H_ |
| 7 | |
| 8 | #include <atlbase.h> |
| 9 | #include <atlcom.h> |
| 10 | #include <exdisp.h> |
| 11 | |
| 12 | #include <vector> |
| 13 | |
[email protected] | 1357c32 | 2010-12-30 22:18:56 | [diff] [blame] | 14 | #include "base/threading/thread_local.h" |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 15 | #include "base/win/scoped_comptr.h" |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 16 | |
| 17 | namespace buggy_bho { |
| 18 | |
| 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); |
| 24 | |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 25 | // Construct a per thread instance of this class before firing web browser |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 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 |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 28 | // as long as ChromeFrame is the active view. |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 29 | class BuggyBhoTls { |
| 30 | public: |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 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. |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 34 | // For each of those, a patch will be applied that temporarily ignores certain |
| 35 | // invokes. |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 36 | HRESULT PatchBuggyBHOs(IWebBrowser2* browser); |
| 37 | |
| 38 | // Returns the instance of the BuggyBhoTls object for the current thread. |
| 39 | static BuggyBhoTls* GetInstance(); |
| 40 | |
| 41 | // Destroys the BuggyBhoTls instance foe the current thread. |
| 42 | static void DestroyInstance(); |
| 43 | |
| 44 | void set_web_browser(IWebBrowser2* web_browser2) { |
| 45 | web_browser2_ = web_browser2; |
| 46 | } |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 47 | |
| 48 | protected: |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 49 | BuggyBhoTls(); |
| 50 | ~BuggyBhoTls(); |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 51 | // internal implementation: |
| 52 | |
| 53 | // Called when a buggy instance is found to be subscribing to browser events. |
| 54 | void AddBuggyObject(IDispatch* obj); |
| 55 | |
| 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. |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 61 | bool ShouldSkipInvoke(IDispatch* obj) const; |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 62 | |
| 63 | // Static, protected member methods |
| 64 | |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 65 | // Patches a subscriber if it belongs to a buggy dll. |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 66 | bool PatchIfBuggy(IUnknown* unk, const IID& diid); |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 67 | |
| 68 | // Patches the IDispatch::Invoke method. |
| 69 | static HRESULT PatchInvokeMethod(PROC* invoke); |
| 70 | |
| 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); |
| 77 | |
| 78 | protected: |
| 79 | // List of buggy subscribers. |
| 80 | std::vector<IDispatch*> bad_objects_; |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 81 | // Where we store the current thread's instance. |
| 82 | static base::ThreadLocalPointer<BuggyBhoTls> s_bad_object_tls_; |
[email protected] | a17930d8 | 2011-02-11 23:12:35 | [diff] [blame] | 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. |
| 86 | bool patched_; |
[email protected] | 5ae94d2 | 2010-07-21 19:55:36 | [diff] [blame] | 87 | }; |
| 88 | |
| 89 | } // end namespace buggy_bho |
| 90 | |
| 91 | #endif // CHROME_FRAME_BUGGY_BHO_HANDLING_H_ |