1// Copyright (c) 2011 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_BHO_H_
6#define CHROME_FRAME_BHO_H_
7
8#include <atlbase.h>
9#include <atlcom.h>
10#include <deletebrowsinghistory.h>
11#include <exdisp.h>
12#include <exdispid.h>
13#include <mshtml.h>
14#include <shdeprecated.h>
15
16#include <string>
17
18#include "chrome_frame/chrome_tab.h"
19#include "chrome_frame/delete_chrome_history.h"
20#include "chrome_frame/resource.h"
21#include "chrome_frame/urlmon_moniker.h"
22#include "chrome_frame/urlmon_url_request.h"
23#include "grit/chrome_frame_resources.h"
24
25class DeleteChromeHistory;
26
27class PatchHelper {
28 public:
29  enum State { UNKNOWN, PATCH_IBROWSER, PATCH_PROTOCOL, PATCH_MONIKER };
30  PatchHelper() : state_(UNKNOWN) {
31  }
32
33  State state() const {
34    return state_;
35  }
36
37  // Returns true if protocols were patched, false if patching has already
38  // been done.
39  bool InitializeAndPatchProtocolsIfNeeded();
40
41  void PatchBrowserService(IBrowserService* p);
42  void UnpatchIfNeeded();
43 protected:
44  State state_;
45};
46
47// Single global variable
48extern PatchHelper g_patch_helper;
49
50class ATL_NO_VTABLE Bho
51    : public CComObjectRootEx<CComSingleThreadModel>,
52      public CComCoClass<Bho, &CLSID_ChromeFrameBHO>,
53      public IObjectWithSiteImpl<Bho>,
54      public IDispEventSimpleImpl<0, Bho, &DIID_DWebBrowserEvents2>,
55      public NavigationManager {
56 public:
57  typedef HRESULT (STDMETHODCALLTYPE* IBrowserService_OnHttpEquiv_Fn)(
58      IBrowserService* browser, IShellView* shell_view, BOOL done,
59      VARIANT* in_arg, VARIANT* out_arg);
60
61DECLARE_GET_CONTROLLING_UNKNOWN()
62DECLARE_REGISTRY_RESOURCEID(IDR_BHO)
63DECLARE_NOT_AGGREGATABLE(Bho)
64DECLARE_PROTECT_FINAL_CONSTRUCT()
65
66BEGIN_COM_MAP(Bho)
67  COM_INTERFACE_ENTRY(IObjectWithSite)
68  // When calling DeleteChromeHistory, ensure that only one instance
69  // is created to avoid mulitple message loops.
70  COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(IID_IDeleteBrowsingHistory,
71                                      DeleteChromeHistory,
72                                      delete_chrome_history_.p)
73END_COM_MAP()
74
75BEGIN_SINK_MAP(Bho)
76  SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2,
77                  BeforeNavigate2, &kBeforeNavigate2Info)
78  SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2,
79                  NavigateComplete2, &kNavigateComplete2Info)
80  SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE,
81                  DocumentComplete, &kDocumentCompleteInfo)
82END_SINK_MAP()
83
84  Bho();
85
86  HRESULT FinalConstruct();
87  void FinalRelease();
88
89  // IObjectWithSite
90  STDMETHODIMP SetSite(IUnknown* site);
91
92  // WebBrowser2 event sinks.
93  STDMETHOD(BeforeNavigate2)(IDispatch* dispatch, VARIANT* url, VARIANT* flags,
94      VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers,
95      VARIANT_BOOL* cancel);
96  STDMETHOD_(void, NavigateComplete2)(IDispatch* dispatch, VARIANT* url);
97  STDMETHOD_(void, DocumentComplete)(IDispatch* dispatch, VARIANT* url);
98
99  // mshtml sends an IOleCommandTarget::Exec of OLECMDID_HTTPEQUIV
100  // (and OLECMDID_HTTPEQUIV_DONE) as soon as it parses a meta tag.
101  // It also sends contents of the meta tag as an argument. IEFrame
102  // handles this in IBrowserService::OnHttpEquiv.  So this allows
103  // us to sniff the META tag by simply patching it. The renderer
104  // switching can be achieved by canceling original navigation
105  // and issuing a new one using IWebBrowser2->Navigate2.
106  static HRESULT STDMETHODCALLTYPE OnHttpEquiv(
107      IBrowserService_OnHttpEquiv_Fn original_httpequiv,
108      IBrowserService* browser, IShellView* shell_view, BOOL done,
109      VARIANT* in_arg, VARIANT* out_arg);
110
111  static void ProcessOptInUrls(IWebBrowser2* browser, BSTR url);
112
113  // COM_INTERFACE_ENTRY_CACHED_TEAR_OFF manages the raw pointer from CComPtr
114  // which base::win::ScopedComPtr doesn't expose.
115  CComPtr<IUnknown> delete_chrome_history_;
116
117 protected:
118  bool PatchProtocolHandler(const CLSID& handler_clsid);
119
120  static _ATL_FUNC_INFO kBeforeNavigate2Info;
121  static _ATL_FUNC_INFO kNavigateComplete2Info;
122  static _ATL_FUNC_INFO kDocumentCompleteInfo;
123};
124
125#endif  // CHROME_FRAME_BHO_H_
126