1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_FRAME_BHO_H_
#define CHROME_FRAME_BHO_H_
#include <atlbase.h>
#include <atlcom.h>
#include <exdisp.h>
#include <exdispid.h>
#include <mshtml.h>
#include <shdeprecated.h>
#include <string>
#include "base/lazy_instance.h"
#include "base/thread_local.h"
#include "chrome_tab.h" // NOLINT
#include "chrome_frame/resource.h"
#include "grit/chrome_frame_resources.h"
class PatchHelper {
public:
enum State { UNKNOWN, PATCH_IBROWSER, PATCH_PROTOCOL };
PatchHelper() : state_(UNKNOWN) {
}
State state() const {
return state_;
}
// Returns true if protocols were patched, false if patching has already
// been done.
bool InitializeAndPatchProtocolsIfNeeded();
void PatchBrowserService(IBrowserService* p);
void UnpatchIfNeeded();
protected:
State state_;
};
// Single global variable
extern PatchHelper g_patch_helper;
class ATL_NO_VTABLE Bho
: public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<Bho, &CLSID_ChromeFrameBHO>,
public IObjectWithSiteImpl<Bho>,
public IDispEventSimpleImpl<0, Bho, &DIID_DWebBrowserEvents2> {
public:
typedef HRESULT (STDMETHODCALLTYPE* IBrowserService_OnHttpEquiv_Fn)(
IBrowserService* browser, IShellView* shell_view, BOOL done,
VARIANT* in_arg, VARIANT* out_arg);
DECLARE_REGISTRY_RESOURCEID(IDR_BHO)
DECLARE_NOT_AGGREGATABLE(Bho)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(Bho)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()
BEGIN_SINK_MAP(Bho)
SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2,
BeforeNavigate2, &kBeforeNavigate2Info)
SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2,
NavigateComplete2, &kNavigateComplete2Info)
SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR,
OnNavigateError, &kNavigateErrorInfo)
END_SINK_MAP()
// Lifetime management methods
Bho();
HRESULT FinalConstruct();
void FinalRelease();
// IObjectWithSite
STDMETHODIMP SetSite(IUnknown* site);
STDMETHOD(BeforeNavigate2)(IDispatch* dispatch, VARIANT* url, VARIANT* flags,
VARIANT* target_frame_name, VARIANT* post_data, VARIANT* headers,
VARIANT_BOOL* cancel);
STDMETHOD_(void, NavigateComplete2)(IDispatch* dispatch, VARIANT* url);
STDMETHOD_(void, OnNavigateError)(IDispatch* dispatch, VARIANT* url,
VARIANT* frame_name, VARIANT* status_code,
VARIANT* cancel);
HRESULT NavigateToCurrentUrlInCF(IBrowserService* browser);
// mshtml sends an IOleCommandTarget::Exec of OLECMDID_HTTPEQUIV
// (and OLECMDID_HTTPEQUIV_DONE) as soon as it parses a meta tag.
// It also sends contents of the meta tag as an argument. IEFrame
// handles this in IBrowserService::OnHttpEquiv. So this allows
// us to sniff the META tag by simply patching it. The renderer
// switching can be achieved by cancelling original navigation
// and issuing a new one using IWebBrowser2->Navigate2.
static HRESULT STDMETHODCALLTYPE OnHttpEquiv(
IBrowserService_OnHttpEquiv_Fn original_httpequiv,
IBrowserService* browser, IShellView* shell_view, BOOL done,
VARIANT* in_arg, VARIANT* out_arg);
const std::string& referrer() const {
return referrer_;
}
const std::wstring& url() const {
return url_;
}
// Called from HttpNegotiatePatch::BeginningTransaction when a request is
// being issued. We check the url and headers and see if there is a referrer
// header that we need to cache.
void OnBeginningTransaction(IWebBrowser2* browser, const wchar_t* url,
const wchar_t* headers,
const wchar_t* additional_headers);
// Returns the Bho instance for the current thread. This is returned from
// TLS.
static Bho* GetCurrentThreadBhoInstance();
static void ProcessOptInUrls(IWebBrowser2* browser, BSTR url);
int pending_navigation_count() const {
return pending_navigation_count_;
}
protected:
bool PatchProtocolHandler(const CLSID& handler_clsid);
std::string referrer_;
std::wstring url_;
static base::LazyInstance<base::ThreadLocalPointer<Bho> >
bho_current_thread_instance_;
static _ATL_FUNC_INFO kBeforeNavigate2Info;
static _ATL_FUNC_INFO kNavigateComplete2Info;
static _ATL_FUNC_INFO kNavigateErrorInfo;
// This variable holds the pending navigation count seen by the BHO. It is
// incremented in BeforeNavigate2 and decremented in NavigateComplete2.
// Used to determine whether there are embedded frames loading for the
// current document.
int pending_navigation_count_;
};
#endif // CHROME_FRAME_BHO_H_
|