Home | History | Annotate | Download | only in chrome_frame
      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 
     14 #include "base/threading/thread_local.h"
     15 #include "base/win/scoped_comptr.h"
     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 
     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.
     29 class BuggyBhoTls {
     30  public:
     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
     35   // invokes.
     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   }
     47 
     48  protected:
     49   BuggyBhoTls();
     50   ~BuggyBhoTls();
     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.
     61   bool ShouldSkipInvoke(IDispatch* obj) const;
     62 
     63   // Static, protected member methods
     64 
     65   // Patches a subscriber if it belongs to a buggy dll.
     66   bool PatchIfBuggy(IUnknown* unk, const IID& diid);
     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_;
     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.
     86   bool patched_;
     87 };
     88 
     89 }  // end namespace buggy_bho
     90 
     91 #endif  // CHROME_FRAME_BUGGY_BHO_HANDLING_H_
     92