Add character encoding to Font Settings Extension API.
[chromium-blink-merge.git] / chrome_frame / utils.h
blobd9f65804c467d4a5a5098c87cf05099794cf822f
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_FRAME_UTILS_H_
6 #define CHROME_FRAME_UTILS_H_
8 #include <OAidl.h>
9 #include <objidl.h>
10 #include <windows.h>
11 #include <wininet.h>
12 #include <string>
13 #include <vector>
15 #include "base/basictypes.h"
16 #include "base/logging.h"
17 #include "base/metrics/histogram.h"
18 #include "base/string16.h"
19 #include "base/threading/thread.h"
20 #include "base/win/scoped_comptr.h"
21 #include "googleurl/src/gurl.h"
22 #include "ui/gfx/rect.h"
24 class FilePath;
25 class RegistryListPreferencesHolder;
26 interface IBrowserService;
27 interface IWebBrowser2;
28 struct ContextMenuModel;
30 // utils.h : Various utility functions and classes
31 extern const char kGCFProtocol[];
33 extern const wchar_t kAllowUnsafeURLs[];
34 extern const wchar_t kChromeContentPrefix[];
35 extern const wchar_t kChromeFrameAccessibleMode[];
36 extern const wchar_t kChromeFrameAttachTabPattern[];
37 extern const wchar_t kChromeFrameConfigKey[];
38 extern const wchar_t kChromeFrameHeadlessMode[];
39 extern const wchar_t kChromeFrameUnpinnedMode[];
40 extern const wchar_t kChromeMimeType[];
41 extern const wchar_t kChromeProtocolPrefix[];
42 extern const wchar_t kEnableBuggyBhoIntercept[];
43 extern const wchar_t kEnableGCFRendererByDefault[];
44 extern const wchar_t kExcludeUAFromDomainList[];
45 extern const wchar_t kIexploreProfileName[];
46 extern const wchar_t kRenderInGCFUrlList[];
47 extern const wchar_t kRenderInHostUrlList[];
48 extern const wchar_t kRundllProfileName[];
49 extern const wchar_t kUseBackgroundThreadForSubResources[];
51 // This function is very similar to the AtlRegisterTypeLib function except
52 // that it takes a parameter that specifies whether to register the typelib
53 // for the current user only or on a machine-wide basis
54 // Refer to the MSDN documentation for AtlRegisterTypeLib for a description of
55 // the arguments
56 HRESULT UtilRegisterTypeLib(HINSTANCE tlb_instance,
57 LPCOLESTR index,
58 bool for_current_user_only);
60 // This function is very similar to the AtlUnRegisterTypeLib function except
61 // that it takes a parameter that specifies whether to unregister the typelib
62 // for the current user only or on a machine-wide basis
63 // Refer to the MSDN documentation for AtlUnRegisterTypeLib for a description
64 // of the arguments
65 HRESULT UtilUnRegisterTypeLib(HINSTANCE tlb_instance,
66 LPCOLESTR index,
67 bool for_current_user_only);
69 HRESULT UtilRegisterTypeLib(LPCWSTR typelib_path, bool for_current_user_only);
71 HRESULT UtilUnRegisterTypeLib(LPCWSTR typelib_path, bool for_current_user_only);
73 HRESULT UtilRegisterTypeLib(ITypeLib* typelib,
74 LPCWSTR typelib_path,
75 LPCWSTR help_dir,
76 bool for_current_user_only);
78 HRESULT UtilUnRegisterTypeLib(ITypeLib* typelib,
79 bool for_current_user_only);
81 // Clears a marker that causes legacy NPAPI registration to persist across
82 // updates. Returns false if the marker could not be removed.
83 bool UtilRemovePersistentNPAPIMarker();
85 // Given an HTML fragment, this function looks for the
86 // <meta http-equiv="X-UA-Compatible"> tag and extracts the value of the
87 // "content" attribute
88 // This method will currently return a false positive if the tag appears
89 // inside a string in a <SCRIPT> block.
90 HRESULT UtilGetXUACompatContentValue(const std::wstring& html_string,
91 std::wstring* content_value);
93 // Returns a string from ChromeFrame's string table by resource. Must be
94 // provided with a valid resource id.
95 std::wstring GetResourceString(int resource_id);
97 // Displays a message box indicating that there was a version mismatch between
98 // ChromeFrame and the running instance of Chrome.
99 // server_version is the version of the running instance of Chrome.
100 void DisplayVersionMismatchWarning(HWND parent,
101 const std::string& server_version);
103 // This class provides a base implementation for ATL modules which want to
104 // perform all their registration under HKCU. This class overrides the
105 // RegisterServer and UnregisterServer methods and registers the type libraries
106 // under HKCU (the rest of the registration is made under HKCU by changing the
107 // appropriate .RGS files)
108 template < class BaseAtlModule >
109 class AtlPerUserModule : public BaseAtlModule {
110 public:
111 HRESULT RegisterServer(BOOL reg_typelib = FALSE,
112 const CLSID* clsid = NULL) throw() {
113 HRESULT hr = BaseAtlModule::RegisterServer(FALSE, clsid);
114 if (FAILED(hr)) {
115 return hr;
117 if (reg_typelib) {
118 hr = UtilRegisterTypeLib(_AtlComModule.m_hInstTypeLib, NULL, false);
120 return hr;
123 HRESULT UnregisterServer(BOOL unreg_typelib,
124 const CLSID* clsid = NULL) throw() {
125 HRESULT hr = BaseAtlModule::UnregisterServer(FALSE, clsid);
126 if (FAILED(hr)) {
127 return hr;
129 if (unreg_typelib) {
130 hr = UtilUnRegisterTypeLib(_AtlComModule.m_hInstTypeLib, NULL, false);
132 return hr;
136 // Creates a javascript statement for execution from the function name and
137 // arguments passed in.
138 std::string CreateJavascript(const std::string& function_name,
139 const std::string args);
141 // Use to prevent the DLL from being unloaded while there are still living
142 // objects with outstanding references.
143 class AddRefModule {
144 public:
145 AddRefModule();
146 ~AddRefModule();
149 // Retrieves the executable name of the process hosting us. If
150 // |include_extension| is false, then we strip the extension from the name.
151 std::wstring GetHostProcessName(bool include_extension);
153 typedef enum BrowserType {
154 BROWSER_INVALID = -1,
155 BROWSER_UNKNOWN,
156 BROWSER_IE,
159 BrowserType GetBrowserType();
161 typedef enum IEVersion {
162 IE_INVALID,
163 NON_IE,
164 IE_UNSUPPORTED,
165 IE_6,
166 IE_7,
167 IE_8,
168 IE_9,
169 IE_10,
172 // The renderer to be used for a page. Values for Chrome also convey the
173 // reason why Chrome is used.
174 enum RendererType {
175 RENDERER_TYPE_UNDETERMINED = 0,
176 RENDERER_TYPE_CHROME_MIN,
177 // NOTE: group all _CHROME_ values together below here, as they are used for
178 // generating metrics reported via UMA (adjust MIN/MAX as needed).
179 RENDERER_TYPE_CHROME_GCF_PROTOCOL = RENDERER_TYPE_CHROME_MIN,
180 RENDERER_TYPE_CHROME_HTTP_EQUIV,
181 RENDERER_TYPE_CHROME_RESPONSE_HEADER,
182 RENDERER_TYPE_CHROME_DEFAULT_RENDERER,
183 RENDERER_TYPE_CHROME_OPT_IN_URL,
184 RENDERER_TYPE_CHROME_WIDGET,
185 // NOTE: all _CHOME_ values must go above here (adjust MIN/MAX as needed).
186 RENDERER_TYPE_CHROME_MAX = RENDERER_TYPE_CHROME_WIDGET,
187 RENDERER_TYPE_OTHER,
190 // Returns true if the given RendererType represents Chrome.
191 bool IsChrome(RendererType renderer_type);
193 // Convenience macro for logging a sample for the launch type metric.
194 #define UMA_LAUNCH_TYPE_COUNT(sample) \
195 UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.LaunchType", sample, \
196 RENDERER_TYPE_CHROME_MIN, RENDERER_TYPE_CHROME_MAX, \
197 RENDERER_TYPE_CHROME_MAX + 1 - RENDERER_TYPE_CHROME_MIN)
199 // To get the IE version when Chrome Frame is hosted in IE. Make sure that
200 // the hosting browser is IE before calling this function, otherwise NON_IE
201 // will be returned.
203 // Versions newer than the newest supported version are reported as the newest
204 // supported version.
205 IEVersion GetIEVersion();
207 // Returns the actual major version of the IE in which the current process is
208 // hosted. Returns 0 if the current process is not IE or any other error occurs.
209 uint32 GetIEMajorVersion();
211 FilePath GetIETemporaryFilesFolder();
213 // Retrieves the file version from a module handle without extra round trips
214 // to the disk (as happens with the regular GetFileVersionInfo API).
216 // @param module A handle to the module for which to retrieve the version info.
217 // @param high On successful return holds the most significant part of the file
218 // version. Must be non-null.
219 // @param low On successful return holds the least significant part of the file
220 // version. May be NULL.
221 // @returns true if the version info was successfully retrieved.
222 bool GetModuleVersion(HMODULE module, uint32* high, uint32* low);
224 // Return if the IEXPLORE is in private mode. The IEIsInPrivateBrowsing() checks
225 // whether current process is IEXPLORE.
226 bool IsIEInPrivate();
228 // Calls [ieframe|shdocvw]!DoFileDownload to initiate a download.
229 HRESULT DoFileDownloadInIE(const wchar_t* url);
231 // Construct a menu from the model sent from Chrome.
232 HMENU BuildContextMenu(const ContextMenuModel& menu_model);
234 // Uses GURL internally to append 'relative' to 'document'
235 std::string ResolveURL(const std::string& document,
236 const std::string& relative);
238 // Returns true iff the two urls have the same scheme, same host and same port.
239 bool HaveSameOrigin(const std::string& url1, const std::string& url2);
241 // Get a boolean configuration value from registry.
242 bool GetConfigBool(bool default_value, const wchar_t* value_name);
244 // Gets an integer configuration value from the registry.
245 int GetConfigInt(int default_value, const wchar_t* value_name);
247 // Sets an integer configuration value in the registry.
248 bool SetConfigInt(const wchar_t* value_name, int value);
250 // Sets a boolean integer configuration value in the registry.
251 bool SetConfigBool(const wchar_t* value_name, bool value);
253 // Deletes the configuration value passed in.
254 bool DeleteConfigValue(const wchar_t* value_name);
256 // Returns true if we are running in headless mode in which case we need to
257 // gather crash dumps, etc to send them to the crash server.
258 bool IsHeadlessMode();
260 // Returns true if we are running in accessible mode in which we need to enable
261 // renderer accessibility for use in automation.
262 bool IsAccessibleMode();
264 // Returns true if we are running in unpinned mode in which case DLL
265 // eviction should be possible.
266 bool IsUnpinnedMode();
268 // Returns true if all HTML pages should be rendered in GCF by default.
269 bool IsGcfDefaultRenderer();
271 // Check if this url is opting into Chrome Frame based on static settings.
272 // Returns one of:
273 // - RENDERER_TYPE_UNDETERMINED if not opt-in or if explicit opt-out
274 // - RENDERER_TYPE_CHROME_DEFAULT_RENDERER
275 // - RENDERER_TYPE_CHROME_OPT_IN_URL
276 RendererType RendererTypeForUrl(const std::wstring& url);
278 // Check if we should try to remove the CF user agent based on registry
279 // settings.
280 bool ShouldRemoveUAForUrl(const string16& url);
282 // Testing methods that return the backing stores behind RendererTypeForUrl and
283 // ShouldRemoveUAForUrl. Intended to allow unit testing code that calls the
284 // above methods.
285 // TODO(robertshield): All of the FooForUrl code should be removed from here
286 // and further refactored.
287 RegistryListPreferencesHolder& GetRendererTypePreferencesHolderForTesting();
288 RegistryListPreferencesHolder& GetUserAgentPreferencesHolderForTesting();
290 // A shortcut for QueryService
291 template <typename T>
292 HRESULT DoQueryService(const IID& service_id, IUnknown* unk, T** service) {
293 DCHECK(service);
294 if (!unk)
295 return E_INVALIDARG;
297 base::win::ScopedComPtr<IServiceProvider> service_provider;
298 HRESULT hr = service_provider.QueryFrom(unk);
299 if (service_provider)
300 hr = service_provider->QueryService(service_id, service);
302 DCHECK(FAILED(hr) || *service);
303 return hr;
306 // Navigates an IWebBrowser2 object to a moniker.
307 // |headers| can be NULL.
308 HRESULT NavigateBrowserToMoniker(IUnknown* browser, IMoniker* moniker,
309 const wchar_t* headers, IBindCtx* bind_ctx,
310 const wchar_t* fragment, IStream* post_data,
311 VARIANT* flags);
313 // Raises a flag on the current thread (using TLS) to indicate that an
314 // in-progress navigation should be rendered in chrome frame.
315 void MarkBrowserOnThreadForCFNavigation(IBrowserService* browser);
317 // Checks if this browser instance has been marked as currently navigating
318 // to a CF document. If clear_flag is set to true, the tls flag is cleared but
319 // only if the browser has been marked.
320 bool CheckForCFNavigation(IBrowserService* browser, bool clear_flag);
322 // Returns true if the URL passed in is something which can be handled by
323 // Chrome. If this function returns false then we should fail the navigation.
324 // When is_privileged is true, chrome extension URLs will be considered valid.
325 bool IsValidUrlScheme(const GURL& url, bool is_privileged);
327 // Returns the raw http headers for the current request given an
328 // IWinInetHttpInfo pointer.
329 std::string GetRawHttpHeaders(IWinInetHttpInfo* info);
331 // Can be used to determine whether a given request is being performed for
332 // a sub-frame or iframe in Internet Explorer. This can be called
333 // from various places, notably in request callbacks and the like.
335 // |service_provider| must not be NULL and should be a pointer to something
336 // that implements IServiceProvider (if it isn't this method returns false).
338 // Returns true if this method can determine with some certainty that the
339 // request did NOT originate from a top level frame, returns false otherwise.
340 bool IsSubFrameRequest(IUnknown* service_provider);
342 // See COM_INTERFACE_BLIND_DELEGATE below for details.
343 template <class T>
344 STDMETHODIMP CheckOutgoingInterface(void* obj, REFIID iid, void** ret,
345 DWORD cookie) {
346 T* instance = reinterpret_cast<T*>(obj);
347 HRESULT hr = E_NOINTERFACE;
348 IUnknown* delegate = instance ? instance->delegate() : NULL;
349 if (delegate) {
350 hr = delegate->QueryInterface(iid, ret);
351 #if !defined(NDEBUG)
352 if (SUCCEEDED(hr)) {
353 wchar_t iid_string[64] = {0};
354 StringFromGUID2(iid, iid_string, arraysize(iid_string));
355 DVLOG(1) << __FUNCTION__ << " Giving out wrapped interface: "
356 << iid_string;
358 #endif
361 return hr;
364 // See COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS below for details.
365 template <class T>
366 STDMETHODIMP QueryInterfaceIfDelegateSupports(void* obj, REFIID iid,
367 void** ret, DWORD cookie) {
368 HRESULT hr = E_NOINTERFACE;
369 T* instance = reinterpret_cast<T*>(obj);
370 IUnknown* delegate = instance ? instance->delegate() : NULL;
371 if (delegate) {
372 base::win::ScopedComPtr<IUnknown> original;
373 hr = delegate->QueryInterface(iid,
374 reinterpret_cast<void**>(original.Receive()));
375 if (original) {
376 IUnknown* supported_interface = reinterpret_cast<IUnknown*>(
377 reinterpret_cast<DWORD_PTR>(obj) + cookie);
378 supported_interface->AddRef();
379 *ret = supported_interface;
380 hr = S_OK;
384 return hr;
387 // Same as COM_INTERFACE_ENTRY but relies on the class to implement a
388 // delegate() method that returns a pointer to the delegated COM object.
389 #define COM_INTERFACE_ENTRY_IF_DELEGATE_SUPPORTS(x) \
390 COM_INTERFACE_ENTRY_FUNC(_ATL_IIDOF(x), \
391 offsetofclass(x, _ComMapClass), \
392 QueryInterfaceIfDelegateSupports<_ComMapClass>)
394 // Queries the delegated COM object for an interface, bypassing the wrapper.
395 #define COM_INTERFACE_BLIND_DELEGATE() \
396 COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface<_ComMapClass>)
398 // Thread that enters STA and has a UI message loop.
399 class STAThread : public base::Thread {
400 public:
401 explicit STAThread(const char *name) : Thread(name) {}
402 ~STAThread() {
403 Stop();
405 bool Start() {
406 return StartWithOptions(Options(MessageLoop::TYPE_UI, 0));
408 protected:
409 // Called just prior to starting the message loop
410 virtual void Init() {
411 ::CoInitialize(0);
414 // Called just after the message loop ends
415 virtual void CleanUp() {
416 ::CoUninitialize();
420 std::wstring GuidToString(const GUID& guid);
422 // The urls retrieved from the IMoniker interface don't contain the anchor
423 // portion of the actual url navigated to. This function checks whether the
424 // url passed in the bho_url parameter contains an anchor and if yes checks
425 // whether it matches the url retrieved from the moniker. If yes it returns
426 // the bho url, if not the moniker url.
427 std::wstring GetActualUrlFromMoniker(IMoniker* moniker,
428 IBindCtx* bind_context,
429 const std::wstring& bho_url);
431 // Checks if a window is a top level window
432 bool IsTopLevelWindow(HWND window);
434 // Seeks a stream back to position 0.
435 HRESULT RewindStream(IStream* stream);
437 // Fired when we want to notify IE about privacy changes.
438 #define WM_FIRE_PRIVACY_CHANGE_NOTIFICATION (WM_APP + 1)
440 // Sent (not posted) when a request needs to be downloaded in the host browser
441 // instead of Chrome. WPARAM is 0 and LPARAM is a pointer to an IMoniker
442 // object.
443 // NOTE: Since the message is sent synchronously, the handler should only
444 // start asynchronous operations in order to not block the sender unnecessarily.
445 #define WM_DOWNLOAD_IN_HOST (WM_APP + 2)
447 // This structure contains the parameters sent over to initiate a download
448 // request in the host browser.
449 struct DownloadInHostParams {
450 base::win::ScopedComPtr<IBindCtx> bind_ctx;
451 base::win::ScopedComPtr<IMoniker> moniker;
452 base::win::ScopedComPtr<IStream> post_data;
453 std::string request_headers;
456 // Maps the InternetCookieState enum to the corresponding CookieAction values
457 // used for IE privacy stuff.
458 int32 MapCookieStateToCookieAction(InternetCookieState cookie_state);
460 // Parses the url passed in and returns a GURL instance without the fragment.
461 GURL GetUrlWithoutFragment(const wchar_t* url);
463 // Compares the URLs passed in after removing the fragments from them.
464 bool CompareUrlsWithoutFragment(const wchar_t* url1, const wchar_t* url2);
466 // Returns the Referrer from the HTTP headers and additional headers.
467 std::string FindReferrerFromHeaders(const wchar_t* headers,
468 const wchar_t* additional_headers);
470 // Returns the HTTP headers from the binding passed in.
471 std::string GetHttpHeadersFromBinding(IBinding* binding);
473 // Returns the HTTP response code from the binding passed in.
474 int GetHttpResponseStatusFromBinding(IBinding* binding);
476 // Returns the clipboard format for text/html.
477 CLIPFORMAT GetTextHtmlClipboardFormat();
479 // Returns true iff the mime type is text/html.
480 bool IsTextHtmlMimeType(const wchar_t* mime_type);
482 // Returns true iff the clipboard format is text/html.
483 bool IsTextHtmlClipFormat(CLIPFORMAT cf);
485 // Returns true if we can detect that we are running as SYSTEM, false otherwise.
486 bool IsSystemProcess();
488 // STL helper class that implements a functor to delete objects.
489 // E.g: std::for_each(v.begin(), v.end(), utils::DeleteObject());
490 namespace utils {
491 class DeleteObject {
492 public:
493 template <typename T>
494 void operator()(T* obj) {
495 delete obj;
500 // Convert various protocol flags to text representation. Used for logging.
501 std::string BindStatus2Str(ULONG bind_status);
502 std::string PiFlags2Str(DWORD flags);
503 std::string Bscf2Str(DWORD flags);
505 // Reads data from a stream into a string.
506 HRESULT ReadStream(IStream* stream, size_t size, std::string* data);
508 // Parses urls targeted at ChromeFrame. This class maintains state like
509 // whether a url is prefixed with the gcf: prefix, whether it is being
510 // attached to an existing external tab, etc.
511 class ChromeFrameUrl {
512 public:
513 ChromeFrameUrl();
515 // Parses the url passed in. Returns true on success.
516 bool Parse(const std::wstring& url);
518 bool is_chrome_protocol() const {
519 return is_chrome_protocol_;
522 bool attach_to_external_tab() const {
523 return attach_to_external_tab_;
526 uint64 cookie() const {
527 return cookie_;
530 int disposition() const {
531 return disposition_;
534 const gfx::Rect& dimensions() const {
535 return dimensions_;
538 const GURL& gurl() const {
539 return parsed_url_;
542 const std::string& profile_name() const {
543 return profile_name_;
546 private:
547 // If we are attaching to an existing external tab, this function parses the
548 // suffix portion of the URL which contains the attach_external_tab prefix.
549 bool ParseAttachExternalTabUrl();
551 // Clear state.
552 void Reset();
554 bool attach_to_external_tab_;
555 bool is_chrome_protocol_;
556 uint64 cookie_;
557 gfx::Rect dimensions_;
558 int disposition_;
560 GURL parsed_url_;
561 std::string profile_name_;
564 class NavigationConstraints;
565 // Returns true if we can navigate to this URL.
566 // These decisions are controlled by the NavigationConstraints object passed
567 // in.
568 bool CanNavigate(const GURL& url,
569 NavigationConstraints* navigation_constraints);
571 // Utility function that prevents the current module from ever being unloaded.
572 // Call if you make irreversible patches.
573 void PinModule();
575 // Helper function to spin a message loop and dispatch messages while waiting
576 // for a handle to be signaled.
577 void WaitWithMessageLoop(HANDLE* handles, int count, DWORD timeout);
579 // Enumerates values in a key and adds them to an array.
580 // The names of the values are not returned.
581 void EnumerateKeyValues(HKEY parent_key, const wchar_t* sub_key_name,
582 std::vector<std::wstring>* values);
584 // Interprets the value of an X-UA-Compatible header (or <meta> tag equivalent)
585 // and indicates whether the header value contains a Chrome Frame directive
586 // matching a given host browser version.
588 // The header is a series of name-value pairs, with the names being HTTP tokens
589 // and the values being either tokens or quoted-strings. Names and values are
590 // joined by '=' and pairs are delimited by either ';' or ','. LWS may be used
591 // liberally before and between names, values, '=', and ';' or ','. See RFC 2616
592 // for definitions of token, quoted-string, and LWS. See Microsoft's
593 // documentation of the X-UA-COMPATIBLE header here:
594 // http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx
596 // At most one 'Chrome=<FILTER>' entry is expected in the header value. The
597 // first valid instance is used. The value of "<FILTER>" (possibly after
598 // unquoting) is interpreted as follows:
600 // "1" - Always active
601 // "IE7" - Active for IE major version 7 or lower
603 // For example:
604 // X-UA-Compatible: IE=8; Chrome=IE6
606 // The string is first interpreted using ';' as a delimiter. It is reevaluated
607 // using ',' iff no valid 'chrome=' value is found.
608 bool CheckXUaCompatibleDirective(const std::string& directive,
609 int ie_major_version);
611 // Returns the version of the current module as a string.
612 std::wstring GetCurrentModuleVersion();
614 // Returns true if ChromeFrame is the currently loaded document.
615 bool IsChromeFrameDocument(IWebBrowser2* web_browser);
617 // Increases the wininet connection limit for HTTP 1.0/1.1 connections to the
618 // value passed in. This is only done if the existing connection limit is
619 // lesser than the connection limit passed in. This function attempts to
620 // increase the connection count once per process.
621 // Returns true on success.
622 bool IncreaseWinInetConnections(DWORD connections);
624 #endif // CHROME_FRAME_UTILS_H_