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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
|
// 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_UTILS_H_
#define CHROME_FRAME_UTILS_H_
#include <atlbase.h>
#include <string>
#include <shdeprecated.h>
#include <urlmon.h>
#include "base/basictypes.h"
#include "base/histogram.h"
#include "base/lock.h"
#include "base/logging.h"
#include "base/thread.h"
// utils.h : Various utility functions and classes
extern const wchar_t kChromeContentPrefix[];
extern const wchar_t kChromeProtocolPrefix[];
extern const wchar_t kChromeFrameHeadlessMode[];
extern const wchar_t kEnableGCFProtocol[];
// This function is very similar to the AtlRegisterTypeLib function except
// that it takes a parameter that specifies whether to register the typelib
// for the current user only or on a machine-wide basis
// Refer to the MSDN documentation for AtlRegisterTypeLib for a description of
// the arguments
HRESULT UtilRegisterTypeLib(HINSTANCE tlb_instance,
LPCOLESTR index,
bool for_current_user_only);
// This function is very similar to the AtlUnRegisterTypeLib function except
// that it takes a parameter that specifies whether to unregister the typelib
// for the current user only or on a machine-wide basis
// Refer to the MSDN documentation for AtlUnRegisterTypeLib for a description
// of the arguments
HRESULT UtilUnRegisterTypeLib(HINSTANCE tlb_instance,
LPCOLESTR index,
bool for_current_user_only);
HRESULT UtilRegisterTypeLib(LPCWSTR typelib_path, bool for_current_user_only);
HRESULT UtilUnRegisterTypeLib(LPCWSTR typelib_path, bool for_current_user_only);
HRESULT UtilRegisterTypeLib(ITypeLib* typelib,
LPCWSTR typelib_path,
LPCWSTR help_dir,
bool for_current_user_only);
HRESULT UtilUnRegisterTypeLib(ITypeLib* typelib,
bool for_current_user_only);
// Utility function to tell if the NPAPI plugin is registered.
bool UtilIsNPAPIPluginRegistered();
// Sets or clears a marker that causes NPAPI registration to persist across
// updates. The marker is added if set is true and is deleted otherwise.
bool UtilChangePersistentNPAPIMarker(bool set);
// Returns true if the persistent NPAPI marker is set, false otherwise.
bool UtilIsPersistentNPAPIMarkerSet();
// Given an HTML fragment, this function looks for the
// <meta http-equiv="X-UA-Compatible"> tag and extracts the value of the
// "content" attribute
// This method will currently return a false positive if the tag appears
// inside a string in a <SCRIPT> block.
HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string,
std::wstring* content_value);
// Returns a string from ChromeFrame's string table by resource. Must be
// provided with a valid resource id.
std::wstring GetResourceString(int resource_id);
// Displays a message box indicating that there was a version mismatch between
// ChromeFrame and the running instance of Chrome.
// server_version is the version of the running instance of Chrome.
void DisplayVersionMismatchWarning(HWND parent,
const std::string& server_version);
// This class provides a base implementation for ATL modules which want to
// perform all their registration under HKCU. This class overrides the
// RegisterServer and UnregisterServer methods and registers the type libraries
// under HKCU (the rest of the registation is made under HKCU by changing the
// appropriate .RGS files)
template < class BaseAtlModule >
class AtlPerUserModule : public BaseAtlModule {
public:
HRESULT RegisterServer(BOOL reg_typelib = FALSE,
const CLSID* clsid = NULL) throw() {
HRESULT hr = BaseAtlModule::RegisterServer(FALSE, clsid);
if (FAILED(hr)) {
return hr;
}
if (reg_typelib) {
hr = UtilRegisterTypeLib(_AtlComModule.m_hInstTypeLib, NULL, false);
}
return hr;
}
HRESULT UnregisterServer(BOOL unreg_typelib,
const CLSID* clsid = NULL) throw() {
HRESULT hr = BaseAtlModule::UnregisterServer(FALSE, clsid);
if (FAILED(hr)) {
return hr;
}
if (unreg_typelib) {
hr = UtilUnRegisterTypeLib(_AtlComModule.m_hInstTypeLib, NULL, false);
}
return hr;
}
};
// Creates a javascript statement for execution from the function name and
// arguments passed in.
std::string CreateJavascript(const std::string& function_name,
const std::string args);
// Use to prevent the DLL from being unloaded while there are still living
// objects with outstanding references.
class AddRefModule {
public:
AddRefModule();
~AddRefModule();
};
// Retrieves the executable name of the process hosting us. If
// |include_extension| is false, then we strip the extension from the name.
std::wstring GetHostProcessName(bool include_extension);
typedef enum BrowserType {
BROWSER_INVALID = -1,
BROWSER_UNKNOWN,
BROWSER_IE,
BROWSER_FIREFOX,
BROWSER_OPERA,
};
BrowserType GetBrowserType();
typedef enum IEVersion {
IE_INVALID,
NON_IE,
IE_UNSUPPORTED,
IE_6,
IE_7,
IE_8,
};
// To get the IE version when Chrome Frame is hosted in IE. Make sure that
// the hosting browser is IE before calling this function, otherwise NON_IE
// will be returned.
IEVersion GetIEVersion();
// Retrieves the file version from a module handle without extra round trips
// to the disk (as happens with the regular GetFileVersionInfo API).
//
// @param module A handle to the module for which to retrieve the version info.
// @param high On successful return holds the most significant part of the
// file version. Must be non-null.
// @param low On successful return holds the least significant part of the
// file version. May be NULL.
// @returns true if the version info was successfully retrieved.
bool GetModuleVersion(HMODULE module, uint32* high, uint32* low);
// Return if the IEXPLORE is in private mode. The IEIsInPrivateBrowsing() checks
// whether current process is IEXPLORE.
bool IsIEInPrivate();
// Calls [ieframe|shdocvw]!DoFileDownload to initiate a download.
HRESULT DoFileDownloadInIE(const wchar_t* url);
// Creates a copy of a menu. We need this when original menu comes from
// a process with higher integrity.
HMENU UtilCloneContextMenu(HMENU original_menu);
// Uses GURL internally to append 'relative' to 'document'
std::string ResolveURL(const std::string& document,
const std::string& relative);
// Returns true iff the two urls have the same scheme, same host and same port.
bool HaveSameOrigin(const std::string& url1, const std::string& url2);
// Get a boolean configuration value from registry.
bool GetConfigBool(bool default_value, const wchar_t* value_name);
// Gets an integer configuration value from the registry.
int GetConfigInt(int default_value, const wchar_t* value_name);
// Sets an integer configuration value in the registry.
bool SetConfigInt(const wchar_t* value_name, int value);
// Sets a boolean integer configuration value in the registry.
bool SetConfigBool(const wchar_t* value_name, bool value);
// Deletes the configuration value passed in.
bool DeleteConfigValue(const wchar_t* value_name);
// Returns true if we are running in headless mode in which case we need to
// gather crash dumps, etc to send them to the crash server.
bool IsHeadlessMode();
// Check if this url is opting into Chrome Frame based on static settings.
bool IsOptInUrl(const wchar_t* url);
// A shortcut for QueryService
template <typename T>
HRESULT DoQueryService(const IID& service_id, IUnknown* unk, T** service) {
DCHECK(service);
if (!unk)
return E_INVALIDARG;
ScopedComPtr<IServiceProvider> service_provider;
HRESULT hr = service_provider.QueryFrom(unk);
if (!service_provider)
return E_NOINTERFACE;
hr = service_provider->QueryService(service_id, service);
if (*service == NULL)
return E_NOINTERFACE;
return hr;
}
// Get url (display name) from a moniker, |bind_context| is optional
HRESULT GetUrlFromMoniker(IMoniker* moniker, IBindCtx* bind_context,
std::wstring* url);
// Navigates an IWebBrowser2 object to a moniker.
// |headers| can be NULL.
HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
const wchar_t* headers, IBindCtx* bind_ctx,
const wchar_t* fragment);
// Raises a flag on the current thread (using TLS) to indicate that an
// in-progress navigation should be rendered in chrome frame.
void MarkBrowserOnThreadForCFNavigation(IBrowserService* browser);
// Checks if this browser instance has been marked as currently navigating
// to a CF document. If clear_flag is set to true, the tls flag is cleared but
// only if the browser has been marked.
bool CheckForCFNavigation(IBrowserService* browser, bool clear_flag);
// Returns true if the URL passed in is something which can be handled by
// Chrome. If this function returns false then we should fail the navigation.
// When is_privileged is true, chrome extension URLs will be considered valid.
bool IsValidUrlScheme(const std::wstring& url, bool is_privileged);
// Returns the raw http headers for the current request given an
// IWinInetHttpInfo pointer.
std::string GetRawHttpHeaders(IWinInetHttpInfo* info);
// Can be used to determine whether a given request is being performed for
// a sub-frame or iframe in Internet Explorer. This can be called
// from various places, notably in request callbacks and the like.
//
// |service_provider| must not be NULL and should be a pointer to something
// that implements IServiceProvider (if it isn't this method returns false).
//
// Returns true if this method can determine with some certainty that the
// request did NOT originate from a top level frame, returns false otherwise.
bool IsSubFrameRequest(IUnknown* service_provider);
// See COM_INTERFACE_BLIND_DELEGATE below for details.
template <class T>
STDMETHODIMP CheckOutgoingInterface(void* obj, REFIID iid, void** ret,
DWORD cookie) {
T* instance = reinterpret_cast<T*>(obj);
HRESULT hr = E_NOINTERFACE;
IUnknown* delegate = instance ? instance->delegate() : NULL;
if (delegate) {
hr = delegate->QueryInterface(iid, ret);
#if !defined(NDEBUG)
if (SUCCEEDED(hr)) {
wchar_t iid_string[64] = {0};
StringFromGUID2(iid, iid_string, arraysize(iid_string));
DLOG(INFO) << __FUNCTION__ << " Giving out wrapped interface: "
<< iid_string;
}
#endif
}
return hr;
}
// See COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS below for details.
template <class T>
STDMETHODIMP QueryInterfaceIfDelegateSupports(void* obj, REFIID iid,
void** ret, DWORD cookie) {
HRESULT hr = E_NOINTERFACE;
T* instance = reinterpret_cast<T*>(obj);
IUnknown* delegate = instance ? instance->delegate() : NULL;
if (delegate) {
ScopedComPtr<IUnknown> original;
hr = delegate->QueryInterface(iid,
reinterpret_cast<void**>(original.Receive()));
if (original) {
IUnknown* supported_interface = reinterpret_cast<IUnknown*>(
reinterpret_cast<DWORD_PTR>(obj) + cookie);
supported_interface->AddRef();
*ret = supported_interface;
hr = S_OK;
}
}
return hr;
}
// Same as COM_INTERFACE_ENTRY but relies on the class to implement a
// delegate() method that returns a pointer to the delegated COM object.
#define COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(x) \
COM_INTERFACE_ENTRY_FUNC(_ATL_IIDOF(x), \
offsetofclass(x, _ComMapClass), \
QueryInterfaceIfDelegateSupports<_ComMapClass>)
// Queries the delegated COM object for an interface, bypassing the wrapper.
#define COM_INTERFACE_BLIND_DELEGATE() \
COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface<_ComMapClass>)
// Thread that enters STA and has a UI message loop.
class STAThread : public base::Thread {
public:
explicit STAThread(const char *name) : Thread(name) {}
bool Start() {
return StartWithOptions(Options(MessageLoop::TYPE_UI, 0));
}
protected:
// Called just prior to starting the message loop
virtual void Init() {
::CoInitialize(0);
}
// Called just after the message loop ends
virtual void CleanUp() {
::CoUninitialize();
}
};
std::wstring GuidToString(const GUID& guid);
// The urls retrieved from the IMoniker interface don't contain the anchor
// portion of the actual url navigated to. This function checks whether the
// url passed in the bho_url parameter contains an anchor and if yes checks
// whether it matches the url retrieved from the moniker. If yes it returns
// the bho url, if not the moniker url.
std::wstring GetActualUrlFromMoniker(IMoniker* moniker,
IBindCtx* bind_context,
const std::wstring& bho_url);
// Checks if a window is a top level window
bool IsTopLevelWindow(HWND window);
extern Lock g_ChromeFrameHistogramLock;
// Thread safe versions of the UMA histogram macros we use for ChromeFrame.
// These should be used for histograms in ChromeFrame. If other histogram
// macros from base/histogram.h are needed then thread safe versions of those
// should be defined and used.
#define THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, \
bucket_count) { \
AutoLock lock(g_ChromeFrameHistogramLock); \
UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count); \
}
#define THREAD_SAFE_UMA_HISTOGRAM_TIMES(name, sample) { \
AutoLock lock(g_ChromeFrameHistogramLock); \
UMA_HISTOGRAM_TIMES(name, sample); \
}
#endif // CHROME_FRAME_UTILS_H_
|